chiark / gitweb /
consistent key naming to match only the event device or include all parent devices
authorKay Sievers <kay.sievers@suse.de>
Sat, 19 Aug 2006 14:06:25 +0000 (16:06 +0200)
committerKay Sievers <kay.sievers@suse.de>
Sat, 19 Aug 2006 14:06:25 +0000 (16:06 +0200)
This scheme is more consistent and makes it obvious if a match happens
against the event device only, or the full chain of parent devices.

The old key names are now:
  BUS -> SUBSYSTEMS
  ID -> KERNELS
  SYSFS -> ATTRS
  DRIVER -> DRIVERS

Match keys for the event device:
  KERNEL
  SUBSYSTEM
  ATTR
  DRIVER (in a future release, for now the same as DRIVERS)

Match keys for all devices along the parent device chain:
  KERNELS
  SUBSYSTEMS
  ATTRS
  DRIVERS

ID, BUS, SYSFS are no longer mentioned in the man page but still work.
DRIVER must be converted to DRIVERS to match the new scheme. For now,
an error is logged, if DRIVER is used. In a future release, the DRIVER
key behaviour will change.

15 files changed:
extras/scsi_id/scsi_id.c
extras/scsi_id/scsi_serial.c
extras/usb_id/usb_id.c
test/udev-test.pl
udev.7
udev.h
udev.xml
udev_db.c
udev_device.c
udev_node.c
udev_rules.c
udev_rules.h
udev_rules_parse.c
udev_sysfs.c
udevinfo.c

index 446df70949c010f297c3a660f258d25278f764b6..c64e203aff06a5dbfebdd81a582bc541b6758002 100644 (file)
@@ -679,7 +679,7 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
                        if (reformat_serial)
                                format_serial(serial);
                        if (display_bus_id)
                        if (reformat_serial)
                                format_serial(serial);
                        if (display_bus_id)
-                               printf("%s: ", dev_scsi->kernel_name);
+                               printf("%s: ", dev_scsi->kernel);
                        printf("%s\n", serial);
                }
                dbg("%s\n", serial);
                        printf("%s\n", serial);
                }
                dbg("%s\n", serial);
index 0ecfebe1b6bca827e835af48a3a17aacc2f1240f..a0a3ae97d8170f1681aeb9c541a337a3a26bf9ec 100644 (file)
@@ -179,7 +179,7 @@ static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
 
        sb_len = io->sb_len_wr;
        if (sb_len < 1) {
 
        sb_len = io->sb_len_wr;
        if (sb_len < 1) {
-               info("%s: sense buffer empty", dev_scsi->kernel_name);
+               info("%s: sense buffer empty", dev_scsi->kernel);
                return -1;
        }
 
                return -1;
        }
 
@@ -194,7 +194,7 @@ static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
                s = sense_buffer[7] + 8;
                if (sb_len < s) {
                        info("%s: sense buffer too small %d bytes, %d bytes too short",
                s = sense_buffer[7] + 8;
                if (sb_len < s) {
                        info("%s: sense buffer too small %d bytes, %d bytes too short",
-                           dev_scsi->kernel_name, sb_len, s - sb_len);
+                           dev_scsi->kernel, sb_len, s - sb_len);
                        return -1;
                }
                if ((code == 0x0) || (code == 0x1)) {
                        return -1;
                }
                if ((code == 0x0) || (code == 0x1)) {
@@ -205,7 +205,7 @@ static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
                                 * Possible?
                                 */
                                info("%s: sense result too" " small %d bytes",
                                 * Possible?
                                 */
                                info("%s: sense result too" " small %d bytes",
-                                   dev_scsi->kernel_name, s);
+                                   dev_scsi->kernel, s);
                                return -1;
                        }
                        asc = sense_buffer[12];
                                return -1;
                        }
                        asc = sense_buffer[12];
@@ -217,25 +217,25 @@ static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
                        ascq = sense_buffer[3];
                } else {
                        info("%s: invalid sense code 0x%x",
                        ascq = sense_buffer[3];
                } else {
                        info("%s: invalid sense code 0x%x",
-                           dev_scsi->kernel_name, code);
+                           dev_scsi->kernel, code);
                        return -1;
                }
                info("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x",
                        return -1;
                }
                info("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x",
-                   dev_scsi->kernel_name, sense_key, asc, ascq);
+                   dev_scsi->kernel, sense_key, asc, ascq);
        } else {
                if (sb_len < 4) {
                        info("%s: sense buffer too small %d bytes, %d bytes too short",
        } else {
                if (sb_len < 4) {
                        info("%s: sense buffer too small %d bytes, %d bytes too short",
-                           dev_scsi->kernel_name, sb_len, 4 - sb_len);
+                           dev_scsi->kernel, sb_len, 4 - sb_len);
                        return -1;
                }
 
                if (sense_buffer[0] < 15)
                        return -1;
                }
 
                if (sense_buffer[0] < 15)
-                       info("%s: old sense key: 0x%x", dev_scsi->kernel_name, sense_buffer[0] & 0x0f);
+                       info("%s: old sense key: 0x%x", dev_scsi->kernel, sense_buffer[0] & 0x0f);
                else
                        info("%s: sense = %2x %2x",
                else
                        info("%s: sense = %2x %2x",
-                           dev_scsi->kernel_name, sense_buffer[0], sense_buffer[2]);
+                           dev_scsi->kernel, sense_buffer[0], sense_buffer[2]);
                info("%s: non-extended sense class %d code 0x%0x",
                info("%s: non-extended sense class %d code 0x%0x",
-                   dev_scsi->kernel_name, sense_class, code);
+                   dev_scsi->kernel, sense_class, code);
 
        }
 
 
        }
 
@@ -247,8 +247,8 @@ static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
                out_buffer[j++] = ' ';
        }
        out_buffer[j] = '\0';
                out_buffer[j++] = ' ';
        }
        out_buffer[j] = '\0';
-       info("%s: sense dump:", dev_scsi->kernel_name);
-       info("%s: %s", dev_scsi->kernel_name, out_buffer);
+       info("%s: sense dump:", dev_scsi->kernel);
+       info("%s: %s", dev_scsi->kernel, out_buffer);
 
 #endif
        return -1;
 
 #endif
        return -1;
@@ -266,7 +266,7 @@ static int scsi_dump(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
        }
 
        info("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
        }
 
        info("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
-           dev_scsi->kernel_name, io->driver_status, io->host_status, io->msg_status, io->status);
+           dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status);
        if (io->status == SCSI_CHECK_CONDITION)
                return scsi_dump_sense(dev_scsi, io);
        else
        if (io->status == SCSI_CHECK_CONDITION)
                return scsi_dump_sense(dev_scsi, io);
        else
@@ -290,7 +290,7 @@ static int scsi_inquiry(struct sysfs_device *dev_scsi, int fd,
        }
 
 resend:
        }
 
 resend:
-       dbg("%s evpd %d, page 0x%x\n", dev_scsi->kernel_name, evpd, page);
+       dbg("%s evpd %d, page 0x%x\n", dev_scsi->kernel, evpd, page);
 
        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
        io_hdr.interface_id = 'S';
 
        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
        io_hdr.interface_id = 'S';
@@ -304,7 +304,7 @@ resend:
        io_hdr.timeout = DEF_TIMEOUT;
 
        if (ioctl(fd, SG_IO, &io_hdr) < 0) {
        io_hdr.timeout = DEF_TIMEOUT;
 
        if (ioctl(fd, SG_IO, &io_hdr) < 0) {
-               info("%s: ioctl failed: %s", dev_scsi->kernel_name, strerror(errno));
+               info("%s: ioctl failed: %s", dev_scsi->kernel, strerror(errno));
                retval = -1;
                goto error;
        }
                retval = -1;
                goto error;
        }
@@ -328,7 +328,7 @@ resend:
                retval = buflen;
        } else if (retval > 0) {
                if (--retry > 0) {
                retval = buflen;
        } else if (retval > 0) {
                if (--retry > 0) {
-                       dbg("%s: Retrying ...\n", dev_scsi->kernel_name);
+                       dbg("%s: Retrying ...\n", dev_scsi->kernel);
                        goto resend;
                }
                retval = -1;
                        goto resend;
                }
                retval = -1;
@@ -337,7 +337,7 @@ resend:
 error:
        if (retval < 0)
                info("%s: Unable to get INQUIRY vpd %d page 0x%x.",
 error:
        if (retval < 0)
                info("%s: Unable to get INQUIRY vpd %d page 0x%x.",
-                   dev_scsi->kernel_name, evpd, page);
+                   dev_scsi->kernel, evpd, page);
 
        return retval;
 }
 
        return retval;
 }
