From nobody Fri May 16 07:20:45 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1496769736605127.49372575746656; Tue, 6 Jun 2017 10:22:16 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D7C880471; Tue, 6 Jun 2017 17:22:14 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B41F981B54; Tue, 6 Jun 2017 17:22:13 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6AE934A48C; Tue, 6 Jun 2017 17:22:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v559RCwg002062 for ; Mon, 5 Jun 2017 05:27:12 -0400 Received: by smtp.corp.redhat.com (Postfix) id D8A01869FE; Mon, 5 Jun 2017 09:27:12 +0000 (UTC) Received: from virval.usersys.redhat.com (dhcp129-92.brq.redhat.com [10.34.129.92]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 82D2C7A319 for ; Mon, 5 Jun 2017 09:27:09 +0000 (UTC) Received: by virval.usersys.redhat.com (Postfix, from userid 500) id AF9FD10CCFF; Mon, 5 Jun 2017 11:27:04 +0200 (CEST) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0D7C880471 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 0D7C880471 From: Jiri Denemark To: libvir-list@redhat.com Date: Mon, 5 Jun 2017 11:26:58 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: Mail-Followup-To: libvir-list@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 10/15] qemu: Store save cookie in save images and snapshots X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 06 Jun 2017 17:22:14 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The following patches will add an actual content in the cookie and use the data when restoring a domain. Signed-off-by: Jiri Denemark --- docs/formatsnapshot.html.in | 6 +++ docs/schemas/domainsnapshot.rng | 7 ++++ src/qemu/qemu_driver.c | 90 ++++++++++++++++++++++++++++++++++++-= ---- 3 files changed, 93 insertions(+), 10 deletions(-) diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in index c3ab516fa..5e8e21c8a 100644 --- a/docs/formatsnapshot.html.in +++ b/docs/formatsnapshot.html.in @@ -235,6 +235,12 @@ at the time of the snapshot (since 0.9.5). Readonly. +
cookie
+
Save image cookie containing additional data libvirt may need to + properly restore a domain from an active snapshot when such data + cannot be stored directly in the domain to maintain + compatibility with older libvirt or hypervisor. Readonly. +
=20

Examples

