From nobody Mon Feb 9 06:48:18 2026 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=linux.microsoft.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1710150614338793.6440348118111; Mon, 11 Mar 2024 02:50:14 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 3C33F1E6A; Mon, 11 Mar 2024 05:50:13 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 3F34C1E34; Mon, 11 Mar 2024 05:44:35 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 29D651C87; Mon, 11 Mar 2024 05:44:11 -0400 (EDT) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lists.libvirt.org (Postfix) with ESMTP id E88FC1C31 for ; Mon, 11 Mar 2024 05:44:09 -0400 (EDT) Received: from paekkaladevi-dev-u22.gi4irqh5pfqublruu4yyku2wof.phxx.internal.cloudapp.net (unknown [20.125.125.171]) by linux.microsoft.com (Postfix) with ESMTPSA id D3E4B20B74C4; Mon, 11 Mar 2024 02:44:08 -0700 (PDT) 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=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D3E4B20B74C4 From: Purna Pavan Chandra Aekkaladevi To: devel@lists.libvirt.org Subject: [PATCH 03/11] ch_driver: Add domainSave, domainSaveFlags callbacks Date: Mon, 11 Mar 2024 09:43:59 +0000 Message-Id: <20240311094407.12217-4-paekkaladevi@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240311094407.12217-1-paekkaladevi@linux.microsoft.com> References: <20240311094407.12217-1-paekkaladevi@linux.microsoft.com> MIME-Version: 1.0 Message-ID-Hash: JOF3KV7AWOP7LJOBVDD2ETMKLBOL6BWG X-Message-ID-Hash: JOF3KV7AWOP7LJOBVDD2ETMKLBOL6BWG X-MailFrom: paekkaladevi@linux.microsoft.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 CC: prapal@linux.microsoft.com, paekkaladevi@microsoft.com, liuwe@microsoft.com, kumarpraveen@linux.microsoft.com, Purna Pavan Chandra Aekkaladevi 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: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1710150615871100001 Implemented save callbacks. CH's vmm.snapshot API is called to save the domain state. The path passed to these callbacks has to be of directory as CH takes dir as input to snapshot and saves multiple files under it. Signed-off-by: Purna Pavan Chandra Aekkaladevi --- src/ch/ch_conf.h | 11 ++++ src/ch/ch_driver.c | 144 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h index 579eca894e..4b4c3345b6 100644 --- a/src/ch/ch_conf.h +++ b/src/ch/ch_conf.h @@ -81,6 +81,17 @@ struct _virCHDriver ebtablesContext *ebtables; }; =20 +#define CH_SAVE_MAGIC "libvirt-xml\n \0 \r" +#define CH_SAVE_XML "libvirt-save.xml" + +typedef struct _CHSaveXMLHeader CHSaveXMLHeader; +struct _CHSaveXMLHeader { + char magic[sizeof(CH_SAVE_MAGIC)-1]; + uint32_t xmlLen; + /* 20 bytes used, pad up to 64 bytes */ + uint32_t unused[11]; +}; + virCaps *virCHDriverCapsInit(void); virCaps *virCHDriverGetCapabilities(virCHDriver *driver, bool refresh); diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index 2601eea44b..24f697d2e1 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -19,6 +19,7 @@ */ =20 #include +#include =20 #include "ch_capabilities.h" #include "ch_conf.h" @@ -34,6 +35,7 @@ #include "virerror.h" #include "virlog.h" #include "virobject.h" +#include "virfile.h" #include "virtypedparam.h" #include "virutil.h" #include "viruuid.h" @@ -621,6 +623,146 @@ chDomainDestroy(virDomainPtr dom) return chDomainDestroyFlags(dom, 0); } =20 +/** + * chDoDomainSave: + * @driver: pointer to driver structure + * @vm: pointer to virtual machine structure. Must be locked before invoca= tion. + * @to_dir: directory path (CH needs directory input) to save the domain + * @managed: whether the VM is managed or not + * + * Checks if the domain is running or paused, then suspends it and saves it + * using CH's vmm.snapshot API. CH creates multiple files for config, memo= ry, + * device state into @to_dir. + * + * Returns 0 on success or -1 in case of error + */ +static int +chDoDomainSave(virCHDriver *driver, + virDomainObj *vm, + const char *to_dir, + bool managed) +{ + g_autoptr(virCHDriverConfig) cfg =3D virCHDriverGetConfig(driver); + virCHDomainObjPrivate *priv =3D vm->privateData; + CHSaveXMLHeader hdr; + g_autofree char *to =3D NULL; + g_autofree char *xml =3D NULL; + uint32_t xml_len; + VIR_AUTOCLOSE fd =3D -1; + int ret =3D -1; + + virDomainState domainState =3D virDomainObjGetState(vm, NULL); + if (domainState =3D=3D VIR_DOMAIN_RUNNING) { + if (virCHMonitorSuspendVM(priv->monitor) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to suspend domain before saving")); + goto end; + } + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_SAVE= ); + } else if (domainState !=3D VIR_DOMAIN_PAUSED) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("only can save running/paused domain")); + goto end; + } + + if (virDirCreate(to_dir, 0770, cfg->user, cfg->group, + VIR_DIR_CREATE_ALLOW_EXIST) < 0) { + virReportSystemError(errno, _("Failed to create SAVE dir %1$s"), t= o_dir); + goto end; + } + + to =3D g_strdup_printf("%s/%s", to_dir, CH_SAVE_XML); + if ((fd =3D virFileOpenAs(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUS= R, + cfg->user, cfg->group, 0)) < 0) { + virReportSystemError(-fd, + _("Failed to create/open domain save xml file= '%1$s'"), + to); + goto end; + } + + if ((xml =3D virDomainDefFormat(vm->def, driver->xmlopt, 0)) =3D=3D NU= LL) + goto end; + xml_len =3D strlen(xml) + 1; + + memset(&hdr, 0, sizeof(hdr)); + memcpy(hdr.magic, CH_SAVE_MAGIC, sizeof(hdr.magic)); + hdr.xmlLen =3D xml_len; + + if (safewrite(fd, &hdr, sizeof(hdr)) !=3D sizeof(hdr)) { + virReportSystemError(errno, "%s", _("Failed to write file header")= ); + goto end; + } + + if (safewrite(fd, xml, xml_len) !=3D xml_len) { + virReportSystemError(errno, "%s", _("Failed to write xml definitio= n")); + goto end; + } + + if (virCHMonitorSaveVM(priv->monitor, to_dir) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to save dom= ain")); + goto end; + } + + if (virCHProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SAVED) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to shutoff after domain save")); + goto end; + } + + vm->hasManagedSave =3D managed; + ret =3D 0; + + end: + return ret; +} + +static int +chDomainSaveFlags(virDomainPtr dom, const char *to, const char *dxml, unsi= gned int flags) +{ + virCHDriver *driver =3D dom->conn->privateData; + virDomainObj *vm =3D NULL; + int ret =3D -1; + + virCheckFlags(0, -1); + if (dxml) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("xml modification unsupported")); + return -1; + } + + if (!(vm =3D virCHDomainObjFromDomain(dom))) + goto cleanup; + + if (virDomainSaveFlagsEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + if (chDoDomainSave(driver, vm, to, false) < 0) + goto endjob; + + /* Remove if VM is not persistent */ + virCHDomainRemoveInactive(driver, vm); + ret =3D 0; + + endjob: + virDomainObjEndJob(vm); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + +static int +chDomainSave(virDomainPtr dom, const char *to) +{ + return chDomainSaveFlags(dom, to, NULL, 0); +} + static virDomainPtr chDomainLookupByID(virConnectPtr conn, int id) { @@ -1743,6 +1885,8 @@ static virHypervisorDriver chHypervisorDriver =3D { .nodeGetCPUMap =3D chNodeGetCPUMap, /* 8.0.0 */ .domainSetNumaParameters =3D chDomainSetNumaParameters, /* 8.1.0 */ .domainGetNumaParameters =3D chDomainGetNumaParameters, /* 8.1.0 */ + .domainSave =3D chDomainSave, /* 10.2.0 */ + .domainSaveFlags =3D chDomainSaveFlags, /* 10.2.0 */ }; =20 static virConnectDriver chConnectDriver =3D { --=20 2.34.1 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org