@@ -355,11 +355,11 @@ static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd,
                return 1;
 
        if (buffer[1] != 0) {
                return 1;
 
        if (buffer[1] != 0) {
-               info("%s: page 0 not available.", dev_scsi->kernel_name);
+               info("%s: page 0 not available.", dev_scsi->kernel);
                return 1;
        }
        if (buffer[3] > len) {
                return 1;
        }
        if (buffer[3] > len) {
-               info("%s: page 0 buffer too long %d", dev_scsi->kernel_name,  buffer[3]);
+               info("%s: page 0 buffer too long %d", dev_scsi->kernel,  buffer[3]);
                return 1;
        }
 
                return 1;
        }
 
@@ -377,11 +377,11 @@ static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd,
                 */
                vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
                if (!vendor) {
                 */
                vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
                if (!vendor) {
-                       info("%s: cannot get model attribute", dev_scsi->kernel_name);
+                       info("%s: cannot get model attribute", dev_scsi->kernel);
                        return 1;
                }
                if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) {
                        return 1;
                }
                if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) {
-                       info("%s: invalid page0 data", dev_scsi->kernel_name);
+                       info("%s: invalid page0 data", dev_scsi->kernel);
                        return 1;
                }
        }
                        return 1;
                }
        }
@@ -399,7 +399,7 @@ static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial)
 
        attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
        if (!attr) {
 
        attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
        if (!attr) {
-               info("%s: cannot get vendor attribute", dev_scsi->kernel_name);
+               info("%s: cannot get vendor attribute", dev_scsi->kernel);
                return 1;
        }
        strncpy(serial, attr, VENDOR_LENGTH);
                return 1;
        }
        strncpy(serial, attr, VENDOR_LENGTH);
@@ -407,7 +407,7 @@ static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial)
 
        attr = sysfs_attr_get_value(dev_scsi->devpath, "model");
        if (!attr) {
 
        attr = sysfs_attr_get_value(dev_scsi->devpath, "model");
        if (!attr) {
-               info("%s: cannot get model attribute", dev_scsi->kernel_name);
+               info("%s: cannot get model attribute", dev_scsi->kernel);
                return 1;
        }
        strncat(serial, attr, MODEL_LENGTH);
                return 1;
        }
        strncat(serial, attr, MODEL_LENGTH);
@@ -420,7 +420,7 @@ static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial)
         */
        if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
                info("%s: expected length %d, got length %d",
         */
        if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
                info("%s: expected length %d, got length %d",
-                    dev_scsi->kernel_name, (VENDOR_LENGTH + MODEL_LENGTH), ind);
+                    dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind);
                return 1;
        }
        return ind;
                return 1;
        }
        return ind;
@@ -478,7 +478,7 @@ static int check_fill_0x83_id(struct sysfs_device *dev_scsi,
 
        if (max_len < len) {
                info("%s: length %d too short - need %d",
 
        if (max_len < len) {
                info("%s: length %d too short - need %d",
-                   dev_scsi->kernel_name, max_len, len);
+                   dev_scsi->kernel, max_len, len);
                return 1;
        }
 
                return 1;
        }
 
@@ -534,7 +534,7 @@ static int check_fill_0x83_prespc3(struct sysfs_device *dev_scsi,
                serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4];
                serial[j++] = hex_str[ page_83[4+i] & 0x0f];
        }
                serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4];
                serial[j++] = hex_str[ page_83[4+i] & 0x0f];
        }
-       dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name);
+       dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel);
        return 0;
 }
 
        return 0;
 }
 
@@ -554,7 +554,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd,
                return 1;
 
        if (page_83[1] != PAGE_83) {
                return 1;
 
        if (page_83[1] != PAGE_83) {
-               info("%s: Invalid page 0x83", dev_scsi->kernel_name);
+               info("%s: Invalid page 0x83", dev_scsi->kernel);
                return 1;
        }
        
                return 1;
        }
        
@@ -605,7 +605,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd,
                        retval = check_fill_0x83_id(dev_scsi, &page_83[j],
                                                    &id_search_list[id_ind],
                                                    serial, len);
                        retval = check_fill_0x83_id(dev_scsi, &page_83[j],
                                                    &id_search_list[id_ind],
                                                    serial, len);
-                       dbg("%s id desc %d/%d/%d\n", dev_scsi->kernel_name,
+                       dbg("%s id desc %d/%d/%d\n", dev_scsi->kernel,
                                id_search_list[id_ind].id_type,
                                id_search_list[id_ind].naa_type,
                                id_search_list[id_ind].code_set);
                                id_search_list[id_ind].id_type,
                                id_search_list[id_ind].naa_type,
                                id_search_list[id_ind].code_set);
