From patchwork Mon Mar 29 18:55:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170819 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=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 64273C433C1 for ; Mon, 29 Mar 2021 18:58:07 +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 8FD2A6195D for ; Mon, 29 Mar 2021 18:58:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8FD2A6195D 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]:55412 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQx5Q-0005V4-PX for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 14:58:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60510) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3X-00046H-I2 for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:11 -0400 Received: from mout.web.de ([212.227.15.3]:48629) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3E-0001VK-Nj for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617044146; bh=ybGPFs+IiyELjdB4kjrWpvCjsGqjwjL1p7axE6FExWY=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=GGjcspO6JD7IMeKczTzaPbv49OHpLSPWRNrnWDw89LvhABCUjtv2lX7X3SiReLXH7 nRYB5x0h07kPKoSKWHUs86rGWBXoqrIbQX0TdUPvdrk8vBRjOSMuZaJOBSgckjcgd5 5RZpgqJ4wDzeGZWaWKfhOKkFiK8RL5lMR1YUT9UM= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0Ma2V5-1lCSTN2FPL-00LmWt; Mon, 29 Mar 2021 20:55:46 +0200 Date: Mon, 29 Mar 2021 20:55:45 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 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:vBs8PP7HOu9ImlnfYPNihLvhy4uOF1clVod6D0GbowAPxMgjUdl D7wERzjfLXpq2aPaDA/TWXSi0pmXxCExBBIXLlPbDU8yGKLUJI9JnliOuVhmeY0796MQM9I IKSPxxXZawpYMQhkH5pqruVMPmgw5h3noLvlngk3IetC1E5jT7wSRHxY5q6tazfDjcY+oDL TRT8yPOgxCIDW687S554g== X-UI-Out-Filterresults: notjunk:1;V03:K0:ht+0dloK1+4=:o2KtQtcmGIqhwfiSodS+eU kFdPXmabeEscxOjSpbYEgZDuaEA/gnIk1YIkiJgaSYTSqBxiANUwDeyVrmvV55BQMSq7geTDe FNhO2DBFG7QdlVrkgx3p2dzQFT2sACKsh8X/T09wQ7g2tH+uP5v/G49gsyC27LCOuym9L3bUt hur8v8nI3AGzv+h7I6m8Qo2v4WfIeiiuPZMLgKnrF6qJSbXgg308yX9B0qF7cjKvGnAKbuCWP 0GP3/ThnKtCmQNS7EURRlcJM9AqGI51K6X8dMHfcAwHdNaEdJlrtwL9xUn6BTibEhRTaGVG5U 25c8I0SH3+zjtk8QtUMSYZlWFNHIl31Jx9OlIHSWS8bvPU6sRMDZgxFl8TO0b2ap5uOvVnSI/ byskbYunyDuq71wQ5OK9OIEk6aFil7D+zviFaonCgIInlSgzIngB7Plm9ej1CPq//XwH4Yzui 3x0ZLrtfHD4yK2DkH6jYJASZ3Xk+GlMRcYRhLPbwt7koYDiVbyj0Lhl2RALk9UEQEHwgUqWJT oQKjkS2gx+broKUtXEdefy5nPj0R2alW7k8q3g3A/71Za1ckGVxYOHONJEFDaZoumLaDP/W/I 0hWadM9s5MYEpIhgxsLwoLG8ywVoSb0Ub6d5R9LBP8DjgdcOgzz2UpRnpvKoHmekRO79KvZMs WKA+pLaHmpcX7e0epDMdotry366upISuO9RZ4nixt2yPl2xWds9aoNAhkUWq9t7qw8FDNQz88 0a1ba1BWu90tFj3AU7wStYAkEReA2GildT4LjWY/yhtu78RJLuvLDISWlYqUrveSqgC4wFj4W w9Nxkh7nCghv2c5vwcWF+Qn/5Q5dHnOdQ529Iy6MlGKtD0qK2c5CnW2Bh9inIE6Ur3ik1dNp1 oWFDZ8ZM0xo96ThJZbfZagyrEzRum7dnrlIMuABV05nex4snrHc0LZm3LYjfpkMBkBETHzprp nIeRjPQLeSX+TkhHWUq5gpM6uos9Hn0zUK8fAzSlUDeMbGK1CHAFaOUA0GxH27J7jTMgjF5Sy tCws4+sPgMoAM10TJt2xhpIWcu9/087Cxj9jg0hG14Rt59LxnYJa1l2B89r84Dr362xym6YOk khUdzS24YSldqMFXTWFSeNDdTTnZPdWLyQ/4E9PBR4JWgVcSZhx73+q2pPm6Y/F+AVuotsphb mLmCh5U7pemPYCXXrwV15yYndfGSmWZ74gB9vvrOp1y1qVoQ8CEEl6N7Wa1GR14XWtfEg= 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=unavailable 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: Marc-Andre Lureau 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 Mon Mar 29 18:55: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: 12170825 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=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 7969EC433DB for ; Mon, 29 Mar 2021 19:00:11 +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 C34F761585 for ; Mon, 29 Mar 2021 19:00:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C34F761585 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]:32842 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQx7R-0007rc-Lb for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 15:00:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60554) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3b-00047q-PO for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:11 -0400 Received: from mout.web.de ([212.227.15.3]:46089) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3K-0001Wx-9a for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617044150; bh=XE/hPgaLWkL1KNO6Xt3is37V6Zr1ybJs0A2eQp9QpGA=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=S9aQxfZf3Bpwo1YOKxDS2zkualaxHp7lNohOWnvVAK2YMPKDevHjM3CRDPwjJlP1J IMA+DjitspozX3SgEx/ArbU9QXG1nHPBliE3nmDvrWVES94dXFdw/8jVymDxE6SDLO 5q1rwM4awlxkKT9Qmd1xncZO/Cz8NOCBUlAAe9nE= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb002 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MS1xS-1l2FBs0Hk2-00T9fY; Mon, 29 Mar 2021 20:55:50 +0200 Date: Mon, 29 Mar 2021 20:55:48 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 2/4] chardev/char.c: Always pass id to chardev_new Message-ID: <3e669b6c160aa7278e37c4d95e0445574f96c7b7.1617043998.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:xJJ5NnVLqYC+0075Tq8mhZmpHEO8Op46JdWjLwO/iEaRvTsh9fD Baf1YUdAy+pEC/4kjhqS2WHBe4ItyDdf12j5bfjh3SxbGm7P8KN+I3OI6PcugUo0GS+BiD9 4nnOV2iJNkYlUrSm635MZBnJVIRHpwXkmv2uOHdDHOCUckSFjytqatRAnWzVmceJLwigq59 KUS457ormFhcLikEYeRVw== X-UI-Out-Filterresults: notjunk:1;V03:K0:KgHUdfjLTfs=:Y0ticQJCafAon/HtTpr36W J5VikKX307SC0Csbw3+IIVs6x6AKGWD03EDP9YgxuH+fvgMJXXdoFvIoOO6+03finy9wiwXD2 4VBhbe8Kjd0Vdg9DMF2hPjZdLP2TQzT4NwB+b5KRvKPnjAlopVLe5tsaHhVCzjdPWzGCFzcxA YVTlbL7KfJVqwjcR/zehm7pIQ+xkR1y47SYU9hOT6qurEB2Tc1HO+0hbqs9JMelOtxt1Hz6Sh s8BFxyrP4Q7S8J8R1UeV1RuiyWUqKnOeOxCY9v2ntBK6yCI+7IhtNwhBjCSC0U2YbB/anDe7N PPqga4VZoFyMSHs37hASuuh4jLgSgFgZGKi99QamdzOqZCbKmklg3/DldslTwD1d1EU988uxg 2hMcUxkLBFopBpoviVz/eCygeRQ/JTuCan6W9NpPFJeIeWXtsbKQQ7YZN8MLdJSAx7ulqNT+A CpRBVGF9nV9BvsMNquPesvvWCNPZysvvry8Y6JFBx9mv0IrpG35h65soxg1+Stw8XR5neT0A2 YlfHEQQJDUITbu8/ybn1S4pHMoC9a6M7L9glDsr5DvbQuXGdrI0jONKVBb5un+vcknIY9x0rP 4+l+3E6ZH9aIFn0rvB89A8dPbKbjGoC2H3sMWhnPj+UvVPQe/hfHzTvT53/TXk87TPau6MLe9 mPjhs4jaec2X+EPtTAWafSi9hjw+Xj6rOIN4xNfnutWHjYGQGYvzS3WqJ6QdCPMq8+nOt5fj4 DEqCUi9SmvaePxa4T4ij9dMUuUArxau2vG1KvU2gdyEo5iIBS1Y2VowOP7oKumcys5fW51JBk +gX19cqU3FVdtIEJl1XQGich5765UnnUU9myOBTM0w4kpVy1FI+fBhO+K4/isbjQUHnbwhL2c oPbmPA9pR2AHZNUx2mxE2VmF1WbLL6YG6MRiPssOn3IlUmcSdYfNqOZ0ONySCT1mxcXceqC3Z MSGNBFXl8bRCje0/nRg1Nd9Nojr7lGgQZTnOKR0AXSlrHoC0vq9BEYJ7PQZFUuxETH0EYKwAR QnZWV5v5yV5JCB/EZLUVN9+yMvu4Uyb2U2bxfpF3K7eccEEm1CSCUFXj7dLRSfXIw1ycanhKC quFf8K3rFgCSfriRopSTP2NYRv97nEp3lOgOSp+Cv4O8i3f1R1GI9PYjB6mbnZ6Kw/028r1od RKg2xqJtfgVcoI80d5MIPxgE6YHy2tmTRlLWx/9sr2Wgwu+MDOCOCBBbwcg5Smd84x+MI= 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=unavailable 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: Marc-Andre Lureau 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 Mon Mar 29 18:55:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170821 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=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 B55F2C433DB for ; Mon, 29 Mar 2021 18:58:06 +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 D468861968 for ; Mon, 29 Mar 2021 18:58:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D468861968 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]:55456 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQx5Q-0005W9-J8 for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 14:58:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60516) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3X-00046X-JV for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:11 -0400 Received: from mout.web.de ([212.227.15.3]:45717) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3M-0001Xb-Bl for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617044153; bh=3RvPmWNdEWl1HNZ/qZ8MozvI3ECqIyCh35GWfDndBx4=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=f1xgnHYG+vGzFVs4Xp8QM424qOaEJ5a+hvb4sztWl8207glCuX5VOc6dKyZysE6i6 HwMFrJKBt9Xg4FIIZ91pkcwJFzhLtzABm/iKXzTsqrD7NnSIVz1WwoE0qFR4tvfy96 T/Mjulz58tmquj6C0Nu+UGPo14nZmVfH6X+wpTR8= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb002 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MY6lc-1l50LB0fFg-00UnUU; Mon, 29 Mar 2021 20:55:53 +0200 Date: Mon, 29 Mar 2021 20:55:52 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 3/4] chardev: Fix yank with the chardev-change case Message-ID: <9637888d7591d2971975188478bb707299a1dc04.1617043998.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:itv9Y6VLIbq6Y/4ZJwqZT1yfywLYdiqFyZ/X/6w0p6qbtOaQP+L 77njtAN0xSNMKwf+M9c4cTl1stL3b2c9HfgffVzVGvm2viQVYZdSLJBUiQwCXGGRFD1/V9k tL66WiUZD44NILH4RfQ56BYG4Qjt33nW3j0Dbvoy47nngzSpeDs1HAqkf4clVIWQlF/O6Dy k+xiU60hNhRERDrF/UB1g== X-UI-Out-Filterresults: notjunk:1;V03:K0:heMqhtXJiq4=:3R7Dc9+vn624hOt7+leG04 uBOsptbncgAp+TtEtKSHvAOnegdjC7/CaBOVka9SKui7Olbw3RMnw3pBoTKl8Mf6xpAZow2yG P03aviirqabzzbdnX0lZbvv58QuR+dBjaLLEEdyIsJeOQ5k98Ng4mhZ5O/ZrHxg197bXuQ/bq 5br6AGoaufM2dGXZSOjEzHzKPD23yoeckMdG+0CLuNsnuGtruY3WYZlebHplrKD6GPenh+kIz jyoC2N6Hc3zzoQ9W7b3SySSXSLeJWicKBocoMoRkMD8bddkFP4o2bodUzW1I2Vp3LUM4ttoHb Z17FvuhYpME203y52Dgu1RPxsc8TzjWufPt8G7gMBamS/fY43fIPBEiGNmXsvUK1gY2LbiPO1 U3KlfdQvtFRkprGDOWsa/sS/z4MAsEb1CZ/bzPuxbJD5cVgHotW4mdgg2WLkuRPw2rPMmKMvy fTO3BvcBGClfGwC+unGroeYKGOWE+Y1E445KGpjae5DlRpxAqbY/eTcZQtuXmV19rVlTbrcY6 Qh5xDqwt+/xW0afohTbBlhg/q28bFspOFFGgsDETeljsfBahAm+NtGoLAmkhoPheudyobNI5B cpCvCXlHkHGa+5RjF8Se0MnOXwsGRycp/gcEROs0tiEVZnLnnQkM/VdWxd0xtrHIR+Uegg01G PS64ZadqPlOa5sN3zILuyZHhi7xbNagVya+AoZtSvmJEKZumMAscbCNWP5yLr3GZ73D0Y1x3W PRPKqOjkL5a7k9+rz9AZP5/vIm3fhZ1Nq3p2inCqoJFYWgLWyhc+cPo4Twy/0D3VdV+pCCtDj 99MeKTEE00u4O8GVuXR0HIwPm6f/d8PFEZAE3UFHr2n/RVN+WQZagMuNL+oTeRfRpXZmBvgin 3+BtAk8BpjC/Rs/v7QupvNlC3iBiG9hb/AmP1A1Z0d7HPllYCCC6K88xbh0h1Cxq6ft9xuymT 85xrqXUngUTwuSXF0fDnsHJvZDeja2FiE+Lol4rV8ECKXe1/YGQVLrZEf1M4c0kgWEManw5LQ BP3xANKJxP9xuxe50NySfQJMDHJL+stie+yfih5uX569qiXJdT06v6ByT5ibH5K76UYWfTfh7 nTFHB0diQoGjeKwETVFXv9+OPRdhoadbM8LtpN82xmF+J/qCU97YLCsj0qkWx6p5XKkACKiYQ ARaYE20K6r6E32488OiCPVVYLEHLp8/6O+GMJS/+Bj1Zt2b2Z0oqiZ9aR/pnSW9mP7MLQ= 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: Marc-Andre Lureau 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 Reviewed-by: Marc-André Lureau 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 Mon Mar 29 18:55:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170833 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=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 50374C433DB for ; Mon, 29 Mar 2021 19:03:12 +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 A47DC6191B for ; Mon, 29 Mar 2021 19:03:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A47DC6191B 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]:35142 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQxAM-0000XJ-Ih for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 15:03:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60560) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3c-0004AO-DX for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:12 -0400 Received: from mout.web.de ([212.227.15.3]:60199) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQx3Q-0001ZQ-4Y for qemu-devel@nongnu.org; Mon, 29 Mar 2021 14:56:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617044156; bh=GkWeInFAPv/GXGFKkL35Lqyo/aKmE3Y3tGm+mPMxD+M=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=C8VjmVait7UTyIiMgspDwoIalUyz/e84QoGfCRqvLvgwBn5nni3movqCB8ffLTIDh g26WniF49Rj+3YMTFX0FwuSOLcdI0iG47CH98GxYiqVZAzBcwgYDkndpajYsQHo6gr PSt17h+Ve3WqNL9WNWJzhtXcbpDok4m4hMSC46BU= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb004 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MCNY9-1lIOSr0aZN-009AU8; Mon, 29 Mar 2021 20:55:56 +0200 Date: Mon, 29 Mar 2021 20:55:55 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 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:dQeJNO1+PDQAC6BBQrJKxDR6YKxmZS2vEDKd0PA+3AjLLJK+O5a F+rlELX+zbP85N/QwUAhC57kHWVzzC6BXuCyDzMhxxm5TRsZy4TZhGoPwG4X0LVYkhGJ5P/ 70G0uVDS2xCpVE2N3q6a8eVedyzjfQzb6/2G+x0zKVs6JAklvHRf1Ll0P7lilRK5RtYhKOO 9HKncqJXdGXdH++6+0Xsg== X-UI-Out-Filterresults: notjunk:1;V03:K0:mu0NjCx+Et8=:cRLrg8ZKQMq32QcegFJiL2 /mp0DbT2tFTQRElNaQk9iM0rq64vS1buAi5ef2u/GSOzdx/sp9C1QFJq/9LHaxDhiprahzBsn ahLN5zi3mWpjf76x9cgQeg3h6Ok2strAmv9neVDzPvY9+bWU4rjExKVPSyFNExuV+AXg25G+V rnLWim5dlJhp3OwBRmieySmg6OwLulFrY529JwIj9f9CRHh5BCdzKH564GGFIXBZA2zN91NFL WqAwmXQ7lRSj6q9KzAhNLI4jEBHzlqgI+iSJwzg8TGTpm6t0iWjxOweAeqBWXQQvmkGA+rpLU VNRN9nSwmpaZfy4ncgokMFwLCHYOVD4mCO7beEPtLyWUovLS0rcOXIUawfilUHMr8viEOb0Xg 14HdPOQvTy214W1JPVKbEcI/TtVvHOrz/Y/LTLRqTHw3RXYbnZF3xN1iO2RCxEtLvpIeQFUN0 dlMeoQGewB8g9y2C+Qnp94LgpUv9nBCvtNw7Q4eOM7eMZP8aJtJadHvr8RpqDDc/7txp2qlE5 Rc8QO9V5866yIsahHurJ5rA6mEKOhGkdtVUcmV10nkuD+t9Z5ZwA8jjV2Eb7l2qPZ5SFXTFwL Cqb28fNcyDYuM/W1WTgeaV7UhzIdt/oo2nbdFfX37d+unjrybaE4suO0T4OUttzynqqMyezNh NnPS2WKmGq/9shqpAdb20+DCDXTFT0/KPdFB+dmVci8If9yxqIOZiRDDs+g3+07ln9Cyd0KWA AVu/FNapnFVoNdLtSbaWNXEGaTX06BAJXjIs2NtKwAfX27ktEA5UjVw+8W2ewzQ6cMzriTF9u uLCj+8dmCgTNXsTwr2uiwCqqS2JRG9Ou3XB53VzoofeAttmONWEhMGyOXsrAxVNBKc8/uE1PI 7jNL9UwweqNSYzEfy7CyT0p7AGL1ebayxJp9CPw5+k1GkBK+ZszUE7Chgn0G5bcEj3pljgkot u6DFxi7b7AntVMQTtnS/1V9XHmvvvXkuzhLxfRmD1h4vW37yPVvxomYbdRBV1cCvGY+sKUhR+ eGp0JchUlJ1rmgvXe3c8VwsLz1ZhDONks95WjRRE0DoHFGawuDZuaH1wurmLUcUwLDe9Bu6bD b1fLtp24+4TqyEcjVsUimXJsX922cHdmUcJGUEYD+5tV5sEPYFi6Vj3qGph989u7Fdy7FqiKw miNy0C3YfwHvujKv0MvCV/9VuZPgi4vS24tw4m5gNnWx97XqMvMRoYTOUiXqBxv0ppp4DlWg9 GDXMftPNworPlpAJA 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: Marc-Andre Lureau 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 Reviewed-by: Marc-André Lureau Tested-by: Li Zhang --- MAINTAINERS | 1 + tests/unit/meson.build | 3 +- tests/unit/test-yank.c | 227 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 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..c46946b642 --- /dev/null +++ b/tests/unit/test-yank.c @@ -0,0 +1,227 @@ +/* + * 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 "io/net-listener.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; + QIONetListener *listener; + + /* + * 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); + listener = qio_net_listener_new(); + g_assert_nonnull(listener); + qio_net_listener_add(listener, ioc); + + 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)); + object_unref(OBJECT(listener)); + qapi_free_ChardevReturn(ret); + qapi_free_SocketAddress(addr); +} + +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); + + g_test_add_data_func("/yank/char_change/success/to_yank", + &(CharChangeTestConfig) { .addr = &tcpaddr, + .old_yank = false, + .new_yank = true, + .fail = false }, + char_change_test); + g_test_add_data_func("/yank/char_change/fail/to_yank", + &(CharChangeTestConfig) { .addr = &tcpaddr, + .old_yank = false, + .new_yank = true, + .fail = true }, + char_change_test); + + g_test_add_data_func("/yank/char_change/success/yank_to_yank", + &(CharChangeTestConfig) { .addr = &tcpaddr, + .old_yank = true, + .new_yank = true, + .fail = false }, + char_change_test); + g_test_add_data_func("/yank/char_change/fail/yank_to_yank", + &(CharChangeTestConfig) { .addr = &tcpaddr, + .old_yank = true, + .new_yank = true, + .fail = true }, + char_change_test); + + g_test_add_data_func("/yank/char_change/success/from_yank", + &(CharChangeTestConfig) { .addr = &tcpaddr, + .old_yank = true, + .new_yank = false, + .fail = false }, + char_change_test); + g_test_add_data_func("/yank/char_change/fail/from_yank", + &(CharChangeTestConfig) { .addr = &tcpaddr, + .old_yank = true, + .new_yank = false, + .fail = true }, + char_change_test); + +end: + return g_test_run(); +}