1
0
mirror of https://github.com/systemd/systemd synced 2025-09-27 15:54:47 +02:00

Compare commits

..

No commits in common. "239952e890fd4b53859f84bbc43d910e68a8f6bc" and "6597686865ffcba7450b44814618b94321cfa3cf" have entirely different histories.

17 changed files with 79 additions and 107 deletions

View File

@ -647,24 +647,6 @@
on the transition from initramfs.</para> on the transition from initramfs.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>log_level=<replaceable>level</replaceable></option></term>
<listitem>
<para>Takes a log level name like <literal>debug</literal> or
<literal>info</literal>, or a special value <literal>reset</literal>. When a log
level name is specified, the maximum log level is changed to that level. When
<literal>reset</literal> is set, then the previously specified log level is
revoked. Defaults to the log level of the main process of
<command>systemd-udevd</command>.</para>
<para>This may be useful when debugging events for certain devices. Note that the
log level is applied when the line including this rule is processed. So, for
debugging, it is recommended that this is specified at earlier place, e.g., the
first line of <filename>00-debug.rules</filename>.</para>
<para>Example for debugging uevent processing for network interfaces.
<programlisting># /etc/udev/rules.d/00-debug-net.rules
SUBSYSTEM=="net", OPTIONS="log_level=debug"</programlisting></para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -667,6 +667,9 @@ if fallback_hostname == '' or fallback_hostname[0] == '.' or fallback_hostname[0
endif endif
conf.set_quoted('FALLBACK_HOSTNAME', fallback_hostname) conf.set_quoted('FALLBACK_HOSTNAME', fallback_hostname)
conf.set10('ENABLE_COMPAT_GATEWAY_HOSTNAME', get_option('compat-gateway-hostname'))
gateway_hostnames = ['_gateway'] + (conf.get('ENABLE_COMPAT_GATEWAY_HOSTNAME') == 1 ? ['gateway'] : [])
default_hierarchy = get_option('default-hierarchy') default_hierarchy = get_option('default-hierarchy')
conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy, conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy,
description : 'default cgroup hierarchy as string') description : 'default cgroup hierarchy as string')
@ -3685,6 +3688,7 @@ status = [
'nobody user name: @0@'.format(nobody_user), 'nobody user name: @0@'.format(nobody_user),
'nobody group name: @0@'.format(nobody_group), 'nobody group name: @0@'.format(nobody_group),
'fallback hostname: @0@'.format(get_option('fallback-hostname')), 'fallback hostname: @0@'.format(get_option('fallback-hostname')),
'symbolic gateway hostnames: @0@'.format(', '.join(gateway_hostnames)),
'default DNSSEC mode: @0@'.format(default_dnssec), 'default DNSSEC mode: @0@'.format(default_dnssec),
'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls), 'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls),

View File

