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

[Xen-devel] [PATCH v2 2/3] libxl, Introduce the command line handler for the new qemu.



From: Anthony PERARD <anthony.perard@xxxxxxxxxx>

This patch adds a function to check the version of the device model.
Depending on the version of the DM, the command line arguments will be
built differently.

Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 tools/libxl/libxl.c       |  160 ++++++++++++++++++++++++++++++++++++++++++++-
 tools/libxl/libxl_utils.c |   78 ++++++++++++++++++++++
 tools/libxl/libxl_utils.h |    6 ++
 3 files changed, 243 insertions(+), 1 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 97cca38..53b5499 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -964,7 +964,7 @@ skip_autopass:
     return 0;
 }
 
-static char ** libxl_build_device_model_args(libxl_ctx *ctx,
+static char ** libxl_build_device_model_args_old(libxl_ctx *ctx,
                                              libxl_device_model_info *info,
                                              libxl_device_nic *vifs,
                                              int num_vifs)
@@ -1098,10 +1098,168 @@ static char ** libxl_build_device_model_args(libxl_ctx 
*ctx,
     else
         flexarray_set(dm_args, num++, "xenfv");
     flexarray_set(dm_args, num++, NULL);
+    return (char **) flexarray_contents(dm_args);
+}
+
+static char ** libxl_build_device_model_args_new(libxl_ctx *ctx,
+                                             libxl_device_model_info *info,
+                                             libxl_device_nic *vifs,
+                                             int num_vifs)
+{
+    int num = 0, i;
+    flexarray_t *dm_args;
+    int nb;
+    libxl_device_disk *disks;
+
+    dm_args = flexarray_make(16, 1);
+    if (!dm_args)
+        return NULL;
+
+    flexarray_set(dm_args, num++, "qemu-system-xen");
+    flexarray_set(dm_args, num++, "-xen-domid");
+
+    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid));
+
+    if (info->dom_name) {
+        flexarray_set(dm_args, num++, "-name");
+        flexarray_set(dm_args, num++, info->dom_name);
+    }
+    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
+        int display = 0;
+        const char *listen = "127.0.0.1";
+
+        flexarray_set(dm_args, num++, "-vnc");
+
+        if (info->vncdisplay) {
+            display = info->vncdisplay;
+            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
+                listen = info->vnclisten;
+            }
+        } else if (info->vnclisten) {
+            listen = info->vnclisten;
+        }
+
+        if (strchr(listen, ':') != NULL)
+            flexarray_set(dm_args, num++,
+                    libxl_sprintf(ctx, "%s%s", listen,
+                        info->vncunused ? ",to=99" : ""));
+        else
+            flexarray_set(dm_args, num++,
+                    libxl_sprintf(ctx, "%s:%d%s", listen, display,
+                        info->vncunused ? ",to=99" : ""));
+    }
+    if (info->sdl) {
+        flexarray_set(dm_args, num++, "-sdl");
+    }
+    if (info->keymap) {
+        flexarray_set(dm_args, num++, "-k");
+        flexarray_set(dm_args, num++, info->keymap);
+    }
+    if (info->nographic && (!info->sdl && !info->vnc)) {
+        flexarray_set(dm_args, num++, "-nographic");
+    }
+    if (info->serial) {
+        flexarray_set(dm_args, num++, "-serial");
+        flexarray_set(dm_args, num++, info->serial);
+    }
+    if (info->type == XENFV) {
+        int ioemu_vifs = 0;
+
+        if (info->stdvga) {
+                flexarray_set(dm_args, num++, "-vga");
+                flexarray_set(dm_args, num++, "std");
+        }
+
+        if (info->boot) {
+            flexarray_set(dm_args, num++, "-boot");
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "order=%s", 
info->boot));
+        }
+        if (info->usb || info->usbdevice) {
+            flexarray_set(dm_args, num++, "-usb");
+            if (info->usbdevice) {
+                flexarray_set(dm_args, num++, "-usbdevice");
+                flexarray_set(dm_args, num++, info->usbdevice);
+            }
+        }
+        if (info->soundhw) {
+            flexarray_set(dm_args, num++, "-soundhw");
+            flexarray_set(dm_args, num++, info->soundhw);
+        }
+        if (!info->apic) {
+            flexarray_set(dm_args, num++, "-no-acpi");
+        }
+        if (info->vcpus > 1) {
+            flexarray_set(dm_args, num++, "-smp");
+            if (info->vcpu_avail)
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
+            else
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", 
info->vcpus));
+        }
+        for (i = 0; i < num_vifs; i++) {
+            if (vifs[i].nictype == NICTYPE_IOEMU) {
+                char *smac = libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                                           vifs[i].mac[0], vifs[i].mac[1], 
vifs[i].mac[2],
+                                           vifs[i].mac[3], vifs[i].mac[4], 
vifs[i].mac[5]);
+                if (!vifs[i].ifname)
+                    vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", 
info->domid, vifs[i].devid);
+                flexarray_set(dm_args, num++, "-net");
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"nic,vlan=%d,macaddr=%s,model=%s",
+                            vifs[i].devid, smac, vifs[i].model));
+                flexarray_set(dm_args, num++, "-net");
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"tap,vlan=%d,ifname=%s,script=%s",
+                            vifs[i].devid, vifs[i].ifname, 
"/etc/xen/scripts/qemu-ifup"));
+                ioemu_vifs++;
+            }
+        }
+        /* If we have no emulated nics, tell qemu not to create any */
+        if ( ioemu_vifs == 0 ) {
+            flexarray_set(dm_args, num++, "-net");
+            flexarray_set(dm_args, num++, "none");
+        }
+    }
+    if (info->saved_state) {
+        flexarray_set(dm_args, num++, "-loadvm");
+        flexarray_set(dm_args, num++, info->saved_state);
+    }
+    for (i = 0; info->extra && info->extra[i] != NULL; i++)
+        flexarray_set(dm_args, num++, info->extra[i]);
+    flexarray_set(dm_args, num++, "-M");
+    if (info->type == XENPV)
+        flexarray_set(dm_args, num++, "xenpv");
+    else
+        flexarray_set(dm_args, num++, "xenfv");
 
