]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: change the modalias string for usb devices to include the device name
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 16 Jul 2020 14:24:14 +0000 (16:24 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 16 Jul 2020 17:00:26 +0000 (19:00 +0200)
When the kernel does not provide a modalias, we generate our own for usb devices.
For some reason, we generated the expected usb:vXXXXpYYYY string, suffixed by "*".
It was added that way already in 796b06c21b62d13c9021e2fbd9c58a5c6edb2764, but I
think that was a mistake, and Kay was thinking about the match pattern instead
of the matched string.

For example, for a qemu device:
old: "usb:v0627p0001*"
new: "usb:v0627p0001:QEMU USB Tablet"

On the match side, all hwdb files in the wild seem to be using match patterns
with "*" at the end. So we can add more stuff to our generated modalias with
impunity.

This will allow more obvious and more certain matches on USB devices. In
principle the vendor+product id should be unique, but it's only 8 digits, and
there's a high chance of people getting this wrong. And matching the wrong
device would be quite problematic. By including the name in the match string we
make a mismatch much less likely.

src/udev/udev-builtin-hwdb.c

index 8e86d2f0d1c01fbd89e3a21b97cebb4c0834de54..59ae6c7ad44ee3449235f6cecc08eaa9385e9d9d 100644 (file)
@@ -47,7 +47,7 @@ int udev_builtin_hwdb_lookup(sd_device *dev,
 }
 
 static const char *modalias_usb(sd_device *dev, char *s, size_t size) {
-        const char *v, *p;
+        const char *v, *p, *n = NULL;
         uint16_t vn, pn;
 
         if (sd_device_get_sysattr_value(dev, "idVendor", &v) < 0)
@@ -58,15 +58,16 @@ static const char *modalias_usb(sd_device *dev, char *s, size_t size) {
                 return NULL;
         if (safe_atoux16(p, &pn) < 0)
                 return NULL;
-        snprintf(s, size, "usb:v%04Xp%04X*", vn, pn);
+        (void) sd_device_get_sysattr_value(dev, "product", &n);
+
+        snprintf(s, size, "usb:v%04Xp%04X:%s", vn, pn, strempty(n));
         return s;
 }
 
 static int udev_builtin_hwdb_search(sd_device *dev, sd_device *srcdev,
                                     const char *subsystem, const char *prefix,
                                     const char *filter, bool test) {
-        sd_device *d;
-        char s[16];
+        char s[LINE_MAX];
         bool last = false;
         int r = 0;
 
@@ -75,7 +76,7 @@ static int udev_builtin_hwdb_search(sd_device *dev, sd_device *srcdev,
         if (!srcdev)
                 srcdev = dev;
 
-        for (d = srcdev; d; ) {
+        for (sd_device *d = srcdev; d; ) {
                 const char *dsubsys, *devtype, *modalias = NULL;
 
                 if (sd_device_get_subsystem(d, &dsubsys) < 0)
@@ -101,6 +102,8 @@ static int udev_builtin_hwdb_search(sd_device *dev, sd_device *srcdev,
                 if (!modalias)
                         goto next;
 
+                log_device_debug(dev, "hwdb modalias key: \"%s\"", modalias);
+
                 r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test);
                 if (r > 0)
                         break;