@ -187,6 +187,8 @@ option('install-sysconfdir', type : 'boolean', value : true,
option('fallback-hostname', type : 'string', value : 'localhost', option('fallback-hostname', type : 'string', value : 'localhost',
description : 'the hostname used if none configured') description : 'the hostname used if none configured')
option('compat-gateway-hostname', type : 'boolean', value : 'false',
description : 'allow "gateway" as the symbolic name for default gateway')
option('default-hierarchy', type : 'combo', option('default-hierarchy', type : 'combo',
choices : ['legacy', 'hybrid', 'unified'], value : 'unified', choices : ['legacy', 'hybrid', 'unified'], value : 'unified',
description : 'default cgroup hierarchy') description : 'default cgroup hierarchy')

View File

@ -212,6 +212,20 @@ bool is_localhost(const char *hostname) {
endswith_no_case(hostname, ".localhost.localdomain."); endswith_no_case(hostname, ".localhost.localdomain.");
} }
bool is_gateway_hostname(const char *hostname) {
assert(hostname);
/* This tries to identify the valid syntaxes for the our
* synthetic "gateway" host. */
return
strcaseeq(hostname, "_gateway") || strcaseeq(hostname, "_gateway.")
#if ENABLE_COMPAT_GATEWAY_HOSTNAME
|| strcaseeq(hostname, "gateway") || strcaseeq(hostname, "gateway.")
#endif
;
}
int sethostname_idempotent(const char *s) { int sethostname_idempotent(const char *s) {
char buf[HOST_NAME_MAX + 1] = {}; char buf[HOST_NAME_MAX + 1] = {};

View File

@ -5,7 +5,6 @@
#include <stdio.h> #include <stdio.h>
#include "macro.h" #include "macro.h"
#include "strv.h"
bool hostname_is_set(void); bool hostname_is_set(void);
@ -20,11 +19,7 @@ char* hostname_cleanup(char *s);
#define machine_name_is_valid(s) hostname_is_valid(s, false) #define machine_name_is_valid(s) hostname_is_valid(s, false)
bool is_localhost(const char *hostname); bool is_localhost(const char *hostname);
bool is_gateway_hostname(const char *hostname);
static inline bool is_gateway_hostname(const char *hostname) {
/* This tries to identify the valid syntaxes for the our synthetic "gateway" host. */
return STRCASE_IN_SET(hostname, "_gateway", "_gateway.");
}
int sethostname_idempotent(const char *s); int sethostname_idempotent(const char *s);

View File

@ -522,8 +522,13 @@ DnsScopeMatch dns_scope_good_domain(
if (dns_name_endswith(domain, "invalid") > 0) if (dns_name_endswith(domain, "invalid") > 0)
return DNS_SCOPE_NO; return DNS_SCOPE_NO;
/* Never go to network for the _gateway domain, it's something special, synthesized locally. */ /* Never go to network for the _gateway domain, it's something special, synthesized locally. Note
if (is_gateway_hostname(domain)) * that we don't use is_gateway_hostname() here, since that has support for the legacy "gateway"
* hostname (without the prefix underscore), which we don't want to filter on all protocols. i.e. we
* don't want to filter "gateway" on classic DNS, since there might very well be such a host inside
* some search domain, and we shouldn't block that. We do filter it in LLMNR however (and on mDNS by
* side-effect, since it's a single-label name which mDNS doesn't accept anyway). */
if (dns_name_equal(domain, "_gateway") > 0)
return DNS_SCOPE_NO; return DNS_SCOPE_NO;
switch (s->protocol) { switch (s->protocol) {

View File

@ -564,7 +564,7 @@ int generator_write_cryptsetup_unit_section(
fprintf(f, fprintf(f,
"DefaultDependencies=no\n" "DefaultDependencies=no\n"
"IgnoreOnIsolate=true\n" "IgnoreOnIsolate=true\n"
"After=cryptsetup-pre.target systemd-udevd-kernel.socket\n" "After=cryptsetup-pre.target\n"
"Before=blockdev@dev-mapper-%%i.target\n" "Before=blockdev@dev-mapper-%%i.target\n"
"Wants=blockdev@dev-mapper-%%i.target\n"); "Wants=blockdev@dev-mapper-%%i.target\n");

View File

@ -324,20 +324,6 @@ bool device_for_action(sd_device *dev, DeviceAction action) {
return a == action; return a == action;
} }
void log_device_uevent(sd_device *device, const char *str) {
DeviceAction action = _DEVICE_ACTION_INVALID;
uint64_t seqnum = 0;
if (!DEBUG_LOGGING)
return;
(void) device_get_seqnum(device, &seqnum);
(void) device_get_action(device, &action);
log_device_debug(device, "%s%s(SEQNUM=%"PRIu64", ACTION=%s)",
strempty(str), isempty(str) ? "" : " ",
seqnum, strna(device_action_to_string(action)));
}
int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) { int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
char *i, *j; char *i, *j;
int r; int r;

View File

@ -33,6 +33,4 @@ int device_wait_for_devlink(const char *path, const char *subsystem, usec_t dead
int device_is_renaming(sd_device *dev); int device_is_renaming(sd_device *dev);
bool device_for_action(sd_device *dev, DeviceAction action); bool device_for_action(sd_device *dev, DeviceAction action);
void log_device_uevent(sd_device *device, const char *str);
int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos); int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos);

View File

@ -102,7 +102,7 @@ static int run(int argc, char *argv[]) {
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to open device '%s'", devpath); return log_debug_errno(r, "Failed to open device '%s'", devpath);
assert_se(event = udev_event_new(dev, 0, NULL, log_get_max_level())); assert_se(event = udev_event_new(dev, 0, NULL));
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0);

View File

@ -44,10 +44,10 @@ struct udev_ctrl {
int sock_connect; int sock_connect;
union sockaddr_union saddr; union sockaddr_union saddr;
socklen_t addrlen; socklen_t addrlen;
bool bound; bool bound:1;
bool cleanup_socket; bool cleanup_socket:1;
bool connected; bool connected:1;
bool maybe_disconnected; bool maybe_disconnected:1;
sd_event *event; sd_event *event;
sd_event_source *event_source; sd_event_source *event_source;
sd_event_source *event_source_connect; sd_event_source *event_source_connect;

View File

@ -51,7 +51,7 @@ typedef struct Spawn {
size_t result_len; size_t result_len;
} Spawn; } Spawn;
UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl, int log_level) { UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl) {
UdevEvent *event; UdevEvent *event;
assert(dev); assert(dev);
@ -68,8 +68,6 @@ UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rt
.uid = UID_INVALID, .uid = UID_INVALID,
.gid = GID_INVALID, .gid = GID_INVALID,
.mode = MODE_INVALID, .mode = MODE_INVALID,
.log_level_was_debug = log_level == LOG_DEBUG,
.default_log_level = log_level,
}; };
return event; return event;

View File

@ -34,19 +34,17 @@ typedef struct UdevEvent {
unsigned builtin_run; unsigned builtin_run;
unsigned builtin_ret; unsigned builtin_ret;
UdevRuleEscapeType esc:8; UdevRuleEscapeType esc:8;
bool inotify_watch; bool inotify_watch:1;
bool inotify_watch_final; bool inotify_watch_final:1;
bool group_final; bool group_final:1;
bool owner_final; bool owner_final:1;
bool mode_final; bool mode_final:1;
bool name_final; bool name_final:1;
bool devlink_final; bool devlink_final:1;
bool run_final; bool run_final:1;
bool log_level_was_debug;
int default_log_level;
} UdevEvent; } UdevEvent;
UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl, int log_level); UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl);
UdevEvent *udev_event_free(UdevEvent *event); UdevEvent *udev_event_free(UdevEvent *event);
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free); DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free);