@@ -643,7 +643,7 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd,
                return 1;
 
        if (page_83[1] != PAGE_83) {
                return 1;
 
        if (page_83[1] != PAGE_83) {
-               info("%s: Invalid page 0x83", dev_scsi->kernel_name);
+               info("%s: Invalid page 0x83", dev_scsi->kernel);
                return 1;
        }
        /*
                return 1;
        }
        /*
@@ -687,7 +687,7 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd,
                serial[j++] = hex_str[page_83[i] & 0x0f];
                i++;
        }
                serial[j++] = hex_str[page_83[i] & 0x0f];
                i++;
        }
-       dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name);
+       dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel);
        return 0;
 }
 
        return 0;
 }
 
@@ -707,14 +707,14 @@ static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd,
                return retval;
 
        if (buf[1] != PAGE_80) {
                return retval;
 
        if (buf[1] != PAGE_80) {
-               info("%s: Invalid page 0x80", dev_scsi->kernel_name);
+               info("%s: Invalid page 0x80", dev_scsi->kernel);
                return 1;
        }
 
        len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
        if (max_len < len) {
                info("%s: length %d too short - need %d",
                return 1;
        }
 
        len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
        if (max_len < len) {
                info("%s: length %d too short - need %d",
-                   dev_scsi->kernel_name, max_len, len);
+                   dev_scsi->kernel, max_len, len);
                return 1;
        }
        /*
                return 1;
        }
        /*
@@ -744,7 +744,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
        fd = open(devname, O_RDONLY | O_NONBLOCK);
        if (fd < 0) {
                info("%s: cannot open %s: %s",
        fd = open(devname, O_RDONLY | O_NONBLOCK);
        if (fd < 0) {
                info("%s: cannot open %s: %s",
-                   dev_scsi->kernel_name, devname, strerror(errno));
+                   dev_scsi->kernel, devname, strerror(errno));
                return 1;
        }
 
                return 1;
        }
 
@@ -790,7 +790,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
                        goto completed;
                }
        } else if (page_code != 0x00) {
                        goto completed;
                }
        } else if (page_code != 0x00) {
-               info("%s: unsupported page code 0x%d", dev_scsi->kernel_name, page_code);
+               info("%s: unsupported page code 0x%d", dev_scsi->kernel, page_code);
                return 1;
        }
 
                return 1;
        }
 
@@ -808,7 +808,7 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
                goto completed;
        }
 
                goto completed;
        }
 
-       dbg("%s: Checking page0\n", dev_scsi->kernel_name);
+       dbg("%s: Checking page0\n", dev_scsi->kernel);
 
        for (ind = 4; ind <= page0[3] + 3; ind++)
                if (page0[ind] == PAGE_83)
 
        for (ind = 4; ind <= page0[3] + 3; ind++)
                if (page0[ind] == PAGE_83)
@@ -834,6 +834,6 @@ int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
        retval = 1;
 completed:
        if (close(fd) < 0)
        retval = 1;
 completed:
        if (close(fd) < 0)
-               info("%s: close failed: %s", dev_scsi->kernel_name, strerror(errno));
+               info("%s: close failed: %s", dev_scsi->kernel, strerror(errno));
        return retval;
 }
        return retval;
 }
index 85c6beda40e38d307d355aed4d8b789bb193cca4..ba8bfdf8c51475772288499cd90f4340d5123264 100644 (file)
@@ -255,7 +255,7 @@ static int usb_id(const char *devpath)
 
        if_class = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceClass");
        if (!if_class) {
 
        if_class = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceClass");
        if (!if_class) {
-               info("%s: cannot get bInterfaceClass attribute", dev_interface->kernel_name);
+               info("%s: cannot get bInterfaceClass attribute", dev_interface->kernel);
                return 1;
        }
        if_class_num = strtoul(if_class, NULL, 16);
                return 1;
        }
        if_class_num = strtoul(if_class, NULL, 16);
@@ -289,28 +289,28 @@ static int usb_id(const char *devpath)
                /* Generic SPC-2 device */
                scsi_vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
                if (!scsi_vendor) {
                /* Generic SPC-2 device */
                scsi_vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
                if (!scsi_vendor) {
-                       info("%s: cannot get SCSI vendor attribute", dev_scsi->kernel_name);
+                       info("%s: cannot get SCSI vendor attribute", dev_scsi->kernel);
                        goto fallback;
                }
                set_str(vendor_str, scsi_vendor, sizeof(vendor_str)-1);
 
                scsi_model = sysfs_attr_get_value(dev_scsi->devpath, "model");
                if (!scsi_model) {
                        goto fallback;
                }
                set_str(vendor_str, scsi_vendor, sizeof(vendor_str)-1);
 
                scsi_model = sysfs_attr_get_value(dev_scsi->devpath, "model");
                if (!scsi_model) {
-                       info("%s: cannot get SCSI model attribute", dev_scsi->kernel_name);
+                       info("%s: cannot get SCSI model attribute", dev_scsi->kernel);
                        goto fallback;
                }
                set_str(model_str, scsi_model, sizeof(model_str)-1);
 
                scsi_type = sysfs_attr_get_value(dev_scsi->devpath, "type");
                if (!scsi_type) {
                        goto fallback;
                }
                set_str(model_str, scsi_model, sizeof(model_str)-1);
 
                scsi_type = sysfs_attr_get_value(dev_scsi->devpath, "type");
                if (!scsi_type) {
-                       info("%s: cannot get SCSI type attribute", dev_scsi->kernel_name);
+                       info("%s: cannot get SCSI type attribute", dev_scsi->kernel);
                        goto fallback;
                }
                set_scsi_type(type_str, scsi_type, sizeof(type_str)-1);
 
                scsi_rev = sysfs_attr_get_value(dev_scsi->devpath, "rev");
                if (!scsi_rev) {
                        goto fallback;
                }
                set_scsi_type(type_str, scsi_type, sizeof(type_str)-1);
 
                scsi_rev = sysfs_attr_get_value(dev_scsi->devpath, "rev");
                if (!scsi_rev) {
-                       info("%s: cannot get SCSI revision attribute", dev_scsi->kernel_name);
+                       info("%s: cannot get SCSI revision attribute", dev_scsi->kernel);
                        goto fallback;
                }
                set_str(revision_str, scsi_rev, sizeof(revision_str)-1);
                        goto fallback;
                }
                set_str(revision_str, scsi_rev, sizeof(revision_str)-1);
index 63715ac093d77f742c4a01593ccd7195ecf87a6f..c1c5302caf8e4822476aa6491373f4a57322ca02 100755 (executable)
@@ -1075,13 +1075,13 @@ BUS=="scsi", KERNEL=="sda", NAME="should_not_match2", SUBSYSTEM=="vc"
 EOF
        },
        {
 EOF
        },
        {
-               desc            => "DRIVER match test",
+               desc            => "DRIVERS match test",
                subsys          => "block",
                devpath         => "/block/sda",
                exp_name        => "node",
                rules           => <<EOF
                subsys          => "block",
                devpath         => "/block/sda",
                exp_name        => "node",
                rules           => <<EOF
-BUS=="scsi", KERNEL=="sda", NAME="should_not_match", DRIVER=="sd-wrong"
-BUS=="scsi", KERNEL=="sda", NAME="node", DRIVER=="sd"
+BUS=="scsi", KERNEL=="sda", NAME="should_not_match", DRIVERS=="sd-wrong"
+BUS=="scsi", KERNEL=="sda", NAME="node", DRIVERS=="sd"
 EOF
        },
        {
 EOF
        },
        {
diff --git a/udev.7 b/udev.7
index cef84de0411576c691762e706e7475a594bb3eb1..e6828ee4eebdb22af7c18a78b8bfa3f36e5e7433 100644 (file)
--- a/udev.7
+++ b/udev.7
@@ -76,27 +76,32 @@ The following key names can be used to match against device properties:
 \fBACTION\fR
 Match the name of the event action.
 .TP 3n
 \fBACTION\fR
 Match the name of the event action.
 .TP 3n
-\fBKERNEL\fR
-Match the name of the device.
-.TP 3n
 \fBDEVPATH\fR
 \fBDEVPATH\fR
-Match the devpath of the device.
+Match the devpath of the event device.
+.TP 3n
+\fBKERNEL\fR
+Match the name of the event device.
 .TP 3n
 \fBSUBSYSTEM\fR
 .TP 3n
 \fBSUBSYSTEM\fR
-Match the subsystem of the device.
+Match the subsystem of the event device.
+.TP 3n
+\fBATTR{\fR\fB\fIfilename\fR\fR\fB}\fR
+Match sysfs attribute values of the event device. Up to five
+\fBATTR\fR
+keys can be specified per rule. Trailing whitespace in the attribute values is ignored, if the specified match value does not contain trailing whitespace itself.
 .TP 3n
 .TP 3n
-\fBBUS\fR
+\fBKERNELS\fR
+Search the devpath upwards for a matching device name.
+.TP 3n
+\fBSUBSYSTEMS\fR
 Search the devpath upwards for a matching device subsystem name.
 .TP 3n
 Search the devpath upwards for a matching device subsystem name.
 .TP 3n
-\fBDRIVER\fR
+\fBDRIVERS\fR
 Search the devpath upwards for a matching device driver name.
 .TP 3n
 Search the devpath upwards for a matching device driver name.
 .TP 3n
-\fBID\fR
-Search the devpath upwards for a matching device name.
-.TP 3n
-\fBSYSFS{\fR\fB\fIfilename\fR\fR\fB}\fR
+\fBATTRS{\fR\fB\fIfilename\fR\fR\fB}\fR
 Search the devpath upwards for a device with matching sysfs attribute values. Up to five
 Search the devpath upwards for a device with matching sysfs attribute values. Up to five
-\fBSYSFS\fR
+\fBATTRS\fR
 keys can be specified per rule. All attributes must match on the same device. Trailing whitespace in the attribute values is ignored, if the specified match value does not contain trailing whitespace itself.
 .TP 3n
 \fBENV{\fR\fB\fIkey\fR\fR\fB}\fR
 keys can be specified per rule. All attributes must match on the same device. Trailing whitespace in the attribute values is ignored, if the specified match value does not contain trailing whitespace itself.
 .TP 3n
 \fBENV{\fR\fB\fIkey\fR\fR\fB}\fR
@@ -187,13 +192,13 @@ The devpath of the device.
 .TP 3n
 \fB$id\fR, \fB%b\fR
 The name of the device matched while searching the devpath upwards for
 .TP 3n
 \fB$id\fR, \fB%b\fR
 The name of the device matched while searching the devpath upwards for
-\fBBUS\fR,
-\fBID\fR
-\fBDRIVER\fR
+\fBSUBSYSTEMS\fR,
+\fBKERNELS\fR
+\fBDRIVERS\fR
 and
 and
-\fBSYSFS\fR.
+\fBATTRS\fR.
 .TP 3n
 .TP 3n
-\fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR, \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR
+\fB$attr{\fR\fB\fIfile\fR\fR\fB}\fR, \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR
 The value of a sysfs attribute found at the current or a parent device.
 .TP 3n
 \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR, \fB%E{\fR\fB\fIkey\fR\fR\fB}\fR
 The value of a sysfs attribute found at the current or a parent device.
 .TP 3n
 \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR, \fB%E{\fR\fB\fIkey\fR\fR\fB}\fR
diff --git a/udev.h b/udev.h
index a69ce0893f0a35bfc64aa05047d29f39d50708e5..d681ad5613a92c4af782d5243a2c6b78e454bfac 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -54,8 +54,8 @@ struct sysfs_device {
        struct list_head node;                  /* for device cache */
        struct sysfs_device *parent;            /* already cached parent*/
        char devpath[PATH_SIZE];
        struct list_head node;                  /* for device cache */
        struct sysfs_device *parent;            /* already cached parent*/
        char devpath[PATH_SIZE];
-       char subsystem[NAME_SIZE];              /* $class/$bus/"drivers" */
-       char kernel_name[NAME_SIZE];            /* device instance name */
+       char subsystem[NAME_SIZE];              /* $class, $bus, drivers, module */
+       char kernel[NAME_SIZE];                 /* device instance name */
        char kernel_number[NAME_SIZE];
        char driver[NAME_SIZE];                 /* device driver name */
 };
        char kernel_number[NAME_SIZE];
        char driver[NAME_SIZE];                 /* device driver name */
 };
