diff options
author | Kay Sievers <kay.sievers@suse.de> | 2005-06-05 05:11:29 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@suse.de> | 2005-06-05 05:11:29 +0200 |
commit | 6a522681e1438bbd9c317654cc35d5d206d378ad (patch) | |
tree | 8a580e47fcd69bd32c9cfb354c5e74e777519300 | |
parent | c974742bf4d6d8fab1e1c90e2e57dae0a2f297a1 (diff) |
udev: move dev.d/ handling to external helper
Modern rules are expected to call notification and postprocessing with
the RUN key. For compatibility the current behavior can be emulated
with an external helper.
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
-rw-r--r-- | etc/udev/udev.rules | 51 | ||||
-rw-r--r-- | etc/udev/udev.rules.examples | 63 | ||||
-rw-r--r-- | extras/run_directory/Makefile | 55 | ||||
-rw-r--r-- | extras/run_directory/run_directory.c | 79 | ||||
-rw-r--r-- | extras/run_directory/udev_run_devd.c | 78 | ||||
-rw-r--r-- | extras/run_directory/udev_run_hotplugd.c | 79 | ||||
-rw-r--r-- | test/simple-build-check.sh | 2 | ||||
-rw-r--r-- | udev.c | 4 | ||||
-rw-r--r-- | udev.h | 1 | ||||
-rw-r--r-- | udev_config.c | 37 | ||||
-rw-r--r-- | udev_utils.c | 32 | ||||
-rw-r--r-- | udev_utils.h | 2 | ||||
-rw-r--r-- | udevstart.c | 4 |
13 files changed, 378 insertions, 109 deletions
diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index bc8c8bdd6c..bebf74802f 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -5,43 +5,42 @@ # # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" - -# create a symlink named after the device map name -# note devmap_name comes with extras/multipath -KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" +BUS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK+="cdrom" # DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL="card*", NAME="dri/card%n" +KERNEL=="card*", NAME="dri/card%n" # alsa devices -KERNEL="controlC[0-9]*", NAME="snd/%k" -KERNEL="hw[CD0-9]*", NAME="snd/%k" -KERNEL="pcm[CD0-9cp]*", NAME="snd/%k" -KERNEL="midiC[D0-9]*", NAME="snd/%k" -KERNEL="timer", NAME="snd/%k" -KERNEL="seq", NAME="snd/%k" +KERNEL=="controlC[0-9]*", NAME="snd/%k" +KERNEL=="hw[CD0-9]*", NAME="snd/%k" +KERNEL=="pcm[CD0-9cp]*", NAME="snd/%k" +KERNEL=="midiC[D0-9]*", NAME="snd/%k" +KERNEL=="timer", NAME="snd/%k" +KERNEL=="seq", NAME="snd/%k" # input devices -KERNEL="mice", NAME="input/%k" -KERNEL="mouse*", NAME="input/%k" -KERNEL="event*", NAME="input/%k" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +KERNEL=="mice", NAME="input/%k" +KERNEL=="mouse*", NAME="input/%k" +KERNEL=="event*", NAME="input/%k" +KERNEL=="js*", NAME="input/%k" +KERNEL=="ts*", NAME="input/%k" # USB devices -KERNEL="hiddev*", NAME="usb/%k" -KERNEL="auer*", NAME="usb/%k" -KERNEL="legousbtower*", NAME="usb/%k" -KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +KERNEL=="hiddev*", NAME="usb/%k" +KERNEL=="auer*", NAME="usb/%k" +KERNEL=="legousbtower*", NAME="usb/%k" +KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" # CAPI devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi*", NAME="capi/%n" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi*", NAME="capi/%n" # Network devices -KERNEL="tun", NAME="net/%k" +KERNEL=="tun", NAME="net/%k" # raw devices -KERNEL="raw[0-9]*", NAME="raw/%k" +KERNEL=="raw[0-9]*", NAME="raw/%k" + +# emulate dev.d/ +RUN="/sbin/udev_run_devd" diff --git a/etc/udev/udev.rules.examples b/etc/udev/udev.rules.examples index a464b6ba57..1c4527891a 100644 --- a/etc/udev/udev.rules.examples +++ b/etc/udev/udev.rules.examples @@ -9,64 +9,55 @@ # # Looking for scsi bus id 42:0:0:1 -BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" +BUS=="scsi", PROGRAM="/bin/echo -n test-%b", RESULT=="test-42:0:0:1", NAME="%c" # A usb camera. -BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" +BUS=="usb", SYSFS{vendor}=="FUJIFILM", SYSFS{model}=="M100", NAME="camera%n" # USB Epson printer to be called lp_epson -BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" +BUS=="usb", SYSFS_serial=="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" +BUS=="usb", SYSFS{serial}=="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card -BUS="pci", ID="00:0b.0", NAME="dsp" +BUS=="pci", ID=="00:0b.0", NAME="dsp" # sound card with PCI bus id 00:07.1 to be the second sound card -BUS="pci", ID="00:07.1", NAME="dsp1" - -# USB mouse plugged into the third port of the first hub to be called mouse0 -BUS="usb", PLACE="1.3", NAME="mouse0" - -# USB tablet plugged into the third port of the second hub to be called mouse1 -BUS="usb", PLACE="2.3", NAME="mouse1" -BUS="usb", PLACE="2.4", NAME="mouse2" +BUS=="pci", ID=="00:07.1", NAME="dsp1" # ttyUSB1 should always be called visor -KERNEL="ttyUSB1", NAME="visor" -KERNEL="ttyUSB0", NAME="pl2303" +KERNEL=="ttyUSB1", NAME="visor" +KERNEL=="ttyUSB0", NAME="pl2303" # a devfs like way to name some tty devices -KERNEL="ttyS*", NAME="tts/%n" -KERNEL="tty*", NAME="vc/%n" +KERNEL=="ttyS*", NAME="tts/%n" +KERNEL=="tty*", NAME="vc/%n" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" - -# create a symlink named after the device map name -# note devmap_name comes with extras/multipath -KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" +BUS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", NAME="%k", SYMLINK+="cdrom" # DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL="card*", NAME="dri/card%n" +KERNEL=="card*", NAME="dri/card%n" # create all 15 partitions of a USB flash card reader -# note the trailing spaces in the attribute, use udevinfo(8) to examine your device -BUS="scsi", SYSFS{model}="CF/MD ", NAME{all_partitions}="compactflash" +BUS=="scsi", SYSFS{model}=="CF/MD", NAME{all_partitions}="compactflash" # alsa devices -KERNEL="controlC[0-9]*", NAME="snd/%k" -KERNEL="hw[CD0-9]*", NAME="snd/%k" -KERNEL="pcm[CD0-9cp]*", NAME="snd/%k" -KERNEL="midi[CD0-9]*", NAME="snd/%k" -KERNEL="timer", NAME="snd/%k" -KERNEL="seq", NAME="snd/%k" +KERNEL=="controlC[0-9]*", NAME="snd/%k" +KERNEL=="hw[CD0-9]*", NAME="snd/%k" +KERNEL=="pcm[CD0-9cp]*", NAME="snd/%k" +KERNEL=="midi[CD0-9]*", NAME="snd/%k" +KERNEL=="timer", NAME="snd/%k" +KERNEL=="seq", NAME="snd/%k" # input devices -KERNEL="mice", NAME="input/%k" -KERNEL="mouse*", NAME="input/%k" -KERNEL="event*", NAME="input/%k" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +KERNEL=="mice", NAME="input/%k" +KERNEL=="mouse*", NAME="input/%k" +KERNEL=="event*", NAME="input/%k" +KERNEL=="js*", NAME="input/%k" +KERNEL=="ts*", NAME="input/%k" + +# emulate dev.d/ +RUN="/sbin/udev_run_devd" diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile new file mode 100644 index 0000000000..12dccf0749 --- /dev/null +++ b/extras/run_directory/Makefile @@ -0,0 +1,55 @@ +# Makefile for udev_volume_id +# +# Copyright (C) 2004 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 +# the Free Software Foundation; version 2 of the License. +# + +DEVD = udev_run_devd +HOTPLUGD = udev_run_hotplugd + +all: $(DEVD) $(HOTPLUGD) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +override CFLAGS+=-D_FILE_OFFSET_BITS=64 + +OBJS = ../../udev.a ../../libsysfs/sysfs.a + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(DEVD): $(HEADERS) $(DEVD).o run_directory.o + $(QUIET) $(LD) $(LDFLAGS) -o $(DEVD) $(DEVD).o run_directory.o $(OBJS) + +$(HOTPLUGD): $(HEADERS) $(HOTPLUGD).o run_directory.o + $(QUIET) $(LD) $(LDFLAGS) -o $(HOTPLUGD) $(HOTPLUGD).o run_directory.o $(OBJS) + +clean: + rm -f $(DEVD) $(HOTPLUGD) run_directory.o + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(DEVD) $(DESTDIR)$(sbindir)/$(DEVD) + $(INSTALL_PROGRAM) $(HOTPLUGD) $(DESTDIR)$(sbindir)/$(HOTPLUGD) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(DEVD) diff --git a/extras/run_directory/run_directory.c b/extras/run_directory/run_directory.c new file mode 100644 index 0000000000..e6c6173eca --- /dev/null +++ b/extras/run_directory/run_directory.c @@ -0,0 +1,79 @@ +/* + * udev_run_directory.c - directory multiplexer + * + * Copyright (C) 2005 Kay Sievers <kay@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 the + * Free Software Foundation version 2 of the License. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stddef.h> +#include <dirent.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#include "../../udev_utils.h" +#include "../../list.h" +#include "../../logging.h" + +int run_directory(const char *dir, const char *suffix, const char *subsystem); + +static int run_program(const char *filename, const char *subsystem) +{ + pid_t pid; + + dbg("running %s", filename); + pid = fork(); + switch (pid) { + case 0: + /* child */ + execl(filename, filename, subsystem, NULL); + dbg("exec of child failed"); + _exit(1); + case -1: + dbg("fork of child failed"); + break; + return -1; + default: + waitpid(pid, NULL, 0); + } + + return 0; +} + +int run_directory(const char *dir, const char *suffix, const char *subsystem) +{ + char dirname[NAME_SIZE]; + struct name_entry *name_loop, *name_tmp; + LIST_HEAD(name_list); + + if (subsystem) { + snprintf(dirname, sizeof(dirname), "%s/%s", dir, subsystem); + dirname[sizeof(dirname)-1] = '\0'; + dbg("looking at '%s'", dirname); + add_matching_files(&name_list, dirname, suffix); + } + + snprintf(dirname, sizeof(dirname), "%s/default", dir); + dirname[sizeof(dirname)-1] = '\0'; + dbg("looking at '%s'", dirname); + add_matching_files(&name_list, dirname, suffix); + + list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { + run_program(name_loop->name, subsystem); + list_del(&name_loop->node); + } + + logging_close(); + return 0; +} diff --git a/extras/run_directory/udev_run_devd.c b/extras/run_directory/udev_run_devd.c new file mode 100644 index 0000000000..02bbc8c353 --- /dev/null +++ b/extras/run_directory/udev_run_devd.c @@ -0,0 +1,78 @@ +/* + * udev_run_devd.c - directory multiplexer + * + * Copyright (C) 2005 Kay Sievers <kay@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 the + * Free Software Foundation version 2 of the License. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stddef.h> +#include <dirent.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#include "../../udev_utils.h" +#include "../../list.h" +#include "../../logging.h" + +extern int run_directory(const char *dir, const char *suffix, const char *subsystem); + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + static int udev_log = -1; + + if (udev_log == -1) { + const char *value; + + value = getenv("UDEV_LOG"); + if (value) + udev_log = log_priority(value); + else + udev_log = LOG_ERR; + } + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +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_devd"); + + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + } + dbg("running dev.d directory"); + + run_directory("/etc/dev.d", ".dev", subsystem); + exit(0); +} diff --git a/extras/run_directory/udev_run_hotplugd.c b/extras/run_directory/udev_run_hotplugd.c new file mode 100644 index 0000000000..463473d7c7 --- /dev/null +++ b/extras/run_directory/udev_run_hotplugd.c @@ -0,0 +1,79 @@ +/* + * udev_run_hotplugd.c - directory multiplexer + * + * Copyright (C) 2005 Kay Sievers <kay@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 the + * Free Software Foundation version 2 of the License. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stddef.h> +#include <dirent.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#include "../../udev_utils.h" +#include "../../list.h" +#include "../../logging.h" + +extern int run_directory(const char *dir, const char *suffix, const char *subsystem); + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + static int udev_log = -1; + + if (udev_log == -1) { + const char *value; + + value = getenv("UDEV_LOG"); + if (value) + udev_log = log_priority(value); + else + udev_log = LOG_ERR; + } + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +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"); + + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + } + + dbg("running dev.d directory"); + + run_directory("/etc/hotplug.d", ".hotplug", subsystem); + exit(0); +} diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index d1e13e69ed..b653185b26 100644 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -1,6 +1,6 @@ #/bin/sh -EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id" +EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id extras/run_directory" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build echo KERNEL_DIR: "$KERNEL_DIR" @@ -219,10 +219,6 @@ int main(int argc, char *argv[], char *envp[]) execute_command(name_loop->name, udev.subsystem); } - /* run dev.d/ scripts if we created/deleted a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - } else if (udev.type == DEV_DEVICE) { if (strcmp(action, "add") == 0) { /* wait for sysfs */ @@ -102,7 +102,6 @@ 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_dev_d; extern int udev_hotplug_d; #endif diff --git a/udev_config.c b/udev_config.c index 6bc070d63a..0701d37e84 100644 --- a/udev_config.c +++ b/udev_config.c @@ -45,40 +45,8 @@ char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; int udev_log_priority; int udev_run; -int udev_dev_d; int udev_hotplug_d; -static int string_is_true(const char *str) -{ - if (strcasecmp(str, "true") == 0) - return 1; - if (strcasecmp(str, "yes") == 0) - return 1; - if (strcasecmp(str, "1") == 0) - return 1; - return 0; -} - -static int log_priority(const char *priority) -{ - char *endptr; - int prio; - - prio = strtol(priority, &endptr, 10); - if (endptr[0] == '\0') - return prio; - if (strncasecmp(priority, "err", 3) == 0) - return LOG_ERR; - if (strcasecmp(priority, "info") == 0) - return LOG_INFO; - if (strcasecmp(priority, "debug") == 0) - return LOG_DEBUG; - if (string_is_true(priority)) - return LOG_ERR; - - return 0; -} - static int get_key(char **line, char **key, char **value) { char *linepos; @@ -219,7 +187,6 @@ void udev_init_config(void) strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; udev_run = 1; - udev_dev_d = 1; udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); @@ -228,10 +195,6 @@ void udev_init_config(void) if (env && !string_is_true(env)) udev_run = 0; - env = getenv("UDEV_NO_DEVD"); - if (env && string_is_true(env)) - udev_dev_d = 0; - env = getenv("UDEV_NO_HOTPLUGD"); if (env && string_is_true(env)) udev_hotplug_d = 0; diff --git a/udev_utils.c b/udev_utils.c index 74b55ed406..70b20e3a28 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -27,6 +27,7 @@ #include <errno.h> #include <ctype.h> #include <dirent.h> +#include <syslog.h> #include <sys/wait.h> #include <sys/stat.h> #include <sys/mman.h> @@ -109,6 +110,37 @@ void udev_cleanup_device(struct udevice *udev) } } +int string_is_true(const char *str) +{ + if (strcasecmp(str, "true") == 0) + return 1; + if (strcasecmp(str, "yes") == 0) + return 1; + if (strcasecmp(str, "1") == 0) + return 1; + return 0; +} + +int log_priority(const char *priority) +{ + char *endptr; + int prio; + + prio = strtol(priority, &endptr, 10); + if (endptr[0] == '\0') + return prio; + if (strncasecmp(priority, "err", 3) == 0) + return LOG_ERR; + if (strcasecmp(priority, "info") == 0) + return LOG_INFO; + if (strcasecmp(priority, "debug") == 0) + return LOG_DEBUG; + if (string_is_true(priority)) + return LOG_ERR; + + return 0; +} + int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel) { static unsigned int kversion = 0; diff --git a/udev_utils.h b/udev_utils.h index 9cdae6db57..b3e604fb98 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -34,6 +34,8 @@ extern void udev_cleanup_device(struct udevice *udev); extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); +extern int log_priority(const char *priority); +extern int string_is_true(const char *str); extern int parse_get_pair(char **orig_string, char **left, char **right); extern int unlink_secure(const char *filename); extern int file_map(const char *filename, char **buf, size_t *bufsize); diff --git a/udevstart.c b/udevstart.c index 60e63c5ad8..34f3835d65 100644 --- a/udevstart.c +++ b/udevstart.c @@ -137,10 +137,6 @@ static int add_device(const char *path, const char *subsystem) execute_command(name_loop->name, udev.subsystem); } - /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - sysfs_close_class_device(class_dev); udev_cleanup_device(&udev); |