From nobody Mon Feb 9 13:38:01 2026 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.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1568982101; cv=none; d=zoho.com; s=zohoarc; b=CYZVBQ/XJTLh9T3/Tuwqz1hz7iDjxobDxvslJBkZsJ6m7vUsF0bxJIUZsjP3vVtQC/Kcq6kAKeayb2FMbgsZ2Nr07QI3oEITrpKoUNCF9y16bGWeWMPunzsS9goC/d1njSK2OsPlzNx1QzusQNt0JY4SCwKPN0/s17RscEVV2AI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1568982101; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=TW9OyTrO/xFhSniv93+zQcUFVKVe3xVsE3WeWxbQMHM=; b=i/bzNSf8aWltIjoTfyFsN7l0PHz26pySeVU64vw4+IZQlU/AvuMidWk8DIm5bX8+KVLtAgrnsoKTdvqXm+eWSyOdhxhGWgM7Gl6wyGlFy8akxbnF5Hf5sW0O6i3RDh+3onKUTuTJdMTJfqZHzu5U7vnZ/Ve3tLQ5FXm7craa6Rc= ARC-Authentication-Results: i=1; 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; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1568982101058456.43902009132853; Fri, 20 Sep 2019 05:21:41 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0A4A8A26679; Fri, 20 Sep 2019 12:21:39 +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 D87645D6B0; Fri, 20 Sep 2019 12:21:38 +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 9FCEB4EE6F; Fri, 20 Sep 2019 12:21:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x8KCLTQD006771 for ; Fri, 20 Sep 2019 08:21:29 -0400 Received: by smtp.corp.redhat.com (Postfix) id 69F07608C2; Fri, 20 Sep 2019 12:21:29 +0000 (UTC) Received: from angien.brq.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id E765D6061E for ; Fri, 20 Sep 2019 12:21:28 +0000 (UTC) From: Peter Krempa To: libvir-list@redhat.com Date: Fri, 20 Sep 2019 14:21:19 +0200 Message-Id: <8dccd3411550a33bdd3d686811980ca08cfd327c.1568981923.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 6/7] qemu: domain: Move checkpoint related code to qemu_checkpoint.c 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: , 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.68]); Fri, 20 Sep 2019 12:21:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Peter Krempa --- src/qemu/qemu_checkpoint.c | 185 ++++++++++++++++++++++++++++++++++--- src/qemu/qemu_checkpoint.h | 5 + src/qemu/qemu_domain.c | 162 +------------------------------- src/qemu/qemu_domain.h | 15 --- 4 files changed, 180 insertions(+), 187 deletions(-) diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c index 9e9af76871..22f0ffb26e 100644 --- a/src/qemu/qemu_checkpoint.c +++ b/src/qemu/qemu_checkpoint.c @@ -76,6 +76,169 @@ qemuCheckpointObjFromCheckpoint(virDomainObjPtr vm, } +static int +qemuCheckpointWriteMetadata(virDomainObjPtr vm, + virDomainMomentObjPtr checkpoint, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + const char *checkpointDir) +{ + unsigned int flags =3D VIR_DOMAIN_CHECKPOINT_FORMAT_SECURE; + virDomainCheckpointDefPtr def =3D virDomainCheckpointObjGetDef(checkpo= int); + VIR_AUTOFREE(char *) newxml =3D NULL; + VIR_AUTOFREE(char *) chkDir =3D NULL; + VIR_AUTOFREE(char *) chkFile =3D NULL; + + newxml =3D virDomainCheckpointDefFormat(def, caps, xmlopt, flags); + if (newxml =3D=3D NULL) + return -1; + + if (virAsprintf(&chkDir, "%s/%s", checkpointDir, vm->def->name) < 0) + return -1; + if (virFileMakePath(chkDir) < 0) { + virReportSystemError(errno, _("cannot create checkpoint directory = '%s'"), + chkDir); + return -1; + } + + if (virAsprintf(&chkFile, "%s/%s.xml", chkDir, def->parent.name) < 0) + return -1; + + return virXMLSaveFile(chkFile, NULL, "checkpoint-edit", newxml); +} + + +static int +qemuDomainCheckpointDiscard(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainMomentObjPtr chk, + bool update_parent, + bool metadata_only) +{ + virDomainMomentObjPtr parent =3D NULL; + virDomainMomentObjPtr moment; + virDomainCheckpointDefPtr parentdef =3D NULL; + size_t i, j; + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg =3D virQEMUDriverGetConfig(d= river); + VIR_AUTOFREE(char *) chkFile =3D NULL; + + if (!metadata_only && !virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("cannot remove checkpoint from inactive domain")); + return -1; + } + + if (virAsprintf(&chkFile, "%s/%s/%s.xml", cfg->checkpointDir, + vm->def->name, chk->def->name) < 0) + return -1; + + if (!metadata_only) { + qemuDomainObjPrivatePtr priv =3D vm->privateData; + bool success =3D true; + bool search_parents; + virDomainCheckpointDefPtr chkdef =3D virDomainCheckpointObjGetDef(= chk); + + qemuDomainObjEnterMonitor(driver, vm); + parent =3D virDomainCheckpointFindByName(vm->checkpoints, + chk->def->parent_name); + for (i =3D 0; i < chkdef->ndisks; i++) { + virDomainCheckpointDiskDef *disk =3D &chkdef->disks[i]; + const char *node; + + if (disk->type !=3D VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) + continue; + + node =3D qemuDomainDiskNodeFormatLookup(vm, disk->name); + /* If any ancestor checkpoint has a bitmap for the same + * disk, then this bitmap must be merged to the + * ancestor. */ + search_parents =3D true; + for (moment =3D parent; + search_parents && moment; + moment =3D virDomainCheckpointFindByName(vm->checkpoints, + parentdef->parent.= parent_name)) { + parentdef =3D virDomainCheckpointObjGetDef(moment); + for (j =3D 0; j < parentdef->ndisks; j++) { + virDomainCheckpointDiskDef *disk2; + VIR_AUTOPTR(virJSONValue) arr =3D NULL; + + disk2 =3D &parentdef->disks[j]; + if (STRNEQ(disk->name, disk2->name) || + disk2->type !=3D VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) + continue; + search_parents =3D false; + + arr =3D virJSONValueNewArray(); + if (!arr || + virJSONValueArrayAppendString(arr, disk->bitmap) <= 0) { + success =3D false; + break; + } + if (chk =3D=3D virDomainCheckpointGetCurrent(vm->check= points) && + qemuMonitorEnableBitmap(priv->mon, node, + disk2->bitmap) < 0) { + success =3D false; + break; + } + if (qemuMonitorMergeBitmaps(priv->mon, node, + disk2->bitmap, &arr) < 0) { + success =3D false; + break; + } + } + } + if (qemuMonitorDeleteBitmap(priv->mon, node, disk->bitmap) < 0= ) { + success =3D false; + break; + } + } + if (qemuDomainObjExitMonitor(driver, vm) < 0 || !success) + return -1; + } + + if (chk =3D=3D virDomainCheckpointGetCurrent(vm->checkpoints)) { + virDomainCheckpointSetCurrent(vm->checkpoints, NULL); + if (update_parent && parent) { + virDomainCheckpointSetCurrent(vm->checkpoints, parent); + if (qemuCheckpointWriteMetadata(vm, parent, driver->caps, + driver->xmlopt, + cfg->checkpointDir) < 0) { + VIR_WARN("failed to set parent checkpoint '%s' as current", + chk->def->parent_name); + virDomainCheckpointSetCurrent(vm->checkpoints, NULL); + } + } + } + + if (unlink(chkFile) < 0) + VIR_WARN("Failed to unlink %s", chkFile); + if (update_parent) + virDomainMomentDropParent(chk); + virDomainCheckpointObjListRemove(vm->checkpoints, chk); + + return 0; +} + + +int +qemuDomainCheckpointDiscardAllMetadata(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + virQEMUMomentRemove rem =3D { + .driver =3D driver, + .vm =3D vm, + .metadata_only =3D true, + .momentDiscard =3D qemuDomainCheckpointDiscard, + }; + + virDomainCheckpointForEach(vm->checkpoints, qemuDomainMomentDiscardAll, + &rem); + virDomainCheckpointObjListRemoveAll(vm->checkpoints); + + return rem.err; +} + + /* Called inside job lock */ static int qemuDomainCheckpointPrepare(virQEMUDriverPtr driver, virCapsPtr caps, @@ -267,9 +430,9 @@ qemuCheckpointCreateXML(virDomainPtr domain, goto endjob; if (update_current) { virDomainCheckpointSetCurrent(vm->checkpoints, NULL); - if (qemuDomainCheckpointWriteMetadata(vm, other, - driver->caps, driver->xm= lopt, - cfg->checkpointDir) < 0) + if (qemuCheckpointWriteMetadata(vm, other, + driver->caps, driver->xmlopt, + cfg->checkpointDir) < 0) goto endjob; } } @@ -301,9 +464,9 @@ qemuCheckpointCreateXML(virDomainPtr domain, if (checkpoint) { if (update_current) virDomainCheckpointSetCurrent(vm->checkpoints, chk); - if (qemuDomainCheckpointWriteMetadata(vm, chk, driver->caps, - driver->xmlopt, - cfg->checkpointDir) < 0) { + if (qemuCheckpointWriteMetadata(vm, chk, driver->caps, + driver->xmlopt, + cfg->checkpointDir) < 0) { /* if writing of metadata fails, error out rather than trying * to silently carry on without completing the checkpoint */ virObjectUnref(checkpoint); @@ -384,8 +547,8 @@ qemuCheckpointReparentChildren(void *payload, return 0; } - rep->err =3D qemuDomainCheckpointWriteMetadata(rep->vm, moment, rep->c= aps, - rep->xmlopt, rep->dir); + rep->err =3D qemuCheckpointWriteMetadata(rep->vm, moment, rep->caps, + rep->xmlopt, rep->dir); return 0; } @@ -445,9 +608,9 @@ qemuCheckpointDelete(virDomainObjPtr vm, if (rem.found) { virDomainCheckpointSetCurrent(vm->checkpoints, chk); if (flags & VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY) { - if (qemuDomainCheckpointWriteMetadata(vm, chk, driver->cap= s, - driver->xmlopt, - cfg->checkpointDir) = < 0) { + if (qemuCheckpointWriteMetadata(vm, chk, driver->caps, + driver->xmlopt, + cfg->checkpointDir) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set checkpoint '%s' as cur= rent"), chk->def->name); diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h index 0d36d718d6..4cea4bcdb4 100644 --- a/src/qemu/qemu_checkpoint.h +++ b/src/qemu/qemu_checkpoint.h @@ -20,6 +20,7 @@ #include "virconftypes.h" #include "datatypes.h" +#include "qemu_conf.h" virDomainObjPtr qemuDomObjFromCheckpoint(virDomainCheckpointPtr checkpoint); @@ -32,6 +33,10 @@ virDomainMomentObjPtr qemuCheckpointObjFromName(virDomainObjPtr vm, const char *name); +int +qemuDomainCheckpointDiscardAllMetadata(virQEMUDriverPtr driver, + virDomainObjPtr vm); + virDomainCheckpointPtr qemuCheckpointCreateXML(virDomainPtr domain, virDomainObjPtr vm, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f733198ea9..8e4dc34dec 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -35,6 +35,7 @@ #include "qemu_slirp.h" #include "qemu_extdevice.h" #include "qemu_blockjob.h" +#include "qemu_checkpoint.h" #include "viralloc.h" #include "virlog.h" #include "virerror.h" @@ -9559,36 +9560,6 @@ qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm, return ret; } -int -qemuDomainCheckpointWriteMetadata(virDomainObjPtr vm, - virDomainMomentObjPtr checkpoint, - virCapsPtr caps, - virDomainXMLOptionPtr xmlopt, - const char *checkpointDir) -{ - unsigned int flags =3D VIR_DOMAIN_CHECKPOINT_FORMAT_SECURE; - virDomainCheckpointDefPtr def =3D virDomainCheckpointObjGetDef(checkpo= int); - VIR_AUTOFREE(char *) newxml =3D NULL; - VIR_AUTOFREE(char *) chkDir =3D NULL; - VIR_AUTOFREE(char *) chkFile =3D NULL; - - newxml =3D virDomainCheckpointDefFormat(def, caps, xmlopt, flags); - if (newxml =3D=3D NULL) - return -1; - - if (virAsprintf(&chkDir, "%s/%s", checkpointDir, vm->def->name) < 0) - return -1; - if (virFileMakePath(chkDir) < 0) { - virReportSystemError(errno, _("cannot create checkpoint directory = '%s'"), - chkDir); - return -1; - } - - if (virAsprintf(&chkFile, "%s/%s.xml", chkDir, def->parent.name) < 0) - return -1; - - return virXMLSaveFile(chkFile, NULL, "checkpoint-edit", newxml); -} /* The domain is expected to be locked and inactive. Return -1 on normal * failure, 1 if we skipped a disk due to try_all. */ @@ -9786,137 +9757,6 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverP= tr driver, } -/* Discard one checkpoint (or its metadata), without reparenting any child= ren. */ -int -qemuDomainCheckpointDiscard(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainMomentObjPtr chk, - bool update_parent, - bool metadata_only) -{ - virDomainMomentObjPtr parent =3D NULL; - virDomainMomentObjPtr moment; - virDomainCheckpointDefPtr parentdef =3D NULL; - size_t i, j; - VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg =3D virQEMUDriverGetConfig(d= river); - VIR_AUTOFREE(char *) chkFile =3D NULL; - - if (!metadata_only && !virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("cannot remove checkpoint from inactive domain")); - return -1; - } - - if (virAsprintf(&chkFile, "%s/%s/%s.xml", cfg->checkpointDir, - vm->def->name, chk->def->name) < 0) - return -1; - - if (!metadata_only) { - qemuDomainObjPrivatePtr priv =3D vm->privateData; - bool success =3D true; - bool search_parents; - virDomainCheckpointDefPtr chkdef =3D virDomainCheckpointObjGetDef(= chk); - - qemuDomainObjEnterMonitor(driver, vm); - parent =3D virDomainCheckpointFindByName(vm->checkpoints, - chk->def->parent_name); - for (i =3D 0; i < chkdef->ndisks; i++) { - virDomainCheckpointDiskDef *disk =3D &chkdef->disks[i]; - const char *node; - - if (disk->type !=3D VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) - continue; - - node =3D qemuDomainDiskNodeFormatLookup(vm, disk->name); - /* If any ancestor checkpoint has a bitmap for the same - * disk, then this bitmap must be merged to the - * ancestor. */ - search_parents =3D true; - for (moment =3D parent; - search_parents && moment; - moment =3D virDomainCheckpointFindByName(vm->checkpoints, - parentdef->parent.= parent_name)) { - parentdef =3D virDomainCheckpointObjGetDef(moment); - for (j =3D 0; j < parentdef->ndisks; j++) { - virDomainCheckpointDiskDef *disk2; - VIR_AUTOPTR(virJSONValue) arr =3D NULL; - - disk2 =3D &parentdef->disks[j]; - if (STRNEQ(disk->name, disk2->name) || - disk2->type !=3D VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) - continue; - search_parents =3D false; - - arr =3D virJSONValueNewArray(); - if (!arr || - virJSONValueArrayAppendString(arr, disk->bitmap) <= 0) { - success =3D false; - break; - } - if (chk =3D=3D virDomainCheckpointGetCurrent(vm->check= points) && - qemuMonitorEnableBitmap(priv->mon, node, - disk2->bitmap) < 0) { - success =3D false; - break; - } - if (qemuMonitorMergeBitmaps(priv->mon, node, - disk2->bitmap, &arr) < 0) { - success =3D false; - break; - } - } - } - if (qemuMonitorDeleteBitmap(priv->mon, node, disk->bitmap) < 0= ) { - success =3D false; - break; - } - } - if (qemuDomainObjExitMonitor(driver, vm) < 0 || !success) - return -1; - } - - if (chk =3D=3D virDomainCheckpointGetCurrent(vm->checkpoints)) { - virDomainCheckpointSetCurrent(vm->checkpoints, NULL); - if (update_parent && parent) { - virDomainCheckpointSetCurrent(vm->checkpoints, parent); - if (qemuDomainCheckpointWriteMetadata(vm, parent, driver->caps, - driver->xmlopt, - cfg->checkpointDir) < 0)= { - VIR_WARN("failed to set parent checkpoint '%s' as current", - chk->def->parent_name); - virDomainCheckpointSetCurrent(vm->checkpoints, NULL); - } - } - } - - if (unlink(chkFile) < 0) - VIR_WARN("Failed to unlink %s", chkFile); - if (update_parent) - virDomainMomentDropParent(chk); - virDomainCheckpointObjListRemove(vm->checkpoints, chk); - - return 0; -} - -int -qemuDomainCheckpointDiscardAllMetadata(virQEMUDriverPtr driver, - virDomainObjPtr vm) -{ - virQEMUMomentRemove rem =3D { - .driver =3D driver, - .vm =3D vm, - .metadata_only =3D true, - .momentDiscard =3D qemuDomainCheckpointDiscard, - }; - - virDomainCheckpointForEach(vm->checkpoints, qemuDomainMomentDiscardAll, - &rem); - virDomainCheckpointObjListRemoveAll(vm->checkpoints); - - return rem.err; -} - - static void qemuDomainRemoveInactiveCommon(virQEMUDriverPtr driver, virDomainObjPtr vm) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 63d780e79b..22335f5114 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -780,21 +780,6 @@ int qemuDomainMomentDiscardAll(void *payload, int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver, virDomainObjPtr vm); -int qemuDomainCheckpointWriteMetadata(virDomainObjPtr vm, - virDomainMomentObjPtr checkpoint, - virCapsPtr caps, - virDomainXMLOptionPtr xmlopt, - const char *checkpointDir); - -int qemuDomainCheckpointDiscard(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainMomentObjPtr chk, - bool update_current, - bool metadata_only); - -int qemuDomainCheckpointDiscardAllMetadata(virQEMUDriverPtr driver, - virDomainObjPtr vm); - void qemuDomainRemoveInactive(virQEMUDriverPtr driver, virDomainObjPtr vm); --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list