VIR_FREE(def->src);
VIR_FREE(def->dst);
VIR_FREE(def->driverName);
+ virStorageFileFreeMetadata(def->backingChain);
VIR_FREE(def->mirror);
VIR_FREE(def->auth.username);
VIR_FREE(def->wwn);
# include "virobject.h"
# include "device_conf.h"
# include "bitmap.h"
+# include "storage_file.h"
/* forward declarations of all device types, required by
* virDomainDeviceDef
} auth;
char *driverName;
int format; /* enum virStorageFileFormat */
+ virStorageFileMetadataPtr backingChain;
char *mirror;
int mirrorFormat; /* enum virStorageFileFormat */
priv->ncleanupCallbacks = 0;
priv->ncleanupCallbacks_max = 0;
}
+
+int
+qemuDomainDetermineDiskChain(struct qemud_driver *driver,
+ virDomainDiskDefPtr disk,
+ bool force)
+{
+ bool probe = driver->allowDiskFormatProbing;
+
+ if (!disk->src)
+ return 0;
+
+ if (disk->backingChain) {
+ if (force) {
+ virStorageFileFreeMetadata(disk->backingChain);
+ disk->backingChain = NULL;
+ } else {
+ return 0;
+ }
+ }
+ disk->backingChain = virStorageFileGetMetadata(disk->src, disk->format,
+ driver->user, driver->group,
+ probe);
+ if (!disk->backingChain)
+ return -1;
+ return 0;
+}
int qemuDomainCheckDiskPresence(struct qemud_driver *driver,
virDomainObjPtr vm,
bool start_with_state);
+int qemuDomainDetermineDiskChain(struct qemud_driver *driver,
+ virDomainDiskDefPtr disk,
+ bool force);
int qemuDomainCleanupAdd(virDomainObjPtr vm,
qemuDomainCleanupCallback cb);
goto end;
}
+ if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
+ goto end;
+
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
virCgroupPtr cgroup = NULL;
int ret = -1;
+ if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
+ goto end;
+
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
if (virCgroupForDomain(driver->cgroup,
vm->def->name, &cgroup, 0) != 0) {
disk->src = source;
origdriver = disk->format;
disk->format = VIR_STORAGE_FILE_RAW; /* Don't want to probe backing files */
+ /* XXX Here, we know we are about to alter disk->backingChain 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. */
+ virStorageFileFreeMetadata(disk->backingChain);
+ disk->backingChain = NULL;
if (virDomainLockDiskAttach(driver->lockManager, driver->uri,
vm, disk) < 0)
if (disk) {
path = disk->src;
event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
+ /* XXX If we completed a block pull, then recompute the cached
+ * backing chain to match. 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. */
+ if (type == VIR_DOMAIN_BLOCK_JOB_TYPE_PULL &&
+ status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
+ qemuDomainDetermineDiskChain(driver, disk, true);
}
virDomainObjUnlock(vm);