This is a definition that holds information on SCSI persistent
reservation settings. The XML part looks like this:
<reservations enabled='yes' managed='no'>
<source type='unix' path='/path/to/qemu-pr-helper.sock' mode='client'/>
</reservations>
If @managed is set to 'yes' then the <source/> is not parsed.
This design was agreed on here:
https://www.redhat.com/archives/libvir-list/2017-November/msg01005.html
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomain.html.in | 25 +++-
docs/schemas/domaincommon.rng | 34 +-----
docs/schemas/storagecommon.rng | 50 ++++++++
src/conf/domain_conf.c | 38 ++++++
src/libvirt_private.syms | 3 +
src/util/virstoragefile.c | 131 +++++++++++++++++++++
src/util/virstoragefile.h | 14 +++
.../disk-virtio-scsi-reservations.xml | 49 ++++++++
.../disk-virtio-scsi-reservations.xml | 1 +
tests/qemuxml2xmltest.c | 2 +
10 files changed, 316 insertions(+), 31 deletions(-)
create mode 100644 tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml
create mode 120000 tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 5e99884dc5..c20e98b4ef 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2563,7 +2563,10 @@
</disk>
<disk type='block' device='lun'>
<driver name='qemu' type='raw'/>
- <source dev='/dev/sda'/>
+ <source dev='/dev/sda'>
+ <reservations enabled='yes' managed='no'>
+ <source type='unix' path='/path/to/qemu-pr-helper' mode='client'/>
+ </reservations>
<target dev='sda' bus='scsi'/>
<address type='drive' controller='0' bus='0' target='3' unit='0'/>
</disk>
@@ -2926,6 +2929,26 @@
<a href="formatstorageencryption.html">Storage Encryption</a>
page for more information.
</dd>
+ <dt><code>reservations</code></dt>
+ <dd><span class="since">Since libvirt 4.1.0</span>, the
+ <code>reservations</code> can be a sub-element of the
+ <code>source</code> element for storage sources (QEMU driver only).
+ If present (and enabled) it enabled persistent reservations for
+ SCSI based disks. The element has one mandatory attribute
+ <code>enabled</code> with accepted values <code>yes</code> and
+ <code>no</code>. If the feature is enabled, then there's another
+ mandatory attribute <code>managed</code> (accepted values are the
+ same as for <code>enabled</code>) that enables or disables libvirt
+ spawning any helper process (should one be needed). However, if
+ libvirt is not enabled spawning helper process (i.e. hypervisor
+ should just use one which is already running), path to its socket
+ must be provided in child element <code>source</code>, which
+ currently accepts only the following attributes: <code>type</code>
+ with one value <code>unix</code>, <code>path</code> with path the
+ socket, and finally <code>mode</code> which accepts either
+ <code>server</code> or <code>client</code> and specifies the role
+ of hypervisor.
+ </dd>
</dl>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4cab55f05d..93084887fb 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1530,6 +1530,9 @@
<optional>
<ref name="encryption"/>
</optional>
+ <optional>
+ <ref name="reservations"/>
+ </optional>
<zeroOrMore>
<ref name='devSeclabel'/>
</zeroOrMore>
@@ -2434,18 +2437,6 @@
</attribute>
</optional>
</define>
- <define name="reconnect">
- <element name="reconnect">
- <attribute name="enabled">
- <ref name="virYesNo"/>
- </attribute>
- <optional>
- <attribute name="timeout">
- <ref name="unsignedInt"/>
- </attribute>
- </optional>
- </element>
- </define>
<!--
An interface description can either be of type bridge in which case
@@ -2494,24 +2485,7 @@
<value>vhostuser</value>
</attribute>
<interleave>
- <element name="source">
- <attribute name="type">
- <value>unix</value>
- </attribute>
- <attribute name="path">
- <ref name="absFilePath"/>
- </attribute>
- <attribute name="mode">
- <choice>
- <value>server</value>
- <value>client</value>
- </choice>
- </attribute>
- <optional>
- <ref name="reconnect"/>
- </optional>
- <empty/>
- </element>
+ <ref name="unixSocketSource"/>
<ref name="interface-options"/>
</interleave>
</group>
diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng
index edee1b0845..eed0b33347 100644
--- a/docs/schemas/storagecommon.rng
+++ b/docs/schemas/storagecommon.rng
@@ -39,6 +39,56 @@
</element>
</define>
+ <define name="reconnect">
+ <element name="reconnect">
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ <optional>
+ <attribute name="timeout">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name='unixSocketSource'>
+ <element name="source">
+ <attribute name="type">
+ <value>unix</value>
+ </attribute>
+ <attribute name="path">
+ <ref name="absFilePath"/>
+ </attribute>
+ <attribute name="mode">
+ <choice>
+ <value>server</value>
+ <value>client</value>
+ </choice>
+ </attribute>
+ <optional>
+ <ref name="reconnect"/>
+ </optional>
+ <empty/>
+ </element>
+ </define>
+
+ <define name='reservations'>
+ <element name='reservations'>
+ <attribute name='enabled'>
+ <ref name='virYesNo'/>
+ </attribute>
+ <optional>
+ <attribute name='managed'>
+ <ref name='virYesNo'/>
+ </attribute>
+ </optional>
+ <optional>
+ <ref name='unixSocketSource'/>
+ </optional>
+ </element>
+ </define>
+
<define name='secret'>
<element name='secret'>
<attribute name='type'>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d23182f18a..5943d05e0e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5210,6 +5210,13 @@ virDomainDiskDefValidate(const virDomainDiskDef *disk)
}
}
+ if (disk->src->pr &&
+ disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("<reservations/> allowed only for lun disks"));
+ return -1;
+ }
+
/* Reject disks with a bus type that is not compatible with the
* given address type. The function considers only buses that are
* handled in common code. For other bus types it's not possible
@@ -8602,6 +8609,31 @@ virDomainDiskSourcePrivateDataParse(xmlNodePtr node,
}
+static int
+virDomainDiskSourcePRParse(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virStoragePRDefPtr *pr)
+{
+ xmlNodePtr saveNode = ctxt->node;
+ int ret = -1;
+
+ ctxt->node = node;
+
+ if (!(ctxt->node = virXPathNode("./reservations", ctxt))) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (!(*pr = virStoragePRDefParseXML(ctxt)))
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ ctxt->node = saveNode;
+ return ret;
+}
+
+
static int
virDomainStorageSourceParse(xmlNodePtr node,
xmlXPathContextPtr ctxt,
@@ -8648,6 +8680,9 @@ virDomainStorageSourceParse(xmlNodePtr node,
!(src->encryption = virStorageEncryptionParseNode(tmp, ctxt)))
goto cleanup;
+ if (virDomainDiskSourcePRParse(node, ctxt, &src->pr) < 0)
+ goto cleanup;
+
if (virSecurityDeviceLabelDefParseXML(&src->seclabels, &src->nseclabels,
ctxt, flags) < 0)
goto cleanup;
@@ -22927,6 +22962,9 @@ virDomainStorageSourceFormat(virBufferPtr attrBuf,
virStorageEncryptionFormat(childBuf, src->encryption) < 0)
return -1;
+ if (src->pr)
+ virStoragePRDefFormat(childBuf, src->pr);
+
return 0;
}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index cab324c4d7..b39b694c60 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2797,6 +2797,9 @@ virStorageNetHostDefFree;
virStorageNetHostTransportTypeFromString;
virStorageNetHostTransportTypeToString;
virStorageNetProtocolTypeToString;
+virStoragePRDefFormat;
+virStoragePRDefFree;
+virStoragePRDefParseXML;
virStorageSourceBackingStoreClear;
virStorageSourceClear;
virStorageSourceCopy;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 67b9ec71ac..9917837513 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1892,6 +1892,136 @@ virStorageAuthDefFormat(virBufferPtr buf,
}
+void
+virStoragePRDefFree(virStoragePRDefPtr prd)
+{
+ if (!prd)
+ return;
+
+ VIR_FREE(prd->path);
+ VIR_FREE(prd);
+}
+
+
+virStoragePRDefPtr
+virStoragePRDefParseXML(xmlXPathContextPtr ctxt)
+{
+ virStoragePRDefPtr prd, ret = NULL;
+ char *enabled = NULL;
+ char *managed = NULL;
+ char *type = NULL;
+ char *path = NULL;
+ char *mode = NULL;
+
+ if (VIR_ALLOC(prd) < 0)
+ return NULL;
+
+ if (!(enabled = virXPathString("string(./@enabled)", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing @enabled attribute for <reservations/>"));
+ goto cleanup;
+ }
+
+ if ((prd->enabled = virTristateBoolTypeFromString(enabled)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid value for 'enabled': %s"), enabled);
+ goto cleanup;
+ }
+
+ if (prd->enabled == VIR_TRISTATE_BOOL_YES) {
+ if (!(managed = virXPathString("string(./@managed)", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing @managed attribute for <reservations/>"));
+ goto cleanup;
+ }
+
+ if ((prd->managed = virTristateBoolTypeFromString(managed)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid value for 'managed': %s"), managed);
+ goto cleanup;
+ }
+
+ if (prd->managed == VIR_TRISTATE_BOOL_NO) {
+ type = virXPathString("string(./source[1]/@type)", ctxt);
+ path = virXPathString("string(./source[1]/@path)", ctxt);
+ mode = virXPathString("string(./source[1]/@mode)", ctxt);
+
+ if (!type) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing connection type for <reservations/>"));
+ goto cleanup;
+ }
+
+ if (!path) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing path for <reservations/>"));
+ goto cleanup;
+ }
+
+ if (!mode) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing connection mode for <reservations/>"));
+ goto cleanup;
+ }
+
+ if (STRNEQ(type, "unix")) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unsupported connection type for <reservations/>: %s"),
+ type);
+ goto cleanup;
+ }
+
+ if (STRNEQ(mode, "client")) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unsupported connection mode for <reservations/>: %s"),
+ mode);
+ goto cleanup;
+ }
+
+ VIR_STEAL_PTR(prd->path, path);
+ }
+ }
+
+ ret = prd;
+ prd = NULL;
+
+ cleanup:
+ VIR_FREE(mode);
+ VIR_FREE(path);
+ VIR_FREE(type);
+ VIR_FREE(managed);
+ VIR_FREE(enabled);
+ virStoragePRDefFree(prd);
+ return ret;
+}
+
+
+void
+virStoragePRDefFormat(virBufferPtr buf,
+ virStoragePRDefPtr prd)
+{
+ virBufferAsprintf(buf, "<reservations enabled='%s'",
+ virTristateBoolTypeToString(prd->enabled));
+ if (prd->enabled == VIR_TRISTATE_BOOL_YES) {
+ virBufferAsprintf(buf, " managed='%s'",
+ virTristateBoolTypeToString(prd->managed));
+ if (prd->managed == VIR_TRISTATE_BOOL_NO) {
+ virBufferAddLit(buf, ">\n");
+ virBufferAdjustIndent(buf, 2);
+ virBufferAddLit(buf, "<source type='unix'");
+ virBufferEscapeString(buf, " path='%s'", prd->path);
+ virBufferAddLit(buf, " mode='client'/>\n");
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</reservations>\n");
+ } else {
+ virBufferAddLit(buf, "/>\n");
+ }
+ } else {
+ virBufferAddLit(buf, "/>\n");
+ }
+}
+
+
virSecurityDeviceLabelDefPtr
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
const char *model)
@@ -2270,6 +2400,7 @@ virStorageSourceClear(virStorageSourcePtr def)
virBitmapFree(def->features);
VIR_FREE(def->compat);
virStorageEncryptionFree(def->encryption);
+ virStoragePRDefFree(def->pr);
virStorageSourceSeclabelsClear(def);
virStoragePermsFree(def->perms);
VIR_FREE(def->timestamps);
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 596746ccb7..b705ab1f92 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -216,6 +216,14 @@ struct _virStorageAuthDef {
virSecretLookupTypeDef seclookupdef;
};
+typedef struct _virStoragePRDef virStoragePRDef;
+typedef virStoragePRDef *virStoragePRDefPtr;
+struct _virStoragePRDef {
+ int enabled; /* enum virTristateBool */
+ int managed; /* enum virTristateBool */
+ char *path;
+};
+
typedef struct _virStorageDriverData virStorageDriverData;
typedef virStorageDriverData *virStorageDriverDataPtr;
@@ -243,6 +251,7 @@ struct _virStorageSource {
bool authInherited;
virStorageEncryptionPtr encryption;
bool encryptionInherited;
+ virStoragePRDefPtr pr;
virObjectPtr privateData;
@@ -370,6 +379,11 @@ virStorageAuthDefPtr virStorageAuthDefParse(xmlNodePtr node,
xmlXPathContextPtr ctxt);
void virStorageAuthDefFormat(virBufferPtr buf, virStorageAuthDefPtr authdef);
+void virStoragePRDefFree(virStoragePRDefPtr prd);
+virStoragePRDefPtr virStoragePRDefParseXML(xmlXPathContextPtr ctxt);
+void virStoragePRDefFormat(virBufferPtr buf,
+ virStoragePRDefPtr prd);
+
virSecurityDeviceLabelDefPtr
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
const char *model);
diff --git a/tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml b/tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml
new file mode 100644
index 0000000000..036c6e3c25
--- /dev/null
+++ b/tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml
@@ -0,0 +1,49 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>8</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='lun'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'>
+ <reservations enabled='yes' managed='yes'/>
+ </source>
+ <target dev='sda' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='block' device='lun'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest2'>
+ <reservations enabled='yes' managed='no'>
+ <source type='unix' path='/path/to/qemu-pr-helper.sock' mode='client'/>
+ </reservations>
+ </source>
+ <target dev='sdb' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='1'/>
+ </disk>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='scsi' index='0' model='virtio-scsi'>
+ <driver queues='8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml b/tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml
new file mode 120000
index 0000000000..dde52fd1db
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/disk-virtio-scsi-reservations.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index d123180e79..4c069497aa 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -387,6 +387,8 @@ mymain(void)
QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_VIRTIO_SCSI);
DO_TEST("disk-virtio-scsi-num_queues",
QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_VIRTIO_SCSI);
+ DO_TEST("disk-virtio-scsi-reservations",
+ QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_VIRTIO_SCSI);
DO_TEST("disk-virtio-scsi-cmd_per_lun",
QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_VIRTIO_SCSI);
DO_TEST("disk-virtio-scsi-max_sectors",
--
2.16.1
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 04/10/2018 10:58 AM, Michal Privoznik wrote: > This is a definition that holds information on SCSI persistent > reservation settings. The XML part looks like this: > > <reservations enabled='yes' managed='no'> > <source type='unix' path='/path/to/qemu-pr-helper.sock' mode='client'/> > </reservations> > > If @managed is set to 'yes' then the <source/> is not parsed. > This design was agreed on here: > > https://www.redhat.com/archives/libvir-list/2017-November/msg01005.html > > Signed-off-by: Michal Privoznik <mprivozn@redhat.com> > --- > docs/formatdomain.html.in | 25 +++- > docs/schemas/domaincommon.rng | 34 +----- > docs/schemas/storagecommon.rng | 50 ++++++++ > src/conf/domain_conf.c | 38 ++++++ > src/libvirt_private.syms | 3 + > src/util/virstoragefile.c | 131 +++++++++++++++++++++ > src/util/virstoragefile.h | 14 +++ > .../disk-virtio-scsi-reservations.xml | 49 ++++++++ > .../disk-virtio-scsi-reservations.xml | 1 + > tests/qemuxml2xmltest.c | 2 + > 10 files changed, 316 insertions(+), 31 deletions(-) > create mode 100644 tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml > create mode 120000 tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index 5e99884dc5..c20e98b4ef 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -2563,7 +2563,10 @@ > </disk> > <disk type='block' device='lun'> > <driver name='qemu' type='raw'/> > - <source dev='/dev/sda'/> > + <source dev='/dev/sda'> > + <reservations enabled='yes' managed='no'> > + <source type='unix' path='/path/to/qemu-pr-helper' mode='client'/> > + </reservations> > <target dev='sda' bus='scsi'/> > <address type='drive' controller='0' bus='0' target='3' unit='0'/> > </disk> > @@ -2926,6 +2929,26 @@ > <a href="formatstorageencryption.html">Storage Encryption</a> > page for more information. > </dd> > + <dt><code>reservations</code></dt> > + <dd><span class="since">Since libvirt 4.1.0</span>, the Now at least 4.3 > + <code>reservations</code> can be a sub-element of the > + <code>source</code> element for storage sources (QEMU driver only). > + If present (and enabled) it enabled persistent reservations for s/enabled/enables > + SCSI based disks. The element has one mandatory attribute > + <code>enabled</code> with accepted values <code>yes</code> and > + <code>no</code>. If the feature is enabled, then there's another <unrelatedRant>I wish we were consistent about using <code> around 'yes' and 'no' - some places use "yes" and/or "no".</unrelatedRant> > + mandatory attribute <code>managed</code> (accepted values are the > + same as for <code>enabled</code>) that enables or disables libvirt > + spawning any helper process (should one be needed). However, if s/any/a/ ? s/(should one be needed)// IOW: What really decides if one is needed? > + libvirt is not enabled spawning helper process (i.e. hypervisor Starting from "However, if.. " This reads strange - why not just indicate "If enabled is yes, then libvirt will ...; otherwise, libvirt will .... Taken from patch 4: + /* Managed PR means there's one pr-manager object per domain + * and the pr-helper process is spawned and managed by + * libvirt. + * If PR is unmanaged there's one pr-manager object per disk + * (in general each disk can have its own pr-manager) and + * it's user's responsibility to start the pr-helper process. + */ When the PR is unmanaged, then the path to its socket... > + should just use one which is already running), path to its socket > + must be provided in child element <code>source</code>, which > + currently accepts only the following attributes: <code>type</code> > + with one value <code>unix</code>, <code>path</code> with path the > + socket, and finally <code>mode</code> which accepts either > + <code>server</code> or <code>client</code> and specifies the role > + of hypervisor. mode only Parse's and Format's "client"... Perhaps the best thing to indicate here is that since libvirt is then a client of the user provided pr-helper process and will use a unix socket to connect to the process, the type must be unix and the mode must be client with the path being the path to the socket which libvirt will attempt to connect to. > + </dd> > </dl> > > <p> [...] > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index d23182f18a..5943d05e0e 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -5210,6 +5210,13 @@ virDomainDiskDefValidate(const virDomainDiskDef *disk) > } > } > > + if (disk->src->pr && > + disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("<reservations/> allowed only for lun disks")); allowed or required ;-) s/disks/devices/ > + return -1; > + } > + > /* Reject disks with a bus type that is not compatible with the > * given address type. The function considers only buses that are > * handled in common code. For other bus types it's not possible [...] > static int > virDomainStorageSourceParse(xmlNodePtr node, > xmlXPathContextPtr ctxt, > @@ -8648,6 +8680,9 @@ virDomainStorageSourceParse(xmlNodePtr node, > !(src->encryption = virStorageEncryptionParseNode(tmp, ctxt))) > goto cleanup; > > + if (virDomainDiskSourcePRParse(node, ctxt, &src->pr) < 0) > + goto cleanup; > + > if (virSecurityDeviceLabelDefParseXML(&src->seclabels, &src->nseclabels, > ctxt, flags) < 0) > goto cleanup; > @@ -22927,6 +22962,9 @@ virDomainStorageSourceFormat(virBufferPtr attrBuf, > virStorageEncryptionFormat(childBuf, src->encryption) < 0) > return -1; > > + if (src->pr) > + virStoragePRDefFormat(childBuf, src->pr); Or just have virStoragePRDefFormat return if passed src->pr == NULL, IDC either way. > + > return 0; > } > [...] With at least the formatdomain and lun device error message adjustment, Reviewed-by: John Ferlan <jferlan@redhat.com> John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.