From 0bfb84e1edd96b1e82ffd74c43b865e5d6dbf204 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 14:46:36 +0200 Subject: [PATCH] IMPORT: add {parent} to import the persistent data of the parent device Signed-off-by: Kay Sievers --- test/udev-test.pl | 21 +++++++++++++++++++ udev_rules.c | 51 +++++++++++++++++++++++++++++++++++++++++++--- udev_rules.h | 11 ++++++++-- udev_rules_parse.c | 13 +++++++++--- 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index e8cb7c48a..1bb60bb76 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -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 => < "IMPORT parent test sequence 2/2 (keep)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "parentenv-parent_right", + option => "clean", + rules => <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 N isn't present in the udevdb * if 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"); diff --git a/udev_rules.h b/udev_rules.h index 959524a80..3f37d4b0b 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -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[]; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 9483bcd71..7c3c2e7fc 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -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); -- 2.30.2