[libvirt] [RFC PATCH 06/11] nodedev: Introduce the mdev capability to the nodedev driver structure

Erik Skultety eskultet at redhat.com
Wed Mar 29 12:51:16 UTC 2017


Besides updating the capability enum, this patch introduces
'virNodeDevCapMdev' structure which will store everything libvirt can
gather from sysfs about a mediated device. Since we need to report the
info for both the mediated child device it's parent mdev capabilities
(merely the mdev types' attributes), this structure serves in both of
these cases with the difference being that the amount of data it holds
depends on the specific scenario (child vs parent).

Signed-off-by: Erik Skultety <eskultet at redhat.com>
---
 include/libvirt/libvirt-nodedev.h    |  1 +
 src/conf/node_device_conf.c          | 19 ++++++++++++++++++-
 src/conf/node_device_conf.h          | 19 ++++++++++++++++++-
 src/conf/virnodedeviceobj.c          |  3 ++-
 src/libvirt-nodedev.c                |  1 +
 src/libvirt_private.syms             |  1 +
 src/node_device/node_device_driver.c |  1 +
 src/node_device/node_device_udev.c   |  8 +++++++-
 tools/virsh-nodedev.c                |  2 ++
 9 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h
index 85003903d7..59edf4db02 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -79,6 +79,7 @@ typedef enum {
     VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS        = 1 << 10, /* Capable of vport */
     VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC  = 1 << 11, /* Capable of scsi_generic */
     VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM           = 1 << 12, /* DRM device */
+    VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV          = 1 << 13, /* Mediated device */
 } virConnectListAllNodeDeviceFlags;
 
 int                     virConnectListAllNodeDevices (virConnectPtr conn,
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 72fb9a5611..03d7993ab1 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -60,7 +60,8 @@ VIR_ENUM_IMPL(virNodeDevCap, VIR_NODE_DEV_CAP_LAST,
               "fc_host",
               "vports",
               "scsi_generic",
-              "drm")
+              "drm",
+              "mdev")
 
 VIR_ENUM_IMPL(virNodeDevNetCap, VIR_NODE_DEV_CAP_NET_LAST,
               "80203",
@@ -542,6 +543,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
             break;
         case VIR_NODE_DEV_CAP_FC_HOST:
         case VIR_NODE_DEV_CAP_VPORTS:
+        case VIR_NODE_DEV_CAP_MDEV:
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }
@@ -1591,6 +1593,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
     case VIR_NODE_DEV_CAP_FC_HOST:
     case VIR_NODE_DEV_CAP_VPORTS:
     case VIR_NODE_DEV_CAP_SCSI_GENERIC:
+    case VIR_NODE_DEV_CAP_MDEV:
     case VIR_NODE_DEV_CAP_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unknown capability type '%d' for '%s'"),
@@ -1905,6 +1908,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
     case VIR_NODE_DEV_CAP_SCSI_GENERIC:
         VIR_FREE(data->sg.path);
         break;
+    case VIR_NODE_DEV_CAP_MDEV:
     case VIR_NODE_DEV_CAP_DRM:
     case VIR_NODE_DEV_CAP_FC_HOST:
     case VIR_NODE_DEV_CAP_VPORTS:
@@ -1917,6 +1921,19 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
 }
 
 
+void virNodeDevCapMdevFree(virNodeDevCapMdevPtr mdev)
+{
+    if (!mdev)
+        return;
+
+    VIR_FREE(mdev->type);
+    VIR_FREE(mdev->name);
+    VIR_FREE(mdev->description);
+    VIR_FREE(mdev->device_api);
+    VIR_FREE(mdev);
+}
+
+
 /* virNodeDeviceGetParentName
  * @conn: Connection pointer
  * @nodedev_name: Node device to lookup
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index a5d5cdd2a5..b7db35dd50 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -64,6 +64,7 @@ typedef enum {
     VIR_NODE_DEV_CAP_VPORTS,		/* HBA which is capable of vports */
     VIR_NODE_DEV_CAP_SCSI_GENERIC,      /* SCSI generic device */
     VIR_NODE_DEV_CAP_DRM,               /* DRM device */
+    VIR_NODE_DEV_CAP_MDEV,              /* Mediated device */
 
     VIR_NODE_DEV_CAP_LAST
 } virNodeDevCapType;
@@ -131,6 +132,17 @@ struct _virNodeDevCapSystem {
     virNodeDevCapSystemFirmware firmware;
 };
 
