mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemuDomainAttachDiskGeneric: Implement hotplug of <transient> disk
Add code which creates the transient overlay after hotplugging the disk backend before attaching the disk frontend. The state of the topmost image is modified to be already read-only to prevent the need to open the image in read-write mode. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
parent
34c3291139
commit
2e94002d2a
@ -34,6 +34,7 @@
|
|||||||
#include "qemu_process.h"
|
#include "qemu_process.h"
|
||||||
#include "qemu_security.h"
|
#include "qemu_security.h"
|
||||||
#include "qemu_block.h"
|
#include "qemu_block.h"
|
||||||
|
#include "qemu_snapshot.h"
|
||||||
#include "domain_audit.h"
|
#include "domain_audit.h"
|
||||||
#include "netdev_bandwidth_conf.h"
|
#include "netdev_bandwidth_conf.h"
|
||||||
#include "domain_nwfilter.h"
|
#include "domain_nwfilter.h"
|
||||||
@ -685,6 +686,25 @@ qemuDomainChangeEjectableMedia(virQEMUDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static qemuSnapshotDiskContext *
|
||||||
|
qemuDomainAttachDiskGenericTransient(virDomainObj *vm,
|
||||||
|
virDomainDiskDef *disk,
|
||||||
|
GHashTable *blockNamedNodeData)
|
||||||
|
{
|
||||||
|
g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
|
||||||
|
g_autoptr(virDomainSnapshotDiskDef) snapdiskdef = NULL;
|
||||||
|
|
||||||
|
snapdiskdef = qemuSnapshotGetTransientDiskDef(disk, vm->def->name);
|
||||||
|
snapctxt = qemuSnapshotDiskContextNew(1, vm, QEMU_ASYNC_JOB_NONE);
|
||||||
|
|
||||||
|
if (qemuSnapshotDiskPrepareOne(snapctxt, disk, snapdiskdef,
|
||||||
|
blockNamedNodeData, false, false) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return g_steal_pointer(&snapctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemuDomainAttachDiskGeneric:
|
* qemuDomainAttachDiskGeneric:
|
||||||
*
|
*
|
||||||
@ -701,6 +721,11 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
|
|||||||
bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
|
bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
|
||||||
bool extensionDeviceAttached = false;
|
bool extensionDeviceAttached = false;
|
||||||
int rc;
|
int rc;
|
||||||
|
g_autoptr(qemuSnapshotDiskContext) transientDiskSnapshotCtxt = NULL;
|
||||||
|
bool origReadonly = disk->src->readonly;
|
||||||
|
|
||||||
|
if (disk->transient)
|
||||||
|
disk->src->readonly = true;
|
||||||
|
|
||||||
if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
|
if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
|
||||||
if (!(data = qemuBuildStorageSourceChainAttachPrepareChardev(disk)))
|
if (!(data = qemuBuildStorageSourceChainAttachPrepareChardev(disk)))
|
||||||
@ -723,6 +748,8 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disk->src->readonly = origReadonly;
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
|
|
||||||
rc = qemuBlockStorageSourceChainAttach(priv->mon, data);
|
rc = qemuBlockStorageSourceChainAttach(priv->mon, data);
|
||||||
@ -733,6 +760,25 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto rollback;
|
goto rollback;
|
||||||
|
|
||||||
|
if (disk->transient) {
|
||||||
|
g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
|
||||||
|
g_autoptr(GHashTable) blockNamedNodeData = NULL;
|
||||||
|
|
||||||
|
if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
|
||||||
|
goto rollback;
|
||||||
|
|
||||||
|
if (!(transientDiskSnapshotCtxt = qemuDomainAttachDiskGenericTransient(vm, disk, blockNamedNodeData)))
|
||||||
|
goto rollback;
|
||||||
|
|
||||||
|
|
||||||
|
if (qemuSnapshotDiskCreate(transientDiskSnapshotCtxt) < 0)
|
||||||
|
goto rollback;
|
||||||
|
|
||||||
|
QEMU_DOMAIN_DISK_PRIVATE(disk)->transientOverlayCreated = true;
|
||||||
|
backend = qemuBlockStorageSourceDetachPrepare(disk->src, NULL);
|
||||||
|
ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, backend));
|
||||||
|
}
|
||||||
|
|
||||||
if (!(devstr = qemuBuildDiskDeviceStr(vm->def, disk, priv->qemuCaps)))
|
if (!(devstr = qemuBuildDiskDeviceStr(vm->def, disk, priv->qemuCaps)))
|
||||||
goto rollback;
|
goto rollback;
|
||||||
|
|
||||||
@ -937,12 +983,6 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disk->transient) {
|
|
||||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
||||||
_("transient disk hotplug isn't supported"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virDomainDiskTranslateSourcePool(disk) < 0)
|
if (virDomainDiskTranslateSourcePool(disk) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user