virStorageNetProtocolTypeToString;
virStoragePRDefFormat;
virStoragePRDefFree;
+virStoragePRDefIsEnabled;
virStoragePRDefIsEqual;
+virStoragePRDefIsManaged;
virStoragePRDefParseXML;
virStorageSourceBackingStoreClear;
virStorageSourceClear;
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;
+}
char *qemuAliasChardevFromDevAlias(const char *devAlias)
ATTRIBUTE_NONNULL(1);
+const char *qemuDomainGetManagedPRAlias(void);
+
+char *qemuDomainGetUnmanagedPRAlias(const virDomainDiskDef *disk);
+
#endif /* __QEMU_ALIAS_H__*/
}
+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,
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;
}
+/**
+ * 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:
*
if (qemuBuildMasterKeyCommandLine(cmd, priv) < 0)
goto error;
+ if (qemuBuildMasterPRCommandLine(vm, cmd, def) < 0)
+ goto error;
+
if (enableFips)
virCommandAddArg(cmd, "-enable-fips");
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,
}
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;
+}
bool *direct,
bool *noflush);
+char * qemuDomainGetPRSocketPath(virDomainObjPtr vm,
+ virStoragePRDefPtr pr);
+
#endif /* __QEMU_DOMAIN_H__ */
# include "qemu_conf.h"
# include "qemu_domain.h"
+# include "virstoragefile.h"
int qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
const char *domainDir);
}
+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)
virStoragePRDefPtr prd);
bool virStoragePRDefIsEqual(virStoragePRDefPtr a,
virStoragePRDefPtr b);
+bool virStoragePRDefIsEnabled(virStoragePRDefPtr prd);
+bool virStoragePRDefIsManaged(virStoragePRDefPtr prd);
virSecurityDeviceLabelDefPtr
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
--- /dev/null
+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
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;