From f77f64d60bd90cfb27f87587651fb361af4b7c4be5b9f23f610fae6ac98fffcb Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Wed, 30 Jul 2014 12:17:21 +0000 Subject: [PATCH] . OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=739 --- ...cripts-which-provide-network-before-.patch | 34 ++ ...ophone-mute-keymap-for-Dell-Latitude.patch | 38 ++ ...map-Annotate-all-micmute-workarounds.patch | 54 ++ ...aa13539ed2cd4b31972cd30f678543-apply.patch | 26 + ...add-event-timeout-commandline-option.patch | 119 +++++ 1057-udev-unify-event-timeout-handling.patch | 504 ++++++++++++++++++ 1058-udev-unify-event-timeout-handling.patch | 504 ++++++++++++++++++ ...t-dd5eddd28a74a49607a8fffcaf960040db.patch | 26 + systemd-mini.changes | 29 + systemd-mini.spec | 31 ++ systemd.changes | 29 + systemd.spec | 31 ++ tty-ask-password-agent-on-console.patch | 285 ++++++++++ 13 files changed, 1710 insertions(+) create mode 100644 0001-sysv-order-initscripts-which-provide-network-before-.patch create mode 100644 0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch create mode 100644 0003-keymap-Annotate-all-micmute-workarounds.patch create mode 100644 1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch create mode 100644 1056-udevd-add-event-timeout-commandline-option.patch create mode 100644 1057-udev-unify-event-timeout-handling.patch create mode 100644 1058-udev-unify-event-timeout-handling.patch create mode 100644 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch create mode 100644 tty-ask-password-agent-on-console.patch diff --git a/0001-sysv-order-initscripts-which-provide-network-before-.patch b/0001-sysv-order-initscripts-which-provide-network-before-.patch new file mode 100644 index 0000000..944b915 --- /dev/null +++ b/0001-sysv-order-initscripts-which-provide-network-before-.patch @@ -0,0 +1,34 @@ +Based on 805b573fad06b845502e76f3db3a0efa7583149d Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +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, diff --git a/0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch b/0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch new file mode 100644 index 0000000..7ba1dc4 --- /dev/null +++ b/0002-keymap-Add-microphone-mute-keymap-for-Dell-Latitude.patch @@ -0,0 +1,38 @@ +From 1f6d36f267186c0e3184bab4c7eca48481c6faab Mon Sep 17 00:00:00 2001 +From: Hui Wang +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 +Signed-off-by: Martin Pitt +--- + 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 + diff --git a/0003-keymap-Annotate-all-micmute-workarounds.patch b/0003-keymap-Annotate-all-micmute-workarounds.patch new file mode 100644 index 0000000..00f1e43 --- /dev/null +++ b/0003-keymap-Annotate-all-micmute-workarounds.patch @@ -0,0 +1,54 @@ +From d946bb53f94713241004810de92cc37f1e19c2d2 Mon Sep 17 00:00:00 2001 +From: Martin Pitt +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 + diff --git a/1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch b/1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch new file mode 100644 index 0000000..8a108af --- /dev/null +++ b/1055-let-9719859c07aa13539ed2cd4b31972cd30f678543-apply.patch @@ -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 : ""); + 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; diff --git a/1056-udevd-add-event-timeout-commandline-option.patch b/1056-udevd-add-event-timeout-commandline-option.patch new file mode 100644 index 0000000..1f67068 --- /dev/null +++ b/1056-udevd-add-event-timeout-commandline-option.patch @@ -0,0 +1,119 @@ +From 9719859c07aa13539ed2cd4b31972cd30f678543 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +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 @@ + + + ++ + + + +@@ -96,6 +97,15 @@ + + + ++ ++ ++ Wait for the event to finish up to the given ++ number of seconds. After this time the event will ++ be terminated. Default is 30. ++ ++ ++ ++ + + + Specify when systemd-udevd should resolve names of users and groups. +@@ -156,6 +166,15 @@ + + + ++ udev.event-timeout= ++ rd.udev.event-timeout= ++ ++ 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. ++ ++ ++ + net.ifnames= + + 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 : ""); + kill(worker->pid, SIGKILL); +-- +1.7.9.2 + diff --git a/1057-udev-unify-event-timeout-handling.patch b/1057-udev-unify-event-timeout-handling.patch new file mode 100644 index 0000000..9aa819b --- /dev/null +++ b/1057-udev-unify-event-timeout-handling.patch @@ -0,0 +1,504 @@ +From dd5eddd28a74a49607a8fffcaf960040dba98479 Mon Sep 17 00:00:00 2001 +From: Kay Sievers +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 @@ + + + +- Wait for the event to finish up to the given +- number of seconds. After this time the event will +- be terminated. Default is 30. ++ Set the number of seconds to wait for events to finish. After ++ this time the event will be terminated. The default is 30 seconds. + + + +@@ -171,7 +170,7 @@ + + 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. ++ terminated due to kernel drivers taking too long to initialize. + + + +diff --git man/udev.xml man/udev.xml +index 4e5f8f0..123c073 100644 +--- man/udev.xml ++++ man/udev.xml +@@ -516,13 +516,6 @@ + + + +- +- +- Number of seconds an event waits for operations to finish before +- giving up and terminating itself. +- +- +- + + + 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=\n" + " --exec-delay=\n" ++ " --event-timeout=\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 : ""); ++ 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 + diff --git a/1058-udev-unify-event-timeout-handling.patch b/1058-udev-unify-event-timeout-handling.patch new file mode 100644 index 0000000..a92d15f --- /dev/null +++ b/1058-udev-unify-event-timeout-handling.patch @@ -0,0 +1,504 @@ +Based on dd5eddd28a74a49607a8fffcaf960040dba98479 Mon Sep 17 00:00:00 2001 +From: Kay Sievers +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 @@ + + + +- Wait for the event to finish up to the given +- number of seconds. After this time the event will +- be terminated. Default is 30. ++ Set the number of seconds to wait for events to finish. After ++ this time the event will be terminated. The default is 30 seconds. + + + +@@ -171,7 +170,7 @@ + + 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. ++ terminated due to kernel drivers taking too long to initialize. + + + +diff --git man/udev.xml man/udev.xml +index 4e5f8f0..123c073 100644 +--- man/udev.xml ++++ man/udev.xml +@@ -516,13 +516,6 @@ + + + +- +- +- Number of seconds an event waits for operations to finish before +- giving up and terminating itself. +- +- +- + + + 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=\n" + " --exec-delay=\n" ++ " --event-timeout=\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 : ""); ++ 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 + diff --git a/1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch b/1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch new file mode 100644 index 0000000..62d5d66 --- /dev/null +++ b/1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch @@ -0,0 +1,26 @@ +From 9f20a8a376f924c8eb5423cfc1f98644fc1e2d1a Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +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 + diff --git a/systemd-mini.changes b/systemd-mini.changes index f4d2a66..2f453d5 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,32 @@ +------------------------------------------------------------------- +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 (compatibility) + 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch + ------------------------------------------------------------------- Mon Jul 28 10:08:15 UTC 2014 - werner@suse.de diff --git a/systemd-mini.spec b/systemd-mini.spec index 24ae509..690e163 100644 --- a/systemd-mini.spec +++ b/systemd-mini.spec @@ -749,6 +749,14 @@ 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 # UDEV PATCHES # ============ @@ -864,6 +872,16 @@ 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 %description Systemd is a system and service manager, compatible with SysV and LSB @@ -1384,6 +1402,10 @@ cp %{SOURCE7} m4/ %patch359 -p0 %patch360 -p0 %patch361 -p0 +%patch362 -p1 +%patch363 -p0 +%patch364 -p0 +%patch365 -p0 # udev patches %patch1001 -p1 @@ -1456,7 +1478,16 @@ cp %{SOURCE7} m4/ %patch1053 -p1 %if %{with blkrrpart} %patch1054 -p0 +%else +%patch1055 -p1 %endif +%patch1056 -p0 +%if %{with blkrrpart} +%patch1057 -p0 +%else +%patch1058 -p0 +%endif +%patch1059 -p0 # ensure generate files are removed rm -f units/emergency.service diff --git a/systemd.changes b/systemd.changes index f4d2a66..2f453d5 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,32 @@ +------------------------------------------------------------------- +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 (compatibility) + 1059-udev-fixup-commit-dd5eddd28a74a49607a8fffcaf960040db.patch + ------------------------------------------------------------------- Mon Jul 28 10:08:15 UTC 2014 - werner@suse.de diff --git a/systemd.spec b/systemd.spec index 0031cf2..a0753c1 100644 --- a/systemd.spec +++ b/systemd.spec @@ -744,6 +744,14 @@ 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 # UDEV PATCHES # ============ @@ -859,6 +867,16 @@ 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 %description Systemd is a system and service manager, compatible with SysV and LSB @@ -1379,6 +1397,10 @@ cp %{SOURCE7} m4/ %patch359 -p0 %patch360 -p0 %patch361 -p0 +%patch362 -p1 +%patch363 -p0 +%patch364 -p0 +%patch365 -p0 # udev patches %patch1001 -p1 @@ -1451,7 +1473,16 @@ cp %{SOURCE7} m4/ %patch1053 -p1 %if %{with blkrrpart} %patch1054 -p0 +%else +%patch1055 -p1 %endif +%patch1056 -p0 +%if %{with blkrrpart} +%patch1057 -p0 +%else +%patch1058 -p0 +%endif +%patch1059 -p0 # ensure generate files are removed rm -f units/emergency.service diff --git a/tty-ask-password-agent-on-console.patch b/tty-ask-password-agent-on-console.patch new file mode 100644 index 0000000..1091a73 --- /dev/null +++ b/tty-ask-password-agent-on-console.patch @@ -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 + #include + #include ++#include + #include ++#include ++#include + #include ++#include + #include + + #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<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<id); ++ continue; ++ } ++ if (kill(c->pid, 0) < 0) { ++ *usemask &= ~(1<id); ++ continue; ++ } ++ if (*usemask & (1<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<