mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-28 06:12:20 +00:00
virstoragefile: Introduce virStoragePRDef
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> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
4a3d6ed5ee
commit
687730540e
@ -2566,7 +2566,10 @@
|
|||||||
</disk>
|
</disk>
|
||||||
<disk type='block' device='lun'>
|
<disk type='block' device='lun'>
|
||||||
<driver name='qemu' type='raw'/>
|
<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'/>
|
<target dev='sda' bus='scsi'/>
|
||||||
<address type='drive' controller='0' bus='0' target='3' unit='0'/>
|
<address type='drive' controller='0' bus='0' target='3' unit='0'/>
|
||||||
</disk>
|
</disk>
|
||||||
@ -2929,6 +2932,26 @@
|
|||||||
<a href="formatstorageencryption.html">Storage Encryption</a>
|
<a href="formatstorageencryption.html">Storage Encryption</a>
|
||||||
page for more information.
|
page for more information.
|
||||||
</dd>
|
</dd>
|
||||||
|
<dt><code>reservations</code></dt>
|
||||||
|
<dd><span class="since">Since libvirt 4.4.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 enables 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 a helper process. When the PR is unmanaged, then hypervisor
|
||||||
|
acts as a client and path to server 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 one value
|
||||||
|
<code>client</code> and specifies the role of hypervisor.
|
||||||
|
It's recommended to allow libvirt manage the persistent
|
||||||
|
reservations.
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -1530,6 +1530,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="encryption"/>
|
<ref name="encryption"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="reservations"/>
|
||||||
|
</optional>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<ref name='devSeclabel'/>
|
<ref name='devSeclabel'/>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
@ -2434,18 +2437,6 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
</optional>
|
</optional>
|
||||||
</define>
|
</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
|
An interface description can either be of type bridge in which case
|
||||||
@ -2494,24 +2485,7 @@
|
|||||||
<value>vhostuser</value>
|
<value>vhostuser</value>
|
||||||
</attribute>
|
</attribute>
|
||||||
<interleave>
|
<interleave>
|
||||||
<element name="source">
|
<ref name="unixSocketSource"/>
|
||||||
<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="interface-options"/>
|
<ref name="interface-options"/>
|
||||||
</interleave>
|
</interleave>
|
||||||
</group>
|
</group>
|
||||||
|
@ -39,6 +39,56 @@
|
|||||||
</element>
|
</element>
|
||||||
</define>
|
</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'>
|
<define name='secret'>
|
||||||
<element name='secret'>
|
<element name='secret'>
|
||||||
<attribute name='type'>
|
<attribute name='type'>
|
||||||
|
@ -5206,6 +5206,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 devices"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reject disks with a bus type that is not compatible with the
|
/* Reject disks with a bus type that is not compatible with the
|
||||||
* given address type. The function considers only buses that are
|
* given address type. The function considers only buses that are
|
||||||
* handled in common code. For other bus types it's not possible
|
* handled in common code. For other bus types it's not possible
|
||||||
@ -8632,6 +8639,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
|
static int
|
||||||
virDomainStorageSourceParse(xmlNodePtr node,
|
virDomainStorageSourceParse(xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
@ -8678,6 +8710,9 @@ virDomainStorageSourceParse(xmlNodePtr node,
|
|||||||
!(src->encryption = virStorageEncryptionParseNode(tmp, ctxt)))
|
!(src->encryption = virStorageEncryptionParseNode(tmp, ctxt)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virDomainDiskSourcePRParse(node, ctxt, &src->pr) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (virSecurityDeviceLabelDefParseXML(&src->seclabels, &src->nseclabels,
|
if (virSecurityDeviceLabelDefParseXML(&src->seclabels, &src->nseclabels,
|
||||||
ctxt, flags) < 0)
|
ctxt, flags) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -22953,6 +22988,9 @@ virDomainStorageSourceFormat(virBufferPtr attrBuf,
|
|||||||
virStorageEncryptionFormat(childBuf, src->encryption) < 0)
|
virStorageEncryptionFormat(childBuf, src->encryption) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (src->pr)
|
||||||
|
virStoragePRDefFormat(childBuf, src->pr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2801,6 +2801,9 @@ virStorageNetHostDefFree;
|
|||||||
virStorageNetHostTransportTypeFromString;
|
virStorageNetHostTransportTypeFromString;
|
||||||
virStorageNetHostTransportTypeToString;
|
virStorageNetHostTransportTypeToString;
|
||||||
virStorageNetProtocolTypeToString;
|
virStorageNetProtocolTypeToString;
|
||||||
|
virStoragePRDefFormat;
|
||||||
|
virStoragePRDefFree;
|
||||||
|
virStoragePRDefParseXML;
|
||||||
virStorageSourceBackingStoreClear;
|
virStorageSourceBackingStoreClear;
|
||||||
virStorageSourceClear;
|
virStorageSourceClear;
|
||||||
virStorageSourceCopy;
|
virStorageSourceCopy;
|
||||||
|
@ -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
|
virSecurityDeviceLabelDefPtr
|
||||||
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
||||||
const char *model)
|
const char *model)
|
||||||
@ -2268,6 +2398,7 @@ virStorageSourceClear(virStorageSourcePtr def)
|
|||||||
virBitmapFree(def->features);
|
virBitmapFree(def->features);
|
||||||
VIR_FREE(def->compat);
|
VIR_FREE(def->compat);
|
||||||
virStorageEncryptionFree(def->encryption);
|
virStorageEncryptionFree(def->encryption);
|
||||||
|
virStoragePRDefFree(def->pr);
|
||||||
virStorageSourceSeclabelsClear(def);
|
virStorageSourceSeclabelsClear(def);
|
||||||
virStoragePermsFree(def->perms);
|
virStoragePermsFree(def->perms);
|
||||||
VIR_FREE(def->timestamps);
|
VIR_FREE(def->timestamps);
|
||||||
|
@ -216,6 +216,14 @@ struct _virStorageAuthDef {
|
|||||||
virSecretLookupTypeDef seclookupdef;
|
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 struct _virStorageDriverData virStorageDriverData;
|
||||||
typedef virStorageDriverData *virStorageDriverDataPtr;
|
typedef virStorageDriverData *virStorageDriverDataPtr;
|
||||||
|
|
||||||
@ -243,6 +251,7 @@ struct _virStorageSource {
|
|||||||
bool authInherited;
|
bool authInherited;
|
||||||
virStorageEncryptionPtr encryption;
|
virStorageEncryptionPtr encryption;
|
||||||
bool encryptionInherited;
|
bool encryptionInherited;
|
||||||
|
virStoragePRDefPtr pr;
|
||||||
|
|
||||||
virObjectPtr privateData;
|
virObjectPtr privateData;
|
||||||
|
|
||||||
@ -382,6 +391,11 @@ virStorageAuthDefPtr virStorageAuthDefParse(xmlNodePtr node,
|
|||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
void virStorageAuthDefFormat(virBufferPtr buf, virStorageAuthDefPtr authdef);
|
void virStorageAuthDefFormat(virBufferPtr buf, virStorageAuthDefPtr authdef);
|
||||||
|
|
||||||
|
void virStoragePRDefFree(virStoragePRDefPtr prd);
|
||||||
|
virStoragePRDefPtr virStoragePRDefParseXML(xmlXPathContextPtr ctxt);
|
||||||
|
void virStoragePRDefFormat(virBufferPtr buf,
|
||||||
|
virStoragePRDefPtr prd);
|
||||||
|
|
||||||
virSecurityDeviceLabelDefPtr
|
virSecurityDeviceLabelDefPtr
|
||||||
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
|
||||||
const char *model);
|
const char *model);
|
||||||
|
49
tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml
Normal file
49
tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml
Normal file
@ -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>
|
1
tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml
Symbolic link
1
tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../qemuxml2argvdata/disk-virtio-scsi-reservations.xml
|
@ -387,6 +387,8 @@ mymain(void)
|
|||||||
QEMU_CAPS_VIRTIO_SCSI);
|
QEMU_CAPS_VIRTIO_SCSI);
|
||||||
DO_TEST("disk-virtio-scsi-num_queues",
|
DO_TEST("disk-virtio-scsi-num_queues",
|
||||||
QEMU_CAPS_VIRTIO_SCSI);
|
QEMU_CAPS_VIRTIO_SCSI);
|
||||||
|
DO_TEST("disk-virtio-scsi-reservations",
|
||||||
|
QEMU_CAPS_VIRTIO_SCSI);
|
||||||
DO_TEST("disk-virtio-scsi-cmd_per_lun",
|
DO_TEST("disk-virtio-scsi-cmd_per_lun",
|
||||||
QEMU_CAPS_VIRTIO_SCSI);
|
QEMU_CAPS_VIRTIO_SCSI);
|
||||||
DO_TEST("disk-virtio-scsi-max_sectors",
|
DO_TEST("disk-virtio-scsi-max_sectors",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user