| 
									
										
										
										
											2020-01-30 17:32:25 +01:00
										 |  |  | #!/usr/bin/env python3 | 
					
						
							| 
									
										
										
										
											2012-04-18 17:37:04 -05:00
										 |  |  | ## | 
					
						
							|  |  |  | # 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 * | 
					
						
							| 
									
										
										
										
											2020-05-28 18:21:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) | 
					
						
							|  |  |  | from qemu.qmp import QEMUMonitorProtocol | 
					
						
							| 
									
										
										
										
											2012-04-18 17:37:04 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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): | 
					
						
							| 
									
										
										
										
											2018-06-08 09:29:46 -03:00
										 |  |  |         if path in self.ino_map: | 
					
						
							| 
									
										
										
										
											2012-04-18 17:37:04 -05:00
										 |  |  |             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): | 
					
						
							| 
									
										
										
										
											2018-06-08 09:29:52 -03:00
										 |  |  |             value = posix.stat_result((0o755 | stat.S_IFLNK, | 
					
						
							| 
									
										
										
										
											2012-04-18 17:37:04 -05:00
										 |  |  |                                        self.get_ino(path), | 
					
						
							|  |  |  |                                        0, | 
					
						
							|  |  |  |                                        2, | 
					
						
							|  |  |  |                                        1000, | 
					
						
							|  |  |  |                                        1000, | 
					
						
							|  |  |  |                                        4096, | 
					
						
							|  |  |  |                                        0, | 
					
						
							|  |  |  |                                        0, | 
					
						
							|  |  |  |                                        0)) | 
					
						
							|  |  |  |         elif self.is_object(path): | 
					
						
							| 
									
										
										
										
											2018-06-08 09:29:52 -03:00
										 |  |  |             value = posix.stat_result((0o755 | stat.S_IFDIR, | 
					
						
							| 
									
										
										
										
											2012-04-18 17:37:04 -05:00
										 |  |  |                                        self.get_ino(path), | 
					
						
							|  |  |  |                                        0, | 
					
						
							|  |  |  |                                        2, | 
					
						
							|  |  |  |                                        1000, | 
					
						
							|  |  |  |                                        1000, | 
					
						
							|  |  |  |                                        4096, | 
					
						
							|  |  |  |                                        0, | 
					
						
							|  |  |  |                                        0, | 
					
						
							|  |  |  |                                        0)) | 
					
						
							|  |  |  |         elif self.is_property(path): | 
					
						
							| 
									
										
										
										
											2018-06-08 09:29:52 -03:00
										 |  |  |             value = posix.stat_result((0o644 | stat.S_IFREG, | 
					
						
							| 
									
										
										
										
											2012-04-18 17:37:04 -05:00
										 |  |  |                                        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) |