From patchwork Sun May 24 18:31:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1296936 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=none (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=SmphbT1v; 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 49VTQB1qhRz9sRY for ; Mon, 25 May 2020 04:33:54 +1000 (AEST) Received: from localhost ([::1]:49206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcvRX-00089A-M9 for incoming@patchwork.ozlabs.org; Sun, 24 May 2020 14:33:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60784) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvP5-00087m-AA; Sun, 24 May 2020 14:31:19 -0400 Received: from mout.web.de ([212.227.15.14]:46807) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvP4-0006Tb-2G; Sun, 24 May 2020 14:31:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1590345072; bh=/O9xlvzvWBWMRrVLjZtOMmg80GmqgybYiXhnvOjsfhE=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=SmphbT1vmDMLKcPgzfgHbAL7+8b6Ucq5EpxUIXUiHCt82jVCBIQeFvIz88DqBIyKn 1Lv8T0NiOikRDNXuo2+0NHZfKPUOPc1ka4S6VySMxleyUdegZyOtVGOYN+hsPk/9fa Nj/Nn0XRIK4NIpTfq3pNh2ccaxk1dD6cKOsYznMA= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([94.134.180.42]) by smtp.web.de (mrweb002 [213.165.67.108]) with ESMTPSA (Nemesis) id 0LfzcB-1jEFsx1lKl-00pgG2; Sun, 24 May 2020 20:31:12 +0200 Date: Sun, 24 May 2020 20:31:10 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v3 1/4] Introduce yank feature Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:sGSfGPEMZ/dCbbxsG7H+YVELfz/d8Dsdcofzhu/Dq/ahxcwJICc gIMiuzybXHE+cVES+4wUU3Sym9nN0gOyYuF8HGHibJf47TB0burxMVrDYwrP7yhf/38eYeW 06kjpTfi9oE7TO0fvZ1NETPW1SvTabV22VTmMrtwwFvksXnPYAgfTB8Ee6LWmpCeDv4d3Ky R0khZo2DG900YMksIEfNQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:k0/DnYSIAog=:vnAYrYrZYlwzNL4+RHisjW /Alw2aI/0a3+dEtNSB7SUDHiCusDCWsBB8iwGy2/5ZNtJekQgkUu2WgEC/i+C2yxZfjoh8j5U +vp1sP82sIl8evzrr53K8sHfLhxUAnN47MsMG2OUYL9T5DJ82re9I8u6DXxAdAaVCW3MCSs2W khUF41+O7ymhbrNquLbPZXT5pQLZcd7MmXtYrKrlLT9mddNRZDQHyktTdV8XmwK50x4O0qoWq 6tmA77aXsyEg08xxAzehClZDRCSxoTJq9DWrA/JTIHKQzl274IUuTFD0we9dE8TI9t9QttuU6 gp4mKYOsLVPlrmSyWZaq7mzbvvHJ+JZ/984fTx06YVZFjY5O4JIRrzWUEideZRH9JDYKNyo6+ T1XWvSvEbk+IE8oRYjo5COkdxjwi+x9xZ0F4L7AJjcdIDpp5HD5Oh6wC0+Nahyai7VOT4QTRO /T5IIRwwj2hXg9M9xn/pnTpeXw3NOM52qogq4hQTcHAi14YptFOzo8NIez1B+nxTZBPwmb/2n A6NyDMNHZYZ+bNcn6IQSb3MP84AnWPwknz6nM+fA9eRNbHlO0WLCwVvqu00qozIGYHFRTYIHf Ed5Ncp176XMEFMsl7VIAKA6xTzgpDDF8gFiyYb2FWK5PfKC8zYpT5Kyrasgn+W0L/A2cwpoZs TNTlHrVy9/rVgwgIr4eY2VMRu7jU1YqW74huQzE5gwmPTA4hYJWw1T4aq1zqg5Kimr8X0NjEf epRlmwLYXeQ7Aj635bawXUDYSGFObux6Uw/vZAUZRQxDrt7WbicCEn5YCPgpME2A4N+pjeYvQ A+O90mmd65n48sHKBrQlyN7x78nfahGJfnZOz13cEpx+1dpe8Yjmj48UrhUOfhoSXAYuHmxQg x9GVfO/nKepE52/f2BfDBgNmzRC4LaD56TTF5lz8w28A8ck9TnSBL7jsT5Bkm2ws8KnxuqtA4 mufJ8zjYMhmlyaoCyq87q0+qlYyqr6wabJvHeTV2XD12gkB+CeqAykZFH6JyIzC1AvwKQOhr+ dpCK7zi+qkDosUG9KThRebN3yQDmx9pyyWLzARxTL1n20piezApiGi0rcFX1lonLNjEOEs/iP 12T6YNp1WXXwSzz4cbHyrJepROWMBXoOVWn4xiMvU9ZE5ZoI0CCVzpaXVrPS9blpeSoB0Hn8s hWgfvmcPbtvoTFhWOL3Fg06nZ5P/Oaw3XnIj2sW3qci6ibU1nB79HpuxxgPmNehvi1jPc3aNA Zh4lELMmezmHPhs8V Received-SPF: pass client-ip=212.227.15.14; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/24 14:31:16 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] 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_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN 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 , "Dr. David Alan Gilbert" , Max Reitz , 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 --- qapi/misc.json | 45 +++++++++++++ yank.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++ yank.h | 67 +++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 100644 yank.c create mode 100644 yank.h -- 2.20.1 diff --git a/qapi/misc.json b/qapi/misc.json index 99b90ac80b..f5228b2502 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1550,3 +1550,48 @@ ## { 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' } +## +# @YankInstances: +# +# @instances: List of yank instances. +# +# Yank instances are named after the following schema: +# "blockdev:", "chardev:" and "migration" +# +# Since: 5.1 +## +{ 'struct': 'YankInstances', 'data': {'instances': ['str'] } } + +## +# @yank: +# +# Recover from hanging qemu by yanking the specified instances. +# +# Takes @YankInstances as argument. +# +# Returns: nothing. +# +# Example: +# +# -> { "execute": "yank", "arguments": { "instances": ["blockdev:nbd0"] } } +# <- { "return": {} } +# +# Since: 5.1 +## +{ 'command': 'yank', 'data': 'YankInstances', 'allow-oob': true } + +## +# @query-yank: +# +# Query yank instances. +# +# Returns: @YankInstances +# +# Example: +# +# -> { "execute": "query-yank" } +# <- { "return": { "instances": ["blockdev:nbd0"] } } +# +# Since: 5.1 +## +{ 'command': 'query-yank', 'returns': 'YankInstances', 'allow-oob': true } diff --git a/yank.c b/yank.c new file mode 100644 index 0000000000..36d8139d4d --- /dev/null +++ b/yank.c @@ -0,0 +1,174 @@ +/* + * 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-misc.h" +#include "io/channel.h" +#include "yank.h" + +struct YankFuncAndParam { + YankFn *func; + void *opaque; + QLIST_ENTRY(YankFuncAndParam) next; +}; + +struct YankInstance { + char *name; + QLIST_HEAD(, YankFuncAndParam) yankfns; + QLIST_ENTRY(YankInstance) next; +}; + +static QemuMutex lock; +static QLIST_HEAD(yankinst_list, YankInstance) head + = QLIST_HEAD_INITIALIZER(head); + +static struct YankInstance *yank_find_instance(char *name) +{ + struct YankInstance *tmp, *instance; + instance = NULL; + QLIST_FOREACH(tmp, &head, next) { + if (!strcmp(tmp->name, name)) { + instance = tmp; + } + } + return instance; +} + +void yank_register_instance(char *instance_name) +{ + struct YankInstance *instance; + + qemu_mutex_lock(&lock); + assert(!yank_find_instance(instance_name)); + + instance = g_slice_new(struct YankInstance); + instance->name = g_strdup(instance_name); + QLIST_INIT(&instance->yankfns); + QLIST_INSERT_HEAD(&head, instance, next); + + qemu_mutex_unlock(&lock); +} + +void yank_unregister_instance(char *instance_name) +{ + struct YankInstance *instance; + + qemu_mutex_lock(&lock); + instance = yank_find_instance(instance_name); + assert(instance); + + assert(QLIST_EMPTY(&instance->yankfns)); + QLIST_REMOVE(instance, next); + g_free(instance->name); + g_slice_free(struct YankInstance, instance); + + qemu_mutex_unlock(&lock); +} + +void yank_register_function(char *instance_name, YankFn *func, void *opaque) +{ + struct YankInstance *instance; + struct YankFuncAndParam *entry; + + qemu_mutex_lock(&lock); + instance = yank_find_instance(instance_name); + assert(instance); + + entry = g_slice_new(struct YankFuncAndParam); + entry->func = func; + entry->opaque = opaque; + + QLIST_INSERT_HEAD(&instance->yankfns, entry, next); + qemu_mutex_unlock(&lock); +} + +void yank_unregister_function(char *instance_name, YankFn *func, void *opaque) +{ + struct YankInstance *instance; + struct YankFuncAndParam *entry; + + qemu_mutex_lock(&lock); + instance = yank_find_instance(instance_name); + assert(instance); + + QLIST_FOREACH(entry, &instance->yankfns, next) { + if (entry->func == func && entry->opaque == opaque) { + QLIST_REMOVE(entry, next); + g_slice_free(struct YankFuncAndParam, entry); + qemu_mutex_unlock(&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(strList *instances, Error **errp) +{ + strList *tmp; + struct YankInstance *instance; + struct YankFuncAndParam *entry; + + qemu_mutex_lock(&lock); + tmp = instances; + for (; tmp; tmp = tmp->next) { + instance = yank_find_instance(tmp->value); + if (!instance) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, + "Instance '%s' not found", tmp->value); + qemu_mutex_unlock(&lock); + return; + } + } + tmp = instances; + for (; tmp; tmp = tmp->next) { + instance = yank_find_instance(tmp->value); + assert(instance); + QLIST_FOREACH(entry, &instance->yankfns, next) { + entry->func(entry->opaque); + } + } + qemu_mutex_unlock(&lock); +} + +YankInstances *qmp_query_yank(Error **errp) +{ + struct YankInstance *instance; + YankInstances *ret; + + ret = g_new0(YankInstances, 1); + ret->instances = NULL; + + qemu_mutex_lock(&lock); + QLIST_FOREACH(instance, &head, next) { + strList *entry; + entry = g_new0(strList, 1); + entry->value = g_strdup(instance->name); + entry->next = ret->instances; + ret->instances = entry; + } + qemu_mutex_unlock(&lock); + + return ret; +} + +static void __attribute__((__constructor__)) yank_init(void) +{ + qemu_mutex_init(&lock); +} diff --git a/yank.h b/yank.h new file mode 100644 index 0000000000..f1c8743b72 --- /dev/null +++ b/yank.h @@ -0,0 +1,67 @@ + +#ifndef YANK_H +#define 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_name: The globally unique name of the instance. + */ +void yank_register_instance(char *instance_name); + +/** + * 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_name: The name of the instance. + */ +void yank_unregister_instance(char *instance_name); + +/** + * 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. + * + * This function is thread-safe. + * + * @instance_name: The name of the instance + * @func: The yank function + * @opaque: Will be passed to the yank function + */ +void yank_register_function(char *instance_name, YankFn *func, void *opaque); + +/** + * yank_unregister_function: Unregister a yank function + * + * This unregisters a yank function. + * + * This function is thread-safe. + * + * @instance_name: The name of the instance + * @func: func that was passed to yank_register_function + * @opaque: opaque that was passed to yank_register_function + */ +void yank_unregister_function(char *instance_name, YankFn *func, void *opaque); + +/** + * yank_unregister_function: 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); +#endif From patchwork Sun May 24 18:31:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1296937 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=none (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=mSLKI7lo; 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 49VTQD4CJGz9sRY for ; Mon, 25 May 2020 04:33:56 +1000 (AEST) Received: from localhost ([::1]:49280 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcvRZ-0008BT-SX for incoming@patchwork.ozlabs.org; Sun, 24 May 2020 14:33:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60790) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvP8-00089U-BX; Sun, 24 May 2020 14:31:22 -0400 Received: from mout.web.de ([217.72.192.78]:56759) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvP6-0006Tq-Vx; Sun, 24 May 2020 14:31:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1590345076; bh=elKbSKLl3l/JFRMmDA9fenj91qTQd2VT8UJA44f7Xf8=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=mSLKI7loG4D4nHjVxP2SFXZa/1ooY4+ODPOzmVQNWPcA1fc1fxXH152jIX4kWdHOn pMp3BrR9zBx+ZdADSQ8XXsaZwPAsxQsb32HpiMFx1dhI/AuokBpufOeDHm6tE1hSiX 8oHZpMOQAcd7nfhYz5FI5RQM4yTwfZv6GCV7zjFE= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([94.134.180.42]) by smtp.web.de (mrweb106 [213.165.67.124]) with ESMTPSA (Nemesis) id 1M76XN-1jfv8m3RBX-008ibA; Sun, 24 May 2020 20:31:15 +0200 Date: Sun, 24 May 2020 20:31:14 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v3 2/4] block/nbd.c: Add yank feature Message-ID: <8e6a8e61b25813cdcdf385729709ef57f6255a3e.1590344541.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:D/t3yZcETUz1dpJFdB4TItEk5myVnDtI9C7QyWOMDh3+JoNhajc 2BJqXekcf9UY5fnBA1jp+w44jtqN3N9kglL+YIiHW/OJFbq87UpwQGTpevx598YXWYSkapk jBIqtoNtluBv9kJJnI9vrDSMdZvPyqac6SHENgjrUghr6RVFk/kAej3Zndup3vLJK2xgqFU 57JaFKGj7+6gsPCzQXPCw== X-UI-Out-Filterresults: notjunk:1;V03:K0:zGWS4j3n+/I=:JX+CObVvwzs0VxNIgHBkf8 KOsPMdHktXMYIVxQcCx4DBRQEZLKFWwT6+EhBUzp+VVyb5b8z+i7xlO5Kd3Cy8f4tSnKdW/NH pyMBYyt5XMIuhXcGn+zuzoRydfRDMIPrGPmGhduh3RjI8zKUpNDlO0+7IXsb3MzDCVUl+VB/r AMGo5WOONGh1Z845s6g6+hiF4pIu4UxQ6BUvdnHTpABwoBOnTfX0COBSyWKtQe53ooddKunlb P1dzZJZ3qGZpxmpf3nyvqzLvop9sFfFtM6OPHQIZU/Xixoj7byOuWybOuqu6QMxVT3jPTqNjW Hx6ACM0eQzp2S77+W+5DLrtDlXHeelpFrUV1IjdM4rvDyu6+dkHOBU6g9GBaX7q3/UH7IGTf5 YFkwXc0eKD1jlPqD0yzRW9fmpw/giKOQk50vqza3fsmDlEMeY9Dbe88dFBmh0ohynts73Hsnt cV/fX6v/5vA1lVZnqKxxx8FCLc537ALFlzjqZ7TWbxesUAZB+NovnP6k4UFd5y5cceTl8fNLb oem1wMvg19t8YhvHisSAioe+zgOsqu1gGSKYmlMpybSE77Ve18UFpvfzyybQcbAdzOf0FC8SD DA6Wtxe9g+vulGaXjSi4WeqmyZym+j+nMh+9Z8F3Vxd8H9HaR2me4s21bL177RxONcAAJN/0p +Atscep0IL4iBjTYf1w1DsEHl7PEfxNXggb2etSYGpeXaS/NLF2u5Pj3s4tW++O0r4brzT4oI IG5K0hVd9+u6AsSIlfak0XZFd0rq1vSRs6fE81WKZrpDXAza4xcFmjpJFMEGz50mR6hdcGRn+ ZwmzKMMAdT/NwDZqMjB4T34xQ3y4NnpY+fqcXGG6t4eQvXPJ5lxtm2YmkPQkkXTf3FD+41hKL RkvPm7UzteA4zfc7VIHC2CQ2OqUVxLSOARdNs0QfeY1QlUYnwFOmEwHaPHmv5HBmF3FZQN30c HgmYAezEMig6GomlmxfTI/w/GVOzOk5vXg3TZHcuAjqLkRTS70JMAKOCRt+8RaEXI/zYKoD/M rU3GZlpQulyimi1f6h/lxUeR5unsUfhKk52y8Ty1yUu/Zgoisd4uEitsbRsKzZeuqrafkgLBR VkLVnIHPsAdXOs2FqwE/XjFIB+cAWbvmvpKJcKplALyZqlQcKKxou8HpZDcfMIXvivmTfRv7N /LLpP+vOUGo5RVDvJPT+bVK9Zixj0WFpsiYv2z4J+9ELKi7ES2WmvpCnBcHajaPAu45LxXoIp dFKsn/uQRSu/LvyG9 Received-SPF: pass client-ip=217.72.192.78; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/24 14:31:19 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN 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 , "Dr. David Alan Gilbert" , Max Reitz , 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 --- Makefile.objs | 1 + block/nbd.c | 101 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 65 insertions(+), 37 deletions(-) -- 2.20.1 diff --git a/Makefile.objs b/Makefile.objs index a7c967633a..8e403b81f3 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -18,6 +18,7 @@ block-obj-y += block.o blockjob.o job.o block-obj-y += block/ scsi/ block-obj-y += qemu-io-cmds.o block-obj-$(CONFIG_REPLICATION) += replication.o +block-obj-y += yank.o block-obj-m = block/ diff --git a/block/nbd.c b/block/nbd.c index 2160859f64..3a41749f1b 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" @@ -43,6 +44,8 @@ #include "block/nbd.h" #include "block/block_int.h" +#include "yank.h" + #define EN_OPTSTR ":exportname=" #define MAX_NBD_REQUESTS 16 @@ -84,6 +87,8 @@ typedef struct BDRVNBDState { NBDReply reply; BlockDriverState *bs; + char *yank_name; + /* Connection parameters */ uint32_t reconnect_delay; SocketAddress *saddr; @@ -94,6 +99,7 @@ typedef struct BDRVNBDState { } BDRVNBDState; static int nbd_client_connect(BlockDriverState *bs, Error **errp); +static void nbd_yank(void *opaque); static void nbd_clear_bdrvstate(BDRVNBDState *s) { @@ -106,17 +112,19 @@ static void nbd_clear_bdrvstate(BDRVNBDState *s) s->tlscredsid = NULL; g_free(s->x_dirty_bitmap); s->x_dirty_bitmap = NULL; + g_free(s->yank_name); + s->yank_name = NULL; } static void nbd_channel_error(BDRVNBDState *s, int ret) { if (ret == -EIO) { - if (s->state == NBD_CLIENT_CONNECTED) { + if (atomic_read(&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 (atomic_read(&s->state) == NBD_CLIENT_CONNECTED) { qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL); } s->state = NBD_CLIENT_QUIT; @@ -167,7 +175,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 (atomic_read(&s->state) == NBD_CLIENT_CONNECTED) { qio_channel_attach_aio_context(QIO_CHANNEL(s->ioc), new_context); } @@ -206,7 +214,7 @@ static void nbd_teardown_connection(BlockDriverState *bs) { BDRVNBDState *s = (BDRVNBDState *)bs->opaque; - if (s->state == NBD_CLIENT_CONNECTED) { + if (atomic_read(&s->state) == NBD_CLIENT_CONNECTED) { /* finish any pending coroutines */ assert(s->ioc); qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL); @@ -230,13 +238,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 = atomic_read(&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 atomic_read(&s->state) == NBD_CLIENT_CONNECTING_WAIT; } static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) @@ -274,6 +283,7 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) /* Finalize previous connection if any */ if (s->ioc) { nbd_client_detach_aio_context(s->bs); + yank_unregister_function(s->yank_name, nbd_yank, s->bs); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); @@ -305,7 +315,7 @@ static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s) nbd_reconnect_attempt(s); while (nbd_client_connecting(s)) { - if (s->state == NBD_CLIENT_CONNECTING_WAIT && + if (atomic_read(&s->state) == NBD_CLIENT_CONNECTING_WAIT && qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time_ns > delay_ns) { s->state = NBD_CLIENT_CONNECTING_NOWAIT; @@ -341,7 +351,7 @@ static coroutine_fn void nbd_connection_entry(void *opaque) int ret = 0; Error *local_err = NULL; - while (s->state != NBD_CLIENT_QUIT) { + while (atomic_read(&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 @@ -356,7 +366,7 @@ static coroutine_fn void nbd_connection_entry(void *opaque) nbd_co_reconnect_loop(s); } - if (s->state != NBD_CLIENT_CONNECTED) { + if (atomic_read(&s->state) != NBD_CLIENT_CONNECTED) { continue; } @@ -411,6 +421,7 @@ static coroutine_fn void nbd_connection_entry(void *opaque) s->connection_co = NULL; if (s->ioc) { nbd_client_detach_aio_context(s->bs); + yank_unregister_function(s->yank_name, nbd_yank, s->bs); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); @@ -435,7 +446,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 (atomic_read(&s->state) != NBD_CLIENT_CONNECTED) { rc = -EIO; goto err; } @@ -462,7 +473,7 @@ 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 (rc >= 0 && atomic_read(&s->state) == NBD_CLIENT_CONNECTED) { if (qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { rc = -EIO; @@ -777,7 +788,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 (atomic_read(&s->state) != NBD_CLIENT_CONNECTED) { error_setg(errp, "Connection closed"); return -EIO; } @@ -936,7 +947,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 (atomic_read(&s->state) != NBD_CLIENT_CONNECTED) { error_setg(&local_err, "Connection closed"); nbd_iter_channel_error(iter, -EIO, &local_err); goto break_loop; @@ -961,7 +972,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) || + atomic_read(&s->state) != NBD_CLIENT_CONNECTED) { goto break_loop; } @@ -1395,6 +1407,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; + + qio_channel_shutdown(QIO_CHANNEL(s->sioc), QIO_CHANNEL_SHUTDOWN_BOTH, NULL); + atomic_set(&s->state, NBD_CLIENT_QUIT); +} + static void nbd_client_close(BlockDriverState *bs) { BDRVNBDState *s = (BDRVNBDState *)bs->opaque; @@ -1407,25 +1428,29 @@ 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) { - QIOChannelSocket *sioc; + BDRVNBDState *s = (BDRVNBDState *)bs->opaque; Error *local_err = NULL; - 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"); + yank_register_function(s->yank_name, nbd_yank, bs); - qio_channel_socket_connect_sync(sioc, saddr, &local_err); + qio_channel_socket_connect_sync(s->sioc, saddr, &local_err); if (local_err) { - object_unref(OBJECT(sioc)); + yank_unregister_function(s->yank_name, nbd_yank, bs); + object_unref(OBJECT(s->sioc)); + s->sioc = NULL; error_propagate(errp, local_err); - return NULL; + return -1; } - qio_channel_set_delay(QIO_CHANNEL(sioc), false); + qio_channel_set_delay(QIO_CHANNEL(s->sioc), false); - return sioc; + return 0; } static int nbd_client_connect(BlockDriverState *bs, Error **errp) @@ -1438,28 +1463,27 @@ static int nbd_client_connect(BlockDriverState *bs, Error **errp) * establish TCP connection, return error if it fails * TODO: Configurable retry-until-timeout behaviour. */ - QIOChannelSocket *sioc = nbd_establish_connection(s->saddr, errp); - - if (!sioc) { + if (nbd_establish_connection(bs, s->saddr, errp) < 0) { return -ECONNREFUSED; } /* NBD handshake */ trace_nbd_client_connect(s->export); - 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(s->yank_name, nbd_yank, bs); + object_unref(OBJECT(s->sioc)); return ret; } if (s->x_dirty_bitmap && !s->info.base_allocation) { @@ -1485,10 +1509,8 @@ static int nbd_client_connect(BlockDriverState *bs, Error **errp) } } - s->sioc = sioc; - if (!s->ioc) { - s->ioc = QIO_CHANNEL(sioc); + s->ioc = QIO_CHANNEL(s->sioc); object_ref(OBJECT(s->ioc)); } @@ -1504,9 +1526,10 @@ static int nbd_client_connect(BlockDriverState *bs, Error **errp) { 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(s->yank_name, nbd_yank, bs); + object_unref(OBJECT(s->sioc)); return ret; } @@ -1913,6 +1936,9 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, qemu_co_mutex_init(&s->send_mutex); qemu_co_queue_init(&s->free_sema); + s->yank_name = g_strconcat("blockdev:", bs->node_name, NULL); + yank_register_instance(s->yank_name); + ret = nbd_client_connect(bs, errp); if (ret < 0) { nbd_clear_bdrvstate(s); @@ -1972,6 +1998,7 @@ static void nbd_close(BlockDriverState *bs) BDRVNBDState *s = bs->opaque; nbd_client_close(bs); + yank_unregister_instance(s->yank_name); nbd_clear_bdrvstate(s); } From patchwork Sun May 24 18:31: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: 1296938 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=none (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=DlLFCDWA; 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 49VTS06GXjz9sRY for ; Mon, 25 May 2020 04:35:28 +1000 (AEST) Received: from localhost ([::1]:53048 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcvT4-0001RN-B6 for incoming@patchwork.ozlabs.org; Sun, 24 May 2020 14:35:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60808) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvPG-0008Cz-2t; Sun, 24 May 2020 14:31:30 -0400 Received: from mout.web.de ([212.227.15.14]:46561) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvPB-0006U2-AL; Sun, 24 May 2020 14:31:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1590345079; bh=fLYzf2F8wnaTovtphVpUv0gbKjiN2QoyW9YUN9gfPYI=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=DlLFCDWAcxT0BnkdWxdbWXnvVmEw1U8Q/GwwgOE0si5AREE4t8PnCNsilbHCAttDA xewjs8lMgTb2kqv/I9nop9e+O0IswraB1530UJPVoifIF8/xFf6r/MJD9tG136e8Iv AMzzppq9jzdBAhVVXYYLVbpPH+cLSFf/uz99VWCg= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([94.134.180.42]) by smtp.web.de (mrweb001 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MKJAE-1jdTMn1JaA-001ivB; Sun, 24 May 2020 20:31:19 +0200 Date: Sun, 24 May 2020 20:31:17 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v3 3/4] chardev/char-socket.c: Add yank feature Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:4URxPNh+ZnLePpm4Ak6csq4RN1keqS/nxPX84HMEZT0bRARdDCi Mb7Wq3Z5kHzZziVKdybUjbk+aE4nAbUjbIshGdXzE4cXHbo+I4kzd3BwW5DEOfBhSwMRWsD Wra+BOW2jyqNZK2jZQTVUrh8cMsW9XQoICrsMJtfo5I7nZTXy1ZJn91HyWtrDbdC2/tYQCf bDwgCMd0EIFjFp9yOj/vQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:A9kqLo+EwDw=:ZHFjfyIuVpflSrSbXR9e0/ dOxENVao30hOGZJbqvCyOtxLnyw6O9oMgVXnYA0N3Y7XTpy23cSjHt1aOvsiOJiD1MtWZj7/T yUilGCMRFOMT6uHuxlBYbJCqDy5fJu6UbXcikSxcT+Cu5sA8c88tRcSp+1rkHvc4GkPpWQQOZ It8f1wQVAeTbUCVbCDZrzHPSqcRYz+dGYfvZjKWkUQe6sgzbWvgTrMYjvPua9/+NoNKYBUWMK XU+l9tggxVKTxlQxSUv/HgEKAdRh1TgbrmZn1TxgHg8j5g0T0wH9MqQWU5/vQsml1h3fQFhJM AgncmDfdfJ9cbDs5Sktwdd5crjIyIcEHUfx1OlWzgxrlvJ6BfQFpYerw9bwdxVJ/AvXc5J2Z4 YE8iFULmA2farqFg7oswBpiwv2g0gIVV3nzf3X17tlFj/yABX2E7TVjcsxccomNTuvZwrULv+ SLQuGdZS2E4Enhc863LoQbrBZJ48it+50oRhSheT5cHjXQL9wOXPbiAXVFH/h8AB8eSYc636m K79cU2OQNhvVbt7svFBxbIQBNorzG3hZE+BSZ1sMGlO3OaAKlKnvBOgniNIId7RnPXFAb4qmg G6ORo8OJahIxFznyBQ9o7FGdh6n7HQelQqmiboc64KLM9M80e0UhqX9CbFrPxcYQTWFuxRVWQ vRpnj7D3gB3DBmcNcpFFeyFegp5r/pTVzzmG0o6B+ZguI1OvS9hlA48O8yq8QRZXTSxPEmTJU AZejQrkIrc2DLRZTo0FPXnPWb9hT0VJvGQMERHMWY/OcwwAw7sYvMla8N9Lc9SdXssn7mxRci IUjWOLQqm5GQG62F+ukkOcezdgHBYYtoILlOS/1gHgwkUWcNlkMr87o1MRhkInAbj0D78MIaC Ee8OajLwHXyK5NI1jlD5eD4mvTPIbrB3Phr/I0oP+i4LA3VMpDsJIQpa4A+u3Pzodn6+bIQ/y o4AfeHRFbkS+FuVhvl1IwXPGLPQ8FT+Cv68LAXduuZ/z2xA6Ix7yUx/VhDYsygvRs6IjcutPj 3pn/0mGzz0fjypTeYEur48+fYBCmsHjmWZPD7K5NPXBEzRM0p7OJPB5IVo5PfT8NrQeCGXv70 v2/+ShrjD33ruxNmJ/UdnuKE066ABhTXgiJann0Hg1LWwHNRJZjlEyZ1G6bQmOMEFEQdGADB+ 365DO229H1a/GA4dqguuA0Of/YINegG2mSnr9lCgrH7fv/YOZrcj6rxMHzvEYB/l2CV7M3PSP 4XrZQoUF7UrkvZV1t Received-SPF: pass client-ip=212.227.15.14; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/24 14:31:16 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] 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_H2=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN 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 , "Dr. David Alan Gilbert" , Max Reitz , 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 --- Makefile.objs | 1 + chardev/char-socket.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) -- 2.20.1 diff --git a/Makefile.objs b/Makefile.objs index 8e403b81f3..5582f4eda9 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -10,6 +10,7 @@ qom-obj-y = qom/ ifeq ($(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS)),y) chardev-obj-y = chardev/ +chardev-obj-y += yank.o authz-obj-y = authz/ diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 185fe38dda..d5c6cd2153 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 "yank.h" #include "chardev/char-io.h" @@ -69,6 +70,7 @@ typedef struct { size_t read_msgfds_num; int *write_msgfds; size_t write_msgfds_num; + char *yank_name; SocketAddress *addr; bool is_listen; @@ -409,6 +411,11 @@ 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(s->yank_name, yank_generic_iochannel, + QIO_CHANNEL(s->sioc)); + } object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); @@ -912,6 +919,8 @@ 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(s->yank_name, yank_generic_iochannel, + QIO_CHANNEL(sioc)); ret = tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); return ret; @@ -926,6 +935,8 @@ 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(s->yank_name, yank_generic_iochannel, + QIO_CHANNEL(cioc)); tcp_chr_new_client(chr, cioc); } @@ -941,6 +952,8 @@ static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp) object_unref(OBJECT(sioc)); return -1; } + yank_register_function(s->yank_name, yank_generic_iochannel, + QIO_CHANNEL(sioc)); tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); return 0; @@ -956,6 +969,8 @@ 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(s->yank_name, yank_generic_iochannel, + QIO_CHANNEL(sioc)); tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); } @@ -1066,6 +1081,8 @@ static void char_socket_finalize(Object *obj) object_unref(OBJECT(s->tls_creds)); } g_free(s->tls_authz); + yank_unregister_instance(s->yank_name); + g_free(s->yank_name); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -1081,6 +1098,8 @@ 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(s->yank_name, yank_generic_iochannel, + QIO_CHANNEL(sioc)); check_report_connect_error(chr, err); error_free(err); goto cleanup; @@ -1115,6 +1134,8 @@ 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(s->yank_name, 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 @@ -1356,6 +1377,9 @@ static void qmp_chardev_open_socket(Chardev *chr, qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); } + s->yank_name = g_strconcat("chardev:", chr->label, NULL); + yank_register_instance(s->yank_name); + /* be isn't opened until we get a connection */ *be_opened = false; From patchwork Sun May 24 18:31:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1296940 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=none (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=HJ3lxZMo; 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 49VTXl22VBz9sPK for ; Mon, 25 May 2020 04:39:34 +1000 (AEST) Received: from localhost ([::1]:59374 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcvWy-0004F7-Lq for incoming@patchwork.ozlabs.org; Sun, 24 May 2020 14:39:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60812) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvPH-0008EC-60; Sun, 24 May 2020 14:31:31 -0400 Received: from mout.web.de ([212.227.17.12]:56761) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcvPG-0006UI-2y; Sun, 24 May 2020 14:31:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1590345083; bh=HnGhPPIWzFr2cqiH6723UqmRsC/vXvexVasAo/QPp1Y=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=HJ3lxZMo9GHu+msLUSA8oAvfJPfR/2dyL+TnAEdPpD13i/gUQh1hBtExE6y4ZBjgw jn+umePKJSkiAgFmJ4BEsHH/vTgQb/Owa+Qh9+YInM90sjrzSyUm5oyNuPYQjQaecj niHkAnwTY7pxqepqmP1Z/0xMrVwRMCeKcZ08me8A= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([94.134.180.42]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MAvGa-1jmmlD0tYC-009zQu; Sun, 24 May 2020 20:31:23 +0200 Date: Sun, 24 May 2020 20:31:21 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v3 4/4] migration: Add yank feature Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:2Vxyktjm7sPozNvi6cpLcMXsYayHvbxMFY2p8yErzVZX+v/heeV MRZs2A3L8jBzl7QCNae/J3+M0dLxDOAOmfAsuFZklU81h/tLQj8F4zjdtLsYiw0KHBrsz4J CiWzB3cW7BCk4eGL7gbI9gjNDHUbpq6Xq7lA92gmkZ52hvi5hSJC+qWiC/qIK+cZleHB81D zhsqQGS7neOQ65CesQWBg== X-UI-Out-Filterresults: notjunk:1;V03:K0:9w8IwTaLC1U=:W86OkbBor1xV1m25i8LhRI IDDI3Xa2HyoNZyK78aDXJb0cqr3QuPhn1j/aj9jY56x1i9O4klK5Z61EbNmalMgk0dcsaM0DJ oIbumWEc1wRunL7oAz+q/FSNZ1a8PRRmbxW9/ihS9ei61T8sgcyiVsd0trVD4oEk840cLGNnk ZSAofxqQEjrQnQMzbQxig1FzmtHwyyMCV/egK7qIVpuGHsyLO3aDJ9kU2ldQQmPDYAnv5bLcy +qP5lye/X6RePbl1moa1TJCyjkCECyJnt51Hr+4WwIbcLd6QwKt+rXAF5W8odftv58ZptDXRr X6mZLxmiZk2vfs+8OGJKwMiBEU/RapkHTkMV7jVvBWdT77dJe3adDPECc7kqrPbDg9VGNIk1+ yffMhxidqHC2VMtk9pIJDQjRuADnwrVfS+ZlJrnToyy/Vbm/OAABV8X+DwXhfqf4DsimfxP/L 02AeSFrypC0SVKp4ZnMrW5R/teeI5XZVCPIW8O2LQKwW3Ktxi+fzWu8+VgnCRN19yv0APCcO8 Tlb7r2IH2nH7ikMkwZd8xv3kGV14AtfXwbqkYijp6Uml4JKdT5jLC5AeufcQ/lnuwFeQnYIjj 1ItZEuhb94xGv/7RkdKYAJB9+K0Ilh9giqnVqjsL4FRk9uqiOZX/WI9Xc1KjxOTy59L+dn2qW lxq0h3qxEaa8VqghY24YalT1OQhmo/7YWEjNG4HDbQalcKbswmtFyE8lXVCr1Mx15HLh0DYzj 3tXEWPEspnuoWd3PGIlbjt0BgynrkiC5ByG6ccgw1wWSL6aonPiYcqJFq8MH4z6DS33uBC+Du sHuaqY2kcYVizcgjxTC1H5vF34W9bYVT1GJ1VCRM1nktOmL57itEu4Hbz3yphJ64uqO6m1VTK 0Fbn+kBZolE4LIyspqgVrH+bIClQ/q485/XIp5+PflMBxYeZcPtsNJTAD2HhSi4OAW7n9zZ78 frV783yocnI2xbaGc1BpC+IBNcQJCrbuBtxsXLDKqbc6IqYEIIoWJ221FJbmuhI8my4Uuf2Sl KspQa4IwPJyjUAQBI71QFVS3e3zXKLXk7+XHA/t0Y+BPCQ7nLXM7bqvGFs9LEDZra2suOqlY/ ny72uo2sI9XgcmqSkzkLotw5jqGmaZoNq7KOoSIGLIusS5j963KIBdFh3vaWabO+JCLjnGILQ Wm42cylbZc+WdJQPJgNwKn5WKkpjEOsSj3kw08mttSNDLz91N1g/oPpApeDQJAjPON1Ewjix2 m7paXxVnfcmsN9QsT Received-SPF: pass client-ip=212.227.17.12; envelope-from=lukasstraub2@web.de; helo=mout.web.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/24 14:31:12 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] 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_PASS=-0.001 autolearn=_AUTOLEARN 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 , "Dr. David Alan Gilbert" , Max Reitz , 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 --- Makefile.objs | 1 + migration/channel.c | 12 ++++++++++++ migration/migration.c | 18 +++++++++++++++++- migration/multifd.c | 10 ++++++++++ migration/qemu-file-channel.c | 6 ++++++ 5 files changed, 46 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/Makefile.objs b/Makefile.objs index 5582f4eda9..d2a49d3834 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -58,6 +58,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/ common-obj-y += accel/ common-obj-y += migration/ +common-obj-y += yank.o common-obj-y += audio/ common-obj-m += audio/ diff --git a/migration/channel.c b/migration/channel.c index 20e4c8e2dc..5cb48d403a 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 "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((char *) "migration", yank_generic_iochannel, + QIO_CHANNEL(ioc)); + } + if (s->parameters.tls_creds && *s->parameters.tls_creds && !object_dynamic_cast(OBJECT(ioc), @@ -67,6 +74,11 @@ 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((char *) "migration", 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 187ac0410c..c6d7119c08 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -54,6 +54,7 @@ #include "net/announce.h" #include "qemu/queue.h" #include "multifd.h" +#include "yank.h" #define MAX_THROTTLE (32 << 20) /* Migration transfer speed throttling */ @@ -231,6 +232,8 @@ void migration_incoming_state_destroy(void) qapi_free_SocketAddressList(mis->socket_address_list); mis->socket_address_list = NULL; } + + yank_unregister_instance((char *) "migration"); } static void migrate_generate_event(int new_state) @@ -362,7 +365,9 @@ void qemu_start_incoming_migration(const char *uri, Error **errp) const char *p; qapi_event_send_migration(MIGRATION_STATUS_SETUP); + yank_register_instance((char *) "migration"); if (!strcmp(uri, "defer")) { + yank_unregister_instance((char *) "migration"); deferred_incoming_migration(errp); } else if (strstart(uri, "tcp:", &p)) { tcp_start_incoming_migration(p, errp); @@ -377,6 +382,7 @@ 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((char *) "migration"); error_setg(errp, "unknown migration protocol: %s", uri); } } @@ -1632,6 +1638,7 @@ static void migrate_fd_cleanup(MigrationState *s) } notifier_list_notify(&migration_state_notifiers, s); block_cleanup_parameters(s); + yank_unregister_instance((char *) "migration"); } static void migrate_fd_cleanup_schedule(MigrationState *s) @@ -1899,6 +1906,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((char *) "migration"); qemu_start_incoming_migration(uri, errp); } @@ -2035,7 +2043,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, /* Error detected, put into errp */ return; } - + if (!(has_resume && resume)) { + yank_register_instance((char *) "migration"); + } if (strstart(uri, "tcp:", &p)) { tcp_start_outgoing_migration(s, p, &local_err); #ifdef CONFIG_RDMA @@ -2049,6 +2059,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((char *) "migration"); + } error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); migrate_set_state(&s->state, MIGRATION_STATUS_SETUP, @@ -2058,6 +2071,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } if (local_err) { + if (!(has_resume && resume)) { + yank_unregister_instance((char *) "migration"); + } migrate_fd_error(s, local_err); error_propagate(errp, local_err); return; diff --git a/migration/multifd.c b/migration/multifd.c index cb6a4a3ab8..97566262c1 100644 --- a/migration/multifd.c +++ b/migration/multifd.c @@ -24,6 +24,9 @@ #include "trace.h" #include "multifd.h" +#include "yank.h" +#include "io/channel-socket.h" + /* Multiple fd's */ #define MULTIFD_MAGIC 0x11223344U @@ -856,6 +859,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((char *) "migration", + 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..b725ac8098 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 "yank.h" static ssize_t channel_writev_buffer(void *opaque, @@ -104,6 +105,11 @@ 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((char *) "migration", yank_generic_iochannel, + QIO_CHANNEL(ioc)); + } object_unref(OBJECT(ioc)); return ret; }