virmdev: prepare type and attributes for dual state

Create a new structure holding type and attributes as these are
modifiable in a persistent mdev configuration and run out of sync with
the active mdev configuration.

Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Boris Fiuczynski 2024-02-22 14:01:58 +01:00 committed by Michal Privoznik
parent 93d67c58c2
commit 47e57159b3
5 changed files with 51 additions and 47 deletions

View File

@ -593,15 +593,15 @@ virNodeDeviceCapMdevDefFormat(virBuffer *buf,
{
size_t i;
virBufferEscapeString(buf, "<type id='%s'/>\n", data->mdev.type);
virBufferEscapeString(buf, "<type id='%s'/>\n", data->mdev.dev_config.type);
virBufferEscapeString(buf, "<uuid>%s</uuid>\n", data->mdev.uuid);
virBufferEscapeString(buf, "<parent_addr>%s</parent_addr>\n",
data->mdev.parent_addr);
virBufferAsprintf(buf, "<iommuGroup number='%u'/>\n",
data->mdev.iommuGroupNumber);
for (i = 0; i < data->mdev.nattributes; i++) {
virMediatedDeviceAttr *attr = data->mdev.attributes[i];
for (i = 0; i < data->mdev.dev_config.nattributes; i++) {
virMediatedDeviceAttr *attr = data->mdev.dev_config.attributes[i];
virBufferAsprintf(buf, "<attr name='%s' value='%s'/>\n",
attr->name, attr->value);
}
@ -2183,7 +2183,7 @@ virNodeDevCapMdevAttributeParseXML(xmlXPathContextPtr ctxt,
return -1;
}
VIR_APPEND_ELEMENT(mdev->attributes, mdev->nattributes, attr);
VIR_APPEND_ELEMENT(mdev->dev_config.attributes, mdev->dev_config.nattributes, attr);
return 0;
}
@ -2202,7 +2202,7 @@ virNodeDevCapMdevParseXML(xmlXPathContextPtr ctxt,
ctxt->node = node;
if (!(mdev->type = virXPathString("string(./type[1]/@id)", ctxt))) {
if (!(mdev->dev_config.type = virXPathString("string(./type[1]/@id)", ctxt))) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("missing type id attribute for '%1$s'"), def->name);
return -1;
@ -2577,11 +2577,11 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps)
g_free(data->sg.path);
break;
case VIR_NODE_DEV_CAP_MDEV:
g_free(data->mdev.type);
g_free(data->mdev.dev_config.type);
g_free(data->mdev.uuid);
for (i = 0; i < data->mdev.nattributes; i++)
virMediatedDeviceAttrFree(data->mdev.attributes[i]);
g_free(data->mdev.attributes);
for (i = 0; i < data->mdev.dev_config.nattributes; i++)
virMediatedDeviceAttrFree(data->mdev.dev_config.attributes[i]);
g_free(data->mdev.dev_config.attributes);
g_free(data->mdev.parent_addr);
break;
case VIR_NODE_DEV_CAP_CSS_DEV:

View File

@ -151,11 +151,9 @@ struct _virNodeDevCapSystem {
typedef struct _virNodeDevCapMdev virNodeDevCapMdev;
struct _virNodeDevCapMdev {
char *type;
unsigned int iommuGroupNumber;
char *uuid;
virMediatedDeviceAttr **attributes;
size_t nattributes;
virMediatedDeviceConfig dev_config;
char *parent_addr;
bool autostart;
};

View File

@ -609,17 +609,17 @@ nodeDeviceDefToMdevctlConfig(virNodeDeviceDef *def, char **buf)
g_autoptr(virJSONValue) json = virJSONValueNewObject();
const char *startval = mdev->autostart ? "auto" : "manual";
if (virJSONValueObjectAppendString(json, "mdev_type", mdev->type) < 0)
if (virJSONValueObjectAppendString(json, "mdev_type", mdev->dev_config.type) < 0)
return -1;
if (virJSONValueObjectAppendString(json, "start", startval) < 0)
return -1;
if (mdev->attributes) {
if (mdev->dev_config.attributes) {
g_autoptr(virJSONValue) attributes = virJSONValueNewArray();
for (i = 0; i < mdev->nattributes; i++) {
virMediatedDeviceAttr *attr = mdev->attributes[i];
for (i = 0; i < mdev->dev_config.nattributes; i++) {
virMediatedDeviceAttr *attr = mdev->dev_config.attributes[i];
g_autoptr(virJSONValue) jsonattr = virJSONValueNewObject();
if (virJSONValueObjectAppendString(jsonattr, attr->name, attr->value) < 0)
@ -1129,7 +1129,7 @@ nodeDeviceParseMdevctlChildDevice(const char *parent,
mdev = &child->caps->data.mdev;
mdev->uuid = g_strdup(uuid);
mdev->parent_addr = g_strdup(parent);
mdev->type =
mdev->dev_config.type =
g_strdup(virJSONValueObjectGetString(props, "mdev_type"));
start = virJSONValueObjectGetString(props, "start");
mdev->autostart = STREQ_NULLABLE(start, "auto");
@ -1140,8 +1140,8 @@ nodeDeviceParseMdevctlChildDevice(const char *parent,
size_t i;
int nattrs = virJSONValueArraySize(attrs);
mdev->attributes = g_new0(virMediatedDeviceAttr*, nattrs);
mdev->nattributes = nattrs;
mdev->dev_config.attributes = g_new0(virMediatedDeviceAttr*, nattrs);
mdev->dev_config.nattributes = nattrs;
for (i = 0; i < nattrs; i++) {
virJSONValue *attr = virJSONValueArrayGet(attrs, i);
@ -1156,7 +1156,7 @@ nodeDeviceParseMdevctlChildDevice(const char *parent,
attribute->name = g_strdup(virJSONValueObjectGetKey(attr, 0));
value = virJSONValueObjectGetValue(attr, 0);
attribute->value = g_strdup(virJSONValueGetString(value));
mdev->attributes[i] = attribute;
mdev->dev_config.attributes[i] = attribute;
}
}
mdevGenerateDeviceName(child);
@ -1762,39 +1762,39 @@ nodeDeviceUpdateMediatedDevices(void)
/* returns true if any attributes were copied, else returns false */
static bool
virMediatedDeviceAttrsCopy(virNodeDevCapMdev *dst,
virNodeDevCapMdev *src)
virMediatedDeviceAttrsCopy(virMediatedDeviceConfig *dst_config,
virMediatedDeviceConfig *src_config)
{
bool ret = false;
size_t i;
if (src->nattributes != dst->nattributes) {
if (src_config->nattributes != dst_config->nattributes) {
ret = true;
for (i = 0; i < dst->nattributes; i++)
virMediatedDeviceAttrFree(dst->attributes[i]);
g_free(dst->attributes);
for (i = 0; i < dst_config->nattributes; i++)
virMediatedDeviceAttrFree(dst_config->attributes[i]);
g_free(dst_config->attributes);
dst->nattributes = src->nattributes;
dst->attributes = g_new0(virMediatedDeviceAttr*,
src->nattributes);
for (i = 0; i < dst->nattributes; i++)
dst->attributes[i] = virMediatedDeviceAttrNew();
dst_config->nattributes = src_config->nattributes;
dst_config->attributes = g_new0(virMediatedDeviceAttr*,
src_config->nattributes);
for (i = 0; i < dst_config->nattributes; i++)
dst_config->attributes[i] = virMediatedDeviceAttrNew();
}
for (i = 0; i < src->nattributes; i++) {
if (STRNEQ_NULLABLE(src->attributes[i]->name,
dst->attributes[i]->name)) {
for (i = 0; i < src_config->nattributes; i++) {
if (STRNEQ_NULLABLE(src_config->attributes[i]->name,
dst_config->attributes[i]->name)) {
ret = true;
g_free(dst->attributes[i]->name);
dst->attributes[i]->name =
g_strdup(src->attributes[i]->name);
g_free(dst_config->attributes[i]->name);
dst_config->attributes[i]->name =
g_strdup(src_config->attributes[i]->name);
}
if (STRNEQ_NULLABLE(src->attributes[i]->value,
dst->attributes[i]->value)) {
if (STRNEQ_NULLABLE(src_config->attributes[i]->value,
dst_config->attributes[i]->value)) {
ret = true;
g_free(dst->attributes[i]->value);
dst->attributes[i]->value =
g_strdup(src->attributes[i]->value);
g_free(dst_config->attributes[i]->value);
dst_config->attributes[i]->value =
g_strdup(src_config->attributes[i]->value);
}
}
@ -1813,10 +1813,10 @@ nodeDeviceDefCopyFromMdevctl(virNodeDeviceDef *dst,
virNodeDevCapMdev *srcmdev = &src->caps->data.mdev;
virNodeDevCapMdev *dstmdev = &dst->caps->data.mdev;
if (STRNEQ_NULLABLE(dstmdev->type, srcmdev->type)) {
if (STRNEQ_NULLABLE(dstmdev->dev_config.type, srcmdev->dev_config.type)) {
ret = true;
g_free(dstmdev->type);
dstmdev->type = g_strdup(srcmdev->type);
g_free(dstmdev->dev_config.type);
dstmdev->dev_config.type = g_strdup(srcmdev->dev_config.type);
}
if (STRNEQ_NULLABLE(dstmdev->uuid, srcmdev->uuid)) {
@ -1825,7 +1825,7 @@ nodeDeviceDefCopyFromMdevctl(virNodeDeviceDef *dst,
dstmdev->uuid = g_strdup(srcmdev->uuid);
}
if (virMediatedDeviceAttrsCopy(dstmdev, srcmdev))
if (virMediatedDeviceAttrsCopy(&dstmdev->dev_config, &srcmdev->dev_config))
ret = true;
if (dstmdev->autostart != srcmdev->autostart) {

View File

@ -1069,7 +1069,7 @@ udevProcessMediatedDevice(struct udev_device *dev,
return -1;
}
data->type = g_path_get_basename(canonicalpath);
data->dev_config.type = g_path_get_basename(canonicalpath);
data->uuid = g_strdup(udev_device_get_sysname(dev));
if ((iommugrp = virMediatedDeviceGetIOMMUGroupNum(data->uuid)) < 0)

View File

@ -47,6 +47,12 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virMediatedDeviceAttr, virMediatedDeviceAttrFree);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virMediatedDeviceList, virObjectUnref);
typedef struct _virMediatedDeviceConfig virMediatedDeviceConfig;
struct _virMediatedDeviceConfig {
char *type;
virMediatedDeviceAttr **attributes;
size_t nattributes;
};
typedef struct _virMediatedDeviceType virMediatedDeviceType;
struct _virMediatedDeviceType {