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