+    disks = libxl_device_disk_list(ctx, info->domid, &nb);
+    for (; nb > 0; --nb, ++disks) {
+        if ( disks->is_cdrom ) {
+            flexarray_set(dm_args, num++, "-cdrom");
+            flexarray_set(dm_args, num++, disks->physpath);
+        }else{
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-%s", 
disks->virtpath));
+            flexarray_set(dm_args, num++, disks->physpath);
+        }
+    }
+
+    flexarray_set(dm_args, num++, NULL);
     return (char **) flexarray_contents(dm_args);
 }
 
+static char ** libxl_build_device_model_args(libxl_ctx *ctx,
+                                             libxl_device_model_info *info,
+                                             libxl_device_nic *vifs,
+                                             int num_vifs)
+{
+    int new_qemu;
+
+    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
+
+    if (new_qemu == 1) {
+        return libxl_build_device_model_args_new(ctx, info, vifs, num_vifs);
+    } else {
+        return libxl_build_device_model_args_old(ctx, info, vifs, num_vifs);
+    }
+}
+
 void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
 {
     libxl_device_model_starting *starting = for_spawn;
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 8a1fa5a..a6417bb 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -535,3 +535,81 @@ int libxl_strtomac(const char *mac_s, uint8_t *mac)
     }
     return 0;
 }
+
+#define QEMU_VERSION_STR  "QEMU emulator version "
+
+
+int libxl_check_device_model_version(libxl_ctx *ctx, char *path)
+{
+    pid_t pid = -1;
+    int pipefd[2];
+    char buf[100];
+    ssize_t i, count = 0;
+    int status;
+    char *abs_path = NULL;
+
+    abs_path = libxl_abs_path(ctx, path, libxl_private_bindir_path());
+
+    if (pipe(pipefd))
+        return -1;
+
+    pid = fork();
+    if (pid == -1) {
+        return -1;
+    }
+
+    if (!pid) {
+        close(pipefd[0]);
+        if (dup2(pipefd[1], STDOUT_FILENO) == -1)
+            exit(1);
+        execlp(abs_path, abs_path, "-h", NULL);
+
+        close(pipefd[1]);
+        exit(127);
+    }
+
+    close(pipefd[1]);
+    if (abs_path != path)
+        libxl_free(ctx, abs_path);
+
+    /* attempt to get the first line of `qemu -h` */
+    while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) {
+        if (i + count > 90)
+            break;
+        for (int j = 0; j <  i; j++) {
+            if (buf[j + count] == '\n')
+                break;
+        }
+        count += i;
+    }
+    count += i;
+    close(pipefd[0]);
+    waitpid(pid, &status, 0);
+    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+        return -1;
+    }
+
+    /* Check if we have the forked qemu-xen. */
+    /* QEMU-DM emulator version 0.10.2, ... */
+    if (strncmp("QEMU-DM ", buf, 7) == 0) {
+        return 0;
+    }
+
+    /* Check if the version is above 12.0 */
+    /* The first line is : QEMU emulator version 0.12.50, ... */
+    if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) {
+        int major, minor;
+        char *endptr = NULL;
+        char *v = buf + strlen(QEMU_VERSION_STR);
+
+        major = strtol(v, &endptr, 10);
+        if (major == 0 && endptr && *endptr == '.') {
+            v = endptr + 1;
+            minor = strtol(v, &endptr, 10);
+            if (minor >= 12)
+                return 1;
+        }
+    }
+
+    return -1;
+}
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 98a912c..5de2137 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -68,5 +68,11 @@ int libxl_strtomac(const char *mac_s, uint8_t *mac);
 int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
                                const char *devid, libxl_device_net2 *net2);
 
+/* check the version of qemu
+ * return 1 if is the new one
+ * return 0 if is the old one
+ * return -1 if there are an error */
+int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
+
 #endif
 
-- 
1.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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