View File

@ -25,7 +25,6 @@
#include "strv.h" #include "strv.h"
#include "strxcpyx.h" #include "strxcpyx.h"
#include "sysctl-util.h" #include "sysctl-util.h"
#include "syslog-util.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#include "udev-event.h" #include "udev-event.h"
#include "udev-rules.h" #include "udev-rules.h"
@ -105,7 +104,6 @@ typedef enum {
TK_A_OPTIONS_DB_PERSIST, /* no argument */ TK_A_OPTIONS_DB_PERSIST, /* no argument */
TK_A_OPTIONS_INOTIFY_WATCH, /* boolean */ TK_A_OPTIONS_INOTIFY_WATCH, /* boolean */
TK_A_OPTIONS_DEVLINK_PRIORITY, /* int */ TK_A_OPTIONS_DEVLINK_PRIORITY, /* int */
TK_A_OPTIONS_LOG_LEVEL, /* string of log level or "reset" */
TK_A_OWNER, /* user name */ TK_A_OWNER, /* user name */
TK_A_GROUP, /* group name */ TK_A_GROUP, /* group name */
TK_A_MODE, /* mode string */ TK_A_MODE, /* mode string */
@ -836,17 +834,6 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
if (r < 0) if (r < 0)
return log_token_error_errno(rules, r, "Failed to parse link priority '%s': %m", tmp); return log_token_error_errno(rules, r, "Failed to parse link priority '%s': %m", tmp);
r = rule_line_add_token(rule_line, TK_A_OPTIONS_DEVLINK_PRIORITY, op, NULL, INT_TO_PTR(prio)); r = rule_line_add_token(rule_line, TK_A_OPTIONS_DEVLINK_PRIORITY, op, NULL, INT_TO_PTR(prio));
} else if ((tmp = startswith(value, "log_level="))) {
int level;
if (streq(tmp, "reset"))
level = -1;
else {
level = log_level_from_string(tmp);
if (level < 0)
return log_token_error_errno(rules, level, "Failed to parse log level '%s': %m", tmp);
}
r = rule_line_add_token(rule_line, TK_A_OPTIONS_LOG_LEVEL, op, NULL, INT_TO_PTR(level));
} else { } else {
log_token_warning(rules, "Invalid value for OPTIONS key, ignoring: '%s'", value); log_token_warning(rules, "Invalid value for OPTIONS key, ignoring: '%s'", value);
return 0; return 0;
@ -1871,22 +1858,6 @@ static int udev_rule_apply_token_to_event(
case TK_A_OPTIONS_DEVLINK_PRIORITY: case TK_A_OPTIONS_DEVLINK_PRIORITY:
device_set_devlink_priority(dev, PTR_TO_INT(token->data)); device_set_devlink_priority(dev, PTR_TO_INT(token->data));
break; break;
case TK_A_OPTIONS_LOG_LEVEL: {
int level = PTR_TO_INT(token->data);
if (level < 0)
level = event->default_log_level;
log_set_max_level_all_realms(level);
if (level == LOG_DEBUG && !event->log_level_was_debug) {
/* The log level becomes LOG_DEBUG at first time. Let's log basic information. */
log_device_uevent(dev, "The log level is changed to 'debug' while processing device");
event->log_level_was_debug = true;
}
break;
}
case TK_A_OWNER: { case TK_A_OWNER: {
char owner[UTIL_NAME_SIZE]; char owner[UTIL_NAME_SIZE];
const char *ow = owner; const char *ow = owner;

View File

@ -138,7 +138,7 @@ int test_main(int argc, char *argv[], void *userdata) {
/* don't read info from the db */ /* don't read info from the db */
device_seal(dev); device_seal(dev);
event = udev_event_new(dev, 0, NULL, LOG_DEBUG); event = udev_event_new(dev, 0, NULL);
assert_se(sigfillset(&mask) >= 0); assert_se(sigfillset(&mask) >= 0);
assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0); assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0);

View File

@ -84,7 +84,6 @@ typedef struct Manager {
LIST_HEAD(struct event, events); LIST_HEAD(struct event, events);
const char *cgroup; const char *cgroup;
pid_t pid; /* the process that originally allocated the manager object */ pid_t pid; /* the process that originally allocated the manager object */
int log_level;
UdevRules *rules; UdevRules *rules;
Hashmap *properties; Hashmap *properties;
@ -101,8 +100,8 @@ typedef struct Manager {
usec_t last_usec; usec_t last_usec;
bool stop_exec_queue; bool stop_exec_queue:1;
bool exit; bool exit:1;
} Manager; } Manager;
enum event_state { enum event_state {
@ -437,14 +436,25 @@ static int worker_mark_block_device_read_only(sd_device *dev) {
static int worker_process_device(Manager *manager, sd_device *dev) { static int worker_process_device(Manager *manager, sd_device *dev) {
_cleanup_(udev_event_freep) UdevEvent *udev_event = NULL; _cleanup_(udev_event_freep) UdevEvent *udev_event = NULL;
_cleanup_close_ int fd_lock = -1; _cleanup_close_ int fd_lock = -1;
DeviceAction action;
uint64_t seqnum;
int r; int r;
assert(manager); assert(manager);
assert(dev); assert(dev);
log_device_uevent(dev, "Processing device"); r = device_get_seqnum(dev, &seqnum);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get SEQNUM: %m");
udev_event = udev_event_new(dev, arg_exec_delay_usec, manager->rtnl, manager->log_level); r = device_get_action(dev, &action);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get ACTION: %m");
log_device_debug(dev, "Processing device (SEQNUM=%"PRIu64", ACTION=%s)",
seqnum, device_action_to_string(action));
udev_event = udev_event_new(dev, arg_exec_delay_usec, manager->rtnl);
if (!udev_event) if (!udev_event)
return -ENOMEM; return -ENOMEM;
@ -511,7 +521,9 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
} else } else
(void) udev_watch_end(dev); (void) udev_watch_end(dev);
log_device_uevent(dev, "Device processed"); log_device_debug(dev, "Device (SEQNUM=%"PRIu64", ACTION=%s) processed",
seqnum, device_action_to_string(action));
return 0; return 0;
} }
@ -541,9 +553,6 @@ static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *
if (r < 0) if (r < 0)
log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m"); log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m");
/* Reset the log level, as it might be changed by "OPTIONS=log_level=". */
log_set_max_level_all_realms(manager->log_level);
return 1; return 1;
} }
@ -646,7 +655,13 @@ static void event_run(Manager *manager, struct event *event) {
assert(manager); assert(manager);
assert(event); assert(event);
log_device_uevent(event->dev, "Device ready for processing"); if (DEBUG_LOGGING) {
DeviceAction action;
r = device_get_action(event->dev, &action);
log_device_debug(event->dev, "Device (SEQNUM=%"PRIu64", ACTION=%s) ready for processing",
event->seqnum, r >= 0 ? device_action_to_string(action) : "<unknown>");
}
HASHMAP_FOREACH(worker, manager->workers) { HASHMAP_FOREACH(worker, manager->workers) {
if (worker->state != WORKER_IDLE) if (worker->state != WORKER_IDLE)
@ -689,6 +704,7 @@ static void event_run(Manager *manager, struct event *event) {
static int event_queue_insert(Manager *manager, sd_device *dev) { static int event_queue_insert(Manager *manager, sd_device *dev) {
_cleanup_(sd_device_unrefp) sd_device *clone = NULL; _cleanup_(sd_device_unrefp) sd_device *clone = NULL;
struct event *event; struct event *event;
DeviceAction action;
uint64_t seqnum; uint64_t seqnum;
int r; int r;
@ -703,6 +719,11 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
if (r < 0) if (r < 0)
return r; return r;
/* Refuse devices do not have ACTION property. */
r = device_get_action(dev, &action);
if (r < 0)
return r;
/* Save original device to restore the state on failures. */ /* Save original device to restore the state on failures. */
r = device_shallow_clone(dev, &clone); r = device_shallow_clone(dev, &clone);
if (r < 0) if (r < 0)
@ -732,7 +753,8 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
LIST_APPEND(event, manager->events, event); LIST_APPEND(event, manager->events, event);
log_device_uevent(dev, "Device is queued"); log_device_debug(dev, "Device (SEQNUM=%"PRIu64", ACTION=%s) is queued",
seqnum, device_action_to_string(action));
return 0; return 0;
} }
@ -1068,7 +1090,6 @@ static int on_ctrl_msg(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, co
case UDEV_CTRL_SET_LOG_LEVEL: case UDEV_CTRL_SET_LOG_LEVEL:
log_debug("Received udev control message (SET_LOG_LEVEL), setting log_level=%i", value->intval); log_debug("Received udev control message (SET_LOG_LEVEL), setting log_level=%i", value->intval);
log_set_max_level_all_realms(value->intval); log_set_max_level_all_realms(value->intval);
manager->log_level = value->intval;
manager_kill_workers(manager); manager_kill_workers(manager);
break; break;
case UDEV_CTRL_STOP_EXEC_QUEUE: case UDEV_CTRL_STOP_EXEC_QUEUE:
@ -1713,8 +1734,6 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind netlink socket: %m"); return log_error_errno(r, "Failed to bind netlink socket: %m");
manager->log_level = log_get_max_level();
*ret = TAKE_PTR(manager); *ret = TAKE_PTR(manager);
return 0; return 0;

View File

@ -97,7 +97,7 @@ static int create_device(void) {
"Conflicts=umount.target\n" "Conflicts=umount.target\n"
"BindsTo=%s %s\n" "BindsTo=%s %s\n"
"IgnoreOnIsolate=true\n" "IgnoreOnIsolate=true\n"
"After=cryptsetup-pre.target systemd-udevd-kernel.socket %s %s\n" "After=cryptsetup-pre.target %s %s\n"
"Before=cryptsetup.target umount.target\n" "Before=cryptsetup.target umount.target\n"
"\n[Service]\n" "\n[Service]\n"
"Type=oneshot\n" "Type=oneshot\n"