index 01e9d522ed4d5f2b29499f875b565b65d1c3fa46..84341565300d6f02b8136cab04cb71854d66e066 100644 (file)
--- a/udev.xml
+++ b/udev.xml
             </varlistentry>
 
             <varlistentry>
             </varlistentry>
 
             <varlistentry>
-              <term><option>KERNEL</option></term>
+              <term><option>DEVPATH</option></term>
               <listitem>
               <listitem>
-                <para>Match the name of the device.</para>
+                <para>Match the devpath of the event device.</para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               </listitem>
             </varlistentry>
 
             <varlistentry>
-              <term><option>DEVPATH</option></term>
+              <term><option>KERNEL</option></term>
               <listitem>
               <listitem>
-                <para>Match the devpath of the device.</para>
+                <para>Match the name of the event device.</para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               <term><option>SUBSYSTEM</option></term>
               <listitem>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               <term><option>SUBSYSTEM</option></term>
               <listitem>
-                <para>Match the subsystem of the device.</para>
+                <para>Match the subsystem of the event device.</para>
+              </listitem>
+            </varlistentry>
+<!--
+            <varlistentry>
+              <term><option>DRIVER</option></term>
+              <listitem>
+                <para>Match the driver name of the event device. Only set for devices created by a bus driver.</para>
+              </listitem>
+            </varlistentry>
+-->
+            <varlistentry>
+              <term><option>ATTR{<replaceable>filename</replaceable>}</option></term>
+              <listitem>
+                <para>Match sysfs attribute values of the event device. Up to five
+                <option>ATTR</option> keys can be specified per rule. Trailing
+                whitespace in the attribute values is ignored, if the specified match
+                value does not contain trailing whitespace itself.</para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               </listitem>
             </varlistentry>
 
             <varlistentry>
-              <term><option>BUS</option></term>
+              <term><option>KERNELS</option></term>
               <listitem>
               <listitem>
-                <para>Search the devpath upwards for a matching device subsystem name.</para>
+                <para>Search the devpath upwards for a matching device name.</para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               </listitem>
             </varlistentry>
 
             <varlistentry>
-              <term><option>DRIVER</option></term>
+              <term><option>SUBSYSTEMS</option></term>
               <listitem>
               <listitem>
-                <para>Search the devpath upwards for a matching device driver name.</para>
+                <para>Search the devpath upwards for a matching device subsystem name.</para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               </listitem>
             </varlistentry>
 
             <varlistentry>
-              <term><option>ID</option></term>
+              <term><option>DRIVERS</option></term>
               <listitem>
               <listitem>
-                <para>Search the devpath upwards for a matching device name.</para>
+                <para>Search the devpath upwards for a matching device driver name.</para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
               </listitem>
             </varlistentry>
 
             <varlistentry>
-              <term><option>SYSFS{<replaceable>filename</replaceable>}</option></term>
+              <term><option>ATTRS{<replaceable>filename</replaceable>}</option></term>
               <listitem>
                 <para>Search the devpath upwards for a device with matching sysfs attribute values.
               <listitem>
                 <para>Search the devpath upwards for a device with matching sysfs attribute values.
-                Up to five <option>SYSFS</option> keys can be specified per rule. All attributes
+                Up to five <option>ATTRS</option> keys can be specified per rule. All attributes
                 must match on the same device. Trailing whitespace in the attribute values is ignored,
                 if the specified match value does not contain trailing whitespace itself.</para>
               </listitem>
                 must match on the same device. Trailing whitespace in the attribute values is ignored,
                 if the specified match value does not contain trailing whitespace itself.</para>
               </listitem>
               <term><option>$id</option>, <option>%b</option></term>
               <listitem>
                 <para>The name of the device matched while searching the devpath upwards for
               <term><option>$id</option>, <option>%b</option></term>
               <listitem>
                 <para>The name of the device matched while searching the devpath upwards for
-                  <option>BUS</option>, <option>ID</option> <option>DRIVER</option> and <option>SYSFS</option>.
+                  <option>SUBSYSTEMS</option>, <option>KERNELS</option> <option>DRIVERS</option> and <option>ATTRS</option>.
                 </para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
                 </para>
               </listitem>
             </varlistentry>
 
             <varlistentry>
-              <term><option>$sysfs{<replaceable>file</replaceable>}</option>, <option>%s{<replaceable>file</replaceable>}</option></term>
+              <term><option>$attr{<replaceable>file</replaceable>}</option>, <option>%s{<replaceable>file</replaceable>}</option></term>
               <listitem>
                 <para>The value of a sysfs attribute found at the current or a parent device.</para>
               </listitem>
               <listitem>
                 <para>The value of a sysfs attribute found at the current or a parent device.</para>
               </listitem>
index b058351d27e35c8b38574ab50e1b8fe7c4fae1d3..c3034f5037f1320e6090c43799eb747212ee0ce9 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
@@ -81,7 +81,7 @@ int udev_db_add_device(struct udevice *udev)
         * create only a symlink with the name as the target
         * if we don't have any interesting data to remember
         */
         * create only a symlink with the name as the target
         * if we don't have any interesting data to remember
         */
-       if (strcmp(udev->name, udev->dev->kernel_name) == 0 &&
+       if (strcmp(udev->name, udev->dev->kernel) == 0 &&
            list_empty(&udev->symlink_list) && list_empty(&udev->env_list) &&
            !udev->partitions && !udev->ignore_remove) {
                dbg("nothing interesting to store, create symlink");
            list_empty(&udev->symlink_list) && list_empty(&udev->env_list) &&
            !udev->partitions && !udev->ignore_remove) {
                dbg("nothing interesting to store, create symlink");
index 87f90c76769b714320381368ab9cf02649c2030e..b680246bf8e035945bf82d01a96f4e3e16a278d6 100644 (file)
@@ -87,7 +87,7 @@ static int rename_netif(struct udevice *udev)
        struct ifreq ifr;
        int retval;
 
        struct ifreq ifr;
        int retval;
 
-       info("changing net interface name from '%s' to '%s'", udev->dev->kernel_name, udev->name);
+       info("changing net interface name from '%s' to '%s'", udev->dev->kernel, udev->name);
        if (udev->test_run)
                return 0;
 
        if (udev->test_run)
                return 0;
 
@@ -98,7 +98,7 @@ static int rename_netif(struct udevice *udev)
        }
 
        memset(&ifr, 0x00, sizeof(struct ifreq));
        }
 
        memset(&ifr, 0x00, sizeof(struct ifreq));
-       strlcpy(ifr.ifr_name, udev->dev->kernel_name, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, udev->dev->kernel, IFNAMSIZ);
        strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ);
        retval = ioctl(sk, SIOCSIFNAME, &ifr);
        if (retval != 0) {
        strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ);
        retval = ioctl(sk, SIOCSIFNAME, &ifr);
        if (retval != 0) {
@@ -111,7 +111,7 @@ static int rename_netif(struct udevice *udev)
                }
 
                /* free our own name, another process may wait for us */
                }
 
                /* free our own name, another process may wait for us */
-               strlcpy(ifr.ifr_newname, udev->dev->kernel_name, IFNAMSIZ);
+               strlcpy(ifr.ifr_newname, udev->dev->kernel, IFNAMSIZ);
                strlcat(ifr.ifr_newname, "_rename", IFNAMSIZ);
                retval = ioctl(sk, SIOCSIFNAME, &ifr);
                if (retval != 0) {
                strlcat(ifr.ifr_newname, "_rename", IFNAMSIZ);
                retval = ioctl(sk, SIOCSIFNAME, &ifr);
                if (retval != 0) {
@@ -211,7 +211,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
                }
 
                /* look if we want to change the name of the netif */
                }
 
                /* look if we want to change the name of the netif */
