Accepting request 243103 from Base:System

1

OBS-URL: https://build.opensuse.org/request/show/243103
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/systemd?expand=0&rev=197
This commit is contained in:
Stephan Kulow 2014-07-31 19:49:13 +00:00 committed by Git OBS Bridge
commit 40227a1b3f
15 changed files with 1825 additions and 0 deletions

View File

@ -0,0 +1,34 @@
Based on 805b573fad06b845502e76f3db3a0efa7583149d Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 23 Jul 2014 12:49:14 +0200
Subject: [PATCH] sysv: order initscripts which provide $network before
network.target
Due to recent changes where $network "maps" to network-online.target
it is not guaranteed that initscript which provides networking will
be terminated after network.target during shutdown which is against LSB.
---
src/core/service.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- src/core/service.c
+++ src/core/service.c 2014-07-30 11:27:16.074235995 +0000
@@ -820,7 +820,7 @@ static int service_load_sysv_path(Servic
if (unit_name_to_type(m) == UNIT_SERVICE)
r = unit_merge_by_name(u, m);
- else
+ else {
/* NB: SysV targets
* which are provided
* by a service are
@@ -835,6 +835,9 @@ static int service_load_sysv_path(Servic
* in the SysV
* services! */
r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_WANTS, m, NULL, true);
+ if (r >= 0 && streq(m, SPECIAL_NETWORK_ONLINE_TARGET))
+ r = unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_NETWORK_TARGET, NULL, true);
+ }
if (r < 0)
log_error_unit(u->id,

View File

@ -0,0 +1,38 @@
From 1f6d36f267186c0e3184bab4c7eca48481c6faab Mon Sep 17 00:00:00 2001
From: Hui Wang <hui.wang@canonical.com>
Date: Wed, 30 Jul 2014 16:09:08 +0800
Subject: [PATCH] keymap: Add microphone mute keymap for Dell Latitude
On the Dell Latitude, the mic mute key event is generated by wmi
driver, the keycode assigned to this hotkey from kernel is
KEY_MICMUTE (248), this keycode is too big for xorg to handle,
in the xorg, the XF86AudioMicMute is assigned to F20.
Please refer to 4e648ea0 of xkeyboard-config.
BugLink: https://bugs.launchpad.net/bugs/1326684
BugLink: https://bugs.launchpad.net/bugs/1339998
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Signed-off-by: Martin Pitt <martin.pitt@ubuntu.com>
---
hwdb/60-keyboard.hwdb | 4 ++++
1 file changed, 4 insertions(+)
diff --git hwdb/60-keyboard.hwdb hwdb/60-keyboard.hwdb
index c7ff4e4..70e372b 100644
--- hwdb/60-keyboard.hwdb
+++ hwdb/60-keyboard.hwdb
@@ -229,6 +229,10 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:pvr*
keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr*
KEYBOARD_KEY_8c=!unknown
+# Dell Latitude microphone mute
+keyboard:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*
+ KEYBOARD_KEY_150=f20 # Mic mute toggle
+
###########################################################
# Everex
###########################################################
--
1.7.9.2

View File

@ -0,0 +1,54 @@
From d946bb53f94713241004810de92cc37f1e19c2d2 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@ubuntu.com>
Date: Wed, 30 Jul 2014 10:54:23 +0200
Subject: [PATCH] keymap: Annotate all micmute workarounds
Add a comment to all assignments to f20 that this actually should be "micmute"
in a future when we aren't limited by X.org's key code limiations any more.
---
hwdb/60-keyboard.hwdb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git hwdb/60-keyboard.hwdb hwdb/60-keyboard.hwdb
index 70e372b..cbbbf2c 100644
--- hwdb/60-keyboard.hwdb
+++ hwdb/60-keyboard.hwdb
@@ -231,7 +231,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr*
# Dell Latitude microphone mute
keyboard:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*
- KEYBOARD_KEY_150=f20 # Mic mute toggle
+ KEYBOARD_KEY_150=f20 # Mic mute toggle, should be micmute
###########################################################
# Everex
@@ -505,7 +505,7 @@ keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*
KEYBOARD_KEY_15=volumedown
KEYBOARD_KEY_16=mute
KEYBOARD_KEY_17=prog1
- KEYBOARD_KEY_1a=f20
+ KEYBOARD_KEY_1a=f20 # Microphone mute button; should be micmute
# ThinkPad Keyboard with TrackPoint
keyboard:usb:v17EFp6009*
@@ -573,7 +573,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:pvr*
keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:pvr*
KEYBOARD_KEY_f1=f21
- KEYBOARD_KEY_ce=f20
+ KEYBOARD_KEY_ce=f20 # micmute
keyboard:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr*
KEYBOARD_KEY_a0=!mute
@@ -809,7 +809,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:*
KEYBOARD_KEY_f3=f17
KEYBOARD_KEY_f2=f18
KEYBOARD_KEY_f1=f19
- KEYBOARD_KEY_f0=f20
+ KEYBOARD_KEY_f0=f20 # micmute
KEYBOARD_KEY_ef=f21
KEYBOARD_KEY_ee=chat
KEYBOARD_KEY_e4=chat
--
1.7.9.2

View File

@ -0,0 +1,26 @@
Exist only to be able to apply the patch
1056-udevd-add-event-timeout-commandline-option.patch
without the BLKRRPART ioctl patches.
--- systemd-210/src/udev/udevd.c
+++ systemd-210/src/udev/udevd.c 2014-07-30 11:52:34.318235685 +0000
@@ -1311,16 +1311,16 @@ int main(int argc, char *argv[])
if (worker->state != WORKER_RUNNING)
continue;
- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) {
+ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * USEC_PER_SEC) {
log_error("worker [%u] %s timeout; kill it", worker->pid,
worker->event ? worker->event->devpath : "<idle>");
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
+
/* drop reference taken for state 'running' */
worker_unref(worker);
if (worker->event) {
- log_error("seq %llu '%s' killed",
- udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
+ log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
worker->event->exitcode = -64;
event_queue_delete(worker->event, true);
worker->event = NULL;

View File

@ -0,0 +1,119 @@
From 9719859c07aa13539ed2cd4b31972cd30f678543 Mon Sep 17 00:00:00 2001
From: Hannes Reinecke <hare@suse.de>
Date: Tue, 29 Jul 2014 09:06:14 +0200
Subject: [PATCH] udevd: add --event-timeout commandline option
Some events take longer than the default 30 seconds. Killing those
events will leave the machine halfway configured.
Add a commandline option '--event-timeout' to handle these cases.
---
man/systemd-udevd.service.xml | 19 +++++++++++++++++++
src/udev/udevd.c | 12 +++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git man/systemd-udevd.service.xml man/systemd-udevd.service.xml
index f44b7a0..8de43b1 100644
--- man/systemd-udevd.service.xml
+++ man/systemd-udevd.service.xml
@@ -44,6 +44,7 @@
<arg><option>--debug</option></arg>
<arg><option>--children-max=</option></arg>
<arg><option>--exec-delay=</option></arg>
+ <arg><option>--event-timeout=</option></arg>
<arg><option>--resolve-names=early|late|never</option></arg>
<arg><option>--version</option></arg>
<arg><option>--help</option></arg>
@@ -96,6 +97,15 @@
</varlistentry>
<varlistentry>
+ <term><option>--event-timeout=</option></term>
+ <listitem>
+ <para>Wait for the event to finish up to the given
+ number of seconds. After this time the event will
+ be terminated. Default is 30.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--resolve-names=</option></term>
<listitem>
<para>Specify when systemd-udevd should resolve names of users and groups.
@@ -156,6 +166,15 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>udev.event-timeout=</varname></term>
+ <term><varname>rd.udev.event-timeout=</varname></term>
+ <listitem>
+ <para>Wait for events to finish up to the given number
+ of seconds. This option might be useful if events are
+ terminated due to a timeout in large configurations.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>net.ifnames=</varname></term>
<listitem>
<para>Network interfaces are renamed to give them predictable names
diff --git src/udev/udevd.c src/udev/udevd.c
index db935d6..c5dd739 100644
--- src/udev/udevd.c
+++ src/udev/udevd.c
@@ -74,6 +74,7 @@ static bool reload;
static int children;
static int children_max;
static int exec_delay;
+static int event_timeout = 30;
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
@@ -312,6 +313,9 @@ static void worker_new(struct event *event)
}
}
+ if (event_timeout != 30)
+ udev_event->timeout_usec = event_timeout * USEC_PER_SEC;
+
/* apply rules, create node, symlinks */
udev_event_execute_rules(udev_event, rules, &sigmask_orig);
@@ -1009,6 +1013,8 @@ static void kernel_cmdline_options(struct udev *udev)
children_max = strtoul(opt + 18, NULL, 0);
} else if (startswith(opt, "udev.exec-delay=")) {
exec_delay = strtoul(opt + 16, NULL, 0);
+ } else if (startswith(opt, "udev.event-timeout=")) {
+ event_timeout = strtoul(opt + 16, NULL, 0);
}
free(s);
@@ -1026,6 +1032,7 @@ int main(int argc, char *argv[])
{ "debug", no_argument, NULL, 'D' },
{ "children-max", required_argument, NULL, 'c' },
{ "exec-delay", required_argument, NULL, 'e' },
+ { "event-timeout", required_argument, NULL, 't' },
{ "resolve-names", required_argument, NULL, 'N' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
@@ -1069,6 +1076,9 @@ int main(int argc, char *argv[])
case 'e':
exec_delay = strtoul(optarg, NULL, 0);
break;
+ case 't':
+ event_timeout = strtoul(optarg, NULL, 0);
+ break;
case 'D':
debug = true;
log_set_max_level(LOG_DEBUG);
@@ -1406,7 +1416,7 @@ int main(int argc, char *argv[])
if (worker->state != WORKER_RUNNING)
continue;
- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * USEC_PER_SEC) {
+ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout * USEC_PER_SEC) {
log_error("worker [%u] %s timeout; kill it", worker->pid,
worker->event ? worker->event->devpath : "<idle>");
kill(worker->pid, SIGKILL);
--
1.7.9.2

View File

@ -0,0 +1,504 @@
From dd5eddd28a74a49607a8fffcaf960040dba98479 Mon Sep 17 00:00:00 2001
From: Kay Sievers <kay@vrfy.org>
Date: Tue, 29 Jul 2014 15:18:27 +0200
Subject: [PATCH] udev: unify event timeout handling
---
man/systemd-udevd.service.xml | 7 +++---
man/udev.xml | 7 ------
src/test/test-udev.c | 5 ++--
src/udev/udev-event.c | 53 ++++++++++++++++++++++-------------------
src/udev/udev-rules.c | 38 ++++++++---------------------
src/udev/udev.h | 8 +++----
src/udev/udevadm-test.c | 2 +-
src/udev/udevd.c | 32 ++++++++++---------------
8 files changed, 61 insertions(+), 91 deletions(-)
diff --git man/systemd-udevd.service.xml man/systemd-udevd.service.xml
index 8de43b1..3053dc7 100644
--- man/systemd-udevd.service.xml
+++ man/systemd-udevd.service.xml
@@ -99,9 +99,8 @@
<varlistentry>
<term><option>--event-timeout=</option></term>
<listitem>
- <para>Wait for the event to finish up to the given
- number of seconds. After this time the event will
- be terminated. Default is 30.</para>
+ <para>Set the number of seconds to wait for events to finish. After
+ this time the event will be terminated. The default is 30 seconds.</para>
</listitem>
</varlistentry>
@@ -171,7 +170,7 @@
<listitem>
<para>Wait for events to finish up to the given number
of seconds. This option might be useful if events are
- terminated due to a timeout in large configurations.</para>
+ terminated due to kernel drivers taking too long to initialize.</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git man/udev.xml man/udev.xml
index 4e5f8f0..123c073 100644
--- man/udev.xml
+++ man/udev.xml
@@ -516,13 +516,6 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><option>event_timeout=</option></term>
- <listitem>
- <para>Number of seconds an event waits for operations to finish before
- giving up and terminating itself.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term><option>string_escape=<replaceable>none|replace</replaceable></option></term>
<listitem>
<para>Usually control and other possibly unsafe characters are replaced
diff --git src/test/test-udev.c src/test/test-udev.c
index b057cc8..26d6537 100644
--- src/test/test-udev.c
+++ src/test/test-udev.c
@@ -80,7 +80,6 @@ out:
return err;
}
-
int main(int argc, char *argv[]) {
_cleanup_udev_unref_ struct udev *udev = NULL;
_cleanup_udev_event_unref_ struct udev_event *event = NULL;
@@ -155,8 +154,8 @@ int main(int argc, char *argv[]) {
}
}
- udev_event_execute_rules(event, rules, &sigmask_orig);
- udev_event_execute_run(event, NULL);
+ udev_event_execute_rules(event, USEC_PER_SEC, rules, &sigmask_orig);
+ udev_event_execute_run(event, USEC_PER_SEC, NULL);
out:
if (event != NULL && event->fd_signal >= 0)
close(event->fd_signal);
diff --git src/udev/udev-event.c src/udev/udev-event.c
index 5213a4a..6ad80d5 100644
--- src/udev/udev-event.c
+++ src/udev/udev-event.c
@@ -48,7 +48,6 @@ struct udev_event *udev_event_new(struct udev_device *dev)
udev_list_init(udev, &event->seclabel_list, false);
event->fd_signal = -1;
event->birth_usec = now(CLOCK_MONOTONIC);
- event->timeout_usec = 30 * 1000 * 1000;
return event;
}
@@ -422,9 +421,10 @@ static int spawn_exec(struct udev_event *event,
}
static void spawn_read(struct udev_event *event,
- const char *cmd,
- int fd_stdout, int fd_stderr,
- char *result, size_t ressize)
+ usec_t timeout_usec,
+ const char *cmd,
+ int fd_stdout, int fd_stderr,
+ char *result, size_t ressize)
{
size_t respos = 0;
int fd_ep = -1;
@@ -467,15 +467,15 @@ static void spawn_read(struct udev_event *event,
struct epoll_event ev[4];
int i;
- if (event->timeout_usec > 0) {
+ if (timeout_usec > 0) {
usec_t age_usec;
age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
- if (age_usec >= event->timeout_usec) {
+ if (age_usec >= timeout_usec) {
log_error("timeout '%s'", cmd);
goto out;
}
- timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+ timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
} else {
timeout = -1;
}
@@ -543,8 +543,9 @@ out:
close(fd_ep);
}
-static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
-{
+static int spawn_wait(struct udev_event *event,
+ usec_t timeout_usec,
+ const char *cmd, pid_t pid) {
struct pollfd pfd[1];
int err = 0;
@@ -555,14 +556,14 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
int timeout;
int fdcount;
- if (event->timeout_usec > 0) {
+ if (timeout_usec > 0) {
usec_t age_usec;
age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
- if (age_usec >= event->timeout_usec)
+ if (age_usec >= timeout_usec)
timeout = 1000;
else
- timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+ timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
} else {
timeout = -1;
}
@@ -657,9 +658,9 @@ out:
}
int udev_event_spawn(struct udev_event *event,
+ usec_t timeout_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
- char *result, size_t ressize)
-{
+ char *result, size_t ressize) {
struct udev *udev = event->udev;
int outpipe[2] = {-1, -1};
int errpipe[2] = {-1, -1};
@@ -728,11 +729,13 @@ int udev_event_spawn(struct udev_event *event,
errpipe[WRITE_END] = -1;
}
- spawn_read(event, cmd,
- outpipe[READ_END], errpipe[READ_END],
- result, ressize);
+ spawn_read(event,
+ timeout_usec,
+ cmd,
+ outpipe[READ_END], errpipe[READ_END],
+ result, ressize);
- err = spawn_wait(event, cmd, pid);
+ err = spawn_wait(event, timeout_usec, cmd, pid);
}
out:
@@ -776,8 +779,9 @@ static int rename_netif(struct udev_event *event)
return r;
}
-void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask)
-{
+void udev_event_execute_rules(struct udev_event *event,
+ usec_t timeout_usec,
+ struct udev_rules *rules, const sigset_t *sigmask) {
struct udev_device *dev = event->dev;
if (udev_device_get_subsystem(dev) == NULL)
@@ -791,7 +795,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules
if (major(udev_device_get_devnum(dev)) != 0)
udev_watch_end(event->udev, dev);
- udev_rules_apply_to_event(rules, event, sigmask);
+ udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
@@ -808,7 +812,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules
udev_watch_end(event->udev, event->dev_db);
}
- udev_rules_apply_to_event(rules, event, sigmask);
+ udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
/* rename a new network interface, if needed */
if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
@@ -883,8 +887,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules
}
}
-void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
-{
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask) {
struct udev_list_entry *list_entry;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
@@ -907,7 +910,7 @@ void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
udev_event_apply_format(event, cmd, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
- udev_event_spawn(event, program, envp, sigmask, NULL, 0);
+ udev_event_spawn(event, timeout_usec, program, envp, sigmask, NULL, 0);
}
}
}
diff --git src/udev/udev-rules.c src/udev/udev-rules.c
index 9864016..aacde38 100644
--- src/udev/udev-rules.c
+++ src/udev/udev-rules.c
@@ -137,7 +137,6 @@ enum token_type {
TK_M_PARENTS_MAX,
TK_M_TEST, /* val, mode_t */
- TK_M_EVENT_TIMEOUT, /* int */
TK_M_PROGRAM, /* val */
TK_M_IMPORT_FILE, /* val */
TK_M_IMPORT_PROG, /* val */
@@ -201,7 +200,6 @@ struct token {
uid_t uid;
gid_t gid;
int devlink_prio;
- int event_timeout;
int watch;
enum udev_builtin_cmd builtin_cmd;
};
@@ -275,7 +273,6 @@ static const char *token_str(enum token_type type)
[TK_M_PARENTS_MAX] = "M PARENTS_MAX",
[TK_M_TEST] = "M TEST",
- [TK_M_EVENT_TIMEOUT] = "M EVENT_TIMEOUT",
[TK_M_PROGRAM] = "M PROGRAM",
[TK_M_IMPORT_FILE] = "M IMPORT_FILE",
[TK_M_IMPORT_PROG] = "M IMPORT_PROG",
@@ -409,9 +406,6 @@ static void dump_token(struct udev_rules *rules, struct token *token)
case TK_A_SECLABEL:
log_debug("%s %s '%s' '%s'", token_str(type), operation_str(op), attr, value);
break;
- case TK_M_EVENT_TIMEOUT:
- log_debug("%s %u", token_str(type), token->key.event_timeout);
- break;
case TK_A_GOTO:
log_debug("%s '%s' %u", token_str(type), value, token->key.rule_goto);
break;
@@ -627,8 +621,9 @@ static int import_file_into_properties(struct udev_device *dev, const char *file
return 0;
}
-static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
-{
+static int import_program_into_properties(struct udev_event *event,
+ usec_t timeout_usec,
+ const char *program, const sigset_t *sigmask) {
struct udev_device *dev = event->dev;
char **envp;
char result[UTIL_LINE_SIZE];
@@ -636,7 +631,7 @@ static int import_program_into_properties(struct udev_event *event, const char *
int err;
envp = udev_device_get_properties_envp(dev);
- err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result));
+ err = udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result));
if (err < 0)
return err;
@@ -942,9 +937,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_A_MODE_ID:
token->key.mode = *(mode_t *)data;
break;
- case TK_M_EVENT_TIMEOUT:
- token->key.event_timeout = *(int *)data;
- break;
case TK_RULE:
case TK_M_PARENTS_MIN:
case TK_M_PARENTS_MAX:
@@ -1462,14 +1454,6 @@ static int add_rule(struct udev_rules *rules, char *line,
rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
}
- pos = strstr(value, "event_timeout=");
- if (pos != NULL) {
- int tout = atoi(&pos[strlen("event_timeout=")]);
-
- rule_add_key(&rule_tmp, TK_M_EVENT_TIMEOUT, op, NULL, &tout);
- }
-
- pos = strstr(value, "string_escape=");
if (pos != NULL) {
pos = &pos[strlen("string_escape=")];
if (startswith(pos, "none"))
@@ -1829,8 +1813,10 @@ enum escape_type {
ESCAPE_REPLACE,
};
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask)
-{
+int udev_rules_apply_to_event(struct udev_rules *rules,
+ struct udev_event *event,
+ usec_t timeout_usec,
+ const sigset_t *sigmask) {
struct token *cur;
struct token *rule;
enum escape_type esc = ESCAPE_UNSET;
@@ -2024,10 +2010,6 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
goto nomatch;
break;
}
- case TK_M_EVENT_TIMEOUT:
- log_debug("OPTIONS event_timeout=%u", cur->key.event_timeout);
- event->timeout_usec = cur->key.event_timeout * 1000 * 1000;
- break;
case TK_M_PROGRAM: {
char program[UTIL_PATH_SIZE];
char **envp;
@@ -2042,7 +2024,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)) < 0) {
+ if (udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
if (cur->key.op != OP_NOMATCH)
goto nomatch;
} else {
@@ -2078,7 +2060,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (import_program_into_properties(event, import, sigmask) != 0)
+ if (import_program_into_properties(event, timeout_usec, import, sigmask) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
break;
diff --git src/udev/udev.h src/udev/udev.h
index 62538bc..4aca70b 100644
--- src/udev/udev.h
+++ src/udev/udev.h
@@ -43,7 +43,6 @@ struct udev_event {
struct udev_list run_list;
int exec_delay;
usec_t birth_usec;
- usec_t timeout_usec;
int fd_signal;
unsigned int builtin_run;
unsigned int builtin_ret;
@@ -72,7 +71,7 @@ struct udev_rules;
struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
struct udev_rules *udev_rules_unref(struct udev_rules *rules);
bool udev_rules_check_timestamp(struct udev_rules *rules);
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask);
+int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
@@ -82,10 +81,11 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
char *result, size_t maxsize, int read_value);
int udev_event_spawn(struct udev_event *event,
+ usec_t timeout_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
char *result, size_t ressize);
-void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset);
-void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset);
+void udev_event_execute_rules(struct udev_event *event, usec_t timeout_usec, struct udev_rules *rules, const sigset_t *sigset);
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigset);
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
/* udev-watch.c */
diff --git src/udev/udevadm-test.c src/udev/udevadm-test.c
index 6a2f548..52cc26c 100644
--- src/udev/udevadm-test.c
+++ src/udev/udevadm-test.c
@@ -138,7 +138,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[])
goto out;
}
- udev_event_execute_rules(event, rules, &sigmask_orig);
+ udev_event_execute_rules(event, 30 * USEC_PER_SEC, rules, &sigmask_orig);
udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
diff --git src/udev/udevd.c src/udev/udevd.c
index c5dd739..dee7a87 100644
--- src/udev/udevd.c
+++ src/udev/udevd.c
@@ -74,7 +74,7 @@ static bool reload;
static int children;
static int children_max;
static int exec_delay;
-static int event_timeout = 30;
+static usec_t event_timeout_usec = 30 * USEC_PER_SEC;
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
@@ -313,13 +313,10 @@ static void worker_new(struct event *event)
}
}
- if (event_timeout != 30)
- udev_event->timeout_usec = event_timeout * USEC_PER_SEC;
-
/* apply rules, create node, symlinks */
- udev_event_execute_rules(udev_event, rules, &sigmask_orig);
+ udev_event_execute_rules(udev_event, event_timeout_usec, rules, &sigmask_orig);
- udev_event_execute_run(udev_event, &sigmask_orig);
+ udev_event_execute_run(udev_event, event_timeout_usec, &sigmask_orig);
/* apply/restore inotify watch */
if (udev_event->inotify_watch) {
@@ -1014,15 +1011,14 @@ static void kernel_cmdline_options(struct udev *udev)
} else if (startswith(opt, "udev.exec-delay=")) {
exec_delay = strtoul(opt + 16, NULL, 0);
} else if (startswith(opt, "udev.event-timeout=")) {
- event_timeout = strtoul(opt + 16, NULL, 0);
+ event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC;
}
free(s);
}
}
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
struct udev *udev;
sigset_t mask;
int daemonize = false;
@@ -1077,7 +1073,7 @@ int main(int argc, char *argv[])
exec_delay = strtoul(optarg, NULL, 0);
break;
case 't':
- event_timeout = strtoul(optarg, NULL, 0);
+ event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC;
break;
case 'D':
debug = true;
@@ -1103,6 +1099,7 @@ int main(int argc, char *argv[])
" --debug\n"
" --children-max=<maximum number of workers>\n"
" --exec-delay=<seconds to wait before executing RUN=>\n"
+ " --event-timeout=<seconds to wait before terminating an event>\n"
" --resolve-names=early|late|never\n"
" --version\n"
" --help\n"
@@ -1416,20 +1413,17 @@ int main(int argc, char *argv[])
if (worker->state != WORKER_RUNNING)
continue;
- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout * USEC_PER_SEC) {
- log_error("worker [%u] %s timeout; kill it", worker->pid,
- worker->event ? worker->event->devpath : "<idle>");
+ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout_usec) {
+ log_error("worker [%u] %s timeout; kill it", worker->pid, worker->event->devpath);
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
/* drop reference taken for state 'running' */
worker_unref(worker);
- if (worker->event) {
- log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
- worker->event->exitcode = -64;
- event_queue_delete(worker->event);
- worker->event = NULL;
- }
+ log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
+ worker->event->exitcode = -64;
+ event_queue_delete(worker->event);
+ worker->event = NULL;
}
}
--
1.7.9.2

