mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-08 22:15:21 +00:00
qemu: Split handling of managed and unmanaged persistent reservations
Add code that will handle the managed persistent reservations object separately from the unmanaged one. There is only one managed object so handling it with disks is awkward and does not scale well when backing chains come into view. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
b3286a51de
commit
6e6d84163e
@ -2206,6 +2206,35 @@ qemuBulildFloppyCommandLineOptions(virCommandPtr cmd,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildDiskUnmanagedPRCommandLine(virCommandPtr cmd,
|
||||
virStorageSourcePtr src)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
virJSONValuePtr props = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (!src->pr ||
|
||||
virStoragePRDefIsManaged(src->pr))
|
||||
return 0;
|
||||
|
||||
if (!(props = qemuBuildPRManagerInfoProps(src)))
|
||||
return -1;
|
||||
|
||||
if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0)
|
||||
goto cleanup;
|
||||
|
||||
virCommandAddArg(cmd, "-object");
|
||||
virCommandAddArgBuffer(cmd, &buf);
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
virBufferFreeAndReset(&buf);
|
||||
virJSONValueFree(props);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
|
||||
const virDomainDef *def,
|
||||
@ -2273,6 +2302,9 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
|
||||
}
|
||||
}
|
||||
|
||||
if (qemuBuildDiskUnmanagedPRCommandLine(cmd, disk->src) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuBuildDiskSecinfoCommandLine(cmd, secinfo) < 0)
|
||||
return -1;
|
||||
|
||||
@ -9694,6 +9726,44 @@ qemuBuildPanicCommandLine(virCommandPtr cmd,
|
||||
}
|
||||
|
||||
|
||||
static virJSONValuePtr
|
||||
qemuBuildPRManagerInfoPropsInternal(const char *alias,
|
||||
const char *path)
|
||||
{
|
||||
virJSONValuePtr ret = NULL;
|
||||
|
||||
if (qemuMonitorCreateObjectProps(&ret,
|
||||
"pr-manager-helper", alias,
|
||||
"s:path", path, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuBuildPRManagedManagerInfoProps:
|
||||
*
|
||||
* Build the JSON properties for the pr-manager object corresponding to the PR
|
||||
* daemon managed by libvirt.
|
||||
*/
|
||||
virJSONValuePtr
|
||||
qemuBuildPRManagedManagerInfoProps(qemuDomainObjPrivatePtr priv)
|
||||
{
|
||||
char *path = NULL;
|
||||
virJSONValuePtr ret = NULL;
|
||||
|
||||
if (!(path = qemuDomainGetManagedPRSocketPath(priv)))
|
||||
return NULL;
|
||||
|
||||
ret = qemuBuildPRManagerInfoPropsInternal(qemuDomainGetManagedPRAlias(),
|
||||
path);
|
||||
|
||||
VIR_FREE(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuBuildPRManagerInfoProps:
|
||||
* @src: storage source
|
||||
@ -9703,49 +9773,30 @@ qemuBuildPanicCommandLine(virCommandPtr cmd,
|
||||
virJSONValuePtr
|
||||
qemuBuildPRManagerInfoProps(virStorageSourcePtr src)
|
||||
{
|
||||
virJSONValuePtr ret = NULL;
|
||||
|
||||
if (qemuMonitorCreateObjectProps(&ret,
|
||||
"pr-manager-helper", src->pr->mgralias,
|
||||
"s:path", src->pr->path, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
return qemuBuildPRManagerInfoPropsInternal(src->pr->mgralias, src->pr->path);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildMasterPRCommandLine(virCommandPtr cmd,
|
||||
const virDomainDef *def)
|
||||
qemuBuildManagedPRCommandLine(virCommandPtr cmd,
|
||||
const virDomainDef *def,
|
||||
qemuDomainObjPrivatePtr priv)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
size_t i;
|
||||
bool managedAdded = false;
|
||||
virJSONValuePtr props = NULL;
|
||||
int ret = -1;
|
||||
|
||||
for (i = 0; i < def->ndisks; i++) {
|
||||
const virDomainDiskDef *disk = def->disks[i];
|
||||
if (!virDomainDefHasManagedPR(def))
|
||||
return 0;
|
||||
|
||||
if (!disk->src->pr)
|
||||
continue;
|
||||
if (!(props = qemuBuildPRManagedManagerInfoProps(priv)))
|
||||
return -1;
|
||||
|
||||
if (virStoragePRDefIsManaged(disk->src->pr)) {
|
||||
if (managedAdded)
|
||||
continue;
|
||||
if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0)
|
||||
goto cleanup;
|
||||
|
||||
managedAdded = true;
|
||||
}
|
||||
|
||||
if (!(props = qemuBuildPRManagerInfoProps(disk->src)))
|
||||
goto cleanup;
|
||||
|
||||
if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0)
|
||||
goto cleanup;
|
||||
|
||||
virCommandAddArg(cmd, "-object");
|
||||
virCommandAddArgBuffer(cmd, &buf);
|
||||
}
|
||||
virCommandAddArg(cmd, "-object");
|
||||
virCommandAddArgBuffer(cmd, &buf);
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
@ -9977,7 +10028,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
|
||||
if (qemuBuildMasterKeyCommandLine(cmd, priv) < 0)
|
||||
goto error;
|
||||
|
||||
if (qemuBuildMasterPRCommandLine(cmd, def) < 0)
|
||||
if (qemuBuildManagedPRCommandLine(cmd, def, priv) < 0)
|
||||
goto error;
|
||||
|
||||
if (enableFips)
|
||||
|
@ -56,6 +56,7 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
|
||||
|
||||
/* Generate the object properties for pr-manager */
|
||||
virJSONValuePtr qemuBuildPRManagerInfoProps(virStorageSourcePtr src);
|
||||
virJSONValuePtr qemuBuildPRManagedManagerInfoProps(qemuDomainObjPrivatePtr priv);
|
||||
|
||||
/* Generate the object properties for a secret */
|
||||
int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
|
||||
|
@ -350,60 +350,40 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||||
* qemuDomainMaybeStartPRDaemon:
|
||||
* @vm: domain object
|
||||
* @disk: disk to hotplug
|
||||
* @retProps: properties of the managed pr-manager-helper object which needs
|
||||
* to be added to the running vm
|
||||
*
|
||||
* Checks if it's needed to start qemu-pr-helper and starts it.
|
||||
* Checks if it's needed to start qemu-pr-helper and add the corresponding
|
||||
* pr-manager-helper object.
|
||||
*
|
||||
* Returns: 0 if qemu-pr-helper is not needed
|
||||
* 1 if it is needed and was started
|
||||
* -1 otherwise.
|
||||
* Returns: 0 on success, -1 on error. If @retProps is populated the
|
||||
* qemu-pr-helper daemon was started.
|
||||
*/
|
||||
static int
|
||||
qemuDomainMaybeStartPRDaemon(virDomainObjPtr vm,
|
||||
virDomainDiskDefPtr disk)
|
||||
qemuDomainDiskAttachManagedPR(virDomainObjPtr vm,
|
||||
virDomainDiskDefPtr disk,
|
||||
virJSONValuePtr *retProps)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
virJSONValuePtr props = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (!virStoragePRDefIsManaged(disk->src->pr)) {
|
||||
/* @disk itself does not require qemu-pr-helper. */
|
||||
if (priv->prDaemonRunning ||
|
||||
!virStorageSourceChainHasManagedPR(disk->src))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (priv->prDaemonRunning) {
|
||||
/* @disk requires qemu-pr-helper but there's already one running. */
|
||||
return 0;
|
||||
}
|
||||
if (!(props = qemuBuildPRManagedManagerInfoProps(priv)))
|
||||
return -1;
|
||||
|
||||
/* @disk requires qemu-pr-helper but none is running.
|
||||
* Start it now. */
|
||||
if (qemuProcessStartManagedPRDaemon(vm) < 0)
|
||||
return -1;
|
||||
goto cleanup;
|
||||
|
||||
return 1;
|
||||
}
|
||||
VIR_STEAL_PTR(*retProps, props);
|
||||
ret = 0;
|
||||
|
||||
|
||||
static int
|
||||
qemuMaybeBuildPRManagerInfoProps(virDomainObjPtr vm,
|
||||
const virDomainDiskDef *disk,
|
||||
virJSONValuePtr *propsret)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
|
||||
*propsret = NULL;
|
||||
|
||||
if (!disk->src->pr)
|
||||
return 0;
|
||||
|
||||
if (virStoragePRDefIsManaged(disk->src->pr) &&
|
||||
priv->prDaemonRunning) {
|
||||
/* @disk requires qemu-pr-helper but there's already one running. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(*propsret = qemuBuildPRManagerInfoProps(disk->src)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
virJSONValueFree(props);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -418,21 +398,21 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
||||
virDomainDiskDefPtr disk)
|
||||
{
|
||||
int ret = -1;
|
||||
int rv;
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
virErrorPtr orig_err;
|
||||
char *devstr = NULL;
|
||||
char *drivestr = NULL;
|
||||
char *drivealias = NULL;
|
||||
char *prmgrAlias = NULL;
|
||||
char *unmanagedPrmgrAlias = NULL;
|
||||
char *managedPrmgrAlias = NULL;
|
||||
char *encobjAlias = NULL;
|
||||
char *secobjAlias = NULL;
|
||||
bool driveAdded = false;
|
||||
bool prdStarted = false;
|
||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||
virJSONValuePtr secobjProps = NULL;
|
||||
virJSONValuePtr encobjProps = NULL;
|
||||
virJSONValuePtr prmgrProps = NULL;
|
||||
virJSONValuePtr unmanagedPrmgrProps = NULL;
|
||||
virJSONValuePtr managedPrmgrProps = NULL;
|
||||
qemuDomainStorageSourcePrivatePtr srcPriv;
|
||||
qemuDomainSecretInfoPtr secinfo = NULL;
|
||||
qemuDomainSecretInfoPtr encinfo = NULL;
|
||||
@ -460,16 +440,13 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
||||
if (encinfo && qemuBuildSecretInfoProps(encinfo, &encobjProps) < 0)
|
||||
goto error;
|
||||
|
||||
if (qemuMaybeBuildPRManagerInfoProps(vm, disk, &prmgrProps) < 0)
|
||||
if (qemuDomainDiskAttachManagedPR(vm, disk, &managedPrmgrProps) < 0)
|
||||
goto error;
|
||||
|
||||
/* Start daemon only after prmgrProps is built. Otherwise
|
||||
* qemuDomainMaybeStartPRDaemon() might start daemon and set
|
||||
* priv->prDaemonRunning which confuses props building code. */
|
||||
if ((rv = qemuDomainMaybeStartPRDaemon(vm, disk)) < 0)
|
||||
if (disk->src->pr &&
|
||||
!virStoragePRDefIsManaged(disk->src->pr) &&
|
||||
!(unmanagedPrmgrProps = qemuBuildPRManagerInfoProps(disk->src)))
|
||||
goto error;
|
||||
else if (rv > 0)
|
||||
prdStarted = true;
|
||||
|
||||
if (disk->src->haveTLS == VIR_TRISTATE_BOOL_YES &&
|
||||
qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src) < 0)
|
||||
@ -497,8 +474,12 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
||||
qemuMonitorAddObject(priv->mon, &encobjProps, &encobjAlias) < 0)
|
||||
goto exit_monitor;
|
||||
|
||||
if (prmgrProps &&
|
||||
qemuMonitorAddObject(priv->mon, &prmgrProps, &prmgrAlias) < 0)
|
||||
if (managedPrmgrProps &&
|
||||
qemuMonitorAddObject(priv->mon, &managedPrmgrProps, &managedPrmgrAlias) < 0)
|
||||
goto exit_monitor;
|
||||
|
||||
if (unmanagedPrmgrProps &&
|
||||
qemuMonitorAddObject(priv->mon, &unmanagedPrmgrProps, &unmanagedPrmgrAlias) < 0)
|
||||
goto exit_monitor;
|
||||
|
||||
if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
|
||||
@ -519,11 +500,13 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virJSONValueFree(prmgrProps);
|
||||
virJSONValueFree(managedPrmgrProps);
|
||||
virJSONValueFree(unmanagedPrmgrProps);
|
||||
virJSONValueFree(encobjProps);
|
||||
virJSONValueFree(secobjProps);
|
||||
qemuDomainSecretDiskDestroy(disk);
|
||||
VIR_FREE(prmgrAlias);
|
||||
VIR_FREE(managedPrmgrAlias);
|
||||
VIR_FREE(unmanagedPrmgrAlias);
|
||||
VIR_FREE(secobjAlias);
|
||||
VIR_FREE(encobjAlias);
|
||||
VIR_FREE(drivealias);
|
||||
@ -542,8 +525,10 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
||||
ignore_value(qemuMonitorDelObject(priv->mon, secobjAlias));
|
||||
if (encobjAlias)
|
||||
ignore_value(qemuMonitorDelObject(priv->mon, encobjAlias));
|
||||
if (prmgrAlias)
|
||||
ignore_value(qemuMonitorDelObject(priv->mon, prmgrAlias));
|
||||
if (unmanagedPrmgrAlias)
|
||||
ignore_value(qemuMonitorDelObject(priv->mon, unmanagedPrmgrAlias));
|
||||
if (managedPrmgrAlias)
|
||||
ignore_value(qemuMonitorDelObject(priv->mon, managedPrmgrAlias));
|
||||
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||||
ret = -2;
|
||||
virErrorRestore(&orig_err);
|
||||
@ -553,7 +538,8 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
|
||||
error:
|
||||
qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src);
|
||||
ignore_value(qemuHotplugPrepareDiskAccess(driver, vm, disk, NULL, true));
|
||||
if (prdStarted)
|
||||
if (priv->prDaemonRunning &&
|
||||
!virDomainDefHasManagedPR(vm->def))
|
||||
qemuProcessKillManagedPRDaemon(vm);
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -11,8 +11,6 @@ QEMU_AUDIO_DRV=none \
|
||||
file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
|
||||
-object pr-manager-helper,id=pr-helper0,\
|
||||
path=/tmp/lib/domain--1-QEMUGuest1/pr-helper0.sock \
|
||||
-object pr-manager-helper,id=pr-helper-scsi0-0-0-1,\
|
||||
path=/path/to/qemu-pr-helper.sock \
|
||||
-machine pc-i440fx-2.12,accel=tcg,usb=off,dump-guest-core=off \
|
||||
-m 214 \
|
||||
-realtime mlock=off \
|
||||
@ -34,6 +32,8 @@ server,nowait \
|
||||
if=none,id=drive-scsi0-0-0-0 \
|
||||
-device scsi-block,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
|
||||
drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1 \
|
||||
-object pr-manager-helper,id=pr-helper-scsi0-0-0-1,\
|
||||
path=/path/to/qemu-pr-helper.sock \
|
||||
-drive file=/dev/HostVG/QEMUGuest2,file.pr-manager=pr-helper-scsi0-0-0-1,\
|
||||
format=raw,if=none,id=drive-scsi0-0-0-1 \
|
||||
-device scsi-block,bus=scsi0.0,channel=0,scsi-id=0,lun=1,\
|
||||
|
Loading…
Reference in New Issue
Block a user