chiark / gitweb /
store the imported device information in the udevdb
authorKay Sievers <kay.sievers@suse.de>
Sun, 26 Jun 2005 16:55:24 +0000 (18:55 +0200)
committerKay Sievers <kay.sievers@suse.de>
Sun, 26 Jun 2005 16:55:24 +0000 (18:55 +0200)
Any program can query with udevinfo for persistent device
attributes evaluated on device discovery now.

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
extras/ata_id/Makefile
extras/run_directory/Makefile
extras/volume_id/vol_id.c
udev.h
udev_db.c
udev_libc_wrapper.h
udev_rules.c
udev_utils.c
udev_utils.h
udevinfo.c
udevstart.c

index ad79a0d836ce8eaa2d1bc5b50b2a04fdb2ca3af3..a19c4b228983a75f6ab29fcc2ad95dff36af142a 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile for udev_volume_id
+# Makefile for ata_id
 #
 # Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
 #
index 12dccf074973f8d6614c459959061cbec3d1079c..0562073c8ffc41d74f42e43b6bf1d431bc07c58e 100644 (file)
@@ -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
index 3048fd8062c1c43fa4129bac65f8fe1198d66f87..451fd355c1ad10cbe5714fadfcce14ee55818ea5 100644 (file)
@@ -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];
diff --git a/udev.h b/udev.h
index 11fbe024606f24e9cafd4b2f56fe500208139f6d..b5287bb53fd679e59c02bc81d72cc6b37ecb1ac5 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -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;
index afbd50e50fc00fdfb9fa1948a209f0d8ec2893b4..264af79d063c49500753913028df3f352323c3ed 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
@@ -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);
index 4d6d332c691255e7e1ae001c67d3933f83e47bb7..4bb68913a901588fbc2397fbd7b86e14c0a3b43e 100644 (file)
 
 #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_ */
index b81943a17c2bfa7ca4b10be4eae08d45d2aca5e5..9b9454e8fbcd53f8b0654975bb8b8c598c327dbd 100644 (file)
@@ -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");
index 9e2e152763578d3c373d5c69752fd9fe702a4ab4..3ab9e433486aa55f2f95027155327b2c50a22902 100644 (file)
@@ -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;
index 999a4fcf55cd1b77933538dcfd5db4d4d9d5d8d5..655c764fc8c54711ca727b77de0004697d8bdf40 100644 (file)
@@ -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);
index 69e5335b7cef9d26d099c72c8bf45adadac0c483..db562eee49d6c581c8bb1e775f56da76484684f5 100644 (file)
@@ -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"
index b65a28aab69aae78a5189b5726ecaa74468b63b7..4e922bb716a734d21e94fd7b5f5f358a40d72c33 100644 (file)
@@ -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();