Offline internal snapshots can be rolled back with just a little bit of refactoring, meaning that we are now automatically atomic. * src/qemu/qemu_domain.c (qemuDomainSnapshotForEachQcow2): Move guts... (qemuDomainSnapshotForEachQcow2Raw): ...to new helper, to allow rollbacks. * src/qemu/qemu_driver.c (qemuDomainSnapshotCreateXML): Offline snapshots are now atomic. --- v2: new patch. src/qemu/qemu_domain.c | 55 ++++++++++++++++++++++++++++++----------------- src/qemu/qemu_driver.c | 6 ----- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 625c595..a845480 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1,7 +1,7 @@ /* * qemu_domain.h: QEMU domain private state * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -1489,24 +1489,17 @@ cleanup: /* The domain is expected to be locked and inactive. Return -1 on normal * failure, 1 if we skipped a disk due to try_all. */ -int -qemuDomainSnapshotForEachQcow2(struct qemud_driver *driver, - virDomainObjPtr vm, - virDomainSnapshotObjPtr snap, - const char *op, - bool try_all) +static int +qemuDomainSnapshotForEachQcow2Raw(struct qemud_driver *driver, + virDomainDefPtr def, + const char *name, + const char *op, + bool try_all, + int ndisks) { const char *qemuimgarg[] = { NULL, "snapshot", NULL, NULL, NULL, NULL }; int i; bool skipped = false; - virDomainDefPtr def; - - /* Prefer action on the disks in use at the time the snapshot was - * created; but fall back to current definition if dealing with a - * snapshot created prior to libvirt 0.9.5. */ - def = snap->def->dom; - if (!def) - def = vm->def; qemuimgarg[0] = qemuFindQemuImgBinary(driver); if (qemuimgarg[0] == NULL) { @@ -1515,13 +1508,10 @@ qemuDomainSnapshotForEachQcow2(struct qemud_driver *driver, } qemuimgarg[2] = op; - qemuimgarg[3] = snap->def->name; + qemuimgarg[3] = name; - for (i = 0; i < def->ndisks; i++) { + for (i = 0; i < ndisks; i++) { /* FIXME: we also need to handle LVM here */ - /* FIXME: if we fail halfway through this loop, we are in an - * inconsistent state. I'm not quite sure what to do about that - */ if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) { if (!def->disks[i]->driverType || STRNEQ(def->disks[i]->driverType, "qcow2")) { @@ -1533,6 +1523,11 @@ qemuDomainSnapshotForEachQcow2(struct qemud_driver *driver, def->disks[i]->dst); skipped = true; continue; + } else if (STREQ(op, "-c") && i) { + /* We must roll back partial creation by deleting + * all earlier snapshots. */ + qemuDomainSnapshotForEachQcow2Raw(driver, def, name, + "-d", false, i); } qemuReportError(VIR_ERR_OPERATION_INVALID, _("Disk device '%s' does not support" @@ -1558,6 +1553,26 @@ qemuDomainSnapshotForEachQcow2(struct qemud_driver *driver, return skipped ? 1 : 0; } +/* The domain is expected to be locked and inactive. Return -1 on normal + * failure, 1 if we skipped a disk due to try_all. */ +int +qemuDomainSnapshotForEachQcow2(struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainSnapshotObjPtr snap, + const char *op, + bool try_all) +{ + /* Prefer action on the disks in use at the time the snapshot was + * created; but fall back to current definition if dealing with a + * snapshot created prior to libvirt 0.9.5. */ + virDomainDefPtr def = snap->def->dom; + + if (!def) + def = vm->def; + return qemuDomainSnapshotForEachQcow2Raw(driver, def, snap->def->name, + op, try_all, def->ndisks); +} + /* Discard one snapshot (or its metadata), without reparenting any children. */ int qemuDomainSnapshotDiscard(struct qemud_driver *driver, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9e62738..4bbfabd 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10295,12 +10295,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, &vm, snap, flags) < 0) goto cleanup; } else if (!virDomainObjIsActive(vm)) { - if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC) { - qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("atomic snapshots of inactive domains not " - "implemented yet")); - goto cleanup; - } if (qemuDomainSnapshotCreateInactive(driver, vm, snap) < 0) goto cleanup; } else { -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list