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 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list