From patchwork Sun Dec 13 11:48:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415554 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=TnNRbUUV; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv2rz4JHBz9sTg for ; Sun, 13 Dec 2020 22:50:25 +1100 (AEDT) Received: from localhost ([::1]:51562 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koPtO-0005ad-PA for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:50:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60914) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrZ-0005Xd-2F; Sun, 13 Dec 2020 06:48:32 -0500 Received: from mout.web.de ([217.72.192.78]:49879) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrU-0002K9-1O; Sun, 13 Dec 2020 06:48:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860095; bh=b11e9asJoL18FeoBNGbpLYPJRTnbEN+Q1lBSaxI3aFY=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=TnNRbUUV9Wem9bmLJSIIEl21n2uBjLkBT8TnztxIXaStwwJnfJVRaQNvECooJ/yzI /YUdCXFE+eVuhjh92zaFRBtE9EnVlcJ1TESdB/2WDGBHczDG2kj8pR6De5qE7nY8up K9tSgfozTMJr8GAy1hXJUT8hERnlIUmUBZEYb3zg= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MQ6PP-1kkGr73Bvn-005KYk; Sun, 13 Dec 2020 12:48:14 +0100 Date: Sun, 13 Dec 2020 12:48:13 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 1/7] Introduce yank feature Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:nemxQbkFU6Wp20FaL1gtsFHL6YROEuo4mi+zpqrCYQgzLsrpyGn TCT8SM/WvWt5ZZFW5ozgWKple+9mq3cluiMwp+FZ/gHYqKEAA4alEdjgTpbtpW8Gp0/MdmJ cwqu2B+ReQRMDWOmkQQacj2fTR/ocK0Ztrs4pWCibFUB4D8NTMD2WkMQAp44lSyvVEG4VVE 7VsJFyl8vRibgA0VtwglQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:phYyzDjSuoM=:LtQ+SFUzjx7kJ3PhFbjOaf O+GERMMClzOLfyUvgTFcTN1D1M+IBD36PpKvplTU8u2++mG/y2qOu7tjkXht6x8xdkiMEqWSw DXXMeWUoGZ3qeiLM+/Grxw2Q5eottn+cGYcuZFR0OhG3Hnr3Qvz1UYdqIgpapInzNbg8LRqKy LlJo2/NJz6XEscJ9HDvc2p3DfaQ6Lkg2EJ+RDe+6eQf22j76DJKkmyJb3Nlo/wpbed7kDWI59 0Vfnv9RiFdR8SBcmB7/ygDIKgax0WPinSucHKPpOn1kk92kKtzis+SDfddBIbPMCaGPb9OsXX di3Vx28OpOs+dgFsp2gBwkj/IoSIMRntqNo+X1ThiXHshlAaWhq5+qVyhvzSQ7Ct/ALaQbudK nw9u6ytR+HWToT4xdw/aWj+u3o3SamRhD8AvFrb5xdmQXug7+ksWo5IRmgdwITLzz/b+a4ati 2Vd/4p+lis/ALmmFj/2TnXsJubQvS8Phpwc7S1Keuf1Fd0uOSg5afxIcCcyyFrIqOx8Cc+nIr Z+xFgEqNnBBbdPoUL/DKs616lbcN3u3qheFO7duGv1HnQT9z4HkteJ/HOj2ev0SV/43Oiu25p KBuLGwoFBk/9LbsKZrKg1hkl6MrkeX02BZIoZ00E9T35akYV477fLqqR/PrXYotZ5Kuh+Md2k eWcZl2TXiQ1KP7aq4YyYvwNuYxj3tjb8vAUpRvjL8OT3hCJe5FEA9qWWLT2rgh15QoNpprBl8 CV5/Ob0Avi2CxEMqOdxrlaoX6Ex09qjd2nWvMOHmHte7yeHMK8fu4SKb+K7JMTDskioV+cTLL yxril/s3HXplXJ33oTQzFhOv47dAlEZFnh0+NSBfndMEmb4dWOIqr4kKE9GMqtvoOucmclaPQ k97hWG5kTldHK5OTtesujT5NdqKMQS4LcxwzqVrKQ= 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_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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The yank feature allows to recover from hanging qemu by "yanking" at various parts. Other qemu systems can register themselves and multiple yank functions. Then all yank functions for selected instances can be called by the 'yank' out-of-band qmp command. Available instances can be queried by a 'query-yank' oob command. Signed-off-by: Lukas Straub Acked-by: Stefan Hajnoczi Reviewed-by: Markus Armbruster --- MAINTAINERS | 7 ++ include/qemu/yank.h | 95 +++++++++++++++++++ qapi/meson.build | 1 + qapi/qapi-schema.json | 1 + qapi/yank.json | 119 +++++++++++++++++++++++ util/meson.build | 1 + util/yank.c | 216 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 440 insertions(+) create mode 100644 include/qemu/yank.h create mode 100644 qapi/yank.json create mode 100644 util/yank.c -- 2.20.1 diff --git a/MAINTAINERS b/MAINTAINERS index d48a4e8a8b..5d7e3c0e4b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2705,6 +2705,13 @@ F: util/uuid.c F: include/qemu/uuid.h F: tests/test-uuid.c +Yank feature +M: Lukas Straub +S: Odd fixes +F: util/yank.c +F: include/qemu/yank.h +F: qapi/yank.json + COLO Framework M: zhanghailiang S: Maintained diff --git a/include/qemu/yank.h b/include/qemu/yank.h new file mode 100644 index 0000000000..96f5b2626f --- /dev/null +++ b/include/qemu/yank.h @@ -0,0 +1,95 @@ +/* + * 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. + */ + +#ifndef YANK_H +#define YANK_H + +#include "qapi/qapi-types-yank.h" + +typedef void (YankFn)(void *opaque); + +/** + * yank_register_instance: Register a new instance. + * + * This registers a new instance for yanking. Must be called before any yank + * function is registered for this instance. + * + * This function is thread-safe. + * + * @instance: The instance. + * @errp: Error object. + */ +void yank_register_instance(const YankInstance *instance, Error **errp); + +/** + * yank_unregister_instance: Unregister a instance. + * + * This unregisters a instance. Must be called only after every yank function + * of the instance has been unregistered. + * + * This function is thread-safe. + * + * @instance: The instance. + */ +void yank_unregister_instance(const YankInstance *instance); + +/** + * yank_register_function: Register a yank function + * + * This registers a yank function. All limitations of qmp oob commands apply + * to the yank function as well. See docs/devel/qapi-code-gen.txt under + * "An OOB-capable command handler must satisfy the following conditions". + * + * This function is thread-safe. + * + * @instance: The instance. + * @func: The yank function. + * @opaque: Will be passed to the yank function. + */ +void yank_register_function(const YankInstance *instance, + YankFn *func, + void *opaque); + +/** + * yank_unregister_function: Unregister a yank function + * + * This unregisters a yank function. + * + * This function is thread-safe. + * + * @instance: The instance. + * @func: func that was passed to yank_register_function. + * @opaque: opaque that was passed to yank_register_function. + */ +void yank_unregister_function(const YankInstance *instance, + YankFn *func, + void *opaque); + +/** + * yank_generic_iochannel: Generic yank function for iochannel + * + * This is a generic yank function which will call qio_channel_shutdown on the + * provided QIOChannel. + * + * @opaque: QIOChannel to shutdown + */ +void yank_generic_iochannel(void *opaque); + +#define BLOCKDEV_YANK_INSTANCE(the_node_name) (&(YankInstance) { \ + .type = YANK_INSTANCE_TYPE_BLOCK_NODE, \ + .u.block_node.node_name = (the_node_name) }) + +#define CHARDEV_YANK_INSTANCE(the_id) (&(YankInstance) { \ + .type = YANK_INSTANCE_TYPE_CHARDEV, \ + .u.chardev.id = (the_id) }) + +#define MIGRATION_YANK_INSTANCE (&(YankInstance) { \ + .type = YANK_INSTANCE_TYPE_MIGRATION }) + +#endif diff --git a/qapi/meson.build b/qapi/meson.build index 0e98146f1f..ab68e7900e 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -47,6 +47,7 @@ qapi_all_modules = [ 'trace', 'transaction', 'ui', + 'yank', ] qapi_storage_daemon_modules = [ diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 0b444b76d2..3441c9a9ae 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -86,6 +86,7 @@ { 'include': 'machine.json' } { 'include': 'machine-target.json' } { 'include': 'replay.json' } +{ 'include': 'yank.json' } { 'include': 'misc.json' } { 'include': 'misc-target.json' } { 'include': 'audio.json' } diff --git a/qapi/yank.json b/qapi/yank.json new file mode 100644 index 0000000000..167a775594 --- /dev/null +++ b/qapi/yank.json @@ -0,0 +1,119 @@ +# -*- Mode: Python -*- +# vim: filetype=python +# + +## +# = Yank feature +## + +## +# @YankInstanceType: +# +# An enumeration of yank instance types. See @YankInstance for more +# information. +# +# Since: 6.0 +## +{ 'enum': 'YankInstanceType', + 'data': [ 'block-node', 'chardev', 'migration' ] } + +## +# @YankInstanceBlockNode: +# +# Specifies which block graph node to yank. See @YankInstance for more +# information. +# +# @node-name: the name of the block graph node +# +# Since: 6.0 +## +{ 'struct': 'YankInstanceBlockNode', + 'data': { 'node-name': 'str' } } + +## +# @YankInstanceChardev: +# +# Specifies which character device to yank. See @YankInstance for more +# information. +# +# @id: the chardev's ID +# +# Since: 6.0 +## +{ 'struct': 'YankInstanceChardev', + 'data': { 'id': 'str' } } + +## +# @YankInstance: +# +# A yank instance can be yanked with the @yank qmp command to recover from a +# hanging QEMU. +# +# Currently implemented yank instances: +# - nbd block device: +# Yanking it will shut down the connection to the nbd server without +# attempting to reconnect. +# - socket chardev: +# Yanking it will shut down the connected socket. +# - migration: +# Yanking it will shut down all migration connections. Unlike +# @migrate_cancel, it will not notify the migration process, so migration +# will go into @failed state, instead of @cancelled state. @yank should be +# used to recover from hangs. +# +# Since: 6.0 +## +{ 'union': 'YankInstance', + 'base': { 'type': 'YankInstanceType' }, + 'discriminator': 'type', + 'data': { + 'block-node': 'YankInstanceBlockNode', + 'chardev': 'YankInstanceChardev' } } + +## +# @yank: +# +# Try to recover from hanging QEMU by yanking the specified instances. See +# @YankInstance for more information. +# +# Takes a list of @YankInstance as argument. +# +# Returns: - Nothing on success +# - @DeviceNotFound error, if any of the YankInstances doesn't exist +# +# Example: +# +# -> { "execute": "yank", +# "arguments": { +# "instances": [ +# { "type": "block-node", +# "node-name": "nbd0" } +# ] } } +# <- { "return": {} } +# +# Since: 6.0 +## +{ 'command': 'yank', + 'data': { 'instances': ['YankInstance'] }, + 'allow-oob': true } + +## +# @query-yank: +# +# Query yank instances. See @YankInstance for more information. +# +# Returns: list of @YankInstance +# +# Example: +# +# -> { "execute": "query-yank" } +# <- { "return": [ +# { "type": "block-node", +# "node-name": "nbd0" } +# ] } +# +# Since: 6.0 +## +{ 'command': 'query-yank', + 'returns': ['YankInstance'], + 'allow-oob': true } diff --git a/util/meson.build b/util/meson.build index f359af0d46..f7c67344e1 100644 --- a/util/meson.build +++ b/util/meson.build @@ -50,6 +50,7 @@ endif if have_system util_ss.add(when: 'CONFIG_GIO', if_true: [files('dbus.c'), gio]) + util_ss.add(files('yank.c')) endif if have_block diff --git a/util/yank.c b/util/yank.c new file mode 100644 index 0000000000..4a0f538359 --- /dev/null +++ b/util/yank.c @@ -0,0 +1,216 @@ +/* + * 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 "qapi/error.h" +#include "qemu/thread.h" +#include "qemu/queue.h" +#include "qapi/qapi-commands-yank.h" +#include "qapi/qapi-visit-yank.h" +#include "qapi/clone-visitor.h" +#include "io/channel.h" +#include "qemu/yank.h" + +struct YankFuncAndParam { + YankFn *func; + void *opaque; + QLIST_ENTRY(YankFuncAndParam) next; +}; + +struct YankInstanceEntry { + YankInstance *instance; + QLIST_HEAD(, YankFuncAndParam) yankfns; + QLIST_ENTRY(YankInstanceEntry) next; +}; + +typedef struct YankFuncAndParam YankFuncAndParam; +typedef struct YankInstanceEntry YankInstanceEntry; + +/* + * This lock protects the yank_instance_list below. Because it's taken by + * OOB-capable commands, it must be "fast", i.e. it may only be held for a + * bounded, short time. See docs/devel/qapi-code-gen.txt for additional + * information. + */ +static QemuMutex yank_lock; + +static QLIST_HEAD(, YankInstanceEntry) yank_instance_list + = QLIST_HEAD_INITIALIZER(yank_instance_list); + +static bool yank_compare_instances(const YankInstance *a, const YankInstance *b) +{ + if (a->type != b->type) { + return false; + } + + switch (a->type) { + case YANK_INSTANCE_TYPE_BLOCK_NODE: + return !strcmp(a->u.block_node.node_name, b->u.block_node.node_name); + break; + + case YANK_INSTANCE_TYPE_CHARDEV: + return !strcmp(a->u.chardev.id, b->u.chardev.id); + break; + + case YANK_INSTANCE_TYPE_MIGRATION: + return true; + break; + + default: + abort(); + } +} + +static YankInstanceEntry *yank_find_entry(const YankInstance *instance) +{ + YankInstanceEntry *entry; + + QLIST_FOREACH(entry, &yank_instance_list, next) { + if (yank_compare_instances(entry->instance, instance)) { + return entry; + } + } + return NULL; +} + +void yank_register_instance(const YankInstance *instance, Error **errp) +{ + YankInstanceEntry *entry; + + qemu_mutex_lock(&yank_lock); + + if (yank_find_entry(instance)) { + error_setg(errp, "duplicate yank instance"); + qemu_mutex_unlock(&yank_lock); + return; + } + + entry = g_slice_new(YankInstanceEntry); + entry->instance = QAPI_CLONE(YankInstance, instance); + QLIST_INIT(&entry->yankfns); + QLIST_INSERT_HEAD(&yank_instance_list, entry, next); + + qemu_mutex_unlock(&yank_lock); +} + +void yank_unregister_instance(const YankInstance *instance) +{ + YankInstanceEntry *entry; + + qemu_mutex_lock(&yank_lock); + entry = yank_find_entry(instance); + assert(entry); + + assert(QLIST_EMPTY(&entry->yankfns)); + QLIST_REMOVE(entry, next); + qapi_free_YankInstance(entry->instance); + g_slice_free(YankInstanceEntry, entry); + + qemu_mutex_unlock(&yank_lock); +} + +void yank_register_function(const YankInstance *instance, + YankFn *func, + void *opaque) +{ + YankInstanceEntry *entry; + YankFuncAndParam *func_entry; + + qemu_mutex_lock(&yank_lock); + entry = yank_find_entry(instance); + assert(entry); + + func_entry = g_slice_new(YankFuncAndParam); + func_entry->func = func; + func_entry->opaque = opaque; + + QLIST_INSERT_HEAD(&entry->yankfns, func_entry, next); + qemu_mutex_unlock(&yank_lock); +} + +void yank_unregister_function(const YankInstance *instance, + YankFn *func, + void *opaque) +{ + YankInstanceEntry *entry; + YankFuncAndParam *func_entry; + + qemu_mutex_lock(&yank_lock); + entry = yank_find_entry(instance); + assert(entry); + + QLIST_FOREACH(func_entry, &entry->yankfns, next) { + if (func_entry->func == func && func_entry->opaque == opaque) { + QLIST_REMOVE(func_entry, next); + g_slice_free(YankFuncAndParam, func_entry); + qemu_mutex_unlock(&yank_lock); + return; + } + } + + abort(); +} + +void yank_generic_iochannel(void *opaque) +{ + QIOChannel *ioc = QIO_CHANNEL(opaque); + + qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL); +} + +void qmp_yank(YankInstanceList *instances, + Error **errp) +{ + YankInstanceList *tail; + YankInstanceEntry *entry; + YankFuncAndParam *func_entry; + + qemu_mutex_lock(&yank_lock); + for (tail = instances; tail; tail = tail->next) { + entry = yank_find_entry(tail->value); + if (!entry) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Instance not found"); + qemu_mutex_unlock(&yank_lock); + return; + } + } + for (tail = instances; tail; tail = tail->next) { + entry = yank_find_entry(tail->value); + assert(entry); + QLIST_FOREACH(func_entry, &entry->yankfns, next) { + func_entry->func(func_entry->opaque); + } + } + qemu_mutex_unlock(&yank_lock); +} + +YankInstanceList *qmp_query_yank(Error **errp) +{ + YankInstanceEntry *entry; + YankInstanceList *ret; + + ret = NULL; + + qemu_mutex_lock(&yank_lock); + QLIST_FOREACH(entry, &yank_instance_list, next) { + YankInstanceList *new_entry; + new_entry = g_new0(YankInstanceList, 1); + new_entry->value = QAPI_CLONE(YankInstance, entry->instance); + new_entry->next = ret; + ret = new_entry; + } + qemu_mutex_unlock(&yank_lock); + + return ret; +} + +static void __attribute__((__constructor__)) yank_init(void) +{ + qemu_mutex_init(&yank_lock); +} From patchwork Sun Dec 13 11:48:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415556 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=mCOgayaw; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv2sv1gpCz9sTg for ; Sun, 13 Dec 2020 22:51:15 +1100 (AEDT) Received: from localhost ([::1]:52154 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koPuD-0005tD-5y for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:51:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60918) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPra-0005Yu-GH; Sun, 13 Dec 2020 06:48:33 -0500 Received: from mout.web.de ([212.227.17.12]:50835) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrW-0002L5-NH; Sun, 13 Dec 2020 06:48:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860098; bh=6fTjEKsF/GlgEXAcDDOvUej9F+vcA0URWgK8Bi5gdA8=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=mCOgayawyD3JoqUF7VDI44sf9AHx9+J5Exh+aN3JyS51Eg18mqcxn9EZJUB9hNNeJ alajsVPTkR4jf9rl1XGVrQpQ2Ak/Fh5Y9G+gHPqpVnx6bZY2JWo6wdl+eIOB7mgJJM C94rXNwlIuouNq8bd9wA5kgltcOqwqCcB4BjD6/I= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MAMli-1kzv7w2idO-00Bdvt; Sun, 13 Dec 2020 12:48:18 +0100 Date: Sun, 13 Dec 2020 12:48:17 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 2/7] block/nbd.c: Add yank feature Message-ID: <6eca6e24c702ec803a1b6df6d1a3f40abb58770a.1607858747.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:R40lD00JsTI38eX7LnWkO4bWcsM9H/OmqND7QsDIsFc9xX3xaMD x1N4FTefqQz1kqCTl0cIEp+VqBRmswxa3Iym31A5xXBgMV42NPW4DPTVOkDoQGK3u5ea617 3wAcqZMTDJXzhOC20eY2USvb4sOyMukPsyOBzeWHg9i7lSRRs3imeak2/B3tL2yYqFBtfG1 CM+DbK4rJ1CkC93Bx1s/A== X-UI-Out-Filterresults: notjunk:1;V03:K0:lLQq4VhUJqU=:oSfKdRAHTsHK93Y67aeVbZ 31x0UNS8d6oc5DN2POm3zhOboCKJVobSU1wOxLJmq76a5gn+5DjSJMFpJOzy2+vlZOZjF1UEW 4tU0JtgsHxIj9wLB27mXawZGT9v2pVqaFMnsq80zK9nQPbZU8h5pSpSpBFu8oaaBFmPJQKxfn 9cjgAt4EymuLY1JDwYdYA3dkMPrw5hEI1bkdiu+C+Z98xXk+Bw5CcmpdK8PXyM8sqKOZF81BS 4GD9LiGKroLxzE2RY28nbzl1Lky119WjmbqVPndQvFHRaqnM9kjFYp/4jxt2xZh9aqC+U3RNB gIgiDe93a4h+yD4pSNH4mnS0l7FDBBU4OnzvGgq1qPbQxYZ/ocaTEsDBqzeNbsN213WLCjhuu YekYRa5iNIjImNrLHNeDoUIDpPb7zI63W2t5yMZFVfU2x7wqBRmyuetgpxDOivlMHKzEb4i5+ AqYjc1TX9ohtLeftQwQZY8hHMfWlkPTOMGqqPLjUygBM75XMotFZIvGVuNYPzsDBoyBebcJeg FM+nBY4CFweKbczsJDIi+bhFGjNEfjaH0faNoi6Ba1XKVLuMv0ewJJVjziLWyQun+nJUffH2o uBUhiO2ASP6o+j6wteBxLakaAax+jdrlKVSEgUDrm8ljdHtZXac3ZwnwJHdN/F/AWHnWihbsv XBhAKNpBB+mbP5s3+5OgbpM5TpDiSnIHAGluAdmFmg6wbVYyRQzvb292beLL76fh4tFCcR0xI sNvlKmwU06c3wxxxvlQBD8ZvOlkjyWh5sviB+pLG7LPxo5wo8pva2/SbIhE6jWNMS521kSNFc 4fNQ4Clv4u3H16sKlSdtBJQxyux0UgyS+Vm29tiELKr5LuyO3H2sVervAFuzANaynyXilvChj 3HPTLnzTaOiSd/qgP8iQkddJY3M0tyS4dHT/dVvlk= Received-SPF: pass client-ip=212.227.17.12; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 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.01, RCVD_IN_MSPIKE_WL=-0.01, 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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Register a yank function which shuts down the socket and sets s->state = NBD_CLIENT_QUIT. This is the same behaviour as if an error occured. Signed-off-by: Lukas Straub Acked-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- block/nbd.c | 154 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 61 deletions(-) -- 2.20.1 diff --git a/block/nbd.c b/block/nbd.c index 42536702b6..994d1e7b33 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -35,6 +35,7 @@ #include "qemu/option.h" #include "qemu/cutils.h" #include "qemu/main-loop.h" +#include "qemu/atomic.h" #include "qapi/qapi-visit-sockets.h" #include "qapi/qmp/qstring.h" @@ -44,6 +45,8 @@ #include "block/nbd.h" #include "block/block_int.h" +#include "qemu/yank.h" + #define EN_OPTSTR ":exportname=" #define MAX_NBD_REQUESTS 16 @@ -141,14 +144,13 @@ typedef struct BDRVNBDState { NBDConnectThread *connect_thread; } BDRVNBDState; -static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr, - Error **errp); -static QIOChannelSocket *nbd_co_establish_connection(BlockDriverState *bs, - Error **errp); +static int nbd_establish_connection(BlockDriverState *bs, SocketAddress *saddr, + Error **errp); +static int nbd_co_establish_connection(BlockDriverState *bs, Error **errp); static void nbd_co_establish_connection_cancel(BlockDriverState *bs, bool detach); -static int nbd_client_handshake(BlockDriverState *bs, QIOChannelSocket *sioc, - Error **errp); +static int nbd_client_handshake(BlockDriverState *bs, Error **errp); +static void nbd_yank(void *opaque); static void nbd_clear_bdrvstate(BDRVNBDState *s) { @@ -166,12 +168,12 @@ static void nbd_clear_bdrvstate(BDRVNBDState *s) static void nbd_channel_error(BDRVNBDState *s, int ret) { if (ret == -EIO) { - if (s->state == NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTED) { s->state = s->reconnect_delay ? NBD_CLIENT_CONNECTING_WAIT : NBD_CLIENT_CONNECTING_NOWAIT; } } else { - if (s->state == NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTED) { qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL); } s->state = NBD_CLIENT_QUIT; @@ -204,7 +206,7 @@ static void reconnect_delay_timer_cb(void *opaque) { BDRVNBDState *s = opaque; - if (s->state == NBD_CLIENT_CONNECTING_WAIT) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT) { s->state = NBD_CLIENT_CONNECTING_NOWAIT; while (qemu_co_enter_next(&s->free_sema, NULL)) { /* Resume all queued requests */ @@ -216,7 +218,7 @@ static void reconnect_delay_timer_cb(void *opaque) static void reconnect_delay_timer_init(BDRVNBDState *s, uint64_t expire_time_ns) { - if (s->state != NBD_CLIENT_CONNECTING_WAIT) { + if (qatomic_load_acquire(&s->state) != NBD_CLIENT_CONNECTING_WAIT) { return; } @@ -261,7 +263,7 @@ static void nbd_client_attach_aio_context(BlockDriverState *bs, * s->connection_co is either yielded from nbd_receive_reply or from * nbd_co_reconnect_loop() */ - if (s->state == NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTED) { qio_channel_attach_aio_context(QIO_CHANNEL(s->ioc), new_context); } @@ -287,7 +289,7 @@ static void coroutine_fn nbd_client_co_drain_begin(BlockDriverState *bs) reconnect_delay_timer_del(s); - if (s->state == NBD_CLIENT_CONNECTING_WAIT) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT) { s->state = NBD_CLIENT_CONNECTING_NOWAIT; qemu_co_queue_restart_all(&s->free_sema); } @@ -338,13 +340,14 @@ static void nbd_teardown_connection(BlockDriverState *bs) static bool nbd_client_connecting(BDRVNBDState *s) { - return s->state == NBD_CLIENT_CONNECTING_WAIT || - s->state == NBD_CLIENT_CONNECTING_NOWAIT; + NBDClientState state = qatomic_load_acquire(&s->state); + return state == NBD_CLIENT_CONNECTING_WAIT || + state == NBD_CLIENT_CONNECTING_NOWAIT; } static bool nbd_client_connecting_wait(BDRVNBDState *s) { - return s->state == NBD_CLIENT_CONNECTING_WAIT; + return qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT; } static void connect_bh(void *opaque) @@ -424,12 +427,12 @@ static void *connect_thread_func(void *opaque) return NULL; } -static QIOChannelSocket *coroutine_fn +static int coroutine_fn nbd_co_establish_connection(BlockDriverState *bs, Error **errp) { + int ret; QemuThread thread; BDRVNBDState *s = bs->opaque; - QIOChannelSocket *res; NBDConnectThread *thr = s->connect_thread; qemu_mutex_lock(&thr->mutex); @@ -446,10 +449,12 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) case CONNECT_THREAD_SUCCESS: /* Previous attempt finally succeeded in background */ thr->state = CONNECT_THREAD_NONE; - res = thr->sioc; + s->sioc = thr->sioc; thr->sioc = NULL; + yank_register_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), + nbd_yank, bs); qemu_mutex_unlock(&thr->mutex); - return res; + return 0; case CONNECT_THREAD_RUNNING: /* Already running, will wait */ break; @@ -481,8 +486,13 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) thr->state = CONNECT_THREAD_NONE; error_propagate(errp, thr->err); thr->err = NULL; - res = thr->sioc; + s->sioc = thr->sioc; thr->sioc = NULL; + if (s->sioc) { + yank_register_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), + nbd_yank, bs); + } + ret = (s->sioc ? 0 : -1); break; case CONNECT_THREAD_RUNNING: case CONNECT_THREAD_RUNNING_DETACHED: @@ -491,7 +501,7 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) * failed. Still connect thread is executing in background, and its * result may be used for next connection attempt. */ - res = NULL; + ret = -1; error_setg(errp, "Connection attempt cancelled by other operation"); break; @@ -508,7 +518,7 @@ nbd_co_establish_connection(BlockDriverState *bs, Error **errp) qemu_mutex_unlock(&thr->mutex); - return res; + return ret; } /* @@ -561,7 +571,6 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) { int ret; Error *local_err = NULL; - QIOChannelSocket *sioc; if (!nbd_client_connecting(s)) { return; @@ -594,21 +603,22 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) /* Finalize previous connection if any */ if (s->ioc) { qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc)); + yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), + nbd_yank, s->bs); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); s->ioc = NULL; } - sioc = nbd_co_establish_connection(s->bs, &local_err); - if (!sioc) { + if (nbd_co_establish_connection(s->bs, &local_err) < 0) { ret = -ECONNREFUSED; goto out; } bdrv_dec_in_flight(s->bs); - ret = nbd_client_handshake(s->bs, sioc, &local_err); + ret = nbd_client_handshake(s->bs, &local_err); if (s->drained) { s->wait_drained_end = true; @@ -640,7 +650,7 @@ static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s) uint64_t timeout = 1 * NANOSECONDS_PER_SECOND; uint64_t max_timeout = 16 * NANOSECONDS_PER_SECOND; - if (s->state == NBD_CLIENT_CONNECTING_WAIT) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTING_WAIT) { reconnect_delay_timer_init(s, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + s->reconnect_delay * NANOSECONDS_PER_SECOND); } @@ -683,7 +693,7 @@ static coroutine_fn void nbd_connection_entry(void *opaque) int ret = 0; Error *local_err = NULL; - while (s->state != NBD_CLIENT_QUIT) { + while (qatomic_load_acquire(&s->state) != NBD_CLIENT_QUIT) { /* * The NBD client can only really be considered idle when it has * yielded from qio_channel_readv_all_eof(), waiting for data. This is @@ -698,7 +708,7 @@ static coroutine_fn void nbd_connection_entry(void *opaque) nbd_co_reconnect_loop(s); } - if (s->state != NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) != NBD_CLIENT_CONNECTED) { continue; } @@ -753,6 +763,8 @@ static coroutine_fn void nbd_connection_entry(void *opaque) s->connection_co = NULL; if (s->ioc) { qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc)); + yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), + nbd_yank, s->bs); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); @@ -777,7 +789,7 @@ static int nbd_co_send_request(BlockDriverState *bs, qemu_co_queue_wait(&s->free_sema, &s->send_mutex); } - if (s->state != NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) != NBD_CLIENT_CONNECTED) { rc = -EIO; goto err; } @@ -804,7 +816,8 @@ static int nbd_co_send_request(BlockDriverState *bs, if (qiov) { qio_channel_set_cork(s->ioc, true); rc = nbd_send_request(s->ioc, request); - if (rc >= 0 && s->state == NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) == NBD_CLIENT_CONNECTED && + rc >= 0) { if (qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { rc = -EIO; @@ -1129,7 +1142,7 @@ static coroutine_fn int nbd_co_do_receive_one_chunk( s->requests[i].receiving = true; qemu_coroutine_yield(); s->requests[i].receiving = false; - if (s->state != NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) != NBD_CLIENT_CONNECTED) { error_setg(errp, "Connection closed"); return -EIO; } @@ -1288,7 +1301,7 @@ static bool nbd_reply_chunk_iter_receive(BDRVNBDState *s, NBDReply local_reply; NBDStructuredReplyChunk *chunk; Error *local_err = NULL; - if (s->state != NBD_CLIENT_CONNECTED) { + if (qatomic_load_acquire(&s->state) != NBD_CLIENT_CONNECTED) { error_setg(&local_err, "Connection closed"); nbd_iter_channel_error(iter, -EIO, &local_err); goto break_loop; @@ -1313,7 +1326,8 @@ static bool nbd_reply_chunk_iter_receive(BDRVNBDState *s, } /* Do not execute the body of NBD_FOREACH_REPLY_CHUNK for simple reply. */ - if (nbd_reply_is_simple(reply) || s->state != NBD_CLIENT_CONNECTED) { + if (nbd_reply_is_simple(reply) || + qatomic_load_acquire(&s->state) != NBD_CLIENT_CONNECTED) { goto break_loop; } @@ -1745,6 +1759,15 @@ static int nbd_client_reopen_prepare(BDRVReopenState *state, return 0; } +static void nbd_yank(void *opaque) +{ + BlockDriverState *bs = opaque; + BDRVNBDState *s = (BDRVNBDState *)bs->opaque; + + qatomic_store_release(&s->state, NBD_CLIENT_QUIT); + qio_channel_shutdown(QIO_CHANNEL(s->sioc), QIO_CHANNEL_SHUTDOWN_BOTH, NULL); +} + static void nbd_client_close(BlockDriverState *bs) { BDRVNBDState *s = (BDRVNBDState *)bs->opaque; @@ -1757,52 +1780,53 @@ static void nbd_client_close(BlockDriverState *bs) nbd_teardown_connection(bs); } -static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr, - Error **errp) +static int nbd_establish_connection(BlockDriverState *bs, + SocketAddress *saddr, + Error **errp) { ERRP_GUARD(); - QIOChannelSocket *sioc; + BDRVNBDState *s = (BDRVNBDState *)bs->opaque; - sioc = qio_channel_socket_new(); - qio_channel_set_name(QIO_CHANNEL(sioc), "nbd-client"); + s->sioc = qio_channel_socket_new(); + qio_channel_set_name(QIO_CHANNEL(s->sioc), "nbd-client"); - qio_channel_socket_connect_sync(sioc, saddr, errp); + qio_channel_socket_connect_sync(s->sioc, saddr, errp); if (*errp) { - object_unref(OBJECT(sioc)); - return NULL; + object_unref(OBJECT(s->sioc)); + s->sioc = NULL; + return -1; } - qio_channel_set_delay(QIO_CHANNEL(sioc), false); + yank_register_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), nbd_yank, bs); + qio_channel_set_delay(QIO_CHANNEL(s->sioc), false); - return sioc; + return 0; } -/* nbd_client_handshake takes ownership on sioc. On failure it is unref'ed. */ -static int nbd_client_handshake(BlockDriverState *bs, QIOChannelSocket *sioc, - Error **errp) +/* nbd_client_handshake takes ownership on s->sioc. On failure it's unref'ed. */ +static int nbd_client_handshake(BlockDriverState *bs, Error **errp) { BDRVNBDState *s = (BDRVNBDState *)bs->opaque; AioContext *aio_context = bdrv_get_aio_context(bs); int ret; trace_nbd_client_handshake(s->export); - - s->sioc = sioc; - - qio_channel_set_blocking(QIO_CHANNEL(sioc), false, NULL); - qio_channel_attach_aio_context(QIO_CHANNEL(sioc), aio_context); + qio_channel_set_blocking(QIO_CHANNEL(s->sioc), false, NULL); + qio_channel_attach_aio_context(QIO_CHANNEL(s->sioc), aio_context); s->info.request_sizes = true; s->info.structured_reply = true; s->info.base_allocation = true; s->info.x_dirty_bitmap = g_strdup(s->x_dirty_bitmap); s->info.name = g_strdup(s->export ?: ""); - ret = nbd_receive_negotiate(aio_context, QIO_CHANNEL(sioc), s->tlscreds, + ret = nbd_receive_negotiate(aio_context, QIO_CHANNEL(s->sioc), s->tlscreds, s->hostname, &s->ioc, &s->info, errp); g_free(s->info.x_dirty_bitmap); g_free(s->info.name); if (ret < 0) { - object_unref(OBJECT(sioc)); + yank_unregister_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), + nbd_yank, bs); + object_unref(OBJECT(s->sioc)); s->sioc = NULL; return ret; } @@ -1835,7 +1859,7 @@ static int nbd_client_handshake(BlockDriverState *bs, QIOChannelSocket *sioc, } if (!s->ioc) { - s->ioc = QIO_CHANNEL(sioc); + s->ioc = QIO_CHANNEL(s->sioc); object_ref(OBJECT(s->ioc)); } @@ -1851,9 +1875,11 @@ static int nbd_client_handshake(BlockDriverState *bs, QIOChannelSocket *sioc, { NBDRequest request = { .type = NBD_CMD_DISC }; - nbd_send_request(s->ioc ?: QIO_CHANNEL(sioc), &request); + nbd_send_request(s->ioc ?: QIO_CHANNEL(s->sioc), &request); - object_unref(OBJECT(sioc)); + yank_unregister_function(BLOCKDEV_YANK_INSTANCE(bs->node_name), + nbd_yank, bs); + object_unref(OBJECT(s->sioc)); s->sioc = NULL; return ret; @@ -2245,7 +2271,6 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, { int ret; BDRVNBDState *s = (BDRVNBDState *)bs->opaque; - QIOChannelSocket *sioc; ret = nbd_process_options(bs, options, errp); if (ret < 0) { @@ -2256,17 +2281,23 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, qemu_co_mutex_init(&s->send_mutex); qemu_co_queue_init(&s->free_sema); + yank_register_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name), errp); + if (*errp) { + return -EEXIST; + } + /* * establish TCP connection, return error if it fails * TODO: Configurable retry-until-timeout behaviour. */ - sioc = nbd_establish_connection(s->saddr, errp); - if (!sioc) { + if (nbd_establish_connection(bs, s->saddr, errp) < 0) { + yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name)); return -ECONNREFUSED; } - ret = nbd_client_handshake(bs, sioc, errp); + ret = nbd_client_handshake(bs, errp); if (ret < 0) { + yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name)); nbd_clear_bdrvstate(s); return ret; } @@ -2326,6 +2357,7 @@ static void nbd_close(BlockDriverState *bs) BDRVNBDState *s = bs->opaque; nbd_client_close(bs); + yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name)); nbd_clear_bdrvstate(s); } From patchwork Sun Dec 13 11:48:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=i45z+I2Q; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv2xk5wyVz9sTK for ; Sun, 13 Dec 2020 22:54:34 +1100 (AEDT) Received: from localhost ([::1]:60908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koPxQ-0001KH-LS for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:54:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60928) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrc-0005Yy-Fh; Sun, 13 Dec 2020 06:48:34 -0500 Received: from mout.web.de ([217.72.192.78]:37807) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrY-0002LP-Pe; Sun, 13 Dec 2020 06:48:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860102; bh=6DbTaw2VwDiRnD4UDckkIgL0bd5JpZKh2v4ftCcY5Yc=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=i45z+I2QWBy9oWzABVCDoqax0S5qUApWhP/8PW3u3eiA1jGxyFDUzl4OZXocLQ5GG UXeISN4NJSgepi+K+ZGvER5wwjxIS0iLbWES3Ok4b+T/Y+TUqRyCLtxoov+YRT63CY NVKU3ug8siVawN5IrnB89DYtfVDS0gjLzFSWUiHU= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb106 [213.165.67.124]) with ESMTPSA (Nemesis) id 1McZjb-1kFtKF2xe1-00cwzh; Sun, 13 Dec 2020 12:48:22 +0100 Date: Sun, 13 Dec 2020 12:48:20 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 3/7] chardev/char-socket.c: Add yank feature Message-ID: <59d7fbce1687606de93cc69b7755ac80ae6b2eaa.1607858747.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:i+89IbMWfHLeMgXxLRdMfPielK4eugir5vwoir3zh0Fn/gcrJ/L H/6tapW6WZomlQcBbRiypzOoJubuTfGH1Lm+1bbz2zKTj/xva/lHYlo8hg9sJf95ATKh9NS x856YLtg7YnSic/6zl59zyt1Fv6PgPoVXOMamgRV1PntQlyTfakXuviFj/CnXCBpNW3dWhE Z7EitcWg9BZMaMBoAl9gw== X-UI-Out-Filterresults: notjunk:1;V03:K0:0zH/XOmHgpc=:Dhr9XqPDaZokElNgcF+l7J 0aFLLs2KT03f3hy7DYa+OpiyqNf4/RdjafsSmeybNXcbf5JV+ytoS+upeP2Oi6CFEVCwbByhb iR9dLWfYcB+q1Gx504XVGF14R+kRKMJ6d/qwgETThEAf6b+2stddApTxRN5FWYwK5HdrWm9BX e2Kt0d41Pan2AIFhONq5F2J5+3Qba76k7gGzR5rS2ppIHt5EDo06YZzuEf+0yNlDCD55yiqAQ lZRfiovyMINxJ6afC7xhODUQfm6cxWHmfZ31vQW56pP7bXNZyS3qEUT/4nWu069+iVnAYY1wQ nj9X3c5gsZ5/AMdwyb2tQ/e0yPS6aGYDVCmgTOATWFkoYNZQmRfwMmm9fgObYaOPdBWbtJEyb mLfKv/DddMueWrCSy++6qXDpw9mvSxTPhodb3pOaxTD2Hj6ACQEZHygKw2pNy3KFNCxTL3sr3 vgf8HHsXUlIPRPNqexJWAG7yjk+gyF2b+S7mQ3dSpGwDLDC5jsjBbEDBMBMN0czFwdWdClezX umrZbamQYrgn27mU5NxkCIG4+gvh7Ow+KizIHVIMEsGkQAz/Opi9b572UQV9cGwdtFlpiRAPj Y1/Tc0MH60Mr0mxtLUIZEzVkVhH4GSzPrGntGv2RIpx6IK/h1rJOpCv4lUwMkHZiHnYM8k7LO wDcy0soKnAzQBQSuMDHAfgx8cLvmhFfrLF4QL4kxfBsrbaq+QL5zg6I3Rn11hqbAxY4aYRjuM cLmEF49L0Ib+oY98LcAWf3j0SwMY+mA5/i6lEhGjD0mA29Ki1j+uv/VQBQHqpX5Ml0yNIO3Yx 9QtCPqcr4GPYDXajqeOzEImfthu/FsOeC4cbdeW+46ZvWySKhSIRlWE8OZEzuCC43wDN+WvNt uXzBUFq28DMmewv6Vh/bNacb51NEFAact4aUSP2vw= 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_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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Register a yank function to shutdown the socket on yank. Signed-off-by: Lukas Straub Acked-by: Stefan Hajnoczi --- chardev/char-socket.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) -- 2.20.1 diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 213a4c8dd0..7f2ee9a338 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -34,6 +34,7 @@ #include "qapi/error.h" #include "qapi/clone-visitor.h" #include "qapi/qapi-visit-sockets.h" +#include "qemu/yank.h" #include "chardev/char-io.h" #include "qom/object.h" @@ -70,6 +71,7 @@ struct SocketChardev { size_t read_msgfds_num; int *write_msgfds; size_t write_msgfds_num; + bool registered_yank; SocketAddress *addr; bool is_listen; @@ -415,6 +417,12 @@ static void tcp_chr_free_connection(Chardev *chr) tcp_set_msgfds(chr, NULL, 0); remove_fd_in_watch(chr); + if (s->state == TCP_CHARDEV_STATE_CONNECTING + || s->state == TCP_CHARDEV_STATE_CONNECTED) { + yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(s->sioc)); + } object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); @@ -932,6 +940,9 @@ static int tcp_chr_add_client(Chardev *chr, int fd) } tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_set_client_ioc_name(chr, sioc); + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(sioc)); ret = tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); return ret; @@ -946,6 +957,9 @@ static void tcp_chr_accept(QIONetListener *listener, tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_set_client_ioc_name(chr, cioc); + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(cioc)); tcp_chr_new_client(chr, cioc); } @@ -961,6 +975,9 @@ static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp) object_unref(OBJECT(sioc)); return -1; } + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(sioc)); tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); return 0; @@ -976,6 +993,9 @@ static void tcp_chr_accept_server_sync(Chardev *chr) tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); sioc = qio_net_listener_wait_client(s->listener); tcp_chr_set_client_ioc_name(chr, sioc); + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(sioc)); tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); } @@ -1086,6 +1106,9 @@ static void char_socket_finalize(Object *obj) object_unref(OBJECT(s->tls_creds)); } g_free(s->tls_authz); + if (s->registered_yank) { + yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label)); + } qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -1101,6 +1124,9 @@ static void qemu_chr_socket_connected(QIOTask *task, void *opaque) if (qio_task_propagate_error(task, &err)) { tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); + yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(sioc)); check_report_connect_error(chr, err); goto cleanup; } @@ -1134,6 +1160,9 @@ static void tcp_chr_connect_client_async(Chardev *chr) tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); sioc = qio_channel_socket_new(); tcp_chr_set_client_ioc_name(chr, sioc); + yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), + yank_generic_iochannel, + QIO_CHANNEL(sioc)); /* * Normally code would use the qio_channel_socket_connect_async * method which uses a QIOTask + qio_task_set_error internally @@ -1376,6 +1405,12 @@ static void qmp_chardev_open_socket(Chardev *chr, qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); } + yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp); + if (*errp) { + return; + } + s->registered_yank = true; + /* be isn't opened until we get a connection */ *be_opened = false; From patchwork Sun Dec 13 11:48:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415557 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=kQHeIBE3; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv2xd3Sk8z9sTK for ; Sun, 13 Dec 2020 22:54:29 +1100 (AEDT) Received: from localhost ([::1]:60198 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koPxL-00012k-EG for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:54:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60940) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrg-0005ZU-D1; Sun, 13 Dec 2020 06:48:36 -0500 Received: from mout.web.de ([212.227.17.11]:48159) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrd-0002MV-IJ; Sun, 13 Dec 2020 06:48:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860107; bh=MUK9OSiVvwFZVAxMHQYh1PT0NGvcFURN3LjkDO6tetI=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=kQHeIBE3ZEapv+I7FHNv4EjXSKJ4aTwFpLJZzVh0+hlH85JLenF6pvkOYhDrY9qWg 1JQPpp35yyGm3DTPpagKLjfmp8uOXhO81HHIMoAbZ8c/iW+FVMCNbARM90YOyFGu+f fcpXqUit6rSJXW8jvPN7fgPJ0DKA5qqYCNZY6IaE= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0LnS4I-1kCIYm3lSo-00hhLx; Sun, 13 Dec 2020 12:48:26 +0100 Date: Sun, 13 Dec 2020 12:48:25 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 4/7] migration: Add yank feature Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:ThafvwEs8vkLjCpp+tKT4DX/DG9QdpCak1FvleAN1Ck++01h54c zFaV13kKOFiHDkxOpgTABfTpRTHNm4yO8qq53gS/4bQOwbmBKtSv0KVWwSfGFHqgB/Fa4+1 eEx3IxVqZJfp67Vdwa3OHd4FLh4gYC5VvSzlXb1EdjPViOjIwLUW2KbYyMtZPxRUkdR8PYx eRiUOo/hP6funGk2eDqMw== X-UI-Out-Filterresults: notjunk:1;V03:K0:1b9ln7HbW08=:wKtZCX096CKnKTlD3JJGza ZqK4PEvVpGE1cp6Tyw2+YA5/o1/zHvVpVy16DCiOsz1GdivRRs8X4JOXd9Jr/oA0UqVAcX/Mo z4ft1tYT6c6T2zzBkp4JPhBQkBnVJoRCwvBz/vXJFvdZB7RUsTbaT42qFCCxiiJxWsk0uFit7 R3T5zCztRXLWiuYKPbc9ZByywJV59rMOnp9JApURW31QwS6Pu6+0QqjGIYe8t2VLFuVObmzDk 5EMic9CkEUEMcKO07BP2KY/76J+iU2lbbKQd9+3BSOwDnsB1kD1QsG8vYKX1VzEWRgjR29UmO RzTeTtIy9FetKDzWe7ZnCIIBFWrtIwFMMUz3LPP4bAyPl710xGZ4cRgkLH3vPc6v1uQV1/oH9 R6yCVISZBMUAxoQvo/EXHETgq2eDX6cP5dfdkTkGnArAtFttXqJTa1Ze4e/l3T2JnlEcVe4CT 4rQuVjWfhyMHr4e0odvkzqTDqGA71FJmC3kN/hye4pca2HPd3UF/h5bSi9AJ6ipwFuTeB7CWw sJF6M8NN2RJfS78bwSiSceOkquk9hb+AMRA/tAmA+hp9XARIAFOeq3vn1qdCv6yTF/ZjvB82+ sQA7qYMU971EaokvuOxYLepBC6t5/gP+4gJG9xawj0PlRZwaD757CLydB3mX24VVGJynNkf1I +iNdOK5wVG8IcyvesWVtgHlB3Kq2rVUFkBTRNmqOC+Lu0U7T+4lJgyMSNmqyJAmclqgPAY+SM 80U/F2QOXapH3ox3FG/EC92vYrDd6DwPNo8JXl7ZNFWAof8dBEG+Li9JcJvaLPZTIq6P52k64 eCzf7o06tT80emmT/YoiBEvfYVcgBFz7K6HCu125UpWPcnOtJ0YmQJZGzaAEqgQjDUGZtTO0g H/j9LELsgUGlgvjImSr+GnCyBvmfBvkqUBwCwGuic= Received-SPF: pass client-ip=212.227.17.11; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 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.01, RCVD_IN_MSPIKE_WL=-0.01, 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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Register yank functions on sockets to shut them down. Signed-off-by: Lukas Straub Acked-by: Stefan Hajnoczi Acked-by: Dr. David Alan Gilbert --- migration/channel.c | 13 +++++++++++++ migration/migration.c | 24 ++++++++++++++++++++++++ migration/multifd.c | 10 ++++++++++ migration/qemu-file-channel.c | 7 +++++++ migration/savevm.c | 6 ++++++ 5 files changed, 60 insertions(+) -- 2.20.1 diff --git a/migration/channel.c b/migration/channel.c index 8a783baa0b..35fe234e9c 100644 --- a/migration/channel.c +++ b/migration/channel.c @@ -18,6 +18,8 @@ #include "trace.h" #include "qapi/error.h" #include "io/channel-tls.h" +#include "io/channel-socket.h" +#include "qemu/yank.h" /** * @migration_channel_process_incoming - Create new incoming migration channel @@ -35,6 +37,11 @@ void migration_channel_process_incoming(QIOChannel *ioc) trace_migration_set_incoming_channel( ioc, object_get_typename(OBJECT(ioc))); + if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET)) { + yank_register_function(MIGRATION_YANK_INSTANCE, yank_generic_iochannel, + QIO_CHANNEL(ioc)); + } + if (s->parameters.tls_creds && *s->parameters.tls_creds && !object_dynamic_cast(OBJECT(ioc), @@ -67,6 +74,12 @@ void migration_channel_connect(MigrationState *s, ioc, object_get_typename(OBJECT(ioc)), hostname, error); if (!error) { + if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET)) { + yank_register_function(MIGRATION_YANK_INSTANCE, + yank_generic_iochannel, + QIO_CHANNEL(ioc)); + } + if (s->parameters.tls_creds && *s->parameters.tls_creds && !object_dynamic_cast(OBJECT(ioc), diff --git a/migration/migration.c b/migration/migration.c index e0dbde4091..dc520a721b 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -56,6 +56,7 @@ #include "net/announce.h" #include "qemu/queue.h" #include "multifd.h" +#include "qemu/yank.h" #ifdef CONFIG_VFIO #include "hw/vfio/vfio-common.h" @@ -254,6 +255,8 @@ void migration_incoming_state_destroy(void) qapi_free_SocketAddressList(mis->socket_address_list); mis->socket_address_list = NULL; } + + yank_unregister_instance(MIGRATION_YANK_INSTANCE); } static void migrate_generate_event(int new_state) @@ -418,6 +421,11 @@ static void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p = NULL; + yank_register_instance(MIGRATION_YANK_INSTANCE, errp); + if (*errp) { + return; + } + qapi_event_send_migration(MIGRATION_STATUS_SETUP); if (strstart(uri, "tcp:", &p) || strstart(uri, "unix:", NULL) || @@ -432,6 +440,7 @@ static void qemu_start_incoming_migration(const char *uri, Error **errp) } else if (strstart(uri, "fd:", &p)) { fd_start_incoming_migration(p, errp); } else { + yank_unregister_instance(MIGRATION_YANK_INSTANCE); error_setg(errp, "unknown migration protocol: %s", uri); } } @@ -1737,6 +1746,7 @@ static void migrate_fd_cleanup(MigrationState *s) } notifier_list_notify(&migration_state_notifiers, s); block_cleanup_parameters(s); + yank_unregister_instance(MIGRATION_YANK_INSTANCE); } static void migrate_fd_cleanup_schedule(MigrationState *s) @@ -2011,6 +2021,7 @@ void qmp_migrate_recover(const char *uri, Error **errp) * only re-setup the migration stream and poke existing migration * to continue using that newly established channel. */ + yank_unregister_instance(MIGRATION_YANK_INSTANCE); qemu_start_incoming_migration(uri, errp); } @@ -2148,6 +2159,13 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, return; } + if (!(has_resume && resume)) { + yank_register_instance(MIGRATION_YANK_INSTANCE, errp); + if (*errp) { + return; + } + } + if (strstart(uri, "tcp:", &p) || strstart(uri, "unix:", NULL) || strstart(uri, "vsock:", NULL)) { @@ -2161,6 +2179,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } else if (strstart(uri, "fd:", &p)) { fd_start_outgoing_migration(s, p, &local_err); } else { + if (!(has_resume && resume)) { + yank_unregister_instance(MIGRATION_YANK_INSTANCE); + } error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, @@ -2170,6 +2191,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } if (local_err) { + if (!(has_resume && resume)) { + yank_unregister_instance(MIGRATION_YANK_INSTANCE); + } migrate_fd_error(s, local_err); error_propagate(errp, local_err); return; diff --git a/migration/multifd.c b/migration/multifd.c index 45c690aa11..1a1e589064 100644 --- a/migration/multifd.c +++ b/migration/multifd.c @@ -25,6 +25,9 @@ #include "trace.h" #include "multifd.h" +#include "qemu/yank.h" +#include "io/channel-socket.h" + /* Multiple fd's */ #define MULTIFD_MAGIC 0x11223344U @@ -974,6 +977,13 @@ int multifd_load_cleanup(Error **errp) for (i = 0; i < migrate_multifd_channels(); i++) { MultiFDRecvParams *p = &multifd_recv_state->params[i]; + if (object_dynamic_cast(OBJECT(p->c), TYPE_QIO_CHANNEL_SOCKET) + && OBJECT(p->c)->ref == 1) { + yank_unregister_function(MIGRATION_YANK_INSTANCE, + yank_generic_iochannel, + QIO_CHANNEL(p->c)); + } + object_unref(OBJECT(p->c)); p->c = NULL; qemu_mutex_destroy(&p->mutex); diff --git a/migration/qemu-file-channel.c b/migration/qemu-file-channel.c index d2ce32f4b9..afc3a7f642 100644 --- a/migration/qemu-file-channel.c +++ b/migration/qemu-file-channel.c @@ -27,6 +27,7 @@ #include "qemu-file.h" #include "io/channel-socket.h" #include "qemu/iov.h" +#include "qemu/yank.h" static ssize_t channel_writev_buffer(void *opaque, @@ -104,6 +105,12 @@ static int channel_close(void *opaque, Error **errp) int ret; QIOChannel *ioc = QIO_CHANNEL(opaque); ret = qio_channel_close(ioc, errp); + if (object_dynamic_cast(OBJECT(ioc), TYPE_QIO_CHANNEL_SOCKET) + && OBJECT(ioc)->ref == 1) { + yank_unregister_function(MIGRATION_YANK_INSTANCE, + yank_generic_iochannel, + QIO_CHANNEL(ioc)); + } object_unref(OBJECT(ioc)); return ret; } diff --git a/migration/savevm.c b/migration/savevm.c index 5f937a2762..1a3808998e 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -62,6 +62,7 @@ #include "migration/colo.h" #include "qemu/bitmap.h" #include "net/announce.h" +#include "qemu/yank.h" const unsigned int postcopy_ram_discard_version; @@ -3008,6 +3009,11 @@ int load_snapshot(const char *name, Error **errp) qemu_system_reset(SHUTDOWN_CAUSE_NONE); mis->from_src_file = f; + yank_register_instance(MIGRATION_YANK_INSTANCE, errp); + if (*errp) { + ret = -EINVAL; + goto err_drain; + } aio_context_acquire(aio_context); ret = qemu_loadvm_state(f); migration_incoming_state_destroy(); From patchwork Sun Dec 13 11:48:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415561 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=T2XsFsmm; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv31v0Jklz9sTg for ; Sun, 13 Dec 2020 22:58:11 +1100 (AEDT) Received: from localhost ([::1]:39682 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koQ0v-0004KY-1e for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:58:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60952) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPri-0005a7-OO; Sun, 13 Dec 2020 06:48:39 -0500 Received: from mout.web.de ([212.227.17.12]:55105) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrg-0002NQ-ET; Sun, 13 Dec 2020 06:48:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860110; bh=4mPUeJ20EJC5qcXWtIBJGf6xePp4csQ6wgD+OF0lKyA=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=T2XsFsmmTndSGqSv5fRqfrD4Aed72sbdRd7xpqmnyUpg0KB5q6xeCG8C0kLv/QLuW wtsm6HrsyNwzB5D7ppZ4YbDPyUHQypy1R2dOBrrLial9kQ48lK08oTliIcw8d+FCrX Bo/L7fuEErhjGLsMzq0Vef8MYfAb65ESst4iUxHg= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MGAG3-1krvqb2tUd-00FCTX; Sun, 13 Dec 2020 12:48:30 +0100 Date: Sun, 13 Dec 2020 12:48:29 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 5/7] io/channel-tls.c: make qio_channel_tls_shutdown thread-safe Message-ID: <702fb93323fd7b3d6f0e1b6915e7df5f1dd01102.1607858747.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:jCImSP1Jt8BdDsl3tZ3PcwbgolyYjw706hyC6KMI8mcmxNP9PzA 2H/krdmGvA79SIw+WX3Wh5c/KQJQrkZtjxNr13XE8105PFeIFaVXaT5aNHRb14EZLhkzUfU cRZZZhrTFpWPd/qtySeK1wpYp0nKL7J+GeOurUlusHgLkIxhU+RwyRrwd1Me3Nhnskf3fkq 1WCyNAka9bOJx9i+1Nn0g== X-UI-Out-Filterresults: notjunk:1;V03:K0:BJR1J63wSzA=:Lb4Smuw70QIpM9IEoGPbUG ZAB2tTsLBwUFcXRvDqyDPx3wdRuqxPu8dWmtrDCQtqKuFJagTgbhk6cKXxbweVBocqhvTDGzD C3sXLhA7KtoPagegMGPxonNeookB19uxuAT5V8nB+2N/pVpkYqQVKR2FNQ8W7LhBD9qsHdJjE HEJP45DFsS/maMKEq+4DXgtr5o4pyiHriKugXAfhUAmBW8IvIXzVzv0rDoNocAETECFymSO8w gk/5JyWIUFvFA1ufKW7D/+Fr1NEAmabrQSGT7PQG31Z02Xxv8szF/B/cNXGQY78BFoQrQwS4m j54+d9sDRMV8WUTZzkGJVzzC4TJlULSh4Xqg3GnydsFJhJgV97cNiS1PytXpnoF+yBir5Yqva 0daie2LIZTtnot2SG9x12j9kuGbTTLDe55D9+M2KUd5wLimJMV8yGde74tL2SWgikSQN2i/5g WDtmD597enuY+HGb556M4PWeN4sPBgBVr3i0jSCx6ERb7PCJx+kNZFiwHwaqdNJDEsk8dR11l F6RoGmzYVSMFSBKR7ALpT0i2tNgdTeS5krRKMmsDmb46tDL2AsQqBIT7nx5Yz+EYLjQm5olf4 CFYYEOOmBencC5T3n9Mk3l6O84dGyGz3HCVCkDMKbzOxqNDe3WzPm+VZBvprQnxtKirYVuz4P M3y9S33u6iPgqitU6w/axuf++VJsmapymh2biqOldwY/of16u9OaMsT1B3bKJgVMGvUSDpQRo iP8DLWVbwGRv499tfuOkyDr9GnUaTEa2qr8Q4NnQVuKfsAPSWEUpDrVXS4S19kPufb+33hLgR B8Y5rVHOf9AD46iyll3PABnz784RgSP3D3I9V8tL6zakTIbu2RsFXd2PDVABI/AkQ5gu7gbko BxXGpElaGgkz0KEmdkuiMDtfhP5arkHLtGZ/jaa1w= Received-SPF: pass client-ip=212.227.17.12; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 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.01, RCVD_IN_MSPIKE_WL=-0.01, 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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Make qio_channel_tls_shutdown thread-safe by using atomics when accessing tioc->shutdown. Signed-off-by: Lukas Straub Acked-by: Stefan Hajnoczi Reviewed-by: Daniel P. Berrangé --- io/channel-tls.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) -- 2.20.1 diff --git a/io/channel-tls.c b/io/channel-tls.c index 388f019977..2ae1b92fc0 100644 --- a/io/channel-tls.c +++ b/io/channel-tls.c @@ -23,6 +23,7 @@ #include "qemu/module.h" #include "io/channel-tls.h" #include "trace.h" +#include "qemu/atomic.h" static ssize_t qio_channel_tls_write_handler(const char *buf, @@ -277,7 +278,8 @@ static ssize_t qio_channel_tls_readv(QIOChannel *ioc, return QIO_CHANNEL_ERR_BLOCK; } } else if (errno == ECONNABORTED && - (tioc->shutdown & QIO_CHANNEL_SHUTDOWN_READ)) { + (qatomic_load_acquire(&tioc->shutdown) & + QIO_CHANNEL_SHUTDOWN_READ)) { return 0; } @@ -361,7 +363,7 @@ static int qio_channel_tls_shutdown(QIOChannel *ioc, { QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); - tioc->shutdown |= how; + qatomic_or(&tioc->shutdown, how); return qio_channel_shutdown(tioc->master, how, errp); } From patchwork Sun Dec 13 11:48:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415558 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=Ttq+gmpG; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv2xh53kvz9sTK for ; Sun, 13 Dec 2020 22:54:32 +1100 (AEDT) Received: from localhost ([::1]:60564 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koPxO-0001Bz-8K for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:54:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60970) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrq-0005d3-Ug; Sun, 13 Dec 2020 06:48:47 -0500 Received: from mout.web.de ([212.227.17.12]:33115) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPro-0002Py-8i; Sun, 13 Dec 2020 06:48:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860118; bh=ow6CqJwt6pzmZ/mOKyfaSBI+t9Ysq8dUW+Iznaaw7vY=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=Ttq+gmpGf2IJWZPeOdw79VBqgw+3my3uaj//ZYrG/ZSj3G6CFXhck4m0nfZD3b2VZ bcgpI/50ANYZMUIj95GdD5VMrrVahstJJhyggBkKgoxjbOgb1gkar6MkC+N8RLAu1j tI5V5OkeQ/cgTP39ZYmjAtQFIraefN+L6n+fxRRM= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb105 [213.165.67.124]) with ESMTPSA (Nemesis) id 1MREzO-1kREAs2gNg-00NFxW; Sun, 13 Dec 2020 12:48:38 +0100 Date: Sun, 13 Dec 2020 12:48:37 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 6/7] io: Document qmp oob suitability of qio_channel_shutdown and io_shutdown Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:XBCsRBmv/QvQPbtQ5FH+99xa+rJUpH24txh2B0s1pvjW8cN3o3F iSZ7Iw6IhGeIO/iDshNpIRCOBOPvPJmLjAl79BA4XIIqWTAPmWiWqVeeQ2xn+UG5wd5OTxq sDUf0/KDe0ZNdRRe/jRAYRlUC3F6N+QbF/pcG0O2xCtsPOmbj+hvQDVaC9WTc6Y8pi/PmHm u+xUD9Lbf5KvrFCVwYtLg== X-UI-Out-Filterresults: notjunk:1;V03:K0:z+D/+oNA0Ts=:jaL9UcM3bQZHhbgrbDJ6P9 h7cq8azMt5qmOCdDgqWu3LiGJFIVDFeU3oVP84LMKfqG+ADwQSxQjhG+RJeHQVMrMvDsEf0Dw oWlSW9j3MjaP8OZG9t6d8Dp5focSflKWwQ+4CiEWEzl3qE3f2kV6SpAkQPKuH4YnqtsdtcDVd qj66+iTPYKKJr2zXNrhh1RnqRszWns2n9XTSewJ+9WK0QW24j7wCVP7CnmUh36B4pFgkMQ7rg mf3dEG9CI4yNGykjoEitxJEeHU2Rg5+KQKaNICfHcY8FsEAeN/bK6clo7X0Aaeu6xWi+LlRQ6 4FrX/rB/biPxyemf1GfBiz+ITSzj3HlhkvjswtsPY3AI9QsIgdzP8aKIlZYofzUXkWoyylVIP daBv1Z764ArMD4GEOjHpGWMACkh7U8v6SCfG+QOyg7fg2uD2pwQbIoei2VX0QQDLCRCNB9WR6 3YvPm/GVn6vqDIBMPk5SoGVKlJ8L3Q72L3ZiKVj8BHUpaYHI7c+uBeYPjUHQtGI8W5F0GBZMq qqESofeYP2HHtSN3XFVLbarQkN44EdBbE25GaV25MKk2R3bPaLNBBBgpbaMyvlbZhsZwDGQMP WWQhSdPjpLv8Wmjtp6YVcXF2hY8WpwFhrVPBx0jeC8TcxGO37h5CFoLSJiNd0rxNPjdWBjZcj BwtUMB9bm5/hVblTd1BbD7BRQv2DfTDi0Yz3mlkstJbK1HvyBcxoY6yGrYiWItF6u2zhpylE1 NdKDeECWrrt4S0Q2pQMNrx2bNlU3rb9IDfQqUEKB4gmeA+Yxiq9oju8z6jhpmd+8CEsgmUStT R7Vmk/J5pm7GWM8AUVKNYcgVWjJZWpHMtnokKJcd4SMluhFFhPgB7PYrjxAWmnkUmh1Jcj0LQ SwvBWk9GfZaYecoXmU0AGBhHpaFQK7vY7GWiirGgg= Received-SPF: pass client-ip=212.227.17.12; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 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.01, RCVD_IN_MSPIKE_WL=-0.01, 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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Migration and yank code assume that qio_channel_shutdown is thread -safe and can be called from qmp oob handler. Document this after checking the code. Signed-off-by: Lukas Straub Acked-by: Stefan Hajnoczi Reviewed-by: Daniel P. Berrangé --- include/io/channel.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/include/io/channel.h b/include/io/channel.h index 4d6fe45f63..ab9ea77959 100644 --- a/include/io/channel.h +++ b/include/io/channel.h @@ -92,7 +92,8 @@ struct QIOChannel { * provide additional optional features. * * Consult the corresponding public API docs for a description - * of the semantics of each callback + * of the semantics of each callback. io_shutdown in particular + * must be thread-safe, terminate quickly and must not block. */ struct QIOChannelClass { ObjectClass parent; @@ -510,6 +511,8 @@ int qio_channel_close(QIOChannel *ioc, * QIO_CHANNEL_FEATURE_SHUTDOWN prior to calling * this method. * + * This function is thread-safe, terminates quickly and does not block. + * * Returns: 0 on success, -1 on error */ int qio_channel_shutdown(QIOChannel *ioc, From patchwork Sun Dec 13 11:48:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1415560 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.a=rsa-sha256 header.s=dbaedf251592 header.b=VCNZ77If; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4Cv31p38WMz9sTv for ; Sun, 13 Dec 2020 22:58:06 +1100 (AEDT) Received: from localhost ([::1]:39554 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1koQ0q-0004HP-FL for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2020 06:58:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:60992) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPru-0005hO-9Q; Sun, 13 Dec 2020 06:48:50 -0500 Received: from mout.web.de ([212.227.17.12]:41935) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1koPrs-0002Qx-LW; Sun, 13 Dec 2020 06:48:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1607860123; bh=UP4094DmmCJ+Ss3RCBCnPcG3KWGgAKwbGEevrHNiNpE=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=VCNZ77IfrkC0mIykkD1VNnfurWs/NojE5o5CnlekG8wuAXhMwOeMdZB0Q6XCCwJoO WG2qEfJbYUzNgdGzoUylIe4is5abHwVKIvLK782NnU/BepQIrtBVYALWOLHYzEu5rl 9C/2U+yA14cqFiDhfJeLLCvV/pyVbxDqrZBf8dZU= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from gecko.fritz.box ([88.130.61.131]) by smtp.web.de (mrweb103 [213.165.67.124]) with ESMTPSA (Nemesis) id 0M8Qtq-1jtXmi3VII-00vyY0; Sun, 13 Dec 2020 12:48:42 +0100 Date: Sun, 13 Dec 2020 12:48:41 +0100 From: Lukas Straub To: qemu-devel Subject: [PATCH v12 7/7] tests/test-char.c: Wait for the chardev to connect in char_socket_client_dupid_test Message-ID: <9289057e4a736e2c9823634fdfe47e81962905b6.1607858747.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:mBJsKeb0IRIDimauNo3NTTY2lxh8A2GPAoU1noJWPyc1rA86MrC Yf8faXMWuSRNPip4TBmWgj5HOIwuGIwg+EL0VYmi+s+f/5msw3ONCHHbLgIoYL4V40uOMD4 D7TPFCEvTR8O6dpBvnZNxxI2YGMa3sxQIY/KiIBMI33vkIkX5og9KWrHXe5MRNGKVX8yeLC YTE6a1ycgQFweqXdjtesg== X-UI-Out-Filterresults: notjunk:1;V03:K0:QsisDYe2Z00=:12RICRZtUVRBvPs5ocFqTe jkN1sfPWDB1DCWk4NbxOpFdHxIc5G+ajvNgEYxnO+0pjMxDK4J0fO3wCfRwYWV5MmStInGO0j acgV1Uz4+LmrnmMnZ6fW8nQxTQSB5gl9evTfnFv9oJxn0Px2U03e0qB9si415xFMKYACKXZzq lmnTnXrpzBbeCKkQ7wLtTUrXOWsUcO2J843evPhdwOUyEoiVMbU9i6jph9Nt3JpQ3fCaaOsO7 /fYZpyxIj/7iTDeplcNO238gpVsW0b1OK5s5HLzvyXY1iCA+Uqx0kMK3/FoNOERPFcWhTPoZy lRsVthrCl9Wc562ROAWAVnC/XUwpZha3dlqf5aKvqOpYNRu/FcIO5Thc+5jLcTZwUlAOQGWss 9T2NoHkG6tEKFRwH6VsgOEQyM5aXKvo42BVflzdYu84KGeDWJ74Yk57zH/aXn0UKqszASYb0h q6qCHaNTFvL5xNPAd9jcgrF/8u/BXwmli459jZPjOxHOviz+TwlyJETKhFIYGCkyFy81CtI6r Y5afrfx5b/kSsPdr6/g7mT7Vn2S20b+HXinnnPCGUwIi/pzokClMVDaC7eWiaLZgeg9Hgn5AK 7no84QbQZggUp/WLrafRC4jvYmaO8gk4Satkv1GMFHjTwcgr7fqd4QmRJrC/8RD+w04dS4Uxm hfQ28P+unzFW8/dD3SdQU5HCaNcHBPftd60dMvC/Qzugzs21d+RXkaOgbMDWMIZ/Oo1/TiF5C gargmGrRZ53wUNsebqJ/CJUMjB6a5HWgGvCJqveHdQd5abzfBtCM7aZ4d4n5M5QnfNPgigBu+ WdeautkK5o4MmmqPZPbrJ5uPnO2oIFy+PVyEyoZp2kAi6ZFrf3IgvgWJLBzSAYevafbPN7zMp gazH1h8ix8ZPxV9oZCPNKLBAJ2rwMBDAmKSLmd8RU= Received-SPF: pass client-ip=212.227.17.12; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 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.01, RCVD_IN_MSPIKE_WL=-0.01, 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: Kevin Wolf , "Daniel P. =?utf-8?b?QmVycmFuZ8Op?= " , qemu-block , Juan Quintela , Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , =?utf-8?q?Marc-Andr=C3=A9?= Lureau , Paolo Bonzini , =?utf-8?q?Marc-Andr=C3=A9?= Lureau Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A connecting chardev object has an additional reference by the connecting thread, so if the chardev is still connecting by the end of the test, then the chardev object won't be freed. This in turn means that the yank instance won't be unregistered and when running the next test-case yank_register_instance will abort, because the yank instance is already/still registered. Signed-off-by: Lukas Straub Reviewed-by: Daniel P. Berrangé --- tests/test-char.c | 1 + 1 file changed, 1 insertion(+) -- 2.20.1 diff --git a/tests/test-char.c b/tests/test-char.c index 953e0d1c1f..41a76410d8 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -937,6 +937,7 @@ static void char_socket_client_dupid_test(gconstpointer opaque) g_assert_nonnull(opts); chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort); g_assert_nonnull(chr1); + qemu_chr_wait_connected(chr1, &error_abort); chr2 = qemu_chr_new_from_opts(opts, NULL, &local_err); g_assert_null(chr2);