debuggers.hg

changeset 21989:88adea5b4546

libxl, Introduce the command line handler for the new qemu.
From: Anthony PERARD <anthony.perard@citrix.com>

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@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
tools/libxl/libxl.c | 160 ++++++++++++++++++++++++++++++++++++++++++++-
tools/libxl/libxl_utils.c | 78 ++++++++++++++++++++++
tools/libxl/libxl_utils.h | 6 ++
3 files changed, 243 insertions(+), 1 deletions(-)
author Anthony Perard <anthony.perard@citrix.com>
date Mon Aug 09 16:46:01 2010 +0100 (2010-08-09)
parents a8098da3461c
children 0232bc7c9544
files tools/libxl/libxl.c tools/libxl/libxl_utils.c tools/libxl/libxl_utils.h
line diff
     1.1 --- a/tools/libxl/libxl.c	Mon Aug 09 16:46:00 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Mon Aug 09 16:46:01 2010 +0100
     1.3 @@ -964,7 +964,7 @@ skip_autopass:
     1.4      return 0;
     1.5  }
     1.6  
     1.7 -static char ** libxl_build_device_model_args(libxl_ctx *ctx,
     1.8 +static char ** libxl_build_device_model_args_old(libxl_ctx *ctx,
     1.9                                               libxl_device_model_info *info,
    1.10                                               libxl_device_nic *vifs,
    1.11                                               int num_vifs)
    1.12 @@ -1098,10 +1098,168 @@ static char ** libxl_build_device_model_
    1.13      else
    1.14          flexarray_set(dm_args, num++, "xenfv");
    1.15      flexarray_set(dm_args, num++, NULL);
    1.16 -
    1.17      return (char **) flexarray_contents(dm_args);
    1.18  }
    1.19  
    1.20 +static char ** libxl_build_device_model_args_new(libxl_ctx *ctx,
    1.21 +                                             libxl_device_model_info *info,
    1.22 +                                             libxl_device_nic *vifs,
    1.23 +                                             int num_vifs)
    1.24 +{
    1.25 +    int num = 0, i;
    1.26 +    flexarray_t *dm_args;
    1.27 +    int nb;
    1.28 +    libxl_device_disk *disks;
    1.29 +
    1.30 +    dm_args = flexarray_make(16, 1);
    1.31 +    if (!dm_args)
    1.32 +        return NULL;
    1.33 +
    1.34 +    flexarray_set(dm_args, num++, "qemu-system-xen");
    1.35 +    flexarray_set(dm_args, num++, "-xen-domid");
    1.36 +
    1.37 +    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid));
    1.38 +
    1.39 +    if (info->dom_name) {
    1.40 +        flexarray_set(dm_args, num++, "-name");
    1.41 +        flexarray_set(dm_args, num++, info->dom_name);
    1.42 +    }
    1.43 +    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
    1.44 +        int display = 0;
    1.45 +        const char *listen = "127.0.0.1";
    1.46 +
    1.47 +        flexarray_set(dm_args, num++, "-vnc");
    1.48 +
    1.49 +        if (info->vncdisplay) {
    1.50 +            display = info->vncdisplay;
    1.51 +            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
    1.52 +                listen = info->vnclisten;
    1.53 +            }
    1.54 +        } else if (info->vnclisten) {
    1.55 +            listen = info->vnclisten;
    1.56 +        }
    1.57 +
    1.58 +        if (strchr(listen, ':') != NULL)
    1.59 +            flexarray_set(dm_args, num++,
    1.60 +                    libxl_sprintf(ctx, "%s%s", listen,
    1.61 +                        info->vncunused ? ",to=99" : ""));
    1.62 +        else
    1.63 +            flexarray_set(dm_args, num++,
    1.64 +                    libxl_sprintf(ctx, "%s:%d%s", listen, display,
    1.65 +                        info->vncunused ? ",to=99" : ""));
    1.66 +    }
    1.67 +    if (info->sdl) {
    1.68 +        flexarray_set(dm_args, num++, "-sdl");
    1.69 +    }
    1.70 +    if (info->keymap) {
    1.71 +        flexarray_set(dm_args, num++, "-k");
    1.72 +        flexarray_set(dm_args, num++, info->keymap);
    1.73 +    }
    1.74 +    if (info->nographic && (!info->sdl && !info->vnc)) {
    1.75 +        flexarray_set(dm_args, num++, "-nographic");
    1.76 +    }
    1.77 +    if (info->serial) {
    1.78 +        flexarray_set(dm_args, num++, "-serial");
    1.79 +        flexarray_set(dm_args, num++, info->serial);
    1.80 +    }
    1.81 +    if (info->type == XENFV) {
    1.82 +        int ioemu_vifs = 0;
    1.83 +
    1.84 +        if (info->stdvga) {
    1.85 +                flexarray_set(dm_args, num++, "-vga");
    1.86 +                flexarray_set(dm_args, num++, "std");
    1.87 +        }
    1.88 +
    1.89 +        if (info->boot) {
    1.90 +            flexarray_set(dm_args, num++, "-boot");
    1.91 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "order=%s", info->boot));
    1.92 +        }
    1.93 +        if (info->usb || info->usbdevice) {
    1.94 +            flexarray_set(dm_args, num++, "-usb");
    1.95 +            if (info->usbdevice) {
    1.96 +                flexarray_set(dm_args, num++, "-usbdevice");
    1.97 +                flexarray_set(dm_args, num++, info->usbdevice);
    1.98 +            }
    1.99 +        }
   1.100 +        if (info->soundhw) {
   1.101 +            flexarray_set(dm_args, num++, "-soundhw");
   1.102 +            flexarray_set(dm_args, num++, info->soundhw);
   1.103 +        }
   1.104 +        if (!info->apic) {
   1.105 +            flexarray_set(dm_args, num++, "-no-acpi");
   1.106 +        }
   1.107 +        if (info->vcpus > 1) {
   1.108 +            flexarray_set(dm_args, num++, "-smp");
   1.109 +            if (info->vcpu_avail)
   1.110 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
   1.111 +            else
   1.112 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus));
   1.113 +        }
   1.114 +        for (i = 0; i < num_vifs; i++) {
   1.115 +            if (vifs[i].nictype == NICTYPE_IOEMU) {
   1.116 +                char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x",
   1.117 +                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
   1.118 +                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   1.119 +                if (!vifs[i].ifname)
   1.120 +                    vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid);
   1.121 +                flexarray_set(dm_args, num++, "-net");
   1.122 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s",
   1.123 +                            vifs[i].devid, smac, vifs[i].model));
   1.124 +                flexarray_set(dm_args, num++, "-net");
   1.125 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,script=%s",
   1.126 +                            vifs[i].devid, vifs[i].ifname, "/etc/xen/scripts/qemu-ifup"));
   1.127 +                ioemu_vifs++;
   1.128 +            }
   1.129 +        }
   1.130 +        /* If we have no emulated nics, tell qemu not to create any */
   1.131 +        if ( ioemu_vifs == 0 ) {
   1.132 +            flexarray_set(dm_args, num++, "-net");
   1.133 +            flexarray_set(dm_args, num++, "none");
   1.134 +        }
   1.135 +    }
   1.136 +    if (info->saved_state) {
   1.137 +        flexarray_set(dm_args, num++, "-loadvm");
   1.138 +        flexarray_set(dm_args, num++, info->saved_state);
   1.139 +    }
   1.140 +    for (i = 0; info->extra && info->extra[i] != NULL; i++)
   1.141 +        flexarray_set(dm_args, num++, info->extra[i]);
   1.142 +    flexarray_set(dm_args, num++, "-M");
   1.143 +    if (info->type == XENPV)
   1.144 +        flexarray_set(dm_args, num++, "xenpv");
   1.145 +    else
   1.146 +        flexarray_set(dm_args, num++, "xenfv");
   1.147 +
   1.148 +    disks = libxl_device_disk_list(ctx, info->domid, &nb);
   1.149 +    for (; nb > 0; --nb, ++disks) {
   1.150 +        if ( disks->is_cdrom ) {
   1.151 +            flexarray_set(dm_args, num++, "-cdrom");
   1.152 +            flexarray_set(dm_args, num++, disks->physpath);
   1.153 +        }else{
   1.154 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-%s", disks->virtpath));
   1.155 +            flexarray_set(dm_args, num++, disks->physpath);
   1.156 +        }
   1.157 +    }
   1.158 +
   1.159 +    flexarray_set(dm_args, num++, NULL);
   1.160 +    return (char **) flexarray_contents(dm_args);
   1.161 +}
   1.162 +
   1.163 +static char ** libxl_build_device_model_args(libxl_ctx *ctx,
   1.164 +                                             libxl_device_model_info *info,
   1.165 +                                             libxl_device_nic *vifs,
   1.166 +                                             int num_vifs)
   1.167 +{
   1.168 +    int new_qemu;
   1.169 +
   1.170 +    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
   1.171 +
   1.172 +    if (new_qemu == 1) {
   1.173 +        return libxl_build_device_model_args_new(ctx, info, vifs, num_vifs);
   1.174 +    } else {
   1.175 +        return libxl_build_device_model_args_old(ctx, info, vifs, num_vifs);
   1.176 +    }
   1.177 +}
   1.178 +
   1.179  void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
   1.180  {
   1.181      libxl_device_model_starting *starting = for_spawn;
     2.1 --- a/tools/libxl/libxl_utils.c	Mon Aug 09 16:46:00 2010 +0100
     2.2 +++ b/tools/libxl/libxl_utils.c	Mon Aug 09 16:46:01 2010 +0100
     2.3 @@ -538,3 +538,81 @@ int libxl_strtomac(const char *mac_s, ui
     2.4      }
     2.5      return 0;
     2.6  }
     2.7 +
     2.8 +#define QEMU_VERSION_STR  "QEMU emulator version "
     2.9 +
    2.10 +
    2.11 +int libxl_check_device_model_version(libxl_ctx *ctx, char *path)
    2.12 +{
    2.13 +    pid_t pid = -1;
    2.14 +    int pipefd[2];
    2.15 +    char buf[100];
    2.16 +    ssize_t i, count = 0;
    2.17 +    int status;
    2.18 +    char *abs_path = NULL;
    2.19 +
    2.20 +    abs_path = libxl_abs_path(ctx, path, libxl_private_bindir_path());
    2.21 +
    2.22 +    if (pipe(pipefd))
    2.23 +        return -1;
    2.24 +
    2.25 +    pid = fork();
    2.26 +    if (pid == -1) {
    2.27 +        return -1;
    2.28 +    }
    2.29 +
    2.30 +    if (!pid) {
    2.31 +        close(pipefd[0]);
    2.32 +        if (dup2(pipefd[1], STDOUT_FILENO) == -1)
    2.33 +            exit(1);
    2.34 +        execlp(abs_path, abs_path, "-h", NULL);
    2.35 +
    2.36 +        close(pipefd[1]);
    2.37 +        exit(127);
    2.38 +    }
    2.39 +
    2.40 +    close(pipefd[1]);
    2.41 +    if (abs_path != path)
    2.42 +        libxl_free(ctx, abs_path);
    2.43 +
    2.44 +    /* attempt to get the first line of `qemu -h` */
    2.45 +    while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) {
    2.46 +        if (i + count > 90)
    2.47 +            break;
    2.48 +        for (int j = 0; j <  i; j++) {
    2.49 +            if (buf[j + count] == '\n')
    2.50 +                break;
    2.51 +        }
    2.52 +        count += i;
    2.53 +    }
    2.54 +    count += i;
    2.55 +    close(pipefd[0]);
    2.56 +    waitpid(pid, &status, 0);
    2.57 +    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
    2.58 +        return -1;
    2.59 +    }
    2.60 +
    2.61 +    /* Check if we have the forked qemu-xen. */
    2.62 +    /* QEMU-DM emulator version 0.10.2, ... */
    2.63 +    if (strncmp("QEMU-DM ", buf, 7) == 0) {
    2.64 +        return 0;
    2.65 +    }
    2.66 +
    2.67 +    /* Check if the version is above 12.0 */
    2.68 +    /* The first line is : QEMU emulator version 0.12.50, ... */
    2.69 +    if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) {
    2.70 +        int major, minor;
    2.71 +        char *endptr = NULL;
    2.72 +        char *v = buf + strlen(QEMU_VERSION_STR);
    2.73 +
    2.74 +        major = strtol(v, &endptr, 10);
    2.75 +        if (major == 0 && endptr && *endptr == '.') {
    2.76 +            v = endptr + 1;
    2.77 +            minor = strtol(v, &endptr, 10);
    2.78 +            if (minor >= 12)
    2.79 +                return 1;
    2.80 +        }
    2.81 +    }
    2.82 +
    2.83 +    return -1;
    2.84 +}
     3.1 --- a/tools/libxl/libxl_utils.h	Mon Aug 09 16:46:00 2010 +0100
     3.2 +++ b/tools/libxl/libxl_utils.h	Mon Aug 09 16:46:01 2010 +0100
     3.3 @@ -68,5 +68,11 @@ int libxl_strtomac(const char *mac_s, ui
     3.4  int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
     3.5                                 const char *devid, libxl_device_net2 *net2);
     3.6  
     3.7 +/* check the version of qemu
     3.8 + * return 1 if is the new one
     3.9 + * return 0 if is the old one
    3.10 + * return -1 if there are an error */
    3.11 +int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
    3.12 +
    3.13  #endif
    3.14