1#!/usr/bin/python 2## 3# QEMU Object Model test tools 4# 5# Copyright IBM, Corp. 2012 6# 7# Authors: 8# Anthony Liguori <aliguori@us.ibm.com> 9# 10# This work is licensed under the terms of the GNU GPL, version 2 or later. See 11# the COPYING file in the top-level directory. 12## 13 14from __future__ import absolute_import 15import fuse, stat 16from fuse import Fuse 17import os, posix 18from errno import * 19from .qmp import QEMUMonitorProtocol 20 21fuse.fuse_python_api = (0, 2) 22 23class QOMFS(Fuse): 24 def __init__(self, qmp, *args, **kwds): 25 Fuse.__init__(self, *args, **kwds) 26 self.qmp = qmp 27 self.qmp.connect() 28 self.ino_map = {} 29 self.ino_count = 1 30 31 def get_ino(self, path): 32 if path in self.ino_map: 33 return self.ino_map[path] 34 self.ino_map[path] = self.ino_count 35 self.ino_count += 1 36 return self.ino_map[path] 37 38 def is_object(self, path): 39 try: 40 items = self.qmp.command('qom-list', path=path) 41 return True 42 except: 43 return False 44 45 def is_property(self, path): 46 try: 47 path, prop = path.rsplit('/', 1) 48 for item in self.qmp.command('qom-list', path=path): 49 if item['name'] == prop: 50 return True 51 return False 52 except: 53 return False 54 55 def is_link(self, path): 56 try: 57 path, prop = path.rsplit('/', 1) 58 for item in self.qmp.command('qom-list', path=path): 59 if item['name'] == prop: 60 if item['type'].startswith('link<'): 61 return True 62 return False 63 return False 64 except: 65 return False 66 67 def read(self, path, length, offset): 68 if not self.is_property(path): 69 return -ENOENT 70 71 path, prop = path.rsplit('/', 1) 72 try: 73 data = str(self.qmp.command('qom-get', path=path, property=prop)) 74 data += '\n' # make values shell friendly 75 except: 76 return -EPERM 77 78 if offset > len(data): 79 return '' 80 81 return str(data[offset:][:length]) 82 83 def readlink(self, path): 84 if not self.is_link(path): 85 return False 86 path, prop = path.rsplit('/', 1) 87 prefix = '/'.join(['..'] * (len(path.split('/')) - 1)) 88 return prefix + str(self.qmp.command('qom-get', path=path, 89 property=prop)) 90 91 def getattr(self, path): 92 if self.is_link(path): 93 value = posix.stat_result((0o755 | stat.S_IFLNK, 94 self.get_ino(path), 95 0, 96 2, 97 1000, 98 1000, 99 4096, 100 0, 101 0, 102 0)) 103 elif self.is_object(path): 104 value = posix.stat_result((0o755 | stat.S_IFDIR, 105 self.get_ino(path), 106 0, 107 2, 108 1000, 109 1000, 110 4096, 111 0, 112 0, 113 0)) 114 elif self.is_property(path): 115 value = posix.stat_result((0o644 | stat.S_IFREG, 116 self.get_ino(path), 117 0, 118 1, 119 1000, 120 1000, 121 4096, 122 0, 123 0, 124 0)) 125 else: 126 value = -ENOENT 127 return value 128 129 def readdir(self, path, offset): 130 yield fuse.Direntry('.') 131 yield fuse.Direntry('..') 132 for item in self.qmp.command('qom-list', path=path): 133 yield fuse.Direntry(str(item['name'])) 134 135if __name__ == '__main__': 136 import sys, os 137 138 fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])) 139 fs.main(sys.argv) 140