]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Include OS driver name (if any) in device XML for nodedev driver
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 12 Jun 2009 13:12:55 +0000 (13:12 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 12 Jun 2009 13:12:55 +0000 (13:12 +0000)
ChangeLog
src/node_device.c
src/node_device_conf.c
src/node_device_conf.h
src/node_device_hal.c

index 4ef02d263f88a6a18b16dba2e032c5b9cd7dfb45..842bbfefb4c86c8d42e654f2d7dadfcae4a09344 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,16 @@
 Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
 
-       Improve error reporting for virConnecOpen URIs
+       Include OS driver name (if any) in device XML
+       * src/node_device.c: Refresh OS driver when generating XML,
+       and include impl for Linux sysfs
+       * src/noe_device_conf.c, src/node_device_conf.h: Add field
+       for OS driver name to config
+       * src/node_device_hal.c: Record sysfs path to be used for
+       driver name fetching later.
+
+Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+
+       Improve error reporting for virConnectOpen URIs
        * src/lxc_driver.c, src/openvz_driver.c, src/qemu_driver.c,
        src/uml_driver.c, src/xen_unified.c: Always return ACCEPT
        or ERROR for URIs without hostname set, but with the driver's
index cd9fb6e65fe7238ff86c8d5c5203b1ab0637afaf..de51bc85f45c49ecc231d9efe2e04fc0b72bf9dc 100644 (file)
@@ -48,6 +48,60 @@ static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap)
     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)
 {
@@ -197,6 +251,7 @@ static char *nodeDeviceDumpXML(virNodeDevicePtr dev,
         goto cleanup;
     }
 
+    update_driver_name(dev->conn, obj);
     ret = virNodeDeviceDefFormat(dev->conn, obj->def);
 
 cleanup:
index be198438e031f0c6bad6291858620028e24a7dc1..1fbf9dc891706c56723a0b2f9680cc67bdafd032 100644 (file)
@@ -106,6 +106,7 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
 
     VIR_FREE(def->name);
     VIR_FREE(def->parent);
+    VIR_FREE(def->driver);
 
     caps = def->caps;
     while (caps) {
@@ -122,6 +123,7 @@ void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
     if (!dev)
         return;
 
+    VIR_FREE(dev->devicePath);
     virNodeDeviceDefFree(dev->def);
     if (dev->privateFree)
         (*dev->privateFree)(dev->privateData);
@@ -219,6 +221,11 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
 
     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];
index 522dfde4840d9888578dc48a1542437b98a5628f..c33cc738c2f418b95f6684007860603642e0acb8 100644 (file)
@@ -156,6 +156,7 @@ typedef virNodeDeviceDef *virNodeDeviceDefPtr;
 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 */
 };
 
@@ -165,6 +166,7 @@ typedef virNodeDeviceObj *virNodeDeviceObjPtr;
 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 */
index b2af7a05200a6774ac786de04e9728e78c1b81e4..ea519466c5d6376c68380cf51193b1f345817ba1 100644 (file)
@@ -429,6 +429,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;
@@ -455,15 +456,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);