From c974742bf4d6d8fab1e1c90e2e57dae0a2f297a1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:57:03 +0200 Subject: udev: allow final assignments := The use of KEY:= will make the key unchangeable by later rules. Signed-off-by: Kay Sievers --- udev_rules.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'udev_rules.h') diff --git a/udev_rules.h b/udev_rules.h index 5fba2d5571..f4a74bba45 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -62,6 +62,7 @@ enum key_operation { KEY_OP_NOMATCH, KEY_OP_ADD, KEY_OP_ASSIGN, + KEY_OP_ASSIGN_FINAL, }; struct key_pair { @@ -96,10 +97,15 @@ struct udev_rule { char name[PATH_SIZE]; char symlink[PATH_SIZE]; + enum key_operation symlink_operation; char owner[USER_SIZE]; + enum key_operation owner_operation; char group[USER_SIZE]; + enum key_operation group_operation; mode_t mode; + enum key_operation mode_operation; char run[PATH_SIZE]; + enum key_operation run_operation; int last_rule; int ignore_device; -- cgit v1.2.3-54-g00ecf From c07669bd663d780e4957691e488798aa0178e76b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 15:55:29 +0200 Subject: udev: handle all events - not only class and block devices Handle all events with rules. If udev is expected to handle hotplug.d/ the exernal helper must be called. Signed-off-by: Kay Sievers --- Makefile | 2 +- extras/run_directory/udev_run_hotplugd.c | 3 - udev.8.in | 28 +---- udev.c | 155 ++++++++++-------------- udev.h | 9 +- udev.spec | 3 - udev_add.c | 16 --- udev_config.c | 6 - udev_multiplex.c | 92 --------------- udev_remove.c | 26 ++-- udev_rules.c | 196 ++++++++++++------------------- udev_rules.h | 3 +- udev_rules_parse.c | 8 +- udevstart.c | 24 +++- 14 files changed, 180 insertions(+), 391 deletions(-) delete mode 100644 udev_multiplex.c (limited to 'udev_rules.h') diff --git a/Makefile b/Makefile index 1cf3e54fb7..d36bd5866c 100644 --- a/Makefile +++ b/Makefile @@ -143,7 +143,6 @@ UDEV_OBJS = \ udev_remove.o \ udev_sysfs.o \ udev_db.o \ - udev_multiplex.o \ udev_rules.o \ udev_rules_parse.o \ udev_libc_wrapper.o @@ -382,6 +381,7 @@ install: install-config install-man install-dev.d all - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug ifndef DESTDIR - killall $(DAEMON) + - $(sbindir)/$(DAEMON) -d - rm -rf $(udevdb) endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ diff --git a/extras/run_directory/udev_run_hotplugd.c b/extras/run_directory/udev_run_hotplugd.c index 463473d7c7..54b6bf44e3 100644 --- a/extras/run_directory/udev_run_hotplugd.c +++ b/extras/run_directory/udev_run_hotplugd.c @@ -58,9 +58,6 @@ int main(int argc, char *argv[], char *envp[]) const char *subsystem; int fd; - if (getenv("DEVNAME") == NULL) - exit(0); - subsystem = argv[1]; logging_init("udev_run_hotplugd"); diff --git a/udev.8.in b/udev.8.in index 79c4a83d16..e4c1c11af2 100644 --- a/udev.8.in +++ b/udev.8.in @@ -306,11 +306,9 @@ following the '[' is a '!', any characters not enclosed are matched. .P After device node creation, removal, or network device renaming, .B udev -executes the programs located in the directory tree under -.IR /etc/dev.d/ . -The name of a program must have the suffix -.I .dev -to be recognized. +executes the programs specified by the +.B RUN +key. .br In addition to the kernel provided hotplug environment variables, .B UDEV_LOG @@ -319,15 +317,7 @@ is set and contains the numerical priority value, if udev is configured to use Executed programs may want to follow that setting. .B DEVNAME is exported to make the name of the created node, or the name the network -device is renamed to, available to the executed program. The programs in every -directory are sorted in lexical order, while the directories are searched in -the following order: -.sp -.nf -/etc/dev.d/$(DEVNAME)/*.dev -/etc/dev.d/$(SUBSYSTEM)/*.dev -/etc/dev.d/default/*.dev -.fi +device is renamed to, available to the executed programs. .SH "ENVIRONMENT" .P The following variables are read from the environment: @@ -353,20 +343,10 @@ Overrides the log priority specified in the config file. .TP .B UDEV_RUN If set to "0", it disables the execution of programs added by rules. -.TP -.B UDEV_NO_DEVD -The default behavior of -.B udev -is to execute programs in the -.I /etc/dev.d/ -directory after device handling. If set, -.B udev -will skip this step. .SH "FILES" .nf /sbin/udev udev program /etc/udev/* udev config files -/etc/dev.d/* programs invoked by udev .fi .SH "SEE ALSO" .BR udevinfo (8), diff --git a/udev.c b/udev.c index 3f76e98b24..d623cbcc67 100644 --- a/udev.c +++ b/udev.c @@ -54,39 +54,6 @@ void log_message(int priority, const char *format, ...) } #endif -/* Decide if we should manage the whole uevent, including multiplexing - * of the hotplug directories. - * For now look if the kernel calls udevsend instead of /sbin/hotplug, - * or the uevent-helper in /proc/sys/kernel/hotplug is empty. - */ -static int manage_hotplug_event(void) { - char helper[256]; - int fd; - int len; - - /* don't handle hotplug.d if we are called directly */ - if (!getenv("UDEVD_EVENT")) - return 0; - - fd = open("/proc/sys/kernel/hotplug", O_RDONLY); - if (fd < 0) - return 0; - - len = read(fd, helper, sizeof(helper)-1); - close(fd); - - if (len < 0) - return 0; - helper[len] = '\0'; - - if (helper[0] == '\0' || helper[0] == '\n') - return 1; - if (strstr(helper, "udevsend")) - return 1; - - return 0; -} - static void asmlinkage sig_handler(int signum) { switch (signum) { @@ -100,15 +67,12 @@ static void asmlinkage sig_handler(int signum) int main(int argc, char *argv[], char *envp[]) { - struct sysfs_class_device *class_dev; - struct sysfs_device *devices_dev; struct udevice udev; char path[PATH_SIZE]; const char *error; const char *action; const char *devpath; const char *subsystem; - int managed_event; struct sigaction act; int retval = -EINVAL; @@ -133,11 +97,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - /* let the executed programs know if we handle the whole hotplug event */ - managed_event = manage_hotplug_event(); - if (managed_event) - setenv("MANAGED_EVENT", "1", 1); - action = getenv("ACTION"); devpath = getenv("DEVPATH"); subsystem = getenv("SUBSYSTEM"); @@ -145,14 +104,12 @@ int main(int argc, char *argv[], char *envp[]) if (!subsystem && argc == 2) subsystem = argv[1]; - udev_init_device(&udev, devpath, subsystem, action); - if (!action || !subsystem || !devpath) { err("action, subsystem or devpath missing"); - goto hotplug; + goto exit; } - /* export logging flag, as called programs may want to do the same as udev */ + /* export log_level , as called programs may want to do the same as udev */ if (udev_log_priority) { char priority[32]; @@ -160,93 +117,109 @@ int main(int argc, char *argv[], char *envp[]) setenv("UDEV_LOG", priority, 1); } - if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { - udev_rules_init(); + udev_init_device(&udev, devpath, subsystem, action); + udev_rules_init(); + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { + /* handle device node */ if (strcmp(action, "add") == 0) { - /* wait for sysfs and possibly add node */ - dbg("udev add"); - - /* skip subsystems without "dev", but handle net devices */ - if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) { - dbg("don't care about '%s' devices", udev.subsystem); - goto hotplug; - } + struct sysfs_class_device *class_dev; + /* wait for sysfs of /sys/class /sys/block */ + dbg("node add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); path[sizeof(path)-1] = '\0'; class_dev = wait_class_device_open(path); if (class_dev == NULL) { dbg("open class device failed"); - goto hotplug; + goto run; } dbg("opened class_dev->name='%s'", class_dev->name); - wait_for_class_device(class_dev, &error); - /* name, create node, store in db */ - retval = udev_add_device(&udev, class_dev); - + /* get major/minor */ + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) { + udev.devt = get_devt(class_dev); + if (udev.devt) { + /* name device */ + udev_rules_get_name(&udev, class_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } + if (udev.name[0] == '\0') { + info("device node creation supressed"); + goto run; + } + + /* create node, store in db */ + retval = udev_add_device(&udev, class_dev); + } else { + dbg("no dev-file found"); + udev_rules_get_run(&udev, NULL); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } + } + } sysfs_close_class_device(class_dev); } else if (strcmp(action, "remove") == 0) { - /* possibly remove a node */ - dbg("udev remove"); - - /* skip subsystems without "dev" */ - if (subsystem_expect_no_dev(udev.subsystem)) { - dbg("don't care about '%s' devices", udev.subsystem); - goto hotplug; - } - - udev_rules_get_run(&udev); + dbg("node remove"); + udev_rules_get_run(&udev, NULL); if (udev.ignore_device) { dbg("device event will be ignored"); - goto hotplug; + goto exit; } - /* get node from db, remove db-entry, delete created node */ + /* get name from db, remove db-entry, delete node */ retval = udev_remove_device(&udev); } + /* export name of device node or netif */ if (udev.devname[0] != '\0') setenv("DEVNAME", udev.devname, 1); - - if (udev_run && !list_empty(&udev.run_list)) { - struct name_entry *name_loop; - - dbg("executing run list"); - list_for_each_entry(name_loop, &udev.run_list, node) - execute_command(name_loop->name, udev.subsystem); - } - } else if (udev.type == DEV_DEVICE) { if (strcmp(action, "add") == 0) { - /* wait for sysfs */ - dbg("devices add"); + struct sysfs_device *devices_dev; + /* wait for sysfs of /sys/devices/ */ + dbg("devices add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); path[sizeof(path)-1] = '\0'; devices_dev = wait_devices_device_open(path); if (!devices_dev) { dbg("devices device unavailable (probably remove has beaten us)"); - goto hotplug; + goto run; } dbg("devices device opened '%s'", path); - wait_for_devices_device(devices_dev, &error); - + udev_rules_get_run(&udev, devices_dev); sysfs_close_device(devices_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } } else if (strcmp(action, "remove") == 0) { dbg("devices remove"); + udev_rules_get_run(&udev, NULL); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } } - } else { - dbg("unhandled"); } -hotplug: - if (udev_hotplug_d && managed_event) - udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); +run: + if (udev_run && !list_empty(&udev.run_list)) { + struct name_entry *name_loop; + + dbg("executing run list"); + list_for_each_entry(name_loop, &udev.run_list, node) + execute_command(name_loop->name, udev.subsystem); + } +exit: udev_cleanup_device(&udev); logging_close(); diff --git a/udev.h b/udev.h index 2c3377ad2e..11fbe02460 100644 --- a/udev.h +++ b/udev.h @@ -39,12 +39,6 @@ #define SEQNUM_SIZE 32 #define VALUE_SIZE 128 -#define DEVD_DIR "/etc/dev.d" -#define DEVD_SUFFIX ".dev" - -#define HOTPLUGD_DIR "/etc/hotplug.d" -#define HOTPLUG_SUFFIX ".hotplug" - #define DEFAULT_PARTITIONS_COUNT 15 enum device_type { @@ -62,6 +56,7 @@ struct udevice { enum device_type type; char name[PATH_SIZE]; + int name_set; char devname[PATH_SIZE]; struct list_head symlink_list; int symlink_final; @@ -92,7 +87,6 @@ extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *clas extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); -extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix); extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); extern char sysfs_path[PATH_SIZE]; @@ -102,6 +96,5 @@ extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; extern int udev_log_priority; extern int udev_run; -extern int udev_hotplug_d; #endif diff --git a/udev.spec b/udev.spec index 28f19565da..0430a1259d 100644 --- a/udev.spec +++ b/udev.spec @@ -112,9 +112,6 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev*.8* -%attr(755,root,root) %dir /etc/dev.d/ -%attr(755,root,root) %dir /etc/dev.d/net/ -%attr(0755,root,root) /etc/dev.d/net/hotplug.dev %if %{scsi_id} %attr(755,root,root) /sbin/scsi_id diff --git a/udev_add.c b/udev_add.c index 9764cb9bcd..2081e503c7 100644 --- a/udev_add.c +++ b/udev_add.c @@ -268,22 +268,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) char *pos; int retval = 0; - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { - udev->devt = get_devt(class_dev); - if (!udev->devt) { - dbg("no dev-file found, do nothing"); - return 0; - } - } - - udev_rules_get_name(udev, class_dev); - if (udev->ignore_device) { - dbg("device event will be ignored"); - return 0; - } - dbg("adding name='%s'", udev->name); - selinux_init(); if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { @@ -325,6 +310,5 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) exit: selinux_exit(); - return retval; } diff --git a/udev_config.c b/udev_config.c index 0701d37e84..773ee67f9e 100644 --- a/udev_config.c +++ b/udev_config.c @@ -45,7 +45,6 @@ char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; int udev_log_priority; int udev_run; -int udev_hotplug_d; static int get_key(char **line, char **key, char **value) { @@ -187,7 +186,6 @@ void udev_init_config(void) strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; udev_run = 1; - udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); /* disable RUN key execution */ @@ -195,10 +193,6 @@ void udev_init_config(void) if (env && !string_is_true(env)) udev_run = 0; - env = getenv("UDEV_NO_HOTPLUGD"); - if (env && string_is_true(env)) - udev_hotplug_d = 0; - env = getenv("UDEV_CONFIG_FILE"); if (env) { strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); diff --git a/udev_multiplex.c b/udev_multiplex.c deleted file mode 100644 index 22bbaf7b61..0000000000 --- a/udev_multiplex.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * udev_multiplex.c directory multiplexer - * - * Copyright (C) 2004 Greg Kroah-Hartman - * - * 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. - */ - -/* - * This essentially emulates the following shell script logic in C: - * DIR="/etc/dev.d" - * export DEVNAME="whatever_dev_name_udev_just_gave" - * for I in "${DIR}/$DEVNAME/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do - * if [ -f $I ]; then $I $1 ; fi - * done - * exit 1; - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "udev.h" -#include "udev_libc_wrapper.h" -#include "udev_utils.h" -#include "logging.h" - - -/* - * runs files in these directories in order: - * / - * subsystem/ - * default/ - */ -void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) -{ - char dirname[PATH_SIZE]; - struct name_entry *name_loop, *name_tmp; - LIST_HEAD(name_list); - - /* chop the device name up into pieces based on '/' */ - if (udev->name[0] != '\0') { - char devname[PATH_SIZE]; - char *temp; - - strlcpy(devname, udev->name, sizeof(devname)); - temp = strchr(devname, '/'); - while (temp != NULL) { - temp[0] = '\0'; - - /* don't call the subsystem directory here */ - if (strcmp(devname, udev->subsystem) != 0) { - snprintf(dirname, sizeof(dirname), "%s/%s", basedir, devname); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - } - - temp[0] = '/'; - ++temp; - temp = strchr(temp, '/'); - } - } - - if (udev->name[0] != '\0') { - snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->name); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - } - - if (udev->subsystem[0] != '\0') { - snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->subsystem); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - } - - snprintf(dirname, sizeof(dirname), "%s/default", basedir); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - - list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { - execute_command(name_loop->name, udev->subsystem); - list_del(&name_loop->node); - } - -} diff --git a/udev_remove.c b/udev_remove.c index 2df555327b..cf28ff37a9 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -140,26 +140,20 @@ static int delete_node(struct udevice *udev) */ int udev_remove_device(struct udevice *udev) { - const char *temp; - if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS) return 0; - if (udev_db_get_device(udev, udev->devpath) == 0) { - if (udev->ignore_remove) { - dbg("remove event for '%s' requested to be ignored by rule", udev->name); - return 0; - } - dbg("remove name='%s'", udev->name); - udev_db_delete_device(udev); - } else { - /* fall back to kernel name */ - temp = strrchr(udev->devpath, '/'); - if (temp == NULL) - return -ENODEV; - strlcpy(udev->name, &temp[1], sizeof(udev->name)); - info("'%s' not found in database, falling back on default name", udev->name); + /* remove node only if we can find it in our database */ + if (udev_db_get_device(udev, udev->devpath) != 0) { + dbg("'%s' not found in database, ignore event", udev->name); + return -1; + } + if (udev->ignore_remove) { + dbg("remove event for '%s' requested to be ignored by rule", udev->name); + return 0; } + dbg("remove name='%s'", udev->name); + udev_db_delete_device(udev); /* use full path to the environment */ snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); diff --git a/udev_rules.c b/udev_rules.c index 631cc4270a..cbd76e66eb 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -731,7 +731,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d list_for_each_entry(rule, &udev_rule_list, node) { dbg("process rule"); if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { - if (udev->name[0] != '\0' && rule->name[0] != '\0') { + if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { dbg("node name already set, rule ignored"); continue; } @@ -776,73 +776,84 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d } /* collect symlinks */ - if (!udev->symlink_final && rule->symlink[0] != '\0') { + if (!udev->symlink_final && rule->symlink_operation != KEY_OP_UNSET) { char temp[PATH_SIZE]; char *pos, *next; if (rule->symlink_operation == KEY_OP_ASSIGN_FINAL) udev->symlink_final = 1; - else if (rule->symlink_operation == KEY_OP_ASSIGN) { + if (rule->symlink_operation == KEY_OP_ASSIGN || rule->symlink_operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; + info("reset symlink list"); list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { list_del(&name_loop->node); free(name_loop); } } - info("configured rule in '%s[%i]' applied, added symlink '%s'", - rule->config_file, rule->config_line, rule->symlink); - strlcpy(temp, rule->symlink, sizeof(temp)); - apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); - - /* add multiple symlinks separated by spaces */ - pos = temp; - next = strchr(temp, ' '); - while (next) { - next[0] = '\0'; + if (rule->symlink[0] != '\0') { + info("configured rule in '%s[%i]' applied, added symlink '%s'", + rule->config_file, rule->config_line, rule->symlink); + strlcpy(temp, rule->symlink, sizeof(temp)); + apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); + + /* add multiple symlinks separated by spaces */ + pos = temp; + next = strchr(temp, ' '); + while (next) { + next[0] = '\0'; + info("add symlink '%s'", pos); + name_list_add(&udev->symlink_list, pos, 0); + pos = &next[1]; + next = strchr(pos, ' '); + } info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); - pos = &next[1]; - next = strchr(pos, ' '); } - info("add symlink '%s'", pos); - name_list_add(&udev->symlink_list, pos, 0); } /* set name, later rules with name set will be ignored */ - if (rule->name[0] != '\0') { - info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", - rule->config_file, rule->config_line, udev->kernel_name, rule->name); - - strlcpy(udev->name, rule->name, sizeof(udev->name)); - apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - strlcpy(udev->config_file, rule->config_file, sizeof(udev->config_file)); - udev->config_line = rule->config_line; - - if (udev->type != DEV_NET) - dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i", - udev->name, udev->owner, udev->group, udev->mode, udev->partitions); + if (rule->name_operation != KEY_OP_UNSET) { + udev->name_set = 1; + if (rule->name[0] == '\0') { + info("configured rule in '%s[%i]' applied, node handling for '%s' supressed", + rule->config_file, rule->config_line, udev->kernel_name); + } else { + strlcpy(udev->name, rule->name, sizeof(udev->name)); + apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + strlcpy(udev->config_file, rule->config_file, sizeof(udev->config_file)); + udev->config_line = rule->config_line; + + info("configured rule in '%s:%i' applied, '%s' becomes '%s'", + rule->config_file, rule->config_line, udev->kernel_name, rule->name); + if (udev->type != DEV_NET) + dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i", + udev->name, udev->owner, udev->group, udev->mode, udev->partitions); + } } - if (!udev->run_final && rule->run[0] != '\0') { + if (!udev->run_final && rule->run_operation != KEY_OP_UNSET) { char program[PATH_SIZE]; if (rule->run_operation == KEY_OP_ASSIGN_FINAL) udev->run_final = 1; - else if (rule->run_operation == KEY_OP_ASSIGN) { + if (rule->run_operation == KEY_OP_ASSIGN || rule->run_operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; + info("reset run list"); list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { list_del(&name_loop->node); free(name_loop); } } - strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); + if (rule->run[0] != '\0') { + strlcpy(program, rule->run, sizeof(program)); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); + } } if (rule->last_rule) { @@ -866,113 +877,58 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d return 0; } -int udev_rules_get_run(struct udevice *udev) +int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) { struct udev_rule *rule; - char program[PATH_SIZE]; /* look for a matching rule to apply */ list_for_each_entry(rule, &udev_rule_list, node) { dbg("process rule"); - if (rule->run[0] == '\0') + if (rule->run_operation == KEY_OP_UNSET) continue; - if (rule->name[0] != '\0' || rule->symlink[0] != '\0' || + if (rule->name_operation != KEY_OP_UNSET || rule->symlink_operation != KEY_OP_UNSET || rule->mode != 0000 || rule->owner[0] != '\0' || rule->group[0] != '\0') { dbg("skip rule that names a device"); continue; } - if (rule->action_operation != KEY_OP_UNSET) { - dbg("check for " KEY_ACTION " rule->action='%s' udev->action='%s'", - rule->action, udev->action); - if (strcmp_pattern(rule->action, udev->action) != 0) { - dbg(KEY_ACTION " is not matching"); - if (rule->action_operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_ACTION " matches"); - if (rule->action_operation == KEY_OP_NOMATCH) - continue; - } - dbg(KEY_ACTION " key is true"); - } - - if (rule->kernel_operation != KEY_OP_UNSET) { - dbg("check for " KEY_KERNEL " rule->kernel='%s' udev->kernel_name='%s'", - rule->kernel, udev->kernel_name); - if (strcmp_pattern(rule->kernel, udev->kernel_name) != 0) { - dbg(KEY_KERNEL " is not matching"); - if (rule->kernel_operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_KERNEL " matches"); - if (rule->kernel_operation == KEY_OP_NOMATCH) - continue; - } - dbg(KEY_KERNEL " key is true"); - } - - if (rule->subsystem_operation != KEY_OP_UNSET) { - dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' udev->subsystem='%s'", - rule->subsystem, udev->subsystem); - if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { - dbg(KEY_SUBSYSTEM " is not matching"); - if (rule->subsystem_operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_SUBSYSTEM " matches"); - if (rule->subsystem_operation == KEY_OP_NOMATCH) - continue; + if (match_rule(udev, rule, NULL, sysfs_device) == 0) { + if (rule->ignore_device) { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + rule->config_file, rule->config_line, udev->kernel_name); + udev->ignore_device = 1; + return 0; } - dbg(KEY_SUBSYSTEM " key is true"); - } - if (rule->env_pair_count) { - int i; + if (!udev->run_final && rule->run_operation != KEY_OP_UNSET) { + char program[PATH_SIZE]; - dbg("check for " KEY_ENV " pairs"); - for (i = 0; i < rule->env_pair_count; i++) { - struct key_pair *pair; - const char *value; + if (rule->run_operation == KEY_OP_ASSIGN || rule->run_operation == KEY_OP_ASSIGN_FINAL) { + struct name_entry *name_loop; + struct name_entry *temp_loop; - pair = &rule->env_pair[i]; - value = getenv(pair->name); - if (!value) { - dbg(KEY_ENV "{'%s'} is not found", pair->name); - continue; + info("reset run list"); + list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { + list_del(&name_loop->node); + free(name_loop); + } } - if (strcmp_pattern(pair->value, value) != 0) { - dbg(KEY_ENV "{'%s'} is not matching", pair->name); - if (pair->operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_ENV "{'%s'} matches", pair->name); - if (pair->operation == KEY_OP_NOMATCH) - continue; + if (rule->run[0] != '\0') { + strlcpy(program, rule->run, sizeof(program)); + apply_format(udev, program, sizeof(program), NULL, NULL); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); } + if (rule->run_operation == KEY_OP_ASSIGN_FINAL) + break; } - dbg(KEY_ENV " key is true"); - } - - /* rule matches */ - - if (rule->ignore_device) { - info("configured rule in '%s[%i]' applied, '%s' is ignored", - rule->config_file, rule->config_line, udev->kernel_name); - udev->ignore_device = 1; - return 0; - } - - strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), NULL, NULL); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); - if (rule->last_rule) { - dbg("last rule to be applied"); - break; + if (rule->last_rule) { + dbg("last rule to be applied"); + break; + } } } diff --git a/udev_rules.h b/udev_rules.h index f4a74bba45..75ffd5cb0f 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -96,6 +96,7 @@ struct udev_rule { int env_pair_count; char name[PATH_SIZE]; + enum key_operation name_operation; char symlink[PATH_SIZE]; enum key_operation symlink_operation; char owner[USER_SIZE]; @@ -120,7 +121,7 @@ extern struct list_head udev_rule_list; extern int udev_rules_init(void); extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); -extern int udev_rules_get_run(struct udevice *udev); +extern int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device); extern void udev_rules_close(void); #endif diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 3f07521ccb..57c797dd31 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -349,21 +349,19 @@ static int rules_parse(const char *filename) if (strncasecmp(key, KEY_NAME, sizeof(KEY_NAME)-1) == 0) { attr = get_key_attribute(key + sizeof(KEY_NAME)-1); - /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { if (strstr(attr, OPTION_PARTITIONS) != NULL) { dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } + /* FIXME: remove old style option and make OPTIONS= mandatory */ if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; } } - if (value[0] != '\0') - strlcpy(rule.name, value, sizeof(rule.name)); - else - rule.ignore_device = 1; + rule.name_operation = operation; + strlcpy(rule.name, value, sizeof(rule.name)); valid = 1; continue; } diff --git a/udevstart.c b/udevstart.c index 34f3835d65..d1a0a8379c 100644 --- a/udevstart.c +++ b/udevstart.c @@ -37,6 +37,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" +#include "udev_sysfs.h" #include "udev.h" #include "udev_version.h" #include "logging.h" @@ -110,25 +111,37 @@ static int add_device(const char *path, const char *subsystem) const char *devpath; devpath = &path[strlen(sysfs_path)]; - - /* set environment for callouts and dev.d/ */ setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 1); - dbg("exec: '%s' (%s)\n", devpath, path); class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg ("sysfs_open_class_device_path failed"); - return -ENODEV; + return -1; } udev_init_device(&udev, devpath, subsystem, "add"); - udev_add_device(&udev, class_dev); + udev.devt = get_devt(class_dev); + if (!udev.devt) { + dbg ("sysfs_open_class_device_path failed"); + return -1; + } + udev_rules_get_name(&udev, class_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } + if (udev.name[0] == '\0') { + info("device node creation supressed"); + goto run; + } + udev_add_device(&udev, class_dev); if (udev.devname[0] != '\0') setenv("DEVNAME", udev.devname, 1); +run: if (udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; @@ -137,6 +150,7 @@ static int add_device(const char *path, const char *subsystem) execute_command(name_loop->name, udev.subsystem); } +exit: sysfs_close_class_device(class_dev); udev_cleanup_device(&udev); -- cgit v1.2.3-54-g00ecf From bf5d2964730e63316861e310d1f24c165b11e961 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 20 Jun 2005 00:29:38 +0200 Subject: prepare for module loading rules and add MODALIAS key Signed-off-by: Kay Sievers --- test/udev-test.pl | 51 ++++++++++++- udev_rules.c | 216 +++++++++++++++++++++++++++++++++++++++++------------ udev_rules.h | 6 ++ udev_rules_parse.c | 14 ++++ udev_sysfs.c | 54 +++++++------- 5 files changed, 262 insertions(+), 79 deletions(-) (limited to 'udev_rules.h') diff --git a/test/udev-test.pl b/test/udev-test.pl index 884abf9e8b..9225352130 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -241,7 +241,7 @@ BUS=="scsi", ID=="0:0:0:0", NAME="first_disk%n" EOF }, { - desc => "test NAME substitution chars", + desc => "test substitution chars", subsys => "block", devpath => "/block/sda/sda3", exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , @@ -250,7 +250,7 @@ BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" EOF }, { - desc => "test NAME substitution chars (with length limit)", + desc => "test substitution chars (with length limit)", subsys => "block", devpath => "/block/sda/sda3", exp_name => "M8-m3-n3-b0:0-sIBM" , @@ -360,6 +360,51 @@ EOF exp_name => "my-foo8" , rules => < "test substitution by variable name", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8-minor:3-kernelnumber:3-bus:0:0:0:0" , + rules => < "test substitution by variable name 2", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8-minor:3-kernelnumber:3-bus:0:0:0:0" , + rules => < "test substitution by variable name 3", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "830:0:0:03" , + rules => < "test substitution by variable name 4", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "833" , + rules => < "test substitution by variable name 5", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "8330:0:0:0" , + rules => < "yes", option => "clean", rules => <path, name); tmpattr = sysfs_get_classdev_attr(class_dev, name); if (tmpattr) goto attr_found; } if (sysfs_device) { + dbg("look for devices attribute '%s/%s'", sysfs_device->path, name); tmpattr = sysfs_get_device_attr(sysfs_device, name); if (tmpattr) goto attr_found; } - return -1; attr_found: @@ -197,56 +198,133 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { char temp[PATH_SIZE]; char temp2[PATH_SIZE]; - char *tail, *pos, *cpos, *attr, *rest; + char *head, *tail, *cpos, *attr, *rest; int len; int i; - char c; unsigned int next_free_number; struct sysfs_class_device *class_dev_parent; - - pos = string; + enum subst_type { + SUBST_UNKNOWN, + SUBST_DEVPATH, + SUBST_ID, + SUBST_KERNEL_NUMBER, + SUBST_KERNEL_NAME, + SUBST_MAJOR, + SUBST_MINOR, + SUBST_RESULT, + SUBST_SYSFS, + SUBST_ENUM, + SUBST_PARENT, + SUBST_TEMP_NODE, + SUBST_ROOT, + SUBST_MODALIAS, + }; + static const struct subst_map { + char *name; + char fmt; + enum subst_type type; + } map[] = { + { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH }, + { .name = "id", .fmt = 'b', .type = SUBST_ID }, + { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER }, + { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL_NAME }, + { .name = "major", .fmt = 'M', .type = SUBST_MAJOR }, + { .name = "minor", .fmt = 'm', .type = SUBST_MINOR }, + { .name = "result", .fmt = 'c', .type = SUBST_RESULT }, + { .name = "sysfs", .fmt = 's', .type = SUBST_SYSFS }, + { .name = "enum", .fmt = 'e', .type = SUBST_ENUM }, + { .name = "parent", .fmt = 'P', .type = SUBST_PARENT }, + { .name = "tempnode", .fmt = 'N', .type = SUBST_TEMP_NODE }, + { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, + { .name = "modalias", .fmt = 'A', .type = SUBST_MODALIAS }, + {} + }; + enum subst_type type; + const struct subst_map *subst; + + head = string; while (1) { - pos = strchr(pos, '%'); - if (pos == NULL) - break; - - pos[0] = '\0'; - tail = pos+1; - len = get_format_len(&tail); - c = tail[0]; - strlcpy(temp, tail+1, sizeof(temp)); - tail = temp; - dbg("format=%c, string='%s', tail='%s'",c , string, tail); + len = -1; + while (head[0] != '\0') { + if (head[0] == '$') { + /* substitute named variable */ + if (head[1] == '\0') + break; + if (head[1] == '$') { + strlcpy(temp, head+2, sizeof(temp)); + strlcpy(head+1, temp, maxsize); + head++; + continue; + } + head[0] = '\0'; + for (subst = map; subst->name; subst++) { + if (strncasecmp(&head[1], subst->name, strlen(subst->name)) == 0) { + type = subst->type; + tail = head + strlen(subst->name)+1; + dbg("will substitute format name '%s'", subst->name); + goto found; + } + } + } + else if (head[0] == '%') { + /* substitute format char */ + if (head[1] == '\0') + break; + if (head[1] == '%') { + strlcpy(temp, head+2, sizeof(temp)); + strlcpy(head+1, temp, maxsize); + head++; + continue; + } + head[0] = '\0'; + tail = head+1; + len = get_format_len(&tail); + for (subst = map; subst->name; subst++) { + if (tail[0] == subst->fmt) { + type = subst->type; + tail++; + dbg("will substitute format char '%c'", subst->fmt); + goto found; + } + } + } + head++; + } + break; +found: attr = get_format_attribute(&tail); + strlcpy(temp, tail, sizeof(temp)); + dbg("format=%i, string='%s', tail='%s', class_dev=%p, sysfs_dev=%p", + type ,string, tail, class_dev, sysfs_device); - switch (c) { - case 'p': + switch (type) { + case SUBST_DEVPATH: strlcat(string, udev->devpath, maxsize); - dbg("substitute kernel name '%s'", udev->kernel_name); + dbg("substitute devpath '%s'", udev->devpath); break; - case 'b': + case SUBST_ID: strlcat(string, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; - case 'k': + case SUBST_KERNEL_NAME: strlcat(string, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; - case 'n': + case SUBST_KERNEL_NUMBER: strlcat(string, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); - break; - case 'm': - sprintf(temp2, "%d", minor(udev->devt)); - strlcat(string, temp2, maxsize); - dbg("substitute minor number '%s'", temp2); break; - case 'M': + case SUBST_MAJOR: sprintf(temp2, "%d", major(udev->devt)); strlcat(string, temp2, maxsize); dbg("substitute major number '%s'", temp2); break; - case 'c': + case SUBST_MINOR: + sprintf(temp2, "%d", minor(udev->devt)); + strlcat(string, temp2, maxsize); + dbg("substitute minor number '%s'", temp2); + break; + case SUBST_RESULT: if (udev->program_result[0] == '\0') break; /* get part part of the result string */ @@ -280,7 +358,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute result string '%s'", udev->program_result); } break; - case 's': + case SUBST_SYSFS: if (attr == NULL) { dbg("missing attribute"); break; @@ -307,18 +385,14 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strlcat(string, temp2, maxsize); dbg("substitute sysfs value '%s'", temp2); break; - case '%': - strlcat(string, "%", maxsize); - pos++; - break; - case 'e': + case SUBST_ENUM: next_free_number = find_free_number(udev, string); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strlcat(string, temp2, maxsize); } break; - case 'P': + case SUBST_PARENT: if (!class_dev) break; class_dev_parent = sysfs_get_classdev_parent(class_dev); @@ -336,7 +410,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, udev_cleanup_device(&udev_parent); } break; - case 'N': + case SUBST_TEMP_NODE: if (udev->tmp_node[0] == '\0') { dbg("create temporary device node for callout"); snprintf(udev->tmp_node, sizeof(udev->tmp_node), "%s/.tmp-%u-%u", @@ -347,19 +421,27 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strlcat(string, udev->tmp_node, maxsize); dbg("substitute temporary device node name '%s'", udev->tmp_node); break; - case 'r': + case SUBST_ROOT: strlcat(string, udev_root, maxsize); dbg("substitute udev_root '%s'", udev_root); break; + case SUBST_MODALIAS: + if (find_sysfs_attribute(NULL, sysfs_device, "modalias", temp2, sizeof(temp2)) != 0) + break; + strlcat(string, temp2, maxsize); + dbg("substitute MODALIAS '%s'", temp2); + break; default: - err("unknown substitution type '%%%c'", c); + err("unknown substitution type=%i", type); break; } - /* truncate to specified length */ - if (len > 0) - pos[len] = '\0'; + /* possibly truncate to format-char specified length */ + if (len != -1) { + head[len] = '\0'; + dbg("truncate to %i chars, subtitution string becomes '%s'", len, head); + } - strlcat(string, tail, maxsize); + strlcat(string, temp, maxsize); } } @@ -519,6 +601,42 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg(KEY_SUBSYSTEM " key is true"); } + if (rule->devpath_operation != KEY_OP_UNSET) { + dbg("check for " KEY_DEVPATH " rule->devpath='%s' udev->devpath='%s'", + rule->devpath, udev->devpath); + if (strcmp_pattern(rule->devpath, udev->devpath) != 0) { + dbg(KEY_DEVPATH " is not matching"); + if (rule->devpath_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_DEVPATH " matches"); + if (rule->devpath_operation == KEY_OP_NOMATCH) + goto exit; + } + dbg(KEY_DEVPATH " key is true"); + } + + if (rule->modalias_operation != KEY_OP_UNSET) { + char value[NAME_SIZE]; + + if (find_sysfs_attribute(NULL, sysfs_device, "modalias", value, sizeof(value)) != 0) { + dbg(KEY_MODALIAS " value not found"); + goto exit; + } + dbg("check for " KEY_MODALIAS " rule->modalias='%s' modalias='%s'", + rule->modalias, value); + if (strcmp_pattern(rule->modalias, value) != 0) { + dbg(KEY_MODALIAS " is not matching"); + if (rule->modalias_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_MODALIAS " matches"); + if (rule->modalias_operation == KEY_OP_NOMATCH) + goto exit; + } + dbg(KEY_MODALIAS " key is true"); + } + if (rule->env_pair_count) { int i; @@ -729,13 +847,13 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d /* look for a matching rule to apply */ list_for_each_entry(rule, &udev_rule_list, node) { + if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { + dbg("node name already set, rule ignored"); + continue; + } + dbg("process rule"); if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { - if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { - dbg("node name already set, rule ignored"); - continue; - } - /* apply options */ if (rule->ignore_device) { info("configured rule in '%s[%i]' applied, '%s' is ignored", @@ -917,7 +1035,7 @@ int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) } if (rule->run[0] != '\0') { strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), NULL, NULL); + apply_format(udev, program, sizeof(program), NULL, sysfs_device); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); } diff --git a/udev_rules.h b/udev_rules.h index 75ffd5cb0f..2bf8107543 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -31,6 +31,7 @@ #define KEY_KERNEL "KERNEL" #define KEY_SUBSYSTEM "SUBSYSTEM" #define KEY_ACTION "ACTION" +#define KEY_DEVPATH "DEVPATH" #define KEY_BUS "BUS" #define KEY_ID "ID" #define KEY_PROGRAM "PROGRAM" @@ -38,6 +39,7 @@ #define KEY_DRIVER "DRIVER" #define KEY_SYSFS "SYSFS" #define KEY_ENV "ENV" +#define KEY_MODALIAS "MODALIAS" #define KEY_NAME "NAME" #define KEY_SYMLINK "SYMLINK" #define KEY_OWNER "OWNER" @@ -80,6 +82,8 @@ struct udev_rule { enum key_operation subsystem_operation; char action[NAME_SIZE]; enum key_operation action_operation; + char devpath[PATH_SIZE]; + enum key_operation devpath_operation; char bus[NAME_SIZE]; enum key_operation bus_operation; char id[NAME_SIZE]; @@ -94,6 +98,8 @@ struct udev_rule { int sysfs_pair_count; struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; int env_pair_count; + enum key_operation modalias_operation; + char modalias[PATH_SIZE]; char name[PATH_SIZE]; enum key_operation name_operation; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 57c797dd31..89925a35e4 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -269,6 +269,13 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_DEVPATH) == 0) { + strlcpy(rule.devpath, value, sizeof(rule.devpath)); + rule.devpath_operation = operation; + valid = 1; + continue; + } + if (strcasecmp(key, KEY_BUS) == 0) { strlcpy(rule.bus, value, sizeof(rule.bus)); rule.bus_operation = operation; @@ -325,6 +332,13 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_MODALIAS) == 0) { + strlcpy(rule.modalias, value, sizeof(rule.modalias)); + rule.modalias_operation = operation; + valid = 1; + continue; + } + if (strcasecmp(key, KEY_DRIVER) == 0) { strlcpy(rule.driver, value, sizeof(rule.driver)); rule.driver_operation = operation; diff --git a/udev_sysfs.c b/udev_sysfs.c index f9ff1ed2f9..5c43190644 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -297,38 +297,38 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, { .bus = "usb", .file = "bNumEndpoints" }, - { .bus = "usb-serial", .file = "detach_state" }, - { .bus = "ide", .file = "detach_state" }, + { .bus = "usb-serial", .file = "power" }, + { .bus = "ide", .file = "power" }, { .bus = "pci", .file = "vendor" }, - { .bus = "platform", .file = "detach_state" }, - { .bus = "pcmcia", .file = "detach_state" }, - { .bus = "i2c", .file = "detach_state" }, + { .bus = "platform", .file = "power" }, + { .bus = "pcmcia", .file = "power" }, + { .bus = "i2c", .file = "power" }, { .bus = "ieee1394", .file = "node_count" }, { .bus = "ieee1394", .file = "nodeid" }, { .bus = "ieee1394", .file = "address" }, { .bus = "bttv-sub", .file = NULL }, - { .bus = "pnp", .file = "detach_state" }, - { .bus = "eisa", .file = "detach_state" }, - { .bus = "serio", .file = "detach_state" }, - { .bus = "pseudo", .file = "detach_state" }, - { .bus = "mmc", .file = "detach_state" }, - { .bus = "macio", .file = "detach_state" }, - { .bus = "of_platform", .file = "detach_state" }, - { .bus = "vio", .file = "detach_state" }, - { .bus = "ecard", .file = "detach_state" }, - { .bus = "sa1111-rab", .file = "detach_state" }, - { .bus = "amba", .file = "detach_state" }, - { .bus = "locomo-bus", .file = "detach_state" }, - { .bus = "logicmodule", .file = "detach_state" }, - { .bus = "parisc", .file = "detach_state" }, - { .bus = "ocp", .file = "detach_state" }, - { .bus = "dio", .file = "detach_state" }, - { .bus = "MCA", .file = "detach_state" }, - { .bus = "wl", .file = "detach_state" }, - { .bus = "ccwgroup", .file = "detach_state" }, - { .bus = "css", .file = "detach_state" }, - { .bus = "ccw", .file = "detach_state" }, - { .bus = "iucv", .file = "detach_state" }, + { .bus = "pnp", .file = "power" }, + { .bus = "eisa", .file = "power" }, + { .bus = "serio", .file = "power" }, + { .bus = "pseudo", .file = "power" }, + { .bus = "mmc", .file = "power" }, + { .bus = "macio", .file = "power" }, + { .bus = "of_platform", .file = "power" }, + { .bus = "vio", .file = "power" }, + { .bus = "ecard", .file = "power" }, + { .bus = "sa1111-rab", .file = "power" }, + { .bus = "amba", .file = "power" }, + { .bus = "locomo-bus", .file = "power" }, + { .bus = "logicmodule", .file = "power" }, + { .bus = "parisc", .file = "power" }, + { .bus = "ocp", .file = "power" }, + { .bus = "dio", .file = "power" }, + { .bus = "MCA", .file = "power" }, + { .bus = "wl", .file = "power" }, + { .bus = "ccwgroup", .file = "power" }, + { .bus = "css", .file = "power" }, + { .bus = "ccw", .file = "power" }, + { .bus = "iucv", .file = "power" }, { NULL, NULL } }; const struct device_file *devicefile = NULL; -- cgit v1.2.3-54-g00ecf