qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC][PATCH v7 12/16] virtagent: add "shutdown" RPC to serv


From: Michael Roth
Subject: [Qemu-devel] [RFC][PATCH v7 12/16] virtagent: add "shutdown" RPC to server
Date: Mon, 7 Mar 2011 14:10:38 -0600

Signed-off-by: Michael Roth <address@hidden>
---
 virtagent-server.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/virtagent-server.c b/virtagent-server.c
index b0fc0c4..3c8c805 100644
--- a/virtagent-server.c
+++ b/virtagent-server.c
@@ -113,11 +113,69 @@ static QDict *va_ping(const QDict *params)
     return va_server_format_response(NULL, 0, NULL);
 }
 
+/* va_shutdown(): initiate guest shutdown
+ * params/response qdict format:
+ *   params{shutdown_mode}: "reboot"|"powerdown"|"shutdown"
+ *   response{error}: <error code>
+ *   response{errstr}: <error description>
+ */
+static QDict *va_shutdown(const QDict *params)
+{
+    int ret;
+    const char *shutdown_mode, *shutdown_flag;
+
+    shutdown_mode = qdict_get_try_str(params, "shutdown_mode");
+    SLOG("va_shutdown(), shutdown_mode:%s", shutdown_mode);
+
+    if (!shutdown_mode) {
+        ret = -EINVAL;
+        LOG("missing shutdown argument");
+        goto out;
+    } else if (strcmp(shutdown_mode, "halt") == 0) {
+        shutdown_flag = "-H";
+    } else if (strcmp(shutdown_mode, "powerdown") == 0) {
+        shutdown_flag = "-P";
+    } else if (strcmp(shutdown_mode, "reboot") == 0) {
+        shutdown_flag = "-r";
+    } else {
+        ret = -EINVAL;
+        LOG("invalid shutdown argument");
+        goto out;
+    }
+
+    ret = fork();
+    if (ret == 0) {
+        /* child, start the shutdown */
+        setsid();
+        fclose(stdin);
+        fclose(stdout);
+        fclose(stderr);
+
+        sleep(5);
+        ret = execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
+                    "hypervisor initiated shutdown", (char*)NULL);
+        if (ret < 0) {
+            LOG("execl() failed: %s", strerror(errno));
+            exit(1);
+        }
+        exit(0);
+    } else if (ret < 0) {
+        LOG("fork() failed: %s", strerror(errno));
+    } else {
+        ret = 0;
+    }
+
+out:
+    return va_server_format_response(NULL, ret, strerror(errno));
+}
+
 static VARPCFunction guest_functions[] = {
     { .func = va_capabilities,
       .func_name = "capabilities" },
     { .func = va_ping,
       .func_name = "ping" },
+    { .func = va_shutdown,
+      .func_name = "shutdown" },
     { NULL, NULL }
 };
 
-- 
1.7.0.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]