systemctl: shutdown agent explicitly so that it can reset the tty properly

This commit is contained in:
Lennart Poettering 2011-02-25 02:51:48 +01:00
parent 6d55002a69
commit c0f9c7da07
5 changed files with 40 additions and 19 deletions

5
TODO
View File

@ -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

View 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);
}

View 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));

View 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;
}

View 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;
}