139 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			139 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | #!/usr/bin/python | ||
|  | ## | ||
|  | # QEMU Object Model test tools | ||
|  | # | ||
|  | # Copyright IBM, Corp. 2012 | ||
|  | # | ||
|  | # Authors: | ||
|  | #  Anthony Liguori   <aliguori@us.ibm.com> | ||
|  | # | ||
|  | # This work is licensed under the terms of the GNU GPL, version 2 or later.  See | ||
|  | # the COPYING file in the top-level directory. | ||
|  | ## | ||
|  | 
 | ||
|  | import fuse, stat | ||
|  | from fuse import Fuse | ||
|  | import os, posix | ||
|  | from errno import * | ||
|  | from qmp import QEMUMonitorProtocol | ||
|  | 
 | ||
|  | fuse.fuse_python_api = (0, 2) | ||
|  | 
 | ||
|  | class QOMFS(Fuse): | ||
|  |     def __init__(self, qmp, *args, **kwds): | ||
|  |         Fuse.__init__(self, *args, **kwds) | ||
|  |         self.qmp = qmp | ||
|  |         self.qmp.connect() | ||
|  |         self.ino_map = {} | ||
|  |         self.ino_count = 1 | ||
|  | 
 | ||
|  |     def get_ino(self, path): | ||
|  |         if self.ino_map.has_key(path): | ||
|  |             return self.ino_map[path] | ||
|  |         self.ino_map[path] = self.ino_count | ||
|  |         self.ino_count += 1 | ||
|  |         return self.ino_map[path] | ||
|  | 
 | ||
|  |     def is_object(self, path): | ||
|  |         try: | ||
|  |             items = self.qmp.command('qom-list', path=path) | ||
|  |             return True | ||
|  |         except: | ||
|  |             return False | ||
|  | 
 | ||
|  |     def is_property(self, path): | ||
|  |         try: | ||
|  |             path, prop = path.rsplit('/', 1) | ||
|  |             for item in self.qmp.command('qom-list', path=path): | ||
|  |                 if item['name'] == prop: | ||
|  |                     return True | ||
|  |             return False | ||
|  |         except: | ||
|  |             return False | ||
|  | 
 | ||
|  |     def is_link(self, path): | ||
|  |         try: | ||
|  |             path, prop = path.rsplit('/', 1) | ||
|  |             for item in self.qmp.command('qom-list', path=path): | ||
|  |                 if item['name'] == prop: | ||
|  |                     if item['type'].startswith('link<'): | ||
|  |                         return True | ||
|  |                     return False | ||
|  |             return False | ||
|  |         except: | ||
|  |             return False | ||
|  | 
 | ||
|  |     def read(self, path, length, offset): | ||
|  |         if not self.is_property(path): | ||
|  |             return -ENOENT | ||
|  | 
 | ||
|  |         path, prop = path.rsplit('/', 1) | ||
|  |         try: | ||
|  |             data = str(self.qmp.command('qom-get', path=path, property=prop)) | ||
|  |             data += '\n' # make values shell friendly | ||
|  |         except: | ||
|  |             return -EPERM | ||
|  | 
 | ||
|  |         if offset > len(data): | ||
|  |             return '' | ||
|  | 
 | ||
|  |         return str(data[offset:][:length]) | ||
|  | 
 | ||
|  |     def readlink(self, path): | ||
|  |         if not self.is_link(path): | ||
|  |             return False | ||
|  |         path, prop = path.rsplit('/', 1) | ||
|  |         prefix = '/'.join(['..'] * (len(path.split('/')) - 1)) | ||
|  |         return prefix + str(self.qmp.command('qom-get', path=path, | ||
|  |                                              property=prop)) | ||
|  | 
 | ||
|  |     def getattr(self, path): | ||
|  |         if self.is_link(path): | ||
|  |             value = posix.stat_result((0755 | stat.S_IFLNK, | ||
|  |                                        self.get_ino(path), | ||
|  |                                        0, | ||
|  |                                        2, | ||
|  |                                        1000, | ||
|  |                                        1000, | ||
|  |                                        4096, | ||
|  |                                        0, | ||
|  |                                        0, | ||
|  |                                        0)) | ||
|  |         elif self.is_object(path): | ||
|  |             value = posix.stat_result((0755 | stat.S_IFDIR, | ||
|  |                                        self.get_ino(path), | ||
|  |                                        0, | ||
|  |                                        2, | ||
|  |                                        1000, | ||
|  |                                        1000, | ||
|  |                                        4096, | ||
|  |                                        0, | ||
|  |                                        0, | ||
|  |                                        0)) | ||
|  |         elif self.is_property(path): | ||
|  |             value = posix.stat_result((0644 | stat.S_IFREG, | ||
|  |                                        self.get_ino(path), | ||
|  |                                        0, | ||
|  |                                        1, | ||
|  |                                        1000, | ||
|  |                                        1000, | ||
|  |                                        4096, | ||
|  |                                        0, | ||
|  |                                        0, | ||
|  |                                        0)) | ||
|  |         else: | ||
|  |             value = -ENOENT | ||
|  |         return value | ||
|  | 
 | ||
|  |     def readdir(self, path, offset): | ||
|  |         yield fuse.Direntry('.') | ||
|  |         yield fuse.Direntry('..') | ||
|  |         for item in self.qmp.command('qom-list', path=path): | ||
|  |             yield fuse.Direntry(str(item['name'])) | ||
|  | 
 | ||
|  | if __name__ == '__main__': | ||
|  |     import sys, os | ||
|  | 
 | ||
|  |     fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])) | ||
|  |     fs.main(sys.argv) |