mirror of https://gitee.com/openkylin/libvirt.git
qemu: Generate pr cmd line at startup
For command line we need two things: 1) -object pr-manager-helper,id=$alias,path=$socketPath 2) -drive file.pr-manager=$alias In -object pr-manager-helper we tell qemu which socket to connect to, then in -drive file-pr-manager we just reference the object the drive in question should use. For managed PR helper the alias is always "pr-helper0" and socket path "${vm->priv->libDir}/pr-helper0.sock". Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
3c28602759
commit
13fe558fb4
|
@ -2803,7 +2803,9 @@ virStorageNetHostTransportTypeToString;
|
|||
virStorageNetProtocolTypeToString;
|
||||
virStoragePRDefFormat;
|
||||
virStoragePRDefFree;
|
||||
virStoragePRDefIsEnabled;
|
||||
virStoragePRDefIsEqual;
|
||||
virStoragePRDefIsManaged;
|
||||
virStoragePRDefParseXML;
|
||||
virStorageSourceBackingStoreClear;
|
||||
virStorageSourceClear;
|
||||
|
|
|
@ -773,3 +773,21 @@ qemuAliasChardevFromDevAlias(const char *devAlias)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
qemuDomainGetManagedPRAlias(void)
|
||||
{
|
||||
return "pr-helper0";
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
qemuDomainGetUnmanagedPRAlias(const virDomainDiskDef *disk)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ignore_value(virAsprintf(&ret, "pr-helper-%s", disk->info.alias));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -92,4 +92,8 @@ char *qemuAliasTLSObjFromSrcAlias(const char *srcAlias)
|
|||
char *qemuAliasChardevFromDevAlias(const char *devAlias)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
const char *qemuDomainGetManagedPRAlias(void);
|
||||
|
||||
char *qemuDomainGetUnmanagedPRAlias(const virDomainDiskDef *disk);
|
||||
|
||||
#endif /* __QEMU_ALIAS_H__*/
|
||||
|
|
|
@ -1470,6 +1470,28 @@ qemuDiskSourceGetProps(virStorageSourcePtr src)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildDriveSourcePR(virBufferPtr buf,
|
||||
virDomainDiskDefPtr disk)
|
||||
{
|
||||
char *alias = NULL;
|
||||
const char *defaultAlias = NULL;
|
||||
|
||||
if (!virStoragePRDefIsEnabled(disk->src->pr))
|
||||
return 0;
|
||||
|
||||
if (virStoragePRDefIsManaged(disk->src->pr))
|
||||
defaultAlias = qemuDomainGetManagedPRAlias();
|
||||
else if (!(alias = qemuDomainGetUnmanagedPRAlias(disk)))
|
||||
return -1;
|
||||
|
||||
|
||||
virBufferAsprintf(buf, ",file.pr-manager=%s", alias ? alias : defaultAlias);
|
||||
VIR_FREE(alias);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
|
@ -1533,6 +1555,9 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
|
|||
|
||||
if (disk->src->debug)
|
||||
virBufferAsprintf(buf, ",file.debug=%d", disk->src->debugLevel);
|
||||
|
||||
if (qemuBuildDriveSourcePR(buf, disk) < 0)
|
||||
goto cleanup;
|
||||
} else {
|
||||
if (!(source = virQEMUBuildDriveCommandlineFromJSON(srcprops)))
|
||||
goto cleanup;
|
||||
|
@ -9619,6 +9644,112 @@ qemuBuildPanicCommandLine(virCommandPtr cmd,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuBuildPRManagerInfoProps:
|
||||
* @prd: disk PR runtime info
|
||||
* @propsret: JSON properties to return
|
||||
*
|
||||
* Build the JSON properties for the pr-manager object.
|
||||
*
|
||||
* Returns: 0 on success (@propsret is NULL if no properties are needed),
|
||||
* -1 on failure (with error message set).
|
||||
*/
|
||||
int
|
||||
qemuBuildPRManagerInfoProps(virDomainObjPtr vm,
|
||||
const virDomainDiskDef *disk,
|
||||
virJSONValuePtr *propsret,
|
||||
char **aliasret)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
char *socketPath = NULL;
|
||||
char *alias = NULL;
|
||||
int ret = -1;
|
||||
|
||||
*propsret = NULL;
|
||||
*aliasret = NULL;
|
||||
|
||||
if (!virStoragePRDefIsEnabled(disk->src->pr))
|
||||
return 0;
|
||||
|
||||
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PR_MANAGER_HELPER)) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("reservations not supported with this QEMU binary"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(socketPath = qemuDomainGetPRSocketPath(vm, disk->src->pr)))
|
||||
return ret;
|
||||
|
||||
if (virStoragePRDefIsManaged(disk->src->pr)) {
|
||||
if (VIR_STRDUP(alias, qemuDomainGetManagedPRAlias()) < 0)
|
||||
goto cleanup;
|
||||
} else {
|
||||
if (!(alias = qemuDomainGetUnmanagedPRAlias(disk)))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectCreate(propsret,
|
||||
"s:path", socketPath,
|
||||
NULL) < 0)
|
||||
goto cleanup;
|
||||
|
||||
VIR_STEAL_PTR(*aliasret, alias);
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(alias);
|
||||
VIR_FREE(socketPath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildMasterPRCommandLine(virDomainObjPtr vm,
|
||||
virCommandPtr cmd,
|
||||
const virDomainDef *def)
|
||||
{
|
||||
size_t i;
|
||||
bool managedAdded = false;
|
||||
virJSONValuePtr props = NULL;
|
||||
char *alias = NULL;
|
||||
char *tmp = NULL;
|
||||
int ret = -1;
|
||||
|
||||
for (i = 0; i < def->ndisks; i++) {
|
||||
const virDomainDiskDef *disk = def->disks[i];
|
||||
|
||||
if (virStoragePRDefIsManaged(disk->src->pr)) {
|
||||
if (managedAdded)
|
||||
continue;
|
||||
|
||||
managedAdded = true;
|
||||
}
|
||||
|
||||
if (qemuBuildPRManagerInfoProps(vm, disk, &props, &alias) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!props)
|
||||
continue;
|
||||
|
||||
if (!(tmp = virQEMUBuildObjectCommandlineFromJSON("pr-manager-helper",
|
||||
alias,
|
||||
props)))
|
||||
goto cleanup;
|
||||
VIR_FREE(alias);
|
||||
virJSONValueFree(props);
|
||||
props = NULL;
|
||||
|
||||
virCommandAddArgList(cmd, "-object", tmp, NULL);
|
||||
VIR_FREE(tmp);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(alias);
|
||||
virJSONValueFree(props);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuBuildCommandLineValidate:
|
||||
*
|
||||
|
@ -9787,6 +9918,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
|
|||
if (qemuBuildMasterKeyCommandLine(cmd, priv) < 0)
|
||||
goto error;
|
||||
|
||||
if (qemuBuildMasterPRCommandLine(vm, cmd, def) < 0)
|
||||
goto error;
|
||||
|
||||
if (enableFips)
|
||||
virCommandAddArg(cmd, "-enable-fips");
|
||||
|
||||
|
|
|
@ -54,6 +54,11 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
|
|||
size_t *nnicindexes,
|
||||
int **nicindexes);
|
||||
|
||||
/* Generate the object properties for pr-manager */
|
||||
int qemuBuildPRManagerInfoProps(virDomainObjPtr vm,
|
||||
const virDomainDiskDef *disk,
|
||||
virJSONValuePtr *propsret,
|
||||
char **alias);
|
||||
|
||||
/* Generate the object properties for a secret */
|
||||
int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
|
||||
|
|
|
@ -12001,3 +12001,25 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
|
|||
}
|
||||
VIR_FREE(event);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
qemuDomainGetPRSocketPath(virDomainObjPtr vm,
|
||||
virStoragePRDefPtr pr)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
const char *defaultAlias = NULL;
|
||||
char *ret = NULL;
|
||||
|
||||
if (!virStoragePRDefIsEnabled(pr))
|
||||
return NULL;
|
||||
|
||||
if (virStoragePRDefIsManaged(pr)) {
|
||||
defaultAlias = qemuDomainGetManagedPRAlias();
|
||||
ignore_value(virAsprintf(&ret, "%s/%s.sock", priv->libDir, defaultAlias));
|
||||
} else {
|
||||
ignore_value(VIR_STRDUP(ret, pr->path));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1003,4 +1003,7 @@ qemuDomainDiskCachemodeFlags(int cachemode,
|
|||
bool *direct,
|
||||
bool *noflush);
|
||||
|
||||
char * qemuDomainGetPRSocketPath(virDomainObjPtr vm,
|
||||
virStoragePRDefPtr pr);
|
||||
|
||||
#endif /* __QEMU_DOMAIN_H__ */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
# include "qemu_conf.h"
|
||||
# include "qemu_domain.h"
|
||||
# include "virstoragefile.h"
|
||||
|
||||
int qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
|
||||
const char *domainDir);
|
||||
|
|
|
@ -2041,6 +2041,20 @@ virStoragePRDefIsEqual(virStoragePRDefPtr a,
|
|||
}
|
||||
|
||||
|
||||
bool
|
||||
virStoragePRDefIsEnabled(virStoragePRDefPtr prd)
|
||||
{
|
||||
return prd && prd->enabled == VIR_TRISTATE_BOOL_YES;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
virStoragePRDefIsManaged(virStoragePRDefPtr prd)
|
||||
{
|
||||
return prd && prd->managed == VIR_TRISTATE_BOOL_YES;
|
||||
}
|
||||
|
||||
|
||||
virSecurityDeviceLabelDefPtr
|
||||
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
||||
const char *model)
|
||||
|
|
|
@ -397,6 +397,8 @@ void virStoragePRDefFormat(virBufferPtr buf,
|
|||
virStoragePRDefPtr prd);
|
||||
bool virStoragePRDefIsEqual(virStoragePRDefPtr a,
|
||||
virStoragePRDefPtr b);
|
||||
bool virStoragePRDefIsEnabled(virStoragePRDefPtr prd);
|
||||
bool virStoragePRDefIsManaged(virStoragePRDefPtr prd);
|
||||
|
||||
virSecurityDeviceLabelDefPtr
|
||||
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
LC_ALL=C \
|
||||
PATH=/bin \
|
||||
HOME=/home/test \
|
||||
USER=test \
|
||||
LOGNAME=test \
|
||||
QEMU_AUDIO_DRV=none \
|
||||
/usr/bin/qemu-system-i686 \
|
||||
-name QEMUGuest1 \
|
||||
-S \
|
||||
-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,accel=tcg,usb=off,dump-guest-core=off \
|
||||
-m 214 \
|
||||
-smp 8,sockets=8,cores=1,threads=1 \
|
||||
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
|
||||
-display none \
|
||||
-no-user-config \
|
||||
-nodefaults \
|
||||
-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
|
||||
server,nowait \
|
||||
-mon chardev=charmonitor,id=monitor,mode=control \
|
||||
-rtc base=utc \
|
||||
-no-shutdown \
|
||||
-no-acpi \
|
||||
-boot c \
|
||||
-device virtio-scsi-pci,id=scsi0,num_queues=8,bus=pci.0,addr=0x3 \
|
||||
-usb \
|
||||
-drive file=/dev/HostVG/QEMUGuest1,file.pr-manager=pr-helper0,format=raw,\
|
||||
if=none,id=drive-scsi0-0-0-0,boot=on \
|
||||
-device scsi-block,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
|
||||
drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
|
||||
-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,\
|
||||
drive=drive-scsi0-0-0-1,id=scsi0-0-0-1 \
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
|
|
@ -2801,6 +2801,10 @@ mymain(void)
|
|||
QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4,
|
||||
QEMU_CAPS_ICH9_USB_EHCI1);
|
||||
|
||||
DO_TEST("disk-virtio-scsi-reservations",
|
||||
QEMU_CAPS_DRIVE_BOOT, QEMU_CAPS_VIRTIO_SCSI,
|
||||
QEMU_CAPS_SCSI_BLOCK, QEMU_CAPS_PR_MANAGER_HELPER);
|
||||
|
||||
/* Test disks with format probing enabled for legacy reasons.
|
||||
* New tests should not go in this section. */
|
||||
driver.config->allowDiskFormatProbing = true;
|
||||
|
|
Loading…
Reference in New Issue