提交 13fe558f 编写于 作者: M Michal Privoznik

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: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJohn Ferlan <jferlan@redhat.com>
上级 3c286027
......@@ -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,
......
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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册