From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800012400560.0076653066204; Wed, 12 Mar 2025 10:20:12 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 54A4B1B60; Wed, 12 Mar 2025 13:20:11 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 7C4F71E04; Wed, 12 Mar 2025 13:18:23 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 434571AF3; Wed, 12 Mar 2025 13:18:16 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 9CAE01659 for ; Wed, 12 Mar 2025 13:18:15 -0400 (EDT) Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-691-J_8DSfW2ObqbNJR_0FKmOw-1; Wed, 12 Mar 2025 13:18:07 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 60FEF1955D69 for ; Wed, 12 Mar 2025 17:18:06 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 53DDB1801751; Wed, 12 Mar 2025 17:18:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799895; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bfM1VRCcFh2oWStABg+r/XhVMZBQ6TAOiWdrw8XkmS0=; b=LewN/LKGED9tyExyypgU9ccc48GeREr7qaxISrBQs1nCIMx+4XgIqj/zkgdDq5q4EFWS7k DgxJnnkJ3ucHn6XbAaypcE6SjeCKApXSBvW43SPyymh16gnaDe5Axsps6CRTSF32ieddmA MezQAN+ToUXNu02dDwdW91Oy8BvOTyY= X-MC-Unique: J_8DSfW2ObqbNJR_0FKmOw-1 X-Mimecast-MFC-AGG-ID: J_8DSfW2ObqbNJR_0FKmOw_1741799886 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 01/22] hypervisor: move support for auto-shutdown out of QEMU driver Date: Wed, 12 Mar 2025 17:17:41 +0000 Message-ID: <20250312171802.1854985-2-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: TnDj1k8WV43sH01E24MmxE7ULPd5OeRUFVmBQ3uI6xM_1741799886 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: YVIVWLC4VXFJMPKS3U5BJHTL2RCK7ZVI X-Message-ID-Hash: YVIVWLC4VXFJMPKS3U5BJHTL2RCK7ZVI X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800015126019100 Content-Type: text/plain; charset="utf-8" This is a move of the code that currently exists in the QEMU driver, into the common layer that can be used by multiple drivers. The code currently supports performing managed save of all running guests, ignoring any failures. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/hypervisor/domain_driver.c | 48 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 6 +++++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 47 ++++----------------------------- 4 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index b7499a376f..0ca482275f 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -712,3 +712,51 @@ virDomainDriverAutoStart(virDomainObjList *domains, =20 virDomainObjListForEach(domains, false, virDomainDriverAutoStartOne, &= state); } + + +void +virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) +{ + g_autoptr(virConnect) conn =3D NULL; + int numDomains =3D 0; + size_t i; + int state; + virDomainPtr *domains =3D NULL; + g_autofree unsigned int *flags =3D NULL; + + if (!(conn =3D virConnectOpen(cfg->uri))) + goto cleanup; + + if ((numDomains =3D virConnectListAllDomains(conn, + &domains, + VIR_CONNECT_LIST_DOMAINS_AC= TIVE)) < 0) + goto cleanup; + + flags =3D g_new0(unsigned int, numDomains); + + /* First we pause all VMs to make them stop dirtying + pages, etc. We remember if any VMs were paused so + we can restore that on resume. */ + for (i =3D 0; i < numDomains; i++) { + flags[i] =3D VIR_DOMAIN_SAVE_RUNNING; + if (virDomainGetState(domains[i], &state, NULL, 0) =3D=3D 0) { + if (state =3D=3D VIR_DOMAIN_PAUSED) + flags[i] =3D VIR_DOMAIN_SAVE_PAUSED; + } + virDomainSuspend(domains[i]); + } + + /* Then we save the VMs to disk */ + for (i =3D 0; i < numDomains; i++) + if (virDomainManagedSave(domains[i], flags[i]) < 0) + VIR_WARN("Unable to perform managed save of '%s': %s", + virDomainGetName(domains[i]), + virGetLastErrorMessage()); + + cleanup: + if (domains) { + for (i =3D 0; i < numDomains; i++) + virObjectUnref(domains[i]); + VIR_FREE(domains); + } +} diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index f81d436c2c..f36db5c6f0 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -90,3 +90,9 @@ typedef struct _virDomainDriverAutoStartConfig { =20 void virDomainDriverAutoStart(virDomainObjList *domains, virDomainDriverAutoStartConfig *cfg); + +typedef struct _virDomainDriverAutoShutdownConfig { + const char *uri; +} virDomainDriverAutoShutdownConfig; + +void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e63939e2b5..e6fec0a151 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1649,6 +1649,7 @@ virDomainCgroupSetupVcpuBW; =20 # hypervisor/domain_driver.h virDomainDriverAddIOThreadCheck; +virDomainDriverAutoShutdown; virDomainDriverAutoStart; virDomainDriverDelIOThreadCheck; virDomainDriverGenerateMachineName; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2364b4d312..14b128d268 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -944,51 +944,14 @@ qemuStateReload(void) static int qemuStateStop(void) { - int ret =3D -1; - g_autoptr(virConnect) conn =3D NULL; - int numDomains =3D 0; - size_t i; - int state; - virDomainPtr *domains =3D NULL; - g_autofree unsigned int *flags =3D NULL; g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(qemu_dri= ver); + virDomainDriverAutoShutdownConfig ascfg =3D { + .uri =3D cfg->uri, + }; =20 - if (!(conn =3D virConnectOpen(cfg->uri))) - goto cleanup; - - if ((numDomains =3D virConnectListAllDomains(conn, - &domains, - VIR_CONNECT_LIST_DOMAINS_AC= TIVE)) < 0) - goto cleanup; - - flags =3D g_new0(unsigned int, numDomains); - - /* First we pause all VMs to make them stop dirtying - pages, etc. We remember if any VMs were paused so - we can restore that on resume. */ - for (i =3D 0; i < numDomains; i++) { - flags[i] =3D VIR_DOMAIN_SAVE_RUNNING; - if (virDomainGetState(domains[i], &state, NULL, 0) =3D=3D 0) { - if (state =3D=3D VIR_DOMAIN_PAUSED) - flags[i] =3D VIR_DOMAIN_SAVE_PAUSED; - } - virDomainSuspend(domains[i]); - } - - ret =3D 0; - /* Then we save the VMs to disk */ - for (i =3D 0; i < numDomains; i++) - if (virDomainManagedSave(domains[i], flags[i]) < 0) - ret =3D -1; - - cleanup: - if (domains) { - for (i =3D 0; i < numDomains; i++) - virObjectUnref(domains[i]); - VIR_FREE(domains); - } + virDomainDriverAutoShutdown(&ascfg); =20 - return ret; + return 0; } =20 =20 --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 174180044872186.72081188470565; Wed, 12 Mar 2025 10:27:28 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id B46A41F83; Wed, 12 Mar 2025 13:27:27 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 3DB161F52; Wed, 12 Mar 2025 13:26:18 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id F329B1E62; Wed, 12 Mar 2025 13:26:12 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 7830D1F63 for ; Wed, 12 Mar 2025 13:25:37 -0400 (EDT) Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-534-ng9gZSb8NHOv68kH7b4drg-1; Wed, 12 Mar 2025 13:25:29 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E120218930C5 for ; Wed, 12 Mar 2025 17:18:07 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EF76C18001D4; Wed, 12 Mar 2025 17:18:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800337; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K9deI0AFJsAZCMmnuQN2LzyeECP74cBrhm5U4lP5KmE=; b=d6sY7P3thoHjyuzVLqHIakLUXIBqU7jd95ZpVdREA3jTuC7iAywoh0DSe7bzOXyvzX8XTs TzfBlwQZBUdqwV6pUZeShuK9ZyCxR83rsP9CLvHrKYYaVDfr8IUuJS3dwelT5DSGaqwemy Bw5Mf2MG0qbCHQTIcc/ZzSkzvkZqxyw= X-MC-Unique: ng9gZSb8NHOv68kH7b4drg-1 X-Mimecast-MFC-AGG-ID: ng9gZSb8NHOv68kH7b4drg_1741800328 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 02/22] remote: always invoke virStateStop for all daemons Date: Wed, 12 Mar 2025 17:17:42 +0000 Message-ID: <20250312171802.1854985-3-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: HDQV6rAKxiPqtsyZaFgof3BPoQf12JOfOynPbAvOpn8_1741800328 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 3Y47W2HAEWXLZCLZAN7CDXGLDDXXICJK X-Message-ID-Hash: 3Y47W2HAEWXLZCLZAN7CDXGLDDXXICJK X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800450170019100 Content-Type: text/plain; charset="utf-8" Currently the virStateStop method is only wired up to run save for the unprivileged daemons, so there is no functional change. IOW, session exit, or host OS shutdown will trigger VM managed saved for QEMU session daemon, but not the system daemon. This changes the daemon code to always run virStateStop for all daemons. Instead the QEMU driver is responsible for skipping its own logic when running privileged...for now. This means that virStateStop will now be triggered by logind's PrepareForShutdown signal. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/qemu_driver.c | 3 ++- src/remote/remote_daemon.c | 34 ++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 14b128d268..7e6ce5f69b 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -949,7 +949,8 @@ qemuStateStop(void) .uri =3D cfg->uri, }; =20 - virDomainDriverAutoShutdown(&ascfg); + if (!qemu_driver->privileged) + virDomainDriverAutoShutdown(&ascfg); =20 return 0; } diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index d90355c0d2..2f6cef1828 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -628,30 +628,32 @@ static void daemonRunStateInit(void *opaque) virStateShutdownPrepare, virStateShutdownWait); =20 - /* Tie the non-privileged daemons to the session/shutdown lifecycle */ + /* Signal for VM shutdown when desktop session is terminated, in + * unprivileged daemons */ if (!virNetDaemonIsPrivileged(dmn)) { - if (virGDBusHasSessionBus()) { sessionBus =3D virGDBusGetSessionBus(); if (sessionBus !=3D NULL) g_dbus_connection_add_filter(sessionBus, handleSessionMessageFunc, dmn= , NULL); } + } =20 - if (virGDBusHasSystemBus()) { - systemBus =3D virGDBusGetSystemBus(); - if (systemBus !=3D NULL) - g_dbus_connection_signal_subscribe(systemBus, - "org.freedesktop.login1= ", - "org.freedesktop.login1= .Manager", - "PrepareForShutdown", - NULL, - NULL, - G_DBUS_SIGNAL_FLAGS_NON= E, - handleSystemMessageFunc, - dmn, - NULL); - } + if (virGDBusHasSystemBus()) { + /* Signal for VM shutdown when host OS shutdown is requested, in + * both privileged and unprivileged daemons */ + systemBus =3D virGDBusGetSystemBus(); + if (systemBus !=3D NULL) + g_dbus_connection_signal_subscribe(systemBus, + "org.freedesktop.login1", + "org.freedesktop.login1.Man= ager", + "PrepareForShutdown", + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + handleSystemMessageFunc, + dmn, + NULL); } =20 /* Only now accept clients from network */ --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 174179993131724.955588558102477; Wed, 12 Mar 2025 10:18:51 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 3A68F1E4A; Wed, 12 Mar 2025 13:18:50 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 35BAF1A8D; Wed, 12 Mar 2025 13:18:16 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 652411A1B; Wed, 12 Mar 2025 13:18:12 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id BBEEB1659 for ; Wed, 12 Mar 2025 13:18:11 -0400 (EDT) Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-36-Ie29eHfhN7-lcw3-lo1LMg-1; Wed, 12 Mar 2025 13:18:10 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5BF9E1955D61 for ; Wed, 12 Mar 2025 17:18:09 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 66AAE18001DE; Wed, 12 Mar 2025 17:18:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799891; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cFOBi+/HxScqc1+RV6aHaOLKagCteIXU0Cz/YLEcW6Y=; b=GpvDZr0vRezTwa+tUdxIDbiZ4izslGkMC76xefBmJZ9qiUdxT8hboDtkEyGzNjOGIrqvPG si1iy7XesKmYVesQZvoHNIoXCDDUPdBYSHGJVWWimrCo5EGNj55Jgb+9wd81Pr9q63SmnQ MmzPO7FF03J83uIQCTxiUw8E6spY6c4= X-MC-Unique: Ie29eHfhN7-lcw3-lo1LMg-1 X-Mimecast-MFC-AGG-ID: Ie29eHfhN7-lcw3-lo1LMg_1741799889 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 03/22] hypervisor: expand available shutdown actions Date: Wed, 12 Mar 2025 17:17:43 +0000 Message-ID: <20250312171802.1854985-4-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: jV3oOOO6_GEF6hX_XTy9bHKPULt5VAf9UUktxECIUJI_1741799889 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 7XFNSLS3L5USZSISSDZ6GE47INKZSUEK X-Message-ID-Hash: 7XFNSLS3L5USZSISSDZ6GE47INKZSUEK X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741799933150019100 Content-Type: text/plain; charset="utf-8" The auto shutdown code can currently only perform managed save, which may fail in some cases, for example when PCI devices are assigned. On failure, shutdown inhibitors remain in place which may be undesirable. This expands the logic to try a sequence of operations * Managed save * Graceful shutdown * Forced poweroff Each of these operations can be enabled or disabled, but they are always applied in this order. With the shutdown option, a configurable time is allowed for shutdown to complete, defaulting to 30 seconds, before moving onto the forced poweroff phase. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/hypervisor/domain_driver.c | 130 ++++++++++++++++++++++++++++----- src/hypervisor/domain_driver.h | 7 ++ src/qemu/qemu_driver.c | 3 + 3 files changed, 121 insertions(+), 19 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index 0ca482275f..e625726c07 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -720,9 +720,25 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) g_autoptr(virConnect) conn =3D NULL; int numDomains =3D 0; size_t i; - int state; virDomainPtr *domains =3D NULL; - g_autofree unsigned int *flags =3D NULL; + + VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%d tryShutdown=3D%d pow= eroff=3D%d waitShutdownSecs=3D%u", + cfg->uri, cfg->trySave, cfg->tryShutdown, cfg->poweroff, + cfg->waitShutdownSecs); + + /* + * Ideally guests will shutdown in a few seconds, but it would + * not be unsual for it to take a while longer, especially under + * load, or if the guest OS has inhibitors slowing down shutdown. + * + * If we wait too long, then guests which ignore the shutdown + * request will significantly delay host shutdown. + * + * Pick 30 seconds as a moderately safe default, assuming that + * most guests are well behaved. + */ + if (cfg->waitShutdownSecs <=3D 0) + cfg->waitShutdownSecs =3D 30; =20 if (!(conn =3D virConnectOpen(cfg->uri))) goto cleanup; @@ -732,31 +748,107 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutd= ownConfig *cfg) VIR_CONNECT_LIST_DOMAINS_AC= TIVE)) < 0) goto cleanup; =20 - flags =3D g_new0(unsigned int, numDomains); + VIR_DEBUG("Auto shutdown with %d running domains", numDomains); + if (cfg->trySave) { + g_autofree unsigned int *flags =3D g_new0(unsigned int, numDomains= ); + for (i =3D 0; i < numDomains; i++) { + int state; + /* + * Pause all VMs to make them stop dirtying pages, + * so save is quicker. We remember if any VMs were + * paused so we can restore that on resume. + */ + flags[i] =3D VIR_DOMAIN_SAVE_RUNNING; + if (virDomainGetState(domains[i], &state, NULL, 0) =3D=3D 0) { + if (state =3D=3D VIR_DOMAIN_PAUSED) + flags[i] =3D VIR_DOMAIN_SAVE_PAUSED; + } + if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) + virDomainSuspend(domains[i]); + } + + for (i =3D 0; i < numDomains; i++) { + if (virDomainManagedSave(domains[i], flags[i]) < 0) { + VIR_WARN("Unable to perform managed save of '%s': %s", + virDomainGetName(domains[i]), + virGetLastErrorMessage()); + if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) + virDomainResume(domains[i]); + continue; + } + virObjectUnref(domains[i]); + domains[i] =3D NULL; + } + } + + if (cfg->tryShutdown) { + GTimer *timer =3D NULL; + for (i =3D 0; i < numDomains; i++) { + if (domains[i] =3D=3D NULL) + continue; + if (virDomainShutdown(domains[i]) < 0) { + VIR_WARN("Unable to request graceful shutdown of '%s': %s", + virDomainGetName(domains[i]), + virGetLastErrorMessage()); + break; + } + } + + timer =3D g_timer_new(); + while (1) { + bool anyRunning =3D false; + for (i =3D 0; i < numDomains; i++) { + if (!domains[i]) + continue; =20 - /* First we pause all VMs to make them stop dirtying - pages, etc. We remember if any VMs were paused so - we can restore that on resume. */ - for (i =3D 0; i < numDomains; i++) { - flags[i] =3D VIR_DOMAIN_SAVE_RUNNING; - if (virDomainGetState(domains[i], &state, NULL, 0) =3D=3D 0) { - if (state =3D=3D VIR_DOMAIN_PAUSED) - flags[i] =3D VIR_DOMAIN_SAVE_PAUSED; + if (virDomainIsActive(domains[i]) =3D=3D 1) { + anyRunning =3D true; + } else { + virObjectUnref(domains[i]); + domains[i] =3D NULL; + } + } + + if (!anyRunning) + break; + if (g_timer_elapsed(timer, NULL) > cfg->waitShutdownSecs) + break; + g_usleep(1000*500); } - virDomainSuspend(domains[i]); + g_timer_destroy(timer); } =20 - /* Then we save the VMs to disk */ - for (i =3D 0; i < numDomains; i++) - if (virDomainManagedSave(domains[i], flags[i]) < 0) - VIR_WARN("Unable to perform managed save of '%s': %s", - virDomainGetName(domains[i]), - virGetLastErrorMessage()); + if (cfg->poweroff) { + for (i =3D 0; i < numDomains; i++) { + if (domains[i] =3D=3D NULL) + continue; + /* + * NB might fail if we gave up on waiting for + * virDomainShutdown, but it then completed anyway, + * hence we're not checking for failure + */ + virDomainDestroy(domains[i]); + + virObjectUnref(domains[i]); + domains[i] =3D NULL; + } + } =20 cleanup: if (domains) { - for (i =3D 0; i < numDomains; i++) + /* Anything non-NULL in this list indicates none of + * the configured ations were successful in processing + * the domain. There's not much we can do about that + * as the host is powering off, logging at least lets + * admins know + */ + for (i =3D 0; i < numDomains; i++) { + if (domains[i] =3D=3D NULL) + continue; + VIR_WARN("Domain '%s' not successfully shut off by any action", + virDomainGetName(domains[i])); virObjectUnref(domains[i]); + } VIR_FREE(domains); } } diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index f36db5c6f0..ff68517edd 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -93,6 +93,13 @@ void virDomainDriverAutoStart(virDomainObjList *domains, =20 typedef struct _virDomainDriverAutoShutdownConfig { const char *uri; + bool trySave; + bool tryShutdown; + bool poweroff; + unsigned int waitShutdownSecs; /* Seconds to wait for VM to shutdown + * before moving onto next action. + * If 0 a default is used (currently 30= secs) + */ } virDomainDriverAutoShutdownConfig; =20 void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7e6ce5f69b..946f1c7e96 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -947,6 +947,9 @@ qemuStateStop(void) g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(qemu_dri= ver); virDomainDriverAutoShutdownConfig ascfg =3D { .uri =3D cfg->uri, + .trySave =3D true, + .tryShutdown =3D false, + .poweroff =3D false, }; =20 if (!qemu_driver->privileged) --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800422101115.24737660901712; Wed, 12 Mar 2025 10:27:02 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 18FA61275; Wed, 12 Mar 2025 13:27:01 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id D8B101A78; Wed, 12 Mar 2025 13:26:12 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 8CA02BC2; Wed, 12 Mar 2025 13:26:05 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 13C821DB1 for ; Wed, 12 Mar 2025 13:25:37 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-549-sW4FtbXVP8iCkB1tJgNwaA-1; Wed, 12 Mar 2025 13:25:35 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C0254190756D for ; Wed, 12 Mar 2025 17:18:10 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E84B9180174E; Wed, 12 Mar 2025 17:18:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800336; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+aMOLhWk2ePjZ9GSX6hLX9hb+/ktPNT883aDXPXekqc=; b=iZV8Rz6LvpqbFZdleASdq3ACjtNgMco3gPxmYEnKxfvASAtApJYeqVNs8BnVq5RzbzuqdX K2G+Gt8czeqlY/MCJavPGbhwzX/g0bkKYcDp3MHuvnQbGdPQmhIvwfdHZjyJfqRW3rRBiN O9KscYDOyh8+XZI/TbdihlNChNn1wwU= X-MC-Unique: sW4FtbXVP8iCkB1tJgNwaA-1 X-Mimecast-MFC-AGG-ID: sW4FtbXVP8iCkB1tJgNwaA_1741800334 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 04/22] hypervisor: custom shutdown actions for transient vs persistent VMs Date: Wed, 12 Mar 2025 17:17:44 +0000 Message-ID: <20250312171802.1854985-5-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 9RkFruOJxClBVM2J4hxGXdijhZbUICbCBRsRksh1o5A_1741800334 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: JBQGTR47ZIMOTOTHJNIOX5AF4NJRUMHB X-Message-ID-Hash: JBQGTR47ZIMOTOTHJNIOX5AF4NJRUMHB X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800424231019100 Content-Type: text/plain; charset="utf-8" It may be desirable to treat transient VMs differently from persistent VMs. For example, while performing managed save on persistent VMs makes sense, the same not usually true of transient VMs, since by their nature they will have no config to restore from. This also lets us fix a long standing problem with incorrectly attempting to perform managed save on transient VMs. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/hypervisor/domain_driver.c | 62 +++++++++++++++++++++++++++++++--- src/hypervisor/domain_driver.h | 18 ++++++++-- src/libvirt_private.syms | 2 ++ src/qemu/qemu_driver.c | 6 ++-- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index e625726c07..c510e1d2ae 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -35,6 +35,13 @@ =20 VIR_LOG_INIT("hypervisor.domain_driver"); =20 +VIR_ENUM_IMPL(virDomainDriverAutoShutdownScope, + VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_LAST, + "none", + "persistent", + "transient", + "all"); + char * virDomainDriverGenerateRootHash(const char *drivername, const char *root) @@ -721,9 +728,13 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) int numDomains =3D 0; size_t i; virDomainPtr *domains =3D NULL; + g_autofree bool *transient =3D NULL; =20 - VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%d tryShutdown=3D%d pow= eroff=3D%d waitShutdownSecs=3D%u", - cfg->uri, cfg->trySave, cfg->tryShutdown, cfg->poweroff, + VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%s tryShutdown=3D%s pow= eroff=3D%s waitShutdownSecs=3D%u", + cfg->uri, + virDomainDriverAutoShutdownScopeTypeToString(cfg->trySave), + virDomainDriverAutoShutdownScopeTypeToString(cfg->tryShutdow= n), + virDomainDriverAutoShutdownScopeTypeToString(cfg->poweroff), cfg->waitShutdownSecs); =20 /* @@ -740,6 +751,21 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) if (cfg->waitShutdownSecs <=3D 0) cfg->waitShutdownSecs =3D 30; =20 + /* Short-circuit if all actions are disabled */ + if (cfg->trySave =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE && + cfg->tryShutdown =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE= && + cfg->poweroff =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) + return; + + if (cfg->trySave =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || + cfg->trySave =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIEN= T) { + /* virDomainManagedSave will return an error. We'll let + * the code run, since it'll just fall through to the next + * actions, but give a clear warning upfront */ + VIR_WARN("Managed save not supported for transient VMs"); + return; + } + if (!(conn =3D virConnectOpen(cfg->uri))) goto cleanup; =20 @@ -749,10 +775,22 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdo= wnConfig *cfg) goto cleanup; =20 VIR_DEBUG("Auto shutdown with %d running domains", numDomains); - if (cfg->trySave) { + + transient =3D g_new0(bool, numDomains); + for (i =3D 0; i < numDomains; i++) { + if (virDomainIsPersistent(domains[i]) =3D=3D 0) + transient[i] =3D true; + } + + if (cfg->trySave !=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { g_autofree unsigned int *flags =3D g_new0(unsigned int, numDomains= ); for (i =3D 0; i < numDomains; i++) { int state; + + if ((transient[i] && cfg->trySave =3D=3D VIR_DOMAIN_DRIVER_AUT= O_SHUTDOWN_SCOPE_PERSISTENT) || + (!transient[i] && cfg->trySave =3D=3D VIR_DOMAIN_DRIVER_AU= TO_SHUTDOWN_SCOPE_TRANSIENT)) + continue; + /* * Pause all VMs to make them stop dirtying pages, * so save is quicker. We remember if any VMs were @@ -781,11 +819,16 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdo= wnConfig *cfg) } } =20 - if (cfg->tryShutdown) { + if (cfg->tryShutdown !=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { GTimer *timer =3D NULL; for (i =3D 0; i < numDomains; i++) { if (domains[i] =3D=3D NULL) continue; + + if ((transient[i] && cfg->tryShutdown =3D=3D VIR_DOMAIN_DRIVER= _AUTO_SHUTDOWN_SCOPE_PERSISTENT) || + (!transient[i] && cfg->tryShutdown =3D=3D VIR_DOMAIN_DRIVE= R_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) + continue; + if (virDomainShutdown(domains[i]) < 0) { VIR_WARN("Unable to request graceful shutdown of '%s': %s", virDomainGetName(domains[i]), @@ -801,6 +844,10 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) if (!domains[i]) continue; =20 + if ((transient[i] && cfg->tryShutdown =3D=3D VIR_DOMAIN_DR= IVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || + (!transient[i] && cfg->tryShutdown =3D=3D VIR_DOMAIN_D= RIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) + continue; + if (virDomainIsActive(domains[i]) =3D=3D 1) { anyRunning =3D true; } else { @@ -818,10 +865,15 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdo= wnConfig *cfg) g_timer_destroy(timer); } =20 - if (cfg->poweroff) { + if (cfg->poweroff !=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { for (i =3D 0; i < numDomains; i++) { if (domains[i] =3D=3D NULL) continue; + + if ((transient[i] && cfg->poweroff =3D=3D VIR_DOMAIN_DRIVER_AU= TO_SHUTDOWN_SCOPE_PERSISTENT) || + (!transient[i] && cfg->poweroff =3D=3D VIR_DOMAIN_DRIVER_A= UTO_SHUTDOWN_SCOPE_TRANSIENT)) + continue; + /* * NB might fail if we gave up on waiting for * virDomainShutdown, but it then completed anyway, diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index ff68517edd..6e535ca444 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -24,6 +24,7 @@ #include "virhostdev.h" #include "virpci.h" #include "virdomainobjlist.h" +#include "virenum.h" =20 char * virDomainDriverGenerateRootHash(const char *drivername, @@ -91,11 +92,22 @@ typedef struct _virDomainDriverAutoStartConfig { void virDomainDriverAutoStart(virDomainObjList *domains, virDomainDriverAutoStartConfig *cfg); =20 +typedef enum { + VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE, + VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT, + VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT, + VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL, + + VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_LAST, +} virDomainDriverAutoShutdownScope; + +VIR_ENUM_DECL(virDomainDriverAutoShutdownScope); + typedef struct _virDomainDriverAutoShutdownConfig { const char *uri; - bool trySave; - bool tryShutdown; - bool poweroff; + virDomainDriverAutoShutdownScope trySave; + virDomainDriverAutoShutdownScope tryShutdown; + virDomainDriverAutoShutdownScope poweroff; unsigned int waitShutdownSecs; /* Seconds to wait for VM to shutdown * before moving onto next action. * If 0 a default is used (currently 30= secs) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e6fec0a151..5f3aa10371 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1650,6 +1650,8 @@ virDomainCgroupSetupVcpuBW; # hypervisor/domain_driver.h virDomainDriverAddIOThreadCheck; virDomainDriverAutoShutdown; +virDomainDriverAutoShutdownScopeTypeFromString; +virDomainDriverAutoShutdownScopeTypeToString; virDomainDriverAutoStart; virDomainDriverDelIOThreadCheck; virDomainDriverGenerateMachineName; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 946f1c7e96..ec389453e7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -947,9 +947,9 @@ qemuStateStop(void) g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(qemu_dri= ver); virDomainDriverAutoShutdownConfig ascfg =3D { .uri =3D cfg->uri, - .trySave =3D true, - .tryShutdown =3D false, - .poweroff =3D false, + .trySave =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT, + .tryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE, + .poweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE }; =20 if (!qemu_driver->privileged) --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741799972972718.4053189041814; Wed, 12 Mar 2025 10:19:32 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id E35ED1CC7; Wed, 12 Mar 2025 13:19:31 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 671D11C39; Wed, 12 Mar 2025 13:18:20 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id ED21A1AC5; Wed, 12 Mar 2025 13:18:15 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id EECBE1A12 for ; Wed, 12 Mar 2025 13:18:14 -0400 (EDT) Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-457-arW7pMVFPaqFTUPIEp4Sew-1; Wed, 12 Mar 2025 13:18:13 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 503131954B36 for ; Wed, 12 Mar 2025 17:18:12 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2D41718001D4; Wed, 12 Mar 2025 17:18:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799894; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l7GOHc8kUHsRjvGZbrlsBwgNghnb5dXSLg23DtFgLYU=; b=WTwd2unM5srWQthNMwloE2gbBkkAMey39yGiNOgh/z0qdCG0DIHG5013FW72blqy/ilVk0 IUzguRQxI+OZRczY/k8SYniusT5rkr++NKnXN3Wwa8RfoKty2eEcPmyitJ6RQG9vYiqC6s TD12h+6hGR7XCiPAQOMa8e1jzpuVE2A= X-MC-Unique: arW7pMVFPaqFTUPIEp4Sew-1 X-Mimecast-MFC-AGG-ID: arW7pMVFPaqFTUPIEp4Sew_1741799892 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 05/22] qemu: support automatic VM managed save in system daemon Date: Wed, 12 Mar 2025 17:17:45 +0000 Message-ID: <20250312171802.1854985-6-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: VSTRT8oEMCwWgx3cK3ilmVigBcJzHoOHJbswkCVj3Bs_1741799892 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: QOEZRZDQ75WTTQF2HKY4FSANGXX26F5S X-Message-ID-Hash: QOEZRZDQ75WTTQF2HKY4FSANGXX26F5S X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741799975113019100 Content-Type: text/plain; charset="utf-8" Currently automatic VM managed save is only performed in session daemons, on desktop session close, or host OS shutdown request. With this change it is possible to control shutdown behaviour for all daemons. A recommended setup might be: auto_shutdown_try_save =3D "persistent" auto_shutdown_try_shutdown =3D "all" auto_shutdown_poweroff =3D "all" Each setting accepts 'none', 'persistent', 'transient', and 'all' to control what types of guest it applies to. For historical compatibility, for the system daemon, the settings currently default to: auto_shutdown_try_save =3D "none" auto_shutdown_try_shutdown =3D "none" auto_shutdown_poweroff =3D "none" while for the session daemon they currently default to auto_shutdown_try_save =3D "persistent" auto_shutdown_try_shutdown =3D "none" auto_shutdown_poweroff =3D "none" The system daemon settings should NOT be enabled if the traditional libvirt-guests.service is already enabled. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/qemu/libvirtd_qemu.aug | 3 ++ src/qemu/qemu.conf.in | 42 +++++++++++++++++++ src/qemu/qemu_conf.c | 65 ++++++++++++++++++++++++++++++ src/qemu/qemu_conf.h | 4 ++ src/qemu/qemu_driver.c | 9 ++--- src/qemu/test_libvirtd_qemu.aug.in | 3 ++ 6 files changed, 121 insertions(+), 5 deletions(-) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 642093c40b..605604a01a 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -98,6 +98,9 @@ module Libvirtd_qemu =3D | bool_entry "auto_dump_bypass_cache" | bool_entry "auto_start_bypass_cache" | int_entry "auto_start_delay" + | str_entry "auto_shutdown_try_save" + | str_entry "auto_shutdown_try_shutdown" + | str_entry "auto_shutdown_poweroff" =20 let process_entry =3D str_entry "hugetlbfs_mount" | str_entry "bridge_helper" diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in index 31172303dc..a674e11388 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -639,6 +639,48 @@ # #auto_start_delay =3D 0 =20 +# The settings for auto shutdown actions accept one of +# four possible options: +# +# * "none" - do not try to save any running VMs +# * "persistent" - only try to save persistent running VMs +# * "transient" - only try to save transient running VMs +# * "all" - try to save all running VMs +# +# Whether to perform managed save of running VMs if a host OS +# shutdown is requested (system/session daemons), or the desktop +# session terminates (session daemon only). +# +# Defaults to "persistent" for session daemons and "none" +# for system daemons. The values "all" and "transient" are +# not permitted for this setting, since managed save is not +# implemented for transient VMs. +# +# If 'libvirt-guests.service' is enabled, then this must be +# set to 'none' for system daemons to avoid dueling actions +#auto_shutdown_try_save =3D "persistent" + +# As above, but with a graceful shutdown action instead of +# managed save. If managed save is enabled, shutdown will +# be tried only on failure to perform managed save. +# +# Defaults to "none" +# +# If 'libvirt-guests.service' is enabled, then this must be +# set to 'none' for system daemons to avoid dueling actions +#auto_shutdown_try_shutdown =3D "none" + +# As above, but with a forced poweroff instead of managed +# save. If managed save or graceful shutdown are enabled, +# forced poweroff will be tried only on failure of the +# other options. +# +# Defaults to "none" +# +# If 'libvirt-guests.service' is enabled, then this must be +# set to 'none' for system daemons to avoid dueling actions +#auto_shutdown_poweroff =3D "none" + # If provided by the host and a hugetlbfs mount point is configured, # a guest may request huge page backing. When this mount point is # unspecified here, determination of a host mount point in /proc/mounts diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b376841388..8554558201 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -304,6 +304,21 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privi= leged, cfg->dumpGuestCore =3D true; #endif =20 + if (privileged) { + /* + * Defer to libvirt-guests.service. + * + * XXX, or query if libvirt-guests.service is enabled perhaps ? + */ + cfg->autoShutdownTrySave =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE= _NONE; + cfg->autoShutdownTryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_S= COPE_NONE; + cfg->autoShutdownPoweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOP= E_NONE; + } else { + cfg->autoShutdownTrySave =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE= _PERSISTENT; + cfg->autoShutdownTryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_S= COPE_NONE; + cfg->autoShutdownPoweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOP= E_NONE; + } + return g_steal_pointer(&cfg); } =20 @@ -627,6 +642,8 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *c= fg, g_autofree char *savestr =3D NULL; g_autofree char *dumpstr =3D NULL; g_autofree char *snapstr =3D NULL; + g_autofree char *autoShutdownScope =3D NULL; + int autoShutdownScopeVal; =20 if (virConfGetValueString(conf, "save_image_format", &savestr) < 0) return -1; @@ -663,6 +680,54 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *= cfg, return -1; if (virConfGetValueUInt(conf, "auto_start_delay", &cfg->autoStartDelay= MS) < 0) return -1; + if (virConfGetValueString(conf, "auto_shutdown_try_save", &autoShutdow= nScope) < 0) + return -1; + + if (autoShutdownScope !=3D NULL) { + if ((autoShutdownScopeVal =3D + virDomainDriverAutoShutdownScopeTypeFromString(autoShutdownSc= ope)) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown auto_shutdown_try_save '%1$s'"), + autoShutdownScope); + return -1; + } + cfg->autoShutdownTrySave =3D autoShutdownScopeVal; + } + + if (cfg->autoShutdownTrySave =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SC= OPE_ALL || + cfg->autoShutdownTrySave =3D=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SC= OPE_TRANSIENT) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("managed save cannot be requested for transient d= omains")); + return -1; + } + + if (virConfGetValueString(conf, "auto_shutdown_try_shutdown", &autoShu= tdownScope) < 0) + return -1; + + if (autoShutdownScope !=3D NULL) { + if ((autoShutdownScopeVal =3D + virDomainDriverAutoShutdownScopeTypeFromString(autoShutdownSc= ope)) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown auto_shutdown_try_shutdown '%1$s'"), + autoShutdownScope); + return -1; + } + cfg->autoShutdownTryShutdown =3D autoShutdownScopeVal; + } + + if (virConfGetValueString(conf, "auto_shutdown_poweroff", &autoShutdow= nScope) < 0) + return -1; + + if (autoShutdownScope !=3D NULL) { + if ((autoShutdownScopeVal =3D + virDomainDriverAutoShutdownScopeTypeFromString(autoShutdownSc= ope)) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown auto_shutdown_poweroff '%1$s'"), + autoShutdownScope); + return -1; + } + cfg->autoShutdownPoweroff =3D autoShutdownScopeVal; + } =20 return 0; } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 3e1b41af73..3450f277f0 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -43,6 +43,7 @@ #include "virfilecache.h" #include "virfirmware.h" #include "virinhibitor.h" +#include "domain_driver.h" =20 #define QEMU_DRIVER_NAME "QEMU" =20 @@ -201,6 +202,9 @@ struct _virQEMUDriverConfig { bool autoDumpBypassCache; bool autoStartBypassCache; unsigned int autoStartDelayMS; + virDomainDriverAutoShutdownScope autoShutdownTrySave; + virDomainDriverAutoShutdownScope autoShutdownTryShutdown; + virDomainDriverAutoShutdownScope autoShutdownPoweroff; =20 char *lockManagerName; =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ec389453e7..cb7b03e391 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -947,13 +947,12 @@ qemuStateStop(void) g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(qemu_dri= ver); virDomainDriverAutoShutdownConfig ascfg =3D { .uri =3D cfg->uri, - .trySave =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT, - .tryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE, - .poweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE + .trySave =3D cfg->autoShutdownTrySave, + .tryShutdown =3D cfg->autoShutdownTryShutdown, + .poweroff =3D cfg->autoShutdownPoweroff, }; =20 - if (!qemu_driver->privileged) - virDomainDriverAutoShutdown(&ascfg); + virDomainDriverAutoShutdown(&ascfg); =20 return 0; } diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index c2a1d7d829..bb216483a7 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -76,6 +76,9 @@ module Test_libvirtd_qemu =3D { "auto_dump_bypass_cache" =3D "0" } { "auto_start_bypass_cache" =3D "0" } { "auto_start_delay" =3D "0" } +{ "auto_shutdown_try_save" =3D "persistent" } +{ "auto_shutdown_try_shutdown" =3D "none" } +{ "auto_shutdown_poweroff" =3D "none" } { "hugetlbfs_mount" =3D "/dev/hugepages" } { "bridge_helper" =3D "qemu-bridge-helper" } { "set_process_name" =3D "1" } --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800472572144.3409776165331; Wed, 12 Mar 2025 10:27:52 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id EBA981E6E; Wed, 12 Mar 2025 13:27:51 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 78A4D1F64; Wed, 12 Mar 2025 13:26:28 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 8982E1F0B; Wed, 12 Mar 2025 13:26:22 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id EDDD31B45 for ; Wed, 12 Mar 2025 13:25:40 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-396-KOYpcbUEO1KvMir5zIYRUA-1; Wed, 12 Mar 2025 13:25:39 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D206F190A28C for ; Wed, 12 Mar 2025 17:18:13 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C903918001DE; Wed, 12 Mar 2025 17:18:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800340; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YcXwwckCMyA/RTNh9fCC31QZBIOMxAiH9NOoskixP0o=; b=gwNt0aPSxjU1E+0knSNnIYFSxrKEpRaFuG+0mnAabyzlWiel8oL6XvrU+PSubOivb023yD E/UeP4pBvtE5d1W2A/kd3HZPC2IAE1DzYgvoK0327eauvLgcxd3FrPMpd0g6HundhqDcwr ZTa6jBSa5EE+9YPUrovZ8uw0dMX6W4U= X-MC-Unique: KOYpcbUEO1KvMir5zIYRUA-1 X-Mimecast-MFC-AGG-ID: KOYpcbUEO1KvMir5zIYRUA_1741800338 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 06/22] qemu: improve shutdown defaults for session daemon Date: Wed, 12 Mar 2025 17:17:46 +0000 Message-ID: <20250312171802.1854985-7-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: y0-a8RUX8vBs-2DYfnXIqQaUPpV35mkocSDtwyJtT5Q_1741800338 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: ZMBE2KU7VLU2P34F7GQLAJ25BP66ZW3W X-Message-ID-Hash: ZMBE2KU7VLU2P34F7GQLAJ25BP66ZW3W X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800474208019000 Content-Type: text/plain; charset="utf-8" Currently the session daemon will try a managed save on all VMs, leaving them running if that fails. This limits the managed save just to persistent VMs, as there will usually not be any way to restore transient VMs later. It also enables graceful shutdown and then forced poweroff, should save fail for some reason. These new defaults can be overridden in the config file if needed. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/qemu.conf.in | 10 ++++++---- src/qemu/qemu_conf.c | 4 ++-- src/qemu/test_libvirtd_qemu.aug.in | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in index a674e11388..c9bebf1e7d 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -664,22 +664,24 @@ # managed save. If managed save is enabled, shutdown will # be tried only on failure to perform managed save. # -# Defaults to "none" +# Defaults to "all" for session daemons and "none" for +# system daemons # # If 'libvirt-guests.service' is enabled, then this must be # set to 'none' for system daemons to avoid dueling actions -#auto_shutdown_try_shutdown =3D "none" +#auto_shutdown_try_shutdown =3D "all" =20 # As above, but with a forced poweroff instead of managed # save. If managed save or graceful shutdown are enabled, # forced poweroff will be tried only on failure of the # other options. # -# Defaults to "none" +# Defaults to "all" for session daemons and "none" for +# system daemons. # # If 'libvirt-guests.service' is enabled, then this must be # set to 'none' for system daemons to avoid dueling actions -#auto_shutdown_poweroff =3D "none" +#auto_shutdown_poweroff =3D "all" =20 # If provided by the host and a hugetlbfs mount point is configured, # a guest may request huge page backing. When this mount point is diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 8554558201..f069ed00b1 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -315,8 +315,8 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privil= eged, cfg->autoShutdownPoweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOP= E_NONE; } else { cfg->autoShutdownTrySave =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE= _PERSISTENT; - cfg->autoShutdownTryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_S= COPE_NONE; - cfg->autoShutdownPoweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOP= E_NONE; + cfg->autoShutdownTryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_S= COPE_ALL; + cfg->autoShutdownPoweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOP= E_ALL; } =20 return g_steal_pointer(&cfg); diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index bb216483a7..3bc8104d7a 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -77,8 +77,8 @@ module Test_libvirtd_qemu =3D { "auto_start_bypass_cache" =3D "0" } { "auto_start_delay" =3D "0" } { "auto_shutdown_try_save" =3D "persistent" } -{ "auto_shutdown_try_shutdown" =3D "none" } -{ "auto_shutdown_poweroff" =3D "none" } +{ "auto_shutdown_try_shutdown" =3D "all" } +{ "auto_shutdown_poweroff" =3D "all" } { "hugetlbfs_mount" =3D "/dev/hugepages" } { "bridge_helper" =3D "qemu-bridge-helper" } { "set_process_name" =3D "1" } --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800035808488.3200757247979; Wed, 12 Mar 2025 10:20:35 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 37E811C39; Wed, 12 Mar 2025 13:20:35 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 063171E53; Wed, 12 Mar 2025 13:18:35 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 643501D1A; Wed, 12 Mar 2025 13:18:30 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id E398D1D1A for ; Wed, 12 Mar 2025 13:18:17 -0400 (EDT) Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-332-d-SeZI43MBWF8oiyQFhBtg-1; Wed, 12 Mar 2025 13:18:16 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 628F819560BE for ; Wed, 12 Mar 2025 17:18:15 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5794818001DE; Wed, 12 Mar 2025 17:18:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799897; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EKaNWEtfDZPmmIcd5O/dDaSbbO6TEF/+bHlgM8yDIkA=; b=Or/Eo7ewc23d1AJAepHaTeT++NnsczrLaKd2orU8nlVhp2XerdFk7j/cAdV2b58OibMEOc ZZVGGofChW5J/2wUIe5OZwC/+5D0B5bRQabWCG6FNt9B+FBBOmGKTGaqfBhS9LOJwJGcwC x2ReHBzLASdlzB6b2YruKczAd2fHqaM= X-MC-Unique: d-SeZI43MBWF8oiyQFhBtg-1 X-Mimecast-MFC-AGG-ID: d-SeZI43MBWF8oiyQFhBtg_1741799895 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 07/22] qemu: configurable delay for shutdown before poweroff Date: Wed, 12 Mar 2025 17:17:47 +0000 Message-ID: <20250312171802.1854985-8-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ULd8DQwPYCEc0NS-dtSO6U0kf8HMOk_g6dNIr1trIHQ_1741799895 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: NFHX6PXNLCVSX74WZ5FQCOJLKEBCYM5L X-Message-ID-Hash: NFHX6PXNLCVSX74WZ5FQCOJLKEBCYM5L X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800038084019000 Content-Type: text/plain; charset="utf-8" Allow users to control how many seconds libvirt waits for QEMU shutdown before force powering off a guest. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf.in | 6 ++++++ src/qemu/qemu_conf.c | 4 ++++ src/qemu/qemu_conf.h | 1 + src/qemu/qemu_driver.c | 1 + src/qemu/test_libvirtd_qemu.aug.in | 1 + 6 files changed, 14 insertions(+) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 605604a01a..8cb1b144b9 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -101,6 +101,7 @@ module Libvirtd_qemu =3D | str_entry "auto_shutdown_try_save" | str_entry "auto_shutdown_try_shutdown" | str_entry "auto_shutdown_poweroff" + | int_entry "auto_shutdown_wait" =20 let process_entry =3D str_entry "hugetlbfs_mount" | str_entry "bridge_helper" diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in index c9bebf1e7d..5a9bfd90e8 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -683,6 +683,12 @@ # set to 'none' for system daemons to avoid dueling actions #auto_shutdown_poweroff =3D "all" =20 +# How may seconds to wait for running VMs to gracefully shutdown +# when 'auto_shutdown_try_shutdown' is enabled. If set to 0 +# then an arbitrary built-in default value will be used (which +# is currently 30 secs) +#auto_shutdown_wait =3D 30 + # If provided by the host and a hugetlbfs mount point is configured, # a guest may request huge page backing. When this mount point is # unspecified here, determination of a host mount point in /proc/mounts diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index f069ed00b1..d1ae5fa308 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -729,6 +729,10 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *= cfg, cfg->autoShutdownPoweroff =3D autoShutdownScopeVal; } =20 + if (virConfGetValueUInt(conf, "auto_shutdown_wait", + &cfg->autoShutdownWait) < 0) + return -1; + return 0; } =20 diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 3450f277f0..f6fcfe444d 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -205,6 +205,7 @@ struct _virQEMUDriverConfig { virDomainDriverAutoShutdownScope autoShutdownTrySave; virDomainDriverAutoShutdownScope autoShutdownTryShutdown; virDomainDriverAutoShutdownScope autoShutdownPoweroff; + unsigned int autoShutdownWait; =20 char *lockManagerName; =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cb7b03e391..08e2248852 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -950,6 +950,7 @@ qemuStateStop(void) .trySave =3D cfg->autoShutdownTrySave, .tryShutdown =3D cfg->autoShutdownTryShutdown, .poweroff =3D cfg->autoShutdownPoweroff, + .waitShutdownSecs =3D cfg->autoShutdownWait, }; =20 virDomainDriverAutoShutdown(&ascfg); diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index 3bc8104d7a..4c6de31199 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -79,6 +79,7 @@ module Test_libvirtd_qemu =3D { "auto_shutdown_try_save" =3D "persistent" } { "auto_shutdown_try_shutdown" =3D "all" } { "auto_shutdown_poweroff" =3D "all" } +{ "auto_shutdown_wait" =3D "30" } { "hugetlbfs_mount" =3D "/dev/hugepages" } { "bridge_helper" =3D "qemu-bridge-helper" } { "set_process_name" =3D "1" } --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800055038851.3401659586362; Wed, 12 Mar 2025 10:20:55 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 65B681EA5; Wed, 12 Mar 2025 13:20:54 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 90DD81E67; Wed, 12 Mar 2025 13:18:39 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 1851A1AC4; Wed, 12 Mar 2025 13:18:35 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 0294C1AF3 for ; Wed, 12 Mar 2025 13:18:19 -0400 (EDT) Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-172-j60Lu-x2MaCIDzQ52axhZQ-1; Wed, 12 Mar 2025 13:18:17 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E5D061955D61 for ; Wed, 12 Mar 2025 17:18:16 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D95A818001D4; Wed, 12 Mar 2025 17:18:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799899; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OVhduHm6kP4aRuJfATRwvPM2l/6BtjvAPcaYJHUERRY=; b=FzLdQtuOpvQFuWQoO45EsJ8EqDOaPMOcPNJozTx9cbhmBc9PuGwi8WQoB6MePDhbuDIk2f B19S/fiFTKhy1P//vLuev2ib9EdK9U2++2BnfopaI2qexwUSOOn4ki1KNrHy7848u14wBa sqR4fF2m222Y8V+ZGBe5Rw9xnQSCIAE= X-MC-Unique: j60Lu-x2MaCIDzQ52axhZQ-1 X-Mimecast-MFC-AGG-ID: j60Lu-x2MaCIDzQ52axhZQ_1741799897 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 08/22] hypervisor: support bypassing cache for managed save Date: Wed, 12 Mar 2025 17:17:48 +0000 Message-ID: <20250312171802.1854985-9-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Tt1oeLDXQQkaqUH8Kz8210mHG_sSROVPIwgZFzfkMmk_1741799897 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 6O2SESVA44FM7YXBQQ2SIFILVVAZ7WOQ X-Message-ID-Hash: 6O2SESVA44FM7YXBQQ2SIFILVVAZ7WOQ X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800056115019000 Content-Type: text/plain; charset="utf-8" Bypassing cache can make save performance more predictable and avoids trashing the OS cache with data that will not be read again. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/hypervisor/domain_driver.c | 7 +++++-- src/hypervisor/domain_driver.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index c510e1d2ae..d4cf09174b 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -730,12 +730,12 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdo= wnConfig *cfg) virDomainPtr *domains =3D NULL; g_autofree bool *transient =3D NULL; =20 - VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%s tryShutdown=3D%s pow= eroff=3D%s waitShutdownSecs=3D%u", + VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%s tryShutdown=3D%s pow= eroff=3D%s waitShutdownSecs=3D%u saveBypassCache=3D%d", cfg->uri, virDomainDriverAutoShutdownScopeTypeToString(cfg->trySave), virDomainDriverAutoShutdownScopeTypeToString(cfg->tryShutdow= n), virDomainDriverAutoShutdownScopeTypeToString(cfg->poweroff), - cfg->waitShutdownSecs); + cfg->waitShutdownSecs, cfg->saveBypassCache); =20 /* * Ideally guests will shutdown in a few seconds, but it would @@ -801,6 +801,9 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdown= Config *cfg) if (state =3D=3D VIR_DOMAIN_PAUSED) flags[i] =3D VIR_DOMAIN_SAVE_PAUSED; } + if (cfg->saveBypassCache) + flags[i] |=3D VIR_DOMAIN_SAVE_BYPASS_CACHE; + if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) virDomainSuspend(domains[i]); } diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index 6e535ca444..fae316ee2d 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -112,6 +112,7 @@ typedef struct _virDomainDriverAutoShutdownConfig { * before moving onto next action. * If 0 a default is used (currently 30= secs) */ + bool saveBypassCache; } virDomainDriverAutoShutdownConfig; =20 void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800497356661.8123074381716; Wed, 12 Mar 2025 10:28:17 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id AF20F1B17; Wed, 12 Mar 2025 13:28:16 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id C2DA41B10; Wed, 12 Mar 2025 13:26:30 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 0E3EC1C39; Wed, 12 Mar 2025 13:26:23 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 5BEAE1F77 for ; Wed, 12 Mar 2025 13:25:45 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-443-MDidtQ4mM0uBGR8wxtGd2A-1; Wed, 12 Mar 2025 13:25:44 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5A82C18EF3A4 for ; Wed, 12 Mar 2025 17:18:18 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6912518001DE; Wed, 12 Mar 2025 17:18:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800345; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S1LYi4isN3JrhcrQIeReL2aZ/32dMHBFLIPVO+uXWuI=; b=WUJKQslHjc78/0HWNX8aR9AaEDiqe1aGuRr4/JMjTRC/0TjJ4p7VwskPKyN9nLhzAlVZr7 f8U2W0Y4K+tp2X+xDV20RbJnyLP5jZXqknUf3aD7REHqYN9OwLOihLh5emjr0L7CaInQqd UJMb3MbOmdPkJEgYuGlUV7iW/PqW4U0= X-MC-Unique: MDidtQ4mM0uBGR8wxtGd2A-1 X-Mimecast-MFC-AGG-ID: MDidtQ4mM0uBGR8wxtGd2A_1741800343 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 09/22] qemu: add config parameter to control auto-save bypass cache Date: Wed, 12 Mar 2025 17:17:49 +0000 Message-ID: <20250312171802.1854985-10-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: DDxDZFBlyTypwPG9Y1Hz8QAVDX122f0hDmq3tmUi5Jw_1741800343 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: OLV5LVYLAGINEJJPBZL2GM33P5IPYUFC X-Message-ID-Hash: OLV5LVYLAGINEJJPBZL2GM33P5IPYUFC X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800498067019000 Content-Type: text/plain; charset="utf-8" When doing managed save of VMs, triggered by OS shutdown, it may be desirable to control cache usage. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf.in | 8 ++++++++ src/qemu/qemu_conf.c | 3 +++ src/qemu/qemu_conf.h | 1 + src/qemu/qemu_driver.c | 1 + src/qemu/test_libvirtd_qemu.aug.in | 1 + 6 files changed, 15 insertions(+) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 8cb1b144b9..9fa6398d8d 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -102,6 +102,7 @@ module Libvirtd_qemu =3D | str_entry "auto_shutdown_try_shutdown" | str_entry "auto_shutdown_poweroff" | int_entry "auto_shutdown_wait" + | bool_entry "auto_save_bypass_cache" =20 let process_entry =3D str_entry "hugetlbfs_mount" | str_entry "bridge_helper" diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in index 5a9bfd90e8..5643e849ad 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -689,6 +689,14 @@ # is currently 30 secs) #auto_shutdown_wait =3D 30 =20 +# When a domain is configured to be auto-saved on shutdown, enabling +# this flag has the same effect as using the VIR_DOMAIN_SAVE_BYPASS_CACHE +# flag with the virDomainManagedSave API. That is, the system will +# avoid using the file system cache when writing any managed state +# file, but may cause slower operation. +# +#auto_save_bypass_cache =3D 0 + # If provided by the host and a hugetlbfs mount point is configured, # a guest may request huge page backing. When this mount point is # unspecified here, determination of a host mount point in /proc/mounts diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index d1ae5fa308..6161a3c8d6 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -732,6 +732,9 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *c= fg, if (virConfGetValueUInt(conf, "auto_shutdown_wait", &cfg->autoShutdownWait) < 0) return -1; + if (virConfGetValueBool(conf, "auto_save_bypass_cache", + &cfg->autoSaveBypassCache) < 0) + return -1; =20 return 0; } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index f6fcfe444d..06c917ba3e 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -206,6 +206,7 @@ struct _virQEMUDriverConfig { virDomainDriverAutoShutdownScope autoShutdownTryShutdown; virDomainDriverAutoShutdownScope autoShutdownPoweroff; unsigned int autoShutdownWait; + bool autoSaveBypassCache; =20 char *lockManagerName; =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 08e2248852..3932640b79 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -951,6 +951,7 @@ qemuStateStop(void) .tryShutdown =3D cfg->autoShutdownTryShutdown, .poweroff =3D cfg->autoShutdownPoweroff, .waitShutdownSecs =3D cfg->autoShutdownWait, + .saveBypassCache =3D cfg->autoSaveBypassCache, }; =20 virDomainDriverAutoShutdown(&ascfg); diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index 4c6de31199..65d0c20fe1 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -80,6 +80,7 @@ module Test_libvirtd_qemu =3D { "auto_shutdown_try_shutdown" =3D "all" } { "auto_shutdown_poweroff" =3D "all" } { "auto_shutdown_wait" =3D "30" } +{ "auto_save_bypass_cache" =3D "0" } { "hugetlbfs_mount" =3D "/dev/hugepages" } { "bridge_helper" =3D "qemu-bridge-helper" } { "set_process_name" =3D "1" } --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800098138706.2686222273546; Wed, 12 Mar 2025 10:21:38 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 0EBE21EA7; Wed, 12 Mar 2025 13:21:36 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id B62511C1D; Wed, 12 Mar 2025 13:18:47 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 570021AC4; Wed, 12 Mar 2025 13:18:42 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 7B4E01B5B for ; Wed, 12 Mar 2025 13:18:22 -0400 (EDT) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-345-mc0TSuqxMyCCBX4pVkEi0Q-1; Wed, 12 Mar 2025 13:18:20 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0334E1955DE4 for ; Wed, 12 Mar 2025 17:18:20 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D288D18001DE; Wed, 12 Mar 2025 17:18:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799902; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VSfEQU7O9i17O6gm07oRoHoW1pAIp2KrPgIVaw+jzmw=; b=jNWUhw9qYYoDiNXza76QqNFJ3IU3s9kvYWFrTpocOxqKs4Hj8A4oTV6bSD8VE0rS19V0Ik zDkDUhBECoOjg8/WpsbY0wWIYgdd1ML0cJhU0gfXfXoWGOj+lOcvYC2micDSCs2L/CNN/z kHe+oj8U8IN0/7Zaae19TpF2RtKOR7E= X-MC-Unique: mc0TSuqxMyCCBX4pVkEi0Q-1 X-Mimecast-MFC-AGG-ID: mc0TSuqxMyCCBX4pVkEi0Q_1741799900 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 10/22] src: add new APIs for marking a domain to autostart once Date: Wed, 12 Mar 2025 17:17:50 +0000 Message-ID: <20250312171802.1854985-11-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: -l4OBbtuz99Ik7-jE33-WNCKFT1famCdaoMDtUB75CA_1741799900 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: AMWRPJDOA2C72OHVGIOXUQJC2U3MNY5D X-Message-ID-Hash: AMWRPJDOA2C72OHVGIOXUQJC2U3MNY5D X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800099746019100 Content-Type: text/plain; charset="utf-8" When a domain is marked for autostart, it will be started on every subsequent host OS boot. There may be times when it is desirable to mark a domain to be autostarted, on the next boot only. Thus we add virDomainSetAutostartOnce / virDomainGetAutostartOnce. An alternative would have been to overload the existing virDomainSetAutostart method, to accept values '1' or '2' for the autostart flag. This was not done because it is expected that language bindings will have mapped the current autostart flag to a boolean, and thus turning it into an enum would create a compatibility problem. A further alternative would have been to create a new method virDomainSetAutostartFlags, with a VIR_DOMAIN_AUTOSTART_ONCE flag defined. This was not done because it is felt desirable to clearly separate the two flags. Setting the "once" flag should not interfere with existing autostart setting, whether it is enabled or disabled currently. The 'virsh autostart' command, however, is still overloaded by just adding a --once flag, while current state is added to 'virsh dominfo'. No ability to filter by 'autostart once' status is added to the domain list APIs. The most common use of autostart once will be to automatically set it on host shutdown, and it be cleared on host startup. Thus there would rarely be scenarios in which a running app will need to filter on this new flag. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- include/libvirt/libvirt-domain.h | 4 ++ src/driver-hypervisor.h | 10 ++++ src/libvirt-domain.c | 87 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 6 +++ src/remote/remote_driver.c | 2 + src/remote/remote_protocol.x | 30 ++++++++++- src/remote_protocol-structs | 12 +++++ src/rpc/gendispatch.pl | 4 +- tools/virsh-domain-monitor.c | 7 +++ tools/virsh-domain.c | 39 ++++++++++---- 10 files changed, 189 insertions(+), 12 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index 8c86bd8f94..c4e768f26f 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2429,6 +2429,10 @@ int virDomainGetAutostart (vir= DomainPtr domain, int *autostart); int virDomainSetAutostart (virDomainPtr domain, int autostart); +int virDomainGetAutostartOnce(virDomainPtr domain, + int *autostart); +int virDomainSetAutostartOnce(virDomainPtr domain, + int autostart); =20 /** * virVcpuState: diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 4ce8da078d..c05c71b9fe 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -478,6 +478,14 @@ typedef int (*virDrvDomainSetAutostart)(virDomainPtr domain, int autostart); =20 +typedef int +(*virDrvDomainGetAutostartOnce)(virDomainPtr domain, + int *autostart); + +typedef int +(*virDrvDomainSetAutostartOnce)(virDomainPtr domain, + int autostart); + typedef char * (*virDrvDomainGetSchedulerType)(virDomainPtr domain, int *nparams); @@ -1564,6 +1572,8 @@ struct _virHypervisorDriver { virDrvDomainDetachDeviceAlias domainDetachDeviceAlias; virDrvDomainGetAutostart domainGetAutostart; virDrvDomainSetAutostart domainSetAutostart; + virDrvDomainGetAutostartOnce domainGetAutostartOnce; + virDrvDomainSetAutostartOnce domainSetAutostartOnce; virDrvDomainGetSchedulerType domainGetSchedulerType; virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; virDrvDomainGetSchedulerParametersFlags domainGetSchedulerParametersFl= ags; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index b23a3489c5..4e78c687d5 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -7344,6 +7344,93 @@ virDomainSetAutostart(virDomainPtr domain, } =20 =20 +/** + * virDomainGetAutostartOnce: + * @domain: a domain object + * @autostart: the value returned + * + * Provides a boolean value indicating whether the domain + * is configured to be automatically started the next time + * the host machine boots only. + * + * Returns -1 in case of error, 0 in case of success + * + * Since: 11.2.0 + */ +int +virDomainGetAutostartOnce(virDomainPtr domain, + int *autostart) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "autostart=3D%p", autostart); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + virCheckNonNullArgGoto(autostart, error); + + conn =3D domain->conn; + + if (conn->driver->domainGetAutostartOnce) { + int ret; + ret =3D conn->driver->domainGetAutostartOnce(domain, autostart); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + + +/** + * virDomainSetAutostartOnce: + * @domain: a domain object + * @autostart: whether the domain should be automatically started 0 or 1 + * + * Configure the domain to be automatically started + * the next time the host machine boots only. + * + * Returns -1 in case of error, 0 in case of success + * + * Since: 11.2.0 + */ +int +virDomainSetAutostartOnce(virDomainPtr domain, + int autostart) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "autostart=3D%d", autostart); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn =3D domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainSetAutostartOnce) { + int ret; + ret =3D conn->driver->domainSetAutostartOnce(domain, autostart); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + + /** * virDomainInjectNMI: * @domain: pointer to domain object, or NULL for Domain0 diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 7a3492d9d7..103f8e6f53 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -948,4 +948,10 @@ LIBVIRT_10.2.0 { virDomainGraphicsReload; } LIBVIRT_10.1.0; =20 +LIBVIRT_11.2.0 { + global: + virDomainGetAutostartOnce; + virDomainSetAutostartOnce; +} LIBVIRT_10.2.0; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 307f9ca945..c39b8cf676 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7672,6 +7672,8 @@ static virHypervisorDriver hypervisor_driver =3D { .domainDetachDeviceAlias =3D remoteDomainDetachDeviceAlias, /* 4.4.0 */ .domainGetAutostart =3D remoteDomainGetAutostart, /* 0.3.0 */ .domainSetAutostart =3D remoteDomainSetAutostart, /* 0.3.0 */ + .domainGetAutostartOnce =3D remoteDomainGetAutostartOnce, /* 11.2.0 */ + .domainSetAutostartOnce =3D remoteDomainSetAutostartOnce, /* 11.2.0 */ .domainGetSchedulerType =3D remoteDomainGetSchedulerType, /* 0.3.0 */ .domainGetSchedulerParameters =3D remoteDomainGetSchedulerParameters, = /* 0.3.0 */ .domainGetSchedulerParametersFlags =3D remoteDomainGetSchedulerParamet= ersFlags, /* 0.9.2 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 41c045ff78..4f873cb4cf 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3973,6 +3973,20 @@ struct remote_domain_fd_associate_args { remote_nonnull_string name; unsigned int flags; }; + +struct remote_domain_get_autostart_once_args { + remote_nonnull_domain dom; +}; + +struct remote_domain_get_autostart_once_ret { + int autostart; +}; + +struct remote_domain_set_autostart_once_args { + remote_nonnull_domain dom; + int autostart; +}; + /*----- Protocol. -----*/ =20 /* Define the program number, protocol version and procedure numbers here.= */ @@ -7048,5 +7062,19 @@ enum remote_procedure { * @generate: both * @acl: domain:write */ - REMOTE_PROC_DOMAIN_GRAPHICS_RELOAD =3D 448 + REMOTE_PROC_DOMAIN_GRAPHICS_RELOAD =3D 448, + + /** + * @generate: both + * @priority: high + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_GET_AUTOSTART_ONCE =3D 449, + + /** + * @generate: both + * @priority: high + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SET_AUTOSTART_ONCE =3D 450 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 4d3dc2d249..6337a082ce 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3306,6 +3306,16 @@ struct remote_domain_fd_associate_args { remote_nonnull_string name; u_int flags; }; +struct remote_domain_get_autostart_once_args { + remote_nonnull_domain dom; +}; +struct remote_domain_get_autostart_once_ret { + int autostart; +}; +struct remote_domain_set_autostart_once_args { + remote_nonnull_domain dom; + int autostart; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN =3D 1, REMOTE_PROC_CONNECT_CLOSE =3D 2, @@ -3755,4 +3765,6 @@ enum remote_procedure { REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE =3D 446, REMOTE_PROC_NODE_DEVICE_UPDATE =3D 447, REMOTE_PROC_DOMAIN_GRAPHICS_RELOAD =3D 448, + REMOTE_PROC_DOMAIN_GET_AUTOSTART_ONCE =3D 449, + REMOTE_PROC_DOMAIN_SET_AUTOSTART_ONCE =3D 450, }; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index 724a6aed6e..f9fae39fb1 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -839,7 +839,7 @@ elsif ($mode eq "server") { push(@ret_list, "ret->$1 =3D $1;"); $single_ret_var =3D $1; =20 - if ($call->{ProcName} =3D~ m/GetAutostart$/) { + if ($call->{ProcName} =3D~ m/GetAutostart(Once)?$/) { $single_ret_by_ref =3D 1; } else { $single_ret_by_ref =3D 0; @@ -1650,7 +1650,7 @@ elsif ($mode eq "client") { } elsif ($ret_member =3D~ m/^int (\S+);/) { my $arg_name =3D $1; =20 - if ($call->{ProcName} =3D~ m/GetAutostart$/) { + if ($call->{ProcName} =3D~ m/GetAutostart(Once)?$/) { push(@args_list, "int *$arg_name"); push(@ret_list, "if ($arg_name) *$arg_name =3D ret= .$arg_name;"); push(@ret_list, "rv =3D 0;"); diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index fa1c05ac77..f4274f2721 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1236,6 +1236,13 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%-15s %s\n", _("Autostart:"), autostart ? _("enable") : _("disable")); } + /* Check and display whether the domain autostarts next boot or not */ + if (!virDomainGetAutostartOnce(dom, &autostart)) { + vshPrint(ctl, "%-15s %s\n", _("Autostart Once:"), + autostart ? _("enable") : _("disable")); + } else { + vshResetLibvirtError(); + } =20 has_managed_save =3D virDomainHasManagedSaveImage(dom, 0); if (has_managed_save < 0) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 93c34c4971..4f2af7a078 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -1158,6 +1158,10 @@ static const vshCmdOptDef opts_autostart[] =3D { .type =3D VSH_OT_BOOL, .help =3D N_("disable autostarting") }, + {.name =3D "once", + .type =3D VSH_OT_BOOL, + .help =3D N_("control next boot state") + }, {.name =3D NULL} }; =20 @@ -1167,24 +1171,41 @@ cmdAutostart(vshControl *ctl, const vshCmd *cmd) g_autoptr(virshDomain) dom =3D NULL; const char *name; int autostart; + int once; =20 if (!(dom =3D virshCommandOptDomain(ctl, cmd, &name))) return false; =20 autostart =3D !vshCommandOptBool(cmd, "disable"); + once =3D vshCommandOptBool(cmd, "once"); + + if (once) { + if (virDomainSetAutostartOnce(dom, autostart) < 0) { + if (autostart) + vshError(ctl, _("Failed to mark domain '%1$s' as autostart= ed on next boot"), name); + else + vshError(ctl, _("Failed to unmark domain '%1$s' as autosta= rted on next boot"), name); + return false; + } =20 - if (virDomainSetAutostart(dom, autostart) < 0) { if (autostart) - vshError(ctl, _("Failed to mark domain '%1$s' as autostarted")= , name); + vshPrintExtra(ctl, _("Domain '%1$s' marked as autostarted on n= ext boot\n"), name); else - vshError(ctl, _("Failed to unmark domain '%1$s' as autostarted= "), name); - return false; - } + vshPrintExtra(ctl, _("Domain '%1$s' unmarked as autostarted on= next boot\n"), name); + } else { + if (virDomainSetAutostart(dom, autostart) < 0) { + if (autostart) + vshError(ctl, _("Failed to mark domain '%1$s' as autostart= ed"), name); + else + vshError(ctl, _("Failed to unmark domain '%1$s' as autosta= rted"), name); + return false; + } =20 - if (autostart) - vshPrintExtra(ctl, _("Domain '%1$s' marked as autostarted\n"), nam= e); - else - vshPrintExtra(ctl, _("Domain '%1$s' unmarked as autostarted\n"), n= ame); + if (autostart) + vshPrintExtra(ctl, _("Domain '%1$s' marked as autostarted\n"),= name); + else + vshPrintExtra(ctl, _("Domain '%1$s' unmarked as autostarted\n"= ), name); + } =20 return true; } --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800283330149.06742866557659; Wed, 12 Mar 2025 10:24:43 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 9C12B1186; Wed, 12 Mar 2025 13:24:42 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id BF1E31EE4; Wed, 12 Mar 2025 13:19:26 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 45B531C8F; Wed, 12 Mar 2025 13:19:23 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id EDAFC1CED for ; Wed, 12 Mar 2025 13:18:56 -0400 (EDT) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-168-spjFdpFqMt-GctLxEWLCZA-1; Wed, 12 Mar 2025 13:18:23 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8A4C7195605A for ; Wed, 12 Mar 2025 17:18:22 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8F9071800945; Wed, 12 Mar 2025 17:18:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZHGHFVIh0JVu0AMyEOShoA4Tg4IZINSfd28AeE12ITw=; b=NgTdRiM0zqI97401wVB6PJ22JkNbH9KY3LMcf/tSQs1kNklnH/aKxIDu+9iNJqoCR1BvKe yF9+bKiyekKjO4N/Wuma8Pt5vUQ9i6Lo1nfesui2/+iVuXPanV//15+4cf399XiDoGKNKm +woDBy/wDCls5HfabI6cs8HwxPjRZEk= X-MC-Unique: spjFdpFqMt-GctLxEWLCZA-1 X-Mimecast-MFC-AGG-ID: spjFdpFqMt-GctLxEWLCZA_1741799902 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 11/22] conf: implement support for autostart once feature Date: Wed, 12 Mar 2025 17:17:51 +0000 Message-ID: <20250312171802.1854985-12-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: V2ltfGDQ8gYWbP_qn38JmSUVx_29keGXFyLOiZwFzUY_1741799902 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: PQWS4Z7ZQLLEDG2VW3NZWAYQBTX2FKL3 X-Message-ID-Hash: PQWS4Z7ZQLLEDG2VW3NZWAYQBTX2FKL3 X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800285072019000 Content-Type: text/plain; charset="utf-8" This is maintained in the same way as the autostart flag, using a symlink. The difference is that instead of '.xml', the symlink suffix is '.xml.once'. The link is also deleted immediately after it has been read. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/conf/domain_conf.c | 7 ++++++- src/conf/domain_conf.h | 2 ++ src/conf/virdomainobjlist.c | 8 ++++++++ src/hypervisor/domain_driver.c | 14 +++++++++++--- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b94cf99236..cf8374ab18 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4166,6 +4166,7 @@ static void virDomainObjDispose(void *obj) virDomainCheckpointObjListFree(dom->checkpoints); virDomainJobObjFree(dom->job); virObjectUnref(dom->closecallbacks); + g_free(dom->autostartOnceLink); } =20 virDomainObj * @@ -29135,13 +29136,17 @@ virDomainDeleteConfig(const char *configDir, { g_autofree char *configFile =3D NULL; g_autofree char *autostartLink =3D NULL; + g_autofree char *autostartOnceLink =3D NULL; =20 configFile =3D virDomainConfigFile(configDir, dom->def->name); autostartLink =3D virDomainConfigFile(autostartDir, dom->def->name); + autostartOnceLink =3D g_strdup_printf("%s.once", autostartLink); =20 - /* Not fatal if this doesn't work */ + /* Not fatal if these don't work */ unlink(autostartLink); + unlink(autostartOnceLink); dom->autostart =3D 0; + dom->autostartOnce =3D 0; =20 if (unlink(configFile) < 0 && errno !=3D ENOENT) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a97fd866c..c648864083 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3324,9 +3324,11 @@ struct _virDomainObj { virDomainStateReason state; =20 unsigned int autostart : 1; + unsigned int autostartOnce : 1; unsigned int persistent : 1; unsigned int updated : 1; unsigned int removing : 1; + char *autostartOnceLink; =20 virDomainDef *def; /* The current definition */ virDomainDef *newDef; /* New definition to activate at shutdown */ diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c index 72207450c5..90efb3465c 100644 --- a/src/conf/virdomainobjlist.c +++ b/src/conf/virdomainobjlist.c @@ -487,9 +487,11 @@ virDomainObjListLoadConfig(virDomainObjList *doms, { g_autofree char *configFile =3D NULL; g_autofree char *autostartLink =3D NULL; + g_autofree char *autostartOnceLink =3D NULL; g_autoptr(virDomainDef) def =3D NULL; virDomainObj *dom; int autostart; + int autostartOnce; g_autoptr(virDomainDef) oldDef =3D NULL; =20 configFile =3D virDomainConfigFile(configDir, name); @@ -500,13 +502,19 @@ virDomainObjListLoadConfig(virDomainObjList *doms, return NULL; =20 autostartLink =3D virDomainConfigFile(autostartDir, name); + autostartOnceLink =3D g_strdup_printf("%s.once", autostartLink); =20 autostart =3D virFileLinkPointsTo(autostartLink, configFile); + autostartOnce =3D virFileLinkPointsTo(autostartOnceLink, configFile); =20 if (!(dom =3D virDomainObjListAddLocked(doms, &def, xmlopt, 0, &oldDef= ))) return NULL; =20 dom->autostart =3D autostart; + dom->autostartOnce =3D autostartOnce; + + if (autostartOnce) + dom->autostartOnceLink =3D g_steal_pointer(&autostartOnceLink); =20 if (notify) (*notify)(dom, oldDef =3D=3D NULL, opaque); diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index d4cf09174b..bfba435ee0 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -682,10 +682,12 @@ virDomainDriverAutoStartOne(virDomainObj *vm, virObjectLock(vm); virObjectRef(vm); =20 - VIR_DEBUG("Autostart %s: autostart=3D%d", - vm->def->name, vm->autostart); + VIR_DEBUG("Autostart %s: autostart=3D%d autostartOnce=3D%d autostartOn= ceLink=3D%s", + vm->def->name, vm->autostart, vm->autostartOnce, + NULLSTR(vm->autostartOnceLink)); =20 - if (vm->autostart && !virDomainObjIsActive(vm)) { + if ((vm->autostart || vm->autostartOnce) && + !virDomainObjIsActive(vm)) { virResetLastError(); if (state->cfg->delayMS) { if (!state->first) { @@ -696,6 +698,12 @@ virDomainDriverAutoStartOne(virDomainObj *vm, } =20 state->cfg->callback(vm, state->cfg->opaque); + vm->autostartOnce =3D 0; + } + + if (vm->autostartOnceLink) { + unlink(vm->autostartOnceLink); + g_clear_pointer(&vm->autostartOnceLink, g_free); } =20 virDomainObjEndAPI(&vm); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800519817360.34323528309324; Wed, 12 Mar 2025 10:28:39 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 4070F1F72; Wed, 12 Mar 2025 13:28:39 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id D7D4E1F71; Wed, 12 Mar 2025 13:26:33 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 40F9C1C39; Wed, 12 Mar 2025 13:26:23 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id CC5B71CD7 for ; Wed, 12 Mar 2025 13:25:45 -0400 (EDT) Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-462-ve267aEaOHmACdjkmk1HsQ-1; Wed, 12 Mar 2025 13:25:44 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0001718908DF for ; Wed, 12 Mar 2025 17:18:23 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E492C1801757; Wed, 12 Mar 2025 17:18:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800345; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=j07yMj1bp/Ln3ipZHzuX7MllVXSmSdnBpaSAJ4G89wY=; b=QmAeNDPA0ErGZcVTfZqG9mB9aUJ+NmwOsaKmOf9rB1CyZOqK3MrMUrRGV86JRcotKXOifU PYEgACeP+i46OTtUSacFbErDpOJXq3WSXMZSfMsylyO95NyplakV95cLPt6+zZIe/U5kp+ Lnqgu7ddTl5F4pH3gpsH+xj5Y6CSoKo= X-MC-Unique: ve267aEaOHmACdjkmk1HsQ-1 X-Mimecast-MFC-AGG-ID: ve267aEaOHmACdjkmk1HsQ_1741800343 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 12/22] hypervisor: wire up support for auto restore of running domains Date: Wed, 12 Mar 2025 17:17:52 +0000 Message-ID: <20250312171802.1854985-13-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: sJe-_G-RKMg8gX7mXACLrjBsWv9s1lJ6i8DnvBYL8OM_1741800343 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: VWKJQFRFTS3XNF2CWMUZNVUWNGIUYV5C X-Message-ID-Hash: VWKJQFRFTS3XNF2CWMUZNVUWNGIUYV5C X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800520151019000 Content-Type: text/plain; charset="utf-8" When performing auto-shutdown of running domains, there is now the option to mark them as "autostart once", so that their state is restored on next boot. This applies on top of the traditional autostart flag. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/hypervisor/domain_driver.c | 19 +++++++++++++++++-- src/hypervisor/domain_driver.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index bfba435ee0..1105d36388 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -738,12 +738,12 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdo= wnConfig *cfg) virDomainPtr *domains =3D NULL; g_autofree bool *transient =3D NULL; =20 - VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%s tryShutdown=3D%s pow= eroff=3D%s waitShutdownSecs=3D%u saveBypassCache=3D%d", + VIR_DEBUG("Run autoshutdown uri=3D%s trySave=3D%s tryShutdown=3D%s pow= eroff=3D%s waitShutdownSecs=3D%u saveBypassCache=3D%d autoRestore=3D%d", cfg->uri, virDomainDriverAutoShutdownScopeTypeToString(cfg->trySave), virDomainDriverAutoShutdownScopeTypeToString(cfg->tryShutdow= n), virDomainDriverAutoShutdownScopeTypeToString(cfg->poweroff), - cfg->waitShutdownSecs, cfg->saveBypassCache); + cfg->waitShutdownSecs, cfg->saveBypassCache, cfg->autoRestor= e); =20 /* * Ideally guests will shutdown in a few seconds, but it would @@ -788,6 +788,21 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) for (i =3D 0; i < numDomains; i++) { if (virDomainIsPersistent(domains[i]) =3D=3D 0) transient[i] =3D true; + + if (cfg->autoRestore) { + if (transient[i]) { + VIR_DEBUG("Cannot auto-restore transient VM %s", + virDomainGetName(domains[i])); + } else { + VIR_DEBUG("Mark %s for autostart on next boot", + virDomainGetName(domains[i])); + if (virDomainSetAutostartOnce(domains[i], 1) < 0) { + VIR_WARN("Unable to mark domain '%s' for auto restore:= %s", + virDomainGetName(domains[i]), + virGetLastErrorMessage()); + } + } + } } =20 if (cfg->trySave !=3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index fae316ee2d..d90466b942 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -113,6 +113,7 @@ typedef struct _virDomainDriverAutoShutdownConfig { * If 0 a default is used (currently 30= secs) */ bool saveBypassCache; + bool autoRestore; } virDomainDriverAutoShutdownConfig; =20 void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800129881693.1451949759875; Wed, 12 Mar 2025 10:22:09 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 425231DAF; Wed, 12 Mar 2025 13:22:09 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 58B481B5D; Wed, 12 Mar 2025 13:18:55 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 343E81E4D; Wed, 12 Mar 2025 13:18:51 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 5DC281E45 for ; Wed, 12 Mar 2025 13:18:28 -0400 (EDT) Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-619-9ci39S8mOU-CbKWiNnA5rQ-1; Wed, 12 Mar 2025 13:18:26 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 83392195421B for ; Wed, 12 Mar 2025 17:18:25 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 795721800945; Wed, 12 Mar 2025 17:18:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799907; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=StNedOiH/tkZP3AFrm2Z5VhI+DQ5U8Ro90LGmxbS3cQ=; b=XrsMOv1EUxE1hRMC1IVeVl4CioHwO9/Jvk5Hi6o9Pw2iIfVHZZqjUYEx1pTPSytOkDkNbC LS8Bri84/4fyCkM0xkYTdU8Xg+r4J0Jq2AY7HrNK0s3b9sNELMG755zticLwhkBjsJmLks rdlBS0gFiww1UZNXxE7n4jtWyrSZmQw= X-MC-Unique: 9ci39S8mOU-CbKWiNnA5rQ-1 X-Mimecast-MFC-AGG-ID: 9ci39S8mOU-CbKWiNnA5rQ_1741799905 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 13/22] qemu: wire up support for once only autostart Date: Wed, 12 Mar 2025 17:17:53 +0000 Message-ID: <20250312171802.1854985-14-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: _VT6Mb0RSmISwL3wzPSvGl5AekBeALPLVfeFXxw0eUk_1741799905 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: N5QCQJ4CFSXTIEOIDLW3M3K226HGMBLQ X-Message-ID-Hash: N5QCQJ4CFSXTIEOIDLW3M3K226HGMBLQ X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800130442019000 Content-Type: text/plain; charset="utf-8" Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/qemu_driver.c | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3932640b79..3b74a98685 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7775,6 +7775,101 @@ static int qemuDomainSetAutostart(virDomainPtr dom, } =20 =20 +static int +qemuDomainGetAutostartOnce(virDomainPtr dom, + int *autostart) +{ + virDomainObj *vm; + int ret =3D -1; + + if (!(vm =3D qemuDomainObjFromDomain(dom))) + goto cleanup; + + if (virDomainGetAutostartOnceEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + *autostart =3D vm->autostartOnce; + ret =3D 0; + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + +static int +qemuDomainSetAutostartOnce(virDomainPtr dom, + int autostart) +{ + virQEMUDriver *driver =3D dom->conn->privateData; + virDomainObj *vm; + g_autofree char *configFile =3D NULL; + g_autofree char *autostartLink =3D NULL; + g_autofree char *autostartOnceLink =3D NULL; + int ret =3D -1; + g_autoptr(virQEMUDriverConfig) cfg =3D NULL; + + if (!(vm =3D qemuDomainObjFromDomain(dom))) + return -1; + + cfg =3D virQEMUDriverGetConfig(driver); + + if (virDomainSetAutostartOnceEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + if (!vm->persistent) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("cannot set autostart for transient domain"= )); + goto cleanup; + } + + autostart =3D (autostart !=3D 0); + + if (vm->autostartOnce !=3D autostart) { + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto cleanup; + + configFile =3D virDomainConfigFile(cfg->configDir, vm->def->name); + autostartLink =3D virDomainConfigFile(cfg->autostartDir, vm->def->= name); + autostartOnceLink =3D g_strdup_printf("%s.once", autostartLink); + + if (autostart) { + if (g_mkdir_with_parents(cfg->autostartDir, 0777) < 0) { + virReportSystemError(errno, + _("cannot create autostart directory = %1$s"), + cfg->autostartDir); + goto endjob; + } + + if (symlink(configFile, autostartOnceLink) < 0) { + virReportSystemError(errno, + _("Failed to create symlink '%1$s' to= '%2$s'"), + autostartOnceLink, configFile); + goto endjob; + } + } else { + if (unlink(autostartOnceLink) < 0 && + errno !=3D ENOENT && + errno !=3D ENOTDIR) { + virReportSystemError(errno, + _("Failed to delete symlink '%1$s'"), + autostartOnceLink); + goto endjob; + } + } + + vm->autostartOnce =3D autostart; + + endjob: + virDomainObjEndJob(vm); + } + ret =3D 0; + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + static char *qemuDomainGetSchedulerType(virDomainPtr dom, int *nparams) { @@ -20186,6 +20281,8 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .domainSetLaunchSecurityState =3D qemuDomainSetLaunchSecurityState, /*= 8.0.0 */ .domainFDAssociate =3D qemuDomainFDAssociate, /* 9.0.0 */ .domainGraphicsReload =3D qemuDomainGraphicsReload, /* 10.2.0 */ + .domainGetAutostartOnce =3D qemuDomainGetAutostartOnce, /* 11.2.0 */ + .domainSetAutostartOnce =3D qemuDomainSetAutostartOnce, /* 11.2.0 */ }; =20 =20 --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 17418001530741.455958607847947; Wed, 12 Mar 2025 10:22:33 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 6627A1C58; Wed, 12 Mar 2025 13:22:32 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 99BA41E9F; Wed, 12 Mar 2025 13:18:59 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id A8E3F1AED; Wed, 12 Mar 2025 13:18:53 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 897B11AED for ; Wed, 12 Mar 2025 13:18:29 -0400 (EDT) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-617-39KGxMtyOxiwU7WlpeCmug-1; Wed, 12 Mar 2025 13:18:28 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 44DD31956060 for ; Wed, 12 Mar 2025 17:18:27 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 201F6180174E; Wed, 12 Mar 2025 17:18:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799909; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8M2u+455nYDPyFIlB2IbivvQZywsFNzZe67HY5bJni4=; b=XRZbwRKQxHaqmHA/vFxXqp9bGs6KbZn5X/79V/LBjrUIw/TnoQ8mXSxF1Cpm73l9ojJk92 ZbLocv2kyfxyJY5qiRVSg9b2boH0lEGxy6DYjLzgfR3K0zqsjzHe1+mf5k0ytgfe9sPXKW HqieiDsuyahIftYulYCE9cXVJZus6fc= X-MC-Unique: 39KGxMtyOxiwU7WlpeCmug-1 X-Mimecast-MFC-AGG-ID: 39KGxMtyOxiwU7WlpeCmug_1741799907 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 14/22] qemu: add config to control if auto-shutdown VMs are restored Date: Wed, 12 Mar 2025 17:17:54 +0000 Message-ID: <20250312171802.1854985-15-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: oEfTZ9_tRee8W_oM4-6GznU1qWL_yekL7jvar4MFf3E_1741799907 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: QMTM3WPC4J3IBAZW5OFQKACZOBFJ7TON X-Message-ID-Hash: QMTM3WPC4J3IBAZW5OFQKACZOBFJ7TON X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800154631019000 Content-Type: text/plain; charset="utf-8" If shutting down running VMs at host shutdown, it can be useful to automatically start them again on next boot. This adds a config parameter 'auto_shutdown_restore', which defaults to enabled, which leverages the autostart once feature. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf.in | 4 ++++ src/qemu/qemu_conf.c | 3 +++ src/qemu/qemu_conf.h | 1 + src/qemu/qemu_driver.c | 1 + src/qemu/test_libvirtd_qemu.aug.in | 1 + 6 files changed, 11 insertions(+) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 9fa6398d8d..ee39da73b9 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -102,6 +102,7 @@ module Libvirtd_qemu =3D | str_entry "auto_shutdown_try_shutdown" | str_entry "auto_shutdown_poweroff" | int_entry "auto_shutdown_wait" + | bool_entry "auto_shutdown_restore" | bool_entry "auto_save_bypass_cache" =20 let process_entry =3D str_entry "hugetlbfs_mount" diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in index 5643e849ad..794b8cf31f 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -689,6 +689,10 @@ # is currently 30 secs) #auto_shutdown_wait =3D 30 =20 +# Whether VMs that are automatically powered off or saved during +# host shutdown, should be set to restore on next boot +#auto_shutdown_restore =3D 1 + # When a domain is configured to be auto-saved on shutdown, enabling # this flag has the same effect as using the VIR_DOMAIN_SAVE_BYPASS_CACHE # flag with the virDomainManagedSave API. That is, the system will diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 6161a3c8d6..fa6a9941b4 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -318,6 +318,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privil= eged, cfg->autoShutdownTryShutdown =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_S= COPE_ALL; cfg->autoShutdownPoweroff =3D VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOP= E_ALL; } + cfg->autoShutdownRestore =3D true; =20 return g_steal_pointer(&cfg); } @@ -732,6 +733,8 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *c= fg, if (virConfGetValueUInt(conf, "auto_shutdown_wait", &cfg->autoShutdownWait) < 0) return -1; + if (virConfGetValueBool(conf, "auto_shutdown_restore", &cfg->autoShutd= ownRestore) < 0) + return -1; if (virConfGetValueBool(conf, "auto_save_bypass_cache", &cfg->autoSaveBypassCache) < 0) return -1; diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 06c917ba3e..d064c7bb9c 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -206,6 +206,7 @@ struct _virQEMUDriverConfig { virDomainDriverAutoShutdownScope autoShutdownTryShutdown; virDomainDriverAutoShutdownScope autoShutdownPoweroff; unsigned int autoShutdownWait; + bool autoShutdownRestore; bool autoSaveBypassCache; =20 char *lockManagerName; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3b74a98685..ccac2a1259 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -952,6 +952,7 @@ qemuStateStop(void) .poweroff =3D cfg->autoShutdownPoweroff, .waitShutdownSecs =3D cfg->autoShutdownWait, .saveBypassCache =3D cfg->autoSaveBypassCache, + .autoRestore =3D cfg->autoShutdownRestore, }; =20 virDomainDriverAutoShutdown(&ascfg); diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index 65d0c20fe1..922cb35db7 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -80,6 +80,7 @@ module Test_libvirtd_qemu =3D { "auto_shutdown_try_shutdown" =3D "all" } { "auto_shutdown_poweroff" =3D "all" } { "auto_shutdown_wait" =3D "30" } +{ "auto_shutdown_restore" =3D "1" } { "auto_save_bypass_cache" =3D "0" } { "hugetlbfs_mount" =3D "/dev/hugepages" } { "bridge_helper" =3D "qemu-bridge-helper" } --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800552880157.168973519578; Wed, 12 Mar 2025 10:29:12 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 2B28E2102; Wed, 12 Mar 2025 13:29:12 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 4AF591F57; Wed, 12 Mar 2025 13:26:39 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 62E581D99; Wed, 12 Mar 2025 13:26:35 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id EEA621F5B for ; Wed, 12 Mar 2025 13:25:56 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-327-q2UPp40lNgiHZx5DcGVkfg-1; Wed, 12 Mar 2025 13:25:55 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 67BBA18EFA61 for ; Wed, 12 Mar 2025 17:18:29 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BBB9518001D4; Wed, 12 Mar 2025 17:18:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800356; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+GrpoPXzEcQG9XiJglQK67l1gqU24PMtDq2w21rSuWs=; b=FOYPUM+qgQyuRyoHjJbfgZ4YEzOdo1FvXM04F937jsZDTdWRzpdkNxoqTFTkRwKSaj59cE 9IRAFMWY9tYQU7A0O5elKlCDM+7380t2Qj1hySHES+VkKnrwWYa57jhx7jqLMvxms1shyQ FGmbQZJBovdg48IVAmDyNdZ2MK3dntM= X-MC-Unique: q2UPp40lNgiHZx5DcGVkfg-1 X-Mimecast-MFC-AGG-ID: q2UPp40lNgiHZx5DcGVkfg_1741800354 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 15/22] src: clarify semantics of the various virStateNNN methods Date: Wed, 12 Mar 2025 17:17:55 +0000 Message-ID: <20250312171802.1854985-16-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: OUApyADOf3N9bJ59RFA06uhDset_DejrlhKwDiY0u3k_1741800354 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: HCSVWWBML3ZRPDFTABRIJQDQGIXJQUFW X-Message-ID-Hash: HCSVWWBML3ZRPDFTABRIJQDQGIXJQUFW X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800555132019000 Content-Type: text/plain; charset="utf-8" It is not documented what the various virStateNNN methods are each responsible for doing and the names give little guidance either. Provide some useful documentation comments to explain the intended usage of each. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/libvirt.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 1d37696d6f..581fc6deea 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -688,7 +688,13 @@ virStateInitialize(bool privileged, /** * virStateShutdownPrepare: * - * Run each virtualization driver's shutdown prepare method. + * Tell each driver to prepare for shutdown of the daemon. This should + * trigger any actions required to stop processing background work. + * + * This method is called directly from the main event loop thread, so + * the event loop will not execute while this method is running. After + * this method returns, the event loop will continue running until + * the virStateShutdownWait method completes. * * Returns 0 if all succeed, -1 upon any failure. */ @@ -709,7 +715,12 @@ virStateShutdownPrepare(void) /** * virStateShutdownWait: * - * Run each virtualization driver's shutdown wait method. + * Tell each driver to finalize any work required to enable + * graceful shutdown of the daemon. This method is invoked + * from a background thread, and when it completes, the event + * loop will terminate. As such drivers can register callbacks + * that will prevent the event loop terminating until actions + * initiated by virStateShutdownPrepare are complete. * * Returns 0 if all succeed, -1 upon any failure. */ @@ -730,7 +741,12 @@ virStateShutdownWait(void) /** * virStateCleanup: * - * Run each virtualization driver's cleanup method. + * Tell each driver to release all resources it holds in + * order to fully shutdown the daemon. When this is called + * the event loop will no longer be running. Thus any + * cleanup that depends on execution of the event loop + * must have been triggered by the virStateShutdownPrepare + * method. * * Returns 0 if all succeed, -1 upon any failure. */ @@ -752,7 +768,8 @@ virStateCleanup(void) /** * virStateReload: * - * Run each virtualization driver's reload method. + * Tell each driver to reload their global configuration + * file(s). * * Returns 0 if all succeed, -1 upon any failure. */ @@ -774,7 +791,24 @@ virStateReload(void) /** * virStateStop: * - * Run each virtualization driver's "stop" method. + * Tell each driver to prepare for system/session stop. + * + * In an unprivileged daemon, this indicates that the + * current user's primary login session is about to + * be terminated. + * + * In a privileged daemon, this indicates that the host + * OS is about to shutdown. + * + * This is a signal that the driver should stop and/or + * preserve any resources affected by the system/session + * stop. + * + * On host OS stop there is a very short wait for the + * stop action to complete. For any prolonged tasks + * the driver must acquire inhibitor locks, or send + * a request to systemd to extend the shutdown wait + * timeout. * * Returns 0 if successful, -1 on failure */ --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800173477292.05503812074176; Wed, 12 Mar 2025 10:22:53 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id DF50B18B9; Wed, 12 Mar 2025 13:22:52 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id E29201E1B; Wed, 12 Mar 2025 13:19:02 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 6BFA71B3C; Wed, 12 Mar 2025 13:18:54 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 4BD801DA3 for ; Wed, 12 Mar 2025 13:18:33 -0400 (EDT) Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-147-Jxnpqt5hOfi6Mhazw4ws9w-1; Wed, 12 Mar 2025 13:18:31 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 130691954216 for ; Wed, 12 Mar 2025 17:18:31 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E0CD318001DE; Wed, 12 Mar 2025 17:18:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UWCpiDjdnGnP7LhMSEa3N3dGvlj5rZky3d7pLKIStzs=; b=bBaCX3JGZGMboSdcY3pjxKc3LdnzLOk/16o2H8LpcD1kcQ+Y4IIiY9I/2PqXwWZRN42gyZ FufRWpL3CJ9wZ6OpZFpUK/i75/xb4KhpB6kpEPpL6IXItXtA9pnCoyH5fQunNm2SzvPooh 2RbRhMwfqsriMx/PG3aC+PFWj4jQB5E= X-MC-Unique: Jxnpqt5hOfi6Mhazw4ws9w-1 X-Mimecast-MFC-AGG-ID: Jxnpqt5hOfi6Mhazw4ws9w_1741799911 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 16/22] rpc: rename virNetDaemonSetShutdownCallbacks Date: Wed, 12 Mar 2025 17:17:56 +0000 Message-ID: <20250312171802.1854985-17-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: cTsryJNtV0OlxfbeHaUODeoJwj5TEVL2LkAzV1WgjQc_1741799911 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: CACHNGN44U2ADL57JP24BDA6IVLDU3HF X-Message-ID-Hash: CACHNGN44U2ADL57JP24BDA6IVLDU3HF X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800174686019000 Content-Type: text/plain; charset="utf-8" The next patch will be introducing a new callback, so rename the method to virNetDaemonSetLifecycleCallbacks to reflect the more general usage. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/libvirt_remote.syms | 2 +- src/remote/remote_daemon.c | 6 +++--- src/rpc/virnetdaemon.c | 10 +++++----- src/rpc/virnetdaemon.h | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms index f0f90815cf..c4053fdcb2 100644 --- a/src/libvirt_remote.syms +++ b/src/libvirt_remote.syms @@ -94,7 +94,7 @@ virNetDaemonQuit; virNetDaemonQuitExecRestart; virNetDaemonRemoveShutdownInhibition; virNetDaemonRun; -virNetDaemonSetShutdownCallbacks; +virNetDaemonSetLifecycleCallbacks; virNetDaemonSetStateStopWorkerThread; virNetDaemonUpdateServices; =20 diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 2f6cef1828..9c0025a3bc 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -624,9 +624,9 @@ static void daemonRunStateInit(void *opaque) =20 g_atomic_int_set(&driversInitialized, 1); =20 - virNetDaemonSetShutdownCallbacks(dmn, - virStateShutdownPrepare, - virStateShutdownWait); + virNetDaemonSetLifecycleCallbacks(dmn, + virStateShutdownPrepare, + virStateShutdownWait); =20 /* Signal for VM shutdown when desktop session is terminated, in * unprivileged daemons */ diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index e6bdfe0f88..6d20edf28b 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -65,8 +65,8 @@ struct _virNetDaemon { GHashTable *servers; virJSONValue *srvObject; =20 - virNetDaemonShutdownCallback shutdownPrepareCb; - virNetDaemonShutdownCallback shutdownWaitCb; + virNetDaemonLifecycleCallback shutdownPrepareCb; + virNetDaemonLifecycleCallback shutdownWaitCb; virThread *stateStopThread; int finishTimer; bool quit; @@ -873,9 +873,9 @@ virNetDaemonHasClients(virNetDaemon *dmn) } =20 void -virNetDaemonSetShutdownCallbacks(virNetDaemon *dmn, - virNetDaemonShutdownCallback prepareCb, - virNetDaemonShutdownCallback waitCb) +virNetDaemonSetLifecycleCallbacks(virNetDaemon *dmn, + virNetDaemonLifecycleCallback prepareCb, + virNetDaemonLifecycleCallback waitCb) { VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 diff --git a/src/rpc/virnetdaemon.h b/src/rpc/virnetdaemon.h index 31a355adb4..0f4ebb6df7 100644 --- a/src/rpc/virnetdaemon.h +++ b/src/rpc/virnetdaemon.h @@ -82,8 +82,8 @@ ssize_t virNetDaemonGetServers(virNetDaemon *dmn, virNetS= erver ***servers); bool virNetDaemonHasServer(virNetDaemon *dmn, const char *serverName); =20 -typedef int (*virNetDaemonShutdownCallback)(void); +typedef int (*virNetDaemonLifecycleCallback)(void); =20 -void virNetDaemonSetShutdownCallbacks(virNetDaemon *dmn, - virNetDaemonShutdownCallback prepare= Cb, - virNetDaemonShutdownCallback waitCb); +void virNetDaemonSetLifecycleCallbacks(virNetDaemon *dmn, + virNetDaemonLifecycleCallback prepa= reCb, + virNetDaemonLifecycleCallback waitC= b); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800598352346.8237225777144; Wed, 12 Mar 2025 10:29:58 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id AD2691F65; Wed, 12 Mar 2025 13:29:57 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 1C1061AEF; Wed, 12 Mar 2025 13:26:45 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 102C31186; Wed, 12 Mar 2025 13:26:36 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id AD47C1D2C for ; Wed, 12 Mar 2025 13:26:01 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-436-_ycbdU1IMK2h3Tg3r3nITw-1; Wed, 12 Mar 2025 13:25:58 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 795DD190E8DF for ; Wed, 12 Mar 2025 17:18:32 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 899901800945; Wed, 12 Mar 2025 17:18:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800361; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JdDwgdEMrb1Lt6OgNf8XwJIJ3sFBBesk+ozKoxRTlTk=; b=GmaKdChnjyHw45YdLEbywaTPpRpOc4s5k+olRb5hSDCJa1+w5x34/U5s/RyQHo/mcme5pP gZVg4kzK9nfoA3a5cOzlJttmnICj2FB8MCD/Ivxk5LbcLukCHPD+M6FLgbukX/YYAiN+8E 1eyiittNdPnIUfmto+QEz51k6nWqqiA= X-MC-Unique: _ycbdU1IMK2h3Tg3r3nITw-1 X-Mimecast-MFC-AGG-ID: _ycbdU1IMK2h3Tg3r3nITw_1741800357 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 17/22] rpc: move state stop into virNetDaemon class Date: Wed, 12 Mar 2025 17:17:57 +0000 Message-ID: <20250312171802.1854985-18-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: xBYVWdf5C5-Q-3q6Q_8NwoDHLavnqfAcr3XU4qIoLtY_1741800357 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 2NU4WJYSRM2PIXYVATAHNJ4GIBH4FIEL X-Message-ID-Hash: 2NU4WJYSRM2PIXYVATAHNJ4GIBH4FIEL X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800600583019000 Content-Type: text/plain; charset="utf-8" Currently the remote daemon code is responsible for calling virStateStop in a background thread. The virNetDaemon code wants to synchronize with this during shutdown, however, so the virThreadPtr must be passed over. Even the limited synchronization done currently, however, is flawed and to fix this requires the virNetDaemon code to be responsible for calling virStateStop in a thread more directly. Thus the logic is moved over into virStateStop via a further callback to be registered by the remote daemon. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/libvirt_remote.syms | 2 +- src/remote/remote_daemon.c | 40 ++------------------------ src/rpc/virnetdaemon.c | 59 +++++++++++++++++++++++++++++++------- src/rpc/virnetdaemon.h | 27 +++++++++++++++-- 4 files changed, 77 insertions(+), 51 deletions(-) diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms index c4053fdcb2..9dcc2792c1 100644 --- a/src/libvirt_remote.syms +++ b/src/libvirt_remote.syms @@ -95,7 +95,7 @@ virNetDaemonQuitExecRestart; virNetDaemonRemoveShutdownInhibition; virNetDaemonRun; virNetDaemonSetLifecycleCallbacks; -virNetDaemonSetStateStopWorkerThread; +virNetDaemonStop; virNetDaemonUpdateServices; =20 =20 diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 9c0025a3bc..16dc1d86f7 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -514,41 +514,6 @@ static void daemonInhibitCallback(bool inhibit, void *= opaque) static GDBusConnection *sessionBus; static GDBusConnection *systemBus; =20 -static void daemonStopWorker(void *opaque) -{ - virNetDaemon *dmn =3D opaque; - - VIR_DEBUG("Begin stop dmn=3D%p", dmn); - - ignore_value(virStateStop()); - - VIR_DEBUG("Completed stop dmn=3D%p", dmn); - - /* Exit daemon cleanly */ - virNetDaemonQuit(dmn); -} - - -/* We do this in a thread to not block the main loop */ -static void daemonStop(virNetDaemon *dmn) -{ - virThread *thr; - virObjectRef(dmn); - - thr =3D g_new0(virThread, 1); - - if (virThreadCreateFull(thr, true, - daemonStopWorker, - "daemon-stop", false, dmn) < 0) { - virObjectUnref(dmn); - g_free(thr); - return; - } - - virNetDaemonSetStateStopWorkerThread(dmn, &thr); -} - - static GDBusMessage * handleSessionMessageFunc(GDBusConnection *connection G_GNUC_UNUSED, GDBusMessage *message, @@ -562,7 +527,7 @@ handleSessionMessageFunc(GDBusConnection *connection G_= GNUC_UNUSED, if (virGDBusMessageIsSignal(message, "org.freedesktop.DBus.Local", "Disconnected")) - daemonStop(dmn); + virNetDaemonStop(dmn); =20 return message; } @@ -581,7 +546,7 @@ handleSystemMessageFunc(GDBusConnection *connection G_G= NUC_UNUSED, =20 VIR_DEBUG("dmn=3D%p", dmn); =20 - daemonStop(dmn); + virNetDaemonStop(dmn); } =20 =20 @@ -625,6 +590,7 @@ static void daemonRunStateInit(void *opaque) g_atomic_int_set(&driversInitialized, 1); =20 virNetDaemonSetLifecycleCallbacks(dmn, + virStateStop, virStateShutdownPrepare, virStateShutdownWait); =20 diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 6d20edf28b..43a75b330f 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -65,6 +65,7 @@ struct _virNetDaemon { GHashTable *servers; virJSONValue *srvObject; =20 + virNetDaemonLifecycleCallback stopCb; virNetDaemonLifecycleCallback shutdownPrepareCb; virNetDaemonLifecycleCallback shutdownWaitCb; virThread *stateStopThread; @@ -793,8 +794,10 @@ virNetDaemonRun(virNetDaemon *dmn) } } =20 + VIR_DEBUG("Main loop exited"); if (dmn->graceful) { virThreadJoin(&shutdownThread); + VIR_DEBUG("Graceful shutdown complete"); } else { VIR_WARN("Make forcefull daemon shutdown"); exit(EXIT_FAILURE); @@ -806,34 +809,61 @@ virNetDaemonRun(virNetDaemon *dmn) =20 =20 void -virNetDaemonSetStateStopWorkerThread(virNetDaemon *dmn, - virThread **thr) +virNetDaemonQuit(virNetDaemon *dmn) { VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 - VIR_DEBUG("Setting state stop worker thread on dmn=3D%p to thr=3D%p", = dmn, thr); - dmn->stateStopThread =3D g_steal_pointer(thr); + VIR_DEBUG("Quit requested %p", dmn); + dmn->quit =3D true; } =20 =20 void -virNetDaemonQuit(virNetDaemon *dmn) +virNetDaemonQuitExecRestart(virNetDaemon *dmn) { VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 - VIR_DEBUG("Quit requested %p", dmn); + VIR_DEBUG("Exec-restart requested %p", dmn); dmn->quit =3D true; + dmn->execRestart =3D true; +} + + +static void +virNetDaemonStopWorker(void *opaque) +{ + virNetDaemon *dmn =3D opaque; + + VIR_DEBUG("Begin stop dmn=3D%p", dmn); + + dmn->stopCb(); + + VIR_DEBUG("Completed stop dmn=3D%p", dmn); + + virNetDaemonQuit(dmn); + virObjectUnref(dmn); } =20 =20 void -virNetDaemonQuitExecRestart(virNetDaemon *dmn) +virNetDaemonStop(virNetDaemon *dmn) { VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 - VIR_DEBUG("Exec-restart requested %p", dmn); - dmn->quit =3D true; - dmn->execRestart =3D true; + if (!dmn->stopCb || + dmn->stateStopThread) + return; + + virObjectRef(dmn); + dmn->stateStopThread =3D g_new0(virThread, 1); + + if (virThreadCreateFull(dmn->stateStopThread, true, + virNetDaemonStopWorker, + "daemon-stop", false, dmn) < 0) { + virObjectUnref(dmn); + g_clear_pointer(&dmn->stateStopThread, g_free); + return; + } } =20 =20 @@ -874,11 +904,20 @@ virNetDaemonHasClients(virNetDaemon *dmn) =20 void virNetDaemonSetLifecycleCallbacks(virNetDaemon *dmn, + virNetDaemonLifecycleCallback stopCb, virNetDaemonLifecycleCallback prepareCb, virNetDaemonLifecycleCallback waitCb) { VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 + VIR_DEBUG("Lifecycle callbacks stop=3D%p prepare=3D%p wait=3D%p", + stopCb, prepareCb, waitCb); + + /* Immutable once set */ + if (dmn->stopCb || dmn->shutdownPrepareCb || dmn->shutdownWaitCb) + return; + + dmn->stopCb =3D stopCb; dmn->shutdownPrepareCb =3D prepareCb; dmn->shutdownWaitCb =3D waitCb; } diff --git a/src/rpc/virnetdaemon.h b/src/rpc/virnetdaemon.h index 0f4ebb6df7..68c95ade4a 100644 --- a/src/rpc/virnetdaemon.h +++ b/src/rpc/virnetdaemon.h @@ -66,13 +66,11 @@ int virNetDaemonAddSignalHandler(virNetDaemon *dmn, void virNetDaemonUpdateServices(virNetDaemon *dmn, bool enabled); =20 -void virNetDaemonSetStateStopWorkerThread(virNetDaemon *dmn, - virThread **thr); - void virNetDaemonRun(virNetDaemon *dmn); =20 void virNetDaemonQuit(virNetDaemon *dmn); void virNetDaemonQuitExecRestart(virNetDaemon *dmn); +void virNetDaemonStop(virNetDaemon *dmn); =20 bool virNetDaemonHasClients(virNetDaemon *dmn); =20 @@ -84,6 +82,29 @@ bool virNetDaemonHasServer(virNetDaemon *dmn, =20 typedef int (*virNetDaemonLifecycleCallback)(void); =20 +/* + * @stopCb: preserves any active state on host shutdown / session exit + * @prepareCb: start shutting down daemon + * @waitCb: wait for shutdown completion + * + * This method may only be invoked once, the callbacks are immutable + * once set. + * + * On host shutdown (privileged) or session exit (unprivileged) + * the @stopCb will be invoked first. + * + * When the daemon shuts down, the sequence of operations is + * as follows + * + * - Listener stops accepting new clients + * - Existing clients are closed + * - Delay until @stopCb is complete (if still running) + * - @prepareCb invoked + * - Server worker pool is drained in background + * - @waitCb is invoked in background + * - Main loop terminates + */ void virNetDaemonSetLifecycleCallbacks(virNetDaemon *dmn, + virNetDaemonLifecycleCallback stopC= b, virNetDaemonLifecycleCallback prepa= reCb, virNetDaemonLifecycleCallback waitC= b); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800570560365.4282364380456; Wed, 12 Mar 2025 10:29:30 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id EC34518B9; Wed, 12 Mar 2025 13:29:29 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 1B1BB1D6D; Wed, 12 Mar 2025 13:26:42 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 189561B55; Wed, 12 Mar 2025 13:26:36 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id C7FAB1EB8 for ; Wed, 12 Mar 2025 13:26:01 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-88-FaivO4IdOoSlkpXCN9voEw-1; Wed, 12 Mar 2025 13:25:59 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E3C6A190E8F3 for ; Wed, 12 Mar 2025 17:18:33 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F22C718001D4; Wed, 12 Mar 2025 17:18:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800361; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JANkFDo6iN7opUWSu78NFZXu/kVxxQhsD0ohnHFlAdo=; b=Dk8udMw+qrRiSo0hYwxotqQ5kGin7MuW6WYhtEHaLKLxCBxxsRclhM2VnRYgYNRZNbCpUM qdE3BDC/LCDwhpBSJMG1bh5IvrPff45zda+qwlyynW7LmFvdu8T6sc/mM03S7fyXKVOa7J HQjP/8D4hLrl5d6rTQIJA/HnAiCeaUk= X-MC-Unique: FaivO4IdOoSlkpXCN9voEw-1 X-Mimecast-MFC-AGG-ID: FaivO4IdOoSlkpXCN9voEw_1741800359 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 18/22] rpc: don't unconditionally quit after preserving state Date: Wed, 12 Mar 2025 17:17:58 +0000 Message-ID: <20250312171802.1854985-19-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Xq76fmfug0h-7-gg7rF4WsorMpt3uYIXvrunjnPx7ao_1741800359 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: HXPCPLSFFXB7DGTQPHQO7MNBZW3PDKQR X-Message-ID-Hash: HXPCPLSFFXB7DGTQPHQO7MNBZW3PDKQR X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800572607019000 Content-Type: text/plain; charset="utf-8" The call to preserve state (ie running VMs) is triggered in response to the desktop session dbus terminating (session daemon), or logind sending a "PrepareForShutdown" signal. In the case of the latter, daemons should only save their state, not actually exit yet. Other things on the system may still expect the daemon to be running at this stage. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrang=C3=A9 --- src/remote/remote_daemon.c | 4 +++- src/rpc/virnetdaemon.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 16dc1d86f7..1424d4cf5e 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -526,8 +526,10 @@ handleSessionMessageFunc(GDBusConnection *connection G= _GNUC_UNUSED, =20 if (virGDBusMessageIsSignal(message, "org.freedesktop.DBus.Local", - "Disconnected")) + "Disconnected")) { virNetDaemonStop(dmn); + virNetDaemonQuit(dmn); + } =20 return message; } diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 43a75b330f..469a1d3ae2 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -840,7 +840,6 @@ virNetDaemonStopWorker(void *opaque) =20 VIR_DEBUG("Completed stop dmn=3D%p", dmn); =20 - virNetDaemonQuit(dmn); virObjectUnref(dmn); } =20 --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800201951479.8617819386184; Wed, 12 Mar 2025 10:23:21 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id D9C9B1A5F; Wed, 12 Mar 2025 13:23:20 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id F3FC21E48; Wed, 12 Mar 2025 13:19:09 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 75CAC1B13; Wed, 12 Mar 2025 13:19:04 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id B5C661CB6 for ; Wed, 12 Mar 2025 13:18:37 -0400 (EDT) Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-450-mTN2wnCxPYGElW_v_mipDQ-1; Wed, 12 Mar 2025 13:18:36 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5B26F1955E8C for ; Wed, 12 Mar 2025 17:18:35 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5180D18001DE; Wed, 12 Mar 2025 17:18:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799917; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/7UOAZblBGXVwCkqV8g/pO3033aD5xM5Q8f/KitgUx8=; b=WvpAh37iX+dRGXUrielrmgEcGas9MiPINSxYMgWNkeKDvwBa41GJPTJcX+4quIET1xyT8C DvyJd3GRpiDB8uHJWhwe+DlzejT6LWJyMpNninzFEcoIfywzL+niE9vK51PdaNQ5t8qKpC PI6PNBpI2SKelFYc9Q4o9n3sOntyGjI= X-MC-Unique: mTN2wnCxPYGElW_v_mipDQ-1 X-Mimecast-MFC-AGG-ID: mTN2wnCxPYGElW_v_mipDQ_1741799915 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 19/22] rpc: fix shutdown sequence when preserving state Date: Wed, 12 Mar 2025 17:17:59 +0000 Message-ID: <20250312171802.1854985-20-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: j29yZBuON9xkol5IbOFbmxLgzW5itXvKxahqR_M1_Ks_1741799915 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 3DBJTW76HS4X6UNM3GBWHAK4KIBHKAP4 X-Message-ID-Hash: 3DBJTW76HS4X6UNM3GBWHAK4KIBHKAP4 X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800203610019100 Content-Type: text/plain; charset="utf-8" The preserving of state (ie running VMs) requires a fully functional daemon and hypervisor driver. If any part has started shutting down then saving state may fail, or worse, hang. The current shutdown sequence does not guarantee safe ordering, as we synchronize with the state saving thread only after the hypervisor driver has had its 'shutdownPrepare' callback invoked. In the case of QEMU this means that worker threads processing monitor events may well have been stopped. This implements a full state machine that has a well defined ordering that an earlier commit documented as the desired semantics. With this change, nothing will start shutting down if the state saving thread is still running. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/rpc/virnetdaemon.c | 107 ++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 469a1d3ae2..53dee60703 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -39,6 +39,21 @@ =20 VIR_LOG_INIT("rpc.netdaemon"); =20 +/* The daemon shutdown process will step through + * each state listed below in the order they are + * declared. The 'STOPPING' state may be skipped + * over if the stateStopThread is not required + * for the particular shutdown scenari + */ +typedef enum { + VIR_NET_DAEMON_QUIT_NONE, /* Running normally */ + VIR_NET_DAEMON_QUIT_REQUESTED, /* Daemon shutdown requested */ + VIR_NET_DAEMON_QUIT_STOPPING, /* stateStopThread is running, so shutdo= wn cannot request must be delayed */ + VIR_NET_DAEMON_QUIT_READY, /* Ready to initiate shutdown request by ca= lling shutdownPrepareCb */ + VIR_NET_DAEMON_QUIT_WAITING, /* shutdownWaitCb is running, waiting for= it to finished */ + VIR_NET_DAEMON_QUIT_COMPLETED, /* shutdownWaitCb is finished, event lo= op will now terminate */ +} virNetDaemonQuitPhase; + #ifndef WIN32 typedef struct _virNetDaemonSignal virNetDaemonSignal; struct _virNetDaemonSignal { @@ -69,9 +84,8 @@ struct _virNetDaemon { virNetDaemonLifecycleCallback shutdownPrepareCb; virNetDaemonLifecycleCallback shutdownWaitCb; virThread *stateStopThread; - int finishTimer; - bool quit; - bool finished; + int quitTimer; + virNetDaemonQuitPhase quit; bool graceful; bool execRestart; bool running; /* the daemon has reached the running phase */ @@ -414,7 +428,10 @@ virNetDaemonAutoShutdownTimer(int timerid G_GNUC_UNUSE= D, =20 if (!dmn->autoShutdownInhibitions) { VIR_DEBUG("Automatic shutdown triggered"); - dmn->quit =3D true; + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_NONE) { + VIR_DEBUG("Requesting daemon shutdown"); + dmn->quit =3D VIR_NET_DAEMON_QUIT_REQUESTED; + } } } =20 @@ -709,27 +726,26 @@ daemonShutdownWait(void *opaque) bool graceful =3D false; =20 virHashForEach(dmn->servers, daemonServerShutdownWait, NULL); - if (!dmn->shutdownWaitCb || dmn->shutdownWaitCb() >=3D 0) { - if (dmn->stateStopThread) - virThreadJoin(dmn->stateStopThread); - + if (!dmn->shutdownWaitCb || dmn->shutdownWaitCb() >=3D 0) graceful =3D true; - } =20 VIR_WITH_OBJECT_LOCK_GUARD(dmn) { dmn->graceful =3D graceful; - virEventUpdateTimeout(dmn->finishTimer, 0); + dmn->quit =3D VIR_NET_DAEMON_QUIT_COMPLETED; + virEventUpdateTimeout(dmn->quitTimer, 0); + VIR_DEBUG("Shutdown wait completed graceful=3D%d", graceful); } } =20 static void -virNetDaemonFinishTimer(int timerid G_GNUC_UNUSED, - void *opaque) +virNetDaemonQuitTimer(int timerid G_GNUC_UNUSED, + void *opaque) { virNetDaemon *dmn =3D opaque; VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 - dmn->finished =3D true; + dmn->quit =3D VIR_NET_DAEMON_QUIT_COMPLETED; + VIR_DEBUG("Shutdown wait timed out"); } =20 =20 @@ -746,9 +762,8 @@ virNetDaemonRun(virNetDaemon *dmn) goto cleanup; } =20 - dmn->quit =3D false; - dmn->finishTimer =3D -1; - dmn->finished =3D false; + dmn->quit =3D VIR_NET_DAEMON_QUIT_NONE; + dmn->quitTimer =3D -1; dmn->graceful =3D false; dmn->running =3D true; =20 @@ -757,7 +772,7 @@ virNetDaemonRun(virNetDaemon *dmn) virSystemdNotifyReady(); =20 VIR_DEBUG("dmn=3D%p quit=3D%d", dmn, dmn->quit); - while (!dmn->finished) { + while (dmn->quit !=3D VIR_NET_DAEMON_QUIT_COMPLETED) { virNetDaemonShutdownTimerUpdate(dmn); =20 virObjectUnlock(dmn); @@ -771,17 +786,30 @@ virNetDaemonRun(virNetDaemon *dmn) virHashForEach(dmn->servers, daemonServerProcessClients, NULL); =20 /* don't shutdown services when performing an exec-restart */ - if (dmn->quit && dmn->execRestart) + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_REQUESTED && dmn->execRes= tart) goto cleanup; =20 - if (dmn->quit && dmn->finishTimer =3D=3D -1) { + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_REQUESTED) { + VIR_DEBUG("Process quit request"); virHashForEach(dmn->servers, daemonServerClose, NULL); + + if (dmn->stateStopThread) { + VIR_DEBUG("State stop thread running"); + dmn->quit =3D VIR_NET_DAEMON_QUIT_STOPPING; + } else { + VIR_DEBUG("Ready to shutdown"); + dmn->quit =3D VIR_NET_DAEMON_QUIT_READY; + } + } + + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_READY) { + VIR_DEBUG("Starting shutdown, running prepare"); if (dmn->shutdownPrepareCb && dmn->shutdownPrepareCb() < 0) break; =20 - if ((dmn->finishTimer =3D virEventAddTimeout(30 * 1000, - virNetDaemonFinishT= imer, - dmn, NULL)) < 0) { + if ((dmn->quitTimer =3D virEventAddTimeout(30 * 1000, + virNetDaemonQuitTimer, + dmn, NULL)) < 0) { VIR_WARN("Failed to register finish timer."); break; } @@ -791,6 +819,9 @@ virNetDaemonRun(virNetDaemon *dmn) VIR_WARN("Failed to register join thread."); break; } + + VIR_DEBUG("Waiting for shutdown completion"); + dmn->quit =3D VIR_NET_DAEMON_QUIT_WAITING; } } =20 @@ -814,7 +845,8 @@ virNetDaemonQuit(virNetDaemon *dmn) VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 VIR_DEBUG("Quit requested %p", dmn); - dmn->quit =3D true; + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_NONE) + dmn->quit =3D VIR_NET_DAEMON_QUIT_REQUESTED; } =20 =20 @@ -824,7 +856,8 @@ virNetDaemonQuitExecRestart(virNetDaemon *dmn) VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); =20 VIR_DEBUG("Exec-restart requested %p", dmn); - dmn->quit =3D true; + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_NONE) + dmn->quit =3D VIR_NET_DAEMON_QUIT_REQUESTED; dmn->execRestart =3D true; } =20 @@ -840,6 +873,15 @@ virNetDaemonStopWorker(void *opaque) =20 VIR_DEBUG("Completed stop dmn=3D%p", dmn); =20 + VIR_WITH_OBJECT_LOCK_GUARD(dmn) { + if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_STOPPING) { + VIR_DEBUG("Marking shutdown as ready"); + dmn->quit =3D VIR_NET_DAEMON_QUIT_READY; + } + g_clear_pointer(&dmn->stateStopThread, g_free); + } + + VIR_DEBUG("End stop dmn=3D%p", dmn); virObjectUnref(dmn); } =20 @@ -848,15 +890,26 @@ void virNetDaemonStop(virNetDaemon *dmn) { VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); + VIR_DEBUG("State stoprequest"); =20 - if (!dmn->stopCb || - dmn->stateStopThread) + if (!dmn->stopCb) { + VIR_DEBUG("No stop callback registered"); return; + } + if (dmn->stateStopThread) { + VIR_DEBUG("State stop thread already running"); + return; + } + + if (dmn->quit !=3D VIR_NET_DAEMON_QUIT_NONE) { + VIR_WARN("Already initiated shutdown sequence, unable to stop stat= e"); + return; + } =20 virObjectRef(dmn); dmn->stateStopThread =3D g_new0(virThread, 1); =20 - if (virThreadCreateFull(dmn->stateStopThread, true, + if (virThreadCreateFull(dmn->stateStopThread, false, virNetDaemonStopWorker, "daemon-stop", false, dmn) < 0) { virObjectUnref(dmn); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800229738648.5340429425883; Wed, 12 Mar 2025 10:23:49 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id AD5BC1DA3; Wed, 12 Mar 2025 13:23:48 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id E245B1EBF; Wed, 12 Mar 2025 13:19:12 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id C68291BC4; Wed, 12 Mar 2025 13:19:05 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id CD7471E6E for ; Wed, 12 Mar 2025 13:18:39 -0400 (EDT) Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-298-muuCquGwPs2x-76_e-GMpw-1; Wed, 12 Mar 2025 13:18:37 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1B0701954225 for ; Wed, 12 Mar 2025 17:18:37 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D151F18001D4; Wed, 12 Mar 2025 17:18:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799919; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vJVJZFfPuZwZ+bnWMIzewuk5eW+sDxocPkNp41BsN40=; b=QecZ8/S2nAsxR7OZStGfnGC9ur3W3vZBV/6GM8F+/OpKTW2D89D32AIg4GCcMVwMoBDkCA z1BcPX0W3R8mFsKlJyswePekYBePVjvfBXkv9znju7AYO6EciIQsaVg0WicaSP3vF/ZjAN +Z8kIZcKhkd3fHITK+xSJFeHzOZbTRM= X-MC-Unique: muuCquGwPs2x-76_e-GMpw-1 X-Mimecast-MFC-AGG-ID: muuCquGwPs2x-76_e-GMpw_1741799917 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 20/22] admin: add 'daemon-shutdown' command Date: Wed, 12 Mar 2025 17:18:00 +0000 Message-ID: <20250312171802.1854985-21-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: qpZjMfd8iWdVvaL6cYFsKHS61N0agfUIGa7NTjvCMs0_1741799917 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: ALHLJSZKV4HMAJE2FYCCCFZDHUIIACJZ X-Message-ID-Hash: ALHLJSZKV4HMAJE2FYCCCFZDHUIIACJZ X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800231817019100 Content-Type: text/plain; charset="utf-8" The daemons are wired up to shutdown in responsible to UNIX process signals, as well as in response to login1 dbus signals, or loss of desktop session. The latter two options can optionally preserve state (ie running VMs). In non-systemd environments, as well as for testing, it would be useful to have a way to trigger shutdown with state preservation more directly. Thus a new admin protocol API is introduced virAdmConnectDaemonShutdown which will trigger a daemon shutdown, and preserve running VMs if the VIR_DAEMON_SHUTDOWN_PRESERVE flag is set. It has a corresponding 'virt-admin daemon-shutdown [--preserve]' command binding. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- docs/manpages/virt-admin.rst | 13 +++++++++ include/libvirt/libvirt-admin.h | 13 +++++++++ src/admin/admin_protocol.x | 11 +++++++- src/admin/admin_server_dispatch.c | 13 +++++++++ src/admin/libvirt-admin.c | 33 +++++++++++++++++++++++ src/admin/libvirt_admin_public.syms | 5 ++++ tools/virt-admin.c | 41 +++++++++++++++++++++++++++++ 7 files changed, 128 insertions(+), 1 deletion(-) diff --git a/docs/manpages/virt-admin.rst b/docs/manpages/virt-admin.rst index 54a6512ef7..82e9594ba6 100644 --- a/docs/manpages/virt-admin.rst +++ b/docs/manpages/virt-admin.rst @@ -326,6 +326,19 @@ Sets the daemon timeout to the value of '--timeout' ar= gument. Use ``--timeout 0` to disable auto-shutdown of the daemon. =20 =20 +daemon-shutdown +--------------- + +**Syntax:** + +:: + + daemon-shutdown [--preserve] + +Instruct the daemon to exit gracefully. If the ``--preserve`` flag is give= n, +it will save state in the same manner that would be done on a host OS shut= down +(privileged daemons) or a login session quit (unprivileged daemons). + SERVER COMMANDS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admi= n.h index ae4703f89b..d5c0a5bc8f 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -484,6 +484,19 @@ int virAdmConnectSetDaemonTimeout(virAdmConnectPtr con= n, unsigned int timeout, unsigned int flags); =20 +/** + * virAdmConnectDaemonShutdownFlags: + * + * Since: 11.2.0 + */ +typedef enum { + /* Preserve state before shutting down daemon (Since: 11.2.0) */ + VIR_DAEMON_SHUTDOWN_PRESERVE =3D (1 << 0), +} virAdmConnectDaemonShutdownFlags; + +int virAdmConnectDaemonShutdown(virAdmConnectPtr conn, + unsigned int flags); + # ifdef __cplusplus } # endif diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index f3130efd2d..cf5707e62e 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -219,6 +219,10 @@ struct admin_connect_set_daemon_timeout_args { unsigned int flags; }; =20 +struct admin_connect_daemon_shutdown_args { + unsigned int flags; +}; + /* Define the program number, protocol version and procedure numbers here.= */ const ADMIN_PROGRAM =3D 0x06900690; const ADMIN_PROTOCOL_VERSION =3D 1; @@ -334,5 +338,10 @@ enum admin_procedure { /** * @generate: both */ - ADMIN_PROC_CONNECT_SET_DAEMON_TIMEOUT =3D 19 + ADMIN_PROC_CONNECT_SET_DAEMON_TIMEOUT =3D 19, + + /** + * @generate: both + */ + ADMIN_PROC_CONNECT_DAEMON_SHUTDOWN =3D 20 }; diff --git a/src/admin/admin_server_dispatch.c b/src/admin/admin_server_dis= patch.c index ae8a8d4fa6..0eee80f6ac 100644 --- a/src/admin/admin_server_dispatch.c +++ b/src/admin/admin_server_dispatch.c @@ -474,6 +474,19 @@ adminConnectSetDaemonTimeout(virNetDaemon *dmn, return virNetDaemonAutoShutdown(dmn, timeout); } =20 +static int +adminConnectDaemonShutdown(virNetDaemon *dmn, + unsigned int flags) +{ + virCheckFlags(VIR_DAEMON_SHUTDOWN_PRESERVE, -1); + + if (flags & VIR_DAEMON_SHUTDOWN_PRESERVE) + virNetDaemonStop(dmn); + + virNetDaemonQuit(dmn); + + return 0; +} =20 static int adminDispatchConnectGetLoggingOutputs(virNetServer *server G_GNUC_UNUSED, diff --git a/src/admin/libvirt-admin.c b/src/admin/libvirt-admin.c index 3c756eb376..d7efac025f 100644 --- a/src/admin/libvirt-admin.c +++ b/src/admin/libvirt-admin.c @@ -1357,3 +1357,36 @@ virAdmConnectSetDaemonTimeout(virAdmConnectPtr conn, =20 return ret; } + + +/** + * virAdmConnectDaemonShutdown: + * @conn: pointer to an active admin connection + * @flags: optional extra falgs + * + * Trigger shutdown of the daemon, if @flags includes + * VIR_DAEMON_SHUTDOWN_PRESERVE then state will be + * preserved before shutting down + * + * Returns 0 on success, -1 on error. + * + * Since: 11.2.0 + */ +int +virAdmConnectDaemonShutdown(virAdmConnectPtr conn, + unsigned int flags) +{ + int ret; + + VIR_DEBUG("conn=3D%p, flags=3D0x%x", conn, flags); + + virResetLastError(); + virCheckAdmConnectReturn(conn, -1); + + if ((ret =3D remoteAdminConnectDaemonShutdown(conn, flags)) < 0) { + virDispatchError(NULL); + return -1; + } + + return ret; +} diff --git a/src/admin/libvirt_admin_public.syms b/src/admin/libvirt_admin_= public.syms index 17930e4fac..42feba0329 100644 --- a/src/admin/libvirt_admin_public.syms +++ b/src/admin/libvirt_admin_public.syms @@ -53,3 +53,8 @@ LIBVIRT_ADMIN_8.6.0 { global: virAdmConnectSetDaemonTimeout; } LIBVIRT_ADMIN_3.0.0; + +LIBVIRT_ADMIN_11.2.0 { + global: + virAdmConnectDaemonShutdown; +} LIBVIRT_ADMIN_8.6.0; diff --git a/tools/virt-admin.c b/tools/virt-admin.c index 2d63098444..b701ed1fe4 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -1077,6 +1077,41 @@ cmdDaemonTimeout(vshControl *ctl, const vshCmd *cmd) } =20 =20 +/* -------------------------- + * Command daemon-shutdown + * -------------------------- + */ +static const vshCmdInfo info_daemon_shutdown =3D { + .help =3D N_("stop the daemon"), + .desc =3D N_("stop the daemon"), +}; + +static const vshCmdOptDef opts_daemon_shutdown[] =3D { + {.name =3D "preserve", + .type =3D VSH_OT_BOOL, + .required =3D false, + .positional =3D false, + .help =3D N_("preserve state before shutting down"), + }, + {.name =3D NULL} +}; + +static bool +cmdDaemonShutdown(vshControl *ctl, const vshCmd *cmd) +{ + vshAdmControl *priv =3D ctl->privData; + unsigned int flags =3D 0; + + if (vshCommandOptBool(cmd, "preserve")) + flags |=3D VIR_DAEMON_SHUTDOWN_PRESERVE; + + if (virAdmConnectDaemonShutdown(priv->conn, flags) < 0) + return false; + + return true; +} + + static void * vshAdmConnectionHandler(vshControl *ctl) { @@ -1469,6 +1504,12 @@ static const vshCmdDef managementCmds[] =3D { .info =3D &info_daemon_timeout, .flags =3D 0 }, + {.name =3D "daemon-shutdown", + .handler =3D cmdDaemonShutdown, + .opts =3D opts_daemon_shutdown, + .info =3D &info_daemon_shutdown, + .flags =3D 0 + }, {.name =3D NULL} }; =20 --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800628031866.1693590251471; Wed, 12 Mar 2025 10:30:28 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 640931B25; Wed, 12 Mar 2025 13:30:27 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 9E3151F80; Wed, 12 Mar 2025 13:26:48 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 1B01F1C58; Wed, 12 Mar 2025 13:26:37 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 8F7791EA5 for ; Wed, 12 Mar 2025 13:26:03 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-458-grQ9pbwYNfqeRr0BKRh-pg-1; Wed, 12 Mar 2025 13:26:02 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 844B61910E8C for ; Wed, 12 Mar 2025 17:18:38 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9264218001DE; Wed, 12 Mar 2025 17:18:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741800363; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NdJOuBmX9SguRlV4ySt31f7a0lx6/58n/a/Hu8KfqZA=; b=eVUZrmOOtHfVyM5XXt+0FUZ3h1DtgAZ0SbCPea4v14QP91Dm+ZnZF+lgsSMolcJkxT7VoA 1OgM6bC5PJtlkxCV00lUyvjUI3AdRIQqHLN1C59OyuN+nubG7hj7P24pLf7syZ7mgBBkHO STPbL6a51lrlojIKl6CZ3JoenglDjKg= X-MC-Unique: grQ9pbwYNfqeRr0BKRh-pg-1 X-Mimecast-MFC-AGG-ID: grQ9pbwYNfqeRr0BKRh-pg_1741800361 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 21/22] rpc: don't let systemd shutdown daemon while saving VMs Date: Wed, 12 Mar 2025 17:18:01 +0000 Message-ID: <20250312171802.1854985-22-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 8Am3EZoN6_oszosrVRY2Q99KUeSjoUtHxg3-SXwE6yg_1741800361 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: I264QJU2F472WRPCQNSZ7NCRMJINWW3C X-Message-ID-Hash: I264QJU2F472WRPCQNSZ7NCRMJINWW3C X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800628830019000 Content-Type: text/plain; charset="utf-8" The service unit "TimeoutStopSec" setting controls how long systemd waits for a service to stop before aggressively killing it, defaulting to 30 seconds if not set. When we're processing shutdown of VMs in response to OS shutdown, we very likely need more than 30 seconds to complete this job, and can not stop the daemon during this time. To avoid being prematurely killed, setup a timer that repeatedly extends the "TimeoutStopSec" value while stop of running VMs is arranged. This does mean if libvirt hangs while stoppping VMs, systemd won't get to kill the libvirt daemon, but this is considered less harmful that forcefully killing running VMs. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/rpc/virnetdaemon.c | 53 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c index 53dee60703..944a832ea8 100644 --- a/src/rpc/virnetdaemon.c +++ b/src/rpc/virnetdaemon.c @@ -84,6 +84,7 @@ struct _virNetDaemon { virNetDaemonLifecycleCallback shutdownPrepareCb; virNetDaemonLifecycleCallback shutdownWaitCb; virThread *stateStopThread; + int stopTimer; int quitTimer; virNetDaemonQuitPhase quit; bool graceful; @@ -99,6 +100,25 @@ struct _virNetDaemon { =20 static virClass *virNetDaemonClass; =20 +/* + * When running state stop operation which can be slow... + * + * How frequently we tell systemd to extend our stop time, + * and how much we ask for each time. The latter should + * exceed the former with a decent tolerance for high load + * scenarios + */ +#define VIR_NET_DAEMON_STOP_EXTEND_INTERVAL_MSEC (5 * 1000) +#define VIR_NET_DAEMON_STOP_EXTRA_TIME_SEC 10 + +/* + * When running daemon shutdown synchronization which + * ought to be moderately fast + */ +#define VIR_NET_DAEMON_SHUTDOWN_TIMEOUT_SEC 30 +#define VIR_NET_DAEMON_SHUTDOWN_TIMEOUT_MSEC (VIR_NET_DAEMON_SHUTDOWN_TIME= OUT_SEC * 1000) + + static int daemonServerClose(void *payload, const char *key G_GNUC_UNUSED, @@ -168,6 +188,7 @@ virNetDaemonNew(void) if (virEventRegisterDefaultImpl() < 0) goto error; =20 + dmn->stopTimer =3D -1; dmn->autoShutdownTimerID =3D -1; =20 #ifndef WIN32 @@ -737,6 +758,23 @@ daemonShutdownWait(void *opaque) } } =20 +static void +virNetDaemonStopTimer(int timerid G_GNUC_UNUSED, + void *opaque) +{ + virNetDaemon *dmn =3D opaque; + VIR_LOCK_GUARD lock =3D virObjectLockGuard(dmn); + + if (dmn->quit !=3D VIR_NET_DAEMON_QUIT_STOPPING) + return; + + VIR_DEBUG("Extending stop timeout %u", + VIR_NET_DAEMON_STOP_EXTRA_TIME_SEC); + + virSystemdNotifyExtendTimeout(VIR_NET_DAEMON_STOP_EXTRA_TIME_SEC); +} + + static void virNetDaemonQuitTimer(int timerid G_GNUC_UNUSED, void *opaque) @@ -791,11 +829,19 @@ virNetDaemonRun(virNetDaemon *dmn) =20 if (dmn->quit =3D=3D VIR_NET_DAEMON_QUIT_REQUESTED) { VIR_DEBUG("Process quit request"); + virSystemdNotifyStopping(); virHashForEach(dmn->servers, daemonServerClose, NULL); =20 if (dmn->stateStopThread) { VIR_DEBUG("State stop thread running"); dmn->quit =3D VIR_NET_DAEMON_QUIT_STOPPING; + virSystemdNotifyExtendTimeout(VIR_NET_DAEMON_STOP_EXTRA_TI= ME_SEC); + if ((dmn->stopTimer =3D virEventAddTimeout(VIR_NET_DAEMON_= STOP_EXTEND_INTERVAL_MSEC, + virNetDaemonStopT= imer, + dmn, NULL)) < 0) { + VIR_WARN("Failed to register stop timer"); + /* hope for the best */ + } } else { VIR_DEBUG("Ready to shutdown"); dmn->quit =3D VIR_NET_DAEMON_QUIT_READY; @@ -807,7 +853,8 @@ virNetDaemonRun(virNetDaemon *dmn) if (dmn->shutdownPrepareCb && dmn->shutdownPrepareCb() < 0) break; =20 - if ((dmn->quitTimer =3D virEventAddTimeout(30 * 1000, + virSystemdNotifyExtendTimeout(VIR_NET_DAEMON_SHUTDOWN_TIMEOUT_= SEC); + if ((dmn->quitTimer =3D virEventAddTimeout(VIR_NET_DAEMON_SHUT= DOWN_TIMEOUT_MSEC, virNetDaemonQuitTimer, dmn, NULL)) < 0) { VIR_WARN("Failed to register finish timer."); @@ -879,6 +926,10 @@ virNetDaemonStopWorker(void *opaque) dmn->quit =3D VIR_NET_DAEMON_QUIT_READY; } g_clear_pointer(&dmn->stateStopThread, g_free); + if (dmn->stopTimer !=3D -1) { + virEventRemoveTimeout(dmn->stopTimer); + dmn->stopTimer =3D -1; + } } =20 VIR_DEBUG("End stop dmn=3D%p", dmn); --=20 2.48.1 From nobody Fri May 23 10:44:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1741800260340546.1804734249586; Wed, 12 Mar 2025 10:24:20 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 5197B1F4A; Wed, 12 Mar 2025 13:24:19 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id E48751ED7; Wed, 12 Mar 2025 13:19:14 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 1B1C11C78; Wed, 12 Mar 2025 13:19:08 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 2C3591E2B for ; Wed, 12 Mar 2025 13:18:47 -0400 (EDT) Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-398-dt3FYsr8Pdq2pnpqFW5eoQ-1; Wed, 12 Mar 2025 13:18:41 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 479C41955E8D for ; Wed, 12 Mar 2025 17:18:40 +0000 (UTC) Received: from toolbx.redhat.com (unknown [10.42.28.57]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2853718001D4; Wed, 12 Mar 2025 17:18:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741799926; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WsV0nGTvrUABdXZAxEqftr4IzpYCI5yHmeydEAUjA5Q=; b=ESxz/YCNRbUSf38uo8cQnKzf9bPa8JoDMrxE5uZQ1z4f2iOPqZPh4alc1dU8Bp+G61zEM1 yTiGnIHciXqGyn/NkoibD6bkv00SKcRhPIQbJRoPTvTfugNA0SaixVvSkf+35IK2s7VZJm mbRavG2c6XslT8AWS6CCu/uk/x2NI54= X-MC-Unique: dt3FYsr8Pdq2pnpqFW5eoQ-1 X-Mimecast-MFC-AGG-ID: dt3FYsr8Pdq2pnpqFW5eoQ_1741799920 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: devel@lists.libvirt.org Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [PATCH v2 22/22] hypervisor: emit systemd status & log messages while saving Date: Wed, 12 Mar 2025 17:18:02 +0000 Message-ID: <20250312171802.1854985-23-berrange@redhat.com> In-Reply-To: <20250312171802.1854985-1-berrange@redhat.com> References: <20250312171802.1854985-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Wk3DHTzyWJ1KvN7enMDrP7ROM46cWIS1gGBd_wRH_nM_1741799920 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: GYFIA2FRT6IDWVWQO6ACL6WKABPHXUH5 X-Message-ID-Hash: GYFIA2FRT6IDWVWQO6ACL6WKABPHXUH5 X-MailFrom: berrange@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1741800261820019100 Content-Type: text/plain; charset="utf-8" Since processing running VMs on OS shutdown can take a while, it is beneficial to send systemd status messages about the progress. The systemd status is a point-in-time message, with no ability to look at the history of received messages. So in the systemd status we include the progress information. For the same reason there is no benefit in sending failure messages, as they'll disappear as soon as a status is sent for the subsequent VM to be processed. The libvirt log statements can be viewed as a complete log record so don't need progress info, but do include warnings about failures (present from earlier commits). Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Peter Krempa --- src/hypervisor/domain_driver.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index 1105d36388..c7ffd21f05 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -30,6 +30,7 @@ #include "datatypes.h" #include "driver.h" #include "virlog.h" +#include "virsystemd.h" =20 #define VIR_FROM_THIS VIR_FROM_DOMAIN =20 @@ -814,6 +815,10 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) (!transient[i] && cfg->trySave =3D=3D VIR_DOMAIN_DRIVER_AU= TO_SHUTDOWN_SCOPE_TRANSIENT)) continue; =20 + virSystemdNotifyStatus("Suspending '%s' (%zu of %d)", + virDomainGetName(domains[i]), i + 1, nu= mDomains); + VIR_INFO("Suspending '%s'", virDomainGetName(domains[i])); + /* * Pause all VMs to make them stop dirtying pages, * so save is quicker. We remember if any VMs were @@ -832,6 +837,10 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) } =20 for (i =3D 0; i < numDomains; i++) { + virSystemdNotifyStatus("Saving '%s' (%zu of %d)", + virDomainGetName(domains[i]), i + 1, nu= mDomains); + VIR_INFO("Saving '%s'", virDomainGetName(domains[i])); + if (virDomainManagedSave(domains[i], flags[i]) < 0) { VIR_WARN("Unable to perform managed save of '%s': %s", virDomainGetName(domains[i]), @@ -855,6 +864,10 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdow= nConfig *cfg) (!transient[i] && cfg->tryShutdown =3D=3D VIR_DOMAIN_DRIVE= R_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) continue; =20 + virSystemdNotifyStatus("Shutting down '%s' (%zu of %d)", + virDomainGetName(domains[i]), i + 1, nu= mDomains); + VIR_INFO("Shutting down '%s'", virDomainGetName(domains[i])); + if (virDomainShutdown(domains[i]) < 0) { VIR_WARN("Unable to request graceful shutdown of '%s': %s", virDomainGetName(domains[i]), @@ -864,6 +877,9 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdown= Config *cfg) } =20 timer =3D g_timer_new(); + virSystemdNotifyStatus("Waiting %d secs for VM shutdown completion= ", + cfg->waitShutdownSecs); + VIR_INFO("Waiting %d secs for VM shutdown completion", cfg->waitSh= utdownSecs); while (1) { bool anyRunning =3D false; for (i =3D 0; i < numDomains; i++) { @@ -900,6 +916,9 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdown= Config *cfg) (!transient[i] && cfg->poweroff =3D=3D VIR_DOMAIN_DRIVER_A= UTO_SHUTDOWN_SCOPE_TRANSIENT)) continue; =20 + virSystemdNotifyStatus("Destroying '%s' (%zu of %d)", + virDomainGetName(domains[i]), i + 1, nu= mDomains); + VIR_INFO("Destroying '%s'", virDomainGetName(domains[i])); /* * NB might fail if we gave up on waiting for * virDomainShutdown, but it then completed anyway, @@ -912,6 +931,9 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdown= Config *cfg) } } =20 + virSystemdNotifyStatus("Processed %d domains", numDomains); + VIR_INFO("Processed %d domains", numDomains); + cleanup: if (domains) { /* Anything non-NULL in this list indicates none of --=20 2.48.1