Re: [libvirt] [PATCH 5/5] snapshot: Support reparenting external disk snapshots when deleting

2018-11-07 Thread Peter Krempa
On Sun, Oct 21, 2018 at 19:38:52 +0300, Povilas Kanapickas wrote:
> Signed-off-by: Povilas Kanapickas 
> ---
>  src/qemu/qemu_driver.c | 89 ++
>  1 file changed, 89 insertions(+)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 227ec1c6d9..a3ffc19122 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c

[]

> @@ -16617,6 +16618,88 @@ 
> qemuDomainSnapshotReparentChildrenMetadata(virDomainSnapshotObjPtr snap,
> rep->cfg->snapshotDir);
>  }
>  
> +static int
> +qemuDomainSnapshotReparentDiskExternal(virQEMUDriverPtr driver,
> +   virDomainSnapshotObjPtr parent_snap,
> +   virDomainSnapshotDiskDefPtr disk)
> +{
> +const char* qemu_img_path = NULL;
> +virCommandPtr cmd = NULL;
> +int i;
> +int ret = -1;
> +const char* parent_disk_path = NULL;
> +
> +// Find the path to the disk we should use as the base when reparenting
> +// FIXME: what if there's no parent snapshot? i.e. we need to reparent on
> +// "empty" disk?
> +for (i = 0; i < parent_snap->def->dom->ndisks; ++i) {
> +if (STREQ(parent_snap->def->dom->disks[i]->dst, disk->name)) {
> +parent_disk_path = parent_snap->def->dom->disks[i]->src->path;
> +break;
> +}
> +}
> +
> +if (parent_disk_path == NULL) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not find disk to reparent '%s' to"),
> +   disk->src->path);
> +goto cleanup;
> +}
> +
> +if (!(qemu_img_path = qemuFindQemuImgBinary(driver))) {
> +goto cleanup;
> +}
> +
> +if (!(cmd = virCommandNewArgList(qemu_img_path,
> + "rebase", "-b", parent_disk_path,
> + disk->src->path,
> + NULL))) {

Okay, this solves the problems that I've mentioned previously. There
still might be problems with matching which images actually get deleted
if the definition changed.

Also note that it needs to support network disks.

This code also should be added together with the deletion code as they
are tightly related.

> +goto cleanup;
> +}
> +
> +if (virCommandRun(cmd, NULL) < 0)
> +goto cleanup;
> +
> +ret = 0;
> +cleanup:
> +virCommandFree(cmd);
> +return ret;
> +}
> +
> +static int
> +qemuDomainSnapshotReparentDisks(virDomainSnapshotObjPtr snap,
> +virQEMUSnapReparentPtr rep)
> +{
> +int i;
> +virDomainSnapshotDiskDefPtr snap_disk;
> +
> +if (!snap->def->dom) {
> +VIR_WARN("Any external disk snapshots in a snapshot created with "
> + "pre-0.9.5 libvirt will not be correctly reparented.");
> +// In snapshots created with pre-0.9.5 libvirt we don't have 
> information
> +// needed to correctly reparent external disk snapshots but we also
> +// don't even know whether external disk snapshots were used so that
> +// we could report this as an error. We can only emit a warning in 
> that
> +// case.

As said earlier, this should not happen with external snapshots.


signature.asc
Description: PGP signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH 5/5] snapshot: Support reparenting external disk snapshots when deleting

2018-10-21 Thread Povilas Kanapickas
Signed-off-by: Povilas Kanapickas 
---
 src/qemu/qemu_driver.c | 89 ++
 1 file changed, 89 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 227ec1c6d9..a3ffc19122 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16590,6 +16590,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr 
snapshot,
 typedef struct _virQEMUSnapReparent virQEMUSnapReparent;
 typedef virQEMUSnapReparent *virQEMUSnapReparentPtr;
 struct _virQEMUSnapReparent {
+virQEMUDriverPtr driver;
 virQEMUDriverConfigPtr cfg;
 virDomainSnapshotObjPtr parent;
 virDomainObjPtr vm;
@@ -16617,6 +16618,88 @@ 
qemuDomainSnapshotReparentChildrenMetadata(virDomainSnapshotObjPtr snap,
rep->cfg->snapshotDir);
 }
 
+static int
+qemuDomainSnapshotReparentDiskExternal(virQEMUDriverPtr driver,
+   virDomainSnapshotObjPtr parent_snap,
+   virDomainSnapshotDiskDefPtr disk)
+{
+const char* qemu_img_path = NULL;
+virCommandPtr cmd = NULL;
+int i;
+int ret = -1;
+const char* parent_disk_path = NULL;
+
+// Find the path to the disk we should use as the base when reparenting
+// FIXME: what if there's no parent snapshot? i.e. we need to reparent on
+// "empty" disk?
+for (i = 0; i < parent_snap->def->dom->ndisks; ++i) {
+if (STREQ(parent_snap->def->dom->disks[i]->dst, disk->name)) {
+parent_disk_path = parent_snap->def->dom->disks[i]->src->path;
+break;
+}
+}
+
+if (parent_disk_path == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not find disk to reparent '%s' to"),
+   disk->src->path);
+goto cleanup;
+}
+
+if (!(qemu_img_path = qemuFindQemuImgBinary(driver))) {
+goto cleanup;
+}
+
+if (!(cmd = virCommandNewArgList(qemu_img_path,
+ "rebase", "-b", parent_disk_path,
+ disk->src->path,
+ NULL))) {
+goto cleanup;
+}
+
+if (virCommandRun(cmd, NULL) < 0)
+goto cleanup;
+
+ret = 0;
+cleanup:
+virCommandFree(cmd);
+return ret;
+}
+
+static int
+qemuDomainSnapshotReparentDisks(virDomainSnapshotObjPtr snap,
+virQEMUSnapReparentPtr rep)
+{
+int i;
+virDomainSnapshotDiskDefPtr snap_disk;
+
+if (!snap->def->dom) {
+VIR_WARN("Any external disk snapshots in a snapshot created with "
+ "pre-0.9.5 libvirt will not be correctly reparented.");
+// In snapshots created with pre-0.9.5 libvirt we don't have 
information
+// needed to correctly reparent external disk snapshots but we also
+// don't even know whether external disk snapshots were used so that
+// we could report this as an error. We can only emit a warning in that
+// case.
+return 0;
+}
+
+for (i = 0; i < snap->def->ndisks; ++i) {
+snap_disk = &(snap->def->disks[i]);
+
+// FIXME: do we need to explicitly reparent internal snapshots to
+// e.g. prevent long non-visible snapshot chains that might affect
+// performance?
+if (snap_disk->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL)
+continue;
+
+if (qemuDomainSnapshotReparentDiskExternal(rep->driver, rep->parent,
+   snap_disk) < 0)
+return -1;
+}
+return 0;
+}
+
 static int
 qemuDomainSnapshotReparentChildren(void *payload,
const void *name ATTRIBUTE_UNUSED,
@@ -16628,6 +16711,11 @@ qemuDomainSnapshotReparentChildren(void *payload,
 if (rep->err < 0)
 return 0;
 
+if (qemuDomainSnapshotReparentDisks(snap, rep) < 0) {
+rep->err = -1;
+goto cleanup;
+}
+
 if (qemuDomainSnapshotReparentChildrenMetadata(snap, rep) < 0) {
 rep->err = -1;
 goto cleanup;
@@ -16718,6 +16806,7 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
 vm->current_snapshot = snap;
 }
 } else if (snap->nchildren) {
+rep.driver = driver;
 rep.cfg = cfg;
 rep.parent = snap->parent;
 rep.vm = vm;
-- 
2.17.1


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list