diff --git a/systemd-mini.changes b/systemd-mini.changes index 48c71e58..be67a458 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Jul 3 11:17:01 UTC 2015 - werner@suse.de + +- Rework patch tty-ask-password-agent-on-console.patch to fit the + requisition of https://bugs.freedesktop.org/show_bug.cgi?id=82004 + ------------------------------------------------------------------- Wed Jul 1 09:42:44 UTC 2015 - jengelh@inai.de diff --git a/systemd.changes b/systemd.changes index 48c71e58..be67a458 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Jul 3 11:17:01 UTC 2015 - werner@suse.de + +- Rework patch tty-ask-password-agent-on-console.patch to fit the + requisition of https://bugs.freedesktop.org/show_bug.cgi?id=82004 + ------------------------------------------------------------------- Wed Jul 1 09:42:44 UTC 2015 - jengelh@inai.de diff --git a/tty-ask-password-agent-on-console.patch b/tty-ask-password-agent-on-console.patch index 6c48feb3..e38d027a 100644 --- a/tty-ask-password-agent-on-console.patch +++ b/tty-ask-password-agent-on-console.patch @@ -4,7 +4,7 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c =================================================================== ---- systemd-221.orig/src/tty-ask-password-agent/tty-ask-password-agent.c +--- systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c +++ systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -31,6 +31,10 @@ #include @@ -17,26 +17,23 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c #include "util.h" #include "mkdir.h" -@@ -42,6 +46,9 @@ - #include "strv.h" - #include "build.h" - #include "def.h" -+#include "fileio.h" -+#include "macro.h" -+#include "list.h" +@@ -45,6 +49,8 @@ #include "process-util.h" #include "terminal-util.h" #include "signal-util.h" -@@ -53,6 +60,22 @@ static enum { ++#include "fileio.h" ++#include "macro.h" + + static enum { + ACTION_LIST, +@@ -53,6 +59,20 @@ static enum { ACTION_WALL } arg_action = ACTION_QUERY; +struct console { -+ LIST_FIELDS(struct console, handle); -+ const char *tty; ++ char *tty; + pid_t pid; + int id; -+ char dev[]; +}; + +static volatile unsigned long *usemask; @@ -50,22 +47,22 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c static bool arg_plymouth = false; static bool arg_console = false; -@@ -211,6 +234,58 @@ static int ask_password_plymouth( +@@ -211,6 +231,60 @@ static int ask_password_plymouth( return 0; } +static const char *current_dev = "/dev/console"; -+static LIST_HEAD(struct console, consoles); -+static int collect_consoles(void) { ++static struct console* collect_consoles(int * num) { + _cleanup_free_ char *active = NULL; + const char *word, *state; -+ struct console *con; ++ struct console *con = NULL; ++ size_t con_len; + size_t len; + int ret, id = 0; + + ret = read_one_line_file("/sys/class/tty/console/active", &active); + if (ret < 0) -+ return ret; ++ return con; + FOREACH_WORD(word, len, active, state) { + _cleanup_free_ char *tty = NULL; + @@ -74,42 +71,44 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + word = tty; + len = strlen(tty); + } -+ con = malloc0(sizeof(*con) + strlen("/dev/") + len + 1); ++ con = greedy_realloc((void**)&con, &con_len, ++id, sizeof(struct console) + 5 + len + 1); + if (con == NULL) { + log_oom(); -+ continue; ++ return con; + } -+ sprintf(con->dev, "/dev/%.*s", (int)len, word); -+ con->tty = con->dev; -+ con->id = id++; -+ LIST_PREPEND(handle, consoles, con); ++ con->tty = ((char*)con)+sizeof(struct console); ++ sprintf(con->tty, "/dev/%.*s", (int)len, word); ++ con->id = id; + } -+ if (consoles == NULL) { -+ con = malloc0(sizeof(*con)); ++ if (con == NULL) { ++ con = greedy_realloc((void**)&con, &con_len, 1, sizeof(struct console)); + if (con == NULL) { + log_oom(); -+ return -ENOMEM; ++ return con; + } -+ con->tty = current_dev; -+ con->id = id++; -+ LIST_PREPEND(handle, consoles, con); ++ con->tty = (char*)current_dev; ++ con->id = id = 1; + } -+ return 0; ++ ++ if (num) ++ *num = id; ++ return con; +} + -+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 void free_consoles(struct console *con, int num) { ++ int n; ++ ++ if (!con) ++ return; ++ for (n = 0; n < num; n++) ++ free(&con[n]); ++ free(con); +} + static int parse_password(const char *filename, char **wall) { _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL; uint64_t not_after = 0; -@@ -311,7 +386,7 @@ static int parse_password(const char *fi +@@ -311,7 +385,7 @@ static int parse_password(const char *filename, char **wall) { _cleanup_free_ char *password = NULL; if (arg_console) { @@ -118,26 +117,29 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c if (tty_fd < 0) return tty_fd; } -@@ -615,9 +690,85 @@ static int parse_argv(int argc, char *ar +@@ -615,8 +689,87 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -+static int zzz(void) ++static int wait_for_answer(void) +{ -+ struct console *con; ++ struct console *consoles; + struct sigaction sig = { + .sa_handler = chld_handler, + .sa_flags = SA_NOCLDSTOP | SA_RESTART, + }; + struct sigaction oldsig; + sigset_t set, oldset; -+ int status = 0, ret; ++ int status = 0, num = 0, n, ret; + pid_t job; + -+ collect_consoles(); -+ if (!consoles->handle_next) { -+ consoles->pid = 0; -+ con = consoles; ++ consoles = collect_consoles(&num); ++ if (!consoles) { ++ log_error("Failed to query password: %m"); ++ exit(EXIT_FAILURE); ++ } ++ if (num == 1) { ++ n = 1; + goto nofork; + } + @@ -150,9 +152,15 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + sig.sa_handler = SIG_DFL; + assert_se(sigaction(SIGHUP, &sig, NULL) == 0); + -+ LIST_FOREACH(handle, con, consoles) { -+ switch ((con->pid = fork())) { -+ case 0: ++ for (n = 0; n < num; n++) { ++ consoles[n].pid = fork(); ++ ++ if (consoles[n].pid < 0) { ++ log_error("Failed to query password: %m"); ++ exit(EXIT_FAILURE); ++ } ++ ++ if (consoles[n].pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0) + _exit(EXIT_FAILURE); + zero(sig); @@ -161,14 +169,9 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + nofork: + setsid(); + release_terminal(); -+ *usemask |= 1 << con->id; -+ current_dev = con->tty; -+ return con->id; /* child */ -+ case -1: -+ log_error("Failed to query password: %s", strerror(errno)); -+ exit(EXIT_FAILURE); -+ default: -+ break; ++ *usemask |= 1 << consoles[n].id; ++ current_dev = consoles[n].tty; ++ return consoles[n].id; /* child */ + } + } + @@ -179,21 +182,21 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c + break; + continue; + } -+ LIST_FOREACH(handle, con, consoles) { -+ if (con->pid == job || kill(con->pid, 0) < 0) { -+ *usemask &= ~(1 << con->id); ++ for (n = 0; n < num; n++) { ++ if (consoles[n].pid == job || kill(consoles[n].pid, 0) < 0) { ++ *usemask &= ~(1 << consoles[n].id); + continue; + } -+ if (*usemask & (1 << con->id)) ++ if (*usemask & (1 << consoles[n].id)) + continue; -+ kill(con->pid, SIGHUP); ++ kill(consoles[n].pid, SIGHUP); + usleep(50000); -+ kill(con->pid, SIGKILL); ++ kill(consoles[n].pid, SIGKILL); + } + if (WIFEXITED(status) && ret == 0) + ret = WEXITSTATUS(status); + } -+ free_consoles(); ++ free_consoles(consoles, num); + exit(ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS); /* parent */ +} + @@ -201,14 +204,20 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c - int r; + int r, id = 0; -+ LIST_HEAD_INIT(consoles); log_set_target(LOG_TARGET_AUTO); log_parse_environment(); - log_open(); -@@ -628,11 +779,19 @@ int main(int argc, char *argv[]) { +@@ -628,11 +781,27 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; ++ /* ++ * Use this shared memory area to be able to synchronize the ++ * workers asking for password with the main process. ++ * This allows to continue if one of the consoles had been ++ * used as afterwards the remaining asking processes will ++ * be terminated. The wait_for_terminate() does not help ++ * for this use case. ++ */ + usemask = mmap(NULL, sizeof(*usemask), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + assert_se(usemask != NULL); @@ -218,7 +227,7 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c - release_terminal(); + if (!arg_plymouth && arg_action != ACTION_WALL && + arg_action != ACTION_LIST) { -+ id = zzz(); ++ id = wait_for_answer(); + } else { + setsid(); + release_terminal(); @@ -228,11 +237,10 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL)) r = watch_passwords(); else -@@ -641,6 +800,8 @@ int main(int argc, char *argv[]) { +@@ -641,6 +810,7 @@ int main(int argc, char *argv[]) { if (r < 0) log_error_errno(r, "Error: %m"); -+ free_consoles(); + *usemask &= ~(1 << id); finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;