machined: when opening a shell via machined, pass tty fds in
With this change we'll open the shell's tty right from machined and then pass it to the transient unit we create. This way we make sure the pty is opened exactly as long as the transient service is around, and no longer, and vice versa. This way pty forwarders do not have to deal with EIO problems due to vhangup, as the pty is open all the time from the point we set things up to the point where the service goes away.
This commit is contained in:
@@ -639,7 +639,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
|
||||
_cleanup_free_ char *pty_name = NULL;
|
||||
_cleanup_bus_flush_close_unref_ sd_bus *allocated_bus = NULL;
|
||||
sd_bus *container_bus = NULL;
|
||||
_cleanup_close_ int master = -1;
|
||||
_cleanup_close_ int master = -1, slave = -1;
|
||||
_cleanup_strv_free_ char **env = NULL, **args = NULL;
|
||||
Machine *m = userdata;
|
||||
const char *p, *unit, *user, *path, *description, *utmp_id;
|
||||
@@ -700,8 +700,11 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
|
||||
return r;
|
||||
|
||||
p = path_startswith(pty_name, "/dev/pts/");
|
||||
if (!p)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
|
||||
assert(p);
|
||||
|
||||
slave = machine_open_terminal(m, pty_name, O_RDWR|O_NOCTTY|O_CLOEXEC);
|
||||
if (slave < 0)
|
||||
return slave;
|
||||
|
||||
utmp_id = path_startswith(pty_name, "/dev/");
|
||||
assert(utmp_id);
|
||||
@@ -735,16 +738,14 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
|
||||
|
||||
description = strjoina("Shell for User ", isempty(user) ? "root" : user);
|
||||
r = sd_bus_message_append(tm,
|
||||
"(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
|
||||
"(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
|
||||
"Description", "s", description,
|
||||
"StandardInput", "s", "tty",
|
||||
"StandardOutput", "s", "tty",
|
||||
"StandardError", "s", "tty",
|
||||
"TTYPath", "s", pty_name,
|
||||
"StandardInputFileDescriptor", "h", slave,
|
||||
"StandardOutputFileDescriptor", "h", slave,
|
||||
"StandardErrorFileDescriptor", "h", slave,
|
||||
"SendSIGHUP", "b", true,
|
||||
"IgnoreSIGPIPE", "b", false,
|
||||
"KillMode", "s", "mixed",
|
||||
"TTYVHangup", "b", true,
|
||||
"TTYReset", "b", true,
|
||||
"UtmpIdentifier", "s", utmp_id,
|
||||
"UtmpMode", "s", "user",
|
||||
@@ -845,6 +846,8 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
slave = safe_close(slave);
|
||||
|
||||
r = sd_bus_message_new_method_return(message, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -572,6 +572,25 @@ int machine_openpt(Machine *m, int flags) {
|
||||
}
|
||||
}
|
||||
|
||||
int machine_open_terminal(Machine *m, const char *path, int mode) {
|
||||
assert(m);
|
||||
|
||||
switch (m->class) {
|
||||
|
||||
case MACHINE_HOST:
|
||||
return open_terminal(path, mode);
|
||||
|
||||
case MACHINE_CONTAINER:
|
||||
if (m->leader <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return open_terminal_in_namespace(m->leader, path, mode);
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
MachineOperation *machine_operation_unref(MachineOperation *o) {
|
||||
if (!o)
|
||||
return NULL;
|
||||
|
||||
@@ -123,3 +123,4 @@ const char *kill_who_to_string(KillWho k) _const_;
|
||||
KillWho kill_who_from_string(const char *s) _pure_;
|
||||
|
||||
int machine_openpt(Machine *m, int flags);
|
||||
int machine_open_terminal(Machine *m, const char *path, int mode);
|
||||
|
||||
@@ -1390,7 +1390,7 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
return process_forward(event, &forward, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, machine);
|
||||
return process_forward(event, &forward, master, 0, machine);
|
||||
}
|
||||
|
||||
static int remove_image(int argc, char *argv[], void *userdata) {
|
||||
|
||||
Reference in New Issue
Block a user