Merge pull request #30867 from dtardon/udev-conf-dropins

Allow dropins for udev.conf
This commit is contained in:
Yu Watanabe 2024-01-12 06:37:23 +09:00 committed by GitHub
commit 967cd1712c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 88 additions and 102 deletions

View file

@ -1176,7 +1176,7 @@ manpages = [
['timesyncd.conf', '5', ['timesyncd.conf.d'], 'ENABLE_TIMESYNCD'],
['tmpfiles.d', '5', [], ''],
['udev', '7', [], ''],
['udev.conf', '5', [], ''],
['udev.conf', '5', ['udev.conf.d'], ''],
['udev_device_get_syspath',
'3',
['udev_device_get_action',

View file

@ -18,23 +18,35 @@
<refnamediv>
<refname>udev.conf</refname>
<refname>udev.conf.d</refname>
<refpurpose>Configuration for device event managing daemon</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>/etc/udev/udev.conf</filename></para>
<para>
<simplelist>
<member><filename>/etc/udev/udev.conf</filename></member>
<member><filename>/run/udev/udev.conf</filename></member>
<member><filename>/usr/lib/udev/udev.conf</filename></member>
<member><filename>/etc/udev/udev.conf.d/*.conf</filename></member>
<member><filename>/run/udev/udev.conf.d/*.conf</filename></member>
<member><filename>/usr/lib/udev/udev.conf.d/*.conf</filename></member>
</simplelist>
</para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>These files contain configuration options for
<citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
The syntax of these files is very simple: a list
of assignments, one per line.
All empty lines or lines beginning with <literal>#</literal> are
ignored.
</para>
<para>
<citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
expects its main configuration file at
<filename>/etc/udev/udev.conf</filename>. It consists of a set
of variables allowing the user to override default udev
values. All empty lines or lines beginning with '#' are
ignored. The following variables can be set:
The following options can be set:
</para>
<variablelist class='config-directives'>
@ -47,6 +59,12 @@
<option>err</option>, <option>info</option> and
<option>debug</option>.</para>
<note>
<para>This option is also honored by
<citerefentry><refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
</note>
<xi:include href="version-info.xml" xpointer="v216"/>
</listitem>
</varlistentry>

View file

@ -598,10 +598,11 @@ static int config_parse_many_files(
return 0;
}
/* Parse one main config file located in /etc/systemd and its drop-ins, which is what all systemd daemons
/* Parse one main config file located in /etc/$pkgdir and its drop-ins, which is what all systemd daemons
* do. */
int config_parse_config_file(
int config_parse_config_file_full(
const char *conf_file,
const char *pkgdir,
const char *sections,
ConfigItemLookup lookup,
const void *table,
@ -613,6 +614,7 @@ int config_parse_config_file(
int r;
assert(conf_file);
assert(pkgdir);
/* build the dropin dir list */
dropin_dirs = new0(char*, strv_length(conf_paths) + 1);
@ -626,7 +628,7 @@ int config_parse_config_file(
STRV_FOREACH(p, conf_paths) {
char *d;
d = strjoin(*p, "systemd/", conf_file, ".d");
d = strjoin(*p, pkgdir, "/", conf_file, ".d");
if (!d) {
if (flags & CONFIG_PARSE_WARN)
return log_oom();
@ -640,7 +642,7 @@ int config_parse_config_file(
if (r < 0)
return r;
const char *sysconf_file = strjoina(PKGSYSCONFDIR, "/", conf_file);
const char *sysconf_file = strjoina(SYSCONF_DIR, "/", pkgdir, "/", conf_file);
return config_parse_many_files(STRV_MAKE_CONST(sysconf_file), dropins,
sections, lookup, table, flags, userdata, NULL);

View file

@ -93,14 +93,25 @@ int config_parse(
void *userdata,
struct stat *ret_stat); /* possibly NULL */
int config_parse_config_file(
int config_parse_config_file_full(
const char *conf_file,
const char *pkgdir,
const char *sections, /* nulstr */
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
void *userdata);
static inline int config_parse_config_file(
const char *conf_file,
const char *sections, /* nulstr */
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,
void *userdata) {
return config_parse_config_file_full(conf_file, "systemd", sections, lookup, table, flags, userdata);
}
int config_parse_many(
const char* const* conf_files, /* possibly empty */
const char* const* conf_file_dirs,

View file

@ -22,43 +22,37 @@
#include "udev-util.h"
#include "utf8.h"
int udev_set_max_log_level(char *str) {
size_t n;
int udev_parse_config_full(const ConfigTableItem config_table[]) {
int r;
/* This may modify input string. */
assert(config_table);
if (isempty(str))
r = config_parse_config_file_full(
"udev.conf",
"udev",
/* sections = */ NULL,
config_item_table_lookup,
config_table,
CONFIG_PARSE_WARN,
/* userdata = */ NULL);
if (r == -ENOENT)
return 0;
/* unquote */
n = strlen(str);
if (n >= 2 &&
((str[0] == '"' && str[n - 1] == '"') ||
(str[0] == '\'' && str[n - 1] == '\''))) {
str[n - 1] = '\0';
str++;
}
/* we set the udev log level here explicitly, this is supposed
* to regulate the code in libudev/ and udev/. */
return log_set_max_level_from_string(str);
return r;
}
int udev_parse_config(void) {
_cleanup_free_ char *log_val = NULL;
int r;
int r, log_val = -1;
const ConfigTableItem config_table[] = {
{ NULL, "udev_log", config_parse_log_level, 0, &log_val },
{}
};
r = parse_env_file(NULL, "/etc/udev/udev.conf",
"udev_log", &log_val);
if (r == -ENOENT)
return 0;
r = udev_parse_config_full(config_table);
if (r < 0)
return r;
r = udev_set_max_log_level(log_val);
if (r < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to set udev log level '%s', ignoring: %m", log_val);
if (log_val >= 0)
log_set_max_level(log_val);
return 0;
}

View file

@ -3,10 +3,11 @@
#include "sd-device.h"
#include "conf-parser.h"
#include "hashmap.h"
#include "time-util.h"
int udev_set_max_log_level(char *str);
int udev_parse_config_full(const ConfigTableItem config_table[]);
int udev_parse_config(void);
int device_wait_for_initialization(sd_device *device, const char *subsystem, usec_t timeout_usec, sd_device **ret);

View file

@ -10,6 +10,7 @@
#include "sd-daemon.h"
#include "conf-parser.h"
#include "env-file.h"
#include "errno-util.h"
#include "fd-util.h"
@ -65,70 +66,29 @@ static int listen_fds(int *ret_ctrl, int *ret_netlink) {
return 0;
}
static DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_name_timing, resolve_name_timing, ResolveNameTiming, "Failed to parse resolve name timing");
static int manager_parse_udev_config(Manager *manager) {
_cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL,
*event_timeout = NULL, *resolve_names = NULL, *timeout_signal = NULL;
int r;
int r, log_val = -1;
assert(manager);
r = parse_env_file(NULL, "/etc/udev/udev.conf",
"udev_log", &log_val,
"children_max", &children_max,
"exec_delay", &exec_delay,
"event_timeout", &event_timeout,
"resolve_names", &resolve_names,
"timeout_signal", &timeout_signal);
if (r == -ENOENT)
return 0;
const ConfigTableItem config_table[] = {
{ NULL, "udev_log", config_parse_log_level, 0, &log_val },
{ NULL, "children_max", config_parse_unsigned, 0, &manager->children_max },
{ NULL, "exec_delay", config_parse_sec, 0, &manager->exec_delay_usec },
{ NULL, "event_timeout", config_parse_sec, 0, &manager->timeout_usec },
{ NULL, "resolve_names", config_parse_resolve_name_timing, 0, &manager->resolve_name_timing },
{ NULL, "timeout_signal", config_parse_signal, 0, &manager->timeout_signal },
{}
};
r = udev_parse_config_full(config_table);
if (r < 0)
return r;
r = udev_set_max_log_level(log_val);
if (r < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to set udev log level '%s', ignoring: %m", log_val);
if (children_max) {
r = safe_atou(children_max, &manager->children_max);
if (r < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to parse children_max=%s, ignoring: %m", children_max);
}
if (exec_delay) {
r = parse_sec(exec_delay, &manager->exec_delay_usec);
if (r < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to parse exec_delay=%s, ignoring: %m", exec_delay);
}
if (event_timeout) {
r = parse_sec(event_timeout, &manager->timeout_usec);
if (r < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to parse event_timeout=%s, ignoring: %m", event_timeout);
}
if (resolve_names) {
ResolveNameTiming t;
t = resolve_name_timing_from_string(resolve_names);
if (t < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to parse resolve_names=%s, ignoring.", resolve_names);
else
manager->resolve_name_timing = t;
}
if (timeout_signal) {
r = signal_from_string(timeout_signal);
if (r < 0)
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"Failed to parse timeout_signal=%s, ignoring: %m", timeout_signal);
else
manager->timeout_signal = r;
}
if (log_val >= 0)
log_set_max_level(log_val);
return 0;
}

View file

@ -4,11 +4,12 @@ set -eux
TMPDIR=
TEST_RULE="/run/udev/rules.d/49-test.rules"
TEST_CONF="/run/udev/udev.conf.d/test-17.conf"
KILL_PID=
setup() {
mkdir -p "${TEST_RULE%/*}"
[[ -e /etc/udev/udev.conf ]] && cp -f /etc/udev/udev.conf /etc/udev/udev.conf.bak
mkdir -p /run/udev/udev.conf.d
cat >"${TEST_RULE}" <<EOF
ACTION!="add", GOTO="test_end"
@ -21,7 +22,7 @@ PROGRAM!="/bin/sleep 60", ENV{PROGRAM_RESULT}="KILLED"
LABEL="test_end"
EOF
cat >/etc/udev/udev.conf <<EOF
cat >"$TEST_CONF" <<EOF
event_timeout=10
timeout_signal=SIGABRT
EOF
@ -38,8 +39,7 @@ teardown() {
fi
rm -rf "$TMPDIR"
rm -f "$TEST_RULE"
[[ -e /etc/udev/udev.conf.bak ]] && mv -f /etc/udev/udev.conf.bak /etc/udev/udev.conf
rm -f "$TEST_RULE" "$TEST_CONF"
systemctl restart systemd-udevd.service
}