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 :|