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: 281980 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E289C433DF for ; Sun, 24 May 2020 18:35:51 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1B58920787 for ; Sun, 24 May 2020 18:35:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=web.de header.i=@web.de header.b="SmphbT1v" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1B58920787 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54720 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcvTS-00028D-3Q for qemu-devel@archiver.kernel.org; Sun, 24 May 2020 14:35:50 -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+qemu-devel=archiver.kernel.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: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: 281979 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66BFFC433E0 for ; Sun, 24 May 2020 18:37:04 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2CA2220787 for ; Sun, 24 May 2020 18:37:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=web.de header.i=@web.de header.b="DlLFCDWA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2CA2220787 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57084 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcvUd-0003Bm-3O for qemu-devel@archiver.kernel.org; Sun, 24 May 2020 14:37:03 -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+qemu-devel=archiver.kernel.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;