]>
Commit | Line | Data |
---|---|---|
5ade7674 AL |
1 | #!/usr/bin/python |
2 | ## | |
3 | # QEMU Object Model test tools | |
4 | # | |
5 | # Copyright IBM, Corp. 2012 | |
6 | # | |
7 | # Authors: | |
8 | # Anthony Liguori <[email protected]> | |
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) |