chiark / gitweb /
[PATCH] support log-priority levels in udev.conf
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sat, 26 Mar 2005 23:11:03 +0000 (00:11 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 06:54:59 +0000 (23:54 -0700)
20 files changed:
Makefile
RELEASE-NOTES
etc/udev/udev.conf.in
logging.h
udev.8.in
udev.c
udev.h
udev_add.c
udev_config.c
udev_db.c
udev_remove.c
udev_rules.c
udev_rules_parse.c
udevd.8
udevd.c
udevinfo.c
udevsend.c
udevstart.c
udevtest.8
udevtest.c

index 1424cf0315585648a17d0617ec14e3a5907e0c12..9d9caec7f70f4e41c26b7c558980d50fa4bf7ba3 100644 (file)
--- a/Makefile
+++ b/Makefile
 # 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\" >> $@
 
index 2defd7117b388dad12ce770fc5bf3d839f8aa107..17d6097abf48f676c1a279647709ec1f0a8d8be9 100644 (file)
@@ -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:
index 72e25ed48269525d49eea511ce99cc06ab1fcd48..9d5300a8612226bd040e9cd17403ce1ae0b42da9 100644 (file)
@@ -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"
 
index e7653ee1b85228503d7a61fcd9dfbe3284c37b51..904355cb2cf4fa4f590f3bcd7f950069ca95cefe 100644 (file)
--- a/logging.h
+++ b/logging.h
@@ -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)
 #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
index a246efdb45fbc0ea4d4d293a396eb5c9f95c5825..7b061a8c2b769a3c2555c7fdd709147c1259c4c8 100644 (file)
--- a/udev.8.in
+++ b/udev.8.in
@@ -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
diff --git a/udev.c b/udev.c
index 069cecf973193212f82a89a7c0743e6d256a83fc..6d1d679d9a0ccd446f988cb605c407dd545c123f 100644 (file)
--- a/udev.c
+++ b/udev.c
 #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);
diff --git a/udev.h b/udev.h
index 6e41bb5d26770d288d1e522b3a76454be7eb6d39..c2706f4593ad36640ef50dea2f5a2f9b46bb92f1 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -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;
 
index 15c6bf9fbca0ea5f951431c6870f78b2aa213c66..d0d9eab913b21c4d00671e480d602dc1cadea0f6 100644 (file)
@@ -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;
 
index 1b6b6142600dbb19221cb5767cf0d8c29f5f7bc3..54eedb980a19b1db017954529511247ce1e8a8fc 100644 (file)
@@ -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"
 #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);
 }
index 806fc71bce3b9f07f2a8d376c3cce5f2f5676249..f606b5e05c7eddd570ca9b3f11cff8a5ae768315 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
@@ -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;
                }
 
index 0a9996dc6a849b9a3b8cc78d38f733ddb5a6ad0a..2df555327bbeef9a7dd6270e98b7a1201b651424 100644 (file)
@@ -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 */
index 3dc77855da29359f38b354236d92901c9d547877..4eb8fd44118bd52896a02011659c4752e2730fe1 100644 (file)
@@ -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') {
index 55412dba3c5a8e7e717236ffff1f0b8e321b300f..71ca4827288daca318dc9ba81ca5554ea93c0385 100644 (file)
@@ -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));
                }
        }
diff --git a/udevd.8 b/udevd.8
index b06a2b7af12578071898ac059114cea4e8273fd2..02e2e2c5f8f7e2645f907fef0664dd946873f5c6 100644 (file)
--- a/udevd.8
+++ b/udevd.8
@@ -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
diff --git a/udevd.c b/udevd.c
index 6e27c8a0d141779edfe2f8e3420c0d4b927a1bdf..6c4d8b8693be00bcd6f9382fb5e112f47cdab729 100644 (file)
--- a/udevd.c
+++ b/udevd.c
@@ -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 */
index ccc3e58e2b8f884d73a7075252dcd21d5eb688ff..3fb37b41e917791538cc65fd0cf68441dea2cfc3 100644 (file)
 
 
 #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
index dcd5a2ae934ab4620d392e52b93de39bcbfda5ce..8915edacc8cf2c27a4fdb72571fe2b42184e48ca 100644 (file)
 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:
index 7765661fe45b11678c7458125bfeaa906cee287a..a862dadf88c2818a365ef9b7a1ed860d4e5f6df9 100644 (file)
 #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;
 }
index 13b57f03b626845d6fc1387c940719f6b62854f5..a595a30d41d565aaddff6a26c6add8d0b38c6d25 100644 (file)
@@ -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
index 006d55510e3aa1b84e6e189b5d0b9ec343361502..f0c38b3a51b5fd7481e0782bb42a283f304978d7 100644 (file)
@@ -26,6 +26,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <signal.h>
+#include <syslog.h>
 
 #include "libsysfs/sysfs/libsysfs.h"
 #include "udev.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);
        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)