mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
IMPORT: add {parent} to import the persistent data of the parent device
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
parent
0cd4ac473a
commit
0bfb84e1ed
@ -1471,6 +1471,27 @@ EOF
|
|||||||
KERNEL=="dontknow*|*nothing", NAME="nomatch"
|
KERNEL=="dontknow*|*nothing", NAME="nomatch"
|
||||||
KERNEL=="dontknow*|ttyUSB*|nothing*", NAME="right"
|
KERNEL=="dontknow*|ttyUSB*|nothing*", NAME="right"
|
||||||
KERNEL=="ttyUSB*", NAME="wrong"
|
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
|
EOF
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
51
udev_rules.c
51
udev_rules.c
@ -281,6 +281,46 @@ static int import_program_into_env(struct udevice *udev, const char *program)
|
|||||||
return import_keys_into_env(udev, result, reslen);
|
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
|
/* 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
|
* if <name> doesn't exist, 0 is returned, N otherwise
|
||||||
*/
|
*/
|
||||||
@ -604,8 +644,10 @@ found:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos = getenv(attr);
|
pos = getenv(attr);
|
||||||
if (pos == NULL)
|
if (pos == NULL) {
|
||||||
|
dbg("env '%s' not avialable", attr);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
dbg("substitute env '%s=%s'", attr, pos);
|
dbg("substitute env '%s=%s'", attr, pos);
|
||||||
strlcat(string, pos, maxsize);
|
strlcat(string, pos, maxsize);
|
||||||
break;
|
break;
|
||||||
@ -812,12 +854,15 @@ try_parent:
|
|||||||
strlcpy(import, key_val(rule, &rule->import), sizeof(import));
|
strlcpy(import, key_val(rule, &rule->import), sizeof(import));
|
||||||
apply_format(udev, import, sizeof(import), class_dev, sysfs_device);
|
apply_format(udev, import, sizeof(import), class_dev, sysfs_device);
|
||||||
dbg("check for IMPORT import='%s'", import);
|
dbg("check for IMPORT import='%s'", import);
|
||||||
if (rule->import_exec) {
|
if (rule->import_type == IMPORT_PROGRAM) {
|
||||||
dbg("run executable file import='%s'", import);
|
dbg("run executable file import='%s'", import);
|
||||||
rc = import_program_into_env(udev, import);
|
rc = import_program_into_env(udev, import);
|
||||||
} else {
|
} else if (rule->import_type == IMPORT_FILE) {
|
||||||
dbg("import file import='%s'", import);
|
dbg("import file import='%s'", import);
|
||||||
rc = import_file_into_env(udev, 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) {
|
if (rc) {
|
||||||
dbg("IMPORT failed");
|
dbg("IMPORT failed");
|
||||||
|
11
udev_rules.h
11
udev_rules.h
@ -54,6 +54,13 @@ struct key_pairs {
|
|||||||
struct key_pair keys[PAIRS_MAX];
|
struct key_pair keys[PAIRS_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum import_type {
|
||||||
|
IMPORT_UNSET,
|
||||||
|
IMPORT_PROGRAM,
|
||||||
|
IMPORT_FILE,
|
||||||
|
IMPORT_PARENT,
|
||||||
|
};
|
||||||
|
|
||||||
struct udev_rule {
|
struct udev_rule {
|
||||||
struct key kernel_name;
|
struct key kernel_name;
|
||||||
struct key subsystem;
|
struct key subsystem;
|
||||||
@ -66,6 +73,7 @@ struct udev_rule {
|
|||||||
struct key result;
|
struct key result;
|
||||||
struct key modalias;
|
struct key modalias;
|
||||||
struct key import;
|
struct key import;
|
||||||
|
enum import_type import_type;
|
||||||
struct key wait_for_sysfs;
|
struct key wait_for_sysfs;
|
||||||
struct key_pairs sysfs;
|
struct key_pairs sysfs;
|
||||||
struct key_pairs env;
|
struct key_pairs env;
|
||||||
@ -81,8 +89,7 @@ struct udev_rule {
|
|||||||
unsigned int partitions;
|
unsigned int partitions;
|
||||||
unsigned int last_rule:1,
|
unsigned int last_rule:1,
|
||||||
ignore_device:1,
|
ignore_device:1,
|
||||||
ignore_remove:1,
|
ignore_remove:1;
|
||||||
import_exec:1;
|
|
||||||
|
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
char buf[];
|
char buf[];
|
||||||
|
@ -311,9 +311,13 @@ static int add_to_rules(struct udev_rules *rules, char *line)
|
|||||||
attr = get_key_attribute(key + sizeof("IMPORT")-1);
|
attr = get_key_attribute(key + sizeof("IMPORT")-1);
|
||||||
if (attr && strstr(attr, "program")) {
|
if (attr && strstr(attr, "program")) {
|
||||||
dbg("IMPORT will be executed");
|
dbg("IMPORT will be executed");
|
||||||
rule->import_exec = 1;
|
rule->import_type = IMPORT_PROGRAM;
|
||||||
} else if (attr && strstr(attr, "file")) {
|
} else if (attr && strstr(attr, "file")) {
|
||||||
dbg("IMPORT will be included as 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 {
|
} else {
|
||||||
/* figure it out if it is executable */
|
/* figure it out if it is executable */
|
||||||
char file[PATH_SIZE];
|
char file[PATH_SIZE];
|
||||||
@ -326,8 +330,11 @@ static int add_to_rules(struct udev_rules *rules, char *line)
|
|||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
dbg("IMPORT auto mode for '%s'", file);
|
dbg("IMPORT auto mode for '%s'", file);
|
||||||
if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) {
|
if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) {
|
||||||
dbg("IMPORT is executable, will be executed");
|
dbg("IMPORT is executable, will be executed (autotype)");
|
||||||
rule->import_exec = 1;
|
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);
|
add_rule_key(rule, &rule->import, operation, value);
|
||||||
|
Loading…
Reference in New Issue
Block a user