root / QMP / qom-fuse @ d7582078
History | View | Annotate | Download (4.3 kB)
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 |
|
14 |
import fuse, stat |
15 |
from fuse import Fuse |
16 |
import os, posix |
17 |
from errno import * |
18 |
from qmp import QEMUMonitorProtocol |
19 |
|
20 |
fuse.fuse_python_api = (0, 2) |
21 |
|
22 |
class 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 |
|
134 |
if __name__ == '__main__': |
135 |
import sys, os |
136 |
|
137 |
fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])) |
138 |
fs.main(sys.argv) |