From c0f9c7da07fccafed646e0a15df9bc132e3fc7fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 25 Feb 2011 02:51:48 +0100 Subject: [PATCH] systemctl: shutdown agent explicitly so that it can reset the tty properly --- TODO | 5 ---- src/ask-password-api.c | 6 +++-- src/automount.c | 2 +- src/systemctl.c | 44 ++++++++++++++++++++++++++++-------- src/tty-ask-password-agent.c | 2 +- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/TODO b/TODO index b3c33ad1..d1408f00 100644 --- a/TODO +++ b/TODO @@ -6,9 +6,6 @@ F15: * isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target -* increase password timeout - https://bugzilla.redhat.com/show_bug.cgi?id=677962 - * finish syslog socket stuff * load EnvironmentFile= when starting services, not when reloading configuration @@ -19,8 +16,6 @@ F15: * NFS, networkmanager ordering issue -* Make systemd-cryptsetup cancellable - * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target * hook emergency.target into local-fs.target in some way as OnFailure with isolate diff --git a/src/ask-password-api.c b/src/ask-password-api.c index f43075e6..dd54fb6a 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -180,7 +180,6 @@ int ask_password_tty( } if (ttyfd >= 0) - loop_write(ttyfd, "\n", 1, false); passphrase[p] = 0; @@ -196,8 +195,11 @@ finish: close_nointr_nofail(notify); if (ttyfd >= 0) { - if (reset_tty) + + if (reset_tty) { + loop_write(ttyfd, "\n", 1, false); tcsetattr(ttyfd, TCSADRAIN, &old_termios); + } close_nointr_nofail(ttyfd); } diff --git a/src/automount.c b/src/automount.c index 72893116..c225c161 100644 --- a/src/automount.c +++ b/src/automount.c @@ -305,7 +305,7 @@ static int open_dev_autofs(Manager *m) { if (m->dev_autofs_fd >= 0) return m->dev_autofs_fd; - label_fix("/dev/autofs", false); + label_fix("/dev/autofs", false); if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) { log_error("Failed to open /dev/autofs: %s", strerror(errno)); diff --git a/src/systemctl.c b/src/systemctl.c index b33a89f6..c08e78c2 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -112,6 +112,7 @@ static enum dot { static bool private_bus = false; static pid_t pager_pid = 0; +static pid_t agent_pid = 0; static int daemon_reload(DBusConnection *bus, char **args, unsigned n); static void pager_open(void); @@ -132,7 +133,10 @@ static bool on_tty(void) { } static void spawn_ask_password_agent(void) { - pid_t parent, child; + pid_t parent; + + if (agent_pid > 0) + return; /* We check STDIN here, not STDOUT, since this is about input, * not output */ @@ -150,16 +154,11 @@ static void spawn_ask_password_agent(void) { /* Spawns a temporary TTY agent, making sure it goes away when * we go away */ - if ((child = fork()) < 0) + if ((agent_pid = fork()) < 0) return; - if (child == 0) { + if (agent_pid == 0) { /* In the child */ - const char * const args[] = { - SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, - "--watch", - NULL - }; int fd; bool stdout_is_tty, stderr_is_tty; @@ -202,7 +201,9 @@ static void spawn_ask_password_agent(void) { close(fd); } - execv(args[0], (char **) args); + execl(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL); + + log_error("Unable to execute agent: %m"); _exit(EXIT_FAILURE); } } @@ -5447,6 +5448,7 @@ static int runlevel_main(void) { static void pager_open(void) { int fd[2]; const char *pager; + pid_t parent_pid; if (pager_pid > 0) return; @@ -5467,6 +5469,8 @@ static void pager_open(void) { return; } + parent_pid = getpid(); + pager_pid = fork(); if (pager_pid < 0) { log_error("Failed to fork pager: %m"); @@ -5482,7 +5486,14 @@ static void pager_open(void) { setenv("LESS", "FRSX", 0); - prctl(PR_SET_PDEATHSIG, SIGTERM); + /* Make sure the pager goes away when the parent dies */ + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + _exit(EXIT_FAILURE); + + /* Check whether our parent died before we were able + * to set the death signal */ + if (getppid() != parent_pid) + _exit(EXIT_SUCCESS); if (pager) { execlp(pager, pager, NULL); @@ -5523,6 +5534,18 @@ static void pager_close(void) { pager_pid = 0; } +static void agent_close(void) { + siginfo_t dummy; + + if (agent_pid <= 0) + return; + + /* Inform agent that we are done */ + kill(agent_pid, SIGTERM); + wait_for_terminate(agent_pid, &dummy); + agent_pid = 0; +} + int main(int argc, char*argv[]) { int r, retval = EXIT_FAILURE; DBusConnection *bus = NULL; @@ -5605,6 +5628,7 @@ finish: strv_free(arg_property); pager_close(); + agent_close(); return retval; } diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c index 5e745247..bedb0bc3 100644 --- a/src/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent.c @@ -92,7 +92,7 @@ static int ask_password_plymouth( sa.sa.sa_family = AF_UNIX; strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1); if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { - log_error("FAILED TO CONNECT: %m"); + log_error("Failed to connect to Plymouth: %m"); r = -errno; goto finish; } -- 2.39.5