chiark / gitweb /
[PATCH] add NAME{ignore_remove} attribute
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sat, 13 Nov 2004 13:43:24 +0000 (14:43 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 05:27:34 +0000 (22:27 -0700)
Some broken ide drivers are generating high event traffic, with
add/remove events. With this attribute, it can be specified,
that the node is always available. It may be used in conjunction
with the new DRIVER= match to catch specific kernel device drivers.

namedev.c
namedev.h
namedev_parse.c
test/udev-test.pl
udev.8.in
udev.h
udev_db.c
udev_remove.c

index c5c7929ab212680cb53a76710dbf7b6ecd53c91b..69669709df9ef37211525a6bfd8d0527a2797e64 100644 (file)
--- a/namedev.c
+++ b/namedev.c
@@ -807,6 +807,7 @@ found:
                goto done;
 
        udev->partitions = dev->partitions;
+       udev->ignore_remove = dev->ignore_remove;
 
        /* get permissions given in rule */
        set_empty_perms(udev, dev->mode,
index 7a98d66c24ca42c2b5f964c2751c6eac8610ab8d..8e552c85684ba580a3f43ffc55ace21b5a089bd3 100644 (file)
--- a/namedev.h
+++ b/namedev.h
@@ -52,6 +52,7 @@ struct sysfs_class_device;
 #define FIELD_MODE             "MODE"
 
 #define ATTR_PARTITIONS                "all_partitions"
+#define ATTR_IGNORE_REMOVE     "ignore_remove"
 #define PARTITIONS_COUNT       15
 
 #define MAX_SYSFS_PAIRS                5
@@ -90,6 +91,7 @@ struct config_device {
        char group[GROUP_SIZE];
        unsigned int mode;
        int partitions;
+       int ignore_remove;
        char config_file[NAME_SIZE];
        int config_line;
 };
index 4afa85cfa991a6dbbb03469f1dd4ce16f06d4ba4..cb1760fd578c31f889685e954a5f0a9f814d8580 100644 (file)
@@ -278,10 +278,16 @@ static int namedev_parse_rules(const char *filename, void *data)
 
                        if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) {
                                attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1);
-                               if (attr != NULL && strcasecmp(attr, ATTR_PARTITIONS) == 0) {
+                               if (attr != NULL) {
+                                       if (strstr(attr, ATTR_PARTITIONS) != NULL) {
                                                dbg_parse("creation of partition nodes requested");
                                                dev.partitions = PARTITIONS_COUNT;
                                        }
+                                       if (strstr(attr, ATTR_IGNORE_REMOVE) != NULL) {
+                                               dbg_parse("remove event should be ignored");
+                                               dev.ignore_remove = 1;
+                                       }
+                               }
                                strfieldcpy(dev.name, temp3);
                                valid = 1;
                                continue;
index 1e06df5220a7ae78c20601f1cd07b6c211533cb8..d584579584ba2b7bb7606ba2ebaed0d32ba26d93 100644 (file)
@@ -1105,7 +1105,28 @@ KERNEL="sda", NAME="cdrom%e"
 EOF
        },
        {
-               desc            => "SUBSYSTEM test",
+               desc            => "ignore remove event test",
+               subsys          => "block",
+               devpath         => "/block/sda",
+               exp_name        => "node",
+               exp_error       => "yes",
+               conf            => <<EOF
+BUS="scsi", KERNEL="sda", NAME{ignore_remove}="node"
+EOF
+       },
+       {
+               desc            => "ignore remove event test (with all partitions)",
+               subsys          => "block",
+               devpath         => "/block/sda",
+               exp_name        => "node14",
+               exp_error       => "yes",
+               option          => "clear",
+               conf            => <<EOF
+BUS="scsi", KERNEL="sda", NAME{ignore_remove, all_partitions}="node"
+EOF
+       },
+       {
+               desc            => "SUBSYSTEM match test",
                subsys          => "block",
                devpath         => "/block/sda",
                exp_name        => "node",
@@ -1116,7 +1137,7 @@ BUS="scsi", KERNEL="sda", NAME="should_not_match2", SUBSYSTEM="vc"
 EOF
        },
        {
-               desc            => "DRIVER test",
+               desc            => "DRIVER match test",
                subsys          => "block",
                devpath         => "/block/sda",
                exp_name        => "node",
index b5296b472d3c3421ebc2562c83830f4f84b0a0fa..728ddb1a45355c5d3abeb84e2d1599427092f3c5 100644 (file)
--- a/udev.8.in
+++ b/udev.8.in
@@ -216,6 +216,13 @@ If given with the attribute
 .BR NAME{ all_partitions }
 it will  create all 15 partitions of a blockdevice.
 This may be useful for removable media devices.
+.br
+If given with the attribute
+.BR NAME{ ignore_remove }
+it will will ignore any later remove event for this device.
+This may be useful as a workaround for broken device drivers.
+.sp
+Multiple attributes may be separated by comma.
 .TP
 .B SYMLINK
 The name of a symlink targeting the node. Multiple symlinks may be
diff --git a/udev.h b/udev.h
index 73733ad3bb859b9bc166f0f1fd8ac95d22f514b3..d9a775ae91ef4dbc90e06c99c2450054ae34176c 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -57,6 +57,7 @@ struct udevice {
        mode_t mode;
        char symlink[NAME_SIZE];
        int partitions;
+       int ignore_remove;
        int config_line;
        char config_file[NAME_SIZE];
        long config_uptime;
index f2a890ea421c7b3ad8b633a8275727298b5ff405..e07e72b85843e079dec58d0948083d47c5294672 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
@@ -79,7 +79,8 @@ int udev_db_add_device(struct udevice *udev)
        fprintf(f, "P:%s\n", udev->devpath);
        fprintf(f, "N:%s\n", udev->name);
        fprintf(f, "S:%s\n", udev->symlink);
-       fprintf(f, "A:%d\n", udev->partitions);
+       fprintf(f, "A:%u\n", udev->partitions);
+       fprintf(f, "R:%u\n", udev->ignore_remove);
 
        fclose(f);
 
@@ -111,21 +112,34 @@ static int parse_db_file(struct udevice *udev, const char *filename)
                        if (count > DEVPATH_SIZE)
                                count = DEVPATH_SIZE-1;
                        strncpy(udev->devpath, &bufline[2], count-2);
+                       udev->devpath[count-2] = '\0';
                        break;
                case 'N':
                        if (count > NAME_SIZE)
                                count = NAME_SIZE-1;
                        strncpy(udev->name, &bufline[2], count-2);
+                       udev->name[count-2] = '\0';
                        break;
                case 'S':
                        if (count > NAME_SIZE)
                                count = NAME_SIZE-1;
                        strncpy(udev->symlink, &bufline[2], count-2);
+                       udev->symlink[count-2] = '\0';
                        break;
                case 'A':
-                       strfieldcpy(line, &bufline[2]);
+                       if (count > NAME_SIZE)
+                               count = NAME_SIZE-1;
+                       strncpy(line, &bufline[2], count-2);
+                       line[count-2] = '\0';
                        udev->partitions = atoi(line);
                        break;
+               case 'R':
+                       if (count > NAME_SIZE)
+                               count = NAME_SIZE-1;
+                       strncpy(line, &bufline[2], count-2);
+                       line[count-2] = '\0';
+                       udev->ignore_remove = atoi(line);
+                       break;
                }
        }
 
index 32cd785984c821267fde164258098ea07b0aa8b9..8887125dd8aeba84b17ef77604a0456a2e86d101 100644 (file)
@@ -185,6 +185,11 @@ int udev_remove_device(struct udevice *udev)
                dbg("'%s' not found in database, falling back on default name", udev->name);
        }
 
+       if (udev->ignore_remove) {
+               dbg("remove event for '%s' requested to be ignored by rule", udev->name);
+               return 0;
+       }
+
        dbg("remove name='%s'", udev->name);
        udev_db_delete_device(udev);