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