1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-30 06:25:25 +03:00

[PATCH] support log-priority levels in udev.conf

This commit is contained in:
kay.sievers@vrfy.org 2005-03-27 00:11:03 +01:00 committed by Greg KH
parent 65005a7f81
commit 6b493a20e1
20 changed files with 233 additions and 176 deletions

View File

@ -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\" >> $@

View 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:

View 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"

View File

@ -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

View File

@ -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

24
udev.c
View File

@ -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);

2
udev.h
View File

@ -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;

View 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;

View 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"
@ -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);
}

View File

@ -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;
}

View 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 */

View 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') {

View 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));
}
}

View File

@ -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

52
udevd.c
View File

@ -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 */

View File

@ -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

View File

@ -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:

View File

@ -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;
}

View 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

View 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"
@ -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)