X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fmachine%2Fmachinectl.c;h=b3a70188a468130703bcea24fef2ce3d22e00aa8;hb=9130f2128b64de19a3b7d6db7e0d371adfd296c2;hp=c48abcd0bb7aa51f41ffe5c57d1dec6b1021910b;hpb=34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1;p=elogind.git
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index c48abcd0b..b3a70188a 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -19,13 +19,13 @@
along with systemd; If not, see .
***/
+#include
#include
#include
#include
#include
#include
#include
-#include
#include
#include "sd-bus.h"
@@ -84,12 +84,11 @@ static int list_machines(sd_bus *bus, char **args, unsigned n) {
return r;
}
- if (on_tty())
- printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
+ printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
if (r < 0)
- goto fail;
+ return bus_log_parse_error(r);
while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
printf("%-32s %-9s %-16s\n", name, class, service);
@@ -97,20 +96,15 @@ static int list_machines(sd_bus *bus, char **args, unsigned n) {
k++;
}
if (r < 0)
- goto fail;
+ return bus_log_parse_error(r);
r = sd_bus_message_exit_container(reply);
if (r < 0)
- goto fail;
+ return bus_log_parse_error(r);
- if (on_tty())
- printf("\n%u machines listed.\n", k);
+ printf("\n%u machines listed.\n", k);
return 0;
-
-fail:
- log_error("Failed to parse reply: %s", strerror(-r));
- return r;
}
static int show_scope_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
@@ -146,10 +140,8 @@ static int show_scope_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
}
r = sd_bus_message_read(reply, "s", &cgroup);
- if (r < 0) {
- log_error("Failed to parse reply: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return bus_log_parse_error(r);
if (isempty(cgroup))
return 0;
@@ -234,7 +226,7 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
}
static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
- MachineStatusInfo info = {};
+
static const struct bus_properties_map map[] = {
{ "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
{ "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
@@ -246,6 +238,8 @@ static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_
{ "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
{}
};
+
+ MachineStatusInfo info = {};
int r;
assert(path);
@@ -284,7 +278,7 @@ static int show_properties(sd_bus *bus, const char *path, bool *new_line) {
*new_line = true;
- r = bus_print_all_properties(bus, path, arg_property, arg_all);
+ r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
if (r < 0)
log_error("Could not get properties: %s", strerror(-r));
@@ -310,10 +304,8 @@ static int show(sd_bus *bus, char **args, unsigned n) {
/* If no argument is specified, inspect the manager
* itself */
r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
- if (r < 0) {
- log_error("Failed to query properties: %s", strerror(-r));
+ if (r < 0)
return r;
- }
}
for (i = 1; i < n; i++) {
@@ -334,10 +326,8 @@ static int show(sd_bus *bus, char **args, unsigned n) {
}
r = sd_bus_message_read(reply, "o", &path);
- if (r < 0) {
- log_error("Failed to parse reply: %s", strerror(-r));
- break;
- }
+ if (r < 0)
+ return bus_log_parse_error(r);
if (properties)
r = show_properties(bus, path, &new_line);
@@ -406,9 +396,8 @@ static int terminate_machine(sd_bus *bus, char **args, unsigned n) {
}
static int openpt_in_namespace(pid_t pid, int flags) {
- _cleanup_close_ int nsfd = -1, rootfd = -1;
- _cleanup_free_ char *ns = NULL, *root = NULL;
- _cleanup_close_pipe_ int sock[2] = { -1, -1 };
+ _cleanup_close_pipe_ int pair[2] = { -1, -1 };
+ _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
@@ -422,23 +411,11 @@ static int openpt_in_namespace(pid_t pid, int flags) {
pid_t child;
siginfo_t si;
- r = asprintf(&ns, "/proc/%lu/ns/mnt", (unsigned long) pid);
- if (r < 0)
- return -ENOMEM;
-
- nsfd = open(ns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
- if (nsfd < 0)
- return -errno;
-
- r = asprintf(&root, "/proc/%lu/root", (unsigned long) pid);
+ r = namespace_open(pid, &pidnsfd, &mntnsfd, &rootfd);
if (r < 0)
- return -ENOMEM;
-
- rootfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
- if (rootfd < 0)
- return -errno;
+ return r;
- if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sock) < 0)
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
return -errno;
child = fork();
@@ -446,19 +423,13 @@ static int openpt_in_namespace(pid_t pid, int flags) {
return -errno;
if (child == 0) {
- close_nointr_nofail(sock[0]);
- sock[0] = -1;
+ close_nointr_nofail(pair[0]);
+ pair[0] = -1;
- r = setns(nsfd, CLONE_NEWNS);
+ r = namespace_enter(pidnsfd, mntnsfd, rootfd);
if (r < 0)
_exit(EXIT_FAILURE);
- if (fchdir(rootfd) < 0)
- _exit(EXIT_FAILURE);
-
- if (chroot(".") < 0)
- _exit(EXIT_FAILURE);
-
master = posix_openpt(flags);
if (master < 0)
_exit(EXIT_FAILURE);
@@ -471,18 +442,22 @@ static int openpt_in_namespace(pid_t pid, int flags) {
mh.msg_controllen = cmsg->cmsg_len;
- r = sendmsg(sock[1], &mh, MSG_NOSIGNAL);
- close_nointr_nofail(master);
- if (r < 0)
+ if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
_exit(EXIT_FAILURE);
_exit(EXIT_SUCCESS);
}
- close_nointr_nofail(sock[1]);
- sock[1] = -1;
+ close_nointr_nofail(pair[1]);
+ pair[1] = -1;
+
+ r = wait_for_terminate(child, &si);
+ if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) {
+
+ return r < 0 ? r : -EIO;
+ }
- if (recvmsg(sock[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
+ if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
return -errno;
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
@@ -501,14 +476,8 @@ static int openpt_in_namespace(pid_t pid, int flags) {
master = fds[0];
}
- r = wait_for_terminate(child, &si);
- if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS || master < 0) {
-
- if (master >= 0)
- close_nointr_nofail(master);
-
- return r < 0 ? r : -EIO;
- }
+ if (master < 0)
+ return -EIO;
return master;
}
@@ -547,10 +516,8 @@ static int login_machine(sd_bus *bus, char **args, unsigned n) {
}
r = sd_bus_message_read(reply, "o", &path);
- if (r < 0) {
- log_error("Failed to parse reply: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return bus_log_parse_error(r);
r = sd_bus_get_property(
bus,
@@ -567,10 +534,8 @@ static int login_machine(sd_bus *bus, char **args, unsigned n) {
}
r = sd_bus_message_read(reply2, "u", &leader);
- if (r < 0) {
- log_error("Failed to parse reply: %s", strerror(-r));
- return r;
- }
+ if (r < 0)
+ return bus_log_parse_error(r);
master = openpt_in_namespace(leader, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
if (master < 0) {
@@ -617,6 +582,8 @@ static int login_machine(sd_bus *bus, char **args, unsigned n) {
return r;
}
+ container_bus = sd_bus_unref(container_bus);
+
assert_se(sigemptyset(&mask) == 0);
sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
@@ -653,11 +620,11 @@ static int help(void) {
" -s --signal=SIGNAL Which signal to send\n\n"
"Commands:\n"
" list List running VMs and containers\n"
- " status [NAME...] Show VM/container status\n"
- " show [NAME...] Show properties of one or more VMs/containers\n"
- " terminate [NAME...] Terminate one or more VMs/containers\n"
- " kill [NAME...] Send signal to processes of a VM/container\n"
- " login [NAME] Get a login prompt on a container\n",
+ " status NAME... Show VM/container status\n"
+ " show NAME... Show properties of one or more VMs/containers\n"
+ " terminate NAME... Terminate one or more VMs/containers\n"
+ " kill NAME... Send signal to processes of a VM/container\n"
+ " login NAME Get a login prompt on a container\n",
program_invocation_short_name);
return 0;
@@ -793,7 +760,7 @@ static int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
left = argc - optind;
if (left <= 0)
- /* Special rule: no arguments means "list-sessions" */
+ /* Special rule: no arguments means "list" */
i = 0;
else {
if (streq(argv[optind], "help")) {