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:
parent
65005a7f81
commit
6b493a20e1
9
Makefile
9
Makefile
@ -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\" >> $@
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
|
||||
|
11
logging.h
11
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)
|
||||
@ -34,10 +35,16 @@
|
||||
#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
|
||||
@ -48,7 +55,7 @@
|
||||
} 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
|
||||
|
45
udev.8.in
45
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
|
||||
|
20
udev.c
20
udev.c
@ -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,9 +114,8 @@ 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));
|
||||
@ -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) {
|
||||
|
2
udev.h
2
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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
102
udev_config.c
102
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);
|
||||
}
|
||||
|
12
udev_db.c
12
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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
24
udev_rules.c
24
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') {
|
||||
|
@ -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
udevd.8
2
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
|
||||
|
48
udevd.c
48
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;
|
||||
|
||||
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,32 +679,32 @@ 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));
|
||||
@ -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 */
|
||||
|
@ -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
|
||||
|
30
udevsend.c
30
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;
|
||||
|
||||
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:
|
||||
|
17
udevstart.c
17
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
12
udevtest.c
12
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)
|
||||
|
Loading…
Reference in New Issue
Block a user