qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC][PATCH v5 11/21] virtagent: add va.shutdown RPC


From: Michael Roth
Subject: [Qemu-devel] [RFC][PATCH v5 11/21] virtagent: add va.shutdown RPC
Date: Fri, 3 Dec 2010 12:03:12 -0600

RPC to initiate guest reboot/halt/powerdown

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 aac8f70..453cf0d 100644
--- a/virtagent-server.c
+++ b/virtagent-server.c
@@ -127,6 +127,62 @@ EXIT_NOCLOSE:
     return result;
 }
 
+/* va_shutdown(): initiate guest shutdown
+ * rpc return values: none
+ */
+static xmlrpc_value *va_shutdown(xmlrpc_env *env,
+                                    xmlrpc_value *param,
+                                    void *user_data)
+{
+    int ret;
+    const char *shutdown_type, *shutdown_flag;
+    xmlrpc_value *result = xmlrpc_build_value(env, "s", "dummy"); 
+
+    TRACE("called");
+    xmlrpc_decompose_value(env, param, "(s)", &shutdown_type);
+    if (env->fault_occurred) {
+        goto out_bad;
+    }
+
+    if (strcmp(shutdown_type, "halt") == 0) {
+        shutdown_flag = "-H";
+    } else if (strcmp(shutdown_type, "powerdown") == 0) {
+        shutdown_flag = "-P";
+    } else if (strcmp(shutdown_type, "reboot") == 0) {
+        shutdown_flag = "-r";
+    } else {
+        xmlrpc_faultf(env, "invalid shutdown type: %s", shutdown_type);
+        goto out_bad;
+    }
+
+    SLOG("va_shutdown(), shutdown_type:%s", shutdown_type);
+
+    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);
+        }
+        TRACE("shouldn't be here");
+        exit(0);
+    } else if (ret < 0) {
+        xmlrpc_faultf(env, "fork() failed: %s", strerror(errno));
+    }
+
+    return result;
+out_bad:
+    return NULL;
+}
+
 typedef struct RPCFunction {
     xmlrpc_value *(*func)(xmlrpc_env *env, xmlrpc_value *param, void *unused);
     const char *func_name;
@@ -137,6 +193,8 @@ static RPCFunction guest_functions[] = {
       .func_name = "va.getfile" },
     { .func = va_getdmesg,
       .func_name = "va.getdmesg" },
+    { .func = va_shutdown,
+      .func_name = "va.shutdown" },
     { NULL, NULL }
 };
 static RPCFunction host_functions[] = {
-- 
1.7.0.4




reply via email to

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