mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
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;
|
virStorageNetProtocolTypeToString;
|
||||||
virStoragePRDefFormat;
|
virStoragePRDefFormat;
|
||||||
virStoragePRDefFree;
|
virStoragePRDefFree;
|
||||||
|
virStoragePRDefIsEnabled;
|
||||||
virStoragePRDefIsEqual;
|
virStoragePRDefIsEqual;
|
||||||
|
virStoragePRDefIsManaged;
|
||||||
virStoragePRDefParseXML;
|
virStoragePRDefParseXML;
|
||||||
virStorageSourceBackingStoreClear;
|
virStorageSourceBackingStoreClear;
|
||||||
virStorageSourceClear;
|
virStorageSourceClear;
|
||||||
|
@ -773,3 +773,21 @@ qemuAliasChardevFromDevAlias(const char *devAlias)
|
|||||||
|
|
||||||
return ret;
|
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)
|
char *qemuAliasChardevFromDevAlias(const char *devAlias)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
const char *qemuDomainGetManagedPRAlias(void);
|
||||||
|
|
||||||
|
char *qemuDomainGetUnmanagedPRAlias(const virDomainDiskDef *disk);
|
||||||
|
|
||||||
#endif /* __QEMU_ALIAS_H__*/
|
#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
|
static int
|
||||||
qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
|
qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
|
||||||
virQEMUCapsPtr qemuCaps,
|
virQEMUCapsPtr qemuCaps,
|
||||||
@ -1533,6 +1555,9 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
|
|||||||
|
|
||||||
if (disk->src->debug)
|
if (disk->src->debug)
|
||||||
virBufferAsprintf(buf, ",file.debug=%d", disk->src->debugLevel);
|
virBufferAsprintf(buf, ",file.debug=%d", disk->src->debugLevel);
|
||||||
|
|
||||||
|
if (qemuBuildDriveSourcePR(buf, disk) < 0)
|
||||||
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (!(source = virQEMUBuildDriveCommandlineFromJSON(srcprops)))
|
if (!(source = virQEMUBuildDriveCommandlineFromJSON(srcprops)))
|
||||||
goto cleanup;
|
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:
|
* qemuBuildCommandLineValidate:
|
||||||
*
|
*
|
||||||
@ -9787,6 +9918,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
|
|||||||
if (qemuBuildMasterKeyCommandLine(cmd, priv) < 0)
|
if (qemuBuildMasterKeyCommandLine(cmd, priv) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (qemuBuildMasterPRCommandLine(vm, cmd, def) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (enableFips)
|
if (enableFips)
|
||||||
virCommandAddArg(cmd, "-enable-fips");
|
virCommandAddArg(cmd, "-enable-fips");
|
||||||
|
|
||||||
|
@ -54,6 +54,11 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
|
|||||||
size_t *nnicindexes,
|
size_t *nnicindexes,
|
||||||
int **nicindexes);
|
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 */
|
/* Generate the object properties for a secret */
|
||||||
int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
|
int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
|
||||||
|
@ -12001,3 +12001,25 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
|
|||||||
}
|
}
|
||||||
VIR_FREE(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 *direct,
|
||||||
bool *noflush);
|
bool *noflush);
|
||||||
|
|
||||||
|
char * qemuDomainGetPRSocketPath(virDomainObjPtr vm,
|
||||||
|
virStoragePRDefPtr pr);
|
||||||
|
|
||||||
#endif /* __QEMU_DOMAIN_H__ */
|
#endif /* __QEMU_DOMAIN_H__ */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
# include "qemu_conf.h"
|
# include "qemu_conf.h"
|
||||||
# include "qemu_domain.h"
|
# include "qemu_domain.h"
|
||||||
|
# include "virstoragefile.h"
|
||||||
|
|
||||||
int qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
|
int qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
|
||||||
const char *domainDir);
|
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
|
virSecurityDeviceLabelDefPtr
|
||||||
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
||||||
const char *model)
|
const char *model)
|
||||||
|
@ -397,6 +397,8 @@ void virStoragePRDefFormat(virBufferPtr buf,
|
|||||||
virStoragePRDefPtr prd);
|
virStoragePRDefPtr prd);
|
||||||
bool virStoragePRDefIsEqual(virStoragePRDefPtr a,
|
bool virStoragePRDefIsEqual(virStoragePRDefPtr a,
|
||||||
virStoragePRDefPtr b);
|
virStoragePRDefPtr b);
|
||||||
|
bool virStoragePRDefIsEnabled(virStoragePRDefPtr prd);
|
||||||
|
bool virStoragePRDefIsManaged(virStoragePRDefPtr prd);
|
||||||
|
|
||||||
virSecurityDeviceLabelDefPtr
|
virSecurityDeviceLabelDefPtr
|
||||||
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
||||||
|
38
tests/qemuxml2argvdata/disk-virtio-scsi-reservations.args
Normal file
38
tests/qemuxml2argvdata/disk-virtio-scsi-reservations.args
Normal file
@ -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_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4,
|
||||||
QEMU_CAPS_ICH9_USB_EHCI1);
|
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.
|
/* Test disks with format probing enabled for legacy reasons.
|
||||||
* New tests should not go in this section. */
|
* New tests should not go in this section. */
|
||||||
driver.config->allowDiskFormatProbing = true;
|
driver.config->allowDiskFormatProbing = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user