From 221db5daf6b3666f1c8e4ca06ae45892e99a112f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 23 Jul 2020 16:38:45 +0100 Subject: qapi: enable use of g_autoptr with QAPI types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently QAPI generates a type and function for free'ing it: typedef struct QCryptoBlockCreateOptions QCryptoBlockCreateOptions; void qapi_free_QCryptoBlockCreateOptions(QCryptoBlockCreateOptions *obj); This is used in the traditional manner: QCryptoBlockCreateOptions *opts = NULL; opts = g_new0(QCryptoBlockCreateOptions, 1); ....do stuff with opts... qapi_free_QCryptoBlockCreateOptions(opts); Since bumping the min glib to 2.48, QEMU has incrementally adopted the use of g_auto/g_autoptr. This allows the compiler to run a function to free a variable when it goes out of scope, the benefit being the compiler can guarantee it is freed in all possible code ptahs. This benefit is applicable to QAPI types too, and given the seriously long method names for some qapi_free_XXXX() functions, is much less typing. This change thus makes the code generator emit: G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlockCreateOptions, qapi_free_QCryptoBlockCreateOptions) The above code example now becomes g_autoptr(QCryptoBlockCreateOptions) opts = NULL; opts = g_new0(QCryptoBlockCreateOptions, 1); ....do stuff with opts... Note, if the local pointer needs to live beyond the scope holding the variable, then g_steal_pointer can be used. This is useful to return the pointer to the caller in the success codepath, while letting it be freed in all error codepaths. return g_steal_pointer(&opts); The crypto/block.h header needs updating to avoid symbol clash now that the g_autoptr support is a standard QAPI feature. Signed-off-by: Daniel P. Berrangé Message-Id: <20200723153845.2934357-1-berrange@redhat.com> Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qapi/types.py | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 3ad33af..3640f17 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -213,6 +213,7 @@ def gen_type_cleanup_decl(name): ret = mcgen(''' void qapi_free_%(c_name)s(%(c_name)s *obj); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(%(c_name)s, qapi_free_%(c_name)s) ''', c_name=c_name(name)) return ret -- cgit v1.1 From 67abc3ddea74c60a282f46ac6e0af802c3b146f1 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 23 Jul 2020 16:27:36 +0200 Subject: scripts/qmp/qom-fuse: Unbreak import of QEMUMonitorProtocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit c7b942d7f8 "scripts/qmp: Fix shebang and imports" messed with it for reasons I don't quite understand. I do understand how it fails now: it neglects to import sys. Fix that. It now fails because it expects an old version of module fuse. That's next. Fixes: c7b942d7f84ef54f266921bf7668d43f1f2c7c79 Signed-off-by: Markus Armbruster Message-Id: <20200723142738.1868568-2-armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: John Snow --- scripts/qmp/qom-fuse | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse index 5fa6b3b..b7dabe8 100755 --- a/scripts/qmp/qom-fuse +++ b/scripts/qmp/qom-fuse @@ -13,7 +13,7 @@ import fuse, stat from fuse import Fuse -import os, posix +import os, posix, sys from errno import * sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) @@ -134,7 +134,7 @@ class QOMFS(Fuse): yield fuse.Direntry(str(item['name'])) if __name__ == '__main__': - import sys, os + import os fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])) fs.main(sys.argv) -- cgit v1.1 From f713ed4f7eac18dc43d75b08de99196139e56d08 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 23 Jul 2020 16:27:37 +0200 Subject: scripts/qmp/qom-fuse: Port to current Python module fuse Signed-off-by: Markus Armbruster Message-Id: <20200723142738.1868568-3-armbru@redhat.com> Reviewed-by: John Snow --- scripts/qmp/qom-fuse | 93 ++++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) (limited to 'scripts') diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse index b7dabe8..405e6eb 100755 --- a/scripts/qmp/qom-fuse +++ b/scripts/qmp/qom-fuse @@ -3,16 +3,18 @@ # QEMU Object Model test tools # # Copyright IBM, Corp. 2012 +# Copyright (C) 2020 Red Hat, Inc. # # Authors: # Anthony Liguori +# Markus Armbruster # # 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 +from fuse import FUSE, FuseOSError, Operations import os, posix, sys from errno import * @@ -21,9 +23,8 @@ from qemu.qmp import QEMUMonitorProtocol fuse.fuse_python_api = (0, 2) -class QOMFS(Fuse): - def __init__(self, qmp, *args, **kwds): - Fuse.__init__(self, *args, **kwds) +class QOMFS(Operations): + def __init__(self, qmp): self.qmp = qmp self.qmp.connect() self.ino_map = {} @@ -65,21 +66,21 @@ class QOMFS(Fuse): except: return False - def read(self, path, length, offset): + def read(self, path, length, offset, fh): 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 = self.qmp.command('qom-get', path=path, property=prop) data += '\n' # make values shell friendly except: - return -EPERM + raise FuseOSError(EPERM) if offset > len(data): return '' - return str(data[offset:][:length]) + return bytes(data[offset:][:length], encoding='utf-8') def readlink(self, path): if not self.is_link(path): @@ -89,52 +90,52 @@ class QOMFS(Fuse): return prefix + str(self.qmp.command('qom-get', path=path, property=prop)) - def getattr(self, path): + def getattr(self, path, fh=None): if self.is_link(path): - value = posix.stat_result((0o755 | stat.S_IFLNK, - self.get_ino(path), - 0, - 2, - 1000, - 1000, - 4096, - 0, - 0, - 0)) + value = { 'st_mode': 0o755 | stat.S_IFLNK, + 'st_ino': self.get_ino(path), + 'st_dev': 0, + 'st_nlink': 2, + 'st_uid': 1000, + 'st_gid': 1000, + 'st_size': 4096, + 'st_atime': 0, + 'st_mtime': 0, + 'st_ctime': 0 } elif self.is_object(path): - value = posix.stat_result((0o755 | stat.S_IFDIR, - self.get_ino(path), - 0, - 2, - 1000, - 1000, - 4096, - 0, - 0, - 0)) + value = { 'st_mode': 0o755 | stat.S_IFDIR, + 'st_ino': self.get_ino(path), + 'st_dev': 0, + 'st_nlink': 2, + 'st_uid': 1000, + 'st_gid': 1000, + 'st_size': 4096, + 'st_atime': 0, + 'st_mtime': 0, + 'st_ctime': 0 } elif self.is_property(path): - value = posix.stat_result((0o644 | stat.S_IFREG, - self.get_ino(path), - 0, - 1, - 1000, - 1000, - 4096, - 0, - 0, - 0)) + value = { 'st_mode': 0o644 | stat.S_IFREG, + 'st_ino': self.get_ino(path), + 'st_dev': 0, + 'st_nlink': 1, + 'st_uid': 1000, + 'st_gid': 1000, + 'st_size': 4096, + 'st_atime': 0, + 'st_mtime': 0, + 'st_ctime': 0 } else: - value = -ENOENT + raise FuseOSError(ENOENT) return value - def readdir(self, path, offset): - yield fuse.Direntry('.') - yield fuse.Direntry('..') + def readdir(self, path, fh): + yield '.' + yield '..' for item in self.qmp.command('qom-list', path=path): - yield fuse.Direntry(str(item['name'])) + yield str(item['name']) if __name__ == '__main__': import os - fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])) - fs.main(sys.argv) + fuse = FUSE(QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])), + sys.argv[1], foreground=True) -- cgit v1.1 From 3a14019e8216eb5f48074d781343317274b8292a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 23 Jul 2020 16:27:38 +0200 Subject: scripts/qmp/qom-fuse: Fix getattr(), read() for files in / MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit path, prop = "type".rsplit('/', 1) sets path to "", which doesn't work. Correct to "/". Signed-off-by: Markus Armbruster Message-Id: <20200723142738.1868568-4-armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: John Snow --- scripts/qmp/qom-fuse | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse index 405e6eb..7c7cff8 100755 --- a/scripts/qmp/qom-fuse +++ b/scripts/qmp/qom-fuse @@ -45,8 +45,10 @@ class QOMFS(Operations): return False def is_property(self, path): + path, prop = path.rsplit('/', 1) + if path == '': + path = '/' try: - path, prop = path.rsplit('/', 1) for item in self.qmp.command('qom-list', path=path): if item['name'] == prop: return True @@ -55,8 +57,10 @@ class QOMFS(Operations): return False def is_link(self, path): + path, prop = path.rsplit('/', 1) + if path == '': + 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<'): @@ -71,6 +75,8 @@ class QOMFS(Operations): return -ENOENT path, prop = path.rsplit('/', 1) + if path == '': + path = '/' try: data = self.qmp.command('qom-get', path=path, property=prop) data += '\n' # make values shell friendly -- cgit v1.1