-               if (strcmp(udev->name, udev->dev->kernel_name) != 0) {
+               if (strcmp(udev->name, udev->dev->kernel) != 0) {
                        char *pos;
 
                        retval = rename_netif(udev);
                        char *pos;
 
                        retval = rename_netif(udev);
@@ -220,14 +220,14 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
                        info("renamed netif to '%s'", udev->name);
 
                        /* export old name */
                        info("renamed netif to '%s'", udev->name);
 
                        /* export old name */
-                       setenv("INTERFACE_OLD", udev->dev->kernel_name, 1);
+                       setenv("INTERFACE_OLD", udev->dev->kernel, 1);
 
                        /* now fake the devpath, because the kernel name changed silently */
                        pos = strrchr(udev->dev->devpath, '/');
                        if (pos != NULL) {
                                pos[1] = '\0';
                                strlcat(udev->dev->devpath, udev->name, sizeof(udev->dev->devpath));
 
                        /* now fake the devpath, because the kernel name changed silently */
                        pos = strrchr(udev->dev->devpath, '/');
                        if (pos != NULL) {
                                pos[1] = '\0';
                                strlcat(udev->dev->devpath, udev->name, sizeof(udev->dev->devpath));
-                               strlcpy(udev->dev->kernel_name, udev->name, sizeof(udev->dev->kernel_name));
+                               strlcpy(udev->dev->kernel, udev->name, sizeof(udev->dev->kernel));
                                setenv("DEVPATH", udev->dev->devpath, 1);
                                setenv("INTERFACE", udev->name, 1);
                        }
                                setenv("DEVPATH", udev->dev->devpath, 1);
                                setenv("INTERFACE", udev->name, 1);
                        }
@@ -250,8 +250,8 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
                        list_for_each_entry(name_loop, &udev->env_list, node)
                                putenv(name_loop->name);
                } else {
                        list_for_each_entry(name_loop, &udev->env_list, node)
                                putenv(name_loop->name);
                } else {
-                       dbg("'%s' not found in database, using kernel name '%s'", udev->dev->devpath, udev->dev->kernel_name);
-                       strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name));
+                       dbg("'%s' not found in database, using kernel name '%s'", udev->dev->devpath, udev->dev->kernel);
+                       strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
                }
 
                udev_rules_get_run(rules, udev);
                }
 
                udev_rules_get_run(rules, udev);
index 12a738e4e2798fcc1350f4bc7afb8e1e2133e644..4ba1c26c5e014d26fa9fc49e1d0bbc420ebd19c5 100644 (file)
@@ -51,7 +51,7 @@ int udev_node_mknod(struct udevice *udev, const char *file, dev_t devt, mode_t m
        /* preserve node with already correct numbers, to prevent changing the inode number */
        if ((stats.st_mode & S_IFMT) == (mode & S_IFMT) && (stats.st_rdev == devt)) {
                info("preserve file '%s', because it has correct dev_t", file);
        /* preserve node with already correct numbers, to prevent changing the inode number */
        if ((stats.st_mode & S_IFMT) == (mode & S_IFMT) && (stats.st_rdev == devt)) {
                info("preserve file '%s', because it has correct dev_t", file);
-               selinux_setfilecon(file, udev->dev->kernel_name, stats.st_mode);
+               selinux_setfilecon(file, udev->dev->kernel, stats.st_mode);
                goto perms;
        }
 
                goto perms;
        }
 
@@ -61,7 +61,7 @@ int udev_node_mknod(struct udevice *udev, const char *file, dev_t devt, mode_t m
                dbg("already present file '%s' unlinked", file);
 
 create:
                dbg("already present file '%s' unlinked", file);
 
 create:
-       selinux_setfscreatecon(file, udev->dev->kernel_name, mode);
+       selinux_setfscreatecon(file, udev->dev->kernel, mode);
        retval = mknod(file, mode, devt);
        selinux_resetfscreatecon();
        if (retval != 0) {
        retval = mknod(file, mode, devt);
        selinux_resetfscreatecon();
        if (retval != 0) {
index 979b81d821b570b05cbc7a9f1d830ddebb0d02e3..49306295ff8ad85292c3f4031b9f43a8a2081a4c 100644 (file)
@@ -307,13 +307,13 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
        enum subst_type {
                SUBST_UNKNOWN,
                SUBST_DEVPATH,
        enum subst_type {
                SUBST_UNKNOWN,
                SUBST_DEVPATH,
+               SUBST_KERNEL,
                SUBST_KERNEL_NUMBER,
                SUBST_KERNEL_NUMBER,
-               SUBST_KERNEL_NAME,
                SUBST_ID,
                SUBST_MAJOR,
                SUBST_MINOR,
                SUBST_RESULT,
                SUBST_ID,
                SUBST_MAJOR,
                SUBST_MINOR,
                SUBST_RESULT,
-               SUBST_SYSFS,
+               SUBST_ATTR,
                SUBST_PARENT,
                SUBST_TEMP_NODE,
                SUBST_ROOT,
                SUBST_PARENT,
                SUBST_TEMP_NODE,
                SUBST_ROOT,
@@ -324,18 +324,19 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
                char fmt;
                enum subst_type type;
        } map[] = {
                char fmt;
                enum subst_type type;
        } map[] = {
-               { .name = "devpath",            .fmt = 'p',     .type = SUBST_DEVPATH },
-               { .name = "number",             .fmt = 'n',     .type = SUBST_KERNEL_NUMBER },
-               { .name = "kernel",             .fmt = 'k',     .type = SUBST_KERNEL_NAME },
-               { .name = "id",                 .fmt = 'b',     .type = SUBST_ID },
-               { .name = "major",              .fmt = 'M',     .type = SUBST_MAJOR },
-               { .name = "minor",              .fmt = 'm',     .type = SUBST_MINOR },
-               { .name = "result",             .fmt = 'c',     .type = SUBST_RESULT },
-               { .name = "sysfs",              .fmt = 's',     .type = SUBST_SYSFS },
-               { .name = "parent",             .fmt = 'P',     .type = SUBST_PARENT },
-               { .name = "tempnode",           .fmt = 'N',     .type = SUBST_TEMP_NODE },
-               { .name = "root",               .fmt = 'r',     .type = SUBST_ROOT },
-               { .name = "env",                .fmt = 'E',     .type = SUBST_ENV },
+               { .name = "devpath",    .fmt = 'p',     .type = SUBST_DEVPATH },
+               { .name = "number",     .fmt = 'n',     .type = SUBST_KERNEL_NUMBER },
+               { .name = "kernel",     .fmt = 'k',     .type = SUBST_KERNEL },
+               { .name = "id",         .fmt = 'b',     .type = SUBST_ID },
+               { .name = "major",      .fmt = 'M',     .type = SUBST_MAJOR },
+               { .name = "minor",      .fmt = 'm',     .type = SUBST_MINOR },
+               { .name = "result",     .fmt = 'c',     .type = SUBST_RESULT },
+               { .name = "attr",       .fmt = 's',     .type = SUBST_ATTR },
+               { .name = "sysfs",      .fmt = 's',     .type = SUBST_ATTR },
+               { .name = "parent",     .fmt = 'P',     .type = SUBST_PARENT },
+               { .name = "tempnode",   .fmt = 'N',     .type = SUBST_TEMP_NODE },
+               { .name = "root",       .fmt = 'r',     .type = SUBST_ROOT },
+               { .name = "env",        .fmt = 'E',     .type = SUBST_ENV },
                { NULL, '\0', 0 }
        };
        enum subst_type type;
                { NULL, '\0', 0 }
        };
        enum subst_type type;
@@ -399,9 +400,9 @@ found:
                        strlcat(string, udev->dev->devpath, maxsize);
                        dbg("substitute devpath '%s'", udev->dev->devpath);
                        break;
                        strlcat(string, udev->dev->devpath, maxsize);
                        dbg("substitute devpath '%s'", udev->dev->devpath);
                        break;
-               case SUBST_KERNEL_NAME:
-                       strlcat(string, udev->dev->kernel_name, maxsize);
-                       dbg("substitute kernel name '%s'", udev->dev->kernel_name);
+               case SUBST_KERNEL:
+                       strlcat(string, udev->dev->kernel, maxsize);
+                       dbg("substitute kernel name '%s'", udev->dev->kernel);
                        break;
                case SUBST_KERNEL_NUMBER:
                        strlcat(string, udev->dev->kernel_number, maxsize);
                        break;
                case SUBST_KERNEL_NUMBER:
                        strlcat(string, udev->dev->kernel_number, maxsize);
@@ -409,8 +410,8 @@ found:
                        break;
                case SUBST_ID:
                        if (udev->dev_parent != NULL) {
                        break;
                case SUBST_ID:
                        if (udev->dev_parent != NULL) {
-                               strlcat(string, udev->dev_parent->kernel_name, maxsize);
-                               dbg("substitute id '%s'", udev->dev_parent->kernel_name);
+                               strlcat(string, udev->dev_parent->kernel, maxsize);
+                               dbg("substitute id '%s'", udev->dev_parent->kernel);
                        }
                        break;
                case SUBST_MAJOR:
                        }
                        break;
                case SUBST_MAJOR:
@@ -457,7 +458,7 @@ found:
                                dbg("substitute result string '%s'", udev->program_result);
                        }
                        break;
                                dbg("substitute result string '%s'", udev->program_result);
                        }
                        break;
-               case SUBST_SYSFS:
+               case SUBST_ATTR:
                        if (attr == NULL) {
                                dbg("missing attribute");
                                break;
                        if (attr == NULL) {
                                dbg("missing attribute");
                                break;
@@ -605,7 +606,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
        if (match_key("ACTION", rule, &rule->action, udev->action))
                goto nomatch;
 
        if (match_key("ACTION", rule, &rule->action, udev->action))
                goto nomatch;
 
-       if (match_key("KERNEL", rule, &rule->kernel_name, udev->dev->kernel_name))
+       if (match_key("KERNEL", rule, &rule->kernel, udev->dev->kernel))
                goto nomatch;
 
        if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem))
                goto nomatch;
 
        if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem))