+typedef struct _virNodeDevCapMdev virNodeDevCapMdev;
+typedef virNodeDevCapMdev *virNodeDevCapMdevPtr;
+struct _virNodeDevCapMdev {
+    char *type;
+    char *name;
+    char *description;
+    char *device_api;
+    unsigned int available_instances;
+    unsigned int iommuGroupNumber;
+};
+
 typedef struct _virNodeDevCapPCIDev virNodeDevCapPCIDev;
 typedef virNodeDevCapPCIDev *virNodeDevCapPCIDevPtr;
 struct _virNodeDevCapPCIDev {
@@ -262,6 +274,7 @@ struct _virNodeDevCapData {
         virNodeDevCapStorage storage;
         virNodeDevCapSCSIGeneric sg;
         virNodeDevCapDRM drm;
+        virNodeDevCapMdev mdev;
     };
 };
 
@@ -338,6 +351,9 @@ virNodeDeviceDefFree(virNodeDeviceDefPtr def);
 void
 virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
 
+void
+virNodeDevCapMdevFree(virNodeDevCapMdevPtr mdev);
+
 # define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP \
                 (VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM        | \
                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV       | \
@@ -351,7 +367,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST       | \
                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS        | \
                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC  | \
-                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM)
+                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM           | \
+                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV)
 
 char *
 virNodeDeviceGetParentName(virConnectPtr conn,
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
index 3fe3ae5fe8..1dfb7380c7 100644
--- a/src/conf/virnodedeviceobj.c
+++ b/src/conf/virnodedeviceobj.c
@@ -494,7 +494,8 @@ virNodeDeviceMatch(virNodeDeviceObjPtr devobj,
               MATCH(FC_HOST)       ||
               MATCH(VPORTS)        ||
               MATCH(SCSI_GENERIC)  ||
-              MATCH(DRM)))
+              MATCH(DRM)           ||
+              MATCH(MDEV)))
             return false;
     }
 
diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c
index 83376b0d96..f9d8edf7e5 100644
--- a/src/libvirt-nodedev.c
+++ b/src/libvirt-nodedev.c
@@ -98,6 +98,7 @@ virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags)
  *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS
  *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC
  *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM
+ *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV
  *
  * Returns the number of node devices found or -1 and sets @devices to NULL in
  * case of error.  On success, the array stored into @devices is guaranteed to
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b551cb86a6..2a3e8cb705 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -690,6 +690,7 @@ virNetDevIPRouteParseXML;
 
 
 # conf/node_device_conf.h
+virNodeDevCapMdevFree;
 virNodeDevCapsDefFree;
 virNodeDevCapTypeFromString;
 virNodeDevCapTypeToString;
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index 9b1c5bb5e9..bcf204c7b7 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -83,6 +83,7 @@ update_caps(virNodeDeviceObjPtr dev)
         case VIR_NODE_DEV_CAP_FC_HOST:
         case VIR_NODE_DEV_CAP_VPORTS:
         case VIR_NODE_DEV_CAP_SCSI_GENERIC:
+        case VIR_NODE_DEV_CAP_MDEV:
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 36ed92f712..dbbd8e5d06 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -43,6 +43,7 @@
 #include "virpci.h"
 #include "virstring.h"
 #include "virnetdev.h"
+#include "virmdev.h"
 
 #define VIR_FROM_THIS VIR_FROM_NODEDEV
 
@@ -1051,12 +1052,16 @@ udevGetDeviceType(struct udev_device *device,
         if (udevHasDeviceProperty(device, "INTERFACE"))
             *type = VIR_NODE_DEV_CAP_NET;
 
-        /* SCSI generic device doesn't set DEVTYPE property */
+        /* Neither SCSI generic devices nor mediated devices set DEVTYPE
+         * property, but they so we need to rely on the SUBSYSTEM property */
         if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) < 0)
             return -1;
 
         if (STREQ_NULLABLE(subsystem, "scsi_generic"))
             *type = VIR_NODE_DEV_CAP_SCSI_GENERIC;
+        else if (STREQ_NULLABLE(subsystem, "mdev"))
+            *type = VIR_NODE_DEV_CAP_MDEV;
+
         VIR_FREE(subsystem);
     }
 
@@ -1096,6 +1101,7 @@ udevGetDeviceDetails(struct udev_device *device,
         return udevProcessSCSIGeneric(device, def);
     case VIR_NODE_DEV_CAP_DRM:
         return udevProcessDRMDevice(device, def);
+    case VIR_NODE_DEV_CAP_MDEV:
     case VIR_NODE_DEV_CAP_SYSTEM:
     case VIR_NODE_DEV_CAP_FC_HOST:
     case VIR_NODE_DEV_CAP_VPORTS:
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
index c691440219..19dcfafa6e 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -454,6 +454,8 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
         case VIR_NODE_DEV_CAP_DRM:
             flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM;
             break;
+        case VIR_NODE_DEV_CAP_MDEV:
+            flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV;
         case VIR_NODE_DEV_CAP_LAST:
             break;
         }
-- 
2.12.2




More information about the libvir-list mailing list