mirror of https://gitee.com/openkylin/libvirt.git
qemu: Reuse qemuBlockStorageSourceAttachApply in disk hotplug
Create a new "Prepare" function and move the drive add code into the new helpers. This will eventually allow to simplify and unify the attaching code for use with blockdev at the same time as providing compatibility with older qemus. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
d5c5c841e0
commit
ca174424ba
|
@ -24,9 +24,12 @@
|
|||
|
||||
#include "viralloc.h"
|
||||
#include "virstring.h"
|
||||
#include "virlog.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
|
||||
VIR_LOG_INIT("qemu.qemu_block");
|
||||
|
||||
/* qemu declares the buffer for node names as a 32 byte array */
|
||||
static const size_t qemuBlockNodeNameBufSize = 32;
|
||||
|
||||
|
@ -1482,6 +1485,8 @@ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
|
|||
|
||||
virJSONValueFree(data->storageProps);
|
||||
virJSONValueFree(data->formatProps);
|
||||
VIR_FREE(data->driveCmd);
|
||||
VIR_FREE(data->driveAlias);
|
||||
VIR_FREE(data);
|
||||
}
|
||||
|
||||
|
@ -1563,6 +1568,13 @@ qemuBlockStorageSourceAttachApply(qemuMonitorPtr mon,
|
|||
data->formatAttached = true;
|
||||
}
|
||||
|
||||
if (data->driveCmd) {
|
||||
if (qemuMonitorAddDrive(mon, data->driveCmd) < 0)
|
||||
return -1;
|
||||
|
||||
data->driveAdded = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1585,6 +1597,12 @@ qemuBlockStorageSourceAttachRollback(qemuMonitorPtr mon,
|
|||
|
||||
virErrorPreserveLast(&orig_err);
|
||||
|
||||
if (data->driveAdded) {
|
||||
if (qemuMonitorDriveDel(mon, data->driveAlias) < 0)
|
||||
VIR_WARN("Unable to remove drive %s (%s) after failed "
|
||||
"qemuMonitorAddDevice", data->driveAlias, data->driveCmd);
|
||||
}
|
||||
|
||||
if (data->formatAttached)
|
||||
ignore_value(qemuMonitorBlockdevDel(mon, data->formatNodeName));
|
||||
|
||||
|
|
|
@ -78,6 +78,10 @@ struct qemuBlockStorageSourceAttachData {
|
|||
virJSONValuePtr formatProps;
|
||||
const char *formatNodeName;
|
||||
bool formatAttached;
|
||||
|
||||
char *driveCmd;
|
||||
char *driveAlias;
|
||||
bool driveAdded;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1644,7 +1644,7 @@ qemuBuildDiskFrontendAttributes(virDomainDiskDefPtr disk,
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
static char *
|
||||
qemuBuildDriveStr(virDomainDiskDefPtr disk,
|
||||
bool bootable,
|
||||
virQEMUCapsPtr qemuCaps)
|
||||
|
@ -10458,3 +10458,30 @@ qemuBuildHotpluggableCPUProps(const virDomainVcpuDef *vcpu)
|
|||
virJSONValueFree(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuBuildStorageSourceAttachPrepareDrive:
|
||||
* @disk: disk object to prepare
|
||||
* @qemuCaps: qemu capabilities object
|
||||
*
|
||||
* Prepare qemuBlockStorageSourceAttachDataPtr for use with the old approach
|
||||
* using -drive/drive_add. See qemuBlockStorageSourceAttachPrepareBlockdev.
|
||||
*/
|
||||
qemuBlockStorageSourceAttachDataPtr
|
||||
qemuBuildStorageSourceAttachPrepareDrive(virDomainDiskDefPtr disk,
|
||||
virQEMUCapsPtr qemuCaps)
|
||||
{
|
||||
qemuBlockStorageSourceAttachDataPtr data = NULL;
|
||||
|
||||
if (VIR_ALLOC(data) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!(data->driveCmd = qemuBuildDriveStr(disk, false, qemuCaps)) ||
|
||||
!(data->driveAlias = qemuAliasDiskDriveFromDisk(disk))) {
|
||||
qemuBlockStorageSourceAttachDataFree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
# include "domain_conf.h"
|
||||
# include "vircommand.h"
|
||||
# include "capabilities.h"
|
||||
# include "qemu_block.h"
|
||||
# include "qemu_conf.h"
|
||||
# include "qemu_domain.h"
|
||||
# include "qemu_domain_address.h"
|
||||
|
@ -102,10 +103,9 @@ char *qemuBuildNicDevStr(virDomainDefPtr def,
|
|||
|
||||
char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk);
|
||||
|
||||
/* Both legacy & current support */
|
||||
char *qemuBuildDriveStr(virDomainDiskDefPtr disk,
|
||||
bool bootable,
|
||||
virQEMUCapsPtr qemuCaps);
|
||||
qemuBlockStorageSourceAttachDataPtr
|
||||
qemuBuildStorageSourceAttachPrepareDrive(virDomainDiskDefPtr disk,
|
||||
virQEMUCapsPtr qemuCaps);
|
||||
|
||||
/* Current, best practice */
|
||||
char *qemuBuildDriveDevStr(const virDomainDef *def,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "qemu_interface.h"
|
||||
#include "qemu_process.h"
|
||||
#include "qemu_security.h"
|
||||
#include "qemu_block.h"
|
||||
#include "domain_audit.h"
|
||||
#include "netdev_bandwidth_conf.h"
|
||||
#include "domain_nwfilter.h"
|
||||
|
@ -390,15 +391,13 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
|||
{
|
||||
int ret = -1;
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
qemuBlockStorageSourceAttachDataPtr data = NULL;
|
||||
virErrorPtr orig_err;
|
||||
char *devstr = NULL;
|
||||
char *drivestr = NULL;
|
||||
char *drivealias = NULL;
|
||||
char *unmanagedPrmgrAlias = NULL;
|
||||
char *managedPrmgrAlias = NULL;
|
||||
char *encobjAlias = NULL;
|
||||
char *secobjAlias = NULL;
|
||||
bool driveAdded = false;
|
||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||
virJSONValuePtr secobjProps = NULL;
|
||||
virJSONValuePtr encobjProps = NULL;
|
||||
|
@ -439,16 +438,13 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
|||
!(unmanagedPrmgrProps = qemuBuildPRManagerInfoProps(disk->src)))
|
||||
goto error;
|
||||
|
||||
if (!(data = qemuBuildStorageSourceAttachPrepareDrive(disk, priv->qemuCaps)))
|
||||
goto error;
|
||||
|
||||
if (disk->src->haveTLS == VIR_TRISTATE_BOOL_YES &&
|
||||
qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps)))
|
||||
goto error;
|
||||
|
||||
if (!(drivealias = qemuAliasDiskDriveFromDisk(disk)))
|
||||
goto error;
|
||||
|
||||
if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
|
||||
goto error;
|
||||
|
||||
|
@ -473,9 +469,8 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
|||
qemuMonitorAddObject(priv->mon, &unmanagedPrmgrProps, &unmanagedPrmgrAlias) < 0)
|
||||
goto exit_monitor;
|
||||
|
||||
if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
|
||||
if (qemuBlockStorageSourceAttachApply(priv->mon, data) < 0)
|
||||
goto exit_monitor;
|
||||
driveAdded = true;
|
||||
|
||||
if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
|
||||
goto exit_monitor;
|
||||
|
@ -491,6 +486,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
|||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
qemuBlockStorageSourceAttachDataFree(data);
|
||||
virJSONValueFree(managedPrmgrProps);
|
||||
virJSONValueFree(unmanagedPrmgrProps);
|
||||
virJSONValueFree(encobjProps);
|
||||
|
@ -500,18 +496,14 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
|||
VIR_FREE(unmanagedPrmgrAlias);
|
||||
VIR_FREE(secobjAlias);
|
||||
VIR_FREE(encobjAlias);
|
||||
VIR_FREE(drivealias);
|
||||
VIR_FREE(drivestr);
|
||||
VIR_FREE(devstr);
|
||||
virObjectUnref(cfg);
|
||||
return ret;
|
||||
|
||||
exit_monitor:
|
||||
qemuBlockStorageSourceAttachRollback(priv->mon, data);
|
||||
|
||||
virErrorPreserveLast(&orig_err);
|
||||
if (driveAdded && qemuMonitorDriveDel(priv->mon, drivealias) < 0) {
|
||||
VIR_WARN("Unable to remove drive %s (%s) after failed "
|
||||
"qemuMonitorAddDevice", drivealias, drivestr);
|
||||
}
|
||||
if (secobjAlias)
|
||||
ignore_value(qemuMonitorDelObject(priv->mon, secobjAlias));
|
||||
if (encobjAlias)
|
||||
|
|
Loading…
Reference in New Issue