diff --git a/docs/schemas/domainsnapshot.rng b/docs/schemas/domainsnapshot.= rng index 4ab1b828f..268088709 100644 --- a/docs/schemas/domainsnapshot.rng +++ b/docs/schemas/domainsnapshot.rng @@ -90,6 +90,13 @@ + + + + + + + diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 96077df78..10df56e61 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2808,7 +2808,8 @@ struct _virQEMUSaveHeader { uint32_t data_len; uint32_t was_running; uint32_t compressed; - uint32_t unused[15]; + uint32_t cookie; + uint32_t unused[14]; }; =20 typedef struct _virQEMUSaveData virQEMUSaveData; @@ -2816,6 +2817,7 @@ typedef virQEMUSaveData *virQEMUSaveDataPtr; struct _virQEMUSaveData { virQEMUSaveHeader header; char *xml; + char *cookie; }; =20 =20 @@ -2826,6 +2828,7 @@ bswap_header(virQEMUSaveHeaderPtr hdr) hdr->data_len =3D bswap_32(hdr->data_len); hdr->was_running =3D bswap_32(hdr->was_running); hdr->compressed =3D bswap_32(hdr->compressed); + hdr->cookie =3D bswap_32(hdr->cookie); } =20 =20 @@ -2836,6 +2839,7 @@ virQEMUSaveDataFree(virQEMUSaveDataPtr data) return; =20 VIR_FREE(data->xml); + VIR_FREE(data->cookie); VIR_FREE(data); } =20 @@ -2845,8 +2849,10 @@ virQEMUSaveDataFree(virQEMUSaveDataPtr data) */ static virQEMUSaveDataPtr virQEMUSaveDataNew(char *domXML, + qemuDomainSaveCookiePtr cookie, bool running, - int compressed) + int compressed, + virDomainXMLOptionPtr xmlopt) { virQEMUSaveDataPtr data =3D NULL; virQEMUSaveHeaderPtr header; @@ -2856,6 +2862,11 @@ virQEMUSaveDataNew(char *domXML, =20 VIR_STEAL_PTR(data->xml, domXML); =20 + if (cookie && + !(data->cookie =3D virSaveCookieFormat((virObjectPtr) cookie, + virDomainXMLOptionGetSaveCook= ie(xmlopt)))) + goto error; + header =3D &data->header; memcpy(header->magic, QEMU_SAVE_PARTIAL, sizeof(header->magic)); header->version =3D QEMU_SAVE_VERSION; @@ -2863,6 +2874,10 @@ virQEMUSaveDataNew(char *domXML, header->compressed =3D compressed; =20 return data; + + error: + virQEMUSaveDataFree(data); + return NULL; } =20 =20 @@ -2882,9 +2897,15 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data, { virQEMUSaveHeaderPtr header =3D &data->header; size_t len; + size_t xml_len; + size_t cookie_len =3D 0; int ret =3D -1; =20 - len =3D strlen(data->xml) + 1; + xml_len =3D strlen(data->xml) + 1; + if (data->cookie) + cookie_len =3D strlen(data->cookie) + 1; + + len =3D xml_len + cookie_len; =20 if (header->data_len > 0) { if (len > header->data_len) { @@ -2893,12 +2914,15 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data, goto cleanup; } =20 - if (VIR_EXPAND_N(data->xml, len, header->data_len - len) < 0) + if (VIR_EXPAND_N(data->xml, xml_len, header->data_len - len) < 0) goto cleanup; } else { header->data_len =3D len; } =20 + if (data->cookie) + header->cookie =3D xml_len; + if (safewrite(fd, header, sizeof(*header)) !=3D sizeof(*header)) { virReportSystemError(errno, _("failed to write header to domain save file= '%s'"), @@ -2906,13 +2930,21 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data, goto cleanup; } =20 - if (safewrite(fd, data->xml, header->data_len) !=3D header->data_len) { + if (safewrite(fd, data->xml, xml_len) !=3D xml_len) { virReportSystemError(errno, _("failed to write domain xml to '%s'"), path); goto cleanup; } =20 + if (data->cookie && + safewrite(fd, data->cookie, cookie_len) !=3D cookie_len) { + virReportSystemError(errno, + _("failed to write cookie to '%s'"), + path); + goto cleanup; + } + ret =3D 0; =20 cleanup: @@ -3245,6 +3277,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDo= mainPtr dom, qemuDomainObjPrivatePtr priv =3D vm->privateData; virCapsPtr caps; virQEMUSaveDataPtr data =3D NULL; + qemuDomainSaveCookiePtr cookie =3D NULL; =20 if (!(caps =3D virQEMUDriverGetCapabilities(driver, false))) goto cleanup; @@ -3310,7 +3343,11 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virD= omainPtr dom, goto endjob; } =20 - if (!(data =3D virQEMUSaveDataNew(xml, was_running, compressed))) + if (!(cookie =3D qemuDomainSaveCookieNew(vm))) + goto endjob; + + if (!(data =3D virQEMUSaveDataNew(xml, cookie, was_running, compressed, + driver->xmlopt))) goto endjob; xml =3D NULL; =20 @@ -3347,6 +3384,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDo= mainPtr dom, qemuDomainRemoveInactive(driver, vm); =20 cleanup: + virObjectUnref(cookie); VIR_FREE(xml); virQEMUSaveDataFree(data); qemuDomainEventQueue(driver, event); @@ -6283,6 +6321,8 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, virDomainDefPtr def =3D NULL; int oflags =3D open_write ? O_RDWR : O_RDONLY; virCapsPtr caps =3D NULL; + size_t xml_len; + size_t cookie_len; =20 if (bypass_cache) { int directFlag =3D virFileDirectFdFlag(); @@ -6363,15 +6403,33 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver, goto error; } =20 - if (VIR_ALLOC_N(data->xml, header->data_len) < 0) + if (header->cookie) + xml_len =3D header->cookie; + else + xml_len =3D header->data_len; + + cookie_len =3D header->data_len - xml_len; + + if (VIR_ALLOC_N(data->xml, xml_len) < 0) goto error; =20 - if (saferead(fd, data->xml, header->data_len) !=3D header->data_len) { + if (saferead(fd, data->xml, xml_len) !=3D xml_len) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to read domain XML")); goto error; } =20 + if (cookie_len > 0) { + if (VIR_ALLOC_N(data->cookie, cookie_len) < 0) + goto error; + + if (saferead(fd, data->cookie, cookie_len) !=3D cookie_len) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("failed to read cookie")); + goto error; + } + } + /* Create a domain from this XML */ if (!(def =3D virDomainDefParseString(data->xml, caps, driver->xmlopt,= NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE | @@ -6412,6 +6470,11 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, char *errbuf =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); virQEMUSaveHeaderPtr header =3D &data->header; + qemuDomainSaveCookiePtr cookie =3D NULL; + + if (virSaveCookieParseString(data->cookie, (virObjectPtr *) &cookie, + virDomainXMLOptionGetSaveCookie(driver->x= mlopt)) < 0) + goto cleanup; =20 if ((header->version =3D=3D 2) && (header->compressed !=3D QEMU_SAVE_FORMAT_RAW)) { @@ -6502,6 +6565,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, ret =3D 0; =20 cleanup: + virObjectUnref(cookie); virCommandFree(cmd); VIR_FREE(errbuf); if (qemuSecurityRestoreSavedStateLabel(driver->securityManager, @@ -13554,6 +13618,9 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPt= r conn, if (ret < 0) goto cleanup; =20 + if (!(snap->def->cookie =3D (virObjectPtr) qemuDomainSaveCookieNew(vm)= )) + goto cleanup; + if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) { event =3D virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_S= TOPPED, VIR_DOMAIN_EVENT_STOPPED_FROM_SNA= PSHOT); @@ -14433,10 +14500,13 @@ qemuDomainSnapshotCreateActiveExternal(virConnect= Ptr conn, "snapshot", false)) < = 0) goto cleanup; =20 - if (!(xml =3D qemuDomainDefFormatLive(driver, vm->def, true, true)= )) + if (!(xml =3D qemuDomainDefFormatLive(driver, vm->def, true, true)= ) || + !(snap->def->cookie =3D (virObjectPtr) qemuDomainSaveCookieNew= (vm))) goto cleanup; =20 - if (!(data =3D virQEMUSaveDataNew(xml, resume, compressed))) + if (!(data =3D virQEMUSaveDataNew(xml, + (qemuDomainSaveCookiePtr) snap->de= f->cookie, + resume, compressed, driver->xmlopt= ))) goto cleanup; xml =3D NULL; =20 --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list