@@ -614,7 +615,10 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
        if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath))
                goto nomatch;
 
        if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath))
                goto nomatch;
 
-       /* compare NAME against a previously assigned value */
+       if (match_key("DRIVER", rule, &rule->driver, udev->dev->driver))
+               goto nomatch;
+
+       /* match NAME against a value assigned by an earlier rule */
        if (match_key("NAME", rule, &rule->name, udev->name))
                goto nomatch;
 
        if (match_key("NAME", rule, &rule->name, udev->name))
                goto nomatch;
 
@@ -646,26 +650,57 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
                }
        }
 
                }
        }
 
+       /* check for matching sysfs attrubute pairs */
+       if (rule->attr.count) {
+               dbg("check %i ATTR keys", rule->attr.count);
+               for (i = 0; i < rule->attr.count; i++) {
+                       struct key_pair *pair = &rule->attr.keys[i];
+                       const char *key_name = key_pair_name(rule, pair);
+                       const char *key_value = key_val(rule, &pair->key);
+                       const char *value;
+                       char val[VALUE_SIZE];
+                       size_t len;
+
+                       value = sysfs_attr_get_value(udev->dev->devpath, key_name);
+                       if (value == NULL)
+                               goto nomatch;
+                       strlcpy(val, value, sizeof(val));
+
+                       /* strip trailing whitespace of value, if not asked to match for it */
+                       len = strlen(key_value);
+                       if (len > 0 && !isspace(key_value[len-1])) {
+                               len = strlen(val);
+                               while (len > 0 && isspace(val[len-1]))
+                                       val[--len] = '\0';
+                               dbg("removed %zi trailing whitespace chars from '%s'", strlen(val)-len, val);
+                       }
+
+                       if (match_key("ATTR", rule, &pair->key, val))
+                               goto nomatch;
+               }
+               dbg("all %i ATTR keys matched", rule->attr.count);
+       }
+
        /* walk up the chain of parent devices and find a match */
        udev->dev_parent = udev->dev;
        while (1) {
        /* walk up the chain of parent devices and find a match */
        udev->dev_parent = udev->dev;
        while (1) {
-               /* check for matching driver */
-               if (match_key("DRIVER", rule, &rule->driver, udev->dev_parent->driver))
+               /* check for matching kernel device name */
+               if (match_key("KERNELS", rule, &rule->kernels, udev->dev_parent->kernel))
                        goto try_parent;
 
                        goto try_parent;
 
-               /* check for matching subsystem/bus value */
-               if (match_key("BUS", rule, &rule->bus, udev->dev_parent->subsystem))
+               /* check for matching subsystem value */
+               if (match_key("SUBSYSTEMS", rule, &rule->subsystems, udev->dev_parent->subsystem))
                        goto try_parent;
 
                        goto try_parent;
 
-               /* check for matching bus id (device name) */
-               if (match_key("ID", rule, &rule->id, udev->dev_parent->kernel_name))
+               /* check for matching driver */
+               if (match_key("DRIVERS", rule, &rule->drivers, udev->dev_parent->driver))
                        goto try_parent;
 
                        goto try_parent;
 
-               /* check for matching sysfs pairs */
-               if (rule->sysfs.count) {
-                       dbg("check %i SYSFS keys", rule->sysfs.count);
-                       for (i = 0; i < rule->sysfs.count; i++) {
-                               struct key_pair *pair = &rule->sysfs.keys[i];
+               /* check for matching sysfs attrubute pairs */
+               if (rule->attrs.count) {
+                       dbg("check %i ATTRS keys", rule->attrs.count);
+                       for (i = 0; i < rule->attrs.count; i++) {
+                               struct key_pair *pair = &rule->attrs.keys[i];
                                const char *key_name = key_pair_name(rule, pair);
                                const char *key_value = key_val(rule, &pair->key);
                                const char *value;
                                const char *key_name = key_pair_name(rule, pair);
                                const char *key_value = key_val(rule, &pair->key);
                                const char *value;
@@ -688,10 +723,10 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
                                        dbg("removed %zi trailing whitespace chars from '%s'", strlen(val)-len, val);
                                }
 
                                        dbg("removed %zi trailing whitespace chars from '%s'", strlen(val)-len, val);
                                }
 
-                               if (match_key("SYSFS", rule, &pair->key, val))
+                               if (match_key("ATTRS", rule, &pair->key, val))
                                        goto try_parent;
                        }
                                        goto try_parent;
                        }
-                       dbg("all %i SYSFS keys matched", rule->sysfs.count);
+                       dbg("all %i ATTRS keys matched", rule->attrs.count);
                }
 
                /* found matching device  */
                }
 
                /* found matching device  */
@@ -703,7 +738,7 @@ try_parent:
                if (udev->dev_parent == NULL)
                        goto nomatch;
                dbg("looking at dev_parent->devpath='%s'", udev->dev_parent->devpath);
                if (udev->dev_parent == NULL)
                        goto nomatch;
                dbg("looking at dev_parent->devpath='%s'", udev->dev_parent->devpath);
-               dbg("looking at dev_parent->bus_kernel_name='%s'", udev->dev_parent->kernel_name);
+               dbg("looking at dev_parent->kernel='%s'", udev->dev_parent->kernel);
        }
 
        /* execute external program */
        }
 
        /* execute external program */
@@ -794,7 +829,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
        int name_set = 0;
 
        dbg("udev->dev->devpath='%s'", udev->dev->devpath);
        int name_set = 0;
 
        dbg("udev->dev->devpath='%s'", udev->dev->devpath);
