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

[Xen-changelog] [xen master] libxl: add Qdisk backend launch helper



commit 5cf2bea385d1bdd409f06789220910876c0ab17d
Author:     Roger Pau Monne <roger.pau@xxxxxxxxxx>
AuthorDate: Thu Sep 19 15:33:59 2013 +0200
Commit:     Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CommitDate: Mon Nov 18 17:09:14 2013 +0000

    libxl: add Qdisk backend launch helper
    
    Current Qemu launch functions in libxl require the usage of data
    structures only avaialbe on domain creation. All this information is
    not need in order to launch a Qemu instance to serve Qdisk backends,
    so introduce a new simplified helper that can be used to launch
    Qemu/Qdisk, that will be used to launch Qdisk in driver domains.
    
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
    Cc: Anthony PERARD <anthony.perard@xxxxxxxxxx>
    Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
    Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 tools/libxl/libxl_dm.c       |  148 +++++++++++++++++++++++++++++++++++++-----
 tools/libxl/libxl_internal.h |    6 ++
 2 files changed, 138 insertions(+), 16 deletions(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index b4798b8..292e351 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -42,6 +42,23 @@ static const char *qemu_xen_path(libxl__gc *gc)
 #endif
 }
 
+static int libxl__create_qemu_logfile(libxl__gc *gc, char *name)
+{
+    char *logfile;
+    int logfile_w;
+
+    libxl_create_logfile(CTX, name, &logfile);
+    logfile_w = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
+    free(logfile);
+
+    if (logfile_w < 0) {
+        LOGE(ERROR, "unable to open Qemu logfile");
+        return ERROR_FAIL;
+    }
+
+    return logfile_w;
+}
+
 const char *libxl__domain_device_model(libxl__gc *gc,
                                        const libxl_domain_build_info *info)
 {
@@ -1149,7 +1166,7 @@ void libxl__spawn_local_dm(libxl__egc *egc, 
libxl__dm_spawn_state *dmss)
     const libxl_domain_create_info *c_info = &guest_config->c_info;
     const libxl_domain_build_info *b_info = &guest_config->b_info;
     const libxl_vnc_info *vnc = libxl__dm_vnc(guest_config);
-    char *path, *logfile;
+    char *path;
     int logfile_w, null;
     int rc;
     char **args, **arg;
@@ -1204,11 +1221,12 @@ void libxl__spawn_local_dm(libxl__egc *egc, 
libxl__dm_spawn_state *dmss)
         libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/disable_pf", 
path),
                     "%d", !libxl_defbool_val(b_info->u.hvm.xen_platform_pci));
 
-    libxl_create_logfile(ctx,
-                         libxl__sprintf(gc, "qemu-dm-%s", c_info->name),
-                         &logfile);
-    logfile_w = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
-    free(logfile);
+    logfile_w = libxl__create_qemu_logfile(gc, GCSPRINTF("qemu-dm-%s",
+                                                         c_info->name));
+    if (logfile_w < 0) {
+        rc = logfile_w;
+        goto out;
+    }
     null = open("/dev/null", O_RDONLY);
 
     const char *dom_path = libxl__xs_get_dompath(gc, domid);
