From patchwork Fri Mar 26 07:48:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12165961 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 809D6C433C1 for ; Fri, 26 Mar 2021 07:50:15 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 01DEB61A02 for ; Fri, 26 Mar 2021 07:50:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 01DEB61A02 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44126 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPhET-0003v3-VM for qemu-devel@archiver.kernel.org; Fri, 26 Mar 2021 03:50:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53896) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDF-0002cR-1Z for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:48:57 -0400 Received: from mout.web.de ([212.227.15.3]:39735) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhD8-0002WP-Rj for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:48:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1616744926; bh=dn5JnxLD03A1MjGbpLQHn5ts0L4MXedl8j8wX6j74LA=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=AGtjUAfX/PGKmfY/Kyrmi409LKaHufQUUvcdP9iRm6SGqNEluhL8/4HTtFKHiPu3l kCju/nHdHQc7PJMEEYneefMFUXfvAs0lqESNg80Wd/4O5hma5fyM7A/LxMUduO5fMn D1vh8qPWuK9FnIJlttWcTHB8/cuPSzNQ4x7biSmE= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([89.247.255.242]) by smtp.web.de (mrweb006 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MeUbo-1lxeyv41hs-00aXha; Fri, 26 Mar 2021 08:48:46 +0100 Date: Fri, 26 Mar 2021 08:48:44 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v4 1/4] chardev/char.c: Move object_property_try_add_child out of chardev_new Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:AU2Rgykes3wSvIiBmIVH62grL5Wq+sRy75PwqFtai42H82ywmzA IMVhHsWvGJD2jj7eo/IQo/9GA7wIxfsWjIztVD0zhblOeA+qs47iLeL18Qc/nSNYUlBpCX3 +PPb5JfxsxFsp/qn7E66WG7z3Eq51nhH8unbS6klH/sSBi+ycKGhbAkGF8U4kEjBcCU0pbl NaPOPIJRKEotvd5EMj2Uw== X-UI-Out-Filterresults: notjunk:1;V03:K0:SkUsXfJL4k0=:YHzGQgB0dlUDlHQDn1kZCn ZRtsRr46QCHXq6VmGYapiMC5XwRd7ZArLYdiC2/pnaS6+dywRtA3mww7MWdnWYAzW3za6Io1z KI+yNzdB4w3ALMSJiBgb0Z3X5tPVHNMjHwkIbiCxfOy5KFbcK6ucWdOz00M5EuUxesINZvJzu CSevNahWJd6grlWa3R36Mih3okPXQpjuSePdPCcz3BNkDMYf39t2An/uHt0dmpGa4sGwuUs0r u6fGyR6YYD/MnpD50683TnTA0ZhfNma69Tsi+pi2+ekNgCN1qCSW8un04S8m/KYcEMDP58o/I 341dOoyeYd1N1IlvLWp30voeyCehZMgQCQdByq/DY93KBW3QiB/HPhk0I1vAa4ySedbvT7CW5 ScgNx7kTj+kb7y6lY7U4eIr/cUQO4r5NndGRCfCWuoAYgvDx0a28WpNKPvwwiu/Neftlharbu +YR/yFyZSNs02vEuHtOEHd2rgj/FuxIzYj5t6d56O/z5CIyJrOslwwT1UDUgdhaPcmSsIHFqg 0uiQ/5zfdkdscmwXgYOoUjjGght5BJ3KCYsgMfQ8jyklWvqQhZoIw0adRYQhLpWeF0IaTrVqM FMXotRHNkmjihRYvzS+QHPp57FfRgBenBtWOkHOzikAGQBzc5hTOrPREGpW7i+IQF2588R7rZ 6ZKlXF+PeXWrbFJZdUzkCmUvqQMFoG2Jaolz5mK8KYQHlGYXtuzOc3RRGwhe0dJEYJ4ebiyOr youWNY4mKkWn1hTLUz/TQqazCOJ3h7GXOfDkJvJkfKnKOYATSgxpObW6+qR9PsCFan0ndA66X 9ZcZClFQGZcPg9tfFkecodN2xKKWwIfAJw62JID2o8uByM2xOBf7UF2xsSfA2p71pVfws0b8D Y6Ef543vQr9x/qwJFgO+4W9w5WUl2aFRJsJfa1cj+gHitCUHG2b19d5vPAlvb3nUzyFyXXGER 1NjWVKDlSVFYC85KROTgpUiGYbrE6v+cTI0XoceZQuktQSwFzBNXZS9YVtI7Xr58IHaldwbRy XTpGXTTZwwkxM5zpp3why/ao4LAdUnuCXCGlpxfXlKVlOD0UrBQuUye/3d1O+UVEYkFegXGLG eQzGj4aCjU6Ksh3AMSGOB85tPLyq7jjR7b71FAgBDxxJqGkIxHwIfOkIhx0KqBTUlJ78ohDlL Kr13g+jvUTYxMN3qAxJvPNEat8PsH3oE8KwzIgmWnz7lfd7lqh3BfcvDr9/ldKVgX2OB4= Received-SPF: pass client-ip=212.227.15.3; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: Laurent Vivier , Marc-Andre Lureau , Thomas Huth , Li Zhang , Paolo Bonzini Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Move object_property_try_add_child out of chardev_new into it's callers. This is a preparation for the next patches to fix yank with the chardev-change case. Signed-off-by: Lukas Straub Reviewed-by: Marc-André Lureau Tested-by: Li Zhang --- chardev/char.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) -- 2.30.2 diff --git a/chardev/char.c b/chardev/char.c index 140d6d9d36..48f321b3e1 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -975,7 +975,9 @@ static Chardev *chardev_new(const char *id, const char *typename, qemu_char_open(chr, backend, &be_opened, &local_err); if (local_err) { - goto end; + error_propagate(errp, local_err); + object_unref(obj); + return NULL; } if (!chr->filename) { @@ -985,22 +987,6 @@ static Chardev *chardev_new(const char *id, const char *typename, qemu_chr_be_event(chr, CHR_EVENT_OPENED); } - if (id) { - object_property_try_add_child(get_chardevs_root(), id, obj, - &local_err); - if (local_err) { - goto end; - } - object_unref(obj); - } - -end: - if (local_err) { - error_propagate(errp, local_err); - object_unref(obj); - return NULL; - } - return chr; } @@ -1009,6 +995,7 @@ Chardev *qemu_chardev_new(const char *id, const char *typename, GMainContext *gcontext, Error **errp) { + Chardev *chr; g_autofree char *genid = NULL; if (!id) { @@ -1016,7 +1003,19 @@ Chardev *qemu_chardev_new(const char *id, const char *typename, id = genid; } - return chardev_new(id, typename, backend, gcontext, errp); + chr = chardev_new(id, typename, backend, gcontext, errp); + if (!chr) { + return NULL; + } + + if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr), + errp)) { + object_unref(OBJECT(chr)); + return NULL; + } + object_unref(OBJECT(chr)); + + return chr; } ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, @@ -1037,6 +1036,13 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, return NULL; } + if (!object_property_try_add_child(get_chardevs_root(), id, OBJECT(chr), + errp)) { + object_unref(OBJECT(chr)); + return NULL; + } + object_unref(OBJECT(chr)); + ret = g_new0(ChardevReturn, 1); if (CHARDEV_IS_PTY(chr)) { ret->pty = g_strdup(chr->filename + 4); From patchwork Fri Mar 26 07:48:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12165963 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1112C433DB for ; Fri, 26 Mar 2021 07:50:15 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E70861A32 for ; Fri, 26 Mar 2021 07:50:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E70861A32 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44162 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPhEU-0003vq-Eu for qemu-devel@archiver.kernel.org; Fri, 26 Mar 2021 03:50:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53902) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDF-0002dU-Us for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:48:57 -0400 Received: from mout.web.de ([212.227.15.3]:50581) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDE-0002Y5-7x for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:48:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1616744929; bh=4vX8JCGCMY7S2JtCPus/wvHvOi2j74VvUfJZWFN3jWg=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=hHmu9iJHuyGCRdRtebyNu6Ejf4YXHqCBguuWX76yY87Y1yEbbTRQvAGHF5JtoE/W4 cy/otl+o9fmcE6L4eZJWw2TbiUJrTeTOVdhwLE8pJiGVtRH3TKBD6W3skqsXaZEYOq x7dQyAbBoaV3BSWwhbpzK+QYx8mPjIxBM04or6PI= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([89.247.255.242]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1N2jWK-1lmlvp2JRc-013OFD; Fri, 26 Mar 2021 08:48:49 +0100 Date: Fri, 26 Mar 2021 08:48:48 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v4 2/4] chardev/char.c: Always pass id to chardev_new Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:wgzPgc5fHJSuoXxxAYRfFfrBsWYGAUo6ceF/vpu5fA10ucmdGdx QM/xy58hzfTecIQaIcqJ9QEjRJfEa4MExpcmn6IoJdBoRU9Qsw4HrqJ4oepAALq/OfWD/ZD +V9SIF04Zq2uImX4BCx9P9ITjL27k/MxC1CG6H7tb1fjhQH//TOQpzpFg+7D+004QGlh+hy CxFS3ixANi1DEeBW8vkXw== X-UI-Out-Filterresults: notjunk:1;V03:K0:87sKQuITj8w=:R5UUYHBMWf8pdG0G1uYwWT UL6WuORD7a9fT4wpOiI9T/tKVp5GYTg9x8Ou6+ktxWFaB9urSh9cNCxUBZcN7iF7Rr/e1baV5 TFkGm7ebuX5E2yDm2UnMuZN7IeB++VoWHfAfc1jt5s3VlfBR2TVJG+YLN0kiROl8Fgww8CmgT naRkoYxf7/oATrJzeeI+UqiMrMfBPJz9OSQcHmQJEsfPrzmSWgYnxFCGg/ZaTmmcjD+5B2YgV SC90lypaqRCUgLgDPlywGZcCi9Mle6fcRgr3Jky/WdcwvfmSeEvqJmzFP839LpgcSlhj/7Q3o gG3ac9GAPFIXwNxbcJK6LXqfC9xlkfjNSeQ/JKDXMZe0V0lFUb+PoiFaJ2d9gZmlQxRYBs8rc P6bchzPjdFw+J+PV2i3K7neU/QkAHCux9oflQ8p+LnQNe9Eul7kunO/sgcJBOUCrMW4PTICYK YmDyCM/GFuDsEalE0OEr5xb+IccrX5PYFtoaCjvLMjDBljxi5De58/C33dhqjXZlnJr2P2OO8 XsKd0jCfZ/Nx5nXH7mFGmnx5a/0NHs02cLrOSwbRN3NOVbD8ovT5DUan0J7mIEaGsFUqvaWp1 Cl0ySkMP6N+CH6dspTEaHZSLQarp+1+WlGQ10BGoS9r4UupnD872jrX4Ed7SRRdUT88u8MRx3 0XHmtldCL9olJsntuG9lkN5DgD7wsKclFwNKBYEcuo+7damofRGD/nINRB9CvlO9gsb7NlHA1 tlPSO4COfA/cq70K5LhcBrILgoUDNZ/y7bDDYJpQhI3lqSu3v3/w0DDySbEHN0S/DY+Ty0kfc eD9rIOU3Ug0w9b6rDYDqkb/c5odvehHGq2BJ3/NPEhM/SIXvuoRO5EivvaeUIEQrvFAwnMgQu AJ1sAbCeKlxzs0/KwyfQxHYBHLzrPAqPYtoJIsglIpPwrxE5CacXk/QiDUCJF+VqVjuzQNB8X 7WqdNTCZLr98APEMNoI1BWHeC0mmdrRUIhdys70hyyXeDAcQSsR73e/Dwe8FY9djqGFO3E+RW nXbyCHmq21Wu+x+4yVo15Gdfmk/BZllPMCySQaySDQ2LWqaAcJ96DHMynYoBrwvX9wyk38QJt 4e93C74Ml7YmakHkbYX3qXHxCSWl8xnYgqr0lX7K/F39DMihX4iwcJ0SuxnWyL9v5wXLXtCCq Te6V0PK+n7SBNBPgDn8uVPpuPN/+SX7ECDrGXtQ+aWZ5CXFcV+bUGizCwnDJAACmA1CYI= Received-SPF: pass client-ip=212.227.15.3; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: Laurent Vivier , Marc-Andre Lureau , Thomas Huth , Li Zhang , Paolo Bonzini Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Always pass the id to chardev_new, since it is needed to register the yank instance for the chardev. Also, after checking that nothing calls chardev_new with id=NULL, assert() that id!=NULL. This fixes a crash when using chardev-change to change a chardev to chardev-socket, which attempts to register a yank instance. This in turn tries to dereference the NULL-pointer. Signed-off-by: Lukas Straub Reviewed-by: Marc-André Lureau Tested-by: Li Zhang --- chardev/char.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 2.30.2 diff --git a/chardev/char.c b/chardev/char.c index 48f321b3e1..75993f903f 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -967,6 +967,7 @@ static Chardev *chardev_new(const char *id, const char *typename, bool be_opened = true; assert(g_str_has_prefix(typename, "chardev-")); + assert(id); obj = object_new(typename); chr = CHARDEV(obj); @@ -1095,12 +1096,11 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend, return NULL; } - chr_new = chardev_new(NULL, object_class_get_name(OBJECT_CLASS(cc)), + chr_new = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), backend, chr->gcontext, errp); if (!chr_new) { return NULL; } - chr_new->label = g_strdup(id); if (chr->be_open && !chr_new->be_open) { qemu_chr_be_event(chr, CHR_EVENT_CLOSED); From patchwork Fri Mar 26 07:48:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12165967 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D704DC433DB for ; Fri, 26 Mar 2021 07:53:29 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5D71061A02 for ; Fri, 26 Mar 2021 07:53:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5D71061A02 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52874 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPhHc-0007ZP-CI for qemu-devel@archiver.kernel.org; Fri, 26 Mar 2021 03:53:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53922) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDI-0002hS-LS for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:49:00 -0400 Received: from mout.web.de ([212.227.15.14]:34079) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDG-0002a5-DA for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:49:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1616744933; bh=tc4nSX2K/imwhglfrGy7FYN+BVhiobPCL8qKCjYXJjo=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=cwgxOv9UDI5wKtbup5aFMkSa+Zumyb6ZVMgDZ2EUHZo2gRx2eHLhToFXoE8z/cc+n eNr31BzbRvVuA9MyRvQOdPOXYT66zKKuSg+JFtS2RFn6nItgIpzOMwi66qr6ED7jFL uJ0zWvTnAFE+FYxOpDKzy8OTH7WObmT8kpZi1hV0= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([89.247.255.242]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0M8zRF-1lUxzt3LC9-00CTI4; Fri, 26 Mar 2021 08:48:52 +0100 Date: Fri, 26 Mar 2021 08:48:51 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v4 3/4] chardev: Fix yank with the chardev-change case Message-ID: <0b9928d84f1a63b25b668cc1e117772b089c5381.1616744509.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:nwTzPfZA8Tf2kUIZIVUhcMqcn1SGW7xdwEeWsLg+ya8Q69AhsmD HjRrkSaQ9MYKoOs/wh5edfSwJdYCpXwZPXup50YrQIwlNXGKweaD2kwZHzXbRmJaU5QDpfQ CASCnpS463b9Z/obAiANB9KLEHe1Ms66HAwifapy/ZB3HD+c2jcNo3xs1r3fDIcOe4Yir6J Nz4612tVQdfBfQzAEoLkA== X-UI-Out-Filterresults: notjunk:1;V03:K0:79dSHfIF1BI=:oCz75s6VFWfqBPJmM2tUtV vXMuXrotCtJLOFZQMJfIwomc0RcJW15Khp8iSLOdPMrIIBd1OupeGC1XUrCPgo1nuwNutNhu9 41YxaNs+aHknEXbfO2tIqf83lvMe76u64llTctOXCTVn4qLOI1Om7sMV6c59gE5UVFGqhArSE g1f7QvOVt7Ni+ud95vHPXyNHpp1ex9nc65wW19Qr07M9+27CmPOMsms3VSvw79VLYDd3AJ9hv Xj49enB6WXz/aaBP9ZC3TVXt16d21DYBVuCT3x9b0pKH8i4tBvJxp3g1cQMX5y0edXpODRZ++ LeGwGvWSanSH6SY9ercej1nSm/bI2paE5wCllyqB4fgrx7QcXTTBxuFopPzYsWc9+DoRk4sSt 2hkAW2rBboTU0tQaeRARV65j/pKlw2HkJubEHBe5AI/cCIwlc2MIXZh/S6lnqB1LdqNY085NI oNQACFd5ZbgMlscJXgpCJXLKDce5oGk815TyO7E/eZTOneRH46kTPvP81vCTgrM5d5kDqVvO5 arbwXUjB1TRBRcwLQ8BvZncwVnajAN2jmZwnRuMfCtupHmAtekM2mm7Vq2sobP9Fu8CsMKc2i rOriixjXfmN9bcEJSonWj0BadwjrNeKp5OOgSlrofhBP0vSst659dWVgGXrXGOqCF78WIKPKd O1KDYm1z1Q/vwVeHy8vdhZG1dyzsVia7QmiCjDn3oh2qtdLwskckTfPfgIXEJtYXURgc0YJtA +A0kBCoCX2lK6f8KzvsSarziYmUNWC48P8/ZV1TitSVLsoHUbUrcSgefFarNLZIh2EIbxzwju /BRkdNXUNwTdDNYpLY+oAU46F2gOMGXKcBw24SqWjIYDBLaVnpp6wf822CsD5kQIVebnW1mml ybyjfRHW/DzevFptxLpsTtBQqsgSmwc6B9rpaOPB+kpdMV9U/mSgwY7xktTQsrg+VpJVBSV6S CGuSPsiwI16tpz/gOe0spWt4K/kzgTjVd/MDWlriwX+pqTs8SdF8n8AiNcFifvmxo9ZOa/1W2 pUj9AoEiOAYyhtjEHz9W/sSdxvcy/qpdiBo0LjK7v3LF9vwv4e+dhHORtM1QlWmWPfv4alqwU 0bckDOkqmjNGpcSQwN4H2dbcZbMsvc2xcOoANlzabfWq9bI7BRHacER+ydG8pTCgl5j2+Vg1f R7Cr0fyp6tVZH1TCe7JuJqPl8qiYDuwm3ng8ngLZ7XzmsI/Z3xnu2YwJb2RWrDI521enU= Received-SPF: pass client-ip=212.227.15.14; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: Laurent Vivier , Marc-Andre Lureau , Thomas Huth , Li Zhang , Paolo Bonzini Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" When changing from chardev-socket (which supports yank) to chardev-socket again, it fails, because the new chardev attempts to register a new yank instance. This in turn fails, as there still is the yank instance from the current chardev. Also, the old chardev shouldn't unregister the yank instance when it is freed. To fix this, now the new chardev only registers a yank instance if the current chardev doesn't support yank and thus hasn't registered one already. Also, when the old chardev is freed, it now only unregisters the yank instance if the new chardev doesn't need it. If the initialization of the new chardev fails, it still has chr->handover_yank_instance set and won't unregister the yank instance when it is freed. s->registered_yank is always true here, as chardev-change only works on user-visible chardevs and those are guraranteed to register a yank instance as they are initialized via chardev_new() qemu_char_open() cc->open() (qmp_chardev_open_socket()). Signed-off-by: Lukas Straub Tested-by: Li Zhang --- chardev/char-socket.c | 20 +++++++++++++++++--- chardev/char.c | 35 ++++++++++++++++++++++++++++------- include/chardev/char.h | 3 +++ 3 files changed, 48 insertions(+), 10 deletions(-) -- 2.30.2 diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 1d455ecca4..daa89fe5d1 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1126,7 +1126,13 @@ static void char_socket_finalize(Object *obj) } g_free(s->tls_authz); if (s->registered_yank) { - yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label)); + /* + * In the chardev-change special-case, we shouldn't unregister the yank + * instance, as it still may be needed. + */ + if (!chr->handover_yank_instance) { + yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label)); + } } qemu_chr_be_event(chr, CHR_EVENT_CLOSED); @@ -1424,8 +1430,14 @@ static void qmp_chardev_open_socket(Chardev *chr, qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); } - if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) { - return; + /* + * In the chardev-change special-case, we shouldn't register a new yank + * instance, as there already may be one. + */ + if (!chr->handover_yank_instance) { + if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) { + return; + } } s->registered_yank = true; @@ -1567,6 +1579,8 @@ static void char_socket_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); + cc->supports_yank = true; + cc->parse = qemu_chr_parse_socket; cc->open = qmp_chardev_open_socket; cc->chr_wait_connected = tcp_chr_wait_connected; diff --git a/chardev/char.c b/chardev/char.c index 75993f903f..398f09df19 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -39,6 +39,7 @@ #include "qemu/option.h" #include "qemu/id.h" #include "qemu/coroutine.h" +#include "qemu/yank.h" #include "chardev-internal.h" @@ -266,6 +267,7 @@ static void char_init(Object *obj) { Chardev *chr = CHARDEV(obj); + chr->handover_yank_instance = false; chr->logfd = -1; qemu_mutex_init(&chr->chr_write_lock); @@ -959,6 +961,7 @@ void qemu_chr_set_feature(Chardev *chr, static Chardev *chardev_new(const char *id, const char *typename, ChardevBackend *backend, GMainContext *gcontext, + bool handover_yank_instance, Error **errp) { Object *obj; @@ -971,6 +974,7 @@ static Chardev *chardev_new(const char *id, const char *typename, obj = object_new(typename); chr = CHARDEV(obj); + chr->handover_yank_instance = handover_yank_instance; chr->label = g_strdup(id); chr->gcontext = gcontext; @@ -1004,7 +1008,7 @@ Chardev *qemu_chardev_new(const char *id, const char *typename, id = genid; } - chr = chardev_new(id, typename, backend, gcontext, errp); + chr = chardev_new(id, typename, backend, gcontext, false, errp); if (!chr) { return NULL; } @@ -1032,7 +1036,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, } chr = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), - backend, NULL, errp); + backend, NULL, false, errp); if (!chr) { return NULL; } @@ -1057,9 +1061,10 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend, Error **errp) { CharBackend *be; - const ChardevClass *cc; + const ChardevClass *cc, *cc_new; Chardev *chr, *chr_new; bool closed_sent = false; + bool handover_yank_instance; ChardevReturn *ret; chr = qemu_chr_find(id); @@ -1091,13 +1096,20 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend, return NULL; } - cc = char_get_class(ChardevBackendKind_str(backend->type), errp); - if (!cc) { + cc = CHARDEV_GET_CLASS(chr); + cc_new = char_get_class(ChardevBackendKind_str(backend->type), errp); + if (!cc_new) { return NULL; } - chr_new = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), - backend, chr->gcontext, errp); + /* + * The new chardev should not register a yank instance if the current + * chardev has registered one already. + */ + handover_yank_instance = cc->supports_yank && cc_new->supports_yank; + + chr_new = chardev_new(id, object_class_get_name(OBJECT_CLASS(cc_new)), + backend, chr->gcontext, handover_yank_instance, errp); if (!chr_new) { return NULL; } @@ -1121,6 +1133,15 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend, return NULL; } + /* change successfull, clean up */ + chr_new->handover_yank_instance = false; + + /* + * When the old chardev is freed, it should not unregister the yank + * instance if the new chardev needs it. + */ + chr->handover_yank_instance = handover_yank_instance; + object_unparent(OBJECT(chr)); object_property_add_child(get_chardevs_root(), chr_new->label, OBJECT(chr_new)); diff --git a/include/chardev/char.h b/include/chardev/char.h index 4181a2784a..7c0444f90d 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -65,6 +65,8 @@ struct Chardev { char *filename; int logfd; int be_open; + /* used to coordinate the chardev-change special-case: */ + bool handover_yank_instance; GSource *gsource; GMainContext *gcontext; DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); @@ -251,6 +253,7 @@ struct ChardevClass { ObjectClass parent_class; bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ + bool supports_yank; void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); void (*open)(Chardev *chr, ChardevBackend *backend, From patchwork Fri Mar 26 07:48:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12165965 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71266C433DB for ; Fri, 26 Mar 2021 07:52:25 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D866A61A02 for ; Fri, 26 Mar 2021 07:52:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D866A61A02 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50042 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPhGZ-0006PW-UJ for qemu-devel@archiver.kernel.org; Fri, 26 Mar 2021 03:52:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53938) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDL-0002pA-HE for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:49:03 -0400 Received: from mout.web.de ([212.227.15.3]:46657) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPhDJ-0002cG-Db for qemu-devel@nongnu.org; Fri, 26 Mar 2021 03:49:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1616744936; bh=T8DxaAScgrFKLwV5enCxg8uflIx8JLJhszSKyUPNmX8=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=rMVO92kpBHwjAUYkroMutDA03bR6iTKdg4I6cVzkva5I97e851sFoM76MSsCmYTpP yaZzKwdt6D4AI0z6x16gHO+yOL13jjb7DarlPVa1EHx4U9Udg3pzTrI+SedK4+Abej 00zcZs+N0/Q2tSZqatVMK59KmXq3sLrcj4wbdVWk= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([89.247.255.242]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MJnvp-1l5hLt1ott-00JtMa; Fri, 26 Mar 2021 08:48:56 +0100 Date: Fri, 26 Mar 2021 08:48:55 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v4 4/4] tests: Add tests for yank with the chardev-change case Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:LwXCDLZjF7O3MkmqQLo0HIfoxCrBjSXv0c8hnmKUDKLHWqptuvb uGxKB/2UknOn9msbHyhHN5z8rrsWG38EM5Yd+VMrqW1vVtCiliV9YYWUTVflCF6xLZpGSHL qXkiY/SujoKTNrmAkMQlppQpe+sbjy1vk5v1HdOq5Fjhrx/vSA4tdljZN21P8xixRgsoBnX h2uX3Ut7SZqLyCl+yh12w== X-UI-Out-Filterresults: notjunk:1;V03:K0:TSVsGNsY45k=:QXJmx5GQdAE3uLHXifbptu AFUs+xM0apDairHq9T3/M4fadWI3aVdYYTKGLwZw3eNqiypXty0FVqRRuosnomTuuxr1gSi2L G1em/Vgpk8OtWAtlJthbFtI3cpz2lZdMreGvFE8fS+yXmjDbOO2n8NQmM8Xr3y3cfBa/skYYU 4/id9rqsw9p3qNXDkcHljlMVDpRpHi8djMtYQ8SrBiWZgW/1kukPOQeCzbdpAzfaXp1Eo4MI6 C6UT3MmD+TQx4uZdSop+CqFjoF5jlK/u3Zk7tpJv6Fmi+MYP4M30EvtGo5jcjCGagfUSElkG+ HCTuoFQv4JpFDoSB0DACVvCQezoZyJ39e0xOSXglIGFaw5ZaSBeNH+cxmK1CMlkgFzk5ML1ra X5j8gm7IeOFJ5m8U/ny6K6LqWT2ezUolOx9R0bDOPt/eroUT03rymWE+E/IZbSJ/Is0b4ZH0L ueGEiMJYbMdG28Pfb4NDZF5h85wcjbw8debvESiPk6BCI/o+jo/EeVBDdhEHsVxrdObwobOmi i3vpHJp8SC+a3AZvDpXtS4BcgN6eyGcxQCdiCeVdnkHHtSSzm0eKTzCHp9PmSqQRR/mEAG1c3 emfnHrb3/BB+IaFJg0ekyuPG8ds2qqa+ZXWoD9X3x9TDrEJ1QMZu9RNBkiVeBlDZGu3aKUR4a bTN4nKWpDFlGkCuIylRahfea8r3CgdR4gaTur+TRR01InQxYiInEX2vAwiPLYExeMXtvBPcZe blWmM+0CwOWjSsP6mAQ/m3gCo1fIY2rYjAwFXZxwoleHOHiU/+T8Hfj9Ciq0Bfc9h+bgpBT+T AGOvXvrm7IaLEQZo0T51wdXCvmv2M3e/B6OVJS6YxgCmt7B7xKk46UHnkW7LYQaK6QHHH/aF0 9Nbp8Zel9u2yQoyGQXiiLabqRWpdK7yWF5kcy1z6he3AWDd7lpclBlsYJsBfylBnP7UWBuKd8 splqKnOtihPc4h+XzOTFhqx3Yt/NU9J/4OVhzfWnbK+tXjprB1vl9kWCOUAHuXsdJ2neqgTJn cZQw0Z1Ar6SClhWbmIsZULAjwoee+F/GhMwoDzVy8qzG87kidrIqFc8Lq9ZdhzLuTsUl2lNpN Wa79og7/pLM56aICQuZJFcQKajGtvn/V+pJh1kRQrRPL8jvs/9UL+Pz2645A7TPBdB6qizxBl szZWS9WqpIoHR8SuANc5kqZl+i7x08VrLaukOfDywvA4SIMiN7nX82mDdK0d2Uw1c69kP2rSb VMG9tBuKPVcfqCrYd Received-SPF: pass client-ip=212.227.15.3; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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: Laurent Vivier , Marc-Andre Lureau , Thomas Huth , Li Zhang , Paolo Bonzini Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add tests for yank with the chardev-change case. Signed-off-by: Lukas Straub --- MAINTAINERS | 1 + tests/unit/meson.build | 3 +- tests/unit/test-yank.c | 199 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test-yank.c -- 2.30.2 diff --git a/MAINTAINERS b/MAINTAINERS index 77259c031d..accb683a55 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2821,6 +2821,7 @@ M: Lukas Straub S: Odd fixes F: util/yank.c F: migration/yank_functions* +F: tests/unit/test-yank.c F: include/qemu/yank.h F: qapi/yank.json diff --git a/tests/unit/meson.build b/tests/unit/meson.build index 4bfe4627ba..b3bc2109da 100644 --- a/tests/unit/meson.build +++ b/tests/unit/meson.build @@ -123,7 +123,8 @@ if have_system 'test-util-sockets': ['socket-helpers.c'], 'test-base64': [], 'test-bufferiszero': [], - 'test-vmstate': [migration, io] + 'test-vmstate': [migration, io], + 'test-yank': ['socket-helpers.c', qom, io, chardev] } if 'CONFIG_INOTIFY1' in config_host tests += {'test-util-filemonitor': []} diff --git a/tests/unit/test-yank.c b/tests/unit/test-yank.c new file mode 100644 index 0000000000..8bc8291a82 --- /dev/null +++ b/tests/unit/test-yank.c @@ -0,0 +1,199 @@ +/* + * Tests for QEMU yank feature + * + * Copyright (c) Lukas Straub + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include + +#include "qemu/config-file.h" +#include "qemu/module.h" +#include "qemu/option.h" +#include "chardev/char-fe.h" +#include "sysemu/sysemu.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-char.h" +#include "qapi/qapi-types-char.h" +#include "qapi/qapi-commands-yank.h" +#include "qapi/qapi-types-yank.h" +#include "io/channel-socket.h" +#include "socket-helpers.h" + +typedef struct { + SocketAddress *addr; + bool old_yank; + bool new_yank; + bool fail; +} CharChangeTestConfig; + +static int chardev_change(void *opaque) +{ + return 0; +} + +static bool is_yank_instance_registered(void) +{ + YankInstanceList *list; + bool ret; + + list = qmp_query_yank(&error_abort); + + ret = !!list; + + qapi_free_YankInstanceList(list); + + return ret; +} + +static void char_change_test(gconstpointer opaque) +{ + CharChangeTestConfig *conf = (gpointer) opaque; + SocketAddress *addr; + Chardev *chr; + CharBackend be; + ChardevReturn *ret; + QIOChannelSocket *ioc; + + /* + * Setup a listener socket and determine its address + * so we know the TCP port for the client later + */ + ioc = qio_channel_socket_new(); + g_assert_nonnull(ioc); + qio_channel_socket_listen_sync(ioc, conf->addr, 1, &error_abort); + addr = qio_channel_socket_get_local_address(ioc, &error_abort); + g_assert_nonnull(addr); + + ChardevBackend backend[2] = { + /* doesn't support yank */ + { .type = CHARDEV_BACKEND_KIND_NULL }, + /* supports yank */ + { + .type = CHARDEV_BACKEND_KIND_SOCKET, + .u.socket.data = &(ChardevSocket) { + .addr = &(SocketAddressLegacy) { + .type = SOCKET_ADDRESS_LEGACY_KIND_INET, + .u.inet.data = &addr->u.inet + }, + .has_server = true, + .server = false + } + } }; + + ChardevBackend fail_backend[2] = { + /* doesn't support yank */ + { + .type = CHARDEV_BACKEND_KIND_UDP, + .u.udp.data = &(ChardevUdp) { + .remote = &(SocketAddressLegacy) { + .type = SOCKET_ADDRESS_LEGACY_KIND_UNIX, + .u.q_unix.data = &(UnixSocketAddress) { + .path = (char *)"" + } + } + } + }, + /* supports yank */ + { + .type = CHARDEV_BACKEND_KIND_SOCKET, + .u.socket.data = &(ChardevSocket) { + .addr = &(SocketAddressLegacy) { + .type = SOCKET_ADDRESS_LEGACY_KIND_INET, + .u.inet.data = &(InetSocketAddress) { + .host = (char *)"127.0.0.1", + .port = (char *)"0" + } + }, + .has_server = true, + .server = false + } + } }; + + g_assert(!is_yank_instance_registered()); + + ret = qmp_chardev_add("chardev", &backend[conf->old_yank], &error_abort); + qapi_free_ChardevReturn(ret); + chr = qemu_chr_find("chardev"); + g_assert_nonnull(chr); + + g_assert(is_yank_instance_registered() == conf->old_yank); + + qemu_chr_wait_connected(chr, &error_abort); + qemu_chr_fe_init(&be, chr, &error_abort); + /* allow chardev-change */ + qemu_chr_fe_set_handlers(&be, NULL, NULL, + NULL, chardev_change, NULL, NULL, true); + + if (conf->fail) { + g_setenv("QTEST_SILENT_ERRORS", "1", 1); + ret = qmp_chardev_change("chardev", &fail_backend[conf->new_yank], + NULL); + g_assert_null(ret); + g_assert(be.chr == chr); + g_assert(is_yank_instance_registered() == conf->old_yank); + g_unsetenv("QTEST_SILENT_ERRORS"); + } else { + ret = qmp_chardev_change("chardev", &backend[conf->new_yank], + &error_abort); + g_assert_nonnull(ret); + g_assert(be.chr != chr); + g_assert(is_yank_instance_registered() == conf->new_yank); + } + + object_unparent(OBJECT(be.chr)); + object_unref(OBJECT(ioc)); + qapi_free_ChardevReturn(ret); +} + +static SocketAddress tcpaddr = { + .type = SOCKET_ADDRESS_TYPE_INET, + .u.inet.host = (char *)"127.0.0.1", + .u.inet.port = (char *)"0", +}; + +int main(int argc, char **argv) +{ + bool has_ipv4, has_ipv6; + + qemu_init_main_loop(&error_abort); + socket_init(); + + g_test_init(&argc, &argv, NULL); + + if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { + g_printerr("socket_check_protocol_support() failed\n"); + goto end; + } + + if (!has_ipv4) { + goto end; + } + + module_call_init(MODULE_INIT_QOM); + qemu_add_opts(&qemu_chardev_opts); + +#define CHAR_CHANGE_TEST(name, _old_yank, _new_yank) \ + g_test_add_data_func("/yank/char_change/success/" # name, \ + &(CharChangeTestConfig) { .addr = &tcpaddr, \ + .old_yank = (_old_yank),\ + .new_yank = (_new_yank),\ + .fail = false }, \ + char_change_test); \ + g_test_add_data_func("/yank/char_change/fail/" # name, \ + &(CharChangeTestConfig) { .addr = &tcpaddr, \ + .old_yank = (_old_yank),\ + .new_yank = (_new_yank),\ + .fail = true }, \ + char_change_test); + + CHAR_CHANGE_TEST(to_yank, false, true); + CHAR_CHANGE_TEST(yank_to_yank, true, true); + CHAR_CHANGE_TEST(from_yank, true, false); + +end: + return g_test_run(); +}