From nobody Mon Dec 15 09:41:38 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