-       dbg("udev->dev->kernel_name='%s'", udev->dev->kernel_name);
+       dbg("udev->dev->kernel='%s'", udev->dev->kernel);
 
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
 
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
@@ -815,7 +850,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                if (match_rule(udev, rule) == 0) {
                        /* apply options */
                        if (rule->ignore_device) {
                if (match_rule(udev, rule) == 0) {
                        /* apply options */
                        if (rule->ignore_device) {
-                               info("rule applied, '%s' is ignored", udev->dev->kernel_name);
+                               info("rule applied, '%s' is ignored", udev->dev->kernel);
                                udev->ignore_device = 1;
                                return 0;
                        }
                                udev->ignore_device = 1;
                                return 0;
                        }
@@ -835,21 +870,21 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                                if (rule->mode_operation == KEY_OP_ASSIGN_FINAL)
                                        udev->mode_final = 1;
                                udev->mode = rule->mode;
                                if (rule->mode_operation == KEY_OP_ASSIGN_FINAL)
                                        udev->mode_final = 1;
                                udev->mode = rule->mode;
-                               dbg("applied mode=%#o to '%s'", rule->mode, udev->dev->kernel_name);
+                               dbg("applied mode=%#o to '%s'", rule->mode, udev->dev->kernel);
                        }
                        if (!udev->owner_final && rule->owner.operation != KEY_OP_UNSET) {
                                if (rule->owner.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->owner_final = 1;
                                strlcpy(udev->owner, key_val(rule, &rule->owner), sizeof(udev->owner));
                                udev_rules_apply_format(udev, udev->owner, sizeof(udev->owner));
                        }
                        if (!udev->owner_final && rule->owner.operation != KEY_OP_UNSET) {
                                if (rule->owner.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->owner_final = 1;
                                strlcpy(udev->owner, key_val(rule, &rule->owner), sizeof(udev->owner));
                                udev_rules_apply_format(udev, udev->owner, sizeof(udev->owner));
-                               dbg("applied owner='%s' to '%s'", udev->owner, udev->dev->kernel_name);
+                               dbg("applied owner='%s' to '%s'", udev->owner, udev->dev->kernel);
                        }
                        if (!udev->group_final && rule->group.operation != KEY_OP_UNSET) {
                                if (rule->group.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->group_final = 1;
                                strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group));
                                udev_rules_apply_format(udev, udev->group, sizeof(udev->group));
                        }
                        if (!udev->group_final && rule->group.operation != KEY_OP_UNSET) {
                                if (rule->group.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->group_final = 1;
                                strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group));
                                udev_rules_apply_format(udev, udev->group, sizeof(udev->group));
-                               dbg("applied group='%s' to '%s'", udev->group, udev->dev->kernel_name);
+                               dbg("applied group='%s' to '%s'", udev->group, udev->dev->kernel);
                        }
 
                        /* collect symlinks */
                        }
 
                        /* collect symlinks */
@@ -904,7 +939,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                                if (count)
                                        info("%i untrusted character(s) replaced", count);
 
                                if (count)
                                        info("%i untrusted character(s) replaced", count);
 
-                               info("rule applied, '%s' becomes '%s'", udev->dev->kernel_name, udev->name);
+                               info("rule applied, '%s' becomes '%s'", udev->dev->kernel, udev->name);
                                if (strcmp(udev->dev->subsystem, "net") != 0)
                                        dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i",
                                            udev->name, udev->owner, udev->group, udev->mode, udev->partitions);
                                if (strcmp(udev->dev->subsystem, "net") != 0)
                                        dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i",
                                            udev->name, udev->owner, udev->group, udev->mode, udev->partitions);
@@ -934,7 +969,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
        }
 
        if (!name_set) {
        }
 
        if (!name_set) {
-               strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name));
+               strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
                info("no node name set, will use kernel name '%s'", udev->name);
        }
 
                info("no node name set, will use kernel name '%s'", udev->name);
        }
 
@@ -951,7 +986,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev)
 {
        struct udev_rule *rule;
 
 {
        struct udev_rule *rule;
 
-       dbg("udev->kernel_name='%s'", udev->dev->kernel_name);
+       dbg("udev->kernel='%s'", udev->dev->kernel);
 
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
 
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
@@ -969,7 +1004,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev)
 
                if (match_rule(udev, rule) == 0) {
                        if (rule->ignore_device) {
 
                if (match_rule(udev, rule) == 0) {
                        if (rule->ignore_device) {
-                               info("rule applied, '%s' is ignored", udev->dev->kernel_name);
+                               info("rule applied, '%s' is ignored", udev->dev->kernel);
                                udev->ignore_device = 1;
                                return 0;
                        }
                                udev->ignore_device = 1;
                                return 0;
                        }
index 2c956fccccef3c9f2d48727baf6aa826eac5b2f4..dac0dfcbb337bbbc5b2bce2ccdf05fa762508dd9 100644 (file)
@@ -60,30 +60,34 @@ enum import_type {
 };
 
 struct udev_rule {
 };
 
 struct udev_rule {
-       struct key label;
-       struct key goto_label;
-       struct key kernel_name;
-       struct key subsystem;
        struct key action;
        struct key devpath;
        struct key action;
        struct key devpath;
-       struct key bus;
-       struct key id;
+       struct key kernel;
+       struct key subsystem;
        struct key driver;
        struct key driver;
+       struct key_pairs attr;
+
+       struct key kernels;
+       struct key subsystems;
+       struct key drivers;
+       struct key_pairs attrs;
+
+       struct key_pairs env;
        struct key program;
        struct key result;
        struct key import;
        enum import_type import_type;
        struct key program;
        struct key result;
        struct key import;
        enum import_type import_type;
+       struct key run;
        struct key wait_for_sysfs;
        struct key wait_for_sysfs;
-       struct key_pairs sysfs;
-       struct key_pairs env;
+       struct key label;
+       struct key goto_label;
 
        struct key name;
        struct key symlink;
 
        struct key name;
        struct key symlink;
-       struct key run;
        struct key owner;
        struct key group;
        struct key owner;
        struct key group;
-       enum key_operation mode_operation;
        mode_t mode;
        mode_t mode;
+       enum key_operation mode_operation;
 
        unsigned int partitions;
        unsigned int last_rule:1,
 
        unsigned int partitions;
        unsigned int last_rule:1,
index 8d69e74864310e5f584f2d490402b914aeb92dd2..5e93e60d4f97f906cc216f522cbed3b9aac3cdb7 100644 (file)
@@ -263,14 +263,24 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                if (retval)
                        break;
 
                if (retval)
                        break;
 
-               if (strcasecmp(key, "LABEL") == 0) {
-                       add_rule_key(rule, &rule->label, operation, value);
+               if (strcasecmp(key, "ACTION") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid ACTION operation");
+                               goto invalid;
+                       }
+                       add_rule_key(rule, &rule->action, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "GOTO") == 0) {
-                       add_rule_key(rule, &rule->goto_label, operation, value);
+               if (strcasecmp(key, "DEVPATH") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid DEVPATH operation");
+                               goto invalid;
+                       }
+                       add_rule_key(rule, &rule->devpath, operation, value);
                        valid = 1;
                        continue;
                }
                        valid = 1;
                        continue;
                }
@@ -281,7 +291,7 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                                err("invalid KERNEL operation");
                                goto invalid;
                        }
                                err("invalid KERNEL operation");
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->kernel_name, operation, value);
+                       add_rule_key(rule, &rule->kernel, operation, value);
                        valid = 1;
                        continue;
                }
                        valid = 1;
                        continue;
                }
@@ -297,68 +307,84 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
                        continue;
                }
 
-               if (strcasecmp(key, "ACTION") == 0) {
+               if (strcasecmp(key, "DRIVER") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid ACTION operation");
+                               err("invalid DRIVER operation");
                                goto invalid;
                        }
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->action, operation, value);
+                       err("DRIVER== will change in a future relase, "
+                           "please use DRIVERS== in %s:%u", filename, lineno);
+                       /* FIXME: this should be rule->driver to match only the event device */
+                       add_rule_key(rule, &rule->drivers, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "DEVPATH") == 0) {
+               if (strncasecmp(key, "ATTR", sizeof("ATTR")-1) == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid DEVPATH operation");
+                               err("invalid ATTR operation");
                                goto invalid;
                        }
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->devpath, operation, value);
+                       attr = get_key_attribute(key + sizeof("ATTR")-1);
+                       if (attr == NULL) {
+                               err("error parsing ATTR attribute in '%s'", line);
+                               continue;
+                       }
+                       add_rule_key_pair(rule, &rule->attr, operation, attr, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "BUS") == 0) {
+               if (strcasecmp(key, "KERNELS") == 0 ||
+                   strcasecmp(key, "ID") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid BUS operation");
+                               err("invalid KERNELS operation");
                                goto invalid;
                        }
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->bus, operation, value);
+                       add_rule_key(rule, &rule->kernels, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "ID") == 0) {
+               if (strcasecmp(key, "SUBSYTEMS") == 0 ||
+                   strcasecmp(key, "BUS") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid ID operation");
+                               err("invalid SUBSYSTEMS operation");
                                goto invalid;
                        }
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->id, operation, value);
+                       add_rule_key(rule, &rule->subsystems, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) {
+               if (strcasecmp(key, "DRIVERS") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid SYSFS operation");
+                               err("invalid DRIVERS operation");
                                goto invalid;
                        }
                                goto invalid;
                        }
