diff options
author | Kay Sievers <kay.sievers@suse.de> | 2005-06-26 18:55:24 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@suse.de> | 2005-06-26 18:55:24 +0200 |
commit | b8476286d62c82a1a0bd8de318aa3f7d835222a0 (patch) | |
tree | 37d3071c2767f819440083e34c5e68efde584b60 | |
parent | 208f6aba21199ff4f93002eeb948d564f76843e6 (diff) | |
download | systemd-b8476286d62c82a1a0bd8de318aa3f7d835222a0.tar.gz systemd-b8476286d62c82a1a0bd8de318aa3f7d835222a0.tar.bz2 systemd-b8476286d62c82a1a0bd8de318aa3f7d835222a0.zip |
store the imported device information in the udevdb
Any program can query with udevinfo for persistent device
attributes evaluated on device discovery now.
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
-rw-r--r-- | extras/ata_id/Makefile | 2 | ||||
-rw-r--r-- | extras/run_directory/Makefile | 4 | ||||
-rw-r--r-- | extras/volume_id/vol_id.c | 9 | ||||
-rw-r--r-- | udev.h | 1 | ||||
-rw-r--r-- | udev_db.c | 9 | ||||
-rw-r--r-- | udev_libc_wrapper.h | 13 | ||||
-rw-r--r-- | udev_rules.c | 28 | ||||
-rw-r--r-- | udev_utils.c | 42 | ||||
-rw-r--r-- | udev_utils.h | 1 | ||||
-rw-r--r-- | udevinfo.c | 45 | ||||
-rw-r--r-- | udevstart.c | 24 |
11 files changed, 126 insertions, 52 deletions
diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index ad79a0d836..a19c4b2289 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -1,4 +1,4 @@ -# Makefile for udev_volume_id +# Makefile for ata_id # # Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> # diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 12dccf0749..0562073c8f 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -1,6 +1,6 @@ -# Makefile for udev_volume_id +# Makefile for run_directory # -# Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> +# Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 3048fd8062..451fd355c1 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -1,11 +1,8 @@ /* - * udev_volume_id - udev callout to read filesystem label and uuid + * vol_id - udev callout to read filesystem label and uuid * * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> * - * sample udev rule for creation of a symlink with the filsystem uuid: - * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -u %N", SYMLINK="%c" - * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. @@ -95,7 +92,7 @@ static void set_str(char *to, const unsigned char *from, int count) int main(int argc, char *argv[]) { - const char help[] = "usage: udev_volume_id [--export|-t|-l|-u] <device>\n" + const char help[] = "usage: vol_id [--export|-t|-l|-u] <device>\n" " --export\n" " -t filesystem type\n" " -l filesystem label\n" @@ -114,7 +111,7 @@ int main(int argc, char *argv[]) const char *node = NULL; int rc = 0; - logging_init("udev_volume_id"); + logging_init("vol_id"); for (i = 1 ; i < argc; i++) { char *arg = argv[i]; @@ -69,6 +69,7 @@ struct udevice { dev_t devt; struct list_head run_list; int run_final; + struct list_head env_list; char tmp_node[PATH_SIZE]; int partitions; @@ -86,7 +86,8 @@ int udev_db_add_device(struct udevice *udev) fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt)); fprintf(f, "A:%u\n", udev->partitions); fprintf(f, "R:%u\n", udev->ignore_remove); - + list_for_each_entry(name_loop, &udev->env_list, node) + fprintf(f, "E:%s\n", name_loop->name); fclose(f); return 0; @@ -149,6 +150,12 @@ static int parse_db_file(struct udevice *udev, const char *filename) strlcpy(line, &bufline[2], count-1); udev->ignore_remove = atoi(line); break; + case 'E': + if (count > sizeof(line)) + count = sizeof(line); + strlcpy(line, &bufline[2], count-1); + name_list_add(&udev->env_list, line, 0); + break; } } file_unmap(buf, bufsize); diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 4d6d332c69..4bb68913a9 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -44,15 +44,18 @@ #include <string.h> +#ifdef __KLIBC__ +static inline int clearenv(void) +{ + environ[0] = NULL; + return 0; +} +#endif + extern uid_t lookup_user(const char *user); extern gid_t lookup_group(const char *group); -#ifndef strlcat extern size_t strlcpy(char *dst, const char *src, size_t size); -#endif - -#ifndef strlcat extern size_t strlcat(char *dst, const char *src, size_t size); -#endif #endif /* _UDEV_LIBC_WRAPPER_H_ */ diff --git a/udev_rules.c b/udev_rules.c index b81943a17c..9b9454e8fb 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -174,21 +174,26 @@ static int get_key(char **line, char **key, char **value) linepos++; /* get the value*/ - if (linepos[0] == '\0') - return -1; - if (linepos[0] == '"') { linepos++; temp = strchr(linepos, '"'); - if (!temp) + if (!temp) { + dbg("missing closing quote"); return -1; + } + dbg("value is quoted"); temp[0] = '\0'; } else if (linepos[0] == '\'') { linepos++; temp = strchr(linepos, '\''); - if (!temp) + if (!temp) { + dbg("missing closing quote"); return -1; + } + dbg("value is quoted"); temp[0] = '\0'; + } else if (linepos[0] == '\0') { + dbg("value is empty"); } else { temp = linepos; while (temp[0] && !isspace(temp[0])) @@ -200,7 +205,7 @@ static int get_key(char **line, char **key, char **value) return 0; } -static int import_keys_into_env(const char *buf, size_t bufsize) +static int import_keys_into_env(struct udevice *udev, const char *buf, size_t bufsize) { char line[LINE_SIZE]; const char *bufline; @@ -211,7 +216,7 @@ static int import_keys_into_env(const char *buf, size_t bufsize) size_t count; int lineno; - /* loop through the whole file */ + /* loop through the whole buffer */ lineno = 0; cur = 0; while (cur < bufsize) { @@ -242,6 +247,7 @@ static int import_keys_into_env(const char *buf, size_t bufsize) linepos = line; if (get_key(&linepos, &variable, &value) == 0) { dbg("import '%s=%s'", variable, value); + name_list_key_add(&udev->env_list, variable, value); setenv(variable, value, 1); } } @@ -249,7 +255,7 @@ static int import_keys_into_env(const char *buf, size_t bufsize) return 0; } -static int import_file_into_env(const char *filename) +static int import_file_into_env(struct udevice *udev, const char *filename) { char *buf; size_t bufsize; @@ -258,7 +264,7 @@ static int import_file_into_env(const char *filename) err("can't open '%s'", filename); return -1; } - import_keys_into_env(buf, bufsize); + import_keys_into_env(udev, buf, bufsize); file_unmap(buf, bufsize); return 0; @@ -271,7 +277,7 @@ static int import_program_into_env(struct udevice *udev, const char *program) if (execute_program(program, udev->subsystem, result, sizeof(result), &reslen) != 0) return -1; - return import_keys_into_env(result, reslen); + return import_keys_into_env(udev, result, reslen); } /* finds the lowest positive N such that <name>N isn't present in the udevdb @@ -828,7 +834,7 @@ try_parent: rc = import_program_into_env(udev, import); } else { dbg("import file import='%s'", import); - rc = import_file_into_env(import); + rc = import_file_into_env(udev, import); } if (rc) { dbg(KEY_IMPORT " failed"); diff --git a/udev_utils.c b/udev_utils.c index 9e2e152763..3ab9e43348 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -47,6 +47,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs memset(udev, 0x00, sizeof(struct udevice)); INIT_LIST_HEAD(&udev->symlink_list); INIT_LIST_HEAD(&udev->run_list); + INIT_LIST_HEAD(&udev->env_list); if (subsystem) strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); @@ -112,6 +113,10 @@ void udev_cleanup_device(struct udevice *udev) list_del(&name_loop->node); free(name_loop); } + list_for_each_entry_safe(name_loop, temp_loop, &udev->env_list, node) { + list_del(&name_loop->node); + free(name_loop); + } } int string_is_true(const char *str) @@ -303,10 +308,14 @@ int name_list_add(struct list_head *name_list, const char *name, int sort) dbg("'%s' is already in the list", name); return 0; } - if (sort && strcmp(loop_name->name, name) > 0) - break; } + if (sort) + list_for_each_entry(loop_name, name_list, node) { + if (sort && strcmp(loop_name->name, name) > 0) + break; + } + new_name = malloc(sizeof(struct name_entry)); if (new_name == NULL) { dbg("error malloc"); @@ -314,6 +323,35 @@ int name_list_add(struct list_head *name_list, const char *name, int sort) } strlcpy(new_name->name, name, sizeof(new_name->name)); + dbg("adding '%s'", new_name->name); + list_add_tail(&new_name->node, &loop_name->node); + + return 0; +} + +int name_list_key_add(struct list_head *name_list, const char *key, const char *value) +{ + struct name_entry *loop_name; + struct name_entry *new_name; + + list_for_each_entry(loop_name, name_list, node) { + if (strncmp(loop_name->name, key, strlen(key)) == 0) { + dbg("key already present '%s', replace it", loop_name->name); + snprintf(loop_name->name, sizeof(loop_name->name), "%s=%s", key, value); + loop_name->name[sizeof(loop_name->name)-1] = '\0'; + return 0; + } + } + + new_name = malloc(sizeof(struct name_entry)); + if (new_name == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + snprintf(new_name->name, sizeof(new_name->name), "%s=%s", key, value); + new_name->name[sizeof(new_name->name)-1] = '\0'; + dbg("adding '%s'", new_name->name); list_add_tail(&new_name->node, &loop_name->node); return 0; diff --git a/udev_utils.h b/udev_utils.h index 999a4fcf55..655c764fc8 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -44,6 +44,7 @@ extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void remove_trailing_char(char *path, char c); extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); +extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); extern int execute_program(const char *command, const char *subsystem, char *result, size_t ressize, size_t *reslen); diff --git a/udevinfo.c b/udevinfo.c index 69e5335b7c..db562eee49 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -92,14 +92,6 @@ static int print_record(struct udevice *udev) return 0; } -enum query_type { - NONE, - NAME, - PATH, - SYMLINK, - ALL, -}; - static int print_device_chain(const char *path) { struct sysfs_class_device *class_dev; @@ -185,7 +177,14 @@ int main(int argc, char *argv[], char *envp[]) struct udevice udev; int root = 0; int attributes = 0; - enum query_type query = NONE; + enum query_type { + QUERY_NONE, + QUERY_NAME, + QUERY_PATH, + QUERY_SYMLINK, + QUERY_ENV, + QUERY_ALL, + } query = QUERY_NONE; char path[PATH_SIZE] = ""; char name[PATH_SIZE] = ""; char temp[PATH_SIZE]; @@ -220,22 +219,27 @@ int main(int argc, char *argv[], char *envp[]) dbg("udev query: %s\n", optarg); if (strcmp(optarg, "name") == 0) { - query = NAME; + query = QUERY_NAME; break; } if (strcmp(optarg, "symlink") == 0) { - query = SYMLINK; + query = QUERY_SYMLINK; break; } if (strcmp(optarg, "path") == 0) { - query = PATH; + query = QUERY_PATH; + break; + } + + if (strcmp(optarg, "env") == 0) { + query = QUERY_ENV; break; } if (strcmp(optarg, "all") == 0) { - query = ALL; + query = QUERY_ALL; break; } @@ -268,7 +272,7 @@ int main(int argc, char *argv[], char *envp[]) } /* process options */ - if (query != NONE) { + if (query != QUERY_NONE) { if (path[0] != '\0') { /* remove sysfs_path if given */ if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) { @@ -317,13 +321,13 @@ int main(int argc, char *argv[], char *envp[]) print: switch(query) { - case NAME: + case QUERY_NAME: if (root) printf("%s/%s\n", udev_root, udev.name); else printf("%s\n", udev.name); goto exit; - case SYMLINK: + case QUERY_SYMLINK: if (list_empty(&udev.symlink_list)) break; if (root) @@ -334,10 +338,14 @@ print: printf("%s ", name_loop->name); printf("\n"); goto exit; - case PATH: + case QUERY_PATH: printf("%s\n", udev.devpath); goto exit; - case ALL: + case QUERY_ENV: + list_for_each_entry(name_loop, &udev.env_list, node) + printf("%s\n", name_loop->name); + goto exit; + case QUERY_ALL: print_record(&udev); goto exit; default: @@ -373,6 +381,7 @@ help: " 'name' name of device node\n" " 'symlink' pointing to node\n" " 'path' sysfs device path\n" + " 'env' the device related imported environment\n" " 'all' all values\n" "\n" " -p PATH sysfs device path used for query or chain\n" diff --git a/udevstart.c b/udevstart.c index b65a28aab6..4e922bb716 100644 --- a/udevstart.c +++ b/udevstart.c @@ -45,6 +45,9 @@ #include "udev_utils.h" #include "list.h" +static const char *udev_run_str; +static const char *udev_log_str; + #ifdef USE_LOG void log_message(int priority, const char *format, ...) { @@ -111,8 +114,17 @@ static int add_device(const char *path, const char *subsystem) const char *devpath; devpath = &path[strlen(sysfs_path)]; + + /* clear and set environment for next event */ + clearenv(); + setenv("ACTION", "add", 1); setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 1); + setenv("UDEV_START", "1", 1); + if (udev_log_str) + setenv("UDEV_LOG", udev_log_str, 1); + if (udev_run_str) + setenv("UDEV_RUN", udev_run_str, 1); dbg("exec: '%s' (%s)\n", devpath, path); class_dev = sysfs_open_class_device_path(path); @@ -327,10 +339,14 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udev"); udev_init_config(); + dbg("version %s", UDEV_VERSION); + + udev_run_str = getenv("UDEV_RUN"); + udev_log_str = getenv("UDEV_LOG"); + /* disable all logging if not explicitely requested */ - if (getenv("UDEV_LOG") == NULL) + if (udev_log_str == NULL) udev_log_priority = 0; - dbg("version %s", UDEV_VERSION); /* set signal handlers */ memset(&act, 0x00, sizeof(act)); @@ -344,10 +360,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - /* set environment for executed programs */ - setenv("ACTION", "add", 1); - setenv("UDEV_START", "1", 1); - udev_rules_init(); udev_scan_block(); |