chiark / gitweb /
IMPORT: add {parent} to import the persistent data of the parent device
authorKay Sievers <kay.sievers@suse.de>
Tue, 12 Jul 2005 12:46:36 +0000 (14:46 +0200)
committerKay Sievers <kay.sievers@suse.de>
Tue, 12 Jul 2005 12:46:36 +0000 (14:46 +0200)
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
test/udev-test.pl
udev_rules.c
udev_rules.h
udev_rules_parse.c

index e8cb7c48a9d8659061d9773cab4becf77f03026d..1bb60bb76e522f57929bf0b818885afbdbb48cb4 100755 (executable)
@@ -1471,6 +1471,27 @@ EOF
 KERNEL=="dontknow*|*nothing", NAME="nomatch"
 KERNEL=="dontknow*|ttyUSB*|nothing*", NAME="right"
 KERNEL=="ttyUSB*", NAME="wrong"
+EOF
+       },
+       {
+               desc            => "IMPORT parent test sequence 1/2 (keep)",
+               subsys          => "block",
+               devpath         => "/block/sda",
+               exp_name        => "parent",
+               option          => "keep",
+               rules           => <<EOF
+KERNEL=="sda", IMPORT="/bin/echo -e \'PARENT_KEY=parent_right\\nWRONG_PARENT_KEY=parent_wrong'"
+KERNEL=="sda", NAME="parent"
+EOF
+       },
+       {
+               desc            => "IMPORT parent test sequence 2/2 (keep)",
+               subsys          => "block",
+               devpath         => "/block/sda/sda1",
+               exp_name        => "parentenv-parent_right",
+               option          => "clean",
+               rules           => <<EOF
+KERNEL=="sda1", IMPORT{parent}="PARENT*", NAME="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}"
 EOF
        },
 );
index 8ec8fc54a4f15a23fd5e62896bbb77a29303c863..d08edf7782fda5460153f9569efdfaa0623c5f21 100644 (file)
@@ -281,6 +281,46 @@ static int import_program_into_env(struct udevice *udev, const char *program)
        return import_keys_into_env(udev, result, reslen);
 }
 
+static int import_parent_into_env(struct udevice *udev, struct sysfs_class_device *class_dev, const char *filter)
+{
+       struct sysfs_class_device *parent = sysfs_get_classdev_parent(class_dev);
+       int rc = -1;
+
+       if (parent != NULL) {
+               struct udevice udev_parent;
+               struct name_entry *name_loop;
+
+               dbg("found parent '%s', get the node name", parent->path);
+               udev_init_device(&udev_parent, NULL, NULL, NULL);
+               /* import the udev_db of the parent */
+               if (udev_db_get_device(&udev_parent, &parent->path[strlen(sysfs_path)]) == 0) {
+                       dbg("import stored parent env '%s'", udev_parent.name);
+                       list_for_each_entry(name_loop, &udev_parent.env_list, node) {
+                               char name[NAME_SIZE];
+                               char *pos;
+
+                               strlcpy(name, name_loop->name, sizeof(name));
+                               pos = strchr(name, '=');
+                               if (pos) {
+                                       pos[0] = '\0';
+                                       pos++;
+                                       if (strcmp_pattern(filter, name) == 0) {
+                                               dbg("import key '%s'", name_loop->name);
+                                               name_list_add(&udev->env_list, name_loop->name, 0);
+                                               setenv(name, pos, 1);
+                                       } else
+                                               dbg("skip key '%s'", name_loop->name);
+                               }
+                       }
+                       rc = 0;
+               } else
+                       dbg("parent not found in database");
+               udev_cleanup_device(&udev_parent);
+       }
+
+       return rc;
+}
+
 /* finds the lowest positive N such that <name>N isn't present in the udevdb
  * if <name> doesn't exist, 0 is returned, N otherwise
  */
@@ -604,8 +644,10 @@ found:
                                break;
                        }
                        pos = getenv(attr);
-                       if (pos == NULL)
+                       if (pos == NULL) {
+                               dbg("env '%s' not avialable", attr);
                                break;
+                       }
                        dbg("substitute env '%s=%s'", attr, pos);
                        strlcat(string, pos, maxsize);
                        break;
@@ -812,12 +854,15 @@ try_parent:
                strlcpy(import, key_val(rule, &rule->import), sizeof(import));
                apply_format(udev, import, sizeof(import), class_dev, sysfs_device);
                dbg("check for IMPORT import='%s'", import);
-               if (rule->import_exec) {
+               if (rule->import_type == IMPORT_PROGRAM) {
                        dbg("run executable file import='%s'", import);
                        rc = import_program_into_env(udev, import);
-               } else {
+               } else if (rule->import_type == IMPORT_FILE) {
                        dbg("import file import='%s'", import);
                        rc = import_file_into_env(udev, import);
+               } else if (rule->import_type == IMPORT_PARENT && class_dev) {
+                       dbg("import parent import='%s'", import);
+                       rc = import_parent_into_env(udev, class_dev, import);
                }
                if (rc) {
                        dbg("IMPORT failed");
index 959524a802fc48bdd7ac8fc5fb8835857822a72c..3f37d4b0b4d3345089dda3ebe512d9015d5daa3e 100644 (file)
@@ -54,6 +54,13 @@ struct key_pairs {
        struct key_pair keys[PAIRS_MAX];
 };
 
+enum import_type {
+       IMPORT_UNSET,
+       IMPORT_PROGRAM,
+       IMPORT_FILE,
+       IMPORT_PARENT,
+};
+
 struct udev_rule {
        struct key kernel_name;
        struct key subsystem;
@@ -66,6 +73,7 @@ struct udev_rule {
        struct key result;
        struct key modalias;
        struct key import;
+       enum import_type import_type;
        struct key wait_for_sysfs;
        struct key_pairs sysfs;
        struct key_pairs env;
@@ -81,8 +89,7 @@ struct udev_rule {
        unsigned int partitions;
        unsigned int last_rule:1,
                     ignore_device:1,
-                    ignore_remove:1,
-                    import_exec:1;
+                    ignore_remove:1;
 
        size_t bufsize;
        char buf[];
index 9483bcd71f802789cbb4e4bf209c113af3cc01e3..7c3c2e7fc252698aed9bb4be6c3d0c551a588b14 100644 (file)
@@ -311,9 +311,13 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                        attr = get_key_attribute(key + sizeof("IMPORT")-1);
                        if (attr && strstr(attr, "program")) {
                                dbg("IMPORT will be executed");
-                               rule->import_exec = 1;
+                               rule->import_type  = IMPORT_PROGRAM;
                        } else if (attr && strstr(attr, "file")) {
                                dbg("IMPORT will be included as file");
+                               rule->import_type  = IMPORT_FILE;
+                       } else if (attr && strstr(attr, "parent")) {
+                               dbg("IMPORT will include the parent values");
+                               rule->import_type = IMPORT_PARENT;
                        } else {
                                /* figure it out if it is executable */
                                char file[PATH_SIZE];
@@ -326,8 +330,11 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                                        pos[0] = '\0';
                                dbg("IMPORT auto mode for '%s'", file);
                                if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) {
-                                               dbg("IMPORT is executable, will be executed");
-                                               rule->import_exec = 1;
+                                       dbg("IMPORT is executable, will be executed (autotype)");
+                                       rule->import_type  = IMPORT_PROGRAM;
+                               } else {
+                                       dbg("IMPORT is not executable, will be included as file (autotype)");
+                                       rule->import_type  = IMPORT_FILE;
                                }
                        }
                        add_rule_key(rule, &rule->import, operation, value);