[RFC,v3,05/11] virtagent: add getfile RPC

Submitted by Michael Roth on Nov. 11, 2010, 1:37 a.m.

Details

Message ID 1289439450-23556-6-git-send-email-mdroth@linux.vnet.ibm.com
State New
Headers show

Commit Message

Michael Roth Nov. 11, 2010, 1:37 a.m.
Add RPC to retrieve a guest file. A size limit of some sort will
eventually be needed else we can block the monitor for arbitrarily long
periods of time. This interface is intended for smaller reads like
peeking at logs and /proc and such.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 virtagent-daemon.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)

Patch hide | download patch | download mbox

diff --git a/virtagent-daemon.c b/virtagent-daemon.c
index 0505a81..3615e8a 100644
--- a/virtagent-daemon.c
+++ b/virtagent-daemon.c
@@ -15,6 +15,57 @@ 
 #include "virtagent-daemon.h"
 #include "virtagent-common.h"
 
+/* RPC functions common to guest/host daemons */
+
+static xmlrpc_value *getfile(xmlrpc_env *env,
+                                xmlrpc_value *param,
+                                void *user_data)
+{
+    const char *path;
+    char *file_contents = NULL;
+    char buf[VA_FILEBUF_LEN];
+    int fd, ret, count = 0;
+    xmlrpc_value *result = NULL;
+
+    /* parse argument array */
+    xmlrpc_decompose_value(env, param, "(s)", &path);
+    if (env->fault_occurred) {
+        return NULL;
+    }
+
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        LOG("open failed: %s", strerror(errno));
+        xmlrpc_faultf(env, "open failed: %s", strerror(errno));
+        return NULL;
+    }
+
+    while ((ret = read(fd, buf, VA_FILEBUF_LEN)) > 0) {
+        file_contents = qemu_realloc(file_contents, count + VA_FILEBUF_LEN);
+        memcpy(file_contents + count, buf, ret);
+        count += ret;
+        if (count > VA_GETFILE_MAX) {
+            xmlrpc_faultf(env, "max file size (%d bytes) exceeded",
+                          VA_GETFILE_MAX);
+            goto EXIT_CLOSE_BAD;
+        }
+    }
+    if (ret == -1) {
+        LOG("read failed: %s", strerror(errno));
+        xmlrpc_faultf(env, "read failed: %s", strerror(errno));
+        goto EXIT_CLOSE_BAD;
+    }
+
+    result = xmlrpc_build_value(env, "6", file_contents, count);
+
+EXIT_CLOSE_BAD:
+    if (file_contents) {
+        qemu_free(file_contents);
+    }
+    close(fd);
+    return result;
+}
+
 static int va_accept(int listen_fd) {
     struct sockaddr_in saddr;
     struct sockaddr *addr;
@@ -42,6 +93,8 @@  typedef struct RPCFunction {
 } RPCFunction;
 
 static RPCFunction guest_functions[] = {
+    { .func = getfile,
+      .func_name = "getfile" },
     { NULL, NULL }
 };
 static RPCFunction host_functions[] = {