systemd-run: support -t mode when combined with -M
For that, ask machined for a container PTY and use that.
This commit is contained in:
parent
40205d706e
commit
ee451d766a
|
@ -404,6 +404,7 @@ int bus_machine_method_open_pty(sd_bus *bus, sd_bus_message *message, void *user
|
|||
.msg_controllen = sizeof(control),
|
||||
};
|
||||
Machine *m = userdata;
|
||||
_cleanup_free_ char *pty_name = NULL;
|
||||
struct cmsghdr *cmsg;
|
||||
siginfo_t si;
|
||||
pid_t child;
|
||||
|
@ -479,11 +480,15 @@ int bus_machine_method_open_pty(sd_bus *bus, sd_bus_message *message, void *user
|
|||
if (master < 0)
|
||||
return -EIO;
|
||||
|
||||
r = ptsname_malloc(master, &pty_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_new_method_return(message, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(reply, "hs", master, ptsname(master));
|
||||
r = sd_bus_message_append(reply, "hs", master, pty_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -1053,7 +1053,7 @@ static int login_machine(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = sd_bus_message_read(reply, "hs", &master, &pty);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
p = startswith(pty, "/dev/pts/");
|
||||
if (!p) {
|
||||
|
|
100
src/run/run.c
100
src/run/run.c
|
@ -657,26 +657,63 @@ static int transient_timer_set_properties(sd_bus_message *m) {
|
|||
|
||||
static int start_transient_service(
|
||||
sd_bus *bus,
|
||||
char **argv,
|
||||
sd_bus_error *error) {
|
||||
char **argv) {
|
||||
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
_cleanup_free_ char *service = NULL;
|
||||
_cleanup_free_ char *service = NULL, *pty_path = NULL;
|
||||
_cleanup_close_ int master = -1;
|
||||
const char *pty_path = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(argv);
|
||||
|
||||
if (arg_pty) {
|
||||
master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
|
||||
if (master < 0)
|
||||
return log_error_errno(errno, "Failed to acquire pseudo tty: %m");
|
||||
|
||||
pty_path = ptsname(master);
|
||||
if (!pty_path)
|
||||
return log_error_errno(errno, "Failed to determine tty name: %m");
|
||||
if (arg_transport == BUS_TRANSPORT_LOCAL) {
|
||||
master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
|
||||
if (master < 0)
|
||||
return log_error_errno(errno, "Failed to acquire pseudo tty: %m");
|
||||
|
||||
r = ptsname_malloc(master, &pty_path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine tty name: %m");
|
||||
|
||||
} else if (arg_transport == BUS_TRANSPORT_CONTAINER) {
|
||||
_cleanup_bus_unref_ sd_bus *system_bus = NULL;
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
const char *s;
|
||||
|
||||
r = sd_bus_open_system(&system_bus);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
r = sd_bus_call_method(system_bus,
|
||||
"org.freedesktop.machine1",
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
"OpenMachinePTY",
|
||||
&error,
|
||||
&reply,
|
||||
"s", arg_host);
|
||||
if (r < 0) {
|
||||
log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_read(reply, "hs", &master, &s);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
master = fcntl(master, F_DUPFD_CLOEXEC, 3);
|
||||
if (master < 0)
|
||||
return log_error_errno(errno, "Failed to duplicate master fd: %m");
|
||||
|
||||
pty_path = strdup(s);
|
||||
if (!pty_path)
|
||||
return log_oom();
|
||||
} else
|
||||
assert_not_reached("Can't allocate tty via ssh");
|
||||
|
||||
if (unlockpt(master) < 0)
|
||||
return log_error_errno(errno, "Failed to unlock tty: %m");
|
||||
|
@ -722,9 +759,11 @@ static int start_transient_service(
|
|||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_call(bus, m, 0, error, NULL);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
r = sd_bus_call(bus, m, 0, &error, NULL);
|
||||
if (r < 0) {
|
||||
log_error("Failed to start transient service unit: %s", bus_error_message(&error, -r));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (master >= 0) {
|
||||
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;
|
||||
|
@ -769,9 +808,9 @@ static int start_transient_service(
|
|||
|
||||
static int start_transient_scope(
|
||||
sd_bus *bus,
|
||||
char **argv,
|
||||
sd_bus_error *error) {
|
||||
char **argv) {
|
||||
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_strv_free_ char **env = NULL, **user_env = NULL;
|
||||
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
_cleanup_free_ char *scope = NULL;
|
||||
|
@ -815,15 +854,16 @@ static int start_transient_scope(
|
|||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
/* aux */
|
||||
/* Auxiliary units */
|
||||
r = sd_bus_message_append(m, "a(sa(sv))", 0);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
/* send dbus */
|
||||
r = sd_bus_call(bus, m, 0, error, NULL);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
r = sd_bus_call(bus, m, 0, &error, NULL);
|
||||
if (r < 0) {
|
||||
log_error("Failed to start transient scope unit: %s", bus_error_message(&error, -r));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (arg_nice_set) {
|
||||
if (setpriority(PRIO_PROCESS, 0, arg_nice) < 0)
|
||||
|
@ -889,9 +929,9 @@ static int start_transient_scope(
|
|||
|
||||
static int start_transient_timer(
|
||||
sd_bus *bus,
|
||||
char **argv,
|
||||
sd_bus_error *error) {
|
||||
char **argv) {
|
||||
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
_cleanup_free_ char *timer = NULL, *service = NULL;
|
||||
int r;
|
||||
|
@ -999,10 +1039,11 @@ static int start_transient_timer(
|
|||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
/* send dbus */
|
||||
r = sd_bus_call(bus, m, 0, error, NULL);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
r = sd_bus_call(bus, m, 0, &error, NULL);
|
||||
if (r < 0) {
|
||||
log_error("Failed to start transient timer unit: %s", bus_error_message(&error, -r));
|
||||
return r;
|
||||
}
|
||||
|
||||
log_info("Running as unit %s.", timer);
|
||||
if (argv[0])
|
||||
|
@ -1012,7 +1053,6 @@ static int start_transient_timer(
|
|||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_bus_close_unref_ sd_bus *bus = NULL;
|
||||
_cleanup_free_ char *description = NULL, *command = NULL;
|
||||
int r;
|
||||
|
@ -1062,11 +1102,11 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
|
||||
if (arg_scope)
|
||||
r = start_transient_scope(bus, argv + optind, &error);
|
||||
r = start_transient_scope(bus, argv + optind);
|
||||
else if (with_timer())
|
||||
r = start_transient_timer(bus, argv + optind, &error);
|
||||
r = start_transient_timer(bus, argv + optind);
|
||||
else
|
||||
r = start_transient_service(bus, argv + optind, &error);
|
||||
r = start_transient_service(bus, argv + optind);
|
||||
|
||||
finish:
|
||||
strv_free(arg_environment);
|
||||
|
|
|
@ -7433,3 +7433,27 @@ int sethostname_idempotent(const char *s) {
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ptsname_malloc(int fd, char **ret) {
|
||||
size_t l = 100;
|
||||
|
||||
for (;;) {
|
||||
char *c;
|
||||
|
||||
c = new(char, l);
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ptsname_r(fd, c, l) == 0) {
|
||||
*ret = c;
|
||||
return 0;
|
||||
}
|
||||
if (errno != ERANGE) {
|
||||
free(c);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
free(c);
|
||||
l *= 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1052,3 +1052,5 @@ int sethostname_idempotent(const char *s);
|
|||
(e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
|
||||
|
||||
#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
|
||||
|
||||
int ptsname_malloc(int fd, char **ret);
|
||||
|
|
Loading…
Reference in New Issue