From patchwork Tue Mar 30 18:13:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12173495 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.7 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,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 1A5CAC433C1 for ; Tue, 30 Mar 2021 18:19:52 +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 5E08A61983 for ; Tue, 30 Mar 2021 18:19:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5E08A61983 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]:40514 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lRIxy-0007ME-9Z for qemu-devel@archiver.kernel.org; Tue, 30 Mar 2021 14:19:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54366) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIrw-00043U-NL for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:37 -0400 Received: from mout.web.de ([212.227.15.3]:34633) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIro-0001qW-Da for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617128006; bh=3XXtN6y+j6slMq4ZGt8WNHFfVhnqvqqw6X0e78KVl50=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=KccI/rcTQ6TkyoS3lEL/z/o9x6dSFwa2m8hr0oAAcMCL8MnhhD3LWtSIVetgbtsJo j79kC7kqP+9dtJnYv7Mbs97niODvBsbQqmY+PAEi1cPw2x3aiUAuaTXmKRV+SSIkDP U7xuGudE3f57LAvuHCW9af02OAoy5QznVM8rgqP0= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.86]) by smtp.web.de (mrweb006 [213.165.67.108]) with ESMTPSA (Nemesis) id 1N14ta-1lbmDU1pk2-012XRn; Tue, 30 Mar 2021 20:13:26 +0200 Date: Tue, 30 Mar 2021 20:13:25 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v8 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:WDQLgNJuO1D+pCjWoSUW+93+3D5XM3hJlo6V0qT0p8UhXJqdXDx CayZG7znBSI5khVcDcvU+Z4WPHM6lY6B+oCHJ47q7U9Q4HvwVDh1b4E+jreWOoQc+UGltRC dxUK7bRBa+hOAWTOSY2OBeB81bkZUHOwWHtuVkAqbIKtGpCAUUBDR6NcNfV5Tv4F/hJ4qVC HppzIQkj0R2HYlDCx+/sg== X-UI-Out-Filterresults: notjunk:1;V03:K0:h30CVOOj9J0=:bUPwMFIif1qUf5qc3Opu+X DUpxltK1k+HZ9/IDlu6U4+QPjYYmvn9HP3VPQqtA4VX4amk5DHjneFGHlEijnmfXaaeft3BXF zpmNmQYN4PtlxVFwK0t+XGXXFOu/xwf3wOXtM8bXuHRh+iCfhg2YobCXw+8IPiX8ZUnzXP02c iH3UV80uMPVvpXWawsTMjOKD0YKTh8hxmtuPSlwCYPzjA1z6vUvZrgOB3ePF00DsaZ+MVAQmj PQvFZKhCu3F9n61iEfDgiY6hScyjcKpo+ybAgXzR6DRrF4UE35Dagswn98U4Qk7bLmRmAi/WJ IVkR5pVAKyCWToW0blola8HCzZnBU4iOPVeSRk+CQlDMs60RgLyiT86thLu32zN4ucqhOExwM WCsf6a6Legf6mhdJwTsRLufrTCrKxtw+GdmvD2rQFRvdKE1z+snLbnY2fp/rUrboW6lOLVQQJ OCe9sThBDUoh6/Xb003fuOVWJhi30f2vmRY/2YAF44pRsYufNsSc8mI1dFbWPl5hrV3CdD/Y6 LwfqRjXuYiZvEh1rLNCeogJB+cvQf0+35NPoUICAktJzFtl6ckX3IZoAodgGB0Wy+K8G8I2Xl yD33z5RcWzW8oZAELH26UCrjK9ERa5oZJMPBXkFkyAK23CPCsJt15l2p2gaZyTSvzU0WCWFaO RE/M7eKoLRnUK9ghlzW2W6PZKJ7jbZdPfLIuACxGxgK6D3BIJJ8WDqfkdbgd8adaaBylaLKEW 5MSYupslx/0m8HC9oO4X8kkMlNLTtQ8c0CwyOMcJERmm+Gd3eXB18WqdSMZCVJWH3vCqXpVRJ p3JbRuX5FYLrFd/cnXz+sdo6KucGQodE5dE2mrLuiDSf6iYE7uJnAI4UXhj4JGUMZn4HYMYYj Ecrf8jE5HocveNxrtkpWsektylAWvkZ9ZcD0VwHjv88WqmYwvYeOqXWn8nZv8qLxhnYgahgPA gVCPHpicjP9PwcoUrxZr4NitG+1FJJvX6SybJKspFRXIoqP9i2rYDmK2Ky7qqj3Z4pN5yF+rU aNcT1bYCXdqt0fPXXZ1HT3TUWBpoFvhxrViPkWwfaZ2xAKETYJXLvvc3K5+e7SmjP1Wgr4ioC hfVpbh8nsko1ONlSJSv/7Nzc9z0ooAZu8lyuLSvFx+pCelwuoW1hnKVauFLtmmiO/aMUUCVgu zZaKV+e0XgvPJ8O8eCm1Cg41pCXie401Ou5CsAUCGmuwky2N7Ioa54A9iRM36e5EYZmqo= 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" 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 Tue Mar 30 18:13:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12173491 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.7 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,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 778AAC433E1 for ; Tue, 30 Mar 2021 18:15:55 +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 BBC6F619CB for ; Tue, 30 Mar 2021 18:15:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BBC6F619CB 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]:35402 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lRIu9-00057L-JD for qemu-devel@archiver.kernel.org; Tue, 30 Mar 2021 14:15:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54362) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIrw-00043O-HQ for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:36 -0400 Received: from mout.web.de ([212.227.15.4]:45577) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIrs-0001rn-Tt for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617128010; bh=9DpaeOdIwE7r2Ud+HU0Mtwm5YefyxWD/qpvs72RsLtM=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=dE9G4xm2+Z5mnNOlAKMxyUEy9OXaGhtvMbV8eEMbn+5RplIZZjvQHqIrvTeSfVLKI oJS2N+3gObzGwVBZ6bruimCcHYHu9oHdiI8KPdl/N/6fvtK0EF/Gal7+pbhtuXNrdh nIxc/UfERy8LYOG774IytZUWtL2MCPx/+lvJF5CI= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.86]) by smtp.web.de (mrweb004 [213.165.67.108]) with ESMTPSA (Nemesis) id 0McBct-1l9uhy3vMd-00JahA; Tue, 30 Mar 2021 20:13:30 +0200 Date: Tue, 30 Mar 2021 20:13:28 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v8 2/4] chardev/char.c: Always pass id to chardev_new Message-ID: <3e669b6c160aa7278e37c4d95e0445574f96c7b7.1617127849.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:7maQWLbrNFeTRh1miM9PmrfQfI8Ytd67Ww45YhqkZJgYYYBDTGS Vxi7oOPziup/5TOmVulbgILqRnnlF/C5ZvU8C6rRe+R3x50j+PZBhnsEvMF5RLKbqGS0CDa CvxWlNBIbiTgxSKb2o5xzkXvooK7L7wxVsY1DwBO7Lldk+Yzw8Pi35/js1mAC98W3VAihrd pUhNfOQg1iZhQVB2yDMPg== X-UI-Out-Filterresults: notjunk:1;V03:K0:StWw7+KhlLI=:ug/oysNNVhRzVXc+6/JXmw yB399LXzUttan6k7ii24N/pt6Rh8iCmzZ4Tf508gsGRdpA4yQXFdGVqNXIeJvmSxZhmetSHab rVTPcfNuFyWk5lZnZc21Mwjy3Ks3NMUJmdRilSafzPTnikrrdqTfmsQC2FyPPKYM0YmJZBM3e TTzlVRREclhEHpqWrsq6yPInSk1z+VFqPN8CKYghGwsu2+dSg1n1oyXiHe3XAjuO7ntPGnSTq yudxBR8FgJ0EOb4/WoLBO7cZM9sp5EhV4KZ5kAlS1zlLrzdktPPIN7pkA2HGWlYnMHOA9+I/3 jwBLmDdCkeLRCjXXXOnJjqpUPM/usdHu+xMzzHJGCX3IiRlAnZfEQI+VKRnY43md3AjB11FJS 6fnQGTSl3ALYlVdGoqlipFzdop3MizcJV0JXFOh4yB+GEiF/CN0ALZeko2PzkETcAKPPnlWEb L4YE1aERjCQ5cZ9VHT6NtCRp4kJ8rFo4Hlqp5eNCkSC/T8d3moTFnH6I7ZmPuDTQ59CSOmzhZ jzA+8sTTLrPTFy4mPADPpD9NC/qZmbZq2aBOeNUS50dqwmf85wE0aK3Q/yGuKinPyii7oUoVn FkXqCK+41SFzh/jH4sv1b89JKhwt4M6hXoSACIx9gLJKt6E0jlJkcXe0w8lvgbkDsxVaBnHfU OsP3lOObTfMNf5d8QI8AntTWCAY9tYg8m4ZojU1+ygvuA4baGLsigWjowUHko36cKpWB/Loxg 4QXwdpCtb4ziWIspPtILm67jqWk0y+8HUOu2sRnt2io7EDXOVRqtqdIO3FEr2Hmvl8irz51kd gOPnQSNfJLUtYWXBsJIF3zi9Eu2rBAhJsH7Ec6VYu25z12inlHEcoG+ZXs4WrpDif0Dx+u0bT UKJC5i8XLb2SpM5ZM50VJcQh7t3NZdjHlGBzyZrYHIH2OM6IWB8EAbnikR+y6OOghymuBLkyc bIcQklrgzB14UOTlq7X7f0w/HcUoHmtP5nSJu90RdSelQ4rO6HAYuLiw5VR5CA569AWzUKcfB cCzLbDOZXIwzuIOhzjf/XQN6hcOMe/iZcz83/ICfAx+kyb53rUIAyAW6Xt0zhcDxXh540iGWt 6+lufSV+5qLuYDmDH6Z1eMZB4ua/kP6Y0dR1YuMQlUxDW1YercVpJh+vb4ewMpIPux2aQc1el RBHrjnv94ccTa58uFVVyXRKURnXQuw0hsdUV3kLYTK6Bwi4FSm3TTJnyYpWKIhX2wXs98= Received-SPF: pass client-ip=212.227.15.4; 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 Tue Mar 30 18:13:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 12173497 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.7 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,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 D724DC433DB for ; Tue, 30 Mar 2021 18:20:00 +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 64E0F619CB for ; Tue, 30 Mar 2021 18:20:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 64E0F619CB 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]:41122 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lRIy7-0007az-G9 for qemu-devel@archiver.kernel.org; Tue, 30 Mar 2021 14:19:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54386) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIry-00044X-JN for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:38 -0400 Received: from mout.web.de ([212.227.15.3]:35357) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIrv-0001rz-5X for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617128013; bh=xPDIAsYxOfhAIS0WEPtnmy532i2hm0fwDkYFf2Zze6E=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=dLQVQEm5Sz9cMCKLt+9ASvueFd8KCUtGBAD3BEkdAWY8Qomkj1sRA9ienx+PSLfjx p0QsfAR9qIjEZMduX6k89k/zdHAxhMU4KNcNRwFdgLK3EXYm9pGB1CzrRpkhJn4eLQ zRNdonLDjzAb04ycjQAyQN0ms3fLS547pXezBQnA= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.86]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0M2MZY-1lk4jp0CEm-00s6CS; Tue, 30 Mar 2021 20:13:33 +0200 Date: Tue, 30 Mar 2021 20:13:31 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v8 3/4] chardev: Fix yank with the chardev-change case Message-ID: <9637888d7591d2971975188478bb707299a1dc04.1617127849.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:O6BdTSpJ/3LgT/3FUtPW2L5cG0mljf19j9h0si/eJHzTsxq24Xe dKJATwCtfsX5VycSvwDELcXjTDG2lp1rH9IHJVeCk4lqezC95hu7XyX9g+or/p0E+Mrw1N9 faPxGm9G5NXLM5tQ8j+cpWO/o2VjbKDPLCKPfG9wPaek5K1EAcfwDmQu8m1Z3w2NIQNg/qS 5K4l2X9W5nHxpaAF+xs6A== X-UI-Out-Filterresults: notjunk:1;V03:K0:XV/mD+NlFX8=:TwV3C5L622lDx6B5lE1cod 1oFShM3sTlhUzQBroWIkbwtoxbGMoIFZemp8JYfXPTgtqMB5h/Ij/27OAYxAnr+g6B5YgqQ9b pcHy+LciwosNnwiQ0upOT87O2hT+VTKNFsTnTrLCV4oLLmmEk/R4faYaM0Vp4BFJBk3PkhIYR /duyGLiRno7LgronPWOtxoCtWJbJSRNCy2d4V3itKqPIzrLI7qzSzoOp0NOwMKKrhITe1EQKy /gPmrk6nVlzF417KPt/VwB9nrlbbmZ0/W/IaWT/iC07MMWS67dwptBW9s4W69zZHzT942iWNG omAl4wqBhO3fsFyl0DebPvDhVLODUjpi6Ll5nhNtI+fCTNM8Pf+o+6hreM4msItzzRSMmmxdC 8tIr5i6FKE52e1fT7gJ3KUnTIUC0STdFPFMz/hqy9tVyTVXqbdMsVpce3hC/jQLqJ+1TCGpAC 60WSEy/g+NVGYSfyQ7Z/c2YU1Y73Td7DrInT1/4YT6MKmVXLGbpd8ckDNTgKVa/EyaHRa6TjH nUm50S98cxRuyZromNQIzn8R7H+Mie0ENTh5U848kH1sCOR+x5ghxfNOf9xIHtn6yqsn8sI/K UvOgyUInhnhTYHwYjksr317xAiXgRyYmxKiIb1gY1hslKPIjqcsIKT10EkqplB4LrgAmnmCIj ncHAqJPHFAuuw3x3PQuk5O+UQpta4UTSHMmFx0S3+vZR4dUjD9cStDa3YgCjIIFseAWaJsdO1 fyLeia34cqMvNf9NxZ0nEllSGl1fTKT6zvAMevqamv68ZNEFvbrTGDmyQuCr5FvbPh7cuTkik Tr5RLWTEoefaagIKTs7dRj+nSzBZ401ZGVoSDfAT+lep2+JITgKgO4zkhGw/+qjZiFlXvwJzM PodJpSs0U00aAnE4t+4RlGrNFoQw+K2Ky07F+jeC1u89yNZmUr8WAJV8Mv6lBmgDN+Jpj1y2t nVj25DtwsXf24t+DfEGYsLA6kYIZLKf8hT5oBI6ZNjAwUUN56piL37UFBWwRapdWqBe85HwF2 6xts3Wo2oDbQQ1jsmsSbEA8PdraKGdo/k6hiQWUxUN5/Qxk02851Cm+YRc41hD1LQtp0Y0unh Fg+GkrFHMzl9m+idKCpV77jtKnR92xqf7+Ycpt1phaCp27NM8tskyZbXvriSDD0ZkxVgjJscg FhaJ0SiX2g4VEwN6G2T86bXCrwqa0ayfHmqpyvPPfbhDyRscOpruYESO7jXGjgNqPnTzg= 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 Tue Mar 30 18:13: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: 12173535 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.7 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,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 8DF03C433C1 for ; Tue, 30 Mar 2021 18:23:40 +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 E672F61983 for ; Tue, 30 Mar 2021 18:23:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E672F61983 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]:45446 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lRJ1e-00019g-Qt for qemu-devel@archiver.kernel.org; Tue, 30 Mar 2021 14:23:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54400) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIs1-00045s-3g for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:41 -0400 Received: from mout.web.de ([212.227.15.14]:47447) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lRIry-0001tS-DF for qemu-devel@nongnu.org; Tue, 30 Mar 2021 14:13:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1617128016; bh=hYWHdhWJ57FW11DHZstamdRVO3I1fZa5ifyu3TnL0nE=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=S0LrXMWn0PrF9gCv1MxcDOgsdzqxrCLFvFZNzR/12U4ZjPBmEzS7m+k58+BWoO/ND z/QV+0rX89nKDr3wJivx13twIWZ0yzIHK5W9ae/U4Ux6JzALHeBIQ1G69zKq69rddw +RxzzCRmtvdkY5/hvnA/KH4Rg0+awLrty+1pgI84= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.86]) by smtp.web.de (mrweb006 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MfKtb-1m6QB91BlL-00gpgn; Tue, 30 Mar 2021 20:13:36 +0200 Date: Tue, 30 Mar 2021 20:13:35 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v8 4/4] tests: Add tests for yank with the chardev-change case Message-ID: <697ce111503a8bab011d21519ae0b6b07041ec9a.1617127849.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:EZSSNlMAuJ2/014CPU1Q1XCHkeSoSoQOm3E/wbYgcfp6Z5ECtAe yXSvfgtdXytYgeUk2XnoLL2+d3iLlgfzHOnyh5WTO3h9IeQ1G3+1GWJ/3vPItGDcoFLHFKf YLHrUv1/3tll9ZniRP1KL0KKCwmQTSzErb/fXeMECKnRNVgfcjGoXOxsovBSuvcPBPh53x4 VxL/PctBiF0QuwroCLUng== X-UI-Out-Filterresults: notjunk:1;V03:K0:lt74Rvaod2A=:+NTKykOuf1XUct5oHBAC5p IcfIi78eC1PrGcKMnm54KGP9I5mGKN2Lxo5Vyc7aOatbJlJoB6jz/woutZnp3BH5kZY0rFz77 IuBO04sU0JNBiIzUwE/9fFmtb8Aw4dhPe1Ep7LwX1Wbo1WCy79prz5mjCZ0TpCQecmN/TCNeA 2O+YFhsmFBPOki6CZ6kN0weNxZBIMvPJ/vS9ywQ4MMKg8Gf47hpeH6ksRYj0IgvHJygQVljTd fBKc/p3RUYsJcQ0PeBec4dJJeywpGzXUPhRqd8Gr2zJCdzmGHfy1QqsjLizlkfIApXEQiOabx v5slXDgIjiKSUSGBEL1J3YWwyb3R5gY5asLF75HO5YeylFYvyGBCw6hOA4qp5YMXPP/ofjJyH BA2oH2O8/EaKacRetpLcSKZr8god5xIU7j9B8d5QQaMB6D24Ug5tJKZXdSvHhtwgf5vyegtje tDplCU/qBjbAzo6NEq1cAJXWOLml5K0worU27I1DjWXZJ9fPu9Yo2dc0SiBo+D6VlS0JAyZ1z j0DRpgSK5rSPRegxe7pEThsHfat8IUFS8uOyKs4HENslYRgG5zE5sLprc3qQJ9PgGKYAG8is+ KLrulnmwLtA9KfclHYOX/E/ig1crX9nQiZa7xNbFtaOICPfgN5j3kvabDIot/c3xKIyPmbJSa YQjfPLx/JW3PFKSutQYUQ7OWShR46tCr7YUckecP+aYFGKQErbGklw14AX7fRfqRAcuXVlxug hwMblO7Xhr5E9GRghlXZ/IuDS5UjnRSmrMbKwplZaDZopIWpLPmDd1PxSZuicxZRlR1TMqKdn pVoRxbVTMe780aYrQQaUG+E4f7vArtk062J/eEim/XCPydD81cZTQC2rYmUeH7Z1otEb4+L1W gQj5/JUNYbJ0kWmJIHgICyjPMm7hEDLMyNNgH0Jk5jaUSxfY5C6BZmD9stskUOb3GK6INsXAa KDlEH0jUMY+rremHulTNb5cdwuROcBq7X9TlM9n91zxxv3R9QcP0jGbDMmi5W3xmHEYM6jooQ HnDi3tyYkOinQfSk8gIXUyzlDT1u8JAOrd8s4RswgZSa1j27suKN2MpzdEqloNxPY4SbKReI5 Clvf5VkWT5eZC90GWQOxKnFgENTo8+iwvsqLPqQAntjbLKoFZGW2QWQM5CrDSAhdm3aFWWBil dmdm3ucmhBjQBYxIjIt8dBVXG4ajxyfy/NB6jxZNyDt4SAvhyTC9ePNmLnvO/cdtLc0tFEB1+ awMnxmgHHIlj9jFLm 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: 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 | 249 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 252 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..2383d2908c --- /dev/null +++ b/tests/unit/test-yank.c @@ -0,0 +1,249 @@ +/* + * 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 gpointer accept_thread(gpointer data) +{ + QIOChannelSocket *ioc = data; + QIOChannelSocket *cioc; + + cioc = qio_channel_socket_accept(ioc, &error_abort); + object_unref(OBJECT(cioc)); + + return NULL; +} + +static void char_change_test(gconstpointer opaque) +{ + CharChangeTestConfig *conf = (gpointer) opaque; + SocketAddress *addr; + Chardev *chr; + CharBackend be; + ChardevReturn *ret; + QIOChannelSocket *ioc; + QemuThread thread; + + /* + * 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()); + + if (conf->old_yank) { + qemu_thread_create(&thread, "accept", accept_thread, + ioc, QEMU_THREAD_JOINABLE); + } + + 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); + if (conf->old_yank) { + qemu_thread_join(&thread); + } + + 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 { + if (conf->new_yank) { + qemu_thread_create(&thread, "accept", accept_thread, + ioc, QEMU_THREAD_JOINABLE); + } + ret = qmp_chardev_change("chardev", &backend[conf->new_yank], + &error_abort); + if (conf->new_yank) { + qemu_thread_join(&thread); + } + 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); + + 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(); +}