@@ -1268,7 +1286,6 @@ out:
 static void device_model_confirm(libxl__egc *egc, libxl__spawn_state *spawn,
                                  const char *xsdata)
 {
-    libxl__dm_spawn_state *dmss = CONTAINER_OF(spawn, *dmss, spawn);
     STATE_AO_GC(spawn->ao);
 
     if (!xsdata)
@@ -1320,18 +1337,91 @@ static void device_model_spawn_outcome(libxl__egc *egc,
     dmss->callback(egc, dmss, rc);
 }
 
-int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
+void libxl__spawn_qdisk_backend(libxl__egc *egc, libxl__dm_spawn_state *dmss)
 {
-    char *pid;
-    int ret;
+    STATE_AO_GC(dmss->spawn.ao);
+    flexarray_t *dm_args;
+    char **args;
+    const char *dm;
+    int logfile_w, null, rc;
+    uint32_t domid = dmss->guest_domid;
+
+    /* Always use qemu-xen as device model */
+    dm = qemu_xen_path(gc);
+
+    dm_args = flexarray_make(gc, 15, 1);
+    flexarray_vappend(dm_args, dm, "-xen-domid",
+                      GCSPRINTF("%d", domid), NULL);
+    flexarray_append(dm_args, "-xen-attach");
+    flexarray_vappend(dm_args, "-name",
+                      GCSPRINTF("domain-%u", domid), NULL);
+    flexarray_append(dm_args, "-nographic");
+    flexarray_vappend(dm_args, "-M", "xenpv", NULL);
+    flexarray_vappend(dm_args, "-monitor", "/dev/null", NULL);
+    flexarray_vappend(dm_args, "-serial", "/dev/null", NULL);
+    flexarray_vappend(dm_args, "-parallel", "/dev/null", NULL);
+    flexarray_append(dm_args, NULL);
+    args = (char **) flexarray_contents(dm_args);
 
-    pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, 
"/local/domain/%d/image/device-model-pid", domid));
-    if (!pid || !atoi(pid)) {
-        LOG(ERROR, "could not find device-model's pid for dom %u", domid);
-        ret = ERROR_FAIL;
+    logfile_w = libxl__create_qemu_logfile(gc, GCSPRINTF("qdisk-%u", domid));
+    if (logfile_w < 0) {
+        rc = logfile_w;
+        goto error;
+    }
+    null = open("/dev/null", O_RDONLY);
+
+    dmss->guest_config = NULL;
+    /*
+     * Clearly specify Qemu not using a saved state, so
+     * device_model_spawn_outcome doesn't try to unlink it.
+     */
+    dmss->build_state = libxl__zalloc(gc, sizeof(*dmss->build_state));
+    dmss->build_state->saved_state = 0;
+
+    dmss->spawn.what = GCSPRINTF("domain %u Qdisk backend", domid);
+    dmss->spawn.xspath = GCSPRINTF("device-model/%u/state", domid);
+    dmss->spawn.timeout_ms = LIBXL_DEVICE_MODEL_START_TIMEOUT * 1000;
+    /*
+     * We cannot save Qemu pid anywhere in the xenstore guest dir,
+     * because we will call this from unprivileged driver domains,
+     * so save it in the current domain libxl private dir.
+     */
+    dmss->spawn.pidpath = GCSPRINTF("libxl/%u/qdisk-backend-pid", domid);
+    dmss->spawn.midproc_cb = libxl__spawn_record_pid;
+    dmss->spawn.confirm_cb = device_model_confirm;
+    dmss->spawn.failure_cb = device_model_startup_failed;
+    dmss->spawn.detached_cb = device_model_detached;
+    rc = libxl__spawn_spawn(egc, &dmss->spawn);
+    if (rc < 0)
+        goto error;
+    if (!rc) { /* inner child */
+        setsid();
+        libxl__exec(gc, null, logfile_w, logfile_w, dm, args, NULL);
+    }
+
+    return;
+
+error:
+    assert(rc);
+    dmss->callback(egc, dmss, rc);
+    return;
+}
+
+/* Generic function to signal a Qemu instance to exit */
+static int kill_device_model(libxl__gc *gc, const char *xs_path_pid)
+{
+    const char *xs_pid;
+    int ret, pid;
+
+    ret = libxl__xs_read_checked(gc, XBT_NULL, xs_path_pid, &xs_pid);
+    if (ret || !xs_pid) {
+        LOG(ERROR, "unable to find device model pid in %s", xs_path_pid);
+        ret = ret ? : ERROR_FAIL;
         goto out;
     }
-    ret = kill(atoi(pid), SIGHUP);
+    pid = atoi(xs_pid);
+
+    ret = kill(pid, SIGHUP);
     if (ret < 0 && errno == ESRCH) {
         LOG(ERROR, "Device Model already exited");
         ret = 0;
@@ -1339,7 +1429,7 @@ int libxl__destroy_device_model(libxl__gc *gc, uint32_t 
domid)
         LOG(DEBUG, "Device Model signaled");
         ret = 0;
     } else {
-        LOGE(ERROR, "failed to kill Device Model [%d]", atoi(pid));
+        LOGE(ERROR, "failed to kill Device Model [%d]", pid);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -1348,6 +1438,32 @@ out:
     return ret;
 }
 
+/* Helper to destroy a Qdisk backend */
+int libxl__destroy_qdisk_backend(libxl__gc *gc, uint32_t domid)
+{
+    char *pid_path;
+    int rc;
+
+    pid_path = GCSPRINTF("libxl/%u/qdisk-backend-pid", domid);
+
+    rc = kill_device_model(gc, pid_path);
+    if (rc)
+        goto out;
+
+    libxl__xs_rm_checked(gc, XBT_NULL, pid_path);
+    libxl__xs_rm_checked(gc, XBT_NULL,
+                         GCSPRINTF("device-model/%u", domid));
+
+out:
+    return rc;
+}
+
+int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
+{
+    return kill_device_model(gc,
+                GCSPRINTF("/local/domain/%d/image/device-model-pid", domid));
+}
+
 int libxl__need_xenpv_qemu(libxl__gc *gc,
         int nr_consoles, libxl__device_console *consoles,
         int nr_vfbs, libxl_device_vfb *vfbs,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index e3b9fb4..cff3518 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2548,6 +2548,12 @@ _hidden void libxl__spawn_stub_dm(libxl__egc *egc, 
libxl__stub_dm_spawn_state*);
 
 _hidden char *libxl__stub_dm_name(libxl__gc *gc, const char * guest_name);
 
+/* Qdisk backend launch helpers */
+
+_hidden void libxl__spawn_qdisk_backend(libxl__egc *egc,
+                                        libxl__dm_spawn_state *dmss);
+_hidden int libxl__destroy_qdisk_backend(libxl__gc *gc, uint32_t domid);
+
 /*----- Domain creation -----*/
 
 typedef struct libxl__domain_create_state libxl__domain_create_state;
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.