[libvirt] PATCH: Include OS driver name in device information

Daniel P. Berrange berrange at redhat.com
Fri May 29 13:39:09 UTC 2009


This patch extends the node device XML from

$ virsh nodedev-dumpxml pci_8086_27d6
<device>
  <name>pci_8086_27d6</name>
  <parent>computer</parent>
  <capability type='pci'>
    <domain>0</domain>
    <bus>0</bus>
    <slot>28</slot>
    <function>3</function>
    <product id='0x27d6'>82801G (ICH7 Family) PCI Express Port 4</product>
    <vendor id='0x8086'>Intel Corporation</vendor>
  </capability>
</device>

To, also include the operating system driver name. 

$ virsh nodedev-dumpxml pci_8086_27d6
<device>
  <name>pci_8086_27d6</name>
  <parent>computer</parent>
  <driver>
    <name>pcieport-driver</name>
  </driver>
  <capability type='pci'>
    <domain>0</domain>
    <bus>0</bus>
    <slot>28</slot>
    <function>3</function>
    <product id='0x27d6'>82801G (ICH7 Family) PCI Express Port 4</product>
    <vendor id='0x8086'>Intel Corporation</vendor>
  </capability>
</device>


We're not defining any particular semantics for the driver name, it is
just a opaque string following rules of the OS in question.

Daniel

diff -r ec78a5d6c00c src/node_device.c
--- a/src/node_device.c	Thu May 28 14:42:24 2009 +0100
+++ b/src/node_device.c	Thu May 28 16:00:12 2009 +0100
@@ -46,6 +46,60 @@ static int dev_has_cap(const virNodeDevi
     return 0;
 }
 
+#ifdef __linux__
+static int update_driver_name(virConnectPtr conn,
+                              virNodeDeviceObjPtr dev)
+{
+    char *driver_link = NULL;
+    char devpath[PATH_MAX];
+    char *p;
+    int ret = -1;
+    int n;
+
+    VIR_FREE(dev->def->driver);
+
+    if (virAsprintf(&driver_link, "%s/driver", dev->devicePath) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    /* Some devices don't have an explicit driver, so just return
+       without a name */
+    if (access(driver_link, R_OK) < 0) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    if ((n = readlink(driver_link, devpath, sizeof devpath)) < 0) {
+        virReportSystemError(conn, errno,
+                             _("cannot resolve driver link %s"), driver_link);
+        goto cleanup;
+    }
+    devpath[n] = '\0';
+
+    p = strrchr(devpath, '/');
+    if (p) {
+        dev->def->driver = strdup(p+1);
+        if (!dev->def->driver) {
+            virReportOOMError(conn);
+            goto cleanup;
+        }
+    }
+    ret = 0;
+
+cleanup:
+    VIR_FREE(driver_link);
+    return ret;
+}
+#else
+/* XXX: Implement me for non-linux */
+static int update_driver_name(virConnectPtr conn ATTRIBUTE_UNUSED,
+                              virNodeDeviceObjPtr dev ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+#endif
+
 
 void nodeDeviceLock(virDeviceMonitorStatePtr driver)
 {
@@ -150,6 +204,7 @@ static char *nodeDeviceDumpXML(virNodeDe
         goto cleanup;
     }
 
+    update_driver_name(dev->conn, obj);
     ret = virNodeDeviceDefFormat(dev->conn, obj->def);
 
 cleanup:
diff -r ec78a5d6c00c src/node_device_conf.c
--- a/src/node_device_conf.c	Thu May 28 14:42:24 2009 +0100
+++ b/src/node_device_conf.c	Thu May 28 16:00:12 2009 +0100
@@ -78,6 +78,7 @@ void virNodeDeviceDefFree(virNodeDeviceD
 
     VIR_FREE(def->name);
     VIR_FREE(def->parent);
+    VIR_FREE(def->driver);
 
     caps = def->caps;
     while (caps) {
@@ -94,6 +95,7 @@ void virNodeDeviceObjFree(virNodeDeviceO
     if (!dev)
         return;
 
+    VIR_FREE(dev->devicePath);
     virNodeDeviceDefFree(dev->def);
     if (dev->privateFree)
         (*dev->privateFree)(dev->privateData);
@@ -191,6 +193,11 @@ char *virNodeDeviceDefFormat(virConnectP
 
     if (def->parent)
         virBufferEscapeString(&buf, "  <parent>%s</parent>\n", def->parent);
+    if (def->driver) {
+        virBufferAddLit(&buf, "  <driver>\n");
+        virBufferEscapeString(&buf, "    <name>%s</name>\n", def->driver);
+        virBufferAddLit(&buf, "  </driver>\n");
+    }
 
     for (caps = def->caps; caps; caps = caps->next) {
         char uuidstr[VIR_UUID_STRING_BUFLEN];
diff -r ec78a5d6c00c src/node_device_conf.h
--- a/src/node_device_conf.h	Thu May 28 14:42:24 2009 +0100
+++ b/src/node_device_conf.h	Thu May 28 16:00:12 2009 +0100
@@ -136,6 +136,7 @@ typedef virNodeDeviceDef *virNodeDeviceD
 struct _virNodeDeviceDef {
     char *name;                         /* device name (unique on node) */
     char *parent;			/* optional parent device name */
+    char *driver;                       /* optional driver name */
     virNodeDevCapsDefPtr caps;		/* optional device capabilities */
 };
 
@@ -145,6 +146,7 @@ typedef virNodeDeviceObj *virNodeDeviceO
 struct _virNodeDeviceObj {
     virMutex lock;
 
+    char *devicePath;                   /* OS specific path to device metadat, eg sysfs */
     virNodeDeviceDefPtr def;		/* device definition */
     void *privateData;			/* driver-specific private data */
     void (*privateFree)(void *data);	/* destructor for private data */
diff -r ec78a5d6c00c src/node_device_hal.c
--- a/src/node_device_hal.c	Thu May 28 14:42:24 2009 +0100
+++ b/src/node_device_hal.c	Thu May 28 16:00:12 2009 +0100
@@ -413,6 +413,7 @@ static void dev_create(const char *udi)
     const char *name = hal_name(udi);
     int rv;
     char *privData = strdup(udi);
+    char *devicePath = NULL;
 
     if (!privData)
         return;
@@ -439,15 +440,22 @@ static void dev_create(const char *udi)
     if (def->caps == NULL)
         goto cleanup;
 
+    /* Some devices don't have a path in sysfs, so ignore failure */
+    get_str_prop(ctx, udi, "linux.sysfs_path", &devicePath);
+
     dev = virNodeDeviceAssignDef(NULL,
                                  &driverState->devs,
                                  def);
 
-    if (!dev)
+    if (!dev) {
+        VIR_FREE(devicePath);
         goto failure;
+    }
 
     dev->privateData = privData;
     dev->privateFree = free_udi;
+    dev->devicePath = devicePath;
+
     virNodeDeviceObjUnlock(dev);
 
     nodeDeviceUnlock(driverState);

-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list