summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-02-12 02:07:57 +0100
committerLennart Poettering <lennart@poettering.net>2014-02-12 02:11:00 +0100
commit923d8fd381bced1c2d90ca53d18629d61a0f454a (patch)
tree24f31fb6e8bc008fb0209757ac324ed03a692a81
parenta87105a38637355bd6d648036f0369a1a9546ae9 (diff)
machinectl: add new "machinectl reboot" call
-rw-r--r--man/machinectl.xml14
-rw-r--r--src/machine/machinectl.c67
2 files changed, 79 insertions, 2 deletions
diff --git a/man/machinectl.xml b/man/machinectl.xml
index 6e991ee957..cabdbac962 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -265,7 +265,19 @@
</varlistentry>
<varlistentry>
- <term><command>login</command> <replaceable>ID</replaceable>...</term>
+ <term><command>reboot</command> <replaceable>ID</replaceable>...</term>
+
+ <listitem><para>Reboot one or more
+ containers. This will trigger a reboot
+ by sending SIGINT to the container's
+ init process, which is roughly
+ equivalent to pressing Ctrl+Alt+Del on
+ a non-containerized
+ system.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>login</command> <replaceable>ID</replaceable></term>
<listitem><para>Open a terminal login
session to a container. This will
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 703fb3a3a0..3f4f8acb7e 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -395,6 +395,69 @@ static int terminate_machine(sd_bus *bus, char **args, unsigned n) {
return 0;
}
+static int reboot_machine(sd_bus *bus, char **args, unsigned n) {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ unsigned i;
+ int r;
+
+ assert(args);
+
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ log_error("Reboot only supported on local machines.");
+ return -ENOTSUP;
+ }
+
+ for (i = 1; i < n; i++) {
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL;
+ const char *path;
+ uint32_t leader;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetMachine",
+ &error,
+ &reply,
+ "s", args[i]);
+
+ if (r < 0) {
+ log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply, "o", &path);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_get_property(
+ bus,
+ "org.freedesktop.machine1",
+ path,
+ "org.freedesktop.machine1.Machine",
+ "Leader",
+ &error,
+ &reply2,
+ "u");
+ if (r < 0) {
+ log_error("Failed to retrieve PID of leader: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply2, "u", &leader);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (kill(leader, SIGINT) < 0) {
+ log_error("Failed to kill init process " PID_FMT ": %m", (pid_t) leader);
+ return -errno;
+ }
+ }
+
+ return 0;
+}
+
static int openpt_in_namespace(pid_t pid, int flags) {
_cleanup_close_pipe_ int pair[2] = { -1, -1 };
_cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
@@ -497,7 +560,7 @@ static int login_machine(sd_bus *bus, char **args, unsigned n) {
assert(args);
if (arg_transport != BUS_TRANSPORT_LOCAL) {
- log_error("Login only support on local machines.");
+ log_error("Login only supported on local machines.");
return -ENOTSUP;
}
@@ -624,6 +687,7 @@ static int help(void) {
" 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"
+ " reboot NAME... Reboot one or more containers\n"
" login NAME Get a login prompt on a container\n",
program_invocation_short_name);
@@ -747,6 +811,7 @@ static int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
{ "status", MORE, 2, show },
{ "show", MORE, 1, show },
{ "terminate", MORE, 2, terminate_machine },
+ { "reboot", MORE, 2, reboot_machine },
{ "kill", MORE, 2, kill_machine },
{ "login", MORE, 2, login_machine },
};