chiark / gitweb /
systemctl: shutdown agent explicitly so that it can reset the tty properly
authorLennart Poettering <lennart@poettering.net>
Fri, 25 Feb 2011 01:51:48 +0000 (02:51 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 25 Feb 2011 01:51:48 +0000 (02:51 +0100)
TODO
src/ask-password-api.c
src/automount.c
src/systemctl.c
src/tty-ask-password-agent.c

diff --git a/TODO b/TODO
index b3c33ad..d1408f0 100644 (file)
--- 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
index f43075e..dd54fb6 100644 (file)
@@ -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);
         }
index 7289311..c225c16 100644 (file)
@@ -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));
index b33a89f..c08e78c 100644 (file)
@@ -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;
 }
index 5e74524..bedb0bc 100644 (file)
@@ -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;
         }