-                       attr = get_key_attribute(key + sizeof("SYSFS")-1);
-                       if (attr == NULL) {
-                               err("error parsing SYSFS attribute in '%s'", line);
-                               continue;
-                       }
-                       add_rule_key_pair(rule, &rule->sysfs, operation, attr, value);
+                       add_rule_key(rule, &rule->drivers, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
-                       add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
+               if (strncasecmp(key, "ATTRS", sizeof("ATTRS")-1) == 0 ||
+                   strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid ATTRSS operation");
+                               goto invalid;
+                       }
+                       attr = get_key_attribute(key + sizeof("ATTRS")-1);
+                       if (attr == NULL) {
+                               err("error parsing ATTRS attribute in '%s'", line);
+                               continue;
+                       }
+                       add_rule_key_pair(rule, &rule->attrs, operation, attr, value);
                        valid = 1;
                        continue;
                }
                        valid = 1;
                        continue;
                }
@@ -374,6 +400,23 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
                        continue;
                }
 
+               if (strcasecmp(key, "PROGRAM") == 0) {
+                       add_rule_key(rule, &rule->program, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
+               if (strcasecmp(key, "RESULT") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid RESULT operation");
+                               goto invalid;
+                       }
+                       add_rule_key(rule, &rule->result, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
                if (strncasecmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) {
                        attr = get_key_attribute(key + sizeof("IMPORT")-1);
                        if (attr && strstr(attr, "program")) {
                if (strncasecmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) {
                        attr = get_key_attribute(key + sizeof("IMPORT")-1);
                        if (attr && strstr(attr, "program")) {
@@ -419,30 +462,26 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
                        continue;
                }
 
-               if (strcasecmp(key, "DRIVER") == 0) {
-                       if (operation != KEY_OP_MATCH &&
-                           operation != KEY_OP_NOMATCH) {
-                               err("invalid DRIVER operation");
-                               goto invalid;
-                       }
-                       add_rule_key(rule, &rule->driver, operation, value);
+               if (strcasecmp(key, "RUN") == 0) {
+                       add_rule_key(rule, &rule->run, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "RESULT") == 0) {
-                       if (operation != KEY_OP_MATCH &&
-                           operation != KEY_OP_NOMATCH) {
-                               err("invalid RESULT operation");
-                               goto invalid;
-                       }
-                       add_rule_key(rule, &rule->result, operation, value);
+               if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
+                       add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
                        valid = 1;
                        continue;
                }
 
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "PROGRAM") == 0) {
-                       add_rule_key(rule, &rule->program, operation, value);
+               if (strcasecmp(key, "LABEL") == 0) {
+                       add_rule_key(rule, &rule->label, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
+               if (strcasecmp(key, "GOTO") == 0) {
+                       add_rule_key(rule, &rule->goto_label, operation, value);
                        valid = 1;
                        continue;
                }
                        valid = 1;
                        continue;
                }
@@ -516,12 +555,6 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
                        continue;
                }
 
-               if (strcasecmp(key, "RUN") == 0) {
-                       add_rule_key(rule, &rule->run, operation, value);
-                       valid = 1;
-                       continue;
-               }
-
                if (strcasecmp(key, "OPTIONS") == 0) {
                        if (strstr(value, "last_rule") != NULL) {
                                dbg("last rule to be applied");
                if (strcasecmp(key, "OPTIONS") == 0) {
                        if (strstr(value, "last_rule") != NULL) {
                                dbg("last rule to be applied");
index 85ea4d15e99b0cc84e4ca68593df9605fbc2dadd..c4afe0cffba90a95f88ecf4feef4928e3073f765 100644 (file)
@@ -95,11 +95,11 @@ void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath,
        if (pos == NULL)
                return;
 
        if (pos == NULL)
                return;
 
-       strlcpy(dev->kernel_name, &pos[1], sizeof(dev->kernel_name));
-       dbg("kernel_name='%s'", dev->kernel_name);
+       strlcpy(dev->kernel, &pos[1], sizeof(dev->kernel));
+       dbg("kernel='%s'", dev->kernel);
 
        /* some devices have '!' in their name, change that to '/' */
 
        /* some devices have '!' in their name, change that to '/' */
-       pos = dev->kernel_name;
+       pos = dev->kernel;
        while (pos[0] != '\0') {
                if (pos[0] == '!')
                        pos[0] = '/';
        while (pos[0] != '\0') {
                if (pos[0] == '!')
                        pos[0] = '/';
@@ -107,7 +107,7 @@ void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath,
        }
 
        /* get kernel number */
        }
 
        /* get kernel number */
-       pos = &dev->kernel_name[strlen(dev->kernel_name)];
+       pos = &dev->kernel[strlen(dev->kernel)];
        while (isdigit(pos[-1]))
                pos--;
        strlcpy(dev->kernel_number, pos, sizeof(dev->kernel_number));
        while (isdigit(pos[-1]))
                pos--;
        strlcpy(dev->kernel_number, pos, sizeof(dev->kernel_number));
index 1a10f9ad073c80f2b58c74717edc70702c0c7da0..d6f564079f0510687c67576efc52434e0c4af6cf 100644 (file)
@@ -45,7 +45,7 @@ void log_message (int priority, const char *format, ...)
 }
 #endif
 
 }
 #endif
 
-static void print_all_attributes(const char *devpath)
+static void print_all_attributes(const char *devpath, const char *key)
 {
        char path[PATH_SIZE];
        DIR *dir;
 {
        char path[PATH_SIZE];
        DIR *dir;
@@ -80,7 +80,7 @@ static void print_all_attributes(const char *devpath)
                        }
 
                        replace_untrusted_chars(value);
                        }
 
                        replace_untrusted_chars(value);
-                       printf("    SYSFS{%s}==\"%s\"\n", dent->d_name, value);
+                       printf("    %s{%s}==\"%s\"\n", key, dent->d_name, value);
                }
        }
        printf("\n");
                }
        }
        printf("\n");
@@ -103,10 +103,10 @@ static int print_device_chain(const char *devpath)
                return -1;
 
        printf("  looking at device '%s':\n", dev->devpath);
                return -1;
 
        printf("  looking at device '%s':\n", dev->devpath);
-       printf("    KERNEL==\"%s\"\n", dev->kernel_name);
+       printf("    KERNEL==\"%s\"\n", dev->kernel);
        printf("    SUBSYSTEM==\"%s\"\n", dev->subsystem);
        printf("    DRIVER==\"%s\"\n", dev->driver);
        printf("    SUBSYSTEM==\"%s\"\n", dev->subsystem);
        printf("    DRIVER==\"%s\"\n", dev->driver);
-       print_all_attributes(dev->devpath);
+       print_all_attributes(dev->devpath, "ATTR");
 
        /* walk up the chain of devices */
        while (1) {
 
        /* walk up the chain of devices */
        while (1) {
@@ -114,11 +114,11 @@ static int print_device_chain(const char *devpath)
                if (dev == NULL)
                        break;
                printf("  looking at parent device '%s':\n", dev->devpath);
                if (dev == NULL)
                        break;
                printf("  looking at parent device '%s':\n", dev->devpath);
-               printf("    ID==\"%s\"\n", dev->kernel_name);
-               printf("    BUS==\"%s\"\n", dev->subsystem);
-               printf("    DRIVER==\"%s\"\n", dev->driver);
+               printf("    KERNELS==\"%s\"\n", dev->kernel);
+               printf("    SUBSYTEMS==\"%s\"\n", dev->subsystem);
+               printf("    DRIVERS==\"%s\"\n", dev->driver);
 
 
-               print_all_attributes(dev->devpath);
+               print_all_attributes(dev->devpath, "ATTRS");
        }
 
        return 0;
        }
 
        return 0;