debuggers.hg

changeset 22725:e1392f5327ce

xl: Move device model functions in to a separate file

No functional changes.

Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
author Gianni Tedesco <gianni.tedesco@citrix.com>
date Fri Jan 07 18:24:54 2011 +0000 (2011-01-07)
parents 52b57a4781b4
children 03718b569d97
files tools/libxl/Makefile tools/libxl/libxl.c tools/libxl/libxl_dm.c tools/libxl/libxl_internal.h
line diff
     1.1 --- a/tools/libxl/Makefile	Fri Jan 07 18:01:18 2011 +0000
     1.2 +++ b/tools/libxl/Makefile	Fri Jan 07 18:24:54 2011 +0000
     1.3 @@ -29,7 +29,7 @@ endif
     1.4  LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
     1.5  LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
     1.6  
     1.7 -LIBXL_OBJS = flexarray.o libxl.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
     1.8 +LIBXL_OBJS = flexarray.o libxl.o libxl_dm.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
     1.9  LIBXL_OBJS += _libxl_types.o
    1.10  
    1.11  AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
     2.1 --- a/tools/libxl/libxl.c	Fri Jan 07 18:01:18 2011 +0000
     2.2 +++ b/tools/libxl/libxl.c	Fri Jan 07 18:24:54 2011 +0000
     2.3 @@ -902,46 +902,6 @@ int libxl_event_get_disk_eject_info(libx
     2.4      return 1;
     2.5  }
     2.6  
     2.7 -static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid)
     2.8 -{
     2.9 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
    2.10 -    char *pid;
    2.11 -    int ret;
    2.12 -
    2.13 -    pid = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid));
    2.14 -    if (!pid) {
    2.15 -        int stubdomid = libxl_get_stubdom_id(ctx, domid);
    2.16 -        if (!stubdomid) {
    2.17 -            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't find device model's pid");
    2.18 -            ret = ERROR_INVAL;
    2.19 -            goto out;
    2.20 -        }
    2.21 -        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device model is a stubdom, domid=%d\n", stubdomid);
    2.22 -        ret = libxl_domain_destroy(ctx, stubdomid, 0);
    2.23 -        if (ret)
    2.24 -            goto out;
    2.25 -    } else {
    2.26 -        ret = kill(atoi(pid), SIGHUP);
    2.27 -        if (ret < 0 && errno == ESRCH) {
    2.28 -            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model already exited");
    2.29 -            ret = 0;
    2.30 -        } else if (ret == 0) {
    2.31 -            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model signaled");
    2.32 -            ret = 0;
    2.33 -        } else {
    2.34 -            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to kill Device Model [%d]",
    2.35 -                    atoi(pid));
    2.36 -            ret = ERROR_FAIL;
    2.37 -            goto out;
    2.38 -        }
    2.39 -    }
    2.40 -    xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", domid));
    2.41 -
    2.42 -out:
    2.43 -    libxl__free_all(&gc);
    2.44 -    return ret;
    2.45 -}
    2.46 -
    2.47  int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force)
    2.48  {
    2.49      libxl__gc gc = LIBXL_INIT_GC(ctx);
    2.50 @@ -975,8 +935,8 @@ int libxl_domain_destroy(libxl_ctx *ctx,
    2.51          LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid);
    2.52      }
    2.53      if (dm_present) {
    2.54 -        if (libxl_destroy_device_model(ctx, domid) < 0)
    2.55 -            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl_destroy_device_model failed for %d", domid);
    2.56 +        if (libxl__destroy_device_model(ctx, domid) < 0)
    2.57 +            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid);
    2.58      }
    2.59      if (libxl__devices_destroy(ctx, domid, force) < 0)
    2.60          LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl_destroy_devices failed for %d", domid);
    2.61 @@ -1107,698 +1067,6 @@ skip_autopass:
    2.62      return 0;
    2.63  }
    2.64  
    2.65 -static char ** libxl_build_device_model_args_old(libxl__gc *gc,
    2.66 -                                             libxl_device_model_info *info,
    2.67 -                                             libxl_device_nic *vifs,
    2.68 -                                             int num_vifs)
    2.69 -{
    2.70 -    int num = 0, i;
    2.71 -    flexarray_t *dm_args;
    2.72 -    dm_args = flexarray_make(16, 1);
    2.73 -
    2.74 -    if (!dm_args)
    2.75 -        return NULL;
    2.76 -
    2.77 -    flexarray_set(dm_args, num++, "qemu-dm");
    2.78 -    flexarray_set(dm_args, num++, "-d");
    2.79 -
    2.80 -    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
    2.81 -
    2.82 -    if (info->dom_name) {
    2.83 -        flexarray_set(dm_args, num++, "-domain-name");
    2.84 -        flexarray_set(dm_args, num++, info->dom_name);
    2.85 -    }
    2.86 -    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
    2.87 -        flexarray_set(dm_args, num++, "-vnc");
    2.88 -        if (info->vncdisplay) {
    2.89 -            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
    2.90 -                flexarray_set(
    2.91 -                    dm_args, num++,
    2.92 -                    libxl__sprintf(gc, "%s:%d%s",
    2.93 -                                  info->vnclisten,
    2.94 -                                  info->vncdisplay,
    2.95 -                                  info->vncpasswd ? ",password" : ""));
    2.96 -            } else {
    2.97 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "127.0.0.1:%d", info->vncdisplay));
    2.98 -            }
    2.99 -        } else if (info->vnclisten) {
   2.100 -            if (strchr(info->vnclisten, ':') != NULL) {
   2.101 -                flexarray_set(dm_args, num++, info->vnclisten);
   2.102 -            } else {
   2.103 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%s:0", info->vnclisten));
   2.104 -            }
   2.105 -        } else {
   2.106 -            flexarray_set(dm_args, num++, "127.0.0.1:0");
   2.107 -        }
   2.108 -        if (info->vncunused) {
   2.109 -            flexarray_set(dm_args, num++, "-vncunused");
   2.110 -        }
   2.111 -    }
   2.112 -    if (info->sdl) {
   2.113 -        flexarray_set(dm_args, num++, "-sdl");
   2.114 -        if (!info->opengl) {
   2.115 -            flexarray_set(dm_args, num++, "-disable-opengl");
   2.116 -        }
   2.117 -    }
   2.118 -    if (info->keymap) {
   2.119 -        flexarray_set(dm_args, num++, "-k");
   2.120 -        flexarray_set(dm_args, num++, info->keymap);
   2.121 -    }
   2.122 -    if (info->nographic && (!info->sdl && !info->vnc)) {
   2.123 -        flexarray_set(dm_args, num++, "-nographic");
   2.124 -    }
   2.125 -    if (info->serial) {
   2.126 -        flexarray_set(dm_args, num++, "-serial");
   2.127 -        flexarray_set(dm_args, num++, info->serial);
   2.128 -    }
   2.129 -    if (info->type == XENFV) {
   2.130 -        int ioemu_vifs = 0;
   2.131 -
   2.132 -        if (info->videoram) {
   2.133 -            flexarray_set(dm_args, num++, "-videoram");
   2.134 -            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->videoram));
   2.135 -        }
   2.136 -        if (info->stdvga) {
   2.137 -            flexarray_set(dm_args, num++, "-std-vga");
   2.138 -        }
   2.139 -
   2.140 -        if (info->boot) {
   2.141 -            flexarray_set(dm_args, num++, "-boot");
   2.142 -            flexarray_set(dm_args, num++, info->boot);
   2.143 -        }
   2.144 -        if (info->usb || info->usbdevice) {
   2.145 -            flexarray_set(dm_args, num++, "-usb");
   2.146 -            if (info->usbdevice) {
   2.147 -                flexarray_set(dm_args, num++, "-usbdevice");
   2.148 -                flexarray_set(dm_args, num++, info->usbdevice);
   2.149 -            }
   2.150 -        }
   2.151 -        if (info->soundhw) {
   2.152 -            flexarray_set(dm_args, num++, "-soundhw");
   2.153 -            flexarray_set(dm_args, num++, info->soundhw);
   2.154 -        }
   2.155 -        if (info->apic) {
   2.156 -            flexarray_set(dm_args, num++, "-acpi");
   2.157 -        }
   2.158 -        if (info->vcpus > 1) {
   2.159 -            flexarray_set(dm_args, num++, "-vcpus");
   2.160 -            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
   2.161 -        }
   2.162 -        if (info->vcpu_avail) {
   2.163 -            flexarray_set(dm_args, num++, "-vcpu_avail");
   2.164 -            flexarray_set(dm_args, num++, libxl__sprintf(gc, "0x%x", info->vcpu_avail));
   2.165 -        }
   2.166 -        for (i = 0; i < num_vifs; i++) {
   2.167 -            if (vifs[i].nictype == NICTYPE_IOEMU) {
   2.168 -                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
   2.169 -                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
   2.170 -                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   2.171 -                char *ifname;
   2.172 -                if (!vifs[i].ifname)
   2.173 -                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
   2.174 -                else
   2.175 -                    ifname = vifs[i].ifname;
   2.176 -                flexarray_set(dm_args, num++, "-net");
   2.177 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
   2.178 -                            vifs[i].devid, smac, vifs[i].model));
   2.179 -                flexarray_set(dm_args, num++, "-net");
   2.180 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
   2.181 -                            vifs[i].devid, ifname, vifs[i].bridge));
   2.182 -                ioemu_vifs++;
   2.183 -            }
   2.184 -        }
   2.185 -        /* If we have no emulated nics, tell qemu not to create any */
   2.186 -        if ( ioemu_vifs == 0 ) {
   2.187 -            flexarray_set(dm_args, num++, "-net");
   2.188 -            flexarray_set(dm_args, num++, "none");
   2.189 -        }
   2.190 -    }
   2.191 -    if (info->saved_state) {
   2.192 -        flexarray_set(dm_args, num++, "-loadvm");
   2.193 -        flexarray_set(dm_args, num++, info->saved_state);
   2.194 -    }
   2.195 -    for (i = 0; info->extra && info->extra[i] != NULL; i++)
   2.196 -        flexarray_set(dm_args, num++, info->extra[i]);
   2.197 -    flexarray_set(dm_args, num++, "-M");
   2.198 -    if (info->type == XENPV)
   2.199 -        flexarray_set(dm_args, num++, "xenpv");
   2.200 -    else
   2.201 -        flexarray_set(dm_args, num++, "xenfv");
   2.202 -    flexarray_set(dm_args, num++, NULL);
   2.203 -    return (char **) flexarray_contents(dm_args);
   2.204 -}
   2.205 -
   2.206 -static char ** libxl_build_device_model_args_new(libxl__gc *gc,
   2.207 -                                             libxl_device_model_info *info,
   2.208 -                                             libxl_device_nic *vifs,
   2.209 -                                             int num_vifs)
   2.210 -{
   2.211 -    int num = 0, i;
   2.212 -    flexarray_t *dm_args;
   2.213 -    int nb;
   2.214 -    libxl_device_disk *disks;
   2.215 -
   2.216 -    dm_args = flexarray_make(16, 1);
   2.217 -    if (!dm_args)
   2.218 -        return NULL;
   2.219 -
   2.220 -    flexarray_set(dm_args, num++, libxl__strdup(gc, info->device_model));
   2.221 -
   2.222 -    flexarray_set(dm_args, num++, "-xen-domid");
   2.223 -    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
   2.224 -
   2.225 -    if (info->type == XENPV) {
   2.226 -        flexarray_set(dm_args, num++, "-xen-attach");
   2.227 -    }
   2.228 -
   2.229 -    if (info->dom_name) {
   2.230 -        flexarray_set(dm_args, num++, "-name");
   2.231 -        flexarray_set(dm_args, num++, info->dom_name);
   2.232 -    }
   2.233 -    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
   2.234 -        int display = 0;
   2.235 -        const char *listen = "127.0.0.1";
   2.236 -
   2.237 -        flexarray_set(dm_args, num++, "-vnc");
   2.238 -
   2.239 -        if (info->vncdisplay) {
   2.240 -            display = info->vncdisplay;
   2.241 -            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
   2.242 -                listen = info->vnclisten;
   2.243 -            }
   2.244 -        } else if (info->vnclisten) {
   2.245 -            listen = info->vnclisten;
   2.246 -        }
   2.247 -
   2.248 -        if (strchr(listen, ':') != NULL)
   2.249 -            flexarray_set(dm_args, num++,
   2.250 -                    libxl__sprintf(gc, "%s%s", listen,
   2.251 -                        info->vncunused ? ",to=99" : ""));
   2.252 -        else
   2.253 -            flexarray_set(dm_args, num++,
   2.254 -                    libxl__sprintf(gc, "%s:%d%s", listen, display,
   2.255 -                        info->vncunused ? ",to=99" : ""));
   2.256 -    }
   2.257 -    if (info->sdl) {
   2.258 -        flexarray_set(dm_args, num++, "-sdl");
   2.259 -    }
   2.260 -
   2.261 -    if (info->type == XENPV && !info->nographic) {
   2.262 -        flexarray_set(dm_args, num++, "-vga");
   2.263 -        flexarray_set(dm_args, num++, "xenfb");
   2.264 -    }
   2.265 -
   2.266 -    if (info->keymap) {
   2.267 -        flexarray_set(dm_args, num++, "-k");
   2.268 -        flexarray_set(dm_args, num++, info->keymap);
   2.269 -    }
   2.270 -    if (info->nographic && (!info->sdl && !info->vnc)) {
   2.271 -        flexarray_set(dm_args, num++, "-nographic");
   2.272 -    }
   2.273 -    if (info->serial) {
   2.274 -        flexarray_set(dm_args, num++, "-serial");
   2.275 -        flexarray_set(dm_args, num++, info->serial);
   2.276 -    }
   2.277 -    if (info->type == XENFV) {
   2.278 -        int ioemu_vifs = 0;
   2.279 -
   2.280 -        if (info->stdvga) {
   2.281 -                flexarray_set(dm_args, num++, "-vga");
   2.282 -                flexarray_set(dm_args, num++, "std");
   2.283 -        }
   2.284 -
   2.285 -        if (info->boot) {
   2.286 -            flexarray_set(dm_args, num++, "-boot");
   2.287 -            flexarray_set(dm_args, num++, libxl__sprintf(gc, "order=%s", info->boot));
   2.288 -        }
   2.289 -        if (info->usb || info->usbdevice) {
   2.290 -            flexarray_set(dm_args, num++, "-usb");
   2.291 -            if (info->usbdevice) {
   2.292 -                flexarray_set(dm_args, num++, "-usbdevice");
   2.293 -                flexarray_set(dm_args, num++, info->usbdevice);
   2.294 -            }
   2.295 -        }
   2.296 -        if (info->soundhw) {
   2.297 -            flexarray_set(dm_args, num++, "-soundhw");
   2.298 -            flexarray_set(dm_args, num++, info->soundhw);
   2.299 -        }
   2.300 -        if (!info->apic) {
   2.301 -            flexarray_set(dm_args, num++, "-no-acpi");
   2.302 -        }
   2.303 -        if (info->vcpus > 1) {
   2.304 -            flexarray_set(dm_args, num++, "-smp");
   2.305 -            if (info->vcpu_avail)
   2.306 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
   2.307 -            else
   2.308 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
   2.309 -        }
   2.310 -        for (i = 0; i < num_vifs; i++) {
   2.311 -            if (vifs[i].nictype == NICTYPE_IOEMU) {
   2.312 -                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
   2.313 -                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
   2.314 -                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   2.315 -                char *ifname;
   2.316 -                if (!vifs[i].ifname) {
   2.317 -                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
   2.318 -                } else {
   2.319 -                    ifname = vifs[i].ifname;
   2.320 -                }
   2.321 -                flexarray_set(dm_args, num++, "-net");
   2.322 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
   2.323 -                            vifs[i].devid, smac, vifs[i].model));
   2.324 -                flexarray_set(dm_args, num++, "-net");
   2.325 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,script=no",
   2.326 -                            vifs[i].devid, ifname));
   2.327 -                ioemu_vifs++;
   2.328 -            }
   2.329 -        }
   2.330 -        /* If we have no emulated nics, tell qemu not to create any */
   2.331 -        if ( ioemu_vifs == 0 ) {
   2.332 -            flexarray_set(dm_args, num++, "-net");
   2.333 -            flexarray_set(dm_args, num++, "none");
   2.334 -        }
   2.335 -    }
   2.336 -    if (info->saved_state) {
   2.337 -        flexarray_set(dm_args, num++, "-loadvm");
   2.338 -        flexarray_set(dm_args, num++, info->saved_state);
   2.339 -    }
   2.340 -    for (i = 0; info->extra && info->extra[i] != NULL; i++)
   2.341 -        flexarray_set(dm_args, num++, info->extra[i]);
   2.342 -    flexarray_set(dm_args, num++, "-M");
   2.343 -    if (info->type == XENPV)
   2.344 -        flexarray_set(dm_args, num++, "xenpv");
   2.345 -    else
   2.346 -        flexarray_set(dm_args, num++, "xenfv");
   2.347 -
   2.348 -    /* RAM Size */
   2.349 -    flexarray_set(dm_args, num++, "-m");
   2.350 -    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->target_ram));
   2.351 -
   2.352 -    if (info->type == XENFV) {
   2.353 -        disks = libxl_device_disk_list(libxl__gc_owner(gc), info->domid, &nb);
   2.354 -        for (i; i < nb; i++) {
   2.355 -            if (disks[i].is_cdrom) {
   2.356 -                flexarray_set(dm_args, num++, "-cdrom");
   2.357 -                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
   2.358 -            } else {
   2.359 -                flexarray_set(dm_args, num++, libxl__sprintf(gc, "-%s", disks[i].virtpath));
   2.360 -                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
   2.361 -            }
   2.362 -            libxl_device_disk_destroy(&disks[i]);
   2.363 -        }
   2.364 -        free(disks);
   2.365 -    }
   2.366 -    flexarray_set(dm_args, num++, NULL);
   2.367 -    return (char **) flexarray_contents(dm_args);
   2.368 -}
   2.369 -
   2.370 -static char ** libxl_build_device_model_args(libxl__gc *gc,
   2.371 -                                             libxl_device_model_info *info,
   2.372 -                                             libxl_device_nic *vifs,
   2.373 -                                             int num_vifs)
   2.374 -{
   2.375 -    libxl_ctx *ctx = libxl__gc_owner(gc);
   2.376 -    int new_qemu;
   2.377 -
   2.378 -    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
   2.379 -
   2.380 -    if (new_qemu == 1) {
   2.381 -        return libxl_build_device_model_args_new(gc, info, vifs, num_vifs);
   2.382 -    } else {
   2.383 -        return libxl_build_device_model_args_old(gc, info, vifs, num_vifs);
   2.384 -    }
   2.385 -}
   2.386 -
   2.387 -static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
   2.388 -{
   2.389 -    libxl_device_model_starting *starting = for_spawn;
   2.390 -    struct xs_handle *xsh;
   2.391 -    char *path = NULL, *pid = NULL;
   2.392 -    int len;
   2.393 -
   2.394 -    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
   2.395 -        goto out;
   2.396 -
   2.397 -    len = asprintf(&pid, "%d", innerchild);
   2.398 -    if (len < 0)
   2.399 -        goto out;
   2.400 -
   2.401 -    /* we mustn't use the parent's handle in the child */
   2.402 -    xsh = xs_daemon_open();
   2.403 -
   2.404 -    xs_write(xsh, XBT_NULL, path, pid, len);
   2.405 -
   2.406 -    xs_daemon_close(xsh);
   2.407 -out:
   2.408 -    free(path);
   2.409 -    free(pid);
   2.410 -}
   2.411 -
   2.412 -static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx,
   2.413 -                                                    libxl_device_model_info *info,
   2.414 -                                                    libxl_device_vfb *vfb,
   2.415 -                                                    libxl_device_vkb *vkb)
   2.416 -{
   2.417 -    memset(vfb, 0x00, sizeof(libxl_device_vfb));
   2.418 -    memset(vkb, 0x00, sizeof(libxl_device_vkb));
   2.419 -
   2.420 -    vfb->backend_domid = 0;
   2.421 -    vfb->devid = 0;
   2.422 -    vfb->vnc = info->vnc;
   2.423 -    vfb->vnclisten = info->vnclisten;
   2.424 -    vfb->vncdisplay = info->vncdisplay;
   2.425 -    vfb->vncunused = info->vncunused;
   2.426 -    vfb->vncpasswd = info->vncpasswd;
   2.427 -    vfb->keymap = info->keymap;
   2.428 -    vfb->sdl = info->sdl;
   2.429 -    vfb->opengl = info->opengl;
   2.430 -
   2.431 -    vkb->backend_domid = 0;
   2.432 -    vkb->devid = 0;
   2.433 -    return 0;
   2.434 -}
   2.435 -
   2.436 -static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args)
   2.437 -{
   2.438 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.439 -    int i;
   2.440 -    char *vm_path;
   2.441 -    char *dmargs, *path;
   2.442 -    int dmargs_size;
   2.443 -    struct xs_permissions roperm[2];
   2.444 -    xs_transaction_t t;
   2.445 -
   2.446 -    roperm[0].id = 0;
   2.447 -    roperm[0].perms = XS_PERM_NONE;
   2.448 -    roperm[1].id = domid;
   2.449 -    roperm[1].perms = XS_PERM_READ;
   2.450 -
   2.451 -    vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/vm", guest_domid));
   2.452 -
   2.453 -    i = 0;
   2.454 -    dmargs_size = 0;
   2.455 -    while (args[i] != NULL) {
   2.456 -        dmargs_size = dmargs_size + strlen(args[i]) + 1;
   2.457 -        i++;
   2.458 -    }
   2.459 -    dmargs_size++;
   2.460 -    dmargs = (char *) malloc(dmargs_size);
   2.461 -    i = 1;
   2.462 -    dmargs[0] = '\0';
   2.463 -    while (args[i] != NULL) {
   2.464 -        if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) {
   2.465 -            strcat(dmargs, " ");
   2.466 -            strcat(dmargs, args[i]);
   2.467 -        }
   2.468 -        i++;
   2.469 -    }
   2.470 -    path = libxl__sprintf(&gc, "%s/image/dmargs", vm_path);
   2.471 -
   2.472 -retry_transaction:
   2.473 -    t = xs_transaction_start(ctx->xsh);
   2.474 -    xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs));
   2.475 -    xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
   2.476 -    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm));
   2.477 -    if (!xs_transaction_end(ctx->xsh, t, 0))
   2.478 -        if (errno == EAGAIN)
   2.479 -            goto retry_transaction;
   2.480 -    free(dmargs);
   2.481 -    libxl__free_all(&gc);
   2.482 -    return 0;
   2.483 -}
   2.484 -
   2.485 -static int libxl_create_stubdom(libxl_ctx *ctx,
   2.486 -                                libxl_device_model_info *info,
   2.487 -                                libxl_device_disk *disks, int num_disks,
   2.488 -                                libxl_device_nic *vifs, int num_vifs,
   2.489 -                                libxl_device_vfb *vfb,
   2.490 -                                libxl_device_vkb *vkb,
   2.491 -                                libxl_device_model_starting **starting_r)
   2.492 -{
   2.493 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.494 -    int i, num_console = 1, ret;
   2.495 -    libxl_device_console *console;
   2.496 -    libxl_domain_create_info c_info;
   2.497 -    libxl_domain_build_info b_info;
   2.498 -    libxl_domain_build_state state;
   2.499 -    uint32_t domid;
   2.500 -    char **args;
   2.501 -    struct xs_permissions perm[2];
   2.502 -    xs_transaction_t t;
   2.503 -    libxl_device_model_starting *dm_starting = 0;
   2.504 -
   2.505 -    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
   2.506 -    if (!args) {
   2.507 -        ret = ERROR_FAIL;
   2.508 -        goto out;
   2.509 -    }
   2.510 -
   2.511 -    memset(&c_info, 0x00, sizeof(libxl_domain_create_info));
   2.512 -    c_info.hvm = 0;
   2.513 -    c_info.name = libxl__sprintf(&gc, "%s-dm", libxl__domid_to_name(&gc, info->domid));
   2.514 -
   2.515 -    libxl_uuid_copy(&c_info.uuid, &info->uuid);
   2.516 -
   2.517 -    memset(&b_info, 0x00, sizeof(libxl_domain_build_info));
   2.518 -    b_info.max_vcpus = 1;
   2.519 -    b_info.max_memkb = 32 * 1024;
   2.520 -    b_info.target_memkb = b_info.max_memkb;
   2.521 -    b_info.kernel.path = libxl__abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
   2.522 -    b_info.u.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
   2.523 -    b_info.u.pv.ramdisk.path = "";
   2.524 -    b_info.u.pv.features = "";
   2.525 -    b_info.hvm = 0;
   2.526 -
   2.527 -    ret = libxl_domain_make(ctx, &c_info, &domid);
   2.528 -    if (ret)
   2.529 -        goto out_free;
   2.530 -    ret = libxl_domain_build(ctx, &b_info, domid, &state);
   2.531 -    if (ret)
   2.532 -        goto out_free;
   2.533 -
   2.534 -    libxl_write_dmargs(ctx, domid, info->domid, args);
   2.535 -    libxl__xs_write(&gc, XBT_NULL,
   2.536 -                   libxl__sprintf(&gc, "%s/image/device-model-domid", libxl__xs_get_dompath(&gc, info->domid)),
   2.537 -                   "%d", domid);
   2.538 -    libxl__xs_write(&gc, XBT_NULL,
   2.539 -                   libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)),
   2.540 -                   "%d", info->domid);
   2.541 -    ret = xc_domain_set_target(ctx->xch, domid, info->domid);
   2.542 -    if (ret<0) {
   2.543 -        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "setting target domain %d -> %d", domid, info->domid);
   2.544 -        ret = ERROR_FAIL;
   2.545 -        goto out_free;
   2.546 -    }
   2.547 -    xs_set_target(ctx->xsh, domid, info->domid);
   2.548 -
   2.549 -    perm[0].id = domid;
   2.550 -    perm[0].perms = XS_PERM_NONE;
   2.551 -    perm[1].id = info->domid;
   2.552 -    perm[1].perms = XS_PERM_READ;
   2.553 -retry_transaction:
   2.554 -    t = xs_transaction_start(ctx->xsh);
   2.555 -    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid));
   2.556 -    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
   2.557 -    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs", domid));
   2.558 -    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
   2.559 -    if (!xs_transaction_end(ctx->xsh, t, 0))
   2.560 -        if (errno == EAGAIN)
   2.561 -            goto retry_transaction;
   2.562 -
   2.563 -    for (i = 0; i < num_disks; i++) {
   2.564 -        disks[i].domid = domid;
   2.565 -        ret = libxl_device_disk_add(ctx, domid, &disks[i]);
   2.566 -        if (ret)
   2.567 -            goto out_free;
   2.568 -    }
   2.569 -    for (i = 0; i < num_vifs; i++) {
   2.570 -        vifs[i].domid = domid;
   2.571 -        ret = libxl_device_nic_add(ctx, domid, &vifs[i]);
   2.572 -        if (ret)
   2.573 -            goto out_free;
   2.574 -    }
   2.575 -    vfb->domid = domid;
   2.576 -    ret = libxl_device_vfb_add(ctx, domid, vfb);
   2.577 -    if (ret)
   2.578 -        goto out_free;
   2.579 -    vkb->domid = domid;
   2.580 -    ret = libxl_device_vkb_add(ctx, domid, vkb);
   2.581 -    if (ret)
   2.582 -        goto out_free;
   2.583 -
   2.584 -    if (info->serial)
   2.585 -        num_console++;
   2.586 -
   2.587 -    console = libxl__calloc(&gc, num_console, sizeof(libxl_device_console));
   2.588 -    if (!console) {
   2.589 -        ret = ERROR_NOMEM;
   2.590 -        goto out_free;
   2.591 -    }
   2.592 -
   2.593 -    for (i = 0; i < num_console; i++) {
   2.594 -        console[i].devid = i;
   2.595 -        console[i].consback = LIBXL_CONSBACK_IOEMU;
   2.596 -        console[i].domid = domid;
   2.597 -        if (!i) {
   2.598 -            char *filename;
   2.599 -            char *name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
   2.600 -            libxl_create_logfile(ctx, name, &filename);
   2.601 -            console[i].output = libxl__sprintf(&gc, "file:%s", filename);
   2.602 -            console[i].build_state = &state;
   2.603 -            free(filename);
   2.604 -        } else
   2.605 -            console[i].output = "pty";
   2.606 -        ret = libxl_device_console_add(ctx, domid, &console[i]);
   2.607 -        if (ret)
   2.608 -            goto out_free;
   2.609 -    }
   2.610 -    if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
   2.611 -        ret = ERROR_FAIL;
   2.612 -        goto out_free;
   2.613 -    }
   2.614 -    if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) {
   2.615 -        ret = ERROR_FAIL;
   2.616 -        goto out_free;
   2.617 -    }
   2.618 -
   2.619 -    libxl_domain_unpause(ctx, domid);
   2.620 -
   2.621 -    if (starting_r) {
   2.622 -        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
   2.623 -        (*starting_r)->domid = info->domid;
   2.624 -        (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
   2.625 -        (*starting_r)->for_spawn = NULL;
   2.626 -    }
   2.627 -
   2.628 -    ret = 0;
   2.629 -
   2.630 -out_free:
   2.631 -    free(args);
   2.632 -out:
   2.633 -    libxl__free_all(&gc);
   2.634 -    return ret;
   2.635 -}
   2.636 -
   2.637 -int libxl_create_device_model(libxl_ctx *ctx,
   2.638 -                              libxl_device_model_info *info,
   2.639 -                              libxl_device_disk *disks, int num_disks,
   2.640 -                              libxl_device_nic *vifs, int num_vifs,
   2.641 -                              libxl_device_model_starting **starting_r)
   2.642 -{
   2.643 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.644 -    char *path, *logfile;
   2.645 -    int logfile_w, null;
   2.646 -    int rc;
   2.647 -    char **args;
   2.648 -    libxl_device_model_starting buf_starting, *p;
   2.649 -    xs_transaction_t t; 
   2.650 -    char *vm_path;
   2.651 -    char **pass_stuff;
   2.652 -
   2.653 -    if (strstr(info->device_model, "stubdom-dm")) {
   2.654 -        libxl_device_vfb vfb;
   2.655 -        libxl_device_vkb vkb;
   2.656 -
   2.657 -        libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb);
   2.658 -        rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r);
   2.659 -        goto out;
   2.660 -    }
   2.661 -
   2.662 -    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
   2.663 -    if (!args) {
   2.664 -        rc = ERROR_FAIL;
   2.665 -        goto out;
   2.666 -    }
   2.667 -
   2.668 -    path = libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid);
   2.669 -    xs_mkdir(ctx->xsh, XBT_NULL, path);
   2.670 -    libxl__xs_write(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci);
   2.671 -
   2.672 -    libxl_create_logfile(ctx, libxl__sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile);
   2.673 -    logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
   2.674 -    free(logfile);
   2.675 -    null = open("/dev/null", O_RDONLY);
   2.676 -
   2.677 -    if (starting_r) {
   2.678 -        rc = ERROR_NOMEM;
   2.679 -        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
   2.680 -        if (!*starting_r)
   2.681 -            goto out_close;
   2.682 -        p = *starting_r;
   2.683 -        p->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
   2.684 -    } else {
   2.685 -        p = &buf_starting;
   2.686 -        p->for_spawn = NULL;
   2.687 -    }
   2.688 -
   2.689 -    p->domid = info->domid;
   2.690 -    p->dom_path = libxl__xs_get_dompath(&gc, info->domid);
   2.691 -    if (!p->dom_path) {
   2.692 -        rc = ERROR_FAIL;
   2.693 -        goto out_close;
   2.694 -    }
   2.695 -
   2.696 -    if (info->vncpasswd) {
   2.697 -retry_transaction:
   2.698 -        /* Find uuid and the write the vnc password to xenstore for qemu. */
   2.699 -        t = xs_transaction_start(ctx->xsh);
   2.700 -        vm_path = libxl__xs_read(&gc,t,libxl__sprintf(&gc, "%s/vm", p->dom_path));
   2.701 -        if (vm_path) {
   2.702 -            /* Now write the vncpassword into it. */
   2.703 -            pass_stuff = libxl__calloc(&gc, 3, sizeof(char *));
   2.704 -            pass_stuff[0] = "vncpasswd";
   2.705 -            pass_stuff[1] = info->vncpasswd;
   2.706 -            libxl__xs_writev(&gc,t,vm_path,pass_stuff);
   2.707 -            if (!xs_transaction_end(ctx->xsh, t, 0))
   2.708 -                if (errno == EAGAIN)
   2.709 -                    goto retry_transaction;
   2.710 -        }
   2.711 -    }
   2.712 -
   2.713 -    rc = libxl__spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid);
   2.714 -    if (rc < 0)
   2.715 -        goto out_close;
   2.716 -    if (!rc) { /* inner child */
   2.717 -        libxl__exec(null, logfile_w, logfile_w,
   2.718 -                   libxl__abs_path(&gc, info->device_model, libxl_libexec_path()),
   2.719 -                   args);
   2.720 -    }
   2.721 -
   2.722 -    rc = 0;
   2.723 -
   2.724 -out_close:
   2.725 -    close(null);
   2.726 -    close(logfile_w);
   2.727 -    free(args);
   2.728 -out:
   2.729 -    libxl__free_all(&gc);
   2.730 -    return rc;
   2.731 -}
   2.732 -
   2.733 -int libxl_detach_device_model(libxl_ctx *ctx,
   2.734 -                              libxl_device_model_starting *starting)
   2.735 -{
   2.736 -    int rc;
   2.737 -    rc = libxl__spawn_detach(ctx, starting->for_spawn);
   2.738 -    if (starting->for_spawn)
   2.739 -        free(starting->for_spawn);
   2.740 -    free(starting);
   2.741 -    return rc;
   2.742 -}
   2.743 -
   2.744 -
   2.745 -int libxl_confirm_device_model_startup(libxl_ctx *ctx,
   2.746 -                                       libxl_device_model_starting *starting)
   2.747 -{
   2.748 -    int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
   2.749 -    int detach;
   2.750 -    if ( !problem )
   2.751 -        problem = libxl__spawn_check(ctx, starting->for_spawn);
   2.752 -    detach = libxl_detach_device_model(ctx, starting);
   2.753 -    return problem ? problem : detach;
   2.754 -}
   2.755 -
   2.756 -
   2.757  /******************************************************************************/
   2.758  
   2.759  int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk)
   2.760 @@ -2631,80 +1899,6 @@ out:
   2.761  }
   2.762  
   2.763  /******************************************************************************/
   2.764 -static int libxl_build_xenpv_qemu_args(libxl__gc *gc,
   2.765 -                                       uint32_t domid,
   2.766 -                                       libxl_device_vfb *vfb,
   2.767 -                                       libxl_device_model_info *info)
   2.768 -{
   2.769 -    libxl_ctx *ctx = libxl__gc_owner(gc);
   2.770 -    memset(info, 0x00, sizeof(libxl_device_model_info));
   2.771 -
   2.772 -    if (vfb != NULL) {
   2.773 -        info->vnc = vfb->vnc;
   2.774 -        if (vfb->vnclisten)
   2.775 -            info->vnclisten = libxl__strdup(gc, vfb->vnclisten);
   2.776 -        info->vncdisplay = vfb->vncdisplay;
   2.777 -        info->vncunused = vfb->vncunused;
   2.778 -        if (vfb->vncpasswd)
   2.779 -            info->vncpasswd = vfb->vncpasswd;
   2.780 -        if (vfb->keymap)
   2.781 -            info->keymap = libxl__strdup(gc, vfb->keymap);
   2.782 -        info->sdl = vfb->sdl;
   2.783 -        info->opengl = vfb->opengl;
   2.784 -    } else
   2.785 -        info->nographic = 1;
   2.786 -    info->domid = domid;
   2.787 -    info->dom_name = libxl_domid_to_name(ctx, domid);
   2.788 -    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
   2.789 -    info->type = XENPV;
   2.790 -    return 0;
   2.791 -}
   2.792 -
   2.793 -int libxl_need_xenpv_qemu(libxl_ctx *ctx,
   2.794 -        int nr_consoles, libxl_device_console *consoles,
   2.795 -        int nr_vfbs, libxl_device_vfb *vfbs,
   2.796 -        int nr_disks, libxl_device_disk *disks)
   2.797 -{
   2.798 -    int i, ret = 0;
   2.799 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.800 -
   2.801 -    if (nr_consoles > 1) {
   2.802 -        ret = 1;
   2.803 -        goto out;
   2.804 -    }
   2.805 -
   2.806 -    for (i = 0; i < nr_consoles; i++) {
   2.807 -        if (consoles[i].consback == LIBXL_CONSBACK_IOEMU) {
   2.808 -            ret = 1;
   2.809 -            goto out;
   2.810 -        }
   2.811 -    }
   2.812 -
   2.813 -    if (nr_vfbs > 0) {
   2.814 -        ret = 1;
   2.815 -        goto out;
   2.816 -    }
   2.817 -
   2.818 -    if (nr_disks > 0 && !libxl__blktap_enabled(&gc))
   2.819 -        ret = 1;
   2.820 -
   2.821 -out:
   2.822 -    libxl__free_all(&gc);
   2.823 -    return ret;
   2.824 -}
   2.825 -
   2.826 -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
   2.827 -                            libxl_device_model_starting **starting_r)
   2.828 -{
   2.829 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.830 -    libxl_device_model_info info;
   2.831 -
   2.832 -    libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
   2.833 -    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
   2.834 -    libxl__free_all(&gc);
   2.835 -    return 0;
   2.836 -}
   2.837 -
   2.838  int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb)
   2.839  {
   2.840      libxl__gc gc = LIBXL_INIT_GC(ctx);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/libxl/libxl_dm.c	Fri Jan 07 18:24:54 2011 +0000
     3.3 @@ -0,0 +1,833 @@
     3.4 +/*
     3.5 + * Copyright (C) 2010      Citrix Ltd.
     3.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     3.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
     3.8 + * Author Gianni Tedesco <gianni.tedesco@citrix.com>
     3.9 + *
    3.10 + * This program is free software; you can redistribute it and/or modify
    3.11 + * it under the terms of the GNU Lesser General Public License as published
    3.12 + * by the Free Software Foundation; version 2.1 only. with the special
    3.13 + * exception on linking described in file LICENSE.
    3.14 + *
    3.15 + * This program is distributed in the hope that it will be useful,
    3.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.18 + * GNU Lesser General Public License for more details.
    3.19 + */
    3.20 +
    3.21 +#include "libxl_osdeps.h"
    3.22 +
    3.23 +#include <stdio.h>
    3.24 +#include <string.h>
    3.25 +#include <stdlib.h>
    3.26 +#include <unistd.h>
    3.27 +#include <fcntl.h>
    3.28 +#include "libxl_utils.h"
    3.29 +#include "libxl_internal.h"
    3.30 +#include "libxl.h"
    3.31 +#include "flexarray.h"
    3.32 +
    3.33 +static char ** libxl_build_device_model_args_old(libxl__gc *gc,
    3.34 +                                             libxl_device_model_info *info,
    3.35 +                                             libxl_device_nic *vifs,
    3.36 +                                             int num_vifs)
    3.37 +{
    3.38 +    int num = 0, i;
    3.39 +    flexarray_t *dm_args;
    3.40 +    dm_args = flexarray_make(16, 1);
    3.41 +
    3.42 +    if (!dm_args)
    3.43 +        return NULL;
    3.44 +
    3.45 +    flexarray_set(dm_args, num++, "qemu-dm");
    3.46 +    flexarray_set(dm_args, num++, "-d");
    3.47 +
    3.48 +    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
    3.49 +
    3.50 +    if (info->dom_name) {
    3.51 +        flexarray_set(dm_args, num++, "-domain-name");
    3.52 +        flexarray_set(dm_args, num++, info->dom_name);
    3.53 +    }
    3.54 +    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
    3.55 +        flexarray_set(dm_args, num++, "-vnc");
    3.56 +        if (info->vncdisplay) {
    3.57 +            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
    3.58 +                flexarray_set(
    3.59 +                    dm_args, num++,
    3.60 +                    libxl__sprintf(gc, "%s:%d%s",
    3.61 +                                  info->vnclisten,
    3.62 +                                  info->vncdisplay,
    3.63 +                                  info->vncpasswd ? ",password" : ""));
    3.64 +            } else {
    3.65 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "127.0.0.1:%d", info->vncdisplay));
    3.66 +            }
    3.67 +        } else if (info->vnclisten) {
    3.68 +            if (strchr(info->vnclisten, ':') != NULL) {
    3.69 +                flexarray_set(dm_args, num++, info->vnclisten);
    3.70 +            } else {
    3.71 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%s:0", info->vnclisten));
    3.72 +            }
    3.73 +        } else {
    3.74 +            flexarray_set(dm_args, num++, "127.0.0.1:0");
    3.75 +        }
    3.76 +        if (info->vncunused) {
    3.77 +            flexarray_set(dm_args, num++, "-vncunused");
    3.78 +        }
    3.79 +    }
    3.80 +    if (info->sdl) {
    3.81 +        flexarray_set(dm_args, num++, "-sdl");
    3.82 +        if (!info->opengl) {
    3.83 +            flexarray_set(dm_args, num++, "-disable-opengl");
    3.84 +        }
    3.85 +    }
    3.86 +    if (info->keymap) {
    3.87 +        flexarray_set(dm_args, num++, "-k");
    3.88 +        flexarray_set(dm_args, num++, info->keymap);
    3.89 +    }
    3.90 +    if (info->nographic && (!info->sdl && !info->vnc)) {
    3.91 +        flexarray_set(dm_args, num++, "-nographic");
    3.92 +    }
    3.93 +    if (info->serial) {
    3.94 +        flexarray_set(dm_args, num++, "-serial");
    3.95 +        flexarray_set(dm_args, num++, info->serial);
    3.96 +    }
    3.97 +    if (info->type == XENFV) {
    3.98 +        int ioemu_vifs = 0;
    3.99 +
   3.100 +        if (info->videoram) {
   3.101 +            flexarray_set(dm_args, num++, "-videoram");
   3.102 +            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->videoram));
   3.103 +        }
   3.104 +        if (info->stdvga) {
   3.105 +            flexarray_set(dm_args, num++, "-std-vga");
   3.106 +        }
   3.107 +
   3.108 +        if (info->boot) {
   3.109 +            flexarray_set(dm_args, num++, "-boot");
   3.110 +            flexarray_set(dm_args, num++, info->boot);
   3.111 +        }
   3.112 +        if (info->usb || info->usbdevice) {
   3.113 +            flexarray_set(dm_args, num++, "-usb");
   3.114 +            if (info->usbdevice) {
   3.115 +                flexarray_set(dm_args, num++, "-usbdevice");
   3.116 +                flexarray_set(dm_args, num++, info->usbdevice);
   3.117 +            }
   3.118 +        }
   3.119 +        if (info->soundhw) {
   3.120 +            flexarray_set(dm_args, num++, "-soundhw");
   3.121 +            flexarray_set(dm_args, num++, info->soundhw);
   3.122 +        }
   3.123 +        if (info->apic) {
   3.124 +            flexarray_set(dm_args, num++, "-acpi");
   3.125 +        }
   3.126 +        if (info->vcpus > 1) {
   3.127 +            flexarray_set(dm_args, num++, "-vcpus");
   3.128 +            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
   3.129 +        }
   3.130 +        if (info->vcpu_avail) {
   3.131 +            flexarray_set(dm_args, num++, "-vcpu_avail");
   3.132 +            flexarray_set(dm_args, num++, libxl__sprintf(gc, "0x%x", info->vcpu_avail));
   3.133 +        }
   3.134 +        for (i = 0; i < num_vifs; i++) {
   3.135 +            if (vifs[i].nictype == NICTYPE_IOEMU) {
   3.136 +                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
   3.137 +                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
   3.138 +                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   3.139 +                char *ifname;
   3.140 +                if (!vifs[i].ifname)
   3.141 +                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
   3.142 +                else
   3.143 +                    ifname = vifs[i].ifname;
   3.144 +                flexarray_set(dm_args, num++, "-net");
   3.145 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
   3.146 +                            vifs[i].devid, smac, vifs[i].model));
   3.147 +                flexarray_set(dm_args, num++, "-net");
   3.148 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
   3.149 +                            vifs[i].devid, ifname, vifs[i].bridge));
   3.150 +                ioemu_vifs++;
   3.151 +            }
   3.152 +        }
   3.153 +        /* If we have no emulated nics, tell qemu not to create any */
   3.154 +        if ( ioemu_vifs == 0 ) {
   3.155 +            flexarray_set(dm_args, num++, "-net");
   3.156 +            flexarray_set(dm_args, num++, "none");
   3.157 +        }
   3.158 +    }
   3.159 +    if (info->saved_state) {
   3.160 +        flexarray_set(dm_args, num++, "-loadvm");
   3.161 +        flexarray_set(dm_args, num++, info->saved_state);
   3.162 +    }
   3.163 +    for (i = 0; info->extra && info->extra[i] != NULL; i++)
   3.164 +        flexarray_set(dm_args, num++, info->extra[i]);
   3.165 +    flexarray_set(dm_args, num++, "-M");
   3.166 +    if (info->type == XENPV)
   3.167 +        flexarray_set(dm_args, num++, "xenpv");
   3.168 +    else
   3.169 +        flexarray_set(dm_args, num++, "xenfv");
   3.170 +    flexarray_set(dm_args, num++, NULL);
   3.171 +    return (char **) flexarray_contents(dm_args);
   3.172 +}
   3.173 +
   3.174 +static char ** libxl_build_device_model_args_new(libxl__gc *gc,
   3.175 +                                             libxl_device_model_info *info,
   3.176 +                                             libxl_device_nic *vifs,
   3.177 +                                             int num_vifs)
   3.178 +{
   3.179 +    int num = 0, i;
   3.180 +    flexarray_t *dm_args;
   3.181 +    int nb;
   3.182 +    libxl_device_disk *disks;
   3.183 +
   3.184 +    dm_args = flexarray_make(16, 1);
   3.185 +    if (!dm_args)
   3.186 +        return NULL;
   3.187 +
   3.188 +    flexarray_set(dm_args, num++, libxl__strdup(gc, info->device_model));
   3.189 +
   3.190 +    flexarray_set(dm_args, num++, "-xen-domid");
   3.191 +    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
   3.192 +
   3.193 +    if (info->type == XENPV) {
   3.194 +        flexarray_set(dm_args, num++, "-xen-attach");
   3.195 +    }
   3.196 +
   3.197 +    if (info->dom_name) {
   3.198 +        flexarray_set(dm_args, num++, "-name");
   3.199 +        flexarray_set(dm_args, num++, info->dom_name);
   3.200 +    }
   3.201 +    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
   3.202 +        int display = 0;
   3.203 +        const char *listen = "127.0.0.1";
   3.204 +
   3.205 +        flexarray_set(dm_args, num++, "-vnc");
   3.206 +
   3.207 +        if (info->vncdisplay) {
   3.208 +            display = info->vncdisplay;
   3.209 +            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
   3.210 +                listen = info->vnclisten;
   3.211 +            }
   3.212 +        } else if (info->vnclisten) {
   3.213 +            listen = info->vnclisten;
   3.214 +        }
   3.215 +
   3.216 +        if (strchr(listen, ':') != NULL)
   3.217 +            flexarray_set(dm_args, num++,
   3.218 +                    libxl__sprintf(gc, "%s%s", listen,
   3.219 +                        info->vncunused ? ",to=99" : ""));
   3.220 +        else
   3.221 +            flexarray_set(dm_args, num++,
   3.222 +                    libxl__sprintf(gc, "%s:%d%s", listen, display,
   3.223 +                        info->vncunused ? ",to=99" : ""));
   3.224 +    }
   3.225 +    if (info->sdl) {
   3.226 +        flexarray_set(dm_args, num++, "-sdl");
   3.227 +    }
   3.228 +
   3.229 +    if (info->type == XENPV && !info->nographic) {
   3.230 +        flexarray_set(dm_args, num++, "-vga");
   3.231 +        flexarray_set(dm_args, num++, "xenfb");
   3.232 +    }
   3.233 +
   3.234 +    if (info->keymap) {
   3.235 +        flexarray_set(dm_args, num++, "-k");
   3.236 +        flexarray_set(dm_args, num++, info->keymap);
   3.237 +    }
   3.238 +    if (info->nographic && (!info->sdl && !info->vnc)) {
   3.239 +        flexarray_set(dm_args, num++, "-nographic");
   3.240 +    }
   3.241 +    if (info->serial) {
   3.242 +        flexarray_set(dm_args, num++, "-serial");
   3.243 +        flexarray_set(dm_args, num++, info->serial);
   3.244 +    }
   3.245 +    if (info->type == XENFV) {
   3.246 +        int ioemu_vifs = 0;
   3.247 +
   3.248 +        if (info->stdvga) {
   3.249 +                flexarray_set(dm_args, num++, "-vga");
   3.250 +                flexarray_set(dm_args, num++, "std");
   3.251 +        }
   3.252 +
   3.253 +        if (info->boot) {
   3.254 +            flexarray_set(dm_args, num++, "-boot");
   3.255 +            flexarray_set(dm_args, num++, libxl__sprintf(gc, "order=%s", info->boot));
   3.256 +        }
   3.257 +        if (info->usb || info->usbdevice) {
   3.258 +            flexarray_set(dm_args, num++, "-usb");
   3.259 +            if (info->usbdevice) {
   3.260 +                flexarray_set(dm_args, num++, "-usbdevice");
   3.261 +                flexarray_set(dm_args, num++, info->usbdevice);
   3.262 +            }
   3.263 +        }
   3.264 +        if (info->soundhw) {
   3.265 +            flexarray_set(dm_args, num++, "-soundhw");
   3.266 +            flexarray_set(dm_args, num++, info->soundhw);
   3.267 +        }
   3.268 +        if (!info->apic) {
   3.269 +            flexarray_set(dm_args, num++, "-no-acpi");
   3.270 +        }
   3.271 +        if (info->vcpus > 1) {
   3.272 +            flexarray_set(dm_args, num++, "-smp");
   3.273 +            if (info->vcpu_avail)
   3.274 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
   3.275 +            else
   3.276 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
   3.277 +        }
   3.278 +        for (i = 0; i < num_vifs; i++) {
   3.279 +            if (vifs[i].nictype == NICTYPE_IOEMU) {
   3.280 +                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
   3.281 +                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
   3.282 +                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
   3.283 +                char *ifname;
   3.284 +                if (!vifs[i].ifname) {
   3.285 +                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
   3.286 +                } else {
   3.287 +                    ifname = vifs[i].ifname;
   3.288 +                }
   3.289 +                flexarray_set(dm_args, num++, "-net");
   3.290 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
   3.291 +                            vifs[i].devid, smac, vifs[i].model));
   3.292 +                flexarray_set(dm_args, num++, "-net");
   3.293 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,script=no",
   3.294 +                            vifs[i].devid, ifname));
   3.295 +                ioemu_vifs++;
   3.296 +            }
   3.297 +        }
   3.298 +        /* If we have no emulated nics, tell qemu not to create any */
   3.299 +        if ( ioemu_vifs == 0 ) {
   3.300 +            flexarray_set(dm_args, num++, "-net");
   3.301 +            flexarray_set(dm_args, num++, "none");
   3.302 +        }
   3.303 +    }
   3.304 +    if (info->saved_state) {
   3.305 +        flexarray_set(dm_args, num++, "-loadvm");
   3.306 +        flexarray_set(dm_args, num++, info->saved_state);
   3.307 +    }
   3.308 +    for (i = 0; info->extra && info->extra[i] != NULL; i++)
   3.309 +        flexarray_set(dm_args, num++, info->extra[i]);
   3.310 +    flexarray_set(dm_args, num++, "-M");
   3.311 +    if (info->type == XENPV)
   3.312 +        flexarray_set(dm_args, num++, "xenpv");
   3.313 +    else
   3.314 +        flexarray_set(dm_args, num++, "xenfv");
   3.315 +
   3.316 +    /* RAM Size */
   3.317 +    flexarray_set(dm_args, num++, "-m");
   3.318 +    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->target_ram));
   3.319 +
   3.320 +    if (info->type == XENFV) {
   3.321 +        disks = libxl_device_disk_list(libxl__gc_owner(gc), info->domid, &nb);
   3.322 +        for (i; i < nb; i++) {
   3.323 +            if (disks[i].is_cdrom) {
   3.324 +                flexarray_set(dm_args, num++, "-cdrom");
   3.325 +                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
   3.326 +            } else {
   3.327 +                flexarray_set(dm_args, num++, libxl__sprintf(gc, "-%s", disks[i].virtpath));
   3.328 +                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
   3.329 +            }
   3.330 +            libxl_device_disk_destroy(&disks[i]);
   3.331 +        }
   3.332 +        free(disks);
   3.333 +    }
   3.334 +    flexarray_set(dm_args, num++, NULL);
   3.335 +    return (char **) flexarray_contents(dm_args);
   3.336 +}
   3.337 +
   3.338 +static char ** libxl_build_device_model_args(libxl__gc *gc,
   3.339 +                                             libxl_device_model_info *info,
   3.340 +                                             libxl_device_nic *vifs,
   3.341 +                                             int num_vifs)
   3.342 +{
   3.343 +    libxl_ctx *ctx = libxl__gc_owner(gc);
   3.344 +    int new_qemu;
   3.345 +
   3.346 +    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
   3.347 +
   3.348 +    if (new_qemu == 1) {
   3.349 +        return libxl_build_device_model_args_new(gc, info, vifs, num_vifs);
   3.350 +    } else {
   3.351 +        return libxl_build_device_model_args_old(gc, info, vifs, num_vifs);
   3.352 +    }
   3.353 +}
   3.354 +
   3.355 +static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
   3.356 +{
   3.357 +    libxl_device_model_starting *starting = for_spawn;
   3.358 +    struct xs_handle *xsh;
   3.359 +    char *path = NULL, *pid = NULL;
   3.360 +    int len;
   3.361 +
   3.362 +    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
   3.363 +        goto out;
   3.364 +
   3.365 +    len = asprintf(&pid, "%d", innerchild);
   3.366 +    if (len < 0)
   3.367 +        goto out;
   3.368 +
   3.369 +    /* we mustn't use the parent's handle in the child */
   3.370 +    xsh = xs_daemon_open();
   3.371 +
   3.372 +    xs_write(xsh, XBT_NULL, path, pid, len);
   3.373 +
   3.374 +    xs_daemon_close(xsh);
   3.375 +out:
   3.376 +    free(path);
   3.377 +    free(pid);
   3.378 +}
   3.379 +
   3.380 +static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx,
   3.381 +                                                    libxl_device_model_info *info,
   3.382 +                                                    libxl_device_vfb *vfb,
   3.383 +                                                    libxl_device_vkb *vkb)
   3.384 +{
   3.385 +    memset(vfb, 0x00, sizeof(libxl_device_vfb));
   3.386 +    memset(vkb, 0x00, sizeof(libxl_device_vkb));
   3.387 +
   3.388 +    vfb->backend_domid = 0;
   3.389 +    vfb->devid = 0;
   3.390 +    vfb->vnc = info->vnc;
   3.391 +    vfb->vnclisten = info->vnclisten;
   3.392 +    vfb->vncdisplay = info->vncdisplay;
   3.393 +    vfb->vncunused = info->vncunused;
   3.394 +    vfb->vncpasswd = info->vncpasswd;
   3.395 +    vfb->keymap = info->keymap;
   3.396 +    vfb->sdl = info->sdl;
   3.397 +    vfb->opengl = info->opengl;
   3.398 +
   3.399 +    vkb->backend_domid = 0;
   3.400 +    vkb->devid = 0;
   3.401 +    return 0;
   3.402 +}
   3.403 +
   3.404 +static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args)
   3.405 +{
   3.406 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   3.407 +    int i;
   3.408 +    char *vm_path;
   3.409 +    char *dmargs, *path;
   3.410 +    int dmargs_size;
   3.411 +    struct xs_permissions roperm[2];
   3.412 +    xs_transaction_t t;
   3.413 +
   3.414 +    roperm[0].id = 0;
   3.415 +    roperm[0].perms = XS_PERM_NONE;
   3.416 +    roperm[1].id = domid;
   3.417 +    roperm[1].perms = XS_PERM_READ;
   3.418 +
   3.419 +    vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/vm", guest_domid));
   3.420 +
   3.421 +    i = 0;
   3.422 +    dmargs_size = 0;
   3.423 +    while (args[i] != NULL) {
   3.424 +        dmargs_size = dmargs_size + strlen(args[i]) + 1;
   3.425 +        i++;
   3.426 +    }
   3.427 +    dmargs_size++;
   3.428 +    dmargs = (char *) malloc(dmargs_size);
   3.429 +    i = 1;
   3.430 +    dmargs[0] = '\0';
   3.431 +    while (args[i] != NULL) {
   3.432 +        if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) {
   3.433 +            strcat(dmargs, " ");
   3.434 +            strcat(dmargs, args[i]);
   3.435 +        }
   3.436 +        i++;
   3.437 +    }
   3.438 +    path = libxl__sprintf(&gc, "%s/image/dmargs", vm_path);
   3.439 +
   3.440 +retry_transaction:
   3.441 +    t = xs_transaction_start(ctx->xsh);
   3.442 +    xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs));
   3.443 +    xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
   3.444 +    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm));
   3.445 +    if (!xs_transaction_end(ctx->xsh, t, 0))
   3.446 +        if (errno == EAGAIN)
   3.447 +            goto retry_transaction;
   3.448 +    free(dmargs);
   3.449 +    libxl__free_all(&gc);
   3.450 +    return 0;
   3.451 +}
   3.452 +
   3.453 +static int libxl_create_stubdom(libxl_ctx *ctx,
   3.454 +                                libxl_device_model_info *info,
   3.455 +                                libxl_device_disk *disks, int num_disks,
   3.456 +                                libxl_device_nic *vifs, int num_vifs,
   3.457 +                                libxl_device_vfb *vfb,
   3.458 +                                libxl_device_vkb *vkb,
   3.459 +                                libxl_device_model_starting **starting_r)
   3.460 +{
   3.461 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   3.462 +    int i, num_console = 1, ret;
   3.463 +    libxl_device_console *console;
   3.464 +    libxl_domain_create_info c_info;
   3.465 +    libxl_domain_build_info b_info;
   3.466 +    libxl_domain_build_state state;
   3.467 +    uint32_t domid;
   3.468 +    char **args;
   3.469 +    struct xs_permissions perm[2];
   3.470 +    xs_transaction_t t;
   3.471 +    libxl_device_model_starting *dm_starting = 0;
   3.472 +
   3.473 +    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
   3.474 +    if (!args) {
   3.475 +        ret = ERROR_FAIL;
   3.476 +        goto out;
   3.477 +    }
   3.478 +
   3.479 +    memset(&c_info, 0x00, sizeof(libxl_domain_create_info));
   3.480 +    c_info.hvm = 0;
   3.481 +    c_info.name = libxl__sprintf(&gc, "%s-dm", libxl__domid_to_name(&gc, info->domid));
   3.482 +
   3.483 +    libxl_uuid_copy(&c_info.uuid, &info->uuid);
   3.484 +
   3.485 +    memset(&b_info, 0x00, sizeof(libxl_domain_build_info));
   3.486 +    b_info.max_vcpus = 1;
   3.487 +    b_info.max_memkb = 32 * 1024;
   3.488 +    b_info.target_memkb = b_info.max_memkb;
   3.489 +    b_info.kernel.path = libxl__abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
   3.490 +    b_info.u.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
   3.491 +    b_info.u.pv.ramdisk.path = "";
   3.492 +    b_info.u.pv.features = "";
   3.493 +    b_info.hvm = 0;
   3.494 +
   3.495 +    ret = libxl_domain_make(ctx, &c_info, &domid);
   3.496 +    if (ret)
   3.497 +        goto out_free;
   3.498 +    ret = libxl_domain_build(ctx, &b_info, domid, &state);
   3.499 +    if (ret)
   3.500 +        goto out_free;
   3.501 +
   3.502 +    libxl_write_dmargs(ctx, domid, info->domid, args);
   3.503 +    libxl__xs_write(&gc, XBT_NULL,
   3.504 +                   libxl__sprintf(&gc, "%s/image/device-model-domid", libxl__xs_get_dompath(&gc, info->domid)),
   3.505 +                   "%d", domid);
   3.506 +    libxl__xs_write(&gc, XBT_NULL,
   3.507 +                   libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)),
   3.508 +                   "%d", info->domid);
   3.509 +    ret = xc_domain_set_target(ctx->xch, domid, info->domid);
   3.510 +    if (ret<0) {
   3.511 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "setting target domain %d -> %d", domid, info->domid);
   3.512 +        ret = ERROR_FAIL;
   3.513 +        goto out_free;
   3.514 +    }
   3.515 +    xs_set_target(ctx->xsh, domid, info->domid);
   3.516 +
   3.517 +    perm[0].id = domid;
   3.518 +    perm[0].perms = XS_PERM_NONE;
   3.519 +    perm[1].id = info->domid;
   3.520 +    perm[1].perms = XS_PERM_READ;
   3.521 +retry_transaction:
   3.522 +    t = xs_transaction_start(ctx->xsh);
   3.523 +    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid));
   3.524 +    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
   3.525 +    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs", domid));
   3.526 +    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
   3.527 +    if (!xs_transaction_end(ctx->xsh, t, 0))
   3.528 +        if (errno == EAGAIN)
   3.529 +            goto retry_transaction;
   3.530 +
   3.531 +    for (i = 0; i < num_disks; i++) {
   3.532 +        disks[i].domid = domid;
   3.533 +        ret = libxl_device_disk_add(ctx, domid, &disks[i]);
   3.534 +        if (ret)
   3.535 +            goto out_free;
   3.536 +    }
   3.537 +    for (i = 0; i < num_vifs; i++) {
   3.538 +        vifs[i].domid = domid;
   3.539 +        ret = libxl_device_nic_add(ctx, domid, &vifs[i]);
   3.540 +        if (ret)
   3.541 +            goto out_free;
   3.542 +    }
   3.543 +    vfb->domid = domid;
   3.544 +    ret = libxl_device_vfb_add(ctx, domid, vfb);
   3.545 +    if (ret)
   3.546 +        goto out_free;
   3.547 +    vkb->domid = domid;
   3.548 +    ret = libxl_device_vkb_add(ctx, domid, vkb);
   3.549 +    if (ret)
   3.550 +        goto out_free;
   3.551 +
   3.552 +    if (info->serial)
   3.553 +        num_console++;
   3.554 +
   3.555 +    console = libxl__calloc(&gc, num_console, sizeof(libxl_device_console));
   3.556 +    if (!console) {
   3.557 +        ret = ERROR_NOMEM;
   3.558 +        goto out_free;
   3.559 +    }
   3.560 +
   3.561 +    for (i = 0; i < num_console; i++) {
   3.562 +        console[i].devid = i;
   3.563 +        console[i].consback = LIBXL_CONSBACK_IOEMU;
   3.564 +        console[i].domid = domid;
   3.565 +        if (!i) {
   3.566 +            char *filename;
   3.567 +            char *name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
   3.568 +            libxl_create_logfile(ctx, name, &filename);
   3.569 +            console[i].output = libxl__sprintf(&gc, "file:%s", filename);
   3.570 +            console[i].build_state = &state;
   3.571 +            free(filename);
   3.572 +        } else
   3.573 +            console[i].output = "pty";
   3.574 +        ret = libxl_device_console_add(ctx, domid, &console[i]);
   3.575 +        if (ret)
   3.576 +            goto out_free;
   3.577 +    }
   3.578 +    if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
   3.579 +        ret = ERROR_FAIL;
   3.580 +        goto out_free;
   3.581 +    }
   3.582 +    if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) {
   3.583 +        ret = ERROR_FAIL;
   3.584 +        goto out_free;
   3.585 +    }
   3.586 +
   3.587 +    libxl_domain_unpause(ctx, domid);
   3.588 +
   3.589 +    if (starting_r) {
   3.590 +        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
   3.591 +        (*starting_r)->domid = info->domid;
   3.592 +        (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
   3.593 +        (*starting_r)->for_spawn = NULL;
   3.594 +    }
   3.595 +
   3.596 +    ret = 0;
   3.597 +
   3.598 +out_free:
   3.599 +    free(args);
   3.600 +out:
   3.601 +    libxl__free_all(&gc);
   3.602 +    return ret;
   3.603 +}
   3.604 +
   3.605 +int libxl_create_device_model(libxl_ctx *ctx,
   3.606 +                              libxl_device_model_info *info,
   3.607 +                              libxl_device_disk *disks, int num_disks,
   3.608 +                              libxl_device_nic *vifs, int num_vifs,
   3.609 +                              libxl_device_model_starting **starting_r)
   3.610 +{
   3.611 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   3.612 +    char *path, *logfile;
   3.613 +    int logfile_w, null;
   3.614 +    int rc;
   3.615 +    char **args;
   3.616 +    libxl_device_model_starting buf_starting, *p;
   3.617 +    xs_transaction_t t; 
   3.618 +    char *vm_path;
   3.619 +    char **pass_stuff;
   3.620 +
   3.621 +    if (strstr(info->device_model, "stubdom-dm")) {
   3.622 +        libxl_device_vfb vfb;
   3.623 +        libxl_device_vkb vkb;
   3.624 +
   3.625 +        libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb);
   3.626 +        rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r);
   3.627 +        goto out;
   3.628 +    }
   3.629 +
   3.630 +    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
   3.631 +    if (!args) {
   3.632 +        rc = ERROR_FAIL;
   3.633 +        goto out;
   3.634 +    }
   3.635 +
   3.636 +    path = libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid);
   3.637 +    xs_mkdir(ctx->xsh, XBT_NULL, path);
   3.638 +    libxl__xs_write(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci);
   3.639 +
   3.640 +    libxl_create_logfile(ctx, libxl__sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile);
   3.641 +    logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
   3.642 +    free(logfile);
   3.643 +    null = open("/dev/null", O_RDONLY);
   3.644 +
   3.645 +    if (starting_r) {
   3.646 +        rc = ERROR_NOMEM;
   3.647 +        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
   3.648 +        if (!*starting_r)
   3.649 +            goto out_close;
   3.650 +        p = *starting_r;
   3.651 +        p->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
   3.652 +    } else {
   3.653 +        p = &buf_starting;
   3.654 +        p->for_spawn = NULL;
   3.655 +    }
   3.656 +
   3.657 +    p->domid = info->domid;
   3.658 +    p->dom_path = libxl__xs_get_dompath(&gc, info->domid);
   3.659 +    if (!p->dom_path) {
   3.660 +        rc = ERROR_FAIL;
   3.661 +        goto out_close;
   3.662 +    }
   3.663 +
   3.664 +    if (info->vncpasswd) {
   3.665 +retry_transaction:
   3.666 +        /* Find uuid and the write the vnc password to xenstore for qemu. */
   3.667 +        t = xs_transaction_start(ctx->xsh);
   3.668 +        vm_path = libxl__xs_read(&gc,t,libxl__sprintf(&gc, "%s/vm", p->dom_path));
   3.669 +        if (vm_path) {
   3.670 +            /* Now write the vncpassword into it. */
   3.671 +            pass_stuff = libxl__calloc(&gc, 3, sizeof(char *));
   3.672 +            pass_stuff[0] = "vncpasswd";
   3.673 +            pass_stuff[1] = info->vncpasswd;
   3.674 +            libxl__xs_writev(&gc,t,vm_path,pass_stuff);
   3.675 +            if (!xs_transaction_end(ctx->xsh, t, 0))
   3.676 +                if (errno == EAGAIN)
   3.677 +                    goto retry_transaction;
   3.678 +        }
   3.679 +    }
   3.680 +
   3.681 +    rc = libxl__spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid);
   3.682 +    if (rc < 0)
   3.683 +        goto out_close;
   3.684 +    if (!rc) { /* inner child */
   3.685 +        libxl__exec(null, logfile_w, logfile_w,
   3.686 +                   libxl__abs_path(&gc, info->device_model, libxl_libexec_path()),
   3.687 +                   args);
   3.688 +    }
   3.689 +
   3.690 +    rc = 0;
   3.691 +
   3.692 +out_close:
   3.693 +    close(null);
   3.694 +    close(logfile_w);
   3.695 +    free(args);
   3.696 +out:
   3.697 +    libxl__free_all(&gc);
   3.698 +    return rc;
   3.699 +}
   3.700 +
   3.701 +int libxl_detach_device_model(libxl_ctx *ctx,
   3.702 +                              libxl_device_model_starting *starting)
   3.703 +{
   3.704 +    int rc;
   3.705 +    rc = libxl__spawn_detach(ctx, starting->for_spawn);
   3.706 +    if (starting->for_spawn)
   3.707 +        free(starting->for_spawn);
   3.708 +    free(starting);
   3.709 +    return rc;
   3.710 +}
   3.711 +
   3.712 +
   3.713 +int libxl_confirm_device_model_startup(libxl_ctx *ctx,
   3.714 +                                       libxl_device_model_starting *starting)
   3.715 +{
   3.716 +    int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
   3.717 +    int detach;
   3.718 +    if ( !problem )
   3.719 +        problem = libxl__spawn_check(ctx, starting->for_spawn);
   3.720 +    detach = libxl_detach_device_model(ctx, starting);
   3.721 +    return problem ? problem : detach;
   3.722 +}
   3.723 +
   3.724 +int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid)
   3.725 +{
   3.726 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   3.727 +    char *pid;
   3.728 +    int ret;
   3.729 +
   3.730 +    pid = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid));
   3.731 +    if (!pid) {
   3.732 +        int stubdomid = libxl_get_stubdom_id(ctx, domid);
   3.733 +        if (!stubdomid) {
   3.734 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't find device model's pid");
   3.735 +            ret = ERROR_INVAL;
   3.736 +            goto out;
   3.737 +        }
   3.738 +        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device model is a stubdom, domid=%d\n", stubdomid);
   3.739 +        ret = libxl_domain_destroy(ctx, stubdomid, 0);
   3.740 +        if (ret)
   3.741 +            goto out;
   3.742 +    } else {
   3.743 +        ret = kill(atoi(pid), SIGHUP);
   3.744 +        if (ret < 0 && errno == ESRCH) {
   3.745 +            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model already exited");
   3.746 +            ret = 0;
   3.747 +        } else if (ret == 0) {
   3.748 +            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model signaled");
   3.749 +            ret = 0;
   3.750 +        } else {
   3.751 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to kill Device Model [%d]",
   3.752 +                    atoi(pid));
   3.753 +            ret = ERROR_FAIL;
   3.754 +            goto out;
   3.755 +        }
   3.756 +    }
   3.757 +    xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", domid));
   3.758 +
   3.759 +out:
   3.760 +    libxl__free_all(&gc);
   3.761 +    return ret;
   3.762 +}
   3.763 +
   3.764 +static int libxl_build_xenpv_qemu_args(libxl__gc *gc,
   3.765 +                                       uint32_t domid,
   3.766 +                                       libxl_device_vfb *vfb,
   3.767 +                                       libxl_device_model_info *info)
   3.768 +{
   3.769 +    libxl_ctx *ctx = libxl__gc_owner(gc);
   3.770 +    memset(info, 0x00, sizeof(libxl_device_model_info));
   3.771 +
   3.772 +    if (vfb != NULL) {
   3.773 +        info->vnc = vfb->vnc;
   3.774 +        if (vfb->vnclisten)
   3.775 +            info->vnclisten = libxl__strdup(gc, vfb->vnclisten);
   3.776 +        info->vncdisplay = vfb->vncdisplay;
   3.777 +        info->vncunused = vfb->vncunused;
   3.778 +        if (vfb->vncpasswd)
   3.779 +            info->vncpasswd = vfb->vncpasswd;
   3.780 +        if (vfb->keymap)
   3.781 +            info->keymap = libxl__strdup(gc, vfb->keymap);
   3.782 +        info->sdl = vfb->sdl;
   3.783 +        info->opengl = vfb->opengl;
   3.784 +    } else
   3.785 +        info->nographic = 1;
   3.786 +    info->domid = domid;
   3.787 +    info->dom_name = libxl_domid_to_name(ctx, domid);
   3.788 +    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
   3.789 +    info->type = XENPV;
   3.790 +    return 0;
   3.791 +}
   3.792 +
   3.793 +int libxl_need_xenpv_qemu(libxl_ctx *ctx,
   3.794 +        int nr_consoles, libxl_device_console *consoles,
   3.795 +        int nr_vfbs, libxl_device_vfb *vfbs,
   3.796 +        int nr_disks, libxl_device_disk *disks)
   3.797 +{
   3.798 +    int i, ret = 0;
   3.799 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   3.800 +
   3.801 +    if (nr_consoles > 1) {
   3.802 +        ret = 1;
   3.803 +        goto out;
   3.804 +    }
   3.805 +
   3.806 +    for (i = 0; i < nr_consoles; i++) {
   3.807 +        if (consoles[i].consback == LIBXL_CONSBACK_IOEMU) {
   3.808 +            ret = 1;
   3.809 +            goto out;
   3.810 +        }
   3.811 +    }
   3.812 +
   3.813 +    if (nr_vfbs > 0) {
   3.814 +        ret = 1;
   3.815 +        goto out;
   3.816 +    }
   3.817 +
   3.818 +    if (nr_disks > 0 && !libxl__blktap_enabled(&gc))
   3.819 +        ret = 1;
   3.820 +
   3.821 +out:
   3.822 +    libxl__free_all(&gc);
   3.823 +    return ret;
   3.824 +}
   3.825 +
   3.826 +int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
   3.827 +                            libxl_device_model_starting **starting_r)
   3.828 +{
   3.829 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   3.830 +    libxl_device_model_info info;
   3.831 +
   3.832 +    libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
   3.833 +    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
   3.834 +    libxl__free_all(&gc);
   3.835 +    return 0;
   3.836 +}
     4.1 --- a/tools/libxl/libxl_internal.h	Fri Jan 07 18:01:18 2011 +0000
     4.2 +++ b/tools/libxl/libxl_internal.h	Fri Jan 07 18:24:54 2011 +0000
     4.3 @@ -204,6 +204,8 @@ struct libxl__device_model_starting {
     4.4                        libxl_device_model_starting *starting,
     4.5                        const char *what,
     4.6                        void (*intermediate_hook)(void *for_spawn, pid_t innerchild));
     4.7 +_hidden int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid);
     4.8 +
     4.9    /* Logs errors.  A copy of "what" is taken.  Return values:
    4.10     *  < 0   error, for_spawn need not be detached
    4.11     *   +1   caller is the parent, must call detach on *for_spawn eventually