View File

@ -0,0 +1,504 @@
Based on dd5eddd28a74a49607a8fffcaf960040dba98479 Mon Sep 17 00:00:00 2001
From: Kay Sievers <kay@vrfy.org>
Date: Tue, 29 Jul 2014 15:18:27 +0200
Subject: [PATCH] udev: unify event timeout handling
---
man/systemd-udevd.service.xml | 7 +++---
man/udev.xml | 7 ------
src/test/test-udev.c | 5 ++--
src/udev/udev-event.c | 53 ++++++++++++++++++++++-------------------
src/udev/udev-rules.c | 38 ++++++++---------------------
src/udev/udev.h | 8 +++----
src/udev/udevadm-test.c | 2 +-
src/udev/udevd.c | 32 ++++++++++---------------
8 files changed, 61 insertions(+), 91 deletions(-)
diff --git man/systemd-udevd.service.xml man/systemd-udevd.service.xml
index 8de43b1..3053dc7 100644
--- man/systemd-udevd.service.xml
+++ man/systemd-udevd.service.xml
@@ -99,9 +99,8 @@
<varlistentry>
<term><option>--event-timeout=</option></term>
<listitem>
- <para>Wait for the event to finish up to the given
- number of seconds. After this time the event will
- be terminated. Default is 30.</para>
+ <para>Set the number of seconds to wait for events to finish. After
+ this time the event will be terminated. The default is 30 seconds.</para>
</listitem>
</varlistentry>
@@ -171,7 +170,7 @@
<listitem>
<para>Wait for events to finish up to the given number
of seconds. This option might be useful if events are
- terminated due to a timeout in large configurations.</para>
+ terminated due to kernel drivers taking too long to initialize.</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git man/udev.xml man/udev.xml
index 4e5f8f0..123c073 100644
--- man/udev.xml
+++ man/udev.xml
@@ -516,13 +516,6 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><option>event_timeout=</option></term>
- <listitem>
- <para>Number of seconds an event waits for operations to finish before
- giving up and terminating itself.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term><option>string_escape=<replaceable>none|replace</replaceable></option></term>
<listitem>
<para>Usually control and other possibly unsafe characters are replaced
diff --git src/test/test-udev.c src/test/test-udev.c
index b057cc8..26d6537 100644
--- src/test/test-udev.c
+++ src/test/test-udev.c
@@ -80,7 +80,6 @@ out:
return err;
}
-
int main(int argc, char *argv[]) {
_cleanup_udev_unref_ struct udev *udev = NULL;
_cleanup_udev_event_unref_ struct udev_event *event = NULL;
@@ -155,8 +154,8 @@ int main(int argc, char *argv[]) {
}
}
- udev_event_execute_rules(event, rules, &sigmask_orig);
- udev_event_execute_run(event, NULL);
+ udev_event_execute_rules(event, USEC_PER_SEC, rules, &sigmask_orig);
+ udev_event_execute_run(event, USEC_PER_SEC, NULL);
out:
if (event != NULL && event->fd_signal >= 0)
close(event->fd_signal);
diff --git src/udev/udev-event.c src/udev/udev-event.c
index 5213a4a..6ad80d5 100644
--- src/udev/udev-event.c
+++ src/udev/udev-event.c
@@ -48,7 +48,6 @@ struct udev_event *udev_event_new(struct udev_device *dev)
udev_list_init(udev, &event->seclabel_list, false);
event->fd_signal = -1;
event->birth_usec = now(CLOCK_MONOTONIC);
- event->timeout_usec = 30 * 1000 * 1000;
return event;
}
@@ -422,9 +421,10 @@ static int spawn_exec(struct udev_event *event,
}
static void spawn_read(struct udev_event *event,
- const char *cmd,
- int fd_stdout, int fd_stderr,
- char *result, size_t ressize)
+ usec_t timeout_usec,
+ const char *cmd,
+ int fd_stdout, int fd_stderr,
+ char *result, size_t ressize)
{
size_t respos = 0;
int fd_ep = -1;
@@ -467,15 +467,15 @@ static void spawn_read(struct udev_event *event,
struct epoll_event ev[4];
int i;
- if (event->timeout_usec > 0) {
+ if (timeout_usec > 0) {
usec_t age_usec;
age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
- if (age_usec >= event->timeout_usec) {
+ if (age_usec >= timeout_usec) {
log_error("timeout '%s'", cmd);
goto out;
}
- timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+ timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
} else {
timeout = -1;
}
@@ -543,8 +543,9 @@ out:
close(fd_ep);
}
-static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
-{
+static int spawn_wait(struct udev_event *event,
+ usec_t timeout_usec,
+ const char *cmd, pid_t pid) {
struct pollfd pfd[1];
int err = 0;
@@ -555,14 +556,14 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
int timeout;
int fdcount;
- if (event->timeout_usec > 0) {
+ if (timeout_usec > 0) {
usec_t age_usec;
age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
- if (age_usec >= event->timeout_usec)
+ if (age_usec >= timeout_usec)
timeout = 1000;
else
- timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+ timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
} else {
timeout = -1;
}
@@ -657,9 +658,9 @@ out:
}
int udev_event_spawn(struct udev_event *event,
+ usec_t timeout_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
- char *result, size_t ressize)
-{
+ char *result, size_t ressize) {
struct udev *udev = event->udev;
int outpipe[2] = {-1, -1};
int errpipe[2] = {-1, -1};
@@ -728,11 +729,13 @@ int udev_event_spawn(struct udev_event *event,
errpipe[WRITE_END] = -1;
}
- spawn_read(event, cmd,
- outpipe[READ_END], errpipe[READ_END],
- result, ressize);
+ spawn_read(event,
+ timeout_usec,
+ cmd,
+ outpipe[READ_END], errpipe[READ_END],
+ result, ressize);
- err = spawn_wait(event, cmd, pid);
+ err = spawn_wait(event, timeout_usec, cmd, pid);
}
out:
@@ -776,8 +779,9 @@ static int rename_netif(struct udev_event *event)
return r;
}
-void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask)
-{
+void udev_event_execute_rules(struct udev_event *event,
+ usec_t timeout_usec,
+ struct udev_rules *rules, const sigset_t *sigmask) {
struct udev_device *dev = event->dev;
if (udev_device_get_subsystem(dev) == NULL)
@@ -791,7 +795,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules
if (major(udev_device_get_devnum(dev)) != 0)
udev_watch_end(event->udev, dev);
- udev_rules_apply_to_event(rules, event, sigmask);
+ udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
@@ -808,7 +812,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules
udev_watch_end(event->udev, event->dev_db);
}
- udev_rules_apply_to_event(rules, event, sigmask);
+ udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
/* rename a new network interface, if needed */
if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
@@ -883,8 +887,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules
}
}
-void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
-{
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask) {
struct udev_list_entry *list_entry;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
@@ -907,7 +910,7 @@ void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
udev_event_apply_format(event, cmd, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
- udev_event_spawn(event, program, envp, sigmask, NULL, 0);
+ udev_event_spawn(event, timeout_usec, program, envp, sigmask, NULL, 0);
}
}
}
diff --git src/udev/udev-rules.c src/udev/udev-rules.c
index 9864016..aacde38 100644
--- src/udev/udev-rules.c
+++ src/udev/udev-rules.c
@@ -137,7 +137,6 @@ enum token_type {
TK_M_PARENTS_MAX,
TK_M_TEST, /* val, mode_t */
- TK_M_EVENT_TIMEOUT, /* int */
TK_M_PROGRAM, /* val */
TK_M_IMPORT_FILE, /* val */
TK_M_IMPORT_PROG, /* val */
@@ -201,7 +200,6 @@ struct token {
uid_t uid;
gid_t gid;
int devlink_prio;
- int event_timeout;
int watch;
enum udev_builtin_cmd builtin_cmd;
};
@@ -275,7 +273,6 @@ static const char *token_str(enum token_type type)
[TK_M_PARENTS_MAX] = "M PARENTS_MAX",
[TK_M_TEST] = "M TEST",
- [TK_M_EVENT_TIMEOUT] = "M EVENT_TIMEOUT",
[TK_M_PROGRAM] = "M PROGRAM",
[TK_M_IMPORT_FILE] = "M IMPORT_FILE",
[TK_M_IMPORT_PROG] = "M IMPORT_PROG",
@@ -409,9 +406,6 @@ static void dump_token(struct udev_rules *rules, struct token *token)
case TK_A_SECLABEL:
log_debug("%s %s '%s' '%s'", token_str(type), operation_str(op), attr, value);
break;
- case TK_M_EVENT_TIMEOUT:
- log_debug("%s %u", token_str(type), token->key.event_timeout);
- break;
case TK_A_GOTO:
log_debug("%s '%s' %u", token_str(type), value, token->key.rule_goto);
break;
@@ -627,8 +621,9 @@ static int import_file_into_properties(struct udev_device *dev, const char *file
return 0;
}
-static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
-{
+static int import_program_into_properties(struct udev_event *event,
+ usec_t timeout_usec,
+ const char *program, const sigset_t *sigmask) {
struct udev_device *dev = event->dev;
char **envp;
char result[UTIL_LINE_SIZE];
@@ -636,7 +631,7 @@ static int import_program_into_properties(struct udev_event *event, const char *
int err;
envp = udev_device_get_properties_envp(dev);
- err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result));
+ err = udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result));
if (err < 0)
return err;
@@ -942,9 +937,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_A_MODE_ID:
token->key.mode = *(mode_t *)data;
break;
- case TK_M_EVENT_TIMEOUT:
- token->key.event_timeout = *(int *)data;
- break;
case TK_RULE:
case TK_M_PARENTS_MIN:
case TK_M_PARENTS_MAX:
@@ -1462,14 +1454,6 @@ static int add_rule(struct udev_rules *rules, char *line,
rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
}
- pos = strstr(value, "event_timeout=");
- if (pos != NULL) {
- int tout = atoi(&pos[strlen("event_timeout=")]);
-
- rule_add_key(&rule_tmp, TK_M_EVENT_TIMEOUT, op, NULL, &tout);
- }
-
- pos = strstr(value, "string_escape=");
if (pos != NULL) {
pos = &pos[strlen("string_escape=")];
if (startswith(pos, "none"))
@@ -1829,8 +1813,10 @@ enum escape_type {
ESCAPE_REPLACE,
};
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask)
-{
+int udev_rules_apply_to_event(struct udev_rules *rules,
+ struct udev_event *event,
+ usec_t timeout_usec,
+ const sigset_t *sigmask) {
struct token *cur;
struct token *rule;
enum escape_type esc = ESCAPE_UNSET;
@@ -2024,10 +2010,6 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
goto nomatch;
break;
}
- case TK_M_EVENT_TIMEOUT:
- log_debug("OPTIONS event_timeout=%u", cur->key.event_timeout);
- event->timeout_usec = cur->key.event_timeout * 1000 * 1000;
- break;
case TK_M_PROGRAM: {
char program[UTIL_PATH_SIZE];
char **envp;
@@ -2042,7 +2024,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)) < 0) {
+ if (udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
if (cur->key.op != OP_NOMATCH)
goto nomatch;
} else {
@@ -2078,7 +2060,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (import_program_into_properties(event, import, sigmask) != 0)
+ if (import_program_into_properties(event, timeout_usec, import, sigmask) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
break;
diff --git src/udev/udev.h src/udev/udev.h
index 62538bc..4aca70b 100644
--- src/udev/udev.h
+++ src/udev/udev.h
@@ -43,7 +43,6 @@ struct udev_event {
struct udev_list run_list;
int exec_delay;
usec_t birth_usec;
- usec_t timeout_usec;
int fd_signal;
unsigned int builtin_run;
unsigned int builtin_ret;
@@ -72,7 +71,7 @@ struct udev_rules;
struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
struct udev_rules *udev_rules_unref(struct udev_rules *rules);
bool udev_rules_check_timestamp(struct udev_rules *rules);
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask);
+int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
@@ -82,10 +81,11 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
char *result, size_t maxsize, int read_value);
int udev_event_spawn(struct udev_event *event,
+ usec_t timeout_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
char *result, size_t ressize);
-void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset);
-void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset);
+void udev_event_execute_rules(struct udev_event *event, usec_t timeout_usec, struct udev_rules *rules, const sigset_t *sigset);
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigset);
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
/* udev-watch.c */
diff --git src/udev/udevadm-test.c src/udev/udevadm-test.c
index 6a2f548..52cc26c 100644
--- src/udev/udevadm-test.c
+++ src/udev/udevadm-test.c
@@ -138,7 +138,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[])
goto out;
}
- udev_event_execute_rules(event, rules, &sigmask_orig);
+ udev_event_execute_rules(event, 30 * USEC_PER_SEC, rules, &sigmask_orig);
udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
diff --git src/udev/udevd.c src/udev/udevd.c
index c5dd739..dee7a87 100644
--- src/udev/udevd.c
+++ src/udev/udevd.c
@@ -74,7 +74,7 @@ static bool reload;
static int children;
static int children_max;
static int exec_delay;
-static int event_timeout = 30;
+static usec_t event_timeout_usec = 30 * USEC_PER_SEC;
static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
@@ -313,13 +313,10 @@ static void worker_new(struct event *event)
}
}
- if (event_timeout != 30)
- udev_event->timeout_usec = event_timeout * USEC_PER_SEC;
-
/* apply rules, create node, symlinks */
- udev_event_execute_rules(udev_event, rules, &sigmask_orig);
+ udev_event_execute_rules(udev_event, event_timeout_usec, rules, &sigmask_orig);
- udev_event_execute_run(udev_event, &sigmask_orig);
+ udev_event_execute_run(udev_event, event_timeout_usec, &sigmask_orig);
/* apply/restore inotify watch */
if (udev_event->inotify_watch) {
@@ -1014,15 +1011,14 @@ static void kernel_cmdline_options(struct udev *udev)
} else if (startswith(opt, "udev.exec-delay=")) {
exec_delay = strtoul(opt + 16, NULL, 0);
} else if (startswith(opt, "udev.event-timeout=")) {
- event_timeout = strtoul(opt + 16, NULL, 0);
+ event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC;
}
free(s);
}
}
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
struct udev *udev;
sigset_t mask;
int daemonize = false;
@@ -1077,7 +1073,7 @@ int main(int argc, char *argv[])
exec_delay = strtoul(optarg, NULL, 0);
break;
case 't':
- event_timeout = strtoul(optarg, NULL, 0);
+ event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC;
break;
case 'D':
debug = true;
@@ -1103,6 +1099,7 @@ int main(int argc, char *argv[])
" --debug\n"
" --children-max=<maximum number of workers>\n"
" --exec-delay=<seconds to wait before executing RUN=>\n"
+ " --event-timeout=<seconds to wait before terminating an event>\n"
" --resolve-names=early|late|never\n"
" --version\n"
" --help\n"
@@ -1416,20 +1413,17 @@ int main(int argc, char *argv[])
if (worker->state != WORKER_RUNNING)
continue;
- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout * USEC_PER_SEC) {
- log_error("worker [%u] %s timeout; kill it", worker->pid,
- worker->event ? worker->event->devpath : "<idle>");
+ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout_usec) {
+ log_error("worker [%u] %s timeout; kill it", worker->pid, worker->event->devpath);
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
/* drop reference taken for state 'running' */
worker_unref(worker);
- if (worker->event) {
- log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
- worker->event->exitcode = -64;
- event_queue_delete(worker->event, true);
- worker->event = NULL;
- }
+ log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
+ worker->event->exitcode = -64;
+ event_queue_delete(worker->event, true);
+ worker->event = NULL;
}
}
--
1.7.9.2

