qemu/scripts/qmp/qom-fuse
<<
>>
Prefs
   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
  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 self.ino_map.has_key(path):
  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((0755 | 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((0755 | 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((0644 | 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