mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
nodedev: add support for mdev attributes
Mediated devices support arbitrary vendor-specific attributes that can be attached to a mediated device. These attributes are ordered, and are written to sysfs in order after a device is created. This patch adds support for these attributes to the mdev data types and XML schema. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
37ab63a6fc
commit
c952d9cc1e
@ -394,6 +394,13 @@
|
||||
belongs. This is a read-only field that is reported by the
|
||||
device driver.
|
||||
</dd>
|
||||
<dt><code>attr</code></dt>
|
||||
<dd>
|
||||
This optional element can occur multiple times. It represents a
|
||||
vendor-specific attribute that is used to configure this
|
||||
mediated device. It has two required attributes:
|
||||
<code>name</code> and <code>value</code>.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>ccw</code></dt>
|
||||
|
@ -636,6 +636,12 @@
|
||||
</attribute>
|
||||
</element>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<element name="attr">
|
||||
<attribute name="name"/>
|
||||
<attribute name="value"/>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</define>
|
||||
|
||||
<define name='capccwdev'>
|
||||
|
@ -500,6 +500,22 @@ virNodeDeviceCapStorageDefFormat(virBufferPtr buf,
|
||||
virBufferAddLit(buf, "<capability type='hotpluggable'/>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
virNodeDeviceCapMdevDefFormat(virBufferPtr buf,
|
||||
const virNodeDevCapData *data)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
virBufferEscapeString(buf, "<type id='%s'/>\n", data->mdev.type);
|
||||
virBufferAsprintf(buf, "<iommuGroup number='%u'/>\n",
|
||||
data->mdev.iommuGroupNumber);
|
||||
|
||||
for (i = 0; i < data->mdev.nattributes; i++) {
|
||||
virMediatedDeviceAttrPtr attr = data->mdev.attributes[i];
|
||||
virBufferAsprintf(buf, "<attr name='%s' value='%s'/>\n",
|
||||
attr->name, attr->value);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
||||
@ -583,9 +599,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
|
||||
virBufferEscapeString(&buf, "<type>%s</type>\n", virNodeDevDRMTypeToString(data->drm.type));
|
||||
break;
|
||||
case VIR_NODE_DEV_CAP_MDEV:
|
||||
virBufferEscapeString(&buf, "<type id='%s'/>\n", data->mdev.type);
|
||||
virBufferAsprintf(&buf, "<iommuGroup number='%u'/>\n",
|
||||
data->mdev.iommuGroupNumber);
|
||||
virNodeDeviceCapMdevDefFormat(&buf, data);
|
||||
break;
|
||||
case VIR_NODE_DEV_CAP_CCW_DEV:
|
||||
virBufferAsprintf(&buf, "<cssid>0x%x</cssid>\n",
|
||||
@ -1757,6 +1771,27 @@ virNodeDevCapSystemParseXML(xmlXPathContextPtr ctxt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
virNodeDevCapMdevAttributeParseXML(xmlXPathContextPtr ctxt,
|
||||
xmlNodePtr node,
|
||||
virNodeDevCapMdevPtr mdev)
|
||||
{
|
||||
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
||||
g_autoptr(virMediatedDeviceAttr) attr = virMediatedDeviceAttrNew();
|
||||
|
||||
ctxt->node = node;
|
||||
attr->name = virXPathString("string(./@name)", ctxt);
|
||||
attr->value = virXPathString("string(./@value)", ctxt);
|
||||
if (!attr->name || !attr->value) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("mdev attribute missing name or value"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return VIR_APPEND_ELEMENT(mdev->attributes,
|
||||
mdev->nattributes,
|
||||
attr);
|
||||
}
|
||||
|
||||
static int
|
||||
virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
|
||||
@ -1766,6 +1801,9 @@ virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
|
||||
{
|
||||
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
||||
int ret = -1;
|
||||
int nattrs = 0;
|
||||
g_autofree xmlNodePtr *attrs = NULL;
|
||||
size_t i;
|
||||
|
||||
ctxt->node = node;
|
||||
|
||||
@ -1785,6 +1823,12 @@ virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((nattrs = virXPathNodeSet("./attr", ctxt, &attrs)) < 0)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < nattrs; i++)
|
||||
virNodeDevCapMdevAttributeParseXML(ctxt, attrs[i], mdev);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
@ -2174,6 +2218,9 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
|
||||
break;
|
||||
case VIR_NODE_DEV_CAP_MDEV:
|
||||
VIR_FREE(data->mdev.type);
|
||||
for (i = 0; i < data->mdev.nattributes; i++)
|
||||
virMediatedDeviceAttrFree(data->mdev.attributes[i]);
|
||||
VIR_FREE(data->mdev.attributes);
|
||||
break;
|
||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||
case VIR_NODE_DEV_CAP_DRM:
|
||||
|
@ -141,6 +141,8 @@ typedef virNodeDevCapMdev *virNodeDevCapMdevPtr;
|
||||
struct _virNodeDevCapMdev {
|
||||
char *type;
|
||||
unsigned int iommuGroupNumber;
|
||||
virMediatedDeviceAttrPtr *attributes;
|
||||
size_t nattributes;
|
||||
};
|
||||
|
||||
typedef struct _virNodeDevCapPCIDev virNodeDevCapPCIDev;
|
||||
|
@ -2487,6 +2487,8 @@ virMacMapRemove;
|
||||
virMacMapWriteFile;
|
||||
|
||||
# util/virmdev.h
|
||||
virMediatedDeviceAttrFree;
|
||||
virMediatedDeviceAttrNew;
|
||||
virMediatedDeviceFree;
|
||||
virMediatedDeviceGetIOMMUGroupDev;
|
||||
virMediatedDeviceGetIOMMUGroupNum;
|
||||
|
@ -512,3 +512,15 @@ virMediatedDeviceTypeReadAttrs(const char *sysfspath,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virMediatedDeviceAttrPtr virMediatedDeviceAttrNew(void)
|
||||
{
|
||||
return g_new0(virMediatedDeviceAttr, 1);
|
||||
}
|
||||
|
||||
void virMediatedDeviceAttrFree(virMediatedDeviceAttrPtr attr)
|
||||
{
|
||||
g_free(attr->name);
|
||||
g_free(attr->value);
|
||||
g_free(attr);
|
||||
}
|
||||
|
@ -37,6 +37,17 @@ typedef struct _virMediatedDevice virMediatedDevice;
|
||||
typedef virMediatedDevice *virMediatedDevicePtr;
|
||||
typedef struct _virMediatedDeviceList virMediatedDeviceList;
|
||||
typedef virMediatedDeviceList *virMediatedDeviceListPtr;
|
||||
typedef struct _virMediatedDeviceAttr virMediatedDeviceAttr;
|
||||
typedef virMediatedDeviceAttr *virMediatedDeviceAttrPtr;
|
||||
|
||||
struct _virMediatedDeviceAttr {
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
virMediatedDeviceAttrPtr virMediatedDeviceAttrNew(void);
|
||||
void virMediatedDeviceAttrFree(virMediatedDeviceAttrPtr attr);
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virMediatedDeviceAttr, virMediatedDeviceAttrFree);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virMediatedDeviceList, virObjectUnref);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user