View File

@ -0,0 +1,26 @@
From 9f20a8a376f924c8eb5423cfc1f98644fc1e2d1a Mon Sep 17 00:00:00 2001
From: Hannes Reinecke <hare@suse.de>
Date: Wed, 30 Jul 2014 10:10:46 +0200
Subject: [PATCH] udev: fixup commit dd5eddd28a74a49607a8fffcaf960040dba98479
Commit dd5eddd28a74a49607a8fffcaf960040dba98479 accidentally
removed one line too many.
---
src/udev/udev-rules.c | 1 +
1 file changed, 1 insertion(+)
diff --git src/udev/udev-rules.c src/udev/udev-rules.c
index 59bc124..cc56215 100644
--- src/udev/udev-rules.c
+++ src/udev/udev-rules.c
@@ -1436,6 +1436,7 @@ static int add_rule(struct udev_rules *rules, char *line,
rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
}
+ pos = strstr(value, "string_escape=");
if (pos != NULL) {
pos = &pos[strlen("string_escape=")];
if (startswith(pos, "none"))
--
1.7.9.2

View File

@ -0,0 +1,43 @@
From: Jeff Mahoney <jeffm@suse.com>
Subject: udev: use device mapper target name for btrfs device ready
References: bnc#888215
When udev gets a change event for a block device, it calls the builtin
btrfs helper to scan it for a btrfs file system. If the file system was
mounted using a device mapper node, mount(8) will have looked up the
device mapper table and used the /dev/mapper/<name> node for mount.
If something like partprobe runs, and then causes change events to be
handled, the btrfs ready event is handled using /dev/dm-N instead of
the device mapper named node. Btrfs caches the last name passed to
the scanning ioctl and uses that to report the device name for
things like /proc/mounts.
So, after running partprobe we go from:
/dev/mapper/test-test on /mnt type btrfs (rw,relatime,space_cache)
... to ...
/dev/dm-0 on /mnt type btrfs (rw,relatime,space_cache)
This doesn't apply only to LVM device, but multipath as well.
If the device is a DM device, udev will have already cached the table name
from sysfs and we can use that to pass /dev/mapper/<name> to the builtin
so that the correct name is used.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
rules/64-btrfs.rules | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/rules/64-btrfs.rules
+++ b/rules/64-btrfs.rules
@@ -6,7 +6,8 @@ ENV{ID_FS_TYPE}!="btrfs", GOTO="btrfs_en
ENV{SYSTEMD_READY}=="0", GOTO="btrfs_end"
# let the kernel know about this btrfs filesystem, and check if it is complete
-IMPORT{builtin}="btrfs ready $devnode"
+ENV{DM_NAME}=="", IMPORT{builtin}="btrfs ready $devnode"
+ENV{DM_NAME}=="?*", IMPORT{builtin}="btrfs ready /dev/mapper/$env{DM_NAME}"
# mark the device as not ready to be used by the system
ENV{ID_BTRFS_READY}=="0", ENV{SYSTEMD_READY}="0"

View File

@ -1,3 +1,53 @@
-------------------------------------------------------------------
Thu Jul 31 07:55:47 UTC 2014 - rmilasan@suse.com
- Rename:
udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
to
1060-udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
-------------------------------------------------------------------
Wed Jul 30 21:10:21 UTC 2014 - jeffm@suse.com
- udev: use device mapper target name for btrfs device ready (bnc#888215).
- Add udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
-------------------------------------------------------------------
Wed Jul 30 12:53:07 UTC 2014 - werner@suse.de
- Add patch tomcat6-var-lock-subsys-legacy.patch to add the
compatibility directory /var/lock/subsys (bnc#889357)
-------------------------------------------------------------------
Wed Jul 30 11:45:21 UTC 2014 - werner@suse.de
- Add portabiltiy patch
1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch
-------------------------------------------------------------------
Wed Jul 30 11:32:23 UTC 2014 - werner@suse.de
- Port and add upstream patch
0001-sysv-order-initscripts-which-provide-network-before-.patch
0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch
0003-keymap-Annotate-all-micmute-workarounds.patch
-------------------------------------------------------------------
Wed Jul 30 11:10:34 UTC 2014 - werner@suse.de
- Add patch tty-ask-password-agent-on-console.patch that is for system
console do ask passphrases on all devices of the console (bnc#886211)
-------------------------------------------------------------------
Wed Jul 30 11:02:27 UTC 2014 - werner@suse.de
- Add former SUSE and/now upstream patches (bnc#889297)
1056-udevd-add-event-timeout-commandline-option.patch
1057-udev-unify-event-timeout-handling.patch
1058-udev-unify-event-timeout-handling.patch (backport for
compatibility if patch 1022 is not applied)
1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch
-------------------------------------------------------------------
Mon Jul 28 10:08:15 UTC 2014 - werner@suse.de

View File

@ -749,6 +749,16 @@ Patch359: 0007-drop_duplicates-copy-full-BindMount-struct.patch
Patch360: 0008-shell-completion-prevent-mangling-unit-names-bash.patch
# PATCH-FIX-UPSTREAM added at 2014/07/28
Patch361: 0009-journald-always-add-syslog-facility-for-messages-com.patch
# PATCH-FIX-SUSE For system console do ask passphrases on all devices of the console
Patch362: tty-ask-password-agent-on-console.patch
# PATCH-FIX-UPSTREAM added at 2014/07/30
Patch363: 0001-sysv-order-initscripts-which-provide-network-before-.patch
# PATCH-FIX-UPSTREAM added at 2014/07/30
Patch364: 0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch
# PATCH-FIX-UPSTREAM added at 2014/07/30
Patch365: 0003-keymap-Annotate-all-micmute-workarounds.patch
# PATCH-FIX-SUSE Provide the /var/lock/subsys at start (bnc#889357)
Patch366: tomcat6-var-lock-subsys-legacy.patch
# UDEV PATCHES
# ============
@ -864,6 +874,18 @@ Patch1052: 1052-rules-uaccess-add-ID_SOFTWARE_RADIO.patch
Patch1053: 1053-better-checks-in-write_net_rules.patch
# PATCH-FIX-SUSE 0001-udev-exclude-MD-from-block-device-ownership-event-lo.patch
Patch1054: 1054-udev-exclude-MD-from-block-device-ownership-event-lo.patch
# PATCH-FIX-SUSE 1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch
Patch1055: 1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch
# PATCH-FIX-UPSTREAM 1056-udevd-add-event-timeout-commandline-option.patch
Patch1056: 1056-udevd-add-event-timeout-commandline-option.patch
# PATCH-FIX-UPSTREAM 1057-udev-unify-event-timeout-handling.patch
Patch1057: 1057-udev-unify-event-timeout-handling.patch
# PATCH-FIX-UPSTREAM 1058-udev-unify-event-timeout-handling.patch
Patch1058: 1058-udev-unify-event-timeout-handling.patch
# PATCH-FIX-UPSTREAM 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch
Patch1059: 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch
# PATCH-FIX-SUSE 1060-udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
Patch1060: 1060-udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
%description
Systemd is a system and service manager, compatible with SysV and LSB
@ -1384,6 +1406,11 @@ cp %{SOURCE7} m4/
%patch359 -p0
%patch360 -p0
%patch361 -p0
%patch362 -p1
%patch363 -p0
%patch364 -p0
%patch365 -p0
%patch366 -p1
# udev patches
%patch1001 -p1
@ -1456,7 +1483,17 @@ cp %{SOURCE7} m4/
%patch1053 -p1
%if %{with blkrrpart}
%patch1054 -p0
%else
%patch1055 -p1
%endif
%patch1056 -p0
%if %{with udevsettle}
%patch1057 -p0
%else
%patch1058 -p0
%endif
%patch1059 -p0
%patch1060 -p1
# ensure generate files are removed
rm -f units/emergency.service

View File

@ -1,3 +1,53 @@
-------------------------------------------------------------------
Thu Jul 31 07:55:47 UTC 2014 - rmilasan@suse.com
- Rename:
udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
to
1060-udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
-------------------------------------------------------------------
Wed Jul 30 21:10:21 UTC 2014 - jeffm@suse.com
- udev: use device mapper target name for btrfs device ready (bnc#888215).
- Add udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
-------------------------------------------------------------------
Wed Jul 30 12:53:07 UTC 2014 - werner@suse.de
- Add patch tomcat6-var-lock-subsys-legacy.patch to add the
compatibility directory /var/lock/subsys (bnc#889357)
-------------------------------------------------------------------
Wed Jul 30 11:45:21 UTC 2014 - werner@suse.de
- Add portabiltiy patch
1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch
-------------------------------------------------------------------
Wed Jul 30 11:32:23 UTC 2014 - werner@suse.de
- Port and add upstream patch
0001-sysv-order-initscripts-which-provide-network-before-.patch
0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch
0003-keymap-Annotate-all-micmute-workarounds.patch
-------------------------------------------------------------------
Wed Jul 30 11:10:34 UTC 2014 - werner@suse.de
- Add patch tty-ask-password-agent-on-console.patch that is for system
console do ask passphrases on all devices of the console (bnc#886211)
-------------------------------------------------------------------
Wed Jul 30 11:02:27 UTC 2014 - werner@suse.de
- Add former SUSE and/now upstream patches (bnc#889297)
1056-udevd-add-event-timeout-commandline-option.patch
1057-udev-unify-event-timeout-handling.patch
1058-udev-unify-event-timeout-handling.patch (backport for
compatibility if patch 1022 is not applied)
1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch
-------------------------------------------------------------------
Mon Jul 28 10:08:15 UTC 2014 - werner@suse.de

View File

@ -744,6 +744,16 @@ Patch359: 0007-drop_duplicates-copy-full-BindMount-struct.patch
Patch360: 0008-shell-completion-prevent-mangling-unit-names-bash.patch
# PATCH-FIX-UPSTREAM added at 2014/07/28
Patch361: 0009-journald-always-add-syslog-facility-for-messages-com.patch
# PATCH-FIX-SUSE For system console do ask passphrases on all devices of the console
Patch362: tty-ask-password-agent-on-console.patch
# PATCH-FIX-UPSTREAM added at 2014/07/30
Patch363: 0001-sysv-order-initscripts-which-provide-network-before-.patch
# PATCH-FIX-UPSTREAM added at 2014/07/30
Patch364: 0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch
# PATCH-FIX-UPSTREAM added at 2014/07/30
Patch365: 0003-keymap-Annotate-all-micmute-workarounds.patch
# PATCH-FIX-SUSE Provide the /var/lock/subsys at start (bnc#889357)
Patch366: tomcat6-var-lock-subsys-legacy.patch
# UDEV PATCHES
# ============
@ -859,6 +869,18 @@ Patch1052: 1052-rules-uaccess-add-ID_SOFTWARE_RADIO.patch
Patch1053: 1053-better-checks-in-write_net_rules.patch
# PATCH-FIX-SUSE 0001-udev-exclude-MD-from-block-device-ownership-event-lo.patch
Patch1054: 1054-udev-exclude-MD-from-block-device-ownership-event-lo.patch
# PATCH-FIX-SUSE 1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch
Patch1055: 1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch
# PATCH-FIX-UPSTREAM 1056-udevd-add-event-timeout-commandline-option.patch
Patch1056: 1056-udevd-add-event-timeout-commandline-option.patch
# PATCH-FIX-UPSTREAM 1057-udev-unify-event-timeout-handling.patch
Patch1057: 1057-udev-unify-event-timeout-handling.patch
# PATCH-FIX-UPSTREAM 1058-udev-unify-event-timeout-handling.patch
Patch1058: 1058-udev-unify-event-timeout-handling.patch
# PATCH-FIX-UPSTREAM 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch
Patch1059: 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch
# PATCH-FIX-SUSE 1060-udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
Patch1060: 1060-udev-use-device-mapper-target-name-for-btrfs-device-ready.patch
%description
Systemd is a system and service manager, compatible with SysV and LSB
@ -1379,6 +1401,11 @@ cp %{SOURCE7} m4/
%patch359 -p0
%patch360 -p0
%patch361 -p0
%patch362 -p1
%patch363 -p0
%patch364 -p0
%patch365 -p0
%patch366 -p1
# udev patches
%patch1001 -p1
@ -1451,7 +1478,17 @@ cp %{SOURCE7} m4/
%patch1053 -p1
%if %{with blkrrpart}
%patch1054 -p0
%else
%patch1055 -p1
%endif
%patch1056 -p0
%if %{with udevsettle}
%patch1057 -p0
%else
%patch1058 -p0
%endif
%patch1059 -p0
%patch1060 -p1
# ensure generate files are removed
rm -f units/emergency.service

View File

@ -0,0 +1,18 @@
Provide /run/lock/subsys directory to be able to provide the
/var/lock/subsys via the symbolic link /var/lock (bnc#889357)
---
tmpfiles.d/legacy.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- systemd-210/tmpfiles.d/legacy.conf
+++ systemd-210/tmpfiles.d/legacy.conf 2014-07-30 12:36:36.862735670 +0000
@@ -16,7 +16,7 @@ d /run/lock 0775 root lock -
# /run/lock/subsys is used for serializing SysV service execution, and
# hence without use on SysV-less systems.
-#d /run/lock/subsys 0755 root root -
+d /run/lock/subsys 0755 root root -
# /run/lock/lockdev is used to serialize access to tty devices via
# LCK..xxx style lock files, For more information see:

View File

@ -0,0 +1,285 @@
---
src/tty-ask-password-agent/tty-ask-password-agent.c | 190 +++++++++++++++++++-
1 file changed, 185 insertions(+), 5 deletions(-)
--- systemd-210/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ systemd-210/src/tty-ask-password-agent/tty-ask-password-agent.c 2014-07-30 10:48:43.602052750 +0000
@@ -28,8 +28,12 @@
#include <sys/poll.h>
#include <sys/inotify.h>
#include <unistd.h>
+#include <sys/prctl.h>
#include <getopt.h>
+#include <signal.h>
+#include <sys/wait.h>
#include <sys/signalfd.h>
+#include <sys/mman.h>
#include <fcntl.h>
#include "util.h"
@@ -41,6 +45,9 @@
#include "ask-password-api.h"
#include "strv.h"
#include "build.h"
+#include "fileio.h"
+#include "macro.h"
+#include "list.h"
static enum {
ACTION_LIST,
@@ -49,6 +56,21 @@ static enum {
ACTION_WALL
} arg_action = ACTION_QUERY;
+struct console {
+ LIST_FIELDS(struct console, handle);
+ char *tty;
+ pid_t pid;
+ int id;
+};
+
+static volatile uint32_t *usemask;
+static volatile sig_atomic_t sigchild;
+static void chld_handler(int sig)
+{
+ (void)sig;
+ sigchild++;
+}
+
static bool arg_plymouth = false;
static bool arg_console = false;
@@ -246,12 +268,77 @@ finish:
return r;
}
+static const char *current_dev = "/dev/console";
+static LIST_HEAD(struct console, consoles);
+static int collect_consoles(void) {
+ _cleanup_free_ char *active = NULL;
+ char *w, *state;
+ struct console *c;
+ size_t l;
+ int id;
+ int r;
+
+ r = read_one_line_file("/sys/class/tty/console/active", &active);
+ if (r < 0)
+ return r;
+
+ id = 0;
+ FOREACH_WORD(w, l, active, state) {
+ _cleanup_free_ char *tty = NULL;
+
+ if (strneq(w, "tty0", l)) {
+ if (read_one_line_file("/sys/class/tty/tty0/active", &tty) >= 0) {
+ w = tty;
+ l = strlen(tty);
+ }
+ }
+
+ c = malloc0(sizeof(struct console)+5+l+1);
+ if (!c) {
+ log_oom();
+ continue;
+ }
+
+ c->tty = ((char*)c)+sizeof(struct console);
+ stpncpy(stpcpy(c->tty, "/dev/"),w,l);
+ c->id = id++;
+
+ LIST_PREPEND(handle, consoles, c);
+ }
+
+ if (!consoles) {
+
+ c = malloc0(sizeof(struct console));
+ if (!c) {
+ log_oom();
+ return -ENOMEM;
+ }
+
+ c->tty = (char *)current_dev;
+ c->id = id++;
+
+ LIST_PREPEND(handle, consoles, c);
+ }
+
+ return 0;
+}
+
+static void free_consoles(void) {
+ struct console *c;
+ LIST_FOREACH(handle, c, consoles) {
+ LIST_REMOVE(handle, consoles, c);
+ free(c);
+ }
+ LIST_HEAD_INIT(consoles);
+}
+
static int parse_password(const char *filename, char **wall) {
char *socket_name = NULL, *message = NULL, *packet = NULL;
uint64_t not_after = 0;
unsigned pid = 0;
int socket_fd = -1;
bool accept_cached = false;
+ size_t packet_length = 0;
const ConfigTableItem items[] = {
{ "Ask", "Socket", config_parse_string, 0, &socket_name },
@@ -323,7 +410,6 @@ static int parse_password(const char *fi
struct sockaddr sa;
struct sockaddr_un un;
} sa = {};
- size_t packet_length = 0;
assert(arg_action == ACTION_QUERY ||
arg_action == ACTION_WATCH);
@@ -365,7 +451,7 @@ static int parse_password(const char *fi
char *password = NULL;
if (arg_console)
- if ((tty_fd = acquire_terminal("/dev/console", false, false, false, (usec_t) -1)) < 0) {
+ if ((tty_fd = acquire_terminal(current_dev, false, false, true, (usec_t) -1)) < 0) {
r = tty_fd;
goto finish;
}
@@ -386,6 +472,7 @@ static int parse_password(const char *fi
strcpy(packet+1, password);
}
+ memset(password, 0, strlen(password));
free(password);
}
}
@@ -423,6 +510,7 @@ finish:
if (socket_fd >= 0)
close_nointr_nofail(socket_fd);
+ memset(packet, 0, packet_length);
free(packet);
free(socket_name);
free(message);
@@ -726,8 +814,10 @@ static int parse_argv(int argc, char *ar
}
int main(int argc, char *argv[]) {
+ int id = 0;
int r;
+ LIST_HEAD_INIT(consoles);
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
log_open();
@@ -737,11 +827,99 @@ int main(int argc, char *argv[]) {
if ((r = parse_argv(argc, argv)) <= 0)
goto finish;
+ usemask = (uint32_t*) mmap(NULL, sizeof(uint32_t), PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_SHARED, -1, 0);
+
if (arg_console) {
- setsid();
- release_terminal();
- }
+ if (!arg_plymouth && arg_action != ACTION_WALL &&
+ arg_action != ACTION_LIST) {
+ struct console *c;
+ struct sigaction sig = {
+ .sa_handler = chld_handler,
+ .sa_flags = SA_NOCLDSTOP|SA_RESTART,
+ };
+ struct sigaction oldsig;
+ sigset_t set, oldset;
+ int status = 0;
+ pid_t job;
+
+ collect_consoles();
+
+ if (!consoles->handle_next) {
+ consoles->pid = 0;
+ c = consoles;
+ goto nofork;
+ }
+ assert_se(sigemptyset(&set) == 0);
+ assert_se(sigaddset(&set, SIGHUP) == 0);
+ assert_se(sigaddset(&set, SIGCHLD) == 0);
+ assert_se(sigemptyset(&sig.sa_mask) == 0);
+
+ assert_se(sigprocmask(SIG_UNBLOCK, &set, &oldset) == 0);
+ assert_se(sigaction(SIGCHLD, &sig, &oldsig) == 0);
+ sig.sa_handler = SIG_DFL;
+ assert_se(sigaction(SIGHUP, &sig, NULL) == 0);
+ LIST_FOREACH(handle, c, consoles) {
+
+ switch ((c->pid = fork())) {
+ case 0:
+ if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0)
+ _exit(EXIT_FAILURE);
+ zero(sig);
+ assert_se(sigprocmask(SIG_UNBLOCK, &oldset, NULL) == 0);
+ assert_se(sigaction(SIGCHLD, &oldsig, NULL) == 0);
+ /* fall through */
+ nofork:
+ setsid();
+ release_terminal();
+ id = c->id;
+ *usemask |= (1<<id);
+ current_dev = c->tty;
+ goto forked; /* child */
+ case -1:
+ log_error("Failed to query password: %s", strerror(errno));
+ return EXIT_FAILURE;
+ default:
+ break;
+ }
+ }
+
+ r = 0;
+ while ((job = wait(&status))) {
+ if (job < 0) {
+ if (errno != EINTR)
+ break;
+ continue;
+ }
+ LIST_FOREACH(handle, c, consoles) {
+ if (c->pid == job) {
+ *usemask &= ~(1<<c->id);
+ continue;
+ }
+ if (kill(c->pid, 0) < 0) {
+ *usemask &= ~(1<<c->id);
+ continue;
+ }
+ if (*usemask & (1<<c->id))
+ continue;
+ kill(c->pid, SIGHUP);
+ usleep(50000);
+ kill(c->pid, SIGKILL);
+ }
+
+ if (WIFEXITED(status) && !r)
+ r = WEXITSTATUS(status);
+ }
+ free_consoles();
+ return r != 0 ? EXIT_FAILURE : EXIT_SUCCESS; /* parent */
+
+ } else {
+ setsid();
+ release_terminal();
+ }
+ }
+forked:
if (arg_action == ACTION_WATCH ||
arg_action == ACTION_WALL)
r = watch_passwords();
@@ -751,6 +929,8 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_error("Error: %s", strerror(-r));
+ free_consoles();
+ *usemask &= ~(1<<id);
finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}