conf: introduce support for Fibre Channel VMID

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Pavel Hrdina 2021-08-05 15:43:58 +02:00
parent 9ea9f7dab2
commit 38b5f4faab
7 changed files with 101 additions and 1 deletions

View File

@ -1221,6 +1221,27 @@ Resource partitions are currently supported by the QEMU and LXC drivers, which
map partition paths to cgroups directories, in all mounted controllers. map partition paths to cgroups directories, in all mounted controllers.
:since:`Since 1.0.5` :since:`Since 1.0.5`
Fibre Channel VMID
-------------------
The FC SAN can provide various QoS levels and access control depending on the
VMID. It can also collect telemetry data at per-VM level which can be used
to enhance the IO performance of the VM. This can be configured by using
the ``appid`` attribute of ``fibrechannel`` element. The attribute contains
single string (max 128 bytes) and it is used by kernel to create VMID.
::
...
<resource>
<fibrechannel appid='userProvidedID'/>
</resource>
...
Using this feature requires Fibre Channel capable HW, kernel compiled with
option ``CONFIG_BLK_CGROUP_FC_APPID`` and ``nvme_fc`` kernel module loaded.
:since:`Since 7.7.0`
:anchor:`<a id="elementsCPU"/>` :anchor:`<a id="elementsCPU"/>`
CPU model and topology CPU model and topology

View File

@ -576,6 +576,17 @@
</element> </element>
</define> </define>
<define name="fibrechannel">
<element name="fibrechannel">
<attribute name="appid">
<data type="string">
<!-- All printable characters -->
<param name="pattern">[&#x20;-&#x7E;]{1,128}</param>
</data>
</attribute>
</element>
</define>
<!-- <!--
The Identifiers can be: The Identifiers can be:
- an optional id attribute with a number on the domain element - an optional id attribute with a number on the domain element
@ -1177,6 +1188,9 @@
<ref name="absFilePath"/> <ref name="absFilePath"/>
</element> </element>
</optional> </optional>
<optional>
<ref name="fibrechannel"/>
</optional>
</element> </element>
</define> </define>

View File

@ -3446,6 +3446,7 @@ virDomainResourceDefFree(virDomainResourceDef *resource)
return; return;
g_free(resource->partition); g_free(resource->partition);
g_free(resource->appid);
g_free(resource); g_free(resource);
} }
@ -17285,16 +17286,19 @@ virDomainResourceDefParse(xmlNodePtr node,
VIR_XPATH_NODE_AUTORESTORE(ctxt) VIR_XPATH_NODE_AUTORESTORE(ctxt)
virDomainResourceDef *def = NULL; virDomainResourceDef *def = NULL;
char *partition = NULL; char *partition = NULL;
char *appid = NULL;
ctxt->node = node; ctxt->node = node;
partition = virXPathString("string(./partition)", ctxt); partition = virXPathString("string(./partition)", ctxt);
appid = virXPathString("string(./fibrechannel/@appid)", ctxt);
if (!partition) if (!partition && !appid)
return NULL; return NULL;
def = g_new0(virDomainResourceDef, 1); def = g_new0(virDomainResourceDef, 1);
def->partition = partition; def->partition = partition;
def->appid = appid;
return def; return def;
} }
@ -26769,6 +26773,9 @@ virDomainResourceDefFormat(virBuffer *buf,
if (def->partition) if (def->partition)
virBufferEscapeString(&childBuf, "<partition>%s</partition>\n", def->partition); virBufferEscapeString(&childBuf, "<partition>%s</partition>\n", def->partition);
if (def->appid)
virBufferEscapeString(&childBuf, "<fibrechannel appid='%s'/>\n", def->appid);
virXMLFormatElement(buf, "resource", NULL, &childBuf); virXMLFormatElement(buf, "resource", NULL, &childBuf);
} }

View File

@ -2538,6 +2538,7 @@ void virBlkioDeviceArrayClear(virBlkioDevice *deviceWeights,
struct _virDomainResourceDef { struct _virDomainResourceDef {
char *partition; char *partition;
char *appid;
}; };
struct _virDomainHugePage { struct _virDomainHugePage {

View File

@ -55,6 +55,37 @@ virDomainDefBootValidate(const virDomainDef *def)
} }
#define APPID_LEN_MIN 1
#define APPID_LEN_MAX 128
static int
virDomainDefResourceValidate(const virDomainDef *def)
{
if (!def->resource)
return 0;
if (def->resource->appid) {
int len;
if (!virStringIsPrintable(def->resource->appid)) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Fibre Channel 'appid' is not a printable string"));
return -1;
}
len = strlen(def->resource->appid);
if (len < APPID_LEN_MIN || len > APPID_LEN_MAX) {
virReportError(VIR_ERR_INVALID_ARG,
_("Fibre Channel 'appid' string length must be between [%d, %d]"),
APPID_LEN_MIN, APPID_LEN_MAX);
return -1;
}
}
return 0;
}
static int static int
virDomainDefVideoValidate(const virDomainDef *def) virDomainDefVideoValidate(const virDomainDef *def)
{ {
@ -1538,6 +1569,9 @@ static int
virDomainDefValidateInternal(const virDomainDef *def, virDomainDefValidateInternal(const virDomainDef *def,
virDomainXMLOption *xmlopt) virDomainXMLOption *xmlopt)
{ {
if (virDomainDefResourceValidate(def) < 0)
return -1;
if (virDomainDefDuplicateDiskInfoValidate(def) < 0) if (virDomainDefDuplicateDiskInfoValidate(def) < 0)
return -1; return -1;

View File

@ -0,0 +1,21 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>4</vcpu>
<resource>
<fibrechannel appid='someapp:c7a5fdbd-edaf-9455-926a-d65c16db1809'/>
</resource>
<os>
<type arch='x86_64' machine='q35'>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-x86_64</emulator>
</devices>
</domain>

View File

@ -225,6 +225,8 @@ mymain(void)
DO_TEST_DIFFERENT("cputune"); DO_TEST_DIFFERENT("cputune");
DO_TEST("device-backenddomain"); DO_TEST("device-backenddomain");
DO_TEST("fibrechannel-appid");
#define DO_TEST_BACKUP_FULL(name, intrnl) \ #define DO_TEST_BACKUP_FULL(name, intrnl) \
do { \ do { \
const struct testCompareBackupXMLData data = { .testname = name, \ const struct testCompareBackupXMLData data = { .testname = name, \