diff options
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | RELEASE-NOTES | 11 | ||||
-rw-r--r-- | etc/udev/udev.conf.in | 14 | ||||
-rw-r--r-- | logging.h | 13 | ||||
-rw-r--r-- | udev.8.in | 45 | ||||
-rw-r--r-- | udev.c | 24 | ||||
-rw-r--r-- | udev.h | 2 | ||||
-rw-r--r-- | udev_add.c | 6 | ||||
-rw-r--r-- | udev_config.c | 102 | ||||
-rw-r--r-- | udev_db.c | 12 | ||||
-rw-r--r-- | udev_remove.c | 2 | ||||
-rw-r--r-- | udev_rules.c | 24 | ||||
-rw-r--r-- | udev_rules_parse.c | 21 | ||||
-rw-r--r-- | udevd.8 | 2 | ||||
-rw-r--r-- | udevd.c | 52 | ||||
-rw-r--r-- | udevinfo.c | 7 | ||||
-rw-r--r-- | udevsend.c | 32 | ||||
-rw-r--r-- | udevstart.c | 17 | ||||
-rw-r--r-- | udevtest.8 | 2 | ||||
-rw-r--r-- | udevtest.c | 12 |
20 files changed, 233 insertions, 176 deletions
@@ -17,16 +17,18 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Set this to make use of syslog +# Set this to make use of syslog. USE_LOG = true -# Set this to ad development debug messages +# Set this to compile-in development debug messages. Pass UDEV_LOG="debug" +# to the executed binary or set the value in the udev configuration file to +# let udev print the debug messages to syslog. DEBUG = false # Set this to include Security-Enhanced Linux support. USE_SELINUX = false -# Set this to comile with the local version of klibc instead of glibc. +# Set this to comile with klibc instead of glibc. USE_KLIBC = false # Set this to create statically linked binaries. @@ -249,7 +251,6 @@ udev_version.h: @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ - @echo \#define UDEV_LOG_DEFAULT \"yes\" >> $@ @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 2defd7117b..17d6097abf 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,14 @@ +udev 057 +======== +We support log priority levels now. The value udev_log in udev.conf is used +to determine what is printed to syslog. This makes it possible to +run a version with compiled-in debug messages in a production environment +which is sometimes needed to find a bug. +It is still possible to supress the inclusion of _any_ syslog usage with +USE_LOG=false to create the smallest possible binaries if needed. +The configured udev_log value can be overridden with the environment variable +UDEV_LOG. + udev 056 ======== Possible use of a system-wide klibc: diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 72e25ed482..9d5300a861 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -1,19 +1,15 @@ # udev.conf -# The main config file for udev # -# This file can be used to override some of udev's default values -# for where it looks for files, and where it places device nodes. - -# udev_root - where in the filesystem to place the device nodes +# Where in the filesystem to place the device nodes udev_root="@udevdir@" -# udev_db - The name and location of the udev database. +# The name and location of the udev database. udev_db="@udevdir@/.udevdb" -# udev_rules - The name and location of the udev rules file +# The name and location of the udev rules file(s). udev_rules="@configdir@/rules.d" -# udev_log - set to "yes" if you want logging, else "no" -udev_log="yes" +# The syslog(3) priority: "err", "info", or the numerical value. +udev_log="err" @@ -24,6 +24,7 @@ #ifndef LOGGING_H #define LOGGING_H +#define err(format, arg...) do { } while (0) #define info(format, arg...) do { } while (0) #define dbg(format, arg...) do { } while (0) #define logging_init(foo) do { } while (0) @@ -34,21 +35,27 @@ #include <unistd.h> #include <syslog.h> +#undef err +#define err(format, arg...) \ + do { \ + log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \ + } while (0) + #undef info #define info(format, arg...) \ do { \ - log_message(LOG_INFO , format , ## arg); \ + log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \ } while (0) #ifdef DEBUG #undef dbg #define dbg(format, arg...) \ do { \ - log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + log_message(LOG_DEBUG ,"%s: " format ,__FUNCTION__ ,## arg); \ } while (0) #endif -extern void log_message(int level, const char *format, ...) +extern void log_message(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3))); #undef logging_init @@ -2,7 +2,7 @@ .SH NAME udev \- Linux configurable dynamic device naming support .SH SYNOPSIS -.BI udev " hotplug-subsystem" +.BI udev .SH "DESCRIPTION" .B udev provides a dynamic device directory containing only the files for actually @@ -56,25 +56,28 @@ All rule files are read in lexical order. The default value is .IR /etc/udev/rules.d/ . .TP .B udev_log -The switch to enable/disable logging of udev information +The logging priority which can be set to +.IR "err " , "info " +or the corresponding numerical +.BR syslog (3) +value. The default value is -.IR yes . +.IR err . .P .RI "A sample " udev.conf " file might look like this: .sp .nf -# udev_root - where to place the device nodes in the filesystem -udev_root="/udev" +# Where in the filesystem to place the device nodes +udev_root="@udevdir@" -# udev_db - The name and location of the udev database -udev_db="/udev/.udevdb" +# The name and location of the udev database. +udev_db="@udevdir@/.udevdb" -# udev_rules - The name of the udev rules file or directory to look - for files with the suffix .rules -udev_rules="/etc/udev/rules.d/" +# The name and location of the udev rules file(s). +udev_rules="@configdir@/rules.d" -# udev_log - set to "yes" if you want logging, else "no" -udev_log="yes" +# The syslog(3) priority: "err", "info", or the numerical value. +udev_log="err" .fi .P The rules for device naming are read from the files located in the @@ -171,7 +174,6 @@ compiled-in default value. .B last_rule will be the last rule applied. No later rules will have any effect. .sp -.B OPTIONS .B ignore_device will ignore this device. No node will be created. .sp @@ -277,13 +279,6 @@ KERNEL=="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" # multiple USB webcams with symlinks to be called webcam0, webcam1, ... BUS=="usb", SYSFS{model}=="XV3", NAME=="video%n", SYMLINK="webcam%n" - -# grouping of optical drives from multiple kernel subsystems -KERNEL=="sr*", NAME="%k", SYMLINK="cdrom%e" -KERNEL=="scd*", NAME="%k", SYMLINK="cdrom%e" -KERNEL=="pcd*", NAME="%k", SYMLINK="cdrom%e" -KERNEL=="hd[a-z]", PROGRAM=="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", - NAME="%k", SYMLINK="cdrom%e" .fi .P A number of different fields in the above configuration files support a simple @@ -312,8 +307,9 @@ to be recognized. .br In addition to the hotplug environment variables, .B UDEV_LOG -is set if udev is configured to use the syslog facility. Executed programs may -want to follow that setting. +is set and contains the numerical priority value, if udev is configured to use +.BR syslog (3). +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 @@ -345,6 +341,9 @@ Overrides the default location of the .B udev config file. .TP +.B UDEV_LOG +Overrides the log priority specified in the config file. +.TP .B UDEV_NO_DEVD The default behavior of .B udev @@ -367,8 +366,8 @@ will skip this step. .PP .B Web resources: .nf -.I http://linux\-hotplug.sourceforge.net/ .I http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html +.I http://linux\-hotplug.sourceforge.net/ .fi .SH AUTHORS .B udev @@ -40,17 +40,16 @@ #include "udev_rules.h" #include "logging.h" - #ifdef USE_LOG -void log_message(int level, const char *format, ...) +void log_message(int priority, const char *format, ...) { va_list args; - if (!udev_log) + if (priority > udev_log_priority) return; va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif @@ -115,13 +114,12 @@ int main(int argc, char *argv[], char *envp[]) } logging_init("udev"); - dbg("version %s", UDEV_VERSION); - udev_init_config(); + dbg("version %s", UDEV_VERSION); /* set signal handlers */ memset(&act, 0x00, sizeof(act)); - act.sa_handler = (void (*) (int))sig_handler; + act.sa_handler = (void (*)(int)) sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); @@ -146,13 +144,17 @@ int main(int argc, char *argv[], char *envp[]) udev_init_device(&udev, devpath, subsystem); if (!action || !subsystem || !devpath) { - dbg("action, subsystem or devpath missing"); + err("action, subsystem or devpath missing"); goto hotplug; } /* export logging flag, as called scripts may want to do the same as udev */ - if (udev_log) - setenv("UDEV_LOG", "1", 1); + if (udev_log_priority) { + char priority[32]; + + sprintf(priority, "%i", udev_log_priority); + setenv("UDEV_LOG", priority, 1); + } if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { if (strcmp(action, "add") == 0) { @@ -169,7 +171,7 @@ int main(int argc, char *argv[], char *envp[]) path[sizeof(path)-1] = '\0'; class_dev = wait_class_device_open(path); if (class_dev == NULL) { - dbg ("open class device failed"); + dbg("open class device failed"); goto hotplug; } dbg("opened class_dev->name='%s'", class_dev->name); @@ -92,7 +92,7 @@ extern char udev_root[PATH_SIZE]; extern char udev_db_path[PATH_SIZE]; extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; -extern int udev_log; +extern int udev_log_priority; extern int udev_dev_d; extern int udev_hotplug_d; diff --git a/udev_add.c b/udev_add.c index 15c6bf9fbc..d0d9eab913 100644 --- a/udev_add.c +++ b/udev_add.c @@ -58,7 +58,7 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo /* preserve node with already correct numbers, to not change the inode number */ if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && (stats.st_rdev == devt)) { - dbg("preserve file '%s', cause it has correct dev_t", file); + info("preserve file '%s', cause it has correct dev_t", file); selinux_setfilecon(file, udev->kernel_name, stats.st_mode); goto perms; } @@ -85,7 +85,7 @@ create: retval = mknod(file, mode, devt); selinux_resetfscreatecon(); if (retval != 0) { - dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", + err("mknod(%s, %#o, %u, %u) failed with error '%s'", file, mode, major(devt), minor(devt), strerror(errno)); goto exit; } @@ -241,7 +241,7 @@ static int rename_net_if(struct udevice *udev) struct ifreq ifr; int retval; - dbg("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name); + info("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name); if (udev->test_run) return 0; diff --git a/udev_config.c b/udev_config.c index 1b6b614260..54eedb980a 100644 --- a/udev_config.c +++ b/udev_config.c @@ -28,6 +28,7 @@ #include <unistd.h> #include <errno.h> #include <ctype.h> +#include <syslog.h> #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" @@ -35,19 +36,17 @@ #include "udev_utils.h" #include "udev_version.h" #include "logging.h" -#include "udev_rules.h" /* global variables */ char sysfs_path[PATH_SIZE]; char udev_root[PATH_SIZE]; char udev_db_path[PATH_SIZE]; -char udev_rules_filename[PATH_SIZE]; char udev_config_filename[PATH_SIZE]; -int udev_log; +char udev_rules_filename[PATH_SIZE]; +int udev_log_priority; int udev_dev_d; int udev_hotplug_d; - static int string_is_true(const char *str) { if (strcasecmp(str, "true") == 0) @@ -59,6 +58,26 @@ static int string_is_true(const char *str) 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; @@ -107,29 +126,6 @@ static int get_key(char **line, char **key, char **value) return 0; } -static void init_variables(void) -{ - const char *env; - - /* If any config values are specified, they will override these values. */ - strcpy(udev_root, UDEV_ROOT); - strcpy(udev_db_path, UDEV_DB); - strcpy(udev_config_filename, UDEV_CONFIG_FILE); - strcpy(udev_rules_filename, UDEV_RULES_FILE); - - udev_log = string_is_true(UDEV_LOG_DEFAULT); - - udev_dev_d = 1; - env = getenv("UDEV_NO_DEVD"); - if (env && string_is_true(env)) - udev_dev_d = 0; - - udev_hotplug_d = 1; - env = getenv("UDEV_NO_HOTPLUGD"); - if (env && string_is_true(env)) - udev_hotplug_d = 0; -} - static int parse_config_file(void) { char line[LINE_SIZE]; @@ -145,10 +141,9 @@ static int parse_config_file(void) int retval = 0; if (file_map(udev_config_filename, &buf, &bufsize) != 0) { - dbg("can't open '%s' as config file", udev_config_filename); + err("can't open '%s' as config file", udev_config_filename); return -ENODEV; } - dbg("reading '%s' as config file", udev_config_filename); /* loop through the whole file */ lineno = 0; @@ -160,8 +155,7 @@ static int parse_config_file(void) lineno++; if (count >= sizeof(line)) { - info("line too long, conf line skipped %s, line %d", - udev_config_filename, lineno); + err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); continue; } @@ -178,17 +172,14 @@ static int parse_config_file(void) continue; strlcpy(line, bufline, count); - dbg("read '%s'", line); linepos = line; retval = get_key(&linepos, &variable, &value); if (retval != 0) { - info("error parsing %s, line %d:%d", udev_config_filename, lineno, (int) (linepos-line)); + err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int) (linepos-line)); continue; } - dbg("variable='%s', value='%s'", variable, value); - if (strcasecmp(variable, "udev_root") == 0) { strlcpy(udev_root, value, sizeof(udev_root)); no_trailing_slash(udev_root); @@ -208,7 +199,7 @@ static int parse_config_file(void) } if (strcasecmp(variable, "udev_log") == 0) { - udev_log = string_is_true(value); + udev_log_priority = log_priority(value); continue; } } @@ -219,20 +210,41 @@ static int parse_config_file(void) void udev_init_config(void) { - const char *config; + const char *env; - init_variables(); + strcpy(udev_root, UDEV_ROOT); + strcpy(udev_db_path, UDEV_DB); + strcpy(udev_config_filename, UDEV_CONFIG_FILE); + strcpy(udev_rules_filename, UDEV_RULES_FILE); + udev_log_priority = LOG_ERR; + udev_dev_d = 1; + udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); - config = getenv("UDEV_CONFIG_FILE"); - if (config != NULL) - strlcpy(udev_config_filename, config, sizeof(udev_config_filename)); + 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; + + env = getenv("UDEV_CONFIG_FILE"); + if (env) { + strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); + no_trailing_slash(udev_config_filename); + } parse_config_file(); + + env = getenv("UDEV_LOG"); + if (env) + udev_log_priority = log_priority(env); + dbg("sysfs_path='%s'", sysfs_path); + dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename); dbg("udev_root='%s'", udev_root); - dbg("udev_config_filename='%s'", udev_config_filename); - dbg("udev_db_path='%s'", udev_db_path); - dbg("udev_rules_filename='%s'", udev_rules_filename); - dbg("udev_log=%d", udev_log); + dbg("udev_db='%s'", udev_db_path); + dbg("udev_rules='%s'", udev_rules_filename); + dbg("udev_log=%d", udev_log_priority); } @@ -74,7 +74,7 @@ int udev_db_add_device(struct udevice *udev) f = fopen(filename, "w"); if (f == NULL) { - dbg("unable to create db file '%s'", filename); + err("unable to create db file '%s'", filename); return -1; } dbg("storing data for device '%s' in '%s'", udev->devpath, filename); @@ -103,7 +103,7 @@ static int parse_db_file(struct udevice *udev, const char *filename) size_t count; if (file_map(filename, &buf, &bufsize) != 0) { - dbg("unable to read db file '%s'", filename); + err("unable to read db file '%s'", filename); return -1; } @@ -187,7 +187,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) dir = opendir(udev_db_path); if (dir == NULL) { - dbg("unable to udev db '%s'", udev_db_path); + err("unable to open udev_db '%s'", udev_db_path); return -1; } @@ -214,7 +214,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { - dbg("unable to read db file '%s'", filename); + err("unable to read db file '%s'", filename); continue; } @@ -260,7 +260,7 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam dir = opendir(udev_db_path); if (dir == NULL) { - dbg("unable to udev db '%s'", udev_db_path); + err("unable to open udev_db '%s'", udev_db_path); return -1; } @@ -287,7 +287,7 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { - dbg("unable to read db file '%s'", filename); + err("unable to read db file '%s'", filename); continue; } diff --git a/udev_remove.c b/udev_remove.c index 0a9996dc6a..2df555327b 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -158,7 +158,7 @@ int udev_remove_device(struct udevice *udev) if (temp == NULL) return -ENODEV; strlcpy(udev->name, &temp[1], sizeof(udev->name)); - dbg("'%s' not found in database, falling back on default name", udev->name); + info("'%s' not found in database, falling back on default name", udev->name); } /* use full path to the environment */ diff --git a/udev_rules.c b/udev_rules.c index 3dc77855da..4eb8fd4411 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -107,7 +107,7 @@ static char *get_format_attribute(char **str) if (*str[0] == '{') { pos = strchr(*str, '}'); if (pos == NULL) { - dbg("missing closing brace for format"); + err("missing closing brace for format"); return NULL; } pos[0] = '\0'; @@ -131,7 +131,7 @@ static int get_format_len(char **str) dbg("format length=%i", num); return num; } else { - dbg("format parsing error '%s'", *str); + err("format parsing error '%s'", *str); } } return -1; @@ -239,7 +239,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, cpos++; } if (i > 0) { - dbg("requested part of result string not found"); + err("requested part of result string not found"); break; } strlcpy(temp2, cpos, sizeof(temp2)); @@ -265,7 +265,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr); if (tmpattr == NULL) { - dbg("sysfa attribute '%s' not found", attr); + dbg("sysfs attribute '%s' not found", attr); break; } /* strip trailing whitespace of matching value */ @@ -327,7 +327,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute udev_root '%s'", udev_root); break; default: - dbg("unknown substitution type '%%%c'", c); + err("unknown substitution type '%%%c'", c); break; } /* truncate to specified length */ @@ -378,7 +378,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, retval = pipe(fds); if (retval != 0) { - dbg("pipe failed"); + err("pipe failed"); return -1; } @@ -393,7 +393,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, info(KEY_PROGRAM " execution of '%s' failed", path); exit(1); case -1: - dbg("fork failed"); + err("fork of '%s' failed", path); return -1; default: /* parent reads from fds[0] */ @@ -407,14 +407,14 @@ static int execute_program(struct udevice *udev, const char *path, char *value, i += count; if (i >= len-1) { - dbg("result len %d too short", len); + err("result len %d too short", len); retval = -1; break; } } if (count < 0) { - dbg("read failed with '%s'", strerror(errno)); + err("read failed with '%s'", strerror(errno)); retval = -1; } @@ -775,12 +775,12 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d next = strchr(temp, ' '); while (next) { next[0] = '\0'; - dbg("add symlink '%s'", pos); + info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); pos = &next[1]; next = strchr(pos, ' '); } - dbg("add symlink '%s'", pos); + info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); } @@ -812,7 +812,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (udev->name[0] == '\0') { /* no rule matched, so we use the kernel name */ strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); - dbg("no rule found, use kernel name '%s'", udev->name); + info("no rule found, use kernel name '%s'", udev->name); } if (udev->tmp_node[0] != '\0') { diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 55412dba3c..71ca482728 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -157,7 +157,7 @@ static char *get_key_attribute(char *str) attr++; pos = strchr(attr, '}'); if (pos == NULL) { - dbg("missing closing brace for format"); + err("missing closing brace for format"); return NULL; } pos[0] = '\0'; @@ -185,7 +185,7 @@ static int rules_parse(const char *filename) struct udev_rule rule; if (file_map(filename, &buf, &bufsize) != 0) { - dbg("can't open '%s' as rules file", filename); + err("can't open '%s' as rules file", filename); return -1; } dbg("reading '%s' as rules file", filename); @@ -274,13 +274,13 @@ static int rules_parse(const char *filename) struct key_pair *pair; if (rule.sysfs_pair_count >= KEY_SYSFS_PAIRS_MAX) { - dbg("skip rule, to many " KEY_SYSFS " keys in a single rule"); + err("skip rule, to many " KEY_SYSFS " keys in a single rule"); goto error; } pair = &rule.sysfs_pair[rule.sysfs_pair_count]; attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); if (attr == NULL) { - dbg("error parsing " KEY_SYSFS " attribute"); + err("error parsing " KEY_SYSFS " attribute"); goto error; } strlcpy(pair->name, attr, sizeof(pair->name)); @@ -295,13 +295,13 @@ static int rules_parse(const char *filename) struct key_pair *pair; if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) { - dbg("skip rule, to many " KEY_ENV " keys in a single rule"); + err("skip rule, to many " KEY_ENV " keys in a single rule"); goto error; } pair = &rule.env_pair[rule.env_pair_count]; attr = get_key_attribute(key + sizeof(KEY_ENV)-1); if (attr == NULL) { - dbg("error parsing " KEY_ENV " attribute"); + err("error parsing " KEY_ENV " attribute"); continue; } strlcpy(pair->name, attr, sizeof(pair->name)); @@ -400,7 +400,7 @@ static int rules_parse(const char *filename) continue; } - dbg("unknown key '%s'", key); + err("unknown key '%s'", key); goto error; } @@ -411,13 +411,12 @@ static int rules_parse(const char *filename) /* simple plausibility checks for given keys */ if ((rule.sysfs_pair[0].name[0] == '\0') ^ (rule.sysfs_pair[0].value[0] == '\0')) { - info("inconsistency in " KEY_SYSFS " key"); + err("inconsistency in " KEY_SYSFS " key"); goto error; } if ((rule.result[0] != '\0') && (program_given == 0)) { - info(KEY_RESULT " is only useful when " - KEY_PROGRAM " is called in any rule before"); + info(KEY_RESULT " is only useful when " KEY_PROGRAM " is called in any rule before"); goto error; } @@ -428,7 +427,7 @@ static int rules_parse(const char *filename) dbg("add_config_dev returned with error %d", retval); continue; error: - info("parse error %s, line %d:%d, rule skipped", + err("parse error %s, line %d:%d, rule skipped", filename, lineno, (int) (linepos - line)); } } @@ -2,7 +2,7 @@ .SH NAME udevd, udevdsend \- udev event serializer daemon and udev event sender .SH SYNOPSIS -.BI udevsend " hotplug-subsystem" +.BI udevsend .SH "DESCRIPTION" .B udevd allows the serialization of @@ -70,20 +70,19 @@ static void reap_sigchilds(void); char *udev_bin; #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { - va_list args; + va_list args; + + if (priority > udev_log_priority) + return; va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif -#define msg_dump(msg) \ - dbg("msg_dump: sequence %llu, '%s', '%s', '%s'", \ - msg->seqnum, msg->action, msg->devpath, msg->subsystem); - static void msg_dump_queue(void) { #ifdef DEBUG @@ -127,7 +126,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) break; if (loop_msg->seqnum == msg->seqnum) { - dbg("ignoring duplicate message seq %llu", msg->seqnum); + info("ignoring duplicate message seq %llu", msg->seqnum); return; } } @@ -160,11 +159,11 @@ static void udev_run(struct hotplug_msg *msg) setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); execve(udev_bin, argv, msg->envp); - dbg("exec of child failed"); + err("exec of child failed"); _exit(1); break; case -1: - dbg("fork of child failed"); + err("fork of child failed"); run_queue_delete(msg); break; default: @@ -452,17 +451,17 @@ static struct hotplug_msg *get_udevsend_msg(void) cred = (struct ucred *) CMSG_DATA(cmsg); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - dbg("no sender credentials received, message ignored"); + info("no sender credentials received, message ignored"); return NULL; } if (cred->uid != 0) { - dbg("sender uid=%i, message ignored", cred->uid); + info("sender uid=%i, message ignored", cred->uid); return NULL; } if (strncmp(usend_msg.magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { - dbg("message magic '%s' doesn't match, ignore it", usend_msg.magic); + info("message magic '%s' doesn't match, ignore it", usend_msg.magic); return NULL; } @@ -605,14 +604,14 @@ static int init_udevsend_socket(void) udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (udevsendsock == -1) { - dbg("error getting socket, %s", strerror(errno)); + err("error getting socket, %s", strerror(errno)); return -1; } /* the bind takes care of ensuring only one copy running */ retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { - dbg("bind failed, %s", strerror(errno)); + err("bind failed, %s", strerror(errno)); close(udevsendsock); return -1; } @@ -634,10 +633,11 @@ int main(int argc, char *argv[], char *envp[]) const char *udevd_expected_seqnum; logging_init("udevd"); + udev_init_config(); dbg("version %s", UDEV_VERSION); if (getuid() != 0) { - dbg("need to be root, exit"); + err("need to be root, exit"); goto exit; } @@ -651,7 +651,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("damonized fork running"); break; case -1: - dbg("fork of daemon failed"); + err("fork of daemon failed"); goto exit; default: logging_close(); @@ -679,36 +679,36 @@ int main(int argc, char *argv[], char *envp[]) if (fd > 2) close(fd); } else - dbg("error opening /dev/null %s", strerror(errno)); + err("error opening /dev/null %s", strerror(errno)); /* setup signal handler pipe */ retval = pipe(pipefds); if (retval < 0) { - dbg("error getting pipes: %s", strerror(errno)); + err("error getting pipes: %s", strerror(errno)); goto exit; } retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); if (retval < 0) { - dbg("error fcntl on read pipe: %s", strerror(errno)); + err("error fcntl on read pipe: %s", strerror(errno)); goto exit; } retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); if (retval < 0) - dbg("error fcntl on read pipe: %s", strerror(errno)); + err("error fcntl on read pipe: %s", strerror(errno)); retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); if (retval < 0) { - dbg("error fcntl on write pipe: %s", strerror(errno)); + err("error fcntl on write pipe: %s", strerror(errno)); goto exit; } retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); if (retval < 0) - dbg("error fcntl on write pipe: %s", strerror(errno)); + err("error fcntl on write pipe: %s", strerror(errno)); /* set signal handlers */ memset(&act, 0x00, sizeof(struct sigaction)); - act.sa_handler = (void (*) (int))sig_handler; + act.sa_handler = (void (*)(int)) sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); @@ -728,7 +728,7 @@ int main(int argc, char *argv[], char *envp[]) /* possible override of udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); if (udev_bin != NULL) - dbg("udev binary is set to '%s'", udev_bin); + info("udev binary is set to '%s'", udev_bin); else udev_bin = UDEV_BIN; @@ -736,7 +736,7 @@ int main(int argc, char *argv[], char *envp[]) udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM"); if (udevd_expected_seqnum != NULL) { expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10); - dbg("initialize expected_seqnum to %llu", expected_seqnum); + info("initialize expected_seqnum to %llu", expected_seqnum); } /* get current time to provide shorter timeout on startup */ diff --git a/udevinfo.c b/udevinfo.c index ccc3e58e2b..3fb37b41e9 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -36,12 +36,15 @@ #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { va_list args; + if (priority > udev_log_priority) + return; + va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif diff --git a/udevsend.c b/udevsend.c index dcd5a2ae93..8915edacc8 100644 --- a/udevsend.c +++ b/udevsend.c @@ -44,12 +44,15 @@ static int sock = -1; #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { - va_list args; + va_list args; + + if (priority > udev_log_priority) + return; va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif @@ -71,17 +74,17 @@ static int start_daemon(void) /* daemon with empty environment */ close(sock); execve(UDEVD_BIN, argv, envp); - dbg("exec of daemon failed"); + err("exec of daemon failed"); _exit(1); case -1: - dbg("fork of daemon failed"); + err("fork of daemon failed"); return -1; default: exit(0); } break; case -1: - dbg("fork of helper failed"); + err("fork of helper failed"); return -1; default: waitpid(pid, NULL, 0); @@ -99,11 +102,11 @@ static void run_udev(const char *subsystem) case 0: /* child */ execv(UDEV_BIN, argv); - dbg("exec of child failed"); + err("exec of udev child failed"); _exit(1); break; case -1: - dbg("fork of child failed"); + err("fork of udev child failed"); break; default: waitpid(pid, NULL, 0); @@ -124,11 +127,14 @@ int main(int argc, char *argv[], char *envp[]) const char *subsystem = NULL; logging_init("udevsend"); +#ifdef USE_LOG + udev_init_config(); +#endif dbg("version %s", UDEV_VERSION); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { - dbg("error getting socket"); + err("error getting socket"); goto fallback; } @@ -156,7 +162,7 @@ int main(int argc, char *argv[], char *envp[]) } if (bufpos + keylen >= HOTPLUG_BUFFER_SIZE-1) { - dbg("environment buffer too small, probably not called by the kernel"); + err("environment buffer too small, probably not called by the kernel"); continue; } @@ -187,12 +193,12 @@ int main(int argc, char *argv[], char *envp[]) } if (errno != ECONNREFUSED) { - dbg("error sending message (%s)", strerror(errno)); + err("error sending message (%s)", strerror(errno)); goto fallback; } if (!started_daemon) { - dbg("try to start udevd daemon"); + info("try to start udevd daemon"); retval = start_daemon(); if (retval) { dbg("error starting daemon"); @@ -207,7 +213,7 @@ int main(int argc, char *argv[], char *envp[]) } fallback: - info("unable to connect to event daemon, try to call udev directly"); + err("unable to connect to event daemon, try to call udev directly"); run_udev(subsystem); exit: diff --git a/udevstart.c b/udevstart.c index 7765661fe4..a862dadf88 100644 --- a/udevstart.c +++ b/udevstart.c @@ -38,14 +38,23 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" #include "udev.h" +#include "udev_version.h" #include "logging.h" #include "udev_rules.h" #include "udev_utils.h" #include "list.h" #ifdef USE_LOG -void log_message(int level, const char *format, ...) +void log_message(int priority, const char *format, ...) { + va_list args; + + if (priority > udev_log_priority) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); } #endif @@ -299,7 +308,12 @@ int main(int argc, char *argv[], char *envp[]) { struct sigaction act; + logging_init("udev"); udev_init_config(); + /* disable all logging if not explicitely requested */ + if (getenv("UDEV_LOG") == NULL) + udev_log_priority = 0; + dbg("version %s", UDEV_VERSION); /* set signal handlers */ memset(&act, 0x00, sizeof(act)); @@ -322,5 +336,6 @@ int main(int argc, char *argv[], char *envp[]) udev_scan_block(); udev_scan_class(); + logging_close(); return 0; } diff --git a/udevtest.8 b/udevtest.8 index 13b57f03b6..a595a30d41 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -3,7 +3,7 @@ udevtest \- simulates a udev run to test the configured rules .SH SYNOPSIS .B udevtest -.IR "sysfs_device_path " [ subsystem ] +.I sysfs_device_path subsystem .SH "DESCRIPTION" .B udevtest simulates a diff --git a/udevtest.c b/udevtest.c index 006d55510e..f0c38b3a51 100644 --- a/udevtest.c +++ b/udevtest.c @@ -26,6 +26,7 @@ #include <errno.h> #include <ctype.h> #include <signal.h> +#include <syslog.h> #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" @@ -37,10 +38,13 @@ #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { va_list args; + if (priority > udev_log_priority) + return; + va_start(args, format); vprintf(format, args); va_end(args); @@ -60,13 +64,15 @@ int main(int argc, char *argv[], char *envp[]) info("version %s", UDEV_VERSION); - if (argc < 2 || argc > 3) { - info("Usage: udevtest <devpath> [subsystem]"); + if (argc != 3) { + info("Usage: udevtest <devpath> <subsystem>"); return 1; } /* initialize our configuration */ udev_init_config(); + if (udev_log_priority < LOG_INFO) + udev_log_priority = LOG_INFO; /* remove sysfs_path if given */ if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) |