From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225604; cv=none; d=zoho.com; s=zohoarc; b=ULKnhCCZ59sRCZQbS34Ed087XFcVNtrgeac4AhXwhFUm+UGjaa42lK4bviTNwEugmOnZWbdA6lWD5ra/59x3jqn6EKN+zYvVl5em6bpo807bA4Tqtw9gr9j99QfIO0y/WmXDdVELNENwdVJTh2rTNdxIOsqPFGFKVwL81zdFWGM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225604; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=IKOvT4fY+hDgHdgpyHo2Rg2+75O/6kQXp/lWkffMxxI=; b=F8A5Co3Jad6vqOxGPfkc0zfn2ZEa1jkvuJfYGUcaSErb9MdSSioZ/EaQE9QGOZyqlUCrF7TZAjXMk+J9vAvolLHReHQgbsxOFSmSjaYxuDkIdiN3UX4WsBrsgGug0wRDM9oJ9IlNYWvRTg+Cc9zkEkAUaONRhiR7gkEL2VEBGY8= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225604860434.7091818557435; Fri, 8 Nov 2019 07:06:44 -0800 (PST) Received: from localhost ([::1]:55896 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qV-00079x-Fv for importer@patchew.org; Fri, 08 Nov 2019 10:06:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45858) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5lo-0002jZ-BT for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:01:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5lm-0003Ku-TF for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:01:52 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:39597 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5lm-0003K3-PW for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:01:50 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-187-1fHarxj5MTSKzaWVESllyg-1; Fri, 08 Nov 2019 10:01:48 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BAF101005502 for ; Fri, 8 Nov 2019 15:01:47 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4F98A5D6B7; Fri, 8 Nov 2019 15:01:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IKOvT4fY+hDgHdgpyHo2Rg2+75O/6kQXp/lWkffMxxI=; b=bOgk6x2+x0Ci3bnbDEtKgvOoY9hntGXk7a34w0k8u1Bl+2q9s9RRK/6vSEwRRwYsEIJ3kz +5/KV2y5VWVtTob5QfvLEtlh53bhuSQLCwEGLTM2F9+vJCvvxSZcizs6mEDDAanInbVfKD RM1M0ojp7iI1GAunyQHbwxwV+tBbIkQ= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 01/25] qmp: constify QmpCommand and list Date: Fri, 8 Nov 2019 19:00:59 +0400 Message-Id: <20191108150123.12213-2-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-MC-Unique: 1fHarxj5MTSKzaWVESllyg-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Since 0b69f6f72ce47a37a749b056b6d5ec64c61f11e8 "qapi: remove qmp_unregister_command()", the command list can be declared const. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Damien Hedde --- include/qapi/qmp/dispatch.h | 9 +++++---- monitor/misc.c | 2 +- monitor/monitor-internal.h | 2 +- qapi/qmp-dispatch.c | 6 +++--- qapi/qmp-registry.c | 6 +++--- qga/commands.c | 2 +- qga/main.c | 6 +++--- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 9aa426a398..5a9cf82472 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -39,7 +39,8 @@ typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpComman= dList; =20 void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); -QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name); +const QmpCommand *qmp_find_command(const QmpCommandList *cmds, + const char *name); void qmp_disable_command(QmpCommandList *cmds, const char *name); void qmp_enable_command(QmpCommandList *cmds, const char *name); =20 @@ -47,13 +48,13 @@ bool qmp_command_is_enabled(const QmpCommand *cmd); const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QDict *qmp_error_response(Error *err); -QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request, +QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, bool allow_oob); bool qmp_is_oob(const QDict *dict); =20 -typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque); +typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, void *opaque); =20 -void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn, +void qmp_for_each_command(const QmpCommandList *cmds, qmp_cmd_callback_fn = fn, void *opaque); =20 #endif diff --git a/monitor/misc.c b/monitor/misc.c index 3baa15f3bf..3052bfe8f1 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -230,7 +230,7 @@ static void hmp_info_help(Monitor *mon, const QDict *qd= ict) help_cmd(mon, "info"); } =20 -static void query_commands_cb(QmpCommand *cmd, void *opaque) +static void query_commands_cb(const QmpCommand *cmd, void *opaque) { CommandInfoList *info, **list =3D opaque; =20 diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index d78f5ca190..3e7dac5910 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -132,7 +132,7 @@ typedef struct { * qmp_capabilities succeeds, we go into command mode, and * @command becomes &qmp_commands. */ - QmpCommandList *commands; + const QmpCommandList *commands; bool capab_offered[QMP_CAPABILITY__MAX]; /* capabilities offered */ bool capab[QMP_CAPABILITY__MAX]; /* offered and accepted */ /* diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index bc264b3c9b..857399c5fe 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -75,14 +75,14 @@ static QDict *qmp_dispatch_check_obj(const QObject *req= uest, bool allow_oob, return dict; } =20 -static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request, +static QObject *do_qmp_dispatch(const QmpCommandList *cmds, QObject *reque= st, bool allow_oob, Error **errp) { Error *local_err =3D NULL; bool oob; const char *command; QDict *args, *dict; - QmpCommand *cmd; + const QmpCommand *cmd; QObject *ret =3D NULL; =20 dict =3D qmp_dispatch_check_obj(request, allow_oob, errp); @@ -164,7 +164,7 @@ bool qmp_is_oob(const QDict *dict) && !qdict_haskey(dict, "execute"); } =20 -QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request, +QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, bool allow_oob) { Error *err =3D NULL; diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index ca00f74795..d0f9a1d3e3 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -27,7 +27,7 @@ void qmp_register_command(QmpCommandList *cmds, const cha= r *name, QTAILQ_INSERT_TAIL(cmds, cmd, node); } =20 -QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name) +const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char = *name) { QmpCommand *cmd; =20 @@ -77,10 +77,10 @@ bool qmp_has_success_response(const QmpCommand *cmd) return !(cmd->options & QCO_NO_SUCCESS_RESP); } =20 -void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn, +void qmp_for_each_command(const QmpCommandList *cmds, qmp_cmd_callback_fn = fn, void *opaque) { - QmpCommand *cmd; + const QmpCommand *cmd; =20 QTAILQ_FOREACH(cmd, cmds, node) { fn(cmd, opaque); diff --git a/qga/commands.c b/qga/commands.c index 0c7d1385c2..05e9ab6c3d 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -54,7 +54,7 @@ void qmp_guest_ping(Error **errp) slog("guest-ping called"); } =20 -static void qmp_command_info(QmpCommand *cmd, void *opaque) +static void qmp_command_info(const QmpCommand *cmd, void *opaque) { GuestAgentInfo *info =3D opaque; GuestAgentCommandInfo *cmd_info; diff --git a/qga/main.c b/qga/main.c index c35c2a2120..f23614528e 100644 --- a/qga/main.c +++ b/qga/main.c @@ -359,7 +359,7 @@ static gint ga_strcmp(gconstpointer str1, gconstpointer= str2) } =20 /* disable commands that aren't safe for fsfreeze */ -static void ga_disable_non_whitelisted(QmpCommand *cmd, void *opaque) +static void ga_disable_non_whitelisted(const QmpCommand *cmd, void *opaque) { bool whitelisted =3D false; int i =3D 0; @@ -378,7 +378,7 @@ static void ga_disable_non_whitelisted(QmpCommand *cmd,= void *opaque) } =20 /* [re-]enable all commands, except those explicitly blacklisted by user */ -static void ga_enable_non_blacklisted(QmpCommand *cmd, void *opaque) +static void ga_enable_non_blacklisted(const QmpCommand *cmd, void *opaque) { GList *blacklist =3D opaque; const char *name =3D qmp_command_name(cmd); @@ -918,7 +918,7 @@ int64_t ga_get_fd_handle(GAState *s, Error **errp) return handle; } =20 -static void ga_print_cmd(QmpCommand *cmd, void *opaque) +static void ga_print_cmd(const QmpCommand *cmd, void *opaque) { printf("%s\n", qmp_command_name(cmd)); } --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225530; cv=none; d=zoho.com; s=zohoarc; b=ihJkhXlz8I7nSB3DgveqDGgZm0LazyyHKjiM/VsBVufECKZIRCarqerqsUbeNNP0jSFt6nXWkHE0+VQ4MhjYXPxt/26152Jf94OIr7IAGTOCsdVNCU/ftA0lzHMtTtyGsk9bN2hHtPUqT2QkrfaaTzTS0qLRqAhaKC3LFV06Wl0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225530; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=idH6Lctnz6gUEPfhrh3e0GxtIlG3tIR/wVTbHh5fUtY=; b=AbK2nNJPy3G0qKsdTVXRBFOcCsWEcyKPS6xdxIIk1PEPvldcHb+fjezZoZWSyIJtCCSx2ODTK5A5om8STRIhWwoGs5Ey4q4qJ3p71wJHL9r0aIHhZu+vxSfX8LgVsiprT3Ao23cyYVzS4XUGme8Z+9W/DCDR8KnuMW1/ZuadGTs= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225529985686.1481129376946; Fri, 8 Nov 2019 07:05:29 -0800 (PST) Received: from localhost ([::1]:55870 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5pG-00058W-3F for importer@patchew.org; Fri, 08 Nov 2019 10:05:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45904) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5m4-0002oe-Cc for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5m3-0003U3-9h for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:08 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:35638 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5m1-0003Sr-Ld for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:05 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-83-LoBFHHMCMXGgzrwgXXSpFA-1; Fri, 08 Nov 2019 10:02:00 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 10117477 for ; Fri, 8 Nov 2019 15:02:00 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0DC5160C18; Fri, 8 Nov 2019 15:01:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225323; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=idH6Lctnz6gUEPfhrh3e0GxtIlG3tIR/wVTbHh5fUtY=; b=DtR8vfggYqpU+Sss7X2J5hWPR8o6gv4u+RWSAkrpYdIl9dJh1QNyfibfZfSx12EFYLEEqN m43NczBnrSTwRxl8OaG0I+YaqlhWRCUpctXPY0YREX9g9e7men0OzArHeO6tn2/FgcLUnK AmFp4mlRGRUeHhG+z/whmDTf/GmbTjc= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 02/25] json-lexer: make it safe to call destroy multiple times Date: Fri, 8 Nov 2019 19:01:00 +0400 Message-Id: <20191108150123.12213-3-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-MC-Unique: LoBFHHMCMXGgzrwgXXSpFA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" We can easily avoid the burden of checking if the lexer was initialized prior to calling destroy by the caller, let's do it. This allows simplification in state tracking with the following patch, "qmp: add QmpSession" can call qmp_session_destroy() multiple times, which in turns calls json_lexer_destroy(). Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Damien Hedde --- qobject/json-lexer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c index 632320d72d..fa7a2c43a8 100644 --- a/qobject/json-lexer.c +++ b/qobject/json-lexer.c @@ -361,5 +361,8 @@ void json_lexer_flush(JSONLexer *lexer) =20 void json_lexer_destroy(JSONLexer *lexer) { - g_string_free(lexer->token, true); + if (lexer->token) { + g_string_free(lexer->token, true); + lexer->token =3D NULL; + } } --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225771; cv=none; d=zoho.com; s=zohoarc; b=FdEhgiq42kuHWDidbi045BBoBPYpED4hXt8cy2Hrl/bytV2qbGK//engn7blpr+s4mIpyr+hc4Zt3uUSREOfAMKy2NhN7Kqo8bhQYRlgeN0h/fRIF6GfeZ9DFbcGLIVaDK4suzUIiTPHXXNPddqsWzEHzgll8XCLs9ihmGV8pfE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225771; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=NDyzyp9lszBVzhOgIQ8TOZ58QA1kDkQfY7FbGxmBrS0=; b=PUUW/9UnUcNYuEuvBsYCz4fPWgFPzOpcO/cv6bUG+2t25zF4d0iLAzP9T5iD06cHb1+63Q2kbjXa5H74SwkTs1n9ZAS73rFer2BzrmCZ9Jm6Ih1j3xaO4bAdg/8irXhm2eFfL5fuI6arltW6XYANwa60rw265TascBelatCOtyE= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225771740494.0860719338931; Fri, 8 Nov 2019 07:09:31 -0800 (PST) Received: from localhost ([::1]:55934 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5tB-0002VN-7o for importer@patchew.org; Fri, 08 Nov 2019 10:09:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45979) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5mG-0002wP-IV for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5mE-0003Za-ID for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:20 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:39309 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5mE-0003ZJ-DS for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:18 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-346-u12A6TUTMCqvp7LGicK1aQ-1; Fri, 08 Nov 2019 10:02:16 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B0056180496F for ; Fri, 8 Nov 2019 15:02:15 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F5296084E; Fri, 8 Nov 2019 15:02:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225338; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NDyzyp9lszBVzhOgIQ8TOZ58QA1kDkQfY7FbGxmBrS0=; b=HQY/xJ+26apn4ZTKVIW6xCijrCS8cg78HN16RagXo1By7hF+d48290COPNidOw6NdVPDdY k5Hot2k6yz1drcNoasz1br4PnTmqhUMbFA+SLedm41PfhNYNWl5TV9MUVB4uemYyGVOoTW kdFOkTiPT+PD7EGg/5+VIXShDwHsHMw= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 03/25] qmp: add QmpSession Date: Fri, 8 Nov 2019 19:01:01 +0400 Message-Id: <20191108150123.12213-4-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-MC-Unique: u12A6TUTMCqvp7LGicK1aQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This structure will hold various data related to a QMP client session: the list of commands, the parser, the callbacks, the pending operations... Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 10 +++++++++- monitor/misc.c | 6 +++--- monitor/monitor-internal.h | 2 +- monitor/monitor.c | 2 +- monitor/qmp.c | 8 +++++--- qapi/qmp-dispatch.c | 15 ++++++++++++--- qga/main.c | 5 ++++- tests/test-qmp-cmds.c | 28 ++++++++++++++++++++++------ 8 files changed, 57 insertions(+), 19 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 5a9cf82472..3b53cfd788 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -37,10 +37,18 @@ typedef struct QmpCommand =20 typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList; =20 +typedef struct QmpSession QmpSession; + +struct QmpSession { + const QmpCommandList *cmds; +}; + void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char *name); +void qmp_session_init(QmpSession *session, const QmpCommandList *cmds); +void qmp_session_destroy(QmpSession *session); void qmp_disable_command(QmpCommandList *cmds, const char *name); void qmp_enable_command(QmpCommandList *cmds, const char *name); =20 @@ -48,7 +56,7 @@ bool qmp_command_is_enabled(const QmpCommand *cmd); const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QDict *qmp_error_response(Error *err); -QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, +QDict *qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob); bool qmp_is_oob(const QDict *dict); =20 diff --git a/monitor/misc.c b/monitor/misc.c index 3052bfe8f1..bb33ca73cf 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -253,7 +253,7 @@ CommandInfoList *qmp_query_commands(Error **errp) assert(monitor_is_qmp(cur_mon)); mon =3D container_of(cur_mon, MonitorQMP, common); =20 - qmp_for_each_command(mon->commands, query_commands_cb, &list); + qmp_for_each_command(mon->session.cmds, query_commands_cb, &list); =20 return list; } @@ -363,7 +363,7 @@ void qmp_qmp_capabilities(bool has_enable, QMPCapabilit= yList *enable, assert(monitor_is_qmp(cur_mon)); mon =3D container_of(cur_mon, MonitorQMP, common); =20 - if (mon->commands =3D=3D &qmp_commands) { + if (mon->session.cmds =3D=3D &qmp_commands) { error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, "Capabilities negotiation is already complete, command " "ignored"); @@ -374,7 +374,7 @@ void qmp_qmp_capabilities(bool has_enable, QMPCapabilit= yList *enable, return; } =20 - mon->commands =3D &qmp_commands; + mon->session.cmds =3D &qmp_commands; } =20 /* Set the current CPU defined by the user. Callers must hold BQL. */ diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 3e7dac5910..b15266e77b 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -132,7 +132,7 @@ typedef struct { * qmp_capabilities succeeds, we go into command mode, and * @command becomes &qmp_commands. */ - const QmpCommandList *commands; + QmpSession session; bool capab_offered[QMP_CAPABILITY__MAX]; /* capabilities offered */ bool capab[QMP_CAPABILITY__MAX]; /* offered and accepted */ /* diff --git a/monitor/monitor.c b/monitor/monitor.c index 12898b6448..ecf21d9786 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -263,7 +263,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QD= ict *qdict) } =20 qmp_mon =3D container_of(mon, MonitorQMP, common); - if (qmp_mon->commands !=3D &qmp_cap_negotiation_commands) { + if (qmp_mon->session.cmds !=3D &qmp_cap_negotiation_commands) { qmp_send_response(qmp_mon, qdict); } } diff --git a/monitor/qmp.c b/monitor/qmp.c index 9d9e5d8b27..24ccdeb4a4 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -117,11 +117,11 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QOb= ject *req) old_mon =3D cur_mon; cur_mon =3D &mon->common; =20 - rsp =3D qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon)); + rsp =3D qmp_dispatch(&mon->session, req, qmp_oob_enabled(mon)); =20 cur_mon =3D old_mon; =20 - if (mon->commands =3D=3D &qmp_cap_negotiation_commands) { + if (mon->session.cmds =3D=3D &qmp_cap_negotiation_commands) { error =3D qdict_get_qdict(rsp, "error"); if (error && !g_strcmp0(qdict_get_try_str(error, "class"), @@ -318,7 +318,7 @@ static void monitor_qmp_event(void *opaque, int event) =20 switch (event) { case CHR_EVENT_OPENED: - mon->commands =3D &qmp_cap_negotiation_commands; + qmp_session_init(&mon->session, &qmp_cap_negotiation_commands); monitor_qmp_caps_reset(mon); data =3D qmp_greeting(mon); qmp_send_response(mon, data); @@ -333,6 +333,7 @@ static void monitor_qmp_event(void *opaque, int event) * is closed. */ monitor_qmp_cleanup_queues(mon); + qmp_session_destroy(&mon->session); json_message_parser_destroy(&mon->parser); json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL); @@ -344,6 +345,7 @@ static void monitor_qmp_event(void *opaque, int event) =20 void monitor_data_destroy_qmp(MonitorQMP *mon) { + qmp_session_destroy(&mon->session); json_message_parser_destroy(&mon->parser); qemu_mutex_destroy(&mon->qmp_queue_lock); monitor_qmp_cleanup_req_queue_locked(mon); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 857399c5fe..0e6b003dd8 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -164,15 +164,24 @@ bool qmp_is_oob(const QDict *dict) && !qdict_haskey(dict, "execute"); } =20 -QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - bool allow_oob) +void qmp_session_init(QmpSession *session, const QmpCommandList *cmds) +{ + session->cmds =3D cmds; +} + +void qmp_session_destroy(QmpSession *session) +{ + session->cmds =3D NULL; +} + +QDict *qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob) { Error *err =3D NULL; QDict *dict =3D qobject_to(QDict, request); QObject *ret, *id =3D dict ? qdict_get(dict, "id") : NULL; QDict *rsp; =20 - ret =3D do_qmp_dispatch(cmds, request, allow_oob, &err); + ret =3D do_qmp_dispatch(session->cmds, request, allow_oob, &err); if (err) { rsp =3D qmp_error_response(err); } else if (ret) { diff --git a/qga/main.c b/qga/main.c index f23614528e..61190db5f3 100644 --- a/qga/main.c +++ b/qga/main.c @@ -74,6 +74,7 @@ typedef struct GAPersistentState { typedef struct GAConfig GAConfig; =20 struct GAState { + QmpSession session; JSONMessageParser parser; GMainLoop *main_loop; GAChannel *channel; @@ -572,7 +573,7 @@ static void process_event(void *opaque, QObject *obj, E= rror *err) } =20 g_debug("processing command"); - rsp =3D qmp_dispatch(&ga_commands, obj, false); + rsp =3D qmp_dispatch(&s->session, obj, false); =20 end: ret =3D send_response(s, rsp); @@ -1338,6 +1339,7 @@ static GAState *initialize_agent(GAConfig *config, in= t socket_activation) ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); json_message_parser_init(&s->parser, process_event, s, NULL); + qmp_session_init(&s->session, &ga_commands); =20 #ifndef _WIN32 if (!register_signal_handlers()) { @@ -1369,6 +1371,7 @@ static void cleanup_agent(GAState *s) CloseHandle(s->wakeup_event); #endif if (s->command_state) { + qmp_session_destroy(&s->session); ga_command_state_cleanup_all(s->command_state); ga_command_state_free(s->command_state); json_message_parser_destroy(&s->parser); diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 27b0afe55a..962c2cb2e1 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -147,44 +147,52 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_q= emu_x_EnumList *a, /* test commands with no input and no return value */ static void test_dispatch_cmd(void) { + QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); QDict *resp; =20 + qmp_session_init(&session, &qmp_commands); qdict_put_str(req, "execute", "user_def_cmd"); =20 - resp =3D qmp_dispatch(&qmp_commands, QOBJECT(req), false); + resp =3D qmp_dispatch(&session, QOBJECT(req), false); assert(resp !=3D NULL); assert(!qdict_haskey(resp, "error")); =20 qobject_unref(resp); qobject_unref(req); + qmp_session_destroy(&session); } =20 static void test_dispatch_cmd_oob(void) { + QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); QDict *resp; =20 + qmp_session_init(&session, &qmp_commands); qdict_put_str(req, "exec-oob", "test-flags-command"); =20 - resp =3D qmp_dispatch(&qmp_commands, QOBJECT(req), true); + resp =3D qmp_dispatch(&session, QOBJECT(req), true); assert(resp !=3D NULL); assert(!qdict_haskey(resp, "error")); =20 qobject_unref(resp); qobject_unref(req); + qmp_session_destroy(&session); } =20 /* test commands that return an error due to invalid parameters */ static void test_dispatch_cmd_failure(void) { + QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); QDict *args =3D qdict_new(); QDict *resp; =20 + qmp_session_init(&session, &qmp_commands); qdict_put_str(req, "execute", "user_def_cmd2"); =20 - resp =3D qmp_dispatch(&qmp_commands, QOBJECT(req), false); + resp =3D qmp_dispatch(&session, QOBJECT(req), false); assert(resp !=3D NULL); assert(qdict_haskey(resp, "error")); =20 @@ -198,36 +206,44 @@ static void test_dispatch_cmd_failure(void) =20 qdict_put_str(req, "execute", "user_def_cmd"); =20 - resp =3D qmp_dispatch(&qmp_commands, QOBJECT(req), false); + resp =3D qmp_dispatch(&session, QOBJECT(req), false); assert(resp !=3D NULL); assert(qdict_haskey(resp, "error")); =20 qobject_unref(resp); qobject_unref(req); + qmp_session_destroy(&session); } =20 static void test_dispatch_cmd_success_response(void) { + QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); QDict *resp; =20 + qmp_session_init(&session, &qmp_commands); qdict_put_str(req, "execute", "cmd-success-response"); - resp =3D qmp_dispatch(&qmp_commands, QOBJECT(req), false); + resp =3D qmp_dispatch(&session, QOBJECT(req), false); g_assert_null(resp); qobject_unref(req); + qmp_session_destroy(&session); } =20 + static QObject *test_qmp_dispatch(QDict *req) { + QmpSession session =3D { 0, }; QDict *resp; QObject *ret; =20 - resp =3D qmp_dispatch(&qmp_commands, QOBJECT(req), false); + qmp_session_init(&session, &qmp_commands); + resp =3D qmp_dispatch(&session, QOBJECT(req), false); assert(resp && !qdict_haskey(resp, "error")); ret =3D qdict_get(resp, "return"); assert(ret); qobject_ref(ret); qobject_unref(resp); + qmp_session_destroy(&session); return ret; } =20 --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225693; cv=none; d=zoho.com; s=zohoarc; b=RZ2JqBDx2/H4jSCROa3z1uEFA8h6vg6eBdeUc43gSYP92BgUthraKYtrVkE0aUiV0qpPKkE0H2F23E0zuYiM4ueHKHFSzDH9zh4Bj4UJUFHl8/ouIhjMgJXP4WV+52hvbjGlMY5rEYLJZsA7vTM4SnKcJZWDx2yTozouKNRgP7U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225693; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=l8Z5y8d3WkdwB1zLwwtTktsfJb3xTBuj4vDuH+BQs3M=; b=YBRHzYX7T8LBU/6s5s6zbUdou5oZKfqo327qEIKYyyzIZ7fbk847K47mvJbUiaiBAS0w+e7Im5Et00gQMABhIYqyDC0ZYEHakZawDI3oC7eGUJ7fV3dI7j+Iu3JfamzPlhqK0cPzJjsc+zTnNjZNI4BXDYmK5ZvO0dTacPYlnT0= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225693224348.49733388366315; Fri, 8 Nov 2019 07:08:13 -0800 (PST) Received: from localhost ([::1]:55918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5rv-0000WB-Fz for importer@patchew.org; Fri, 08 Nov 2019 10:08:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46145) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5mV-00036Y-6F for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5mT-0003jd-8p for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:35 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:42287 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5mS-0003in-PL for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:33 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-393-Q7UhsJ4SNl24DoQYGMwVnw-1; Fri, 08 Nov 2019 10:02:29 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1D4C3800C72 for ; Fri, 8 Nov 2019 15:02:29 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 54F7A600C9; Fri, 8 Nov 2019 15:02:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225351; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l8Z5y8d3WkdwB1zLwwtTktsfJb3xTBuj4vDuH+BQs3M=; b=J8P6mAMQlZzICfoRrxIu3skZiXRoRpazJ49moWwo3gmIjtEy17jVyNEFR0hGNDfQcFJ1pw tfYCIrlH3XQw8C35zeBj3xscxGFtbGr6KcOnoaemmjOS02/da0oOapu5WprEjR6bMSFWmP YW9MI85WbD2h5a4vbF04LsWPDw2w5AA= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 04/25] QmpSession: add a return callback Date: Fri, 8 Nov 2019 19:01:02 +0400 Message-Id: <20191108150123.12213-5-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: Q7UhsJ4SNl24DoQYGMwVnw-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Introduce a return_cb to allow delaying finishing the dispatch and sending the response asynchronously. For now, this is just modifying qmp_dispatch() to call the callback synchronously. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 10 ++++-- monitor/qmp.c | 47 ++++++++++--------------- qapi/qmp-dispatch.c | 22 +++++++++--- qga/main.c | 34 +++++++++++------- tests/test-qmp-cmds.c | 69 ++++++++++++++++++------------------- 5 files changed, 98 insertions(+), 84 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 3b53cfd788..d1ce631a93 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -38,16 +38,20 @@ typedef struct QmpCommand typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList; =20 typedef struct QmpSession QmpSession; +typedef void (QmpDispatchReturn) (QmpSession *session, QDict *rsp); =20 struct QmpSession { const QmpCommandList *cmds; + QmpDispatchReturn *return_cb; }; =20 void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char *name); -void qmp_session_init(QmpSession *session, const QmpCommandList *cmds); +void qmp_session_init(QmpSession *session, + const QmpCommandList *cmds, + QmpDispatchReturn *return_cb); void qmp_session_destroy(QmpSession *session); void qmp_disable_command(QmpCommandList *cmds, const char *name); void qmp_enable_command(QmpCommandList *cmds, const char *name); @@ -56,8 +60,8 @@ bool qmp_command_is_enabled(const QmpCommand *cmd); const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QDict *qmp_error_response(Error *err); -QDict *qmp_dispatch(QmpSession *session, QObject *request, - bool allow_oob); +void qmp_dispatch(QmpSession *session, QObject *request, + bool allow_oob); bool qmp_is_oob(const QDict *dict); =20 typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, void *opaque); diff --git a/monitor/qmp.c b/monitor/qmp.c index 24ccdeb4a4..b215cb70f3 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -96,45 +96,35 @@ void qmp_send_response(MonitorQMP *mon, const QDict *rs= p) qobject_unref(json); } =20 -/* - * Emit QMP response @rsp to @mon. - * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP. - * Nothing is emitted then. - */ -static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp) +static void dispatch_return_cb(QmpSession *session, QDict *rsp) { - if (rsp) { - qmp_send_response(mon, rsp); + MonitorQMP *mon =3D container_of(session, MonitorQMP, session); + + if (mon->session.cmds =3D=3D &qmp_cap_negotiation_commands) { + QDict *error =3D qdict_get_qdict(rsp, "error"); + if (error + && !g_strcmp0(qdict_get_try_str(error, "class"), + QapiErrorClass_str(ERROR_CLASS_COMMAND_NOT_FOUND= ))) { + /* Provide a more useful error message */ + qdict_del(error, "desc"); + qdict_put_str(error, "desc", "Expecting capabilities negotiati= on" + " with 'qmp_capabilities'"); + } } + + qmp_send_response(mon, rsp); } =20 static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) { Monitor *old_mon; - QDict *rsp; - QDict *error; =20 old_mon =3D cur_mon; cur_mon =3D &mon->common; =20 - rsp =3D qmp_dispatch(&mon->session, req, qmp_oob_enabled(mon)); + qmp_dispatch(&mon->session, req, qmp_oob_enabled(mon)); =20 cur_mon =3D old_mon; - - if (mon->session.cmds =3D=3D &qmp_cap_negotiation_commands) { - error =3D qdict_get_qdict(rsp, "error"); - if (error - && !g_strcmp0(qdict_get_try_str(error, "class"), - QapiErrorClass_str(ERROR_CLASS_COMMAND_NOT_FOUND))) { - /* Provide a more useful error message */ - qdict_del(error, "desc"); - qdict_put_str(error, "desc", "Expecting capabilities negotiati= on" - " with 'qmp_capabilities'"); - } - } - - monitor_qmp_respond(mon, rsp); - qobject_unref(rsp); } =20 /* @@ -211,7 +201,7 @@ void monitor_qmp_bh_dispatcher(void *data) assert(req_obj->err); rsp =3D qmp_error_response(req_obj->err); req_obj->err =3D NULL; - monitor_qmp_respond(mon, rsp); + qmp_send_response(req_obj->mon, rsp); qobject_unref(rsp); } =20 @@ -318,7 +308,8 @@ static void monitor_qmp_event(void *opaque, int event) =20 switch (event) { case CHR_EVENT_OPENED: - qmp_session_init(&mon->session, &qmp_cap_negotiation_commands); + qmp_session_init(&mon->session, + &qmp_cap_negotiation_commands, dispatch_return_cb= ); monitor_qmp_caps_reset(mon); data =3D qmp_greeting(mon); qmp_send_response(mon, data); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 0e6b003dd8..1314f4929f 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -164,17 +164,28 @@ bool qmp_is_oob(const QDict *dict) && !qdict_haskey(dict, "execute"); } =20 -void qmp_session_init(QmpSession *session, const QmpCommandList *cmds) +void qmp_session_init(QmpSession *session, + const QmpCommandList *cmds, + QmpDispatchReturn *return_cb) { + assert(return_cb); + assert(!session->return_cb); + session->cmds =3D cmds; + session->return_cb =3D return_cb; } =20 void qmp_session_destroy(QmpSession *session) { + if (!session->return_cb) { + return; + } + session->cmds =3D NULL; + session->return_cb =3D NULL; } =20 -QDict *qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob) +void qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob) { Error *err =3D NULL; QDict *dict =3D qobject_to(QDict, request); @@ -189,12 +200,13 @@ QDict *qmp_dispatch(QmpSession *session, QObject *req= uest, bool allow_oob) qdict_put_obj(rsp, "return", ret); } else { /* Can only happen for commands with QCO_NO_SUCCESS_RESP */ - rsp =3D NULL; + return; } =20 - if (rsp && id) { + if (id) { qdict_put_obj(rsp, "id", qobject_ref(id)); } =20 - return rsp; + session->return_cb(session, rsp); + qobject_unref(rsp); } diff --git a/qga/main.c b/qga/main.c index 61190db5f3..c291d06491 100644 --- a/qga/main.c +++ b/qga/main.c @@ -558,29 +558,37 @@ static int send_response(GAState *s, const QDict *rsp) return 0; } =20 +static void dispatch_return_cb(QmpSession *session, QDict *rsp) +{ + GAState *s =3D container_of(session, GAState, session); + int ret =3D send_response(s, rsp); + if (ret < 0) { + g_warning("error sending response: %s", strerror(-ret)); + } +} + /* handle requests/control events coming in over the channel */ static void process_event(void *opaque, QObject *obj, Error *err) { GAState *s =3D opaque; - QDict *rsp; int ret; =20 g_debug("process_event: called"); assert(!obj !=3D !err); - if (err) { - rsp =3D qmp_error_response(err); - goto end; - } =20 - g_debug("processing command"); - rsp =3D qmp_dispatch(&s->session, obj, false); + if (err) { + QDict *rsp =3D qmp_error_response(err); =20 -end: - ret =3D send_response(s, rsp); - if (ret < 0) { - g_warning("error sending error response: %s", strerror(-ret)); + ret =3D send_response(s, rsp); + if (ret < 0) { + g_warning("error sending error response: %s", strerror(-ret)); + } + qobject_unref(rsp); + } else { + g_debug("processing command"); + qmp_dispatch(&s->session, obj, false); } - qobject_unref(rsp); + qobject_unref(obj); } =20 @@ -1339,7 +1347,7 @@ static GAState *initialize_agent(GAConfig *config, in= t socket_activation) ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); json_message_parser_init(&s->parser, process_event, s, NULL); - qmp_session_init(&s->session, &ga_commands); + qmp_session_init(&s->session, &ga_commands, dispatch_return_cb); =20 #ifndef _WIN32 if (!register_signal_handlers()) { diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 962c2cb2e1..cca15e79ba 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -143,22 +143,23 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_q= emu_x_EnumList *a, return ret; } =20 +static void dispatch_cmd_return(QmpSession *session, QDict *resp) +{ + assert(resp !=3D NULL); + assert(!qdict_haskey(resp, "error")); +} =20 /* test commands with no input and no return value */ static void test_dispatch_cmd(void) { QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); - QDict *resp; =20 - qmp_session_init(&session, &qmp_commands); + qmp_session_init(&session, &qmp_commands, dispatch_cmd_return); qdict_put_str(req, "execute", "user_def_cmd"); =20 - resp =3D qmp_dispatch(&session, QOBJECT(req), false); - assert(resp !=3D NULL); - assert(!qdict_haskey(resp, "error")); + qmp_dispatch(&session, QOBJECT(req), false); =20 - qobject_unref(resp); qobject_unref(req); qmp_session_destroy(&session); } @@ -167,82 +168,80 @@ static void test_dispatch_cmd_oob(void) { QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); - QDict *resp; =20 - qmp_session_init(&session, &qmp_commands); + qmp_session_init(&session, &qmp_commands, dispatch_cmd_return); qdict_put_str(req, "exec-oob", "test-flags-command"); =20 - resp =3D qmp_dispatch(&session, QOBJECT(req), true); - assert(resp !=3D NULL); - assert(!qdict_haskey(resp, "error")); + qmp_dispatch(&session, QOBJECT(req), true); =20 - qobject_unref(resp); qobject_unref(req); qmp_session_destroy(&session); } =20 +static void dispatch_cmd_failure_return(QmpSession *session, QDict *resp) +{ + assert(resp !=3D NULL); + assert(qdict_haskey(resp, "error")); +} + /* test commands that return an error due to invalid parameters */ static void test_dispatch_cmd_failure(void) { QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); QDict *args =3D qdict_new(); - QDict *resp; =20 - qmp_session_init(&session, &qmp_commands); + qmp_session_init(&session, &qmp_commands, dispatch_cmd_failure_return); qdict_put_str(req, "execute", "user_def_cmd2"); =20 - resp =3D qmp_dispatch(&session, QOBJECT(req), false); - assert(resp !=3D NULL); - assert(qdict_haskey(resp, "error")); + qmp_dispatch(&session, QOBJECT(req), false); =20 - qobject_unref(resp); qobject_unref(req); =20 /* check that with extra arguments it throws an error */ req =3D qdict_new(); qdict_put_int(args, "a", 66); qdict_put(req, "arguments", args); - qdict_put_str(req, "execute", "user_def_cmd"); =20 - resp =3D qmp_dispatch(&session, QOBJECT(req), false); - assert(resp !=3D NULL); - assert(qdict_haskey(resp, "error")); + qmp_dispatch(&session, QOBJECT(req), false); =20 - qobject_unref(resp); qobject_unref(req); qmp_session_destroy(&session); } =20 +static QObject *dispatch_ret; + static void test_dispatch_cmd_success_response(void) { QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); - QDict *resp; =20 - qmp_session_init(&session, &qmp_commands); + qmp_session_init(&session, &qmp_commands, (QmpDispatchReturn *)abort); qdict_put_str(req, "execute", "cmd-success-response"); - resp =3D qmp_dispatch(&session, QOBJECT(req), false); - g_assert_null(resp); + + qmp_dispatch(&session, QOBJECT(req), false); + qobject_unref(req); qmp_session_destroy(&session); } =20 +static void dispatch_return(QmpSession *session, QDict *resp) +{ + assert(resp && !qdict_haskey(resp, "error")); + dispatch_ret =3D qdict_get(resp, "return"); + qobject_ref(dispatch_ret); +} =20 static QObject *test_qmp_dispatch(QDict *req) { QmpSession session =3D { 0, }; - QDict *resp; QObject *ret; =20 - qmp_session_init(&session, &qmp_commands); - resp =3D qmp_dispatch(&session, QOBJECT(req), false); - assert(resp && !qdict_haskey(resp, "error")); - ret =3D qdict_get(resp, "return"); - assert(ret); - qobject_ref(ret); - qobject_unref(resp); + qmp_session_init(&session, &qmp_commands, dispatch_return); + qmp_dispatch(&session, QOBJECT(req), false); + ret =3D dispatch_ret; + dispatch_ret =3D NULL; qmp_session_destroy(&session); return ret; } --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225628; cv=none; d=zoho.com; s=zohoarc; b=dCDIFCgx5ATrt4DFX7VaK57zFxzdogiR1Hh3aqeT7sAtuVEAQ1PwDc+EwwweDTLwQYLSV5RiStWquI/2X0WtGgqRMIy8D91+tqh429eHbiR+MXhXCLZVscdNuIWfgqOCO0c7Z40ewhtcTbW+4xwn8Yo82tMsBkD1GcU8XwvL4+s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225628; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=e1yDkbX9kSrQE2esR1pQgQNkZhwENHxRrNgX62Wk9qo=; b=l0j7qNW5grm9s8EhLGpi0G8K0PveAigA6RkEEbHFRad+sukkPrGMsNPxkj9Uw7fz9Rh9CA2d+jseRZNbx0QXNT2R4xsTG2MzulTCbQXQ2DH/d4dHt/C4BZQumbJpmvF/ovMNU51kFY4JkUbdiQdFeC/8nGdnFmmny4qooueXX74= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157322562860689.807409138553; Fri, 8 Nov 2019 07:07:08 -0800 (PST) Received: from localhost ([::1]:55908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qt-0007lL-CZ for importer@patchew.org; Fri, 08 Nov 2019 10:07:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46171) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5mj-0003Cd-DL for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5mi-0003o2-1I for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:49 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:49936 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5mg-0003nG-2v for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:46 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-283-LzGJj93WOm6s5V5vro0rcg-1; Fri, 08 Nov 2019 10:02:43 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CF4778017DD for ; Fri, 8 Nov 2019 15:02:42 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 202A65C1BB; Fri, 8 Nov 2019 15:02:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225364; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=e1yDkbX9kSrQE2esR1pQgQNkZhwENHxRrNgX62Wk9qo=; b=MXIiUya/MPD2Ez2ZMO3WRgSUVGJrGMj9oeAV2dc1fDGh2U6QlROkmBsw3yScmtxyc0HrDx jEy6MP1v17zsv4YMPll0Z9RWLcAW8Ddt5FyoXL3NqKkIX6ae2lCeyoCb9fhlvMmJxDyP/A EHaR0pusZ/Z35NiNuk/9v4WQnnU206I= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 05/25] QmpSession: add json parser and use it in qga Date: Fri, 8 Nov 2019 19:01:03 +0400 Message-Id: <20191108150123.12213-6-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: LzGJj93WOm6s5V5vro0rcg-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Move JSON parser to QmpSession, and implement a simple handler to check the parsed tokens and call qmp_dispatch(). This is enough for a simple QMP client, like QGA. The QEMU monitor has more complicated handling of dispatching which will be addressed in a following patch to benefit from more common code. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 7 +++++++ qapi/qmp-dispatch.c | 19 +++++++++++++++++++ qga/main.c | 31 +------------------------------ 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index d1ce631a93..c84edff7d2 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -15,6 +15,7 @@ #define QAPI_QMP_DISPATCH_H =20 #include "qemu/queue.h" +#include "qapi/qmp/json-parser.h" =20 typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); =20 @@ -42,6 +43,7 @@ typedef void (QmpDispatchReturn) (QmpSession *session, QD= ict *rsp); =20 struct QmpSession { const QmpCommandList *cmds; + JSONMessageParser parser; QmpDispatchReturn *return_cb; }; =20 @@ -52,6 +54,11 @@ const QmpCommand *qmp_find_command(const QmpCommandList = *cmds, void qmp_session_init(QmpSession *session, const QmpCommandList *cmds, QmpDispatchReturn *return_cb); +static inline void +qmp_session_feed(QmpSession *session, const char *buf, size_t count) +{ + json_message_parser_feed(&session->parser, buf, count); +} void qmp_session_destroy(QmpSession *session); void qmp_disable_command(QmpCommandList *cmds, const char *name); void qmp_enable_command(QmpCommandList *cmds, const char *name); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 1314f4929f..f8c491924d 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -164,6 +164,23 @@ bool qmp_is_oob(const QDict *dict) && !qdict_haskey(dict, "execute"); } =20 +static void qmp_json_emit(void *opaque, QObject *obj, Error *err) +{ + QmpSession *session =3D opaque; + + assert(!obj !=3D !err); + + if (err) { + QDict *rsp =3D qmp_error_response(err); + session->return_cb(session, rsp); + qobject_unref(rsp); + } else { + qmp_dispatch(session, obj, false); + } + + qobject_unref(obj); +} + void qmp_session_init(QmpSession *session, const QmpCommandList *cmds, QmpDispatchReturn *return_cb) @@ -171,6 +188,7 @@ void qmp_session_init(QmpSession *session, assert(return_cb); assert(!session->return_cb); =20 + json_message_parser_init(&session->parser, qmp_json_emit, session, NUL= L); session->cmds =3D cmds; session->return_cb =3D return_cb; } @@ -183,6 +201,7 @@ void qmp_session_destroy(QmpSession *session) =20 session->cmds =3D NULL; session->return_cb =3D NULL; + json_message_parser_destroy(&session->parser); } =20 void qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob) diff --git a/qga/main.c b/qga/main.c index c291d06491..057368eb16 100644 --- a/qga/main.c +++ b/qga/main.c @@ -19,7 +19,6 @@ #include #endif #include "qemu-common.h" -#include "qapi/qmp/json-parser.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" #include "qapi/qmp/qstring.h" @@ -75,7 +74,6 @@ typedef struct GAConfig GAConfig; =20 struct GAState { QmpSession session; - JSONMessageParser parser; GMainLoop *main_loop; GAChannel *channel; bool virtio; /* fastpath to check for virtio to deal with poll() quirk= s */ @@ -567,31 +565,6 @@ static void dispatch_return_cb(QmpSession *session, QD= ict *rsp) } } =20 -/* handle requests/control events coming in over the channel */ -static void process_event(void *opaque, QObject *obj, Error *err) -{ - GAState *s =3D opaque; - int ret; - - g_debug("process_event: called"); - assert(!obj !=3D !err); - - if (err) { - QDict *rsp =3D qmp_error_response(err); - - ret =3D send_response(s, rsp); - if (ret < 0) { - g_warning("error sending error response: %s", strerror(-ret)); - } - qobject_unref(rsp); - } else { - g_debug("processing command"); - qmp_dispatch(&s->session, obj, false); - } - - qobject_unref(obj); -} - /* false return signals GAChannel to close the current client connection */ static gboolean channel_event_cb(GIOCondition condition, gpointer data) { @@ -607,7 +580,7 @@ static gboolean channel_event_cb(GIOCondition condition= , gpointer data) case G_IO_STATUS_NORMAL: buf[count] =3D 0; g_debug("read data, count: %d, data: %s", (int)count, buf); - json_message_parser_feed(&s->parser, (char *)buf, (int)count); + qmp_session_feed(&s->session, (char *)buf, (int)count); break; case G_IO_STATUS_EOF: g_debug("received EOF"); @@ -1346,7 +1319,6 @@ static GAState *initialize_agent(GAConfig *config, in= t socket_activation) s->command_state =3D ga_command_state_new(); ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); - json_message_parser_init(&s->parser, process_event, s, NULL); qmp_session_init(&s->session, &ga_commands, dispatch_return_cb); =20 #ifndef _WIN32 @@ -1382,7 +1354,6 @@ static void cleanup_agent(GAState *s) qmp_session_destroy(&s->session); ga_command_state_cleanup_all(s->command_state); ga_command_state_free(s->command_state); - json_message_parser_destroy(&s->parser); } g_free(s->pstate_filepath); g_free(s->state_filepath_isfrozen); --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225547; cv=none; d=zoho.com; s=zohoarc; b=THJ/iRF3F07u/gGBo/eN7i/oIf6r+ktRHVXyClfVSNv0NR91u9C6y5l95a14rbvSonze0ht9asUx+ptjmv1vc2fBr60o1UpzaG9jG0CNpBKvj5jTUhHA2gXsZrwggJgiuetfh2KNTue7oeTkjYjCTn4Ii0nyJBJGJRXlrB70D/g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225547; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Q1Q4UMSoZSlz6+5iKyAOerNgelL9ZOigeHM/bJLClc4=; b=UnaG89KxDwXYzDcDZL88RoEUOG5h09P8/c7XIQDoygPkoKL2psY4W0Ix1sV+Dqe50eNMMehYzpv2zPycbVa5F1mQXOMCn1ndIgR2ZfB8KvIsd5in26xXYGpuak5L98zo6ikudJgBAYNTc7+EKEBAxvAuNx++LxxzYra2sLpAV5A= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225547488744.924438719366; Fri, 8 Nov 2019 07:05:47 -0800 (PST) Received: from localhost ([::1]:55878 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5pa-0005WW-1s for importer@patchew.org; Fri, 08 Nov 2019 10:05:46 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46194) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5mt-0003PX-Ul for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5ms-0003rS-Ap for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:59 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:57130 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5ms-0003rK-7F for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:02:58 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-99-vJUwHQDvMV6MZxD6_cHMtw-1; Fri, 08 Nov 2019 10:02:56 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C8138180496F for ; Fri, 8 Nov 2019 15:02:55 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8D0F05DA7F; Fri, 8 Nov 2019 15:02:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225377; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q1Q4UMSoZSlz6+5iKyAOerNgelL9ZOigeHM/bJLClc4=; b=W48h9ZUh1RlALPZ1Ss8B8Xu0QKMuWL3zmhRJuwxTo22tUgxipMSXMF39wg700fOGvLUV9T g3QO8Acbq/qpPC+x5zMGdkmBl+jWozTwpb6rBfeDZ0HrarHCaqrE9kyrlZHXK9MHPlY/6L 4xV4q8hcHNtF356f72B/9FgbIvVTZTM= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 06/25] monitor: use qmp session to parse json feed Date: Fri, 8 Nov 2019 19:01:04 +0400 Message-Id: <20191108150123.12213-7-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-MC-Unique: vJUwHQDvMV6MZxD6_cHMtw-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Use the QmpSession json parser introduced in previous patch to generalize the handling in both qemu & qemu-ga. Unfortunately, since the introduction of OOB, it's not as common as it was before that. We may want to move some of OOB logic in common qmp-dispatch.c/QmpSession though. The QEMU monitor has peculiar handling of the stream of commands, for OOB command processing, which can be solved by overriding the json emit callback. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 1 + include/qapi/qmp/json-parser.h | 7 ++++--- monitor/monitor-internal.h | 1 - monitor/qmp.c | 13 +++++-------- qapi/qmp-dispatch.c | 4 +++- qga/main.c | 2 +- qobject/json-streamer.c | 3 +-- tests/test-qmp-cmds.c | 11 ++++++----- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index c84edff7d2..b3ca6c9ff2 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -53,6 +53,7 @@ const QmpCommand *qmp_find_command(const QmpCommandList *= cmds, const char *name); void qmp_session_init(QmpSession *session, const QmpCommandList *cmds, + JSONMessageEmit *emit, QmpDispatchReturn *return_cb); static inline void qmp_session_feed(QmpSession *session, const char *buf, size_t count) diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h index 7345a9bd5c..6f168e8007 100644 --- a/include/qapi/qmp/json-parser.h +++ b/include/qapi/qmp/json-parser.h @@ -14,6 +14,8 @@ #ifndef QAPI_QMP_JSON_PARSER_H #define QAPI_QMP_JSON_PARSER_H =20 +typedef void (JSONMessageEmit)(void *opaque, QObject *json, Error *err); + typedef struct JSONLexer { int start_state, state; GString *token; @@ -21,7 +23,7 @@ typedef struct JSONLexer { } JSONLexer; =20 typedef struct JSONMessageParser { - void (*emit)(void *opaque, QObject *json, Error *err); + JSONMessageEmit *emit; void *opaque; va_list *ap; JSONLexer lexer; @@ -32,8 +34,7 @@ typedef struct JSONMessageParser { } JSONMessageParser; =20 void json_message_parser_init(JSONMessageParser *parser, - void (*emit)(void *opaque, QObject *json, - Error *err), + JSONMessageEmit *emit, void *opaque, va_list *ap); =20 void json_message_parser_feed(JSONMessageParser *parser, diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index b15266e77b..b8994f896a 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -124,7 +124,6 @@ struct MonitorHMP { =20 typedef struct { Monitor common; - JSONMessageParser parser; bool pretty; /* * When a client connects, we're in capabilities negotiation mode. diff --git a/monitor/qmp.c b/monitor/qmp.c index b215cb70f3..cd29494e28 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -217,7 +217,7 @@ void monitor_qmp_bh_dispatcher(void *data) =20 static void handle_qmp_command(void *opaque, QObject *req, Error *err) { - MonitorQMP *mon =3D opaque; + MonitorQMP *mon =3D container_of(opaque, MonitorQMP, session); QObject *id =3D NULL; QDict *qdict; QMPRequest *req_obj; @@ -279,7 +279,7 @@ static void monitor_qmp_read(void *opaque, const uint8_= t *buf, int size) { MonitorQMP *mon =3D opaque; =20 - json_message_parser_feed(&mon->parser, (const char *) buf, size); + qmp_session_feed(&mon->session, (const char *) buf, size); } =20 static QDict *qmp_greeting(MonitorQMP *mon) @@ -309,7 +309,9 @@ static void monitor_qmp_event(void *opaque, int event) switch (event) { case CHR_EVENT_OPENED: qmp_session_init(&mon->session, - &qmp_cap_negotiation_commands, dispatch_return_cb= ); + &qmp_cap_negotiation_commands, + handle_qmp_command, + dispatch_return_cb); monitor_qmp_caps_reset(mon); data =3D qmp_greeting(mon); qmp_send_response(mon, data); @@ -325,9 +327,6 @@ static void monitor_qmp_event(void *opaque, int event) */ monitor_qmp_cleanup_queues(mon); qmp_session_destroy(&mon->session); - json_message_parser_destroy(&mon->parser); - json_message_parser_init(&mon->parser, handle_qmp_command, - mon, NULL); mon_refcount--; monitor_fdsets_cleanup(); break; @@ -337,7 +336,6 @@ static void monitor_qmp_event(void *opaque, int event) void monitor_data_destroy_qmp(MonitorQMP *mon) { qmp_session_destroy(&mon->session); - json_message_parser_destroy(&mon->parser); qemu_mutex_destroy(&mon->qmp_queue_lock); monitor_qmp_cleanup_req_queue_locked(mon); g_queue_free(mon->qmp_requests); @@ -373,7 +371,6 @@ void monitor_init_qmp(Chardev *chr, bool pretty) qemu_chr_fe_init(&mon->common.chr, chr, &error_abort); qemu_chr_fe_set_echo(&mon->common.chr, true); =20 - json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL); if (mon->common.use_io_thread) { /* * Make sure the old iowatch is gone. It's possible when diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index f8c491924d..b004d7506f 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -183,12 +183,14 @@ static void qmp_json_emit(void *opaque, QObject *obj,= Error *err) =20 void qmp_session_init(QmpSession *session, const QmpCommandList *cmds, + JSONMessageEmit *emit, QmpDispatchReturn *return_cb) { assert(return_cb); assert(!session->return_cb); =20 - json_message_parser_init(&session->parser, qmp_json_emit, session, NUL= L); + json_message_parser_init(&session->parser, emit ?: qmp_json_emit, + session, NULL); session->cmds =3D cmds; session->return_cb =3D return_cb; } diff --git a/qga/main.c b/qga/main.c index 057368eb16..b005550c70 100644 --- a/qga/main.c +++ b/qga/main.c @@ -1319,7 +1319,7 @@ static GAState *initialize_agent(GAConfig *config, in= t socket_activation) s->command_state =3D ga_command_state_new(); ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); - qmp_session_init(&s->session, &ga_commands, dispatch_return_cb); + qmp_session_init(&s->session, &ga_commands, NULL, dispatch_return_cb); =20 #ifndef _WIN32 if (!register_signal_handlers()) { diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c index 47dd7ea576..2a440f2a9e 100644 --- a/qobject/json-streamer.c +++ b/qobject/json-streamer.c @@ -100,8 +100,7 @@ out_emit: } =20 void json_message_parser_init(JSONMessageParser *parser, - void (*emit)(void *opaque, QObject *json, - Error *err), + JSONMessageEmit *emit, void *opaque, va_list *ap) { parser->emit =3D emit; diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index cca15e79ba..d9623d10b6 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -155,7 +155,7 @@ static void test_dispatch_cmd(void) QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); =20 - qmp_session_init(&session, &qmp_commands, dispatch_cmd_return); + qmp_session_init(&session, &qmp_commands, NULL, dispatch_cmd_return); qdict_put_str(req, "execute", "user_def_cmd"); =20 qmp_dispatch(&session, QOBJECT(req), false); @@ -169,7 +169,7 @@ static void test_dispatch_cmd_oob(void) QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); =20 - qmp_session_init(&session, &qmp_commands, dispatch_cmd_return); + qmp_session_init(&session, &qmp_commands, NULL, dispatch_cmd_return); qdict_put_str(req, "exec-oob", "test-flags-command"); =20 qmp_dispatch(&session, QOBJECT(req), true); @@ -191,7 +191,8 @@ static void test_dispatch_cmd_failure(void) QDict *req =3D qdict_new(); QDict *args =3D qdict_new(); =20 - qmp_session_init(&session, &qmp_commands, dispatch_cmd_failure_return); + qmp_session_init(&session, &qmp_commands, NULL, + dispatch_cmd_failure_return); qdict_put_str(req, "execute", "user_def_cmd2"); =20 qmp_dispatch(&session, QOBJECT(req), false); @@ -217,7 +218,7 @@ static void test_dispatch_cmd_success_response(void) QmpSession session =3D { 0, }; QDict *req =3D qdict_new(); =20 - qmp_session_init(&session, &qmp_commands, (QmpDispatchReturn *)abort); + qmp_session_init(&session, &qmp_commands, NULL, (QmpDispatchReturn *)a= bort); qdict_put_str(req, "execute", "cmd-success-response"); =20 qmp_dispatch(&session, QOBJECT(req), false); @@ -238,7 +239,7 @@ static QObject *test_qmp_dispatch(QDict *req) QmpSession session =3D { 0, }; QObject *ret; =20 - qmp_session_init(&session, &qmp_commands, dispatch_return); + qmp_session_init(&session, &qmp_commands, NULL, dispatch_return); qmp_dispatch(&session, QOBJECT(req), false); ret =3D dispatch_ret; dispatch_ret =3D NULL; --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226015; cv=none; d=zoho.com; s=zohoarc; b=YBga9mKBzwvdi7oSkAvns5hTA3fIurS402YZX7sUOJfygYfn9RSgZJLlx9e6W4hVmZ2UJsXA9BSl0+AE19DSbYXtKgs/nyoZn37QLHfSeMW0eMWI0csyj5AXyXxV8k1OjfopDzNQ0g7zYFnN10Mm27NZKFRys/0+6ICyLqgj7sI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226015; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Nunur+v8C6yUd2Ig0aPCWyll3+RfwG+OyCvKxZXgQ6w=; b=DghoGRb0rCew1GrnmEQeaEeS++Vp2UeghIYA6CKnu9p7d504b04cNqY2ntpyd+0oKt0cinZy0h8SNgNcZVR7xDdmWhJ8UXnCpz2+cJJDgBVSMOJnh33DFi8jjNu7JuZgx09E01FadvfFGGydBjIfjKprcNBiGDOXsfyP+5zbwFY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226015706569.2942700040991; Fri, 8 Nov 2019 07:13:35 -0800 (PST) Received: from localhost ([::1]:55980 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5x8-0007Ra-4V for importer@patchew.org; Fri, 08 Nov 2019 10:13:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46242) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5nD-0003mf-N3 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5nA-00044J-Qp for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:19 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:26661 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5nA-00042v-Ke for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:16 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-114-FaHNDH-QMOS0q3r8iX7A9g-1; Fri, 08 Nov 2019 10:03:14 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 648D2180496F for ; Fri, 8 Nov 2019 15:03:13 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6EC505C1BB; Fri, 8 Nov 2019 15:03:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Nunur+v8C6yUd2Ig0aPCWyll3+RfwG+OyCvKxZXgQ6w=; b=CI5XVGQ5/QqN/gx2RlfVvJGQpuzq5ynAs6lBnE3SxGd55rG6pycSRxSIrhH6RR/uWB7qJ/ fPV9erCwM/jzYEzVBI0Kzzcv3VdwnmsflxNiqpdQpOyDBOXWU7E/F8FCBK40mRPaHi4UP6 k6l01PcjdZA3lXCitT7QdRgA6uM3b6o= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 07/25] qga: simplify dispatch_return_cb Date: Fri, 8 Nov 2019 19:01:05 +0400 Message-Id: <20191108150123.12213-8-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: FaHNDH-QMOS0q3r8iX7A9g-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Fold send_response(). qobject_to_json() can't return NULL (it will crash if allocation failed, either in memcpy() or abort from g_realloc()). Signed-off-by: Marc-Andr=C3=A9 Lureau --- qga/main.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/qga/main.c b/qga/main.c index b005550c70..66fe7ac3de 100644 --- a/qga/main.c +++ b/qga/main.c @@ -522,8 +522,9 @@ fail: #endif } =20 -static int send_response(GAState *s, const QDict *rsp) +static void dispatch_return_cb(QmpSession *session, QDict *rsp) { + GAState *s =3D container_of(session, GAState, session); const char *buf; QString *payload_qstr, *response_qstr; GIOStatus status; @@ -531,9 +532,6 @@ static int send_response(GAState *s, const QDict *rsp) g_assert(rsp && s->channel); =20 payload_qstr =3D qobject_to_json(QOBJECT(rsp)); - if (!payload_qstr) { - return -EINVAL; - } =20 if (s->delimit_response) { s->delimit_response =3D false; @@ -550,18 +548,7 @@ static int send_response(GAState *s, const QDict *rsp) status =3D ga_channel_write_all(s->channel, buf, strlen(buf)); qobject_unref(response_qstr); if (status !=3D G_IO_STATUS_NORMAL) { - return -EIO; - } - - return 0; -} - -static void dispatch_return_cb(QmpSession *session, QDict *rsp) -{ - GAState *s =3D container_of(session, GAState, session); - int ret =3D send_response(s, rsp); - if (ret < 0) { - g_warning("error sending response: %s", strerror(-ret)); + g_warning("Failed sending response"); } } =20 --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225704; cv=none; d=zoho.com; s=zohoarc; b=D8hldpEECdu7viyTpJuEVAjJ+vqahiWRuXVQ7loIL6oVsRQF4TR2g69X1kI3qSHf7C+0lwpfpelSMzRxIWYdq1CtBvdUaY9y3Y49Om9HXE4IYuhKQKfwCaWpdm25YNBZZhcwrQ8rJalgqZakwfzslkpoRw466ibcNcDCExj4A8g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225704; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=g22iItwlMApoL+VpbZVGZPNFEpy+0XtGmVHDjP7V2QM=; b=g3OI99CWJL2AvMxYvgn9U3rmU/nhtIikq7t5o51KWCPhFK/8vl+b9j5n66UEOjl26SKOqfQP9ybC6rKjCAej/ipzEWgO19PX/HvlixOwjjyQ9pbfaK4YhBu1NysRL+UE6QHbqGPfQ+fgEtYmEL2/VxFkrLqfqF/CygD3f7euZ3g= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225704715551.8946124007114; Fri, 8 Nov 2019 07:08:24 -0800 (PST) Received: from localhost ([::1]:55926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5s7-0000tw-5f for importer@patchew.org; Fri, 08 Nov 2019 10:08:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46337) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5nO-0003wv-Mo for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5nN-0004JT-1S for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:30 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:36158 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5nM-0004J7-Tk for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:28 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-159-YEJcvzrhO9WSj3E5UJYoJQ-1; Fri, 08 Nov 2019 10:03:27 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7105E1804971 for ; Fri, 8 Nov 2019 15:03:26 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id BC86F600C9; Fri, 8 Nov 2019 15:03:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225408; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g22iItwlMApoL+VpbZVGZPNFEpy+0XtGmVHDjP7V2QM=; b=IWas4kgFCgxnqP6uAZ53dNwPFxdCEzA96/oML/hHei313ZRXNCsj/4mVhNCw+xxET1vzSO JfeGmnCOA7ej4rxBp7B+evkvSSuBOVK5nnB5VFzQMJZvGeTsRnzVrL6k3WUUx9Qiiew/0x zEld6R2Hlcpqp5Eb3kAgwbKI8lRZwbw= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 08/25] QmpSession: introduce QmpReturn Date: Fri, 8 Nov 2019 19:01:06 +0400 Message-Id: <20191108150123.12213-9-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: YEJcvzrhO9WSj3E5UJYoJQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" QmpReturn (and associated functions) is used during synchronous dispatch return for now. It helps to factor out some code for handling a reply context. In the following patches, the QmpReturn will be the basis upon which asynchronous reply will be handled: it will hold the context for a QMP command reply. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 34 ++++++++++++++++- monitor/qmp.c | 6 +-- qapi/qmp-dispatch.c | 74 ++++++++++++++++++++++--------------- 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index b3ca6c9ff2..6c0d21968e 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -17,6 +17,8 @@ #include "qemu/queue.h" #include "qapi/qmp/json-parser.h" =20 +typedef struct QmpReturn QmpReturn; + typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); =20 typedef enum QmpCommandOptions @@ -47,6 +49,37 @@ struct QmpSession { QmpDispatchReturn *return_cb; }; =20 +struct QmpReturn { + QmpSession *session; + QDict *rsp; +}; + +/** + * qmp_return_new: + * + * Allocates and initializes a QmpReturn. + */ +QmpReturn *qmp_return_new(QmpSession *session, const QObject *req); + +/** + * qmp_return_free: + * + * Free a QmpReturn. This shouldn't be needed if you actually return + * with qmp_return{_error}. + */ +void qmp_return_free(QmpReturn *qret); + +/** + * qmp_return{_error}: + * + * Construct the command reply, and call the + * return_cb() associated with the session. + * + * Finally, free the QmpReturn. + */ +void qmp_return(QmpReturn *qret, QObject *rsp); +void qmp_return_error(QmpReturn *qret, Error *err); + void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); const QmpCommand *qmp_find_command(const QmpCommandList *cmds, @@ -67,7 +100,6 @@ void qmp_enable_command(QmpCommandList *cmds, const char= *name); bool qmp_command_is_enabled(const QmpCommand *cmd); const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); -QDict *qmp_error_response(Error *err); void qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob); bool qmp_is_oob(const QDict *dict); diff --git a/monitor/qmp.c b/monitor/qmp.c index cd29494e28..056ad7b68b 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -179,7 +179,6 @@ static QMPRequest *monitor_qmp_requests_pop_any_with_lo= ck(void) void monitor_qmp_bh_dispatcher(void *data) { QMPRequest *req_obj =3D monitor_qmp_requests_pop_any_with_lock(); - QDict *rsp; bool need_resume; MonitorQMP *mon; =20 @@ -198,11 +197,10 @@ void monitor_qmp_bh_dispatcher(void *data) trace_monitor_qmp_cmd_in_band(qobject_get_try_str(id) ?: ""); monitor_qmp_dispatch(mon, req_obj->req); } else { + QmpSession *session =3D &req_obj->mon->session; assert(req_obj->err); - rsp =3D qmp_error_response(req_obj->err); + qmp_return_error(qmp_return_new(session, req_obj->req), req_obj->e= rr); req_obj->err =3D NULL; - qmp_send_response(req_obj->mon, rsp); - qobject_unref(rsp); } =20 if (need_resume) { diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index b004d7506f..188b5680b6 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -19,6 +19,46 @@ #include "sysemu/runstate.h" #include "qapi/qmp/qbool.h" =20 +QmpReturn *qmp_return_new(QmpSession *session, const QObject *request) +{ + QmpReturn *qret =3D g_new0(QmpReturn, 1); + const QDict *req =3D qobject_to(QDict, request); + QObject *id =3D req ? qdict_get(req, "id") : NULL; + + qret->session =3D session; + qret->rsp =3D qdict_new(); + if (id) { + qobject_ref(id); + qdict_put_obj(qret->rsp, "id", id); + } + + return qret; +} + +void qmp_return_free(QmpReturn *qret) +{ + qobject_unref(qret->rsp); + g_free(qret); +} + +void qmp_return(QmpReturn *qret, QObject *rsp) +{ + qdict_put_obj(qret->rsp, "return", rsp ?: QOBJECT(qdict_new())); + qret->session->return_cb(qret->session, qret->rsp); + qmp_return_free(qret); +} + +void qmp_return_error(QmpReturn *qret, Error *err) +{ + qdict_put_obj(qret->rsp, "error", + qobject_from_jsonf_nofail("{ 'class': %s, 'desc': %s }", + QapiErrorClass_str(error_get_class(err)), + error_get_pretty(err))); + error_free(err); + qret->session->return_cb(qret->session, qret->rsp); + qmp_return_free(qret); +} + static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oo= b, Error **errp) { @@ -144,17 +184,6 @@ static QObject *do_qmp_dispatch(const QmpCommandList *= cmds, QObject *request, return ret; } =20 -QDict *qmp_error_response(Error *err) -{ - QDict *rsp; - - rsp =3D qdict_from_jsonf_nofail("{ 'error': { 'class': %s, 'desc': %s = } }", - QapiErrorClass_str(error_get_class(err)), - error_get_pretty(err)); - error_free(err); - return rsp; -} - /* * Does @qdict look like a command to be run out-of-band? */ @@ -171,9 +200,7 @@ static void qmp_json_emit(void *opaque, QObject *obj, E= rror *err) assert(!obj !=3D !err); =20 if (err) { - QDict *rsp =3D qmp_error_response(err); - session->return_cb(session, rsp); - qobject_unref(rsp); + qmp_return_error(qmp_return_new(session, obj), err); } else { qmp_dispatch(session, obj, false); } @@ -209,25 +236,12 @@ void qmp_session_destroy(QmpSession *session) void qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob) { Error *err =3D NULL; - QDict *dict =3D qobject_to(QDict, request); - QObject *ret, *id =3D dict ? qdict_get(dict, "id") : NULL; - QDict *rsp; + QObject *ret; =20 ret =3D do_qmp_dispatch(session->cmds, request, allow_oob, &err); if (err) { - rsp =3D qmp_error_response(err); + qmp_return_error(qmp_return_new(session, request), err); } else if (ret) { - rsp =3D qdict_new(); - qdict_put_obj(rsp, "return", ret); - } else { - /* Can only happen for commands with QCO_NO_SUCCESS_RESP */ - return; + qmp_return(qmp_return_new(session, request), ret); } - - if (id) { - qdict_put_obj(rsp, "id", qobject_ref(id)); - } - - session->return_cb(session, rsp); - qobject_unref(rsp); } --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226260; cv=none; d=zoho.com; s=zohoarc; b=foeVTOmk7Y994BOvkYgMU1afuEP98qElUYhNfCLXcVUbGLu2MiLlY+HH1JLE166vv+ALHOX0zN9rBmupxOO11RUNlxJ9Z/a3OxItIslsKfAgvn78emDEUyohrRyA1mel6Bw+dM4hNPBraYn5tPX81RyMlBkAiXprUa/QzGJ+se0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226260; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zvIOX9sTV8g3eSq1Z5naFU5517bwNh6zcozKMv6s9c0=; b=Dr5BhvRe39LW6qKd8Nc9wK5p7glLKMdR5O8wMQO2ANqfELoZdI1l7DML4jQ9ckemMDxnAJEAgir4+/8/3of+WOmBpl68ofn8PDGd6PRBFb6EFmqqFk92CQAjcC/dbTuom5i2jZoeSumDDdEo7T/RL4iziXlmCervmvMm+vt1qgY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226260538502.71082845124215; Fri, 8 Nov 2019 07:17:40 -0800 (PST) Received: from localhost ([::1]:56026 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT613-0002so-5G for importer@patchew.org; Fri, 08 Nov 2019 10:17:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46414) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5nd-0004Jz-Dp for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5nc-0004RF-Be for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:45 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:38876 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5nc-0004R5-6Y for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:44 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-387-nJi0IT7iMj-CQRu7_tJwsQ-1; Fri, 08 Nov 2019 10:03:42 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 93E32477 for ; Fri, 8 Nov 2019 15:03:41 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9F2DD5C1BB; Fri, 8 Nov 2019 15:03:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225423; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zvIOX9sTV8g3eSq1Z5naFU5517bwNh6zcozKMv6s9c0=; b=a0nGYUQl/zB3T6c4yTEIElVem2V3naygq2au+bPI1OjK0Hq2uqmvykTa5uBu6BmgI20O6D hMj8rJmmTboVB8IWCPDXwY3MbUym64+AF6G0QBAwzQV9tSfo7ctXe2a7dZLrDinkpfRVik NW049wsIohH1wB1KlQFMDyvZmUX2xrY= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 09/25] qmp: simplify qmp_return_error() Date: Fri, 8 Nov 2019 19:01:07 +0400 Message-Id: <20191108150123.12213-10-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: nJi0IT7iMj-CQRu7_tJwsQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" It's simple, probably more efficient, to hand-craft the dict. Signed-off-by: Marc-Andr=C3=A9 Lureau --- qapi/qmp-dispatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 188b5680b6..fcf6cb0bf8 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -50,10 +50,10 @@ void qmp_return(QmpReturn *qret, QObject *rsp) =20 void qmp_return_error(QmpReturn *qret, Error *err) { - qdict_put_obj(qret->rsp, "error", - qobject_from_jsonf_nofail("{ 'class': %s, 'desc': %s }", - QapiErrorClass_str(error_get_class(err)), - error_get_pretty(err))); + QDict *qdict =3D qdict_new(); + qdict_put_str(qdict, "class", QapiErrorClass_str(error_get_class(err))= ); + qdict_put_str(qdict, "desc", error_get_pretty(err)); + qdict_put_obj(qret->rsp, "error", QOBJECT(qdict)); error_free(err); qret->session->return_cb(qret->session, qret->rsp); qmp_return_free(qret); --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225864; cv=none; d=zoho.com; s=zohoarc; b=iIN2Rzhw2nbgxMenlChMBn2GKzxN93CRdEJ7M5PmWF7DYL0B6dVp5/zV4dXb8auH/ippSfTIilwDl+TVT+VXNVa/VfVe6NPC4/v8m2lPFbWYjZtE+Knn9n8TclZFwlEaSYkTa69HBRT5PCau9i3kzUpsryaMnhKV+a3psodX9QQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225864; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=tokP4vjSso+mNJQryUKg0EPaJ0vjrJNzrRiRGvfAkFI=; b=e4dSUCNoSl5LLcTAK/okgy9xganHfUo8i4xwqbqZgZY//kzNuveyE7YAhYa7tYpgT4lqj1uU2UwNlCgnrC8lkFRk2ycfhUqWAeBg5sIAUon0Zwl/DnIUWsvnriLMB4jde9M/PhxjN2nI3YHMilN+E55lP10pqHuYYMQAHjv8yEg= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225864207380.9119552930582; Fri, 8 Nov 2019 07:11:04 -0800 (PST) Received: from localhost ([::1]:55950 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5uf-0004Ir-8i for importer@patchew.org; Fri, 08 Nov 2019 10:11:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46441) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5nq-0004Rl-H3 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5no-0004ZT-LZ for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:58 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:45748 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5no-0004ZL-Hs for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:03:56 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-215-qe37uHoCO7yql5MqneRGJg-1; Fri, 08 Nov 2019 10:03:54 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C71E7180496F for ; Fri, 8 Nov 2019 15:03:53 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id E519060BE2; Fri, 8 Nov 2019 15:03:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225436; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tokP4vjSso+mNJQryUKg0EPaJ0vjrJNzrRiRGvfAkFI=; b=RwDVLt9dHEDvbUQKDDRXvEEAhX2g0rsUSxv9FDIvt9QAoavnegr3LgEykWpoNhzn6zp2S0 wOqnXrsWlxDzGAUt47BUpuSK7kXlQf1KI3lO0VHeEoBaVSZ28JbWVZaqG9qstIcNOX0DLD 2d3EjTmszHUF1mRu8H9ZUScqLzXHP1I= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 10/25] QmpSession: keep a queue of pending commands Date: Fri, 8 Nov 2019 19:01:08 +0400 Message-Id: <20191108150123.12213-11-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-MC-Unique: qe37uHoCO7yql5MqneRGJg-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" The following commit will introduce asynchronous commands. Let's keep the session aware of the pending commands, so we can do interesting things like order the replies, or cancel pending operations when the client is gone. The queue needs a lock, since QmpReturn may be called from any thread. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 4 ++++ qapi/qmp-dispatch.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 6c0d21968e..7c9de9780d 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -16,6 +16,7 @@ =20 #include "qemu/queue.h" #include "qapi/qmp/json-parser.h" +#include "qemu/thread.h" =20 typedef struct QmpReturn QmpReturn; =20 @@ -47,11 +48,14 @@ struct QmpSession { const QmpCommandList *cmds; JSONMessageParser parser; QmpDispatchReturn *return_cb; + QemuMutex pending_lock; + QTAILQ_HEAD(, QmpReturn) pending; }; =20 struct QmpReturn { QmpSession *session; QDict *rsp; + QTAILQ_ENTRY(QmpReturn) entry; }; =20 /** diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index fcf6cb0bf8..aed5c91057 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -32,11 +32,24 @@ QmpReturn *qmp_return_new(QmpSession *session, const QO= bject *request) qdict_put_obj(qret->rsp, "id", id); } =20 + qemu_mutex_lock(&session->pending_lock); + QTAILQ_INSERT_TAIL(&session->pending, qret, entry); + qemu_mutex_unlock(&session->pending_lock); + return qret; } =20 void qmp_return_free(QmpReturn *qret) { + QmpSession *session =3D qret->session; + + if (session) { + qemu_mutex_lock(&session->pending_lock); + } + QTAILQ_REMOVE(&session->pending, qret, entry); + if (session) { + qemu_mutex_unlock(&session->pending_lock); + } qobject_unref(qret->rsp); g_free(qret); } @@ -44,7 +57,9 @@ void qmp_return_free(QmpReturn *qret) void qmp_return(QmpReturn *qret, QObject *rsp) { qdict_put_obj(qret->rsp, "return", rsp ?: QOBJECT(qdict_new())); - qret->session->return_cb(qret->session, qret->rsp); + if (qret->session) { + qret->session->return_cb(qret->session, qret->rsp); + } qmp_return_free(qret); } =20 @@ -55,7 +70,9 @@ void qmp_return_error(QmpReturn *qret, Error *err) qdict_put_str(qdict, "desc", error_get_pretty(err)); qdict_put_obj(qret->rsp, "error", QOBJECT(qdict)); error_free(err); - qret->session->return_cb(qret->session, qret->rsp); + if (qret->session) { + qret->session->return_cb(qret->session, qret->rsp); + } qmp_return_free(qret); } =20 @@ -220,17 +237,28 @@ void qmp_session_init(QmpSession *session, session, NULL); session->cmds =3D cmds; session->return_cb =3D return_cb; + qemu_mutex_init(&session->pending_lock); + QTAILQ_INIT(&session->pending); } =20 void qmp_session_destroy(QmpSession *session) { + QmpReturn *ret, *next; + if (!session->return_cb) { return; } =20 + qemu_mutex_lock(&session->pending_lock); + QTAILQ_FOREACH_SAFE(ret, &session->pending, entry, next) { + ret->session =3D NULL; + QTAILQ_REMOVE(&session->pending, ret, entry); + } + qemu_mutex_unlock(&session->pending_lock); session->cmds =3D NULL; session->return_cb =3D NULL; json_message_parser_destroy(&session->parser); + qemu_mutex_destroy(&session->pending_lock); } =20 void qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob) --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226465; cv=none; d=zoho.com; s=zohoarc; b=GY3WAONyMxWwGysj9on6ubn4YdPpGt1qiDD0OoVRGYuhinYBO1M1uKsUKyL1JJj2TPubjP3sSLuFCI4GlqwmxCL7iEzMvIRTwBKgTD16uIVHqbJFdWVUOn87vvY6p7wjjHs1YzYSTn8SVyjT2xUTMJ8ip43br4E8ldfZJWl6qyg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226465; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zikJ2amcMtcp+zTObXzjfOccch34WImCsoPOE/0vrII=; b=jyCi+fMJUkCFQVtyVVrxp2I5IwdoAkXZAZE7ZJ+o+ZLyqAnIM0vblq8F/IL8MYg4MRXJLiPkiPFBAVauXAJ12uGdSEQLr3oK4zRD4BjnUxkWc1vvz2rWEX3Y7eQTKM0WPq6IcyYQ+G5Ad6ecSB8DQTBEJLlFplGRiqd64vijUI8= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157322646593447.15268492539337; Fri, 8 Nov 2019 07:21:05 -0800 (PST) Received: from localhost ([::1]:56080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT64N-0006eb-Qv for importer@patchew.org; Fri, 08 Nov 2019 10:21:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46462) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5o1-0004ht-0i for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5nz-0004mk-HR for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:08 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:53306 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5nz-0004mX-0i for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:07 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-20-xP5bygtFOMqhbk1Pe0FfNA-1; Fri, 08 Nov 2019 10:04:04 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 186ED8017DD for ; Fri, 8 Nov 2019 15:04:04 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 95BF85D6B7; Fri, 8 Nov 2019 15:03:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225446; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zikJ2amcMtcp+zTObXzjfOccch34WImCsoPOE/0vrII=; b=Pn/HBfOxpkDJN5nnjiB3V76OvknkMGuG8QZ7T5dNptHebRKHJ3jWaSYipGWKmOx+c+xRAK ihowhEGxegSxZkQdd0UJh0GyfZ3G1eA3zgyQnggbO1zbQxcEh1kRPA4Rf9JwpX5j4boUnq TX3xAe/N1RN1/Qx0+htVWEWWhsODiOA= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 11/25] QmpSession: return orderly Date: Fri, 8 Nov 2019 19:01:09 +0400 Message-Id: <20191108150123.12213-12-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-MC-Unique: xP5bygtFOMqhbk1Pe0FfNA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" QEMU will gain support for asynchronous commands, and may thus finish commands in various order. However, the clients expect replies in order. Let's enforce ordering of replies in QmpReturn: starting from the older command, process each pending QmpReturn, and return until reaching one that is unfinished. Or if the command is OOB, it should return immediately. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 2 ++ qapi/qmp-dispatch.c | 61 ++++++++++++++++++++++++++++++------- tests/test-qmp-cmds.c | 33 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 7c9de9780d..92d6fd1afb 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -55,6 +55,8 @@ struct QmpSession { struct QmpReturn { QmpSession *session; QDict *rsp; + bool oob; + bool finished; QTAILQ_ENTRY(QmpReturn) entry; }; =20 diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index aed5c91057..3eb7e4b610 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -25,6 +25,7 @@ QmpReturn *qmp_return_new(QmpSession *session, const QObj= ect *request) const QDict *req =3D qobject_to(QDict, request); QObject *id =3D req ? qdict_get(req, "id") : NULL; =20 + qret->oob =3D req ? qmp_is_oob(req) : false; qret->session =3D session; qret->rsp =3D qdict_new(); if (id) { @@ -39,6 +40,15 @@ QmpReturn *qmp_return_new(QmpSession *session, const QOb= ject *request) return qret; } =20 +static void qmp_return_free_with_lock(QmpReturn *qret) +{ + if (qret->session) { + QTAILQ_REMOVE(&qret->session->pending, qret, entry); + } + qobject_unref(qret->rsp); + g_free(qret); +} + void qmp_return_free(QmpReturn *qret) { QmpSession *session =3D qret->session; @@ -46,21 +56,53 @@ void qmp_return_free(QmpReturn *qret) if (session) { qemu_mutex_lock(&session->pending_lock); } - QTAILQ_REMOVE(&session->pending, qret, entry); + + qmp_return_free_with_lock(qret); + if (session) { qemu_mutex_unlock(&session->pending_lock); } - qobject_unref(qret->rsp); - g_free(qret); +} + +static void qmp_return_orderly(QmpReturn *qret) +{ + QmpSession *session =3D qret->session; + QmpReturn *ret, *next; + + if (!session) { + /* the session was destroyed before return, discard */ + qmp_return_free(qret); + return; + } + if (qret->oob) { + session->return_cb(session, qret->rsp); + qmp_return_free(qret); + return; + } + + qret->finished =3D true; + + qemu_mutex_lock(&session->pending_lock); + /* + * Process the list of pending and call return_cb until reaching + * an unfinished. + */ + QTAILQ_FOREACH_SAFE(ret, &session->pending, entry, next) { + if (!ret->finished) { + break; + } + session->return_cb(session, ret->rsp); + ret->session =3D session; + qmp_return_free_with_lock(ret); + } + + qemu_mutex_unlock(&session->pending_lock); } =20 void qmp_return(QmpReturn *qret, QObject *rsp) { qdict_put_obj(qret->rsp, "return", rsp ?: QOBJECT(qdict_new())); - if (qret->session) { - qret->session->return_cb(qret->session, qret->rsp); - } - qmp_return_free(qret); + qmp_return_orderly(qret); } =20 void qmp_return_error(QmpReturn *qret, Error *err) @@ -70,10 +112,7 @@ void qmp_return_error(QmpReturn *qret, Error *err) qdict_put_str(qdict, "desc", error_get_pretty(err)); qdict_put_obj(qret->rsp, "error", QOBJECT(qdict)); error_free(err); - if (qret->session) { - qret->session->return_cb(qret->session, qret->rsp); - } - qmp_return_free(qret); + qmp_return_orderly(qret); } =20 static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oo= b, diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index d9623d10b6..213df7e53a 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -361,6 +361,38 @@ static void test_dealloc_partial(void) qapi_free_UserDefTwo(ud2); } =20 +typedef struct QmpReturnOrderly { + QmpSession session; + int returns; +} QmpReturnOrderly; + +static void dispatch_return_orderly(QmpSession *session, QDict *resp) +{ + QmpReturnOrderly *o =3D container_of(session, QmpReturnOrderly, sessio= n); + + o->returns++; +} + +static void test_qmp_return_orderly(void) +{ + QDict *dict =3D qdict_new(); + QmpReturnOrderly o =3D { { 0 }, }; + QmpReturn *r1, *r2, *r3; + + qmp_session_init(&o.session, &qmp_commands, NULL, dispatch_return_orde= rly); + r1 =3D qmp_return_new(&o.session, NULL); + qdict_put_str(dict, "exec-oob", "test"); + r2 =3D qmp_return_new(&o.session, QOBJECT(dict)); + r3 =3D qmp_return_new(&o.session, NULL); + qmp_return(r3, NULL); + g_assert_cmpint(o.returns, =3D=3D, 0); + qmp_return(r2, NULL); + g_assert_cmpint(o.returns, =3D=3D, 1); + qmp_return(r1, NULL); + g_assert_cmpint(o.returns, =3D=3D, 3); + qmp_session_destroy(&o.session); + qobject_unref(dict); +} =20 int main(int argc, char **argv) { @@ -374,6 +406,7 @@ int main(int argc, char **argv) test_dispatch_cmd_success_response); g_test_add_func("/qmp/dealloc_types", test_dealloc_types); g_test_add_func("/qmp/dealloc_partial", test_dealloc_partial); + g_test_add_func("/qmp/return_orderly", test_qmp_return_orderly); =20 test_qmp_init_marshal(&qmp_commands); g_test_run(); --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225801; cv=none; d=zoho.com; s=zohoarc; b=EmWsp5mRQo68dmIjEnZDcMEk5eXCl1eqIQiGn1iT4ZTztm0NTS0f+3qSIxu9A5gq72eYfpdaS3yoW3uhGu37GFVGrXEKoAUhJ7EgRPMNrCn8qZVlcDEXjaf26fz+1zH/pWLhdvK+NjlC47DPEnMj5sMxE04LiGgLIDwsfyvVSgY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225801; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=qchnptFi058dP+AH94G/eZXd37hN440uraGqVjM2KYE=; b=ddofYtfbR9YegkYQp+3xP6O1CRq9vQPZV4l0hMj8q/35f2U9nn7X7hqr1xawraqKW/8INlIrfHxHgu7rUdP16Va6IOb/h65byMG1VovMgcWNbnA5tpH9Owvc3xGeDzUHxIEcaCjLvaPdEDrPYr9o6oqR+R9AlNuGYHUsTLUe45U= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225801309422.9584168286465; Fri, 8 Nov 2019 07:10:01 -0800 (PST) Received: from localhost ([::1]:55946 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5tg-00036a-3t for importer@patchew.org; Fri, 08 Nov 2019 10:10:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46493) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5oH-0004th-3a for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5oF-0004u4-BM for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:24 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:37175 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5oE-0004tF-1u for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:22 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-324-depKDAkFO_CFx_4sucFtuw-1; Fri, 08 Nov 2019 10:04:20 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 14252107ACC4 for ; Fri, 8 Nov 2019 15:04:19 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 388795C1BB; Fri, 8 Nov 2019 15:04:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225461; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qchnptFi058dP+AH94G/eZXd37hN440uraGqVjM2KYE=; b=PRbYFbMHAtVJyMQ0YpVOFq2H7oDjaESiaOex8SErkFVVIuP+zGSKVX8Y4P64X/UzEgAlVg U3BEvDWkLxmQnqUVzHQ6FbSivLQKcs/MGNww85YZaTPSRBQq2xyBDprTh4cQHR38IPeL/F 8P9p47uLisYD2Xed0VxL910xaAH9ch8= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 12/25] qmp: introduce asynchronous command type Date: Fri, 8 Nov 2019 19:01:10 +0400 Message-Id: <20191108150123.12213-13-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: depKDAkFO_CFx_4sucFtuw-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Add a new type of command, QmpCommandFuncAsync: those commands can return later thanks to QmpReturn. This commit introduces the new type and register function and teach qmp_dipatch() to call it without qmp_return(). The async_fn callback will be responsible for calling qmp_return(), either synchronously or asynchronously. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 10 +++++++++- qapi/qmp-dispatch.c | 27 ++++++++++++++++----------- qapi/qmp-registry.c | 27 ++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 92d6fd1afb..6aef0abc70 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -21,6 +21,7 @@ typedef struct QmpReturn QmpReturn; =20 typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); +typedef void (QmpCommandAsyncFunc)(QDict *, QmpReturn *); =20 typedef enum QmpCommandOptions { @@ -28,12 +29,16 @@ typedef enum QmpCommandOptions QCO_NO_SUCCESS_RESP =3D (1U << 0), QCO_ALLOW_OOB =3D (1U << 1), QCO_ALLOW_PRECONFIG =3D (1U << 2), + QCO_ASYNC =3D (1U << 3), } QmpCommandOptions; =20 typedef struct QmpCommand { const char *name; - QmpCommandFunc *fn; + union { + QmpCommandFunc *fn; + QmpCommandAsyncFunc *async_fn; + }; QmpCommandOptions options; QTAILQ_ENTRY(QmpCommand) node; bool enabled; @@ -88,6 +93,9 @@ void qmp_return_error(QmpReturn *qret, Error *err); =20 void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); +void qmp_register_async_command(QmpCommandList *cmds, const char *name, + QmpCommandAsyncFunc *fn, + QmpCommandOptions options); const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char *name); void qmp_session_init(QmpSession *session, diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 3eb7e4b610..85e99671a9 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -171,7 +171,7 @@ static QDict *qmp_dispatch_check_obj(const QObject *req= uest, bool allow_oob, return dict; } =20 -static QObject *do_qmp_dispatch(const QmpCommandList *cmds, QObject *reque= st, +static QObject *do_qmp_dispatch(QmpSession *session, QObject *request, bool allow_oob, Error **errp) { Error *local_err =3D NULL; @@ -193,7 +193,7 @@ static QObject *do_qmp_dispatch(const QmpCommandList *c= mds, QObject *request, command =3D qdict_get_str(dict, "exec-oob"); oob =3D true; } - cmd =3D qmp_find_command(cmds, command); + cmd =3D qmp_find_command(session->cmds, command); if (cmd =3D=3D NULL) { error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found", command); @@ -225,14 +225,19 @@ static QObject *do_qmp_dispatch(const QmpCommandList = *cmds, QObject *request, qobject_ref(args); } =20 - cmd->fn(args, &ret, &local_err); - if (local_err) { - error_propagate(errp, local_err); - } else if (cmd->options & QCO_NO_SUCCESS_RESP) { - g_assert(!ret); - } else if (!ret) { - /* TODO turn into assertion */ - ret =3D QOBJECT(qdict_new()); + + if (cmd->options & QCO_ASYNC) { + cmd->async_fn(args, qmp_return_new(session, request)); + } else { + cmd->fn(args, &ret, &local_err); + if (local_err) { + error_propagate(errp, local_err); + } else if (cmd->options & QCO_NO_SUCCESS_RESP) { + g_assert(!ret); + } else if (!ret) { + /* TODO turn into assertion */ + ret =3D QOBJECT(qdict_new()); + } } =20 qobject_unref(args); @@ -305,7 +310,7 @@ void qmp_dispatch(QmpSession *session, QObject *request= , bool allow_oob) Error *err =3D NULL; QObject *ret; =20 - ret =3D do_qmp_dispatch(session->cmds, request, allow_oob, &err); + ret =3D do_qmp_dispatch(session, request, allow_oob, &err); if (err) { qmp_return_error(qmp_return_new(session, request), err); } else if (ret) { diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index d0f9a1d3e3..0f3d521ce5 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -15,16 +15,37 @@ #include "qemu/osdep.h" #include "qapi/qmp/dispatch.h" =20 -void qmp_register_command(QmpCommandList *cmds, const char *name, - QmpCommandFunc *fn, QmpCommandOptions options) + +static QmpCommand *qmp_command_new(QmpCommandList *cmds, const char *name, + QmpCommandOptions options) { QmpCommand *cmd =3D g_malloc0(sizeof(*cmd)); =20 cmd->name =3D name; - cmd->fn =3D fn; cmd->enabled =3D true; cmd->options =3D options; QTAILQ_INSERT_TAIL(cmds, cmd, node); + + return cmd; +} + + +void qmp_register_command(QmpCommandList *cmds, const char *name, + QmpCommandFunc *fn, QmpCommandOptions options) +{ + QmpCommand *cmd =3D qmp_command_new(cmds, name, options); + + assert(!(options & QCO_ASYNC)); + cmd->fn =3D fn; +} + +void qmp_register_async_command(QmpCommandList *cmds, const char *name, + QmpCommandAsyncFunc *fn, QmpCommandOptions opt= ions) +{ + QmpCommand *cmd =3D qmp_command_new(cmds, name, options); + + assert(options & QCO_ASYNC); + cmd->async_fn =3D fn; } =20 const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char = *name) --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225883; cv=none; d=zoho.com; s=zohoarc; b=MyQn8VZcwZPD7Nz+D7JSWEANkhfCiCH5lQ2aKpEsnz+blIsQfIfGSQWph2mnyMl2XtJUcDGQT86JEnxQY+puxAAtJM33OP0H+quJsNIptsDYyyADbKt5/R4wlsruGd4qOR4iaFflx8H4/qjJIklgl8bZP3nALEEC/NF2BPfX38c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225883; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=MQo/RxsLCbRLIfn5dXPT7MLQoAPuvHzpSnZeI8LguL4=; b=lBTaYJTJD+K624mhz04crASZt7zAJ81xuB9NiFPsBACRYSHDKgt5HfPCOX1Ia3Yvtlqv4qEFdX93H2aRkeM92p2OQyXWTjyOAG+euQQS/J+fwC4B4ThdRI+qNddWkQZiWw3dr6YDaCioZ+MM7Pc/Fg4B7ptDSzGIf9DLaNo7riw= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225883700485.25357818910345; Fri, 8 Nov 2019 07:11:23 -0800 (PST) Received: from localhost ([::1]:55954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5v0-0004cy-1z for importer@patchew.org; Fri, 08 Nov 2019 10:11:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46550) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5oY-00052s-7c for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5oU-00051n-0X for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:41 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:50651 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5oS-00050w-MU for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:37 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-296-rBaDBzpRMPS-4EJfV6kCIA-1; Fri, 08 Nov 2019 10:04:33 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 066A91005500 for ; Fri, 8 Nov 2019 15:04:33 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6E58F60BE2; Fri, 8 Nov 2019 15:04:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225476; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MQo/RxsLCbRLIfn5dXPT7MLQoAPuvHzpSnZeI8LguL4=; b=RZSQKsJB3CivrQxO2pR3MLuf2X+FJlDoa15xazv4HQtpOwa5sIKYOjz+jH8UBRhHaWKUB4 ZJYLOMPF2FUxyZL2P/pZGPkTfDAVVOLas4idkaIcbbCoY2Fuj1vA816gPzLxUqvW4bbvCQ I+jnjerxCy9L+qdTYSYvMKAdRyQQtrY= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 13/25] scripts: learn 'async' qapi commands Date: Fri, 8 Nov 2019 19:01:11 +0400 Message-Id: <20191108150123.12213-14-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-MC-Unique: rBaDBzpRMPS-4EJfV6kCIA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Commands with the 'async' key will be registered as async type (see related commit), and will allow a synchronous (in scope callback) or asynchronous return (out-of-scope when ready, in idle etc) by keeping the given QmpReturn and calling qmp_return function later. Ex: { 'command': 'foo-async, 'data': {'arg': 'str'}, 'returns': 'Foo', 'async': true } generates the following marshaller: void qmp_marshal_foo_async(QDict *args, QmpReturn *qret) { Error *err =3D NULL; Visitor *v; q_obj_foo_async_arg arg =3D {0}; v =3D qmp_input_visitor_new(QOBJECT(args), true); visit_start_struct(v, NULL, NULL, 0, &err); if (err) { goto out; } visit_type_q_obj_foo_async_arg_members(v, &arg, &err); if (!err) { visit_check_struct(v, &err); } visit_end_struct(v, NULL); if (err) { goto out; } qmp_foo_async(arg.arg, qret); out: if (err) { qmp_return_error(qret, err); } visit_free(v); v =3D qapi_dealloc_visitor_new(); visit_start_struct(v, NULL, NULL, 0, NULL); visit_type_q_obj_foo_async_arg_members(v, &arg, NULL); visit_end_struct(v, NULL); visit_free(v); } and a return helper: void qmp_foo_async_return(QmpReturn *qret, Foo *ret_in) { Error *err =3D NULL; QObject *ret_out =3D NULL; qmp_marshal_output_Foo(ret_in, &ret_out, &err); if (err) { qmp_return_error(qret, err); } else { qmp_return(qret, ret_out); } } The dispatched function may call the return helper within the calling scope or delay the return. To return an error, it can call qmp_return_error() directly instead. Signed-off-by: Marc-Andr=C3=A9 Lureau --- scripts/qapi/commands.py | 149 ++++++++++++++++++++---- scripts/qapi/doc.py | 2 +- scripts/qapi/expr.py | 4 +- scripts/qapi/introspect.py | 2 +- scripts/qapi/schema.py | 11 +- tests/qapi-schema/qapi-schema-test.json | 5 + tests/qapi-schema/qapi-schema-test.out | 8 ++ tests/qapi-schema/test-qapi.py | 7 +- tests/test-qmp-cmds.c | 60 ++++++++++ 9 files changed, 212 insertions(+), 36 deletions(-) diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index ab98e504f3..301b1a24d8 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -17,18 +17,35 @@ from qapi.common import * from qapi.gen import QAPIGenCCode, QAPISchemaModularCVisitor, ifcontext =20 =20 -def gen_command_decl(name, arg_type, boxed, ret_type): - return mcgen(''' +def gen_command_decl(name, arg_type, boxed, ret_type, success_response, as= yn): + if asyn: + extra =3D "QmpReturn *qret" + else: + extra =3D 'Error **errp' + + if asyn: + ret =3D mcgen(''' +void qmp_%(name)s(%(params)s); + ''', + name=3Dc_name(name), + params=3Dbuild_params(arg_type, boxed, extra)) + if success_response: + ret +=3D mcgen(''' +void qmp_%(name)s_return(QmpReturn *qret%(c_type)s); +''', + c_type=3D(", " + ret_type.c_type() if ret_type el= se ""), + name=3Dc_name(name)) + return ret + else: + return mcgen(''' %(c_type)s qmp_%(c_name)s(%(params)s); ''', - c_type=3D(ret_type and ret_type.c_type()) or 'void', - c_name=3Dc_name(name), - params=3Dbuild_params(arg_type, boxed, 'Error **errp')) + c_type=3D(ret_type and ret_type.c_type()) or 'void', + c_name=3Dc_name(name), + params=3Dbuild_params(arg_type, boxed, extra)) =20 =20 -def gen_call(name, arg_type, boxed, ret_type): - ret =3D '' - +def gen_argstr(arg_type, boxed): argstr =3D '' if boxed: assert arg_type @@ -39,7 +56,13 @@ def gen_call(name, arg_type, boxed, ret_type): if memb.optional: argstr +=3D 'arg.has_%s, ' % c_name(memb.name) argstr +=3D 'arg.%s, ' % c_name(memb.name) + return argstr =20 + +def gen_call(name, arg_type, boxed, ret_type): + ret =3D '' + + argstr =3D gen_argstr(arg_type, boxed) lhs =3D '' if ret_type: lhs =3D 'retval =3D ' @@ -61,6 +84,51 @@ def gen_call(name, arg_type, boxed, ret_type): return ret =20 =20 +def gen_async_call(name, arg_type, boxed): + argstr =3D gen_argstr(arg_type, boxed) + + push_indent() + ret =3D mcgen(''' + +qmp_%(c_name)s(%(args)sqret); +''', + c_name=3Dc_name(name), args=3Dargstr) + + pop_indent() + return ret + + +def gen_async_return(name, ret_type): + if ret_type: + return mcgen(''' + +void qmp_%(c_name)s_return(QmpReturn *qret, %(ret_type)s ret_in) +{ + Error *err =3D NULL; + QObject *ret_out =3D NULL; + + qmp_marshal_output_%(ret_c_name)s(ret_in, &ret_out, &err); + + if (err) { + qmp_return_error(qret, err); + } else { + qmp_return(qret, ret_out); + } +} +''', + c_name=3Dc_name(name), + ret_type=3Dret_type.c_type(), ret_c_name=3Dret_type.c= _name()) + else: + return mcgen(''' + +void qmp_%(c_name)s_return(QmpReturn *qret) +{ + qmp_return(qret, QOBJECT(qdict_new())); +} +''', + c_name=3Dc_name(name)) + + def gen_marshal_output(ret_type): return mcgen(''' =20 @@ -84,19 +152,22 @@ static void qmp_marshal_output_%(c_name)s(%(c_type)s r= et_in, QObject **ret_out, c_type=3Dret_type.c_type(), c_name=3Dret_type.c_name()) =20 =20 -def build_marshal_proto(name): - return ('void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)' - % c_name(name)) +def build_marshal_proto(name, asyn): + if asyn: + tmpl =3D 'void qmp_marshal_%s(QDict *args, QmpReturn *qret)' + else: + tmpl =3D 'void qmp_marshal_%s(QDict *args, QObject **ret, Error **= errp)' + return tmpl % c_name(name) =20 =20 -def gen_marshal_decl(name): +def gen_marshal_decl(name, asyn): return mcgen(''' %(proto)s; ''', - proto=3Dbuild_marshal_proto(name)) + proto=3Dbuild_marshal_proto(name, asyn)) =20 =20 -def gen_marshal(name, arg_type, boxed, ret_type): +def gen_marshal(name, arg_type, boxed, ret_type, asyn): have_args =3D boxed or (arg_type and not arg_type.is_empty()) =20 ret =3D mcgen(''' @@ -105,9 +176,9 @@ def gen_marshal(name, arg_type, boxed, ret_type): { Error *err =3D NULL; ''', - proto=3Dbuild_marshal_proto(name)) + proto=3Dbuild_marshal_proto(name, asyn)) =20 - if ret_type: + if ret_type and not asyn: ret +=3D mcgen(''' %(c_type)s retval; ''', @@ -154,12 +225,28 @@ def gen_marshal(name, arg_type, boxed, ret_type): } ''') =20 - ret +=3D gen_call(name, arg_type, boxed, ret_type) + if asyn: + ret +=3D gen_async_call(name, arg_type, boxed) + else: + ret +=3D gen_call(name, arg_type, boxed, ret_type) =20 ret +=3D mcgen(''' =20 out: +''') + + if asyn: + ret +=3D mcgen(''' + if (err) { + qmp_return_error(qret, err); + } +''') + else: + ret +=3D mcgen(''' error_propagate(errp, err); +''') + + ret +=3D mcgen(''' visit_free(v); ''') =20 @@ -194,7 +281,8 @@ out: return ret =20 =20 -def gen_register_command(name, success_response, allow_oob, allow_preconfi= g): +def gen_register_command(name, success_response, allow_oob, allow_preconfi= g, + asyn): options =3D [] =20 if not success_response: @@ -203,17 +291,24 @@ def gen_register_command(name, success_response, allo= w_oob, allow_preconfig): options +=3D ['QCO_ALLOW_OOB'] if allow_preconfig: options +=3D ['QCO_ALLOW_PRECONFIG'] + if asyn: + options +=3D ['QCO_ASYNC'] =20 if not options: options =3D ['QCO_NO_OPTIONS'] =20 options =3D " | ".join(options) =20 + if asyn: + regfn =3D 'qmp_register_async_command' + else: + regfn =3D 'qmp_register_command' + ret =3D mcgen(''' - qmp_register_command(cmds, "%(name)s", + %(regfn)s(cmds, "%(name)s", qmp_marshal_%(c_name)s, %(opts)s); ''', - name=3Dname, c_name=3Dc_name(name), + regfn=3Dregfn, name=3Dname, c_name=3Dc_name(name), opts=3Doptions) return ret =20 @@ -278,7 +373,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); =20 def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, - features): + features, asyn): if not gen: return # FIXME: If T is a user-defined type, the user is responsible @@ -292,11 +387,15 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmd= s); self._genh, self._genc, self._regy): self._genc.add(gen_marshal_output(ret_type)) with ifcontext(ifcond, self._genh, self._genc, self._regy): - self._genh.add(gen_command_decl(name, arg_type, boxed, ret_typ= e)) - self._genh.add(gen_marshal_decl(name)) - self._genc.add(gen_marshal(name, arg_type, boxed, ret_type)) + self._genh.add(gen_command_decl(name, arg_type, boxed, ret_typ= e, + success_response, asyn)) + self._genh.add(gen_marshal_decl(name, asyn)) + self._genc.add(gen_marshal(name, arg_type, boxed, ret_type, as= yn)) + if asyn and success_response: + self._genc.add(gen_async_return(name, ret_type)) self._regy.add(gen_register_command(name, success_response, - allow_oob, allow_preconfig= )) + allow_oob, allow_preconfig, + asyn)) =20 =20 def gen_commands(schema, output_dir, prefix): diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index 6f1c17f71f..375978f04f 100644 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -265,7 +265,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor): =20 def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, - features): + features, asyn): doc =3D self.cur_doc self._gen.add(texi_msg('Command', doc, ifcond, texi_arguments(doc, diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index d7a289eded..db4956133d 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -89,7 +89,7 @@ def check_flags(expr, info): if key in expr and expr[key] is not False: raise QAPISemError( info, "flag '%s' may only use false value" % key) - for key in ['boxed', 'allow-oob', 'allow-preconfig']: + for key in ['boxed', 'allow-oob', 'allow-preconfig', 'async']: if key in expr and expr[key] is not True: raise QAPISemError( info, "flag '%s' may only use true value" % key) @@ -344,7 +344,7 @@ def check_exprs(exprs): ['command'], ['data', 'returns', 'boxed', 'if', 'features', 'gen', 'success-response', 'allow-oob', - 'allow-preconfig']) + 'allow-preconfig', 'async']) normalize_members(expr.get('data')) check_command(expr, info) elif meta =3D=3D 'event': diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index b3a463dd8b..f28c96afa3 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -212,7 +212,7 @@ const QLitObject %(c_name)s =3D %(c_string)s; =20 def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, - features): + features, asyn): arg_type =3D arg_type or self._schema.the_empty_object_type ret_type =3D ret_type or self._schema.the_empty_object_type obj =3D {'arg-type': self._use_type(arg_type), diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index cf0045f34e..2e1d5278bf 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -128,7 +128,7 @@ class QAPISchemaVisitor(object): =20 def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, - features): + features, asyn): pass =20 def visit_event(self, name, info, ifcond, arg_type, boxed): @@ -678,7 +678,7 @@ class QAPISchemaCommand(QAPISchemaEntity): =20 def __init__(self, name, info, doc, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, - features): + features, asyn): QAPISchemaEntity.__init__(self, name, info, doc, ifcond, features) assert not arg_type or isinstance(arg_type, str) assert not ret_type or isinstance(ret_type, str) @@ -691,6 +691,7 @@ class QAPISchemaCommand(QAPISchemaEntity): self.boxed =3D boxed self.allow_oob =3D allow_oob self.allow_preconfig =3D allow_preconfig + self.asyn =3D asyn =20 def check(self, schema): QAPISchemaEntity.check(self, schema) @@ -733,7 +734,7 @@ class QAPISchemaCommand(QAPISchemaEntity): self.gen, self.success_response, self.boxed, self.allow_oob, self.allow_preconfig, - self.features) + self.features, self.asyn) =20 =20 class QAPISchemaEvent(QAPISchemaEntity): @@ -1016,6 +1017,7 @@ class QAPISchema(object): allow_preconfig =3D expr.get('allow-preconfig', False) ifcond =3D expr.get('if') features =3D expr.get('features', []) + asyn =3D expr.get('async', False) if isinstance(data, OrderedDict): data =3D self._make_implicit_object_type( name, info, ifcond, 'arg', self._make_members(data, info)) @@ -1025,7 +1027,8 @@ class QAPISchema(object): self._def_entity(QAPISchemaCommand(name, info, doc, ifcond, data, = rets, gen, success_response, boxed, allow_oob, allow_preconf= ig, - self._make_features(features, i= nfo))) + self._make_features(features, i= nfo), + asyn)) =20 def _def_event(self, expr, info, doc): name =3D expr['event'] diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qa= pi-schema-test.json index 9abf175fe0..58d2164c7e 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -148,6 +148,11 @@ =20 { 'command': 'cmd-success-response', 'data': {}, 'success-response': false= } =20 +{ 'command': 'cmd-async', 'data': {'filename': 'str'}, + 'returns': 'Empty2', 'async': true } +{ 'command': 'cmd-success-response-async', 'data': {'filename': 'str'}, + 'async': true, 'success-response': false} + # Returning a non-dictionary requires a name from the whitelist { 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qap= i-schema-test.out index 3660e75a48..19d2d202b9 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -217,6 +217,14 @@ command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserD= efTwo gen=3DTrue success_response=3DTrue boxed=3DFalse oob=3DFalse preconfig= =3DFalse command cmd-success-response None -> None gen=3DTrue success_response=3DFalse boxed=3DFalse oob=3DFalse preconfi= g=3DFalse +object q_obj_cmd-async-arg + member filename: str optional=3DFalse +command cmd-async q_obj_cmd-async-arg -> Empty2 + gen=3DTrue success_response=3DTrue boxed=3DFalse oob=3DFalse preconfig= =3DFalse async=3DTrue +object q_obj_cmd-success-response-async-arg + member filename: str optional=3DFalse +command cmd-success-response-async q_obj_cmd-success-response-async-arg ->= None + gen=3DTrue success_response=3DFalse boxed=3DFalse oob=3DFalse preconfi= g=3DFalse async=3DTrue object q_obj_guest-get-time-arg member a: int optional=3DFalse member b: int optional=3DTrue diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index bad14edb47..1914b7d5ff 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -70,12 +70,13 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): =20 def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, - features): + features, asyn): print('command %s %s -> %s' % (name, arg_type and arg_type.name, ret_type and ret_type.name)) - print(' gen=3D%s success_response=3D%s boxed=3D%s oob=3D%s prec= onfig=3D%s' - % (gen, success_response, boxed, allow_oob, allow_preconfig)) + print(' gen=3D%s success_response=3D%s boxed=3D%s oob=3D%s prec= onfig=3D%s%s' + % (gen, success_response, boxed, allow_oob, allow_preconfig, + ' async=3DTrue' if asyn else '')) self._print_if(ifcond) self._print_features(features) =20 diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 213df7e53a..75ef30f6ea 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -34,6 +34,28 @@ void qmp_cmd_success_response(Error **errp) { } =20 +static gboolean cmd_async_idle(gpointer user_data) +{ + QmpReturn *qret =3D user_data; + + qmp_cmd_async_return(qret, g_new0(Empty2, 1)); + + return G_SOURCE_REMOVE; +} + +void qmp_cmd_async(const char *filename, QmpReturn *qret) +{ + g_idle_add(cmd_async_idle, qret); +} + +void qmp_cmd_success_response_async(const char *filename, QmpReturn *qret) +{ + Error *err =3D NULL; + + error_setg(&err, "no response, but error ok"); + qmp_return_error(qret, err); +} + Empty2 *qmp_user_def_cmd0(Error **errp) { return g_new0(Empty2, 1); @@ -394,6 +416,43 @@ static void test_qmp_return_orderly(void) qobject_unref(dict); } =20 +typedef struct QmpReturnAsync { + QmpSession session; + GMainLoop *loop; +} QmpReturnAsync; + +static void dispatch_return_async(QmpSession *session, QDict *resp) +{ + QmpReturnAsync *a =3D container_of(session, QmpReturnAsync, session); + + g_main_loop_quit(a->loop); + g_main_loop_unref(a->loop); + a->loop =3D NULL; +} + +static void test_qmp_return_async(void) +{ + QmpReturnAsync a =3D { { 0, } , }; + QDict *args =3D qdict_new(); + QDict *req =3D qdict_new(); + + a.loop =3D g_main_loop_new(NULL, TRUE); + qmp_session_init(&a.session, &qmp_commands, + NULL, dispatch_return_async); + + qdict_put_str(args, "filename", "test-filename"); + qdict_put_str(req, "execute", "cmd-async"); + qdict_put(req, "arguments", args); + qmp_dispatch(&a.session, QOBJECT(req), false); + g_assert(a.loop); + + g_main_loop_run(a.loop); + g_assert(!a.loop); + + qmp_session_destroy(&a.session); + qobject_unref(req); +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); @@ -407,6 +466,7 @@ int main(int argc, char **argv) g_test_add_func("/qmp/dealloc_types", test_dealloc_types); g_test_add_func("/qmp/dealloc_partial", test_dealloc_partial); g_test_add_func("/qmp/return_orderly", test_qmp_return_orderly); + g_test_add_func("/qmp/return_async", test_qmp_return_async); =20 test_qmp_init_marshal(&qmp_commands); g_test_run(); --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573225983; cv=none; d=zoho.com; s=zohoarc; b=DeEyR8n2k4M97nCYGnMjeuWH438lET/MMMUWOyeeIe81zRTgGh7xwiPuPHuyghi0ToxtTdTjUdwmi07SGtutrNGcdiTy01Y3F1uFnQCc6m+A+9lgW89VgiZeeB1aswhkY0p28YZ/IYWeUaceRn4oWu4mWiagIBTKk0Qy5rPVxDQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573225983; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=6Ew9vHmiWjfrl81VNZzip86x0hD9sFmj8JBBNQVLTHg=; b=dt1V4dJPegi36sDaBSbzXJCuo7aCwxVeRKUGRS/MEApI60FExmNlEmOB/OdDmYPbRo03TX4S0rQbn1s7+8GUjiu+yWqRTGJJL5fucbd10xtqCIF0n4KnAdh/tY+FRZasg/j0Kh3Q+1EszvUmc/M6OLRT4Eb+gdjeL8h8KfAOOH0= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573225983241324.1040326709424; Fri, 8 Nov 2019 07:13:03 -0800 (PST) Received: from localhost ([::1]:55976 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5wb-0006oP-Q2 for importer@patchew.org; Fri, 08 Nov 2019 10:13:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46566) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5of-00056k-GS for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5oe-00059L-5J for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:49 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:24959 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5od-00058c-W6 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:48 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-335-V8MqFVBvNz2em5aS0e8HwA-1; Fri, 08 Nov 2019 10:04:46 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7FF441005500 for ; Fri, 8 Nov 2019 15:04:45 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 55E035C1BB; Fri, 8 Nov 2019 15:04:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225487; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6Ew9vHmiWjfrl81VNZzip86x0hD9sFmj8JBBNQVLTHg=; b=UauoBIlpiIgKhWGGreQM2ll6+wEALljH7TtReKWnkmjCqUl7c2jsvz1QS5ewXVW2944Eqf T9cvmEOq1Yl+saZtN7K+bE5DbGqFYPEgVKsPUdeQa/P/sWbMo1l1xhp5A2oDVmqpH/72mH Aq7IoS4/YyIctkN9CBxBq8FaQxKOCHI= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 14/25] qmp: add qmp_return_is_cancelled() Date: Fri, 8 Nov 2019 19:01:12 +0400 Message-Id: <20191108150123.12213-15-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: V8MqFVBvNz2em5aS0e8HwA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" If the client is gone, and the session finished, no need to return. The async handler can use this information to avoid unnecessary work and exit earlier. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qapi/qmp/dispatch.h | 8 ++++++++ qapi/qmp-dispatch.c | 10 ++++++++++ tests/test-qmp-cmds.c | 39 ++++++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 6aef0abc70..6673902e95 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -91,6 +91,14 @@ void qmp_return_free(QmpReturn *qret); void qmp_return(QmpReturn *qret, QObject *rsp); void qmp_return_error(QmpReturn *qret, Error *err); =20 +/* + * @qmp_return_is_cancelled: + * + * Return true if the QmpReturn is cancelled, and free the QmpReturn + * in this case. + */ +bool qmp_return_is_cancelled(QmpReturn *qret); + void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); void qmp_register_async_command(QmpCommandList *cmds, const char *name, diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 85e99671a9..e5c1505b05 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -64,6 +64,16 @@ void qmp_return_free(QmpReturn *qret) } } =20 +bool qmp_return_is_cancelled(QmpReturn *qret) +{ + if (!qret->session) { + qmp_return_free(qret); + return true; + } + + return false; +} + static void qmp_return_orderly(QmpReturn *qret) { QmpSession *session =3D qret->session; diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 75ef30f6ea..66ad8726fe 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -34,17 +34,29 @@ void qmp_cmd_success_response(Error **errp) { } =20 +static GMainLoop *loop; + static gboolean cmd_async_idle(gpointer user_data) { QmpReturn *qret =3D user_data; =20 - qmp_cmd_async_return(qret, g_new0(Empty2, 1)); + if (!qret->session) { + g_assert(qmp_return_is_cancelled(qret)); + g_main_loop_quit(loop); + g_main_loop_unref(loop); + loop =3D NULL; + } else { + qmp_cmd_async_return(qret, g_new0(Empty2, 1)); + } =20 return G_SOURCE_REMOVE; } =20 void qmp_cmd_async(const char *filename, QmpReturn *qret) { + if (g_str_equal(filename, "cancel")) { + qmp_session_destroy(qret->session); + } g_idle_add(cmd_async_idle, qret); } =20 @@ -453,6 +465,30 @@ static void test_qmp_return_async(void) qobject_unref(req); } =20 +static void test_qmp_return_async_cancel(void) +{ + QmpReturnAsync a =3D { { 0, }, }; + QDict *args =3D qdict_new(); + QDict *req =3D qdict_new(); + + a.loop =3D g_main_loop_new(NULL, TRUE); + qmp_session_init(&a.session, &qmp_commands, + NULL, dispatch_return_async); + + qdict_put_str(args, "filename", "cancel"); + qdict_put_str(req, "execute", "cmd-async"); + qdict_put(req, "arguments", args); + qmp_dispatch(&a.session, QOBJECT(req), false); + g_assert(a.loop); + + loop =3D a.loop; + g_main_loop_run(loop); + g_assert(!loop); + + qmp_session_destroy(&a.session); + qobject_unref(req); +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); @@ -467,6 +503,7 @@ int main(int argc, char **argv) g_test_add_func("/qmp/dealloc_partial", test_dealloc_partial); g_test_add_func("/qmp/return_orderly", test_qmp_return_orderly); g_test_add_func("/qmp/return_async", test_qmp_return_async); + g_test_add_func("/qmp/return_async_cancel", test_qmp_return_async_canc= el); =20 test_qmp_init_marshal(&qmp_commands); g_test_run(); --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226604; cv=none; d=zoho.com; s=zohoarc; b=NZdll9o5QJKiKundZbV+FizR/27RXcQB/rSc0YMnvR/3XKQtXo5Yqq4IjnotJgXz6eV/i9uVz/59f4q0TuR5oQnjpMcT2Nkgc3pXiZjz9wvD516AkkDpX+KMqtul/zZ9TVa+sdgKoLPI4W3S4CB2eWasTp4sBAFU5MSKmP7Lvy4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226604; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Wc4ftlDRX01CUchMOTZsiibJ9hNVG/BrpUrzGO6rXso=; b=iInKXQwWeSkWbPcYijSZnjflZa8iRh8JtUbkRDCTDiO+dN8OzykEjlCHrdHMWDA+BIfIGJn/1ssSgedn1W10tYxGW59daXUDlXNPtqrOPPeiP9v1qmr2oOXr6gIyDlmuk01FrsqUINDHCEznOzTZyJEUtLq0w+zb++Rj0rPs4rg= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226604072342.53561838268683; Fri, 8 Nov 2019 07:23:24 -0800 (PST) Received: from localhost ([::1]:56114 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT66c-00015t-Ub for importer@patchew.org; Fri, 08 Nov 2019 10:23:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46584) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5om-0005BY-U7 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5ol-0005JN-HE for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:56 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:36409 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5ol-0005J8-DR for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:04:55 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-93-VLkaUK2BN22tSY0L_cdEWg-1; Fri, 08 Nov 2019 10:04:53 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F2DB7477 for ; Fri, 8 Nov 2019 15:04:52 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 69CE15C1BB; Fri, 8 Nov 2019 15:04:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wc4ftlDRX01CUchMOTZsiibJ9hNVG/BrpUrzGO6rXso=; b=FJj2794XmAFpA7z4k6wgK8hDIKmmeKaeZ0e86mBQwcNdEZM10uoniG056tHhRVKx5gDl/Z gZ//M2EnWz5zLVEggo3gwX8wCTpv6W1Cl5O6VZkTJlCwxYUB+dATJiL3FFk+xhJbyAwoUV aUrMCVdWHS6gii4VrICl5EElDg04ig0= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 15/25] console: add graphic_hw_update_done() Date: Fri, 8 Nov 2019 19:01:13 +0400 Message-Id: <20191108150123.12213-16-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: VLkaUK2BN22tSY0L_cdEWg-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Add a function to be called when a graphic update is done. Declare the QXL renderer as async: render_update_cookie_num counts the number of outstanding updates, and graphic_hw_update_done() is called when it reaches none. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Gerd Hoffmann --- hw/display/qxl-render.c | 9 +++++++-- hw/display/qxl.c | 1 + include/ui/console.h | 2 ++ ui/console.c | 9 +++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index f7fdc4901e..3ce2e57b8f 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c @@ -109,7 +109,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevic= e *qxl) qxl->guest_primary.surface= .mem, MEMSLOT_GROUP_GUEST); if (!qxl->guest_primary.data) { - return; + goto end; } qxl_set_rect_to_surface(qxl, &qxl->dirty[0]); qxl->num_dirty_rects =3D 1; @@ -137,7 +137,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevic= e *qxl) } =20 if (!qxl->guest_primary.data) { - return; + goto end; } for (i =3D 0; i < qxl->num_dirty_rects; i++) { if (qemu_spice_rect_is_empty(qxl->dirty+i)) { @@ -158,6 +158,11 @@ static void qxl_render_update_area_unlocked(PCIQXLDevi= ce *qxl) qxl->dirty[i].bottom - qxl->dirty[i].top); } qxl->num_dirty_rects =3D 0; + +end: + if (qxl->render_update_cookie_num =3D=3D 0) { + graphic_hw_update_done(qxl->ssd.dcl.con); + } } =20 /* diff --git a/hw/display/qxl.c b/hw/display/qxl.c index cd7eb39d20..6d43b7433c 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -1181,6 +1181,7 @@ static const QXLInterface qxl_interface =3D { =20 static const GraphicHwOps qxl_ops =3D { .gfx_update =3D qxl_hw_update, + .gfx_update_async =3D true, }; =20 static void qxl_enter_vga_mode(PCIQXLDevice *d) diff --git a/include/ui/console.h b/include/ui/console.h index f981696848..281f9c145b 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -365,6 +365,7 @@ static inline void console_write_ch(console_ch_t *dest,= uint32_t ch) typedef struct GraphicHwOps { void (*invalidate)(void *opaque); void (*gfx_update)(void *opaque); + bool gfx_update_async; /* if true, calls graphic_hw_update_done() */ void (*text_update)(void *opaque, console_ch_t *text); void (*update_interval)(void *opaque, uint64_t interval); int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info); @@ -380,6 +381,7 @@ void graphic_console_set_hwops(QemuConsole *con, void graphic_console_close(QemuConsole *con); =20 void graphic_hw_update(QemuConsole *con); +void graphic_hw_update_done(QemuConsole *con); void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); void graphic_hw_gl_block(QemuConsole *con, bool block); diff --git a/ui/console.c b/ui/console.c index 82d1ddac9c..3c941528d2 100644 --- a/ui/console.c +++ b/ui/console.c @@ -259,13 +259,22 @@ static void gui_setup_refresh(DisplayState *ds) ds->have_text =3D have_text; } =20 +void graphic_hw_update_done(QemuConsole *con) +{ +} + void graphic_hw_update(QemuConsole *con) { + bool async =3D false; if (!con) { con =3D active_console; } if (con && con->hw_ops->gfx_update) { con->hw_ops->gfx_update(con->hw); + async =3D con->hw_ops->gfx_update_async; + } + if (!async) { + graphic_hw_update_done(con); } } =20 --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226750; cv=none; d=zoho.com; s=zohoarc; b=NQjTEAVqnRMAumOvriiF8Wue4xj2E5e5pZzMsRdd5w7f9eOQxvrK44Uw/slHpw/+XhUm3OTXgKEeYpMXAlfUGSdpRXj2zP3Vog0ffrjbpxdsegRlpYyrKNWLBFwozjzXKUPD6GlrKSY6Q70rq8j6lDM3i5e/M1IroZgGA3rtOd0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226750; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=K6atlegt2pHhl2BHFOIZn9sIb4MIPYLA7+KTpFuvx0s=; b=iVfcpcSF4aja9EOLoDlqMbSfmvRCJEOJVArVcRKMKZF5W6wJiTlmQauHjgCr4YO07NwBH9TfFAmw/+UZaTKbeDcJkE+jY/xoRZh2VhfLeZHp3tSfnV1ZNEGJOHoye37ts90otNGv5Ja1QVsKjJNFWQrrC8ru7yTkxTGpRbadMsM= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226750916702.5661532681129; Fri, 8 Nov 2019 07:25:50 -0800 (PST) Received: from localhost ([::1]:56138 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT68z-0003qH-EI for importer@patchew.org; Fri, 08 Nov 2019 10:25:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46646) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5p6-0005dX-3Q for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5p3-0005Wc-Of for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:15 -0500 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:33575 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5p3-0005VT-Kh for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:13 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-24-bUcHVWTCMxmOc7_-1CU6-g-1; Fri, 08 Nov 2019 10:05:09 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D45D0107ACC4 for ; Fri, 8 Nov 2019 15:05:08 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A538277B6; Fri, 8 Nov 2019 15:04:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225510; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K6atlegt2pHhl2BHFOIZn9sIb4MIPYLA7+KTpFuvx0s=; b=LiERhUNpgbhsIzkKg6NiTZp5sApI/i8leO+DWdAeLBqJ6wpWDsYxnGqDvFqt6vo5nGWCq3 42i5crvNLMdJ/wIfEIX6LXTuTefqKj7PS/1Ga95V4M5gfbqdHRmoZ98+CjoT2Mm7R21oOU ugwTEbcoEPEqz3xd2GRnc/hsgW688CQ= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 16/25] ppm-save: pass opened fd Date: Fri, 8 Nov 2019 19:01:14 +0400 Message-Id: <20191108150123.12213-17-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: bUcHVWTCMxmOc7_-1CU6-g-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This will allow to pre-open the file before running the async finish handler and avoid potential monitor fdset races. Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console.c | 45 ++++++++++++++++++++++----------------------- ui/trace-events | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/ui/console.c b/ui/console.c index 3c941528d2..77d62fe76d 100644 --- a/ui/console.c +++ b/ui/console.c @@ -193,6 +193,7 @@ static void dpy_refresh(DisplayState *s); static DisplayState *get_alloc_displaystate(void); static void text_console_update_cursor_timer(void); static void text_console_update_cursor(void *opaque); +static bool ppm_save(int fd, DisplaySurface *ds, Error **errp); =20 static void gui_update(void *opaque) { @@ -308,29 +309,22 @@ void graphic_hw_invalidate(QemuConsole *con) } } =20 -static void ppm_save(const char *filename, DisplaySurface *ds, - Error **errp) +static bool ppm_save(int fd, DisplaySurface *ds, Error **errp) { int width =3D pixman_image_get_width(ds->image); int height =3D pixman_image_get_height(ds->image); - int fd; FILE *f; int y; int ret; pixman_image_t *linebuf; + bool success =3D false; =20 - trace_ppm_save(filename, ds); - fd =3D qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 06= 66); - if (fd =3D=3D -1) { - error_setg(errp, "failed to open file '%s': %s", filename, - strerror(errno)); - return; - } + trace_ppm_save(fd, ds); f =3D fdopen(fd, "wb"); ret =3D fprintf(f, "P6\n%d %d\n%d\n", width, height, 255); if (ret < 0) { linebuf =3D NULL; - goto write_err; + goto end; } linebuf =3D qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width); for (y =3D 0; y < height; y++) { @@ -339,21 +333,16 @@ static void ppm_save(const char *filename, DisplaySur= face *ds, ret =3D fwrite(pixman_image_get_data(linebuf), 1, pixman_image_get_stride(linebuf), f); (void)ret; - if (ferror(f)) { - goto write_err; - } + success =3D !ferror(f); } =20 -out: +end: + if (!success) { + error_setg(errp, "failed to write to PPM file: %s", strerror(errno= )); + } qemu_pixman_image_unref(linebuf); fclose(f); - return; - -write_err: - error_setg(errp, "failed to write to file '%s': %s", filename, - strerror(errno)); - unlink(filename); - goto out; + return success; } =20 void qmp_screendump(const char *filename, bool has_device, const char *dev= ice, @@ -361,6 +350,7 @@ void qmp_screendump(const char *filename, bool has_devi= ce, const char *device, { QemuConsole *con; DisplaySurface *surface; + int fd; =20 if (has_device) { con =3D qemu_console_lookup_by_device_name(device, has_head ? head= : 0, @@ -387,7 +377,16 @@ void qmp_screendump(const char *filename, bool has_dev= ice, const char *device, return; } =20 - ppm_save(filename, surface, errp); + fd =3D qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 06= 66); + if (fd =3D=3D -1) { + error_setg(errp, "failed to open file '%s': %s", filename, + strerror(errno)); + return; + } + + if (!ppm_save(fd, surface, errp)) { + unlink(filename); + } } =20 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata) diff --git a/ui/trace-events b/ui/trace-events index 63de72a798..0dcda393c1 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -15,7 +15,7 @@ displaysurface_create_pixman(void *display_surface) "surf= ace=3D%p" displaysurface_free(void *display_surface) "surface=3D%p" displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]" displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]" -ppm_save(const char *filename, void *display_surface) "%s surface=3D%p" +ppm_save(int fd, void *display_surface) "fd=3D%d surface=3D%p" =20 # gtk.c # gtk-gl-area.c --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226036; cv=none; d=zoho.com; s=zohoarc; b=XO9WcbLA/ZhIsGK5YE16R31Xm8QCaHD4pOaxiV2XsAoFF7EHRI2JSyp7oOkEujH9L31OKj4DRCqTVpYT7d9KmWwgsNO80bC3n3Hf5UKZj7u0owMLGYbg3Iqu6wnr6vH51NY6E4hjRCB1SCg1W0R940ZVgvk+2AKk/T79YKls6lI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226036; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=AUi6QEZalbLTxvUCWZJyEZQMUqLH8rpUCT9b1rwUQl8=; b=k+srXQd6WwtcSxkG4JtRgVzlFBKisnSEYfFAIvR0WCf9gF5TwVwiWm6bdBSTHajT6nCF071GBOzdrE1HoTWQUUxoRFCxvtx8+Bs/NNnpF6j+javGJITSRzgBQIWBk0t6q+VeyBbHviHIqn//wgLje+l4WRGtAwZkXEdZkaMxKOM= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226036281291.21934610313565; Fri, 8 Nov 2019 07:13:56 -0800 (PST) Received: from localhost ([::1]:55982 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5xS-0007zQ-PW for importer@patchew.org; Fri, 08 Nov 2019 10:13:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46693) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5pK-00061O-34 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5pF-0005kL-62 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:29 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:37980 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5pF-0005jz-2A for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:25 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-260-pTyYSquwOQqf7DzP_5NEXw-1; Fri, 08 Nov 2019 10:05:23 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3052B477 for ; Fri, 8 Nov 2019 15:05:22 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 32E81600C9; Fri, 8 Nov 2019 15:05:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225524; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AUi6QEZalbLTxvUCWZJyEZQMUqLH8rpUCT9b1rwUQl8=; b=eYLUWb2rY4PQMO62o7onDQoHlY862Np8pLfuVbzud6kq2j4Sl06b4lKyredPqv8oVZUjnU ME85kA3+4Oh8Upf0H0MOC824MvihVX0Y6TCwgd8P1FJjQ7G6y+tK3K9KMKMRrAiLlwpsZO N7N6ZxuCNerORhwLy5JKiBAhx/6Yq5E= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 17/25] ui: add pixman image g_autoptr support Date: Fri, 8 Nov 2019 19:01:15 +0400 Message-Id: <20191108150123.12213-18-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: pTyYSquwOQqf7DzP_5NEXw-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/ui/qemu-pixman.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index 0668109305..3b7cf70157 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -90,4 +90,6 @@ void qemu_pixman_glyph_render(pixman_image_t *glyph, pixman_color_t *bgcol, int x, int y, int cw, int ch); =20 +G_DEFINE_AUTOPTR_CLEANUP_FUNC(pixman_image_t, qemu_pixman_image_unref) + #endif /* QEMU_PIXMAN_H */ --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226286; cv=none; d=zoho.com; s=zohoarc; b=ahwKJCdHUYEfzgDpPdEIm3whh/cWAfHlvwbeRIjzuHIcgQR8uuiDJq8pLUtfhRM4dTYKPNO7xp7XeS11V5MOl/6HihjBpgMCir9OEuoPTrBrqdOswG+bKLCUu0HEwLHV7uuFHLYOQlC4/qLrZzxTXgtZuDAsnKwcNghF8Lv+mtI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226286; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=i/jhfPVbaw9zN74ATSitQu5mKIuSj4RbYiPEOhbuIgk=; b=OkqDqPdMb5EflDEWa8hpEnjirGm+lKjrga7/eERDkNlLxTk4OP1WFFoMgKTzqDyS2qzN9oO7czzk9/1rFEMvl+5nO/P8PxX13f2GruNawLYUfJf1B9p87l7+Ch8QjcnU7YpWAvP9aPX+kc/P470mvnKGUlLfVv9+FA2O+JiIbvo= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226286918652.1077638499312; Fri, 8 Nov 2019 07:18:06 -0800 (PST) Received: from localhost ([::1]:56028 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT61U-0003EH-4s for importer@patchew.org; Fri, 08 Nov 2019 10:18:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46720) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5pR-0006Cg-LH for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5pQ-0005xT-Me for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:37 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:41901 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5pQ-0005wD-Iq for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:36 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-350-2x3jsTa_OLCb6WVECiCvHQ-1; Fri, 08 Nov 2019 10:05:34 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F268A107ACC4 for ; Fri, 8 Nov 2019 15:05:33 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6E1B66084E; Fri, 8 Nov 2019 15:05:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i/jhfPVbaw9zN74ATSitQu5mKIuSj4RbYiPEOhbuIgk=; b=h4QBm4PQ4oHnHvWWjC3E1hdOuRJPur98hg8b6i8H1SN++V9nkmNzHFdxujwWsPCUJvdsup 8eKnMgSWress1GaNC9w4hTW01oONjEEWmkdVUseFkCya2yZRfOIIm2up6qHSUorOjvrzTm +dKIfUCStIz/pSDMgXYAnVatE4/6Up4= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 18/25] object: add g_autoptr support Date: Fri, 8 Nov 2019 19:01:16 +0400 Message-Id: <20191108150123.12213-19-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-MC-Unique: 2x3jsTa_OLCb6WVECiCvHQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qom/object.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index 128d00c77f..f96a44be64 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1747,4 +1747,7 @@ Object *container_get(Object *root, const char *path); * Returns the instance_size of the given @typename. */ size_t object_type_get_instance_size(const char *typename); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(Object, object_unref) + #endif --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226186; cv=none; d=zoho.com; s=zohoarc; b=VfKjYe7jvxM4BE31aYGaFCuO6Nu/iBHICVokxUzXZvwucW2yKoABk2g9ghCQEryBDHmZwPKnNR9YFNW0Hj44124GcF7pt8Tgcd8kXC5/dEqwlFUmEzxlXwkb+qnrkBOLnNJAeiBPptkw3RI7NYySc29LQJMjZlGGiyITbTjWl3s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226186; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=V/mcHvKX7InUGUgT0KSXWZlTMQTnyJjgwdgTbknSH9s=; b=Z8wwsB4lmG6KJhgWzNTuLYhsdlRTqC+jElOibw9rS+RDS0+KbrnZJ/pKkOwMPJa4xKL3DvGYftsuub+7GIxhZeG9KZiH7M/ZkhIa/sHs2doBqMpnufLfyGKUJqfAynoeUm6FptH2KbCTReMMyNYrQJjju4wOGx6AnH2MW3mNjPs= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226186080251.68830481118687; Fri, 8 Nov 2019 07:16:26 -0800 (PST) Received: from localhost ([::1]:56014 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5zq-0001tU-M7 for importer@patchew.org; Fri, 08 Nov 2019 10:16:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46792) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5pm-0006mC-3n for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5pj-0006M2-Ts for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:58 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:27781 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5pj-0006Ld-Q1 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:05:55 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-28-wHajOuMYMjS7RgWHsoVTeA-1; Fri, 08 Nov 2019 10:05:54 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 485B61005500 for ; Fri, 8 Nov 2019 15:05:53 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id ED49D600CA; Fri, 8 Nov 2019 15:05:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225555; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V/mcHvKX7InUGUgT0KSXWZlTMQTnyJjgwdgTbknSH9s=; b=EermZ3D4Jz5xl9pUoGmCJmbvNdlG2Z09tAYt8paKJej3kqghZooKD1pCOlQdQxvBQtGtM2 1+bo23j37M7KrVx2iykm1imivNUa9es6QvuAx69PHtmI9qkfrG6pw6Mi1Q2BHSkF77rGUS swnrfuZk80FGq2qjkyB7+mwy+PrcS3M= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 19/25] screendump: replace FILE with QIOChannel and fix close()/qemu_close() Date: Fri, 8 Nov 2019 19:01:17 +0400 Message-Id: <20191108150123.12213-20-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: wHajOuMYMjS7RgWHsoVTeA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" The file opened for ppm_save() may be a /dev/fdset, in which case a dup fd is added to the fdset. It should be removed by calling qemu_close(), instead of the implicit close() on fclose(). I don't see a convenient way to solve that with stdio streams, so I switched the code to QIOChannel which uses qemu_close(). Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/ui/console.c b/ui/console.c index 77d62fe76d..587edf4ed4 100644 --- a/ui/console.c +++ b/ui/console.c @@ -33,6 +33,7 @@ #include "chardev/char-fe.h" #include "trace.h" #include "exec/memory.h" +#include "io/channel-file.h" =20 #define DEFAULT_BACKSCROLL 512 #define CONSOLE_CURSOR_PERIOD 500 @@ -313,36 +314,31 @@ static bool ppm_save(int fd, DisplaySurface *ds, Erro= r **errp) { int width =3D pixman_image_get_width(ds->image); int height =3D pixman_image_get_height(ds->image); - FILE *f; + g_autoptr(Object) ioc =3D OBJECT(qio_channel_file_new_fd(fd)); + g_autofree char *header =3D NULL; + g_autoptr(pixman_image_t) linebuf =3D NULL; + g_autoptr(GError) error =3D NULL; int y; - int ret; - pixman_image_t *linebuf; - bool success =3D false; =20 trace_ppm_save(fd, ds); - f =3D fdopen(fd, "wb"); - ret =3D fprintf(f, "P6\n%d %d\n%d\n", width, height, 255); - if (ret < 0) { - linebuf =3D NULL; - goto end; + + header =3D g_strdup_printf("P6\n%d %d\n%d\n", width, height, 255); + if (qio_channel_write_all(QIO_CHANNEL(ioc), + header, strlen(header), errp) < 0) { + return false; } + linebuf =3D qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width); for (y =3D 0; y < height; y++) { qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y); - clearerr(f); - ret =3D fwrite(pixman_image_get_data(linebuf), 1, - pixman_image_get_stride(linebuf), f); - (void)ret; - success =3D !ferror(f); + if (qio_channel_write_all(QIO_CHANNEL(ioc), + (char *)pixman_image_get_data(linebuf), + pixman_image_get_stride(linebuf), errp) = < 0) { + return false; + } } =20 -end: - if (!success) { - error_setg(errp, "failed to write to PPM file: %s", strerror(errno= )); - } - qemu_pixman_image_unref(linebuf); - fclose(f); - return success; + return true; } =20 void qmp_screendump(const char *filename, bool has_device, const char *dev= ice, --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226872; cv=none; d=zoho.com; s=zohoarc; b=X5oQqiJ6yL0AuvJOrgTN6OROA6ETI6iPN1Gwht4DyCjcs+58b0g0ij7GqsSISgnaEQwQ0dwH+M195n678nFhN1Q1i4vVoYbE5KoJK5eBi9ouWp9/9Eulw1RsIB3LGlfkqO0/vfNDdHZCoqffoHpYGe5Vnfboy8Q3EtHk0HMX1/Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226872; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=p8tsVTUfoEfZv9VhDPcAAEq3rQMQDEoIiccaTGADpU8=; b=jIU5sd4cEJDAsEIbVZJ6sr5tofbERa/RaiBeM3X4Ttdrevesv7Y3rM/PH+yywVZ9dNKI6qyxJSvcRaGjidQu8HVtFJQ44AldLp74ljqyf17z82XJdN3T+ZWyxmQ/H/VRo4mY9bWnYE4XEgtwISw5MNk+wtXWxcSfD2JPK5K5oAU= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226872468211.78388611142225; Fri, 8 Nov 2019 07:27:52 -0800 (PST) Received: from localhost ([::1]:56164 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT6Aw-0006Sf-AA for importer@patchew.org; Fri, 08 Nov 2019 10:27:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46894) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5pz-00077R-UQ for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5py-0006Up-Ov for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:11 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:35846 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5py-0006Ul-LU for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:10 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-203-_sIIgBRpN5GmaQELGwyHUQ-1; Fri, 08 Nov 2019 10:06:07 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 018C3800C72 for ; Fri, 8 Nov 2019 15:06:07 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 62F8350; Fri, 8 Nov 2019 15:05:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225570; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=p8tsVTUfoEfZv9VhDPcAAEq3rQMQDEoIiccaTGADpU8=; b=P0SYLfkJGVGCb11QTJjMqlUAk20H+WQ5mqs3rRZmk/zucwuAvpgmMnkM1I+T0e4bcj9o+e VzYnts2khSCvYJi8K/ae7bGbj1rKfJaN9Pg8bSv/DbBsgMzb7B5avj8H6BL+nAv2LB/qRP tP7sD80B4N2Q4pc8eLmS4ZWpJDdnY7o= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 20/25] osdep: add qemu_unlink() Date: Fri, 8 Nov 2019 19:01:18 +0400 Message-Id: <20191108150123.12213-21-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: _sIIgBRpN5GmaQELGwyHUQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Add a helper function to match qemu_open() which may return files under the /dev/fdset prefix. Those shouldn't be removed, since it's only a qemu namespace. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/qemu/osdep.h | 1 + util/osdep.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 0f97d68586..9bd3dcfd13 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -462,6 +462,7 @@ int qemu_mprotect_none(void *addr, size_t size); =20 int qemu_open(const char *name, int flags, ...); int qemu_close(int fd); +int qemu_unlink(const char *name); #ifndef _WIN32 int qemu_dup(int fd); #endif diff --git a/util/osdep.c b/util/osdep.c index 3f04326040..f7d06050f7 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -370,6 +370,21 @@ int qemu_close(int fd) return close(fd); } =20 +/* + * Delete a file from the filesystem, unless the filename is /dev/fdset/... + * + * Returns: On success, zero is returned. On error, -1 is returned, + * and errno is set appropriately. + */ +int qemu_unlink(const char *name) +{ + if (g_str_has_prefix(name, "/dev/fdset/")) { + return 0; + } + + return unlink(name); +} + /* * A variant of write(2) which handles partial write. * --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226070; cv=none; d=zoho.com; s=zohoarc; b=LFjIRVIfpu3Ve77QsPlKIXsuo0AfX8Ei8d2CB5+b3seG3q8btFiDe5RWepL+lUVBll/9xuQxeveg5kNmBpVoEPi+gDnFERGwVQqKpeVAlGrVxrG9ELBfUBF6MDVs57J1bBSrFI8TCt0tSTsIyjnsPY6TCEcsM1w+70gfwT4YR7A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226070; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=sTE5AxWhHFArGW+tZpivPFPM3d7d8XOs49LHe2Qq4Fk=; b=GB36lQq9+E8TxacjAhmNIzDQOeCzuj5UaUPhvvspILVGyI3Edp8QYmbt57TBbYDJGToi0uDhPJPwO55B5v8jkJyTAaD/2k2Efvu9nw7GWBNSs25VPqeZEH3kM2EKNjfHUVIokUD5VcQ8dnCP9KQ1A8RqBxcb/2yM4pG633vwJDE= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226070612846.8826979240863; Fri, 8 Nov 2019 07:14:30 -0800 (PST) Received: from localhost ([::1]:55988 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5xx-0000Lb-Dh for importer@patchew.org; Fri, 08 Nov 2019 10:14:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46945) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qB-0007O2-09 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5qA-0006jT-1H for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:22 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:47117 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5q9-0006j1-Tj for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:21 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-230-p0XitW--PeaYvSuDLBzJ1g-1; Fri, 08 Nov 2019 10:06:20 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4FE31800C72 for ; Fri, 8 Nov 2019 15:06:19 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7BFB860BE2; Fri, 8 Nov 2019 15:06:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225581; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sTE5AxWhHFArGW+tZpivPFPM3d7d8XOs49LHe2Qq4Fk=; b=Zbua80ZVjo98chTLG2HFbjCz1CzZmxhqRDL5Hkzo7LVEuHYL2kWJlPJO0LtRavkAacHBLo e9KCzMZkcPSq8gnedllgVaPztZRoLLrPtPjgJbOGQbPwesVj+K5ciHOK5QG7wkjDWam+f7 XZbRWV3lqIecAzsUNpNHFZt32UZ1tu8= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 21/25] screendump: use qemu_unlink() Date: Fri, 8 Nov 2019 19:01:19 +0400 Message-Id: <20191108150123.12213-22-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-MC-Unique: p0XitW--PeaYvSuDLBzJ1g-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Don't attempt to remove /dev/fdset files. Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/console.c b/ui/console.c index 587edf4ed4..e6ac462aa0 100644 --- a/ui/console.c +++ b/ui/console.c @@ -381,7 +381,7 @@ void qmp_screendump(const char *filename, bool has_devi= ce, const char *device, } =20 if (!ppm_save(fd, surface, errp)) { - unlink(filename); + qemu_unlink(filename); } } =20 --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226350; cv=none; d=zoho.com; s=zohoarc; b=XkcmWXF7E1SWejtmtyU7nA4jSPQ9xsSoqaQ+MXu3/AoFaUA9NRc4HeTFE0FgHZeDMYPTe/DpXwDmWXF3wlR6QVWSl+0X1Hc6KEVShZ2wArVkLeGbb0I7vf2D0qQL8mPPzQnjme2ILoOiet9aCb3KZOBW8RPwECF+KJnTbsGn1iQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226350; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=6a3WqY1R8aTdRQZwRQ6BSdOmt8hmHjf7TQvvlhpK+xA=; b=IocRmBXK7tsVq21itaiIhPLbap2u3zH97OOQjnBm/57hI/2TX9C+Id+zxVfncKVJf/TD5GHvUJg6ZzvW56vZk96LiRoe6DEcq6yuLYVIswaqDjFP4M14911q8XSX0aebONH977G+aQODzo0e43KFk5K5O4LQqhDt8Mhph/1/ccI= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226350104197.60881038833884; Fri, 8 Nov 2019 07:19:10 -0800 (PST) Received: from localhost ([::1]:56046 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT62W-000494-D2 for importer@patchew.org; Fri, 08 Nov 2019 10:19:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46992) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qL-0007hS-NL for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5qK-0006zf-3C for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:33 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:24198 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5qJ-0006yP-VW for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:32 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-257-7p8TTBpQOJ2NQBvL8aCKOg-1; Fri, 08 Nov 2019 10:06:30 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 67A89180496F for ; Fri, 8 Nov 2019 15:06:29 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 288265D6AE; Fri, 8 Nov 2019 15:06:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225591; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6a3WqY1R8aTdRQZwRQ6BSdOmt8hmHjf7TQvvlhpK+xA=; b=LhUTyHuJtQUObRWcGJRd7ecCjw/nLERc7P4KV3n3z0TEZkWIzmWz+XUWbWCUDrO0Ghs8v8 EFLnp/3hB04V7bXgsnnLhSlG1sRmI+a++WmY2f95YTmGwNaCWgg/Mxlb85XqklvnaJe0EH fSXG2p8wG2LAgjdaeKWP9Xca7JlJmRw= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 22/25] console: make screendump asynchronous Date: Fri, 8 Nov 2019 19:01:20 +0400 Message-Id: <20191108150123.12213-23-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-MC-Unique: 7p8TTBpQOJ2NQBvL8aCKOg-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Make screendump asynchronous to provide correct screendumps. For now, HMP doesn't have async support, so it has to remain synchronous and potentially incorrect to avoid races (following patches will add HMP asynchronous commands) Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=3D1230527 Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/ui/console.h | 3 ++ monitor/hmp-cmds.c | 2 +- qapi/ui.json | 3 +- ui/console.c | 117 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 113 insertions(+), 12 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 281f9c145b..a1935557cc 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -74,6 +74,9 @@ typedef struct MouseTransformInfo { } MouseTransformInfo; =20 void hmp_mouse_set(Monitor *mon, const QDict *qdict); +void hmp_screendump_sync(const char *filename, + bool has_device, const char *device, + bool has_head, int64_t head, Error **errp); =20 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx constants) */ diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index b2551c16d1..c52e78fedf 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -2308,7 +2308,7 @@ void hmp_screendump(Monitor *mon, const QDict *qdict) int64_t head =3D qdict_get_try_int(qdict, "head", 0); Error *err =3D NULL; =20 - qmp_screendump(filename, id !=3D NULL, id, id !=3D NULL, head, &err); + hmp_screendump_sync(filename, id !=3D NULL, id, id !=3D NULL, head, &e= rr); hmp_handle_error(mon, &err); } =20 diff --git a/qapi/ui.json b/qapi/ui.json index e04525d8b4..148ae4c062 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -96,7 +96,8 @@ # ## { 'command': 'screendump', - 'data': {'filename': 'str', '*device': 'str', '*head': 'int'} } + 'data': {'filename': 'str', '*device': 'str', '*head': 'int'}, + 'async': true } =20 ## # =3D=3D Spice diff --git a/ui/console.c b/ui/console.c index e6ac462aa0..fd87605b7c 100644 --- a/ui/console.c +++ b/ui/console.c @@ -34,6 +34,7 @@ #include "trace.h" #include "exec/memory.h" #include "io/channel-file.h" +#include "monitor/monitor.h" =20 #define DEFAULT_BACKSCROLL 512 #define CONSOLE_CURSOR_PERIOD 500 @@ -118,6 +119,13 @@ typedef enum { TEXT_CONSOLE_FIXED_SIZE } console_type_t; =20 +struct qmp_screendump { + int fd; + gchar *filename; + QmpReturn *ret; + QLIST_ENTRY(qmp_screendump) link; +}; + struct QemuConsole { Object parent; =20 @@ -168,6 +176,8 @@ struct QemuConsole { uint8_t out_fifo_buf[16]; QEMUTimer *kbd_timer; =20 + QLIST_HEAD(, qmp_screendump) qmp_screendumps; + QTAILQ_ENTRY(QemuConsole) next; }; =20 @@ -261,8 +271,51 @@ static void gui_setup_refresh(DisplayState *ds) ds->have_text =3D have_text; } =20 +static void qmp_screendump_finish(QemuConsole *con, struct qmp_screendump = *dump) +{ + Error *err =3D NULL; + DisplaySurface *surface; + + if (qmp_return_is_cancelled(dump->ret)) { + goto cleanup; + } + + surface =3D qemu_console_surface(con); + if (!surface) { + error_setg(&err, "no surface"); + } else { + /* + * FIXME: async save with coroutine? it would have to copy or + * lock the surface. + */ + if (!ppm_save(dump->fd, surface, &err)) { + qemu_unlink(dump->filename); + } + dump->fd =3D -1; + } + + if (err) { + qmp_return_error(dump->ret, err); + } else { + qmp_screendump_return(dump->ret); + } + +cleanup: + if (dump->fd !=3D -1) { + qemu_close(dump->fd); + } + g_free(dump->filename); + QLIST_REMOVE(dump, link); + g_free(dump); +} + void graphic_hw_update_done(QemuConsole *con) { + struct qmp_screendump *dump, *next; + + QLIST_FOREACH_SAFE(dump, &con->qmp_screendumps, link, next) { + qmp_screendump_finish(con, dump); + } } =20 void graphic_hw_update(QemuConsole *con) @@ -341,31 +394,42 @@ static bool ppm_save(int fd, DisplaySurface *ds, Erro= r **errp) return true; } =20 -void qmp_screendump(const char *filename, bool has_device, const char *dev= ice, - bool has_head, int64_t head, Error **errp) + +static QemuConsole *get_console(bool has_device, const char *device, + bool has_head, int64_t head, Error **errp) { - QemuConsole *con; - DisplaySurface *surface; - int fd; + QemuConsole *con =3D NULL; =20 if (has_device) { con =3D qemu_console_lookup_by_device_name(device, has_head ? head= : 0, errp); - if (!con) { - return; - } } else { if (has_head) { error_setg(errp, "'head' must be specified together with 'devi= ce'"); - return; + return NULL; } con =3D qemu_console_lookup_by_index(0); if (!con) { error_setg(errp, "There is no console to take a screendump fro= m"); - return; } } =20 + return con; +} + +void hmp_screendump_sync(const char *filename, + bool has_device, const char *device, + bool has_head, int64_t head, Error **errp) +{ + DisplaySurface *surface; + QemuConsole *con =3D get_console(has_device, device, has_head, head, e= rrp); + int fd; + + if (!con) { + return; + } + /* This may not complete the drawing with Spice, you may have + * glitches or outdated dumps, use qmp instead! */ graphic_hw_update(con); surface =3D qemu_console_surface(con); if (!surface) { @@ -385,6 +449,38 @@ void qmp_screendump(const char *filename, bool has_dev= ice, const char *device, } } =20 +void qmp_screendump(const char *filename, + bool has_device, const char *device, + bool has_head, int64_t head, + QmpReturn *qret) +{ + Error *err =3D NULL; + struct qmp_screendump *dump =3D NULL; + QemuConsole *con =3D get_console(has_device, device, has_head, head, &= err); + int fd; + + if (!con) { + qmp_return_error(qret, err); + return; + } + + fd =3D qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 06= 66); + if (fd =3D=3D -1) { + error_setg(&err, "failed to open file '%s': %s", + filename, strerror(errno)); + qmp_return_error(qret, err); + return; + } + + dump =3D g_new(struct qmp_screendump, 1); + dump->fd =3D fd; + dump->filename =3D g_strdup(filename); + dump->ret =3D qret; + QLIST_INSERT_HEAD(&con->qmp_screendumps, dump, link); + + graphic_hw_update(con); +} + void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata) { if (!con) { @@ -1295,6 +1391,7 @@ static QemuConsole *new_console(DisplayState *ds, con= sole_type_t console_type, obj =3D object_new(TYPE_QEMU_CONSOLE); s =3D QEMU_CONSOLE(obj); s->head =3D head; + QLIST_INIT(&s->qmp_screendumps); object_property_add_link(obj, "device", TYPE_DEVICE, (Object **)&s->device, object_property_allow_set_link, --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226504; cv=none; d=zoho.com; s=zohoarc; b=gGM05RHMCKxAVUoP4ZWUXbPcb29AKhNzdXXvTpIlsEfzVVVbxcsTeHDc7JqIogbYEfuNKFNt3D7euwOE8IbkFIoKWL5Xf94TvRQFECeZuRy/+lzSqVOfqwGVXwcDAgCaErRJHCWbARIXEux7Gup3h3Irir9AgrISpbaXg96HbKo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226504; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8COIJESeTAOSHPsFPA7tx+V+NQP3cSzWSMBW9wKxKRE=; b=a+z2iSwqLYvmxQYcoZ5xEhtrVRDos746UzG+NJGHGqRFzKGbox9VNYF7qonHhU3uI3j40ZhxrxxoThCAqBQR2PJpwFaxrurW1LYLxEBwXj+DyVbNlM3unPOk0FZWC3LuD1eNBsFRw2CaMyNmhnYu0A3VlgBpWmg7i1FMzpPRD4A= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226504417337.54021033202946; Fri, 8 Nov 2019 07:21:44 -0800 (PST) Received: from localhost ([::1]:56094 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT650-0007mF-44 for importer@patchew.org; Fri, 08 Nov 2019 10:21:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:47049) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qY-00084N-Lj for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5qX-0007KH-Ja for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:46 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:58922 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5qX-0007K8-G3 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:45 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-220-B34aZhinPSCwpmVUNoN-pw-1; Fri, 08 Nov 2019 10:06:43 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B0C44107ACC4 for ; Fri, 8 Nov 2019 15:06:42 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 423AD6084E; Fri, 8 Nov 2019 15:06:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225605; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8COIJESeTAOSHPsFPA7tx+V+NQP3cSzWSMBW9wKxKRE=; b=RZg0z+49IchjJ332ztKvaZcLctcWL5rJSyUKvaz73uNdUA0AbDa46UNrI+Fq9pqBkAMxgM /3aDtCGTQ83NnlkBjUA9LUBc0V4hysAbps+WLB743mS7WP3Hw13MkB+HUcYtMkY1AvKISS Bc6e0Yz8nPqCCeou2D820VjKv9bgGOY= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 23/25] monitor: start making qmp_human_monitor_command() asynchronous Date: Fri, 8 Nov 2019 19:01:21 +0400 Message-Id: <20191108150123.12213-24-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-MC-Unique: B34aZhinPSCwpmVUNoN-pw-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This prepares the work for HMP commands to be asynchronous. Start making QMP human-monitor-command asynchronous, although QmpReturn is used synchronously on error or after handle_hmp_command(). Signed-off-by: Marc-Andr=C3=A9 Lureau --- monitor/misc.c | 14 ++++++++------ qapi/misc.json | 3 ++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/monitor/misc.c b/monitor/misc.c index bb33ca73cf..3617f855f5 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -115,8 +115,8 @@ static QLIST_HEAD(, MonFdset) mon_fdsets; =20 static HMPCommand hmp_info_cmds[]; =20 -char *qmp_human_monitor_command(const char *command_line, bool has_cpu_ind= ex, - int64_t cpu_index, Error **errp) +void qmp_human_monitor_command(const char *command_line, bool has_cpu_inde= x, + int64_t cpu_index, QmpReturn *qret) { char *output =3D NULL; Monitor *old_mon; @@ -130,15 +130,15 @@ char *qmp_human_monitor_command(const char *command_l= ine, bool has_cpu_index, if (has_cpu_index) { int ret =3D monitor_set_cpu(cpu_index); if (ret < 0) { - cur_mon =3D old_mon; - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", + Error *err =3D NULL; + error_setg(&err, QERR_INVALID_PARAMETER_VALUE, "cpu-index", "a CPU number"); + qmp_return_error(qret, err); goto out; } } =20 handle_hmp_command(&hmp, command_line); - cur_mon =3D old_mon; =20 qemu_mutex_lock(&hmp.common.mon_lock); if (qstring_get_length(hmp.common.outbuf) > 0) { @@ -148,9 +148,11 @@ char *qmp_human_monitor_command(const char *command_li= ne, bool has_cpu_index, } qemu_mutex_unlock(&hmp.common.mon_lock); =20 + qmp_human_monitor_command_return(qret, output); + out: + cur_mon =3D old_mon; monitor_data_destroy(&hmp.common); - return output; } =20 /** diff --git a/qapi/misc.json b/qapi/misc.json index 33b94e3589..15a8bc0d0d 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1054,7 +1054,8 @@ { 'command': 'human-monitor-command', 'data': {'command-line': 'str', '*cpu-index': 'int'}, 'returns': 'str', - 'features': [ 'savevm-monitor-nodes' ] } + 'features': [ 'savevm-monitor-nodes' ], + 'async': true } =20 ## # @change: --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226657; cv=none; d=zoho.com; s=zohoarc; b=QWu81PfZKwJQzXpcwVYNxST+WOycnusAklnWFdzr3FLim+2tayR7RK/3MdhmkOjSEmGNDomgJ0FxmJKnkur+bML6mDwza7GjaA4r0PQQ/rpMV3fWS192JzBXG5Hm9CTNMp4VjcCGehwX5C44nJrWqCc40EhqofPwlYIY+s7ihIM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226657; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=t5+8G8AEV1Ea0pzG+NwjP+QZF/+PogJ5CNni0zkdM0g=; b=ltE6U2xzxrJWVcdYo0BoA6TcS5dyi+x/rP2nNjB6OHnjiqbig8+EgKFx9+C7gKLQ1PGHCn8bIKCk9daKQnbvsUH7u7Fic+uC0irR37hZ7hGzMEAFBiGIuv6FwAdEBRMswBleWvRlot1RYFPsYzG/XU2HRy8DpCPKrG4hOxSfnJw= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157322665764471.63486291902075; Fri, 8 Nov 2019 07:24:17 -0800 (PST) Received: from localhost ([::1]:56120 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT67U-00024K-A9 for importer@patchew.org; Fri, 08 Nov 2019 10:24:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:47069) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qg-0008El-9g for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5qe-0007Oy-F0 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:54 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:42268 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5qe-0007Nt-BE for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:06:52 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-255-WcjvzvK1NqKIrJr1yuL7gQ-1; Fri, 08 Nov 2019 10:06:50 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 04D72180496F for ; Fri, 8 Nov 2019 15:06:50 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8F0046084E; Fri, 8 Nov 2019 15:06:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225612; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=t5+8G8AEV1Ea0pzG+NwjP+QZF/+PogJ5CNni0zkdM0g=; b=I9oNEHehXw8dGHMg45a3KK6dq6L+A6SQ3GCpVjuIHWNMp/Yao1722hImUpfO7jawE1d0Zz HfmM+54HflsgMmug0aLIup3DOJvbCcVUTFa6syAmIn7xCaqRJGdESmCyVa2TAVGkwN9fXK jdUlnK+Y+9vYwA89uaa5mU3nm3Y16ic= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 24/25] monitor: teach HMP about asynchronous commands Date: Fri, 8 Nov 2019 19:01:22 +0400 Message-Id: <20191108150123.12213-25-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-MC-Unique: WcjvzvK1NqKIrJr1yuL7gQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Similar to how we handle both synchronous and asynchronous commands in QMP, HMP gains a new async_cmd() that will allow the command to complete asynchronously. For interactive reasons, and command ordering, the HMP monitor is suspended until the asynchronous command completes. It is expected that HMP async commands will be implemented re-using QMP async commands counterparts, so it reuses the QmpSession/QmpReturn for context handling (instead of introducing HmpSession/HmpReturn and having to convert from one to the other as we call QMP counterparts). hmp_dispatch_return_cb() will handle printing the result to the current monitor. It may have different ways to print the QmpReturn result to the current monitor. Currently, only error reporting is implemented. QMP human-monitor-command is modified to deal with an async HMP commands too. It creates a temporary session, and the return callback will return asynchronously to the original QMP command and destroy the temporary monitor when hmp->for_qmp_command is set. Signed-off-by: Marc-Andr=C3=A9 Lureau --- monitor/hmp.c | 110 +++++++++++++++++++++++++++++++++++-- monitor/misc.c | 40 -------------- monitor/monitor-internal.h | 9 ++- 3 files changed, 113 insertions(+), 46 deletions(-) diff --git a/monitor/hmp.c b/monitor/hmp.c index 8942e28933..07f305141d 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -26,11 +26,15 @@ #include #include "monitor-internal.h" #include "qapi/error.h" +#include "qapi/qapi-commands-misc.h" +#include "qapi/qmp/qerror.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qnum.h" +#include "qapi/qmp/qstring.h" #include "qemu/config-file.h" #include "qemu/ctype.h" #include "qemu/cutils.h" +#include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/option.h" #include "qemu/units.h" @@ -38,6 +42,8 @@ #include "sysemu/runstate.h" #include "trace.h" =20 +static bool handle_hmp_command(MonitorHMP *mon, const char *cmdline); + static void monitor_command_cb(void *opaque, const char *cmdline, void *readline_opaque) { @@ -1056,7 +1062,7 @@ fail: return NULL; } =20 -void handle_hmp_command(MonitorHMP *mon, const char *cmdline) +static bool handle_hmp_command(MonitorHMP *mon, const char *cmdline) { QDict *qdict; const HMPCommand *cmd; @@ -1066,7 +1072,7 @@ void handle_hmp_command(MonitorHMP *mon, const char *= cmdline) =20 cmd =3D monitor_parse_command(mon, cmdline, &cmdline, hmp_cmds); if (!cmd) { - return; + return false; } =20 qdict =3D monitor_parse_arguments(&mon->common, &cmdline, cmd); @@ -1076,11 +1082,19 @@ void handle_hmp_command(MonitorHMP *mon, const char= *cmdline) } monitor_printf(&mon->common, "Try \"help %.*s\" for more informati= on\n", (int)(cmdline - cmd_start), cmd_start); - return; + return false; } =20 - cmd->cmd(&mon->common, qdict); + if (cmd->async) { + QmpReturn *qret =3D qmp_return_new(&mon->qmp_session, NULL); + monitor_suspend(&mon->common); + cmd->async_cmd(&mon->common, qdict, qret); + } else { + cmd->cmd(&mon->common, qdict); + } qobject_unref(qdict); + + return cmd->async; } =20 static void cmd_completion(MonitorHMP *mon, const char *name, const char *= list) @@ -1395,6 +1409,59 @@ static void monitor_readline_flush(void *opaque) monitor_flush(&mon->common); } =20 +static void free_hmp_monitor(void *opaque) +{ + MonitorHMP *hmp =3D opaque; + + qmp_session_destroy(&hmp->qmp_session); + monitor_data_destroy(&hmp->common); + g_free(hmp); +} + +static AioContext *monitor_get_aio_context(void) +{ + return iothread_get_aio_context(mon_iothread); +} + +static void qmp_human_monitor_command_finish(MonitorHMP *hmp, QmpReturn *q= ret) +{ + char *output; + + qemu_mutex_lock(&hmp->common.mon_lock); + if (qstring_get_length(hmp->common.outbuf) > 0) { + output =3D g_strdup(qstring_get_str(hmp->common.outbuf)); + } else { + output =3D g_strdup(""); + } + qemu_mutex_unlock(&hmp->common.mon_lock); + + qmp_human_monitor_command_return(qret, output); + + if (hmp->for_qmp_command) { + aio_bh_schedule_oneshot(monitor_get_aio_context(), + free_hmp_monitor, hmp); + } +} + +static void hmp_dispatch_return_cb(QmpSession *session, QDict *rsp) +{ + MonitorHMP *hmp =3D container_of(session, MonitorHMP, qmp_session); + QDict *err =3D qdict_get_qdict(rsp, "error"); + Monitor *old_mon =3D cur_mon; + + cur_mon =3D &hmp->common; + if (err) { + error_report("%s", qdict_get_str(err, "desc")); + } /* XXX: else, report depending on command */ + + if (hmp->for_qmp_command) { + qmp_human_monitor_command_finish(hmp, hmp->for_qmp_command); + } else { + monitor_resume(&hmp->common); + } + cur_mon =3D old_mon; +} + void monitor_init_hmp(Chardev *chr, bool use_readline) { MonitorHMP *mon =3D g_new0(MonitorHMP, 1); @@ -1411,7 +1478,42 @@ void monitor_init_hmp(Chardev *chr, bool use_readlin= e) monitor_read_command(mon, 0); } =20 + qmp_session_init(&mon->qmp_session, + NULL, NULL, hmp_dispatch_return_cb); qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read, monitor_r= ead, monitor_event, NULL, &mon->common, NULL, true= ); monitor_list_append(&mon->common); } + +void qmp_human_monitor_command(const char *command_line, bool has_cpu_inde= x, + int64_t cpu_index, QmpReturn *qret) +{ + Monitor *old_mon; + MonitorHMP *hmp =3D g_new0(MonitorHMP, 1); + + monitor_data_init(&hmp->common, false, true, false); + qmp_session_init(&hmp->qmp_session, NULL, NULL, hmp_dispatch_return_cb= ); + hmp->for_qmp_command =3D qret; + + old_mon =3D cur_mon; + cur_mon =3D &hmp->common; + + if (has_cpu_index) { + int ret =3D monitor_set_cpu(cpu_index); + if (ret < 0) { + Error *err =3D NULL; + error_setg(&err, QERR_INVALID_PARAMETER_VALUE, "cpu-index", + "a CPU number"); + qmp_return_error(qret, err); + free_hmp_monitor(hmp); + goto out; + } + } + + if (!handle_hmp_command(hmp, command_line)) { + qmp_human_monitor_command_finish(hmp, qret); + } + +out: + cur_mon =3D old_mon; +} diff --git a/monitor/misc.c b/monitor/misc.c index 3617f855f5..ed672db650 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -115,46 +115,6 @@ static QLIST_HEAD(, MonFdset) mon_fdsets; =20 static HMPCommand hmp_info_cmds[]; =20 -void qmp_human_monitor_command(const char *command_line, bool has_cpu_inde= x, - int64_t cpu_index, QmpReturn *qret) -{ - char *output =3D NULL; - Monitor *old_mon; - MonitorHMP hmp =3D {}; - - monitor_data_init(&hmp.common, false, true, false); - - old_mon =3D cur_mon; - cur_mon =3D &hmp.common; - - if (has_cpu_index) { - int ret =3D monitor_set_cpu(cpu_index); - if (ret < 0) { - Error *err =3D NULL; - error_setg(&err, QERR_INVALID_PARAMETER_VALUE, "cpu-index", - "a CPU number"); - qmp_return_error(qret, err); - goto out; - } - } - - handle_hmp_command(&hmp, command_line); - - qemu_mutex_lock(&hmp.common.mon_lock); - if (qstring_get_length(hmp.common.outbuf) > 0) { - output =3D g_strdup(qstring_get_str(hmp.common.outbuf)); - } else { - output =3D g_strdup(""); - } - qemu_mutex_unlock(&hmp.common.mon_lock); - - qmp_human_monitor_command_return(qret, output); - -out: - cur_mon =3D old_mon; - monitor_data_destroy(&hmp.common); -} - /** * Is @name in the '|' separated list of names @list? */ diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index b8994f896a..d13da7db31 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -72,7 +72,10 @@ typedef struct HMPCommand { const char *params; const char *help; const char *flags; /* p=3Dpreconfig */ - void (*cmd)(Monitor *mon, const QDict *qdict); + union { + void (*cmd)(Monitor *mon, const QDict *qdict); + void (*async_cmd)(Monitor *mon, const QDict *qdict, QmpReturn *qre= t); + }; /* * @sub_table is a list of 2nd level of commands. If it does not exist, * cmd should be used. If it exists, sub_table[?].cmd should be @@ -80,6 +83,7 @@ typedef struct HMPCommand { */ struct HMPCommand *sub_table; void (*command_completion)(ReadLineState *rs, int nb_args, const char = *str); + bool async; } HMPCommand; =20 struct Monitor { @@ -120,6 +124,8 @@ struct MonitorHMP { * These members can be safely accessed without locks. */ ReadLineState *rs; + QmpReturn *for_qmp_command; + QmpSession qmp_session; }; =20 typedef struct { @@ -175,7 +181,6 @@ void monitor_qmp_bh_dispatcher(void *data); =20 int get_monitor_def(int64_t *pval, const char *name); void help_cmd(Monitor *mon, const char *name); -void handle_hmp_command(MonitorHMP *mon, const char *cmdline); int hmp_compare_cmd(const char *name, const char *list); =20 #endif --=20 2.24.0 From nobody Sat Apr 27 05:16:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573226789; cv=none; d=zoho.com; s=zohoarc; b=Xw60cvhrLHiHdp1Gzp2l78K/GnTOMXtmP/WYshLKiGHiX1jyUD+jSXRbY0XvkseyB9kT93N6Ju4RdDI1QzBVQ4gqY2o1fvcHx/agLMRi/5jhNw45D/MmuF5a5iFVYSCa2AblvvWUc5Wb7zsgAFnvt9OdhITmH2AtczpKXrKXTlg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573226789; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=l8YNejVxznOcDAaMUcNNOGhdD0r56jyIWDDN7FE48fc=; b=FNqYP0kV91b6qxObiSeUVUjg1iuCxnxP5r5C1qAXXuiLbuMW67rEomPz5VqrCXy4kzaHpeFYksj7vRHTfuFX0mxqMw6NnGVpLLFx0G3sr0tryeTQqhSFV4nDK9lDWttLa1vb5Ab797hsgtF0HN75c0WAS5QUZuOGzpXf9vAEEt4= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573226789245594.9712508118116; Fri, 8 Nov 2019 07:26:29 -0800 (PST) Received: from localhost ([::1]:56140 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT69Z-0004fR-Vz for importer@patchew.org; Fri, 08 Nov 2019 10:26:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:47173) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT5qu-00006l-2n for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:07:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT5qs-0007uw-SS for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:07:08 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:44199 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iT5qs-0007s1-O1 for qemu-devel@nongnu.org; Fri, 08 Nov 2019 10:07:06 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-382-4HcH353HN_uQkdXD2rCBGQ-1; Fri, 08 Nov 2019 10:07:05 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 81724180496F for ; Fri, 8 Nov 2019 15:07:02 +0000 (UTC) Received: from localhost (ovpn-112-25.ams2.redhat.com [10.36.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4127C50; Fri, 8 Nov 2019 15:06:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573225626; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l8YNejVxznOcDAaMUcNNOGhdD0r56jyIWDDN7FE48fc=; b=Xusmo5R3odNFLvpu/KRKzM1NjbuJsSNJTcnNw6COH9tDVxEiM12RsEPOEw79hMg8ETMsXJ 1bj7KUyhqbaEUupgCgieTUt5DAr6uSM5Hmzu3awvQACuj5LyZZDXkIu5J3MVX5o5k+TvFx PuFYvChkWygVNbeC0Y2J5i6/hcn2IiQ= From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Subject: [PATCH v6 25/25] hmp: call the asynchronous QMP screendump to fix outdated/glitches Date: Fri, 8 Nov 2019 19:01:23 +0400 Message-Id: <20191108150123.12213-26-marcandre.lureau@redhat.com> In-Reply-To: <20191108150123.12213-1-marcandre.lureau@redhat.com> References: <20191108150123.12213-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: 4HcH353HN_uQkdXD2rCBGQ-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , armbru@redhat.com, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" In order to fix the bad screendumps (same as rhbz#1230527), call into the asynchonous version of the QMP command. Signed-off-by: Marc-Andr=C3=A9 Lureau --- hmp-commands.hx | 3 ++- include/ui/console.h | 5 ++--- monitor/hmp-cmds.c | 6 ++---- ui/console.c | 32 -------------------------------- 4 files changed, 6 insertions(+), 40 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index cfcc044ce4..82b9236deb 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -278,7 +278,8 @@ ETEXI .params =3D "filename [device [head]]", .help =3D "save screen from head 'head' of display device 'd= evice' " "into PPM image 'filename'", - .cmd =3D hmp_screendump, + .async_cmd =3D hmp_screendump_async, + .async =3D true, }, =20 STEXI diff --git a/include/ui/console.h b/include/ui/console.h index a1935557cc..d0a2a2066f 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -6,6 +6,7 @@ #include "qemu/notify.h" #include "qemu/error-report.h" #include "qapi/qapi-types-ui.h" +#include "qapi/qmp/dispatch.h" =20 #ifdef CONFIG_OPENGL # include @@ -74,9 +75,7 @@ typedef struct MouseTransformInfo { } MouseTransformInfo; =20 void hmp_mouse_set(Monitor *mon, const QDict *qdict); -void hmp_screendump_sync(const char *filename, - bool has_device, const char *device, - bool has_head, int64_t head, Error **errp); +void hmp_screendump_async(Monitor *mon, const QDict *qdict, QmpReturn *qre= t); =20 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx constants) */ diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index c52e78fedf..93b061cf4f 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -2301,15 +2301,13 @@ err_out: goto out; } =20 -void hmp_screendump(Monitor *mon, const QDict *qdict) +void hmp_screendump_async(Monitor *mon, const QDict *qdict, QmpReturn *qre= t) { const char *filename =3D qdict_get_str(qdict, "filename"); const char *id =3D qdict_get_try_str(qdict, "device"); int64_t head =3D qdict_get_try_int(qdict, "head", 0); - Error *err =3D NULL; =20 - hmp_screendump_sync(filename, id !=3D NULL, id, id !=3D NULL, head, &e= rr); - hmp_handle_error(mon, &err); + qmp_screendump(filename, id !=3D NULL, id, id !=3D NULL, head, qret); } =20 void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) diff --git a/ui/console.c b/ui/console.c index fd87605b7c..a6f8e34e61 100644 --- a/ui/console.c +++ b/ui/console.c @@ -417,38 +417,6 @@ static QemuConsole *get_console(bool has_device, const= char *device, return con; } =20 -void hmp_screendump_sync(const char *filename, - bool has_device, const char *device, - bool has_head, int64_t head, Error **errp) -{ - DisplaySurface *surface; - QemuConsole *con =3D get_console(has_device, device, has_head, head, e= rrp); - int fd; - - if (!con) { - return; - } - /* This may not complete the drawing with Spice, you may have - * glitches or outdated dumps, use qmp instead! */ - graphic_hw_update(con); - surface =3D qemu_console_surface(con); - if (!surface) { - error_setg(errp, "no surface"); - return; - } - - fd =3D qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 06= 66); - if (fd =3D=3D -1) { - error_setg(errp, "failed to open file '%s': %s", filename, - strerror(errno)); - return; - } - - if (!ppm_save(fd, surface, errp)) { - qemu_unlink(filename); - } -} - void qmp_screendump(const char *filename, bool has_device, const char *device, bool has_head, int64_t head, --=20 2.24.0