提交 363e9a68 编写于 作者: P Peter Krempa

qemu: snapshot: Improve approach to deal with snapshot metadata

Until now we were changing information about the disk source via
multiple steps of copying data. Now that we changed to a pointer to
store the disk source we might use it to change the approach to track
the data.

Additionally this will allow proper tracking of the backing chain.
上级 4cc1f1a0
...@@ -12836,14 +12836,11 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, ...@@ -12836,14 +12836,11 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
qemuDomainAsyncJob asyncJob) qemuDomainAsyncJob asyncJob)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virStorageSourcePtr newDiskSrc = NULL;
virStorageSourcePtr persistDiskSrc = NULL;
char *device = NULL; char *device = NULL;
char *source = NULL; char *source = NULL;
char *newsource = NULL;
virStorageNetHostDefPtr newhosts = NULL;
virStorageNetHostDefPtr persistHosts = NULL;
int format = snap->src->format;
const char *formatStr = NULL; const char *formatStr = NULL;
char *persistSource = NULL;
int ret = -1; int ret = -1;
int fd = -1; int fd = -1;
bool need_unlink = false; bool need_unlink = false;
...@@ -12857,26 +12854,27 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, ...@@ -12857,26 +12854,27 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0) if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0)
goto cleanup; goto cleanup;
/* XXX Here, we know we are about to alter disk->src->backingStore if
* successful, so we nuke the existing chain so that future commands will
* recompute it. Better would be storing the chain ourselves rather than
* reprobing, but this requires modifying domain_conf and our XML to fully
* track the chain across libvirtd restarts. */
virStorageSourceBackingStoreClear(disk->src);
if (virStorageFileInit(snap->src) < 0) if (virStorageFileInit(snap->src) < 0)
goto cleanup; goto cleanup;
if (qemuGetDriveSourceString(snap->src, NULL, &source) < 0) if (qemuGetDriveSourceString(snap->src, NULL, &source) < 0)
goto cleanup; goto cleanup;
if (VIR_STRDUP(newsource, snap->src->path) < 0) if (!(newDiskSrc = virStorageSourceCopy(snap->src, false)))
goto cleanup; goto cleanup;
if (persistDisk && if (virStorageSourceInitChainElement(newDiskSrc, disk->src, false) < 0)
VIR_STRDUP(persistSource, snap->src->path) < 0)
goto cleanup; goto cleanup;
if (persistDisk) {
if (!(persistDiskSrc = virStorageSourceCopy(snap->src, false)))
goto cleanup;
if (virStorageSourceInitChainElement(persistDiskSrc, persistDisk->src,
false) < 0)
goto cleanup;
}
switch ((virStorageType)snap->src->type) { switch ((virStorageType)snap->src->type) {
case VIR_STORAGE_TYPE_BLOCK: case VIR_STORAGE_TYPE_BLOCK:
case VIR_STORAGE_TYPE_FILE: case VIR_STORAGE_TYPE_FILE:
...@@ -12902,15 +12900,6 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, ...@@ -12902,15 +12900,6 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
case VIR_STORAGE_TYPE_NETWORK: case VIR_STORAGE_TYPE_NETWORK:
switch (snap->src->protocol) { switch (snap->src->protocol) {
case VIR_STORAGE_NET_PROTOCOL_GLUSTER: case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
if (!(newhosts = virStorageNetHostDefCopy(snap->src->nhosts,
snap->src->hosts)))
goto cleanup;
if (persistDisk &&
!(persistHosts = virStorageNetHostDefCopy(snap->src->nhosts,
snap->src->hosts)))
goto cleanup;
break; break;
default: default:
...@@ -12961,45 +12950,24 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, ...@@ -12961,45 +12950,24 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
/* Update vm in place to match changes. */ /* Update vm in place to match changes. */
need_unlink = false; need_unlink = false;
VIR_FREE(disk->src->path); newDiskSrc->backingStore = disk->src;
virStorageNetHostDefFree(disk->src->nhosts, disk->src->hosts); disk->src = newDiskSrc;
newDiskSrc = NULL;
disk->src->path = newsource;
disk->src->format = format;
disk->src->type = snap->src->type;
disk->src->protocol = snap->src->protocol;
disk->src->nhosts = snap->src->nhosts;
disk->src->hosts = newhosts;
newsource = NULL;
newhosts = NULL;
if (persistDisk) { if (persistDisk) {
VIR_FREE(persistDisk->src->path); persistDiskSrc->backingStore = persistDisk->src;
virStorageNetHostDefFree(persistDisk->src->nhosts, persistDisk->src = persistDiskSrc;
persistDisk->src->hosts); persistDiskSrc = NULL;
persistDisk->src->path = persistSource;
persistDisk->src->format = format;
persistDisk->src->type = snap->src->type;
persistDisk->src->protocol = snap->src->protocol;
persistDisk->src->nhosts = snap->src->nhosts;
persistDisk->src->hosts = persistHosts;
persistSource = NULL;
persistHosts = NULL;
} }
cleanup: cleanup:
if (need_unlink && virStorageFileUnlink(snap->src)) if (need_unlink && virStorageFileUnlink(snap->src))
VIR_WARN("unable to unlink just-created %s", source); VIR_WARN("unable to unlink just-created %s", source);
virStorageFileDeinit(snap->src); virStorageFileDeinit(snap->src);
virStorageSourceFree(newDiskSrc);
virStorageSourceFree(persistDiskSrc);
VIR_FREE(device); VIR_FREE(device);
VIR_FREE(source); VIR_FREE(source);
VIR_FREE(newsource);
VIR_FREE(persistSource);
virStorageNetHostDefFree(snap->src->nhosts, newhosts);
virStorageNetHostDefFree(snap->src->nhosts, persistHosts);
return ret; return ret;
} }
...@@ -13009,21 +12977,15 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, ...@@ -13009,21 +12977,15 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
static void static void
qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver, qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr origdisk,
virDomainDiskDefPtr disk, virDomainDiskDefPtr disk,
virDomainDiskDefPtr persistDisk, virDomainDiskDefPtr persistDisk,
bool need_unlink) bool need_unlink)
{ {
char *source = NULL; virStorageSourcePtr tmp;
char *persistSource = NULL;
struct stat st; struct stat st;
ignore_value(virStorageFileInit(disk->src)); ignore_value(virStorageFileInit(disk->src));
if (VIR_STRDUP(source, origdisk->src->path) < 0 ||
(persistDisk && VIR_STRDUP(persistSource, source) < 0))
goto cleanup;
qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src, qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src,
VIR_DISK_CHAIN_NO_ACCESS); VIR_DISK_CHAIN_NO_ACCESS);
if (need_unlink && if (need_unlink &&
...@@ -13031,35 +12993,20 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver, ...@@ -13031,35 +12993,20 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
virStorageFileUnlink(disk->src) < 0) virStorageFileUnlink(disk->src) < 0)
VIR_WARN("Unable to remove just-created %s", disk->src->path); VIR_WARN("Unable to remove just-created %s", disk->src->path);
/* Update vm in place to match changes. */ virStorageFileDeinit(disk->src);
VIR_FREE(disk->src->path);
disk->src->path = source; /* Update vm in place to match changes. */
source = NULL; tmp = disk->src;
disk->src->format = origdisk->src->format; disk->src = tmp->backingStore;
disk->src->type = origdisk->src->type; tmp->backingStore = NULL;
disk->src->protocol = origdisk->src->protocol; virStorageSourceFree(tmp);
virStorageNetHostDefFree(disk->src->nhosts, disk->src->hosts);
disk->src->nhosts = origdisk->src->nhosts;
disk->src->hosts = virStorageNetHostDefCopy(origdisk->src->nhosts,
origdisk->src->hosts);
if (persistDisk) { if (persistDisk) {
VIR_FREE(persistDisk->src->path); tmp = persistDisk->src;
persistDisk->src->path = persistSource; persistDisk->src = tmp->backingStore;
persistSource = NULL; tmp->backingStore = NULL;
persistDisk->src->format = origdisk->src->format; virStorageSourceFree(tmp);
persistDisk->src->type = origdisk->src->type;
persistDisk->src->protocol = origdisk->src->protocol;
virStorageNetHostDefFree(persistDisk->src->nhosts,
persistDisk->src->hosts);
persistDisk->src->nhosts = origdisk->src->nhosts;
persistDisk->src->hosts = virStorageNetHostDefCopy(origdisk->src->nhosts,
origdisk->src->hosts);
} }
cleanup:
virStorageFileDeinit(disk->src);
VIR_FREE(source);
VIR_FREE(persistSource);
} }
/* The domain is expected to be locked and active. */ /* The domain is expected to be locked and active. */
...@@ -13163,7 +13110,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, ...@@ -13163,7 +13110,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
} }
qemuDomainSnapshotUndoSingleDiskActive(driver, vm, qemuDomainSnapshotUndoSingleDiskActive(driver, vm,
snap->def->dom->disks[i],
vm->def->disks[i], vm->def->disks[i],
persistDisk, persistDisk,
need_unlink); need_unlink);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册