From patchwork Mon Mar 29 16:38:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170493 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 47F07C433DB for ; Mon, 29 Mar 2021 16:41:38 +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 BDFB761934 for ; Mon, 29 Mar 2021 16:41:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BDFB761934 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]:33864 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQuxM-0004DL-Tx for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 12:41:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51660) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuW-0001dz-OQ for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:40 -0400 Received: from mout.web.de ([217.72.192.78]:40037) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuV-0007eK-1L for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617035916; bh=bHJt6KTZohUnCiAnbNZQQXAkLGvmbOLYRn7NsHq3GyQ=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=X2dWHdlePc/marFnDKKduuI6XLa/Hc+irIXeLKgDTKta1wBVg/+Ooh8kPyZOtcrxO H8sLQ1lbAoUsXjZ+bw/rlaxOhuA/lanY+uWtsV7uT9IPIOQYDULPS31Sp+mg1xjcHN 7eKgx87RF72wy+DsRPXglI7IMh1DDGMs2Z0h1FNU= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb103 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MLPRu-1lQMgA2oLq-000ZNX; Mon, 29 Mar 2021 18:38:36 +0200 Date: Mon, 29 Mar 2021 18:38:35 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 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:7JIrbk2SBGKTy7dbzfl6Eut47m8e2B1qYxyB7p14j+vyKOlG8j/ lX+6jIrvz8fKsf7zUnErZ8AhR5B3/R8Z/QF+d6L4UAHrwioCMZHZhXzhUZnxXIBcn3gk4ly 1NbTUVmB2m7rf6F5LwUT+eSHwvfMZJbLtJnTS9U/HLt3yI1fUwc2RMxot7kTp5S2ohqvJ1K V1GUKHocVYFOXrHwRq68g== X-UI-Out-Filterresults: notjunk:1;V03:K0:J4FERaaRUPE=:WD3+h6Rd+roLB6iiebWPZr dBNVL2TwU7QLOuMj56EPYc69dDAtdrlptSr02MDN7Z5uOyDJ+BCK9iPozqGKTXC0CSaibP7aM LoGZA/yooVe4kguQf9j+bLDKvgOLxTQXdotOfYdWaJr6Gz9m6JtsLsealNNIjOWlY9nNG3Mdo BGaPIyIlylVU7FlxrzfVC2+8/kG3Equ8pcOqVbRJiQnPgQovC5WKEECNgvJSg5zFmdfso4dAx ECXanE5u6P3m4AGxjTWLJcieau74/RX9fL1j5HQwVIYuzEmVtR6LBnYm0PuXCNl7GJ07MMQtQ xVE7LX7yGhm4sTDlQBITwTPiZaHq0aHQQFqVaUkdmeq0I9xVvDhMY9qwHb+nb8RkB2TmogJc/ +4gYATbuT2g/dk1B3qW7IyLVaypSCI5SDZJTFGNKbF+bms0diWf+RChnWr+9b1gC+0JLBQrxf fxWMup1s88eGt2JL721snQg5hjmgBrS9PYp+cYA4aN1pz0lIMEZIvyXQWKGpRjI6hbikSWOvD xC5PvqqCDZUXfXsbD0eAKOniv2wptnpIMmzPFNOOzHIlB+LGd5hyaufwnlKzhr/44hv5VyBzG ijSShIHHGkDEF6GIkjHf+5a/Q4ZpvhZCmEUurAw0DlPvjZOkTC8NEtgQbPFF/5G1Y1DoD0e94 vg4Af5BLvbeD0lT+V1IRE3Ix6G/9Y38PTBA6h1F4KEtXx4Va3ZHUxbl5VKp3MbrAbg4sh0JKD 7mH2A+LQqc7G5pMXS/1/uwSeT47IiY/EuKDbHjkrR3PTPLZn6MSdeWn11EiNAnar8FBw1S5OV Q4m7Fm2wQS9yJyN9drJGmQNWpfllV0bEcy5iiO3RJPmbjP2Zc4uRS5KKsf9LR1ABTsk+9SFYB aHDLrPopHsCcQbpdWn/Re0dx3a0Brb4zShAtCNZDTPm71vGwtOW2A0vNRV3d3YmmYYndWpK8T Tuv6KSfrm5yNi0loXZFRj5Ur5fCU+OWvU54cwf2i3WWGX1N/IZwcbknrj6NoR+7jPQyF0PDr1 73Qmdwa0NCvajdOt4VvaxsmkK9Ex8PXIKqzk5HXgMGQ661Dhj5WWAJs5Viw9vn4YKdb3bEsvv ZJY0qSoibK46AJR6yDCEhNuSRA6Fs6GwlF/pOZkOIBd6ctlDYm/wWz5NcI5wiWauOm2HvD8KV E1ozJe3LvVLyiYMyPOd54HexbDFC+ToGFKAu8yWmONbWNWTHN0Lzz+VO8JBrZeQE4je2Q= Received-SPF: pass client-ip=217.72.192.78; 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" 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 16:38:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170497 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 C1964C433DB for ; Mon, 29 Mar 2021 16:43:28 +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 47FF46191F for ; Mon, 29 Mar 2021 16:43:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 47FF46191F 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]:36438 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQuz9-0005N6-DT for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 12:43:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51696) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuZ-0001iN-Lc for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:43 -0400 Received: from mout.web.de ([212.227.17.12]:44923) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuY-0007gl-1y for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617035920; bh=DaF2NOoBN6091aRooKcdtu/fsO6pM2kOqB+A/5S7bc4=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=OY1laVxPVZhVXTZ4Mz37zzw7NXHFQUqeCcQhaQtI2oKRaB7K4Jnu4PV108ipqO7DF 2UQTQjHL8lWUzAAsOAPXr7vke4UWP/mYkXyo18U8U0G8bezIovle6LSq1Sbk8Sdt1T 2w++MlXwU41++mb/LF5YUeskK1ed+a2eHPx4wVlw= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MQNiS-1l3w153rZs-00Tjxh; Mon, 29 Mar 2021 18:38:39 +0200 Date: Mon, 29 Mar 2021 18:38:38 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 2/4] chardev/char.c: Always pass id to chardev_new Message-ID: <3e669b6c160aa7278e37c4d95e0445574f96c7b7.1617035720.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:EyVERWDMlpwY3pB07coF1luz5pkvptbp+PZAUpxBcPpy83VWDgy zW5bTnQYNN7b2Y5xCjxMCUhuegwkeDp39Z789xbzJDHR0kgkrEV2XVcszMXXYNY6V/RmvOS MV82TqDexEV1hzZaNlVq8ZanqikHCHT0WWQz38H6HaY4E+S9yt+4iX1Zc7rrMqsI/gMG77/ 22XeFFjiDGO6j76BaFb6g== X-UI-Out-Filterresults: notjunk:1;V03:K0:jb8YVuJMxXk=:j2USg3IudkBmWNqoLW5nac 7HlAx066s/R3XUNasrnPO9wnM+kE5XQkSJHYV01NqFogzg1bPfXplAcfeuIrXLRPVeuSSx0bP iQqsXy6d6WZIUoJGe/+nh3WbOVza2ypS9Ba13Ah4q4aR3mDnU4jETCVeKdYxdmyxsa+jPX9oU 1jtM3OrZM7jVlZ+FnFxfAvgLgKEJW3wlye57UlHO9hN4+DhCQcKGTZwhHqxKb6hL8pB0uIOR5 euotmcsMzt7OavCfqzUKh89S8AeLAFVoznkE7EnPArbRL/RdjuWqZWXK1vf6l4Tks03T2kOCj inKK7oZctIFa/t8o3dUV5fZ0ePwaAy26or3OXS/YdGP1ynjXyfPg4uQs0mCc5LOP+a4Fwm9UB TLY8xS5fmfY11fMX/pzSyj8IneLTNlW3gAMu2dN1jhzK33IlkQr6UjFD3dlraCCwdsqD+/gpA Bfg3mvbbciHNiJfXoc5QfBBJvRkGGJ84TvAI+yoH21R8RVr20hywYMPcf3o/mkphEhBN079J9 iiux0v0fU0NfzGa2BNxei83ZG5y/nGdYzcWNrbkMCry3lQZCya53jovJWzl4v6HceRqhc3KNk DdAiAixvbUFbQeco3h5IdEHMOMRFK/wHHFT45tTz/4kqxdfnW4ycS81Z4ELMpBZ+pr8b9nuer wliHkH8Mpg7V/R16GarFhdLo1VrQRS9QfmZxKiBtySBtt/SfMyYFb7p3jF1WAh3VrA2VTHT8s wLiFpnW00J73gs126uf04lWQE2SynwX0Ty8lUwZiAhqCNzqsd93bQ+89lI5WgQ9OXEVq6JlLN fFSJa617qGLx1DCyC1vf0mqRVDIVoavlWr6ZpkyxMutHClIxvkRbLif6k2I/ImuIV65HxQ1nB YW3BW71/e0om9e+sBUqGNPd0IQIbzLrZLcJyhCHpzgBahPr3QurwRt0xgDzD+I33b6G4dsVKU NB80+5YgLgBvk1RGtISVfYJ3uxN0uwblSQnpzlrulbAll9ssRK+Rj28Y/9EzpOkxaDNIdNfe+ swA64rKGovCjuPriAWldlpBnm4oNZ4vvdxqemm8yiOU20y+PRffBc2KVYsS1f3RMty3EahUGw okgDZ4BVwmVKbdtSuiE6PkPXKD3OiBGGtK84UUqbfbdi0MHlHiOS6wwXu3BgK5JzQT6zRZskI 3HEj6bvLNV4UDYyNwFBDQ46lIOoLep+BEhBIRknvBSebeRlIMKrc56pxYRBQ+P1TAEVm8= Received-SPF: pass client-ip=212.227.17.12; 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" 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 16:38:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170499 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 79FE3C433DB for ; Mon, 29 Mar 2021 16:44:42 +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 EEFFB6193A for ; Mon, 29 Mar 2021 16:44:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EEFFB6193A 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]:38574 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQv0L-0006Gu-0L for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 12:44:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51736) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuj-0001q0-EA for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:53 -0400 Received: from mout.web.de ([212.227.17.12]:58829) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuc-0007ia-FM for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617035924; bh=IGmvSdssENvIWp+Q/i9XD5kpAvKkHYiCDDWrv1H9WdM=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=M5QfG7J9oRuRxszihJVTHx+TiHfjwOxcGqqdIHU/gJ6FGJjQT46rkgVKFrrqTZT13 arMpQEPLHBNuhW8e3AX6B4r/6P5pkEbQe5rbHW/sN+UMKY2R9xDd7NZEeZU6+gpmwf rOVWKZNSdAy3aDzkvg40hD9D1tiQkfUtC1x4VtLc= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb105 [213.165.67.124]) with ESMTPSA (Nemesis) id 1MVJRl-1l1Ryt1RSx-00SCp3; Mon, 29 Mar 2021 18:38:44 +0200 Date: Mon, 29 Mar 2021 18:38:42 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 3/4] chardev: Fix yank with the chardev-change case Message-ID: <9637888d7591d2971975188478bb707299a1dc04.1617035720.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:vTPHHZP9b+xfiHhP8UMgOPLQ2pY1oAKdkL+vDJlZTEMkZTCQ8Yc QY7oH8Z7Ev88B81OV/mIug76kYLgJUnbOAs82tQ6BjpZX6I+pjXGBmj5gOfPLBG+kXTnff7 m1TRjozve6nUv2+Z0OjAceZX1yyLZw4Flr54jct83AFamlGuOMcZPrY0QBSW8cNcGt8lTRy L/ZWpPPhrek5QmtuHOptw== X-UI-Out-Filterresults: notjunk:1;V03:K0:eWNPzM0eTXI=:uqSWhnKr9C01xrfiCNsGib Ndu4Kcsg8U5ApTxUXsD1ipb/yqe5Zbblr/W8uy60GyWxBqjaB0ExV2T/yk3Z6LWD2RLFu5lV5 lOJ/W0iA0r2O5sIICSIH0XRvXivsASozaJz0ZeoSBzuopjCsSreE6EQQAn0Zp4qBmX7We0E3J FGFS1X4JK6R1OOu86r90cRa4l+e4VB8RnBzKmI/wOiXIp/32gyA6BKCAvqUDl1XdS/oAeMGGb kkjNib1f8zAb6q6XnqP0zx5WD7yevKKlZYXtfHjpY3oGuMIqCgNtbAZTP3SOPGqN+zlzcfWNT DX0aaxjf/KDMm5L9h0IB0DuSKR3HprrpTHdD60OTMLK+y4Rlm03ousWzI3rB/pmrzxhhdCnLs zzNVNx/MQpLrN4tJVbxJjUHCiE07P36HIyIwDN8dU21teOOP6bajf5EnQ/GimJq+K13K95rjS E1kN7Bfa0RqMC99EVqHgFEnRqk157aR73nssDXn5vvLjs8IrB5TbKWpcE8+aW0r2Gau5Rile8 5662pWbT8mp/Pzot4J2YJr1Y03Q4tic65+xytiiaK4zse5LTbQbEJ8a4vWeVqQZOJemccwKl+ gs5XGhY38Ie3QRd6dLh3M/AoUG7XEhhCjhmnOZTPFrSdZ6em79Sqj0PDpoRvKteGsoFm6D2Jo HmG1PaQg7I/cWi9aeN5UxFaOUMrhERlaRvujn6Nw0mhnSxQsCgTV4w7KD9XJUEcMWdbGhEDw2 h8Yxbed9z+w5SFpEGxYRellaqDu8FOY5ls1hHgWibdHruVoT4k11023g5sxMo9ckkpHxrWLW+ gGhQEQqT4qx8AY5JZvKS9ktwpiKs+jyxnx5D2p+Ujt2Wcl7Tgvqcuo0EKLx3CSZzgNcOKDyb6 d33lfvuEPTqB9foRnoDOsEcZYs3YDhEVoUatn0EvkxqpyWBXQR+N3ECQzIeJ3Z0aR7FMgHju/ 9SGIT+5w/mw37m3EPd+z8uNoVQYG8NZTGMQR5gtPP9eoV+gM18FLF2yLv/Oe3NdE7qHZIzv62 qZvgJ9F/ySTsPmvb9NVEoKbtGOQFbKIfskx+KZRsSCkYz1NlP8STFi9qf4rVaVkwhG93sRnK7 ew1FBnf4FNm7z9HrD0b694xJSWmD9LAu15ely98KucUSO6CtBBSLIyHotviOYHLZi4dGQJ+ys IzS7gTFkXKv0TkGOMIJphXZr6Roflce+HAG7U+ktwfBueT9IkB869rAP6cJeUR6uyGiM8= Received-SPF: pass client-ip=212.227.17.12; 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 16:38:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12170491 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 C53BAC433C1 for ; Mon, 29 Mar 2021 16:40:10 +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 59A2B6191F for ; Mon, 29 Mar 2021 16:40:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 59A2B6191F 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]:59176 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQuvx-0002u5-EK for qemu-devel@archiver.kernel.org; Mon, 29 Mar 2021 12:40:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51770) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuuq-0001ts-AM for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:39:00 -0400 Received: from mout.web.de ([212.227.17.11]:53789) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQuug-0007kF-3Y for qemu-devel@nongnu.org; Mon, 29 Mar 2021 12:38:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617035928; bh=2JqvOaJZTVygyMCS9J0KgGCroHuzkTQBVfZ1gw+FnF4=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=olq0vrlqYFsc9xpa1DPY5q5aByk4kj1eD+oRraCFqJZOWTVIL5iF083iZ755uEmiA a6jMHM8H+oKyCvtiRgr9olGgBFhmFUu+pCqPl3YYfEv7rcf6kpd20TDkM2RQNh+ocf fuOdpBxQe55XTsmHheT90lPxM86uqv2Sji3kjMLo= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([94.134.180.225]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0M8iH2-1lLSs80aEu-00CAMO; Mon, 29 Mar 2021 18:38:48 +0200 Date: Mon, 29 Mar 2021 18:38:46 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 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:XYCulbzhwJVlYF+dPClOvOE5XEg47Fjsu4gZH1H1q0LtYSPeaB+ oiXWF2wotRM3EMvFhSxO3yxSBhbeTJe8cZ7/X1u6ByAoGGYfIb7xNlxIUwYIyjZkEWwUrqr ylvYITgVcoAnMBSDpTffhKSh+oE2+WSDdrALf62t2EZSCkvwTsDX9oE+sfB3Rva4gZu/CSl DvlSoBI+MBcs0ppb7k0aw== X-UI-Out-Filterresults: notjunk:1;V03:K0:uc/0bo0h6Jk=:bol/jUx+FegDfNd9ZJf1sS uKBv1xGdP/1Ps1+ADoi/6sg82i36dDVEA/hWqC2ZbkjPmduOTVryYqbx8kv+qDi5m2I5C38Y/ Zw+iRROr0bZEIfBXAVvyajevc2HLY/UDF3HaW+A6YRUxFGbq0p9f3OlGjGePLK/v8LEPqcwCD V7x/9E7/7/rcJ0E24iMCFEeoHhkUhkdnlOFpvgDoOclL0Mze8IIMSxTRe+eFiZ1DE4NJoMwyv SdkX576A/ZRfGimjNYUQIJzX46CnRdp4v0kxtF23ZEsJurLO7de9ivziR4aEdHtcpBNXRme1H cmR8wBqOsKiVFLNzf8rZ5eiHnNako0ERpwxboxJj3GimAcOF7mimqNK36oSCijhJqsxE+DFFT vROOi4jIogI3qVvqsnu5uX5HeLkbZhWF5QuW41q98D8hbCkJaBEgAFuNdvaX3KXxUatdDt4Z5 5XUiIlUD58qaLelC+1ONuHpvoRga503/fNVKFcpIpyRgpaWQbyZBvYIzycSQXvjLVkj6Z9TGg BfHVzNBXZRHQeeuaZ7t4gUiZdTTV4RS19O52nv/nhR6gEzDNeV05LVxr5ufxjhZCHaZ4DdFxU xzx5KQ12UOu/k4ngSWpx1haE+0u/zU8X1oI3ZJWRyiz9R6V8b90D6aPGFzOpyyVRHd2l2+jg2 ASq7kocnhaKzEv71hY8Ish4GPgJVmAHxhzqh1q4WPpJMgW8yZEhHdX8N52BJf0GtERtlco8aZ F3VrQZ+1dD+ArMWZpGjChmjMwDMuqUQs7SO1R0YEPr82/Trunx8BDqCY5P0mAwsaDeaPhGQJd Zr5g4aPpfzvjBmg6RKhYlI6fTwrPflN9IMThHBPzqfzJ39BxnglOexw5P+CiwbqJv0MB9WFH7 zs7iZkTomIB4RRjkVa7P1dNUqv7D8U3ktZDyo0/Qvmu7e+BnL1/C2WEcaVung2WkYzRctXztm oDyjLZimDpB9Zvh0gF5dVLMCxKtKEEUviCsgT43yS8PVQUfsZgfOPY0cQzf86sH3Hh4BAYOrR 76EV4zOYKEXQkO5lgwppEiFDZf9zb4HLkT7xsZGZ9y1DZTa430gyN1bUUuCPCtFbKaYuBF4O9 QeiYCcq2SWz/Dd6dYjqXxRpLeEa+4NcGzDfXZCJft8nXtBHaupfkGmLXjz5peDcnDOX0k2gEd srWTm/VTXODrq6xC1RBhUvWVSHRytajpRSefAEOS6czG/Rbff0HjdmW/vGCj15wT2+usWnLnw VUqQ8QuHmMBqXHn8L Received-SPF: pass client-ip=212.227.17.11; 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 | 200 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 203 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..1596a3b98e --- /dev/null +++ b/tests/unit/test-yank.c @@ -0,0 +1,200 @@ +/* + * 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); + 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); + +#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(); +}