SHA256
1
0
forked from pool/systemd
Dr. Werner Fink 2015-07-03 11:19:08 +00:00 committed by Git OBS Bridge
parent 6e1b3eb37e
commit 8e335a6c18
3 changed files with 90 additions and 70 deletions

View File

@ -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 Wed Jul 1 09:42:44 UTC 2015 - jengelh@inai.de

View File

@ -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 Wed Jul 1 09:42:44 UTC 2015 - jengelh@inai.de

View File

@ -4,7 +4,7 @@
Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c 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 +++ systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -31,6 +31,10 @@ @@ -31,6 +31,10 @@
#include <getopt.h> #include <getopt.h>
@ -17,26 +17,23 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
#include "util.h" #include "util.h"
#include "mkdir.h" #include "mkdir.h"
@@ -42,6 +46,9 @@ @@ -45,6 +49,8 @@
#include "strv.h"
#include "build.h"
#include "def.h"
+#include "fileio.h"
+#include "macro.h"
+#include "list.h"
#include "process-util.h" #include "process-util.h"
#include "terminal-util.h" #include "terminal-util.h"
#include "signal-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 ACTION_WALL
} arg_action = ACTION_QUERY; } arg_action = ACTION_QUERY;
+struct console { +struct console {
+ LIST_FIELDS(struct console, handle); + char *tty;
+ const char *tty;
+ pid_t pid; + pid_t pid;
+ int id; + int id;
+ char dev[];
+}; +};
+ +
+static volatile unsigned long *usemask; +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_plymouth = false;
static bool arg_console = 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; return 0;
} }
+static const char *current_dev = "/dev/console"; +static const char *current_dev = "/dev/console";
+static LIST_HEAD(struct console, consoles); +static struct console* collect_consoles(int * num) {
+static int collect_consoles(void) {
+ _cleanup_free_ char *active = NULL; + _cleanup_free_ char *active = NULL;
+ const char *word, *state; + const char *word, *state;
+ struct console *con; + struct console *con = NULL;
+ size_t con_len;
+ size_t len; + size_t len;
+ int ret, id = 0; + int ret, id = 0;
+ +
+ ret = read_one_line_file("/sys/class/tty/console/active", &active); + ret = read_one_line_file("/sys/class/tty/console/active", &active);
+ if (ret < 0) + if (ret < 0)
+ return ret; + return con;
+ FOREACH_WORD(word, len, active, state) { + FOREACH_WORD(word, len, active, state) {
+ _cleanup_free_ char *tty = NULL; + _cleanup_free_ char *tty = NULL;
+ +
@ -74,42 +71,44 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ word = tty; + word = tty;
+ len = strlen(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) { + if (con == NULL) {
+ log_oom(); + log_oom();
+ continue; + return con;
+ } + }
+ sprintf(con->dev, "/dev/%.*s", (int)len, word); + con->tty = ((char*)con)+sizeof(struct console);
+ con->tty = con->dev; + sprintf(con->tty, "/dev/%.*s", (int)len, word);
+ con->id = id++; + con->id = id;
+ LIST_PREPEND(handle, consoles, con);
+ } + }
+ if (consoles == NULL) { + if (con == NULL) {
+ con = malloc0(sizeof(*con)); + con = greedy_realloc((void**)&con, &con_len, 1, sizeof(struct console));
+ if (con == NULL) { + if (con == NULL) {
+ log_oom(); + log_oom();
+ return -ENOMEM; + return con;
+ } + }
+ con->tty = current_dev; + con->tty = (char*)current_dev;
+ con->id = id++; + con->id = id = 1;
+ LIST_PREPEND(handle, consoles, con);
+ } + }
+ return 0; +
+ if (num)
+ *num = id;
+ return con;
+} +}
+ +
+static void free_consoles(void) { +static void free_consoles(struct console *con, int num) {
+ struct console *c; + int n;
+ LIST_FOREACH(handle, c, consoles) { +
+ LIST_REMOVE(handle, consoles, c); + if (!con)
+ free(c); + return;
+ } + for (n = 0; n < num; n++)
+ LIST_HEAD_INIT(consoles); + free(&con[n]);
+ free(con);
+} +}
+ +
static int parse_password(const char *filename, char **wall) { static int parse_password(const char *filename, char **wall) {
_cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL; _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
uint64_t not_after = 0; 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; _cleanup_free_ char *password = NULL;
if (arg_console) { if (arg_console) {
@ -118,26 +117,29 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
if (tty_fd < 0) if (tty_fd < 0)
return tty_fd; 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; return 1;
} }
+static int zzz(void) +static int wait_for_answer(void)
+{ +{
+ struct console *con; + struct console *consoles;
+ struct sigaction sig = { + struct sigaction sig = {
+ .sa_handler = chld_handler, + .sa_handler = chld_handler,
+ .sa_flags = SA_NOCLDSTOP | SA_RESTART, + .sa_flags = SA_NOCLDSTOP | SA_RESTART,
+ }; + };
+ struct sigaction oldsig; + struct sigaction oldsig;
+ sigset_t set, oldset; + sigset_t set, oldset;
+ int status = 0, ret; + int status = 0, num = 0, n, ret;
+ pid_t job; + pid_t job;
+ +
+ collect_consoles(); + consoles = collect_consoles(&num);
+ if (!consoles->handle_next) { + if (!consoles) {
+ consoles->pid = 0; + log_error("Failed to query password: %m");
+ con = consoles; + exit(EXIT_FAILURE);
+ }
+ if (num == 1) {
+ n = 1;
+ goto nofork; + goto nofork;
+ } + }
+ +
@ -150,9 +152,15 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ sig.sa_handler = SIG_DFL; + sig.sa_handler = SIG_DFL;
+ assert_se(sigaction(SIGHUP, &sig, NULL) == 0); + assert_se(sigaction(SIGHUP, &sig, NULL) == 0);
+ +
+ LIST_FOREACH(handle, con, consoles) { + for (n = 0; n < num; n++) {
+ switch ((con->pid = fork())) { + consoles[n].pid = fork();
+ case 0: +
+ 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) + if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0)
+ _exit(EXIT_FAILURE); + _exit(EXIT_FAILURE);
+ zero(sig); + zero(sig);
@ -161,14 +169,9 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ nofork: + nofork:
+ setsid(); + setsid();
+ release_terminal(); + release_terminal();
+ *usemask |= 1 << con->id; + *usemask |= 1 << consoles[n].id;
+ current_dev = con->tty; + current_dev = consoles[n].tty;
+ return con->id; /* child */ + return consoles[n].id; /* child */
+ case -1:
+ log_error("Failed to query password: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ default:
+ break;
+ } + }
+ } + }
+ +
@ -179,21 +182,21 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ break; + break;
+ continue; + continue;
+ } + }
+ LIST_FOREACH(handle, con, consoles) { + for (n = 0; n < num; n++) {
+ if (con->pid == job || kill(con->pid, 0) < 0) { + if (consoles[n].pid == job || kill(consoles[n].pid, 0) < 0) {
+ *usemask &= ~(1 << con->id); + *usemask &= ~(1 << consoles[n].id);
+ continue; + continue;
+ } + }
+ if (*usemask & (1 << con->id)) + if (*usemask & (1 << consoles[n].id))
+ continue; + continue;
+ kill(con->pid, SIGHUP); + kill(consoles[n].pid, SIGHUP);
+ usleep(50000); + usleep(50000);
+ kill(con->pid, SIGKILL); + kill(consoles[n].pid, SIGKILL);
+ } + }
+ if (WIFEXITED(status) && ret == 0) + if (WIFEXITED(status) && ret == 0)
+ ret = WEXITSTATUS(status); + ret = WEXITSTATUS(status);
+ } + }
+ free_consoles(); + free_consoles(consoles, num);
+ exit(ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS); /* parent */ + 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;
+ int r, id = 0; + int r, id = 0;
+ LIST_HEAD_INIT(consoles);
log_set_target(LOG_TARGET_AUTO); log_set_target(LOG_TARGET_AUTO);
log_parse_environment(); log_parse_environment();
log_open(); @@ -628,11 +781,27 @@ int main(int argc, char *argv[]) {
@@ -628,11 +779,19 @@ int main(int argc, char *argv[]) {
if (r <= 0) if (r <= 0)
goto finish; 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, + usemask = mmap(NULL, sizeof(*usemask), PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_SHARED, -1, 0); + MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+ assert_se(usemask != NULL); + assert_se(usemask != NULL);
@ -218,7 +227,7 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
- release_terminal(); - release_terminal();
+ if (!arg_plymouth && arg_action != ACTION_WALL && + if (!arg_plymouth && arg_action != ACTION_WALL &&
+ arg_action != ACTION_LIST) { + arg_action != ACTION_LIST) {
+ id = zzz(); + id = wait_for_answer();
+ } else { + } else {
+ setsid(); + setsid();
+ release_terminal(); + 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)) if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
r = watch_passwords(); r = watch_passwords();
else else
@@ -641,6 +800,8 @@ int main(int argc, char *argv[]) { @@ -641,6 +810,7 @@ int main(int argc, char *argv[]) {
if (r < 0) if (r < 0)
log_error_errno(r, "Error: %m"); log_error_errno(r, "Error: %m");
+ free_consoles();
+ *usemask &= ~(1 << id); + *usemask &= ~(1 << id);
finish: finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;