debuggers.hg

annotate tools/libxl/libxl.c @ 20468:50d33023051d

tools: Make build again on netbsd

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Nov 10 13:01:09 2009 +0000 (2009-11-10)
parents 494ad84ad38c
children 8a1d2e35edfa
rev   line source
keir@20462 1 /*
keir@20462 2 * Copyright (C) 2009 Citrix Ltd.
keir@20462 3 * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
keir@20462 4 * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
keir@20462 5 *
keir@20462 6 * This program is free software; you can redistribute it and/or modify
keir@20462 7 * it under the terms of the GNU Lesser General Public License as published
keir@20462 8 * by the Free Software Foundation; version 2.1 only. with the special
keir@20462 9 * exception on linking described in file LICENSE.
keir@20462 10 *
keir@20462 11 * This program is distributed in the hope that it will be useful,
keir@20462 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
keir@20462 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
keir@20462 14 * GNU Lesser General Public License for more details.
keir@20462 15 */
keir@20462 16
keir@20462 17 #include <stdio.h>
keir@20462 18 #include <string.h>
keir@20462 19 #include <stdlib.h>
keir@20462 20 #include <sys/stat.h>
keir@20462 21 #include <sys/types.h>
keir@20462 22 #include <fcntl.h>
keir@20462 23 #include <sys/select.h>
keir@20462 24 #include <signal.h>
keir@20468 25 #include <unistd.h> /* for write, unlink and close */
keir@20462 26 #include "libxl.h"
keir@20462 27 #include "libxl_utils.h"
keir@20462 28 #include "libxl_internal.h"
keir@20462 29 #include "flexarray.h"
keir@20462 30
keir@20462 31 int libxl_ctx_init(struct libxl_ctx *ctx)
keir@20462 32 {
keir@20462 33 memset(ctx, 0, sizeof(struct libxl_ctx));
keir@20462 34 ctx->alloc_maxsize = 256;
keir@20462 35 ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *));
keir@20462 36 if (!ctx->alloc_ptrs)
keir@20462 37 return ERROR_NOMEM;
keir@20462 38
keir@20462 39 ctx->xch = xc_interface_open();
keir@20462 40 ctx->xsh = xs_daemon_open();
keir@20462 41 return 0;
keir@20462 42 }
keir@20462 43
keir@20462 44 int libxl_ctx_free(struct libxl_ctx *ctx)
keir@20462 45 {
keir@20462 46 libxl_free_all(ctx);
keir@20462 47 free(ctx->alloc_ptrs);
keir@20462 48 ctx->alloc_ptrs = NULL;
keir@20462 49 xc_interface_close(ctx->xch);
keir@20462 50 xs_daemon_close(ctx->xsh);
keir@20462 51 return 0;
keir@20462 52 }
keir@20462 53
keir@20462 54 int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data)
keir@20462 55 {
keir@20462 56 ctx->log_callback = log_callback;
keir@20462 57 ctx->log_userdata = log_data;
keir@20462 58 return 0;
keir@20462 59 }
keir@20462 60
keir@20462 61 /******************************************************************************/
keir@20462 62
keir@20462 63 int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info,
keir@20462 64 uint32_t *domid)
keir@20462 65 {
keir@20462 66 int flags, ret, i;
keir@20468 67 char *uuid_string;
keir@20462 68 char *rw_paths[] = { "device" };
keir@20462 69 char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
keir@20462 70 "control", "attr", "data", "messages" };
keir@20462 71 char *dom_path, *vm_path, *vss_path;
keir@20462 72 struct xs_permissions roperm[2];
keir@20462 73 struct xs_permissions rwperm[1];
keir@20462 74 xs_transaction_t t;
keir@20468 75 xen_domain_handle_t handle;
keir@20462 76
keir@20468 77 uuid_string = libxl_uuid_to_string(ctx, info->uuid);
keir@20462 78 if (!uuid_string) {
keir@20462 79 XL_LOG(ctx, XL_LOG_ERROR, "missing uuid");
keir@20462 80 return ERROR_FAIL;
keir@20462 81 }
keir@20462 82
keir@20462 83 flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
keir@20462 84 flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
keir@20462 85 *domid = 0;
keir@20462 86
keir@20468 87 /* XXX handle has to be initialised here.
keir@20468 88 * info->uuid != xen_domain_handle_t
keir@20468 89 * See:
keir@20468 90 * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
keir@20468 91 * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
keir@20468 92 *
keir@20468 93 * A DCE 1.1 compatible source representation of UUIDs.
keir@20468 94 *
keir@20468 95 * struct uuid {
keir@20468 96 * uint32_t time_low;
keir@20468 97 * uint16_t time_mid;
keir@20468 98 * uint16_t time_hi_and_version;
keir@20468 99 * uint8_t clock_seq_hi_and_reserved;
keir@20468 100 * uint8_t clock_seq_low;
keir@20468 101 * uint8_t node[_UUID_NODE_LEN];
keir@20468 102 * };
keir@20468 103 */
keir@20468 104
keir@20468 105 ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
keir@20462 106 if (ret < 0) {
keir@20462 107 XL_LOG(ctx, XL_LOG_ERROR, "domain creation fail: %d", ret);
keir@20462 108 return ERROR_FAIL;
keir@20462 109 }
keir@20462 110
keir@20462 111 dom_path = libxl_xs_get_dompath(ctx, *domid);
keir@20462 112 vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string);
keir@20462 113 vss_path = libxl_sprintf(ctx, "/vss/%s", uuid_string);
keir@20462 114 if (!dom_path || !vm_path || !vss_path) {
keir@20462 115 XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths");
keir@20462 116 return ERROR_FAIL;
keir@20462 117 }
keir@20462 118
keir@20462 119 roperm[0].id = 0;
keir@20462 120 roperm[0].perms = XS_PERM_NONE;
keir@20462 121 roperm[1].id = *domid;
keir@20462 122 roperm[1].perms = XS_PERM_READ;
keir@20462 123 rwperm[0].id = *domid;
keir@20462 124 rwperm[0].perms = XS_PERM_NONE;
keir@20462 125
keir@20462 126 retry_transaction:
keir@20462 127 t = xs_transaction_start(ctx->xsh);
keir@20462 128 xs_rm(ctx->xsh, t, dom_path);
keir@20462 129 xs_mkdir(ctx->xsh, t, dom_path);
keir@20462 130 xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
keir@20462 131
keir@20462 132 xs_rm(ctx->xsh, t, vm_path);
keir@20462 133 xs_mkdir(ctx->xsh, t, vm_path);
keir@20462 134 xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
keir@20462 135
keir@20462 136 xs_rm(ctx->xsh, t, vss_path);
keir@20462 137 xs_mkdir(ctx->xsh, t, vss_path);
keir@20462 138 xs_set_permissions(ctx->xsh, t, vss_path, rwperm, ARRAY_SIZE(rwperm));
keir@20462 139
keir@20462 140 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path));
keir@20462 141 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, strlen(vss_path));
keir@20462 142 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, strlen(info->name));
keir@20462 143
keir@20462 144 for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
keir@20462 145 char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]);
keir@20462 146 xs_mkdir(ctx->xsh, t, path);
keir@20462 147 xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
keir@20462 148 libxl_free(ctx, path);
keir@20462 149 }
keir@20462 150 for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
keir@20462 151 char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]);
keir@20462 152 xs_mkdir(ctx->xsh, t, path);
keir@20462 153 xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
keir@20462 154 libxl_free(ctx, path);
keir@20462 155 }
keir@20462 156
keir@20462 157 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
keir@20462 158 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name));
keir@20462 159
keir@20462 160 libxl_xs_writev(ctx, t, dom_path, info->xsdata);
keir@20462 161 libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata);
keir@20462 162
keir@20462 163 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
keir@20462 164
keir@20462 165 if (!xs_transaction_end(ctx->xsh, t, 0))
keir@20462 166 if (errno == EAGAIN)
keir@20462 167 goto retry_transaction;
keir@20462 168 return 0;
keir@20462 169 }
keir@20462 170
keir@20462 171 int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid)
keir@20462 172 {
keir@20462 173 libxl_domain_build_state state;
keir@20462 174 char **vments = NULL, **localents = NULL;
keir@20462 175
keir@20462 176 memset(&state, '\0', sizeof(state));
keir@20462 177
keir@20462 178 build_pre(ctx, domid, info, &state);
keir@20462 179 if (info->hvm) {
keir@20462 180 build_hvm(ctx, domid, info, &state);
keir@20462 181 vments = libxl_calloc(ctx, 4, sizeof(char *));
keir@20462 182 vments[0] = libxl_sprintf(ctx, "rtc/timeoffset");
keir@20462 183 vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "");
keir@20462 184 } else {
keir@20462 185 build_pv(ctx, domid, info, &state);
keir@20462 186 }
keir@20462 187 build_post(ctx, domid, info, &state, vments, localents);
keir@20462 188 return 0;
keir@20462 189 }
keir@20462 190
keir@20462 191 int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info,
keir@20462 192 uint32_t domid, int fd)
keir@20462 193 {
keir@20462 194 libxl_domain_build_state state;
keir@20462 195 char **vments = NULL, **localents = NULL;
keir@20462 196
keir@20462 197 memset(&state, '\0', sizeof(state));
keir@20462 198
keir@20462 199 build_pre(ctx, domid, info, &state);
keir@20462 200 restore_common(ctx, domid, info, &state, fd);
keir@20462 201 if (info->hvm) {
keir@20462 202 vments = libxl_calloc(ctx, 4, sizeof(char *));
keir@20462 203 vments[0] = libxl_sprintf(ctx, "rtc/timeoffset");
keir@20462 204 vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "");
keir@20462 205 } else {
keir@20462 206 localents = libxl_calloc(ctx, 4 * 2, sizeof(char *));
keir@20462 207 localents[0] = libxl_sprintf(ctx, "serial/0/limit");
keir@20462 208 localents[1] = libxl_sprintf(ctx, "%d", 65536);
keir@20462 209 localents[2] = libxl_sprintf(ctx, "console/port");
keir@20462 210 localents[3] = libxl_sprintf(ctx, "%d", state.console_port);
keir@20462 211 localents[4] = libxl_sprintf(ctx, "console/ring-ref");
keir@20462 212 localents[5] = libxl_sprintf(ctx, "%ld", state.console_mfn);
keir@20462 213 }
keir@20462 214 build_post(ctx, domid, info, &state, vments, localents);
keir@20462 215 return 0;
keir@20462 216 }
keir@20462 217
keir@20462 218 struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain)
keir@20462 219 {
keir@20462 220 struct libxl_dominfo *ptr;
keir@20462 221 int index, i, ret, first_domain;
keir@20462 222 xc_domaininfo_t info[16];
keir@20462 223 int size = 16;
keir@20462 224
keir@20462 225 first_domain = 1;
keir@20462 226 index = 0;
keir@20462 227 ptr = libxl_calloc(ctx, size, sizeof(struct libxl_dominfo));
keir@20462 228 if (!ptr)
keir@20462 229 return NULL;
keir@20462 230 redo:
keir@20462 231 ret = xc_domain_getinfolist(ctx->xch, first_domain, 16, info);
keir@20462 232 for (i = 0; i < ret; i++) {
keir@20462 233 if (index == size) {
keir@20462 234 struct libxl_dominfo *ptr2;
keir@20462 235
keir@20462 236 ptr2 = libxl_calloc(ctx, size * 2, sizeof(struct libxl_dominfo));
keir@20462 237 if (!ptr2) {
keir@20462 238 libxl_free(ctx, ptr);
keir@20462 239 return NULL;
keir@20462 240 }
keir@20462 241 memcpy(ptr2, ptr, sizeof(struct libxl_dominfo) * size);
keir@20462 242 libxl_free(ctx, ptr);
keir@20462 243 ptr = ptr2;
keir@20462 244 size *= 2;
keir@20462 245 }
keir@20462 246 memcpy(ptr[index].uuid, info[i].handle, 16 * sizeof(uint8_t));
keir@20462 247 ptr[index].domid = info[i].domain;
keir@20462 248 first_domain = info[i].domain + 1;
keir@20462 249 index++;
keir@20462 250 }
keir@20462 251 if (ret == 16)
keir@20462 252 goto redo;
keir@20462 253 *nb_domain = index;
keir@20462 254 return ptr;
keir@20462 255 }
keir@20462 256
keir@20462 257 xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain)
keir@20462 258 {
keir@20462 259 int index, first_domain;
keir@20462 260 xc_dominfo_t *info;
keir@20462 261 int size = 1024;
keir@20462 262
keir@20462 263 first_domain = 0;
keir@20462 264 index = 0;
keir@20462 265 info = (xc_dominfo_t *) libxl_calloc(ctx, size, sizeof(xc_dominfo_t));
keir@20462 266 if (!info) {
keir@20462 267 *nb_domain = 0;
keir@20462 268 return NULL;
keir@20462 269 }
keir@20462 270 *nb_domain = xc_domain_getinfo(ctx->xch, first_domain, 1024, info);
keir@20462 271 return info;
keir@20462 272 }
keir@20462 273
keir@20462 274 int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info,
keir@20462 275 uint32_t domid, int fd)
keir@20462 276 {
keir@20462 277 int hvm = 1;
keir@20462 278 int live = 0;
keir@20462 279 int debug = 0;
keir@20462 280 char savesig[] = "XenSavedDomain\n";
keir@20462 281
keir@20462 282 write(fd, savesig, strlen(savesig));
keir@20462 283
keir@20462 284 core_suspend(ctx, domid, fd, hvm, live, debug);
keir@20462 285
keir@20462 286 return 0;
keir@20462 287 }
keir@20462 288
keir@20462 289 int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 290 {
keir@20462 291 xc_domain_pause(ctx->xch, domid);
keir@20462 292 return 0;
keir@20462 293 }
keir@20462 294
keir@20462 295 int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 296 {
keir@20462 297 xc_domain_unpause(ctx->xch, domid);
keir@20462 298 return 0;
keir@20462 299 }
keir@20462 300
keir@20462 301 static char *req_table[] = {
keir@20462 302 [0] = "poweroff",
keir@20462 303 [1] = "reboot",
keir@20462 304 [2] = "suspend",
keir@20462 305 [3] = "crash",
keir@20462 306 [4] = "halt",
keir@20462 307 };
keir@20462 308
keir@20462 309 int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req)
keir@20462 310 {
keir@20462 311 char *shutdown_path;
keir@20462 312 char *dom_path;
keir@20462 313
keir@20462 314 if (req > ARRAY_SIZE(req_table))
keir@20462 315 return ERROR_INVAL;
keir@20462 316
keir@20462 317 dom_path = libxl_xs_get_dompath(ctx, domid);
keir@20462 318 shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path);
keir@20462 319
keir@20462 320 xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req]));
keir@20462 321 if (/* hvm */ 0) {
keir@20462 322 unsigned long acpi_s_state = 0;
keir@20462 323 unsigned long pvdriver = 0;
keir@20462 324 xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state);
keir@20462 325 xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver);
keir@20462 326 if (!pvdriver && acpi_s_state != 0)
keir@20462 327 xc_domain_shutdown(ctx->xch, domid, req);
keir@20462 328 }
keir@20462 329 return 0;
keir@20462 330 }
keir@20462 331
keir@20462 332 static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 333 {
keir@20462 334 char *pid;
keir@20462 335 int ret;
keir@20462 336
keir@20462 337 pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid));
keir@20462 338 if (!pid) {
keir@20462 339 XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find device model's pid\n");
keir@20462 340 return -1;
keir@20462 341 }
keir@20462 342 xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid));
keir@20462 343
keir@20462 344 ret = kill(atoi(pid), SIGHUP);
keir@20462 345 if (ret < 0 && errno == ESRCH) {
keir@20462 346 XL_LOG(ctx, XL_LOG_DEBUG, "Device Model already exited\n");
keir@20462 347 ret = 0;
keir@20462 348 } else if (ret == 0) {
keir@20462 349 XL_LOG(ctx, XL_LOG_DEBUG, "Device Model signaled\n");
keir@20462 350 ret = 0;
keir@20462 351 } else {
keir@20462 352 XL_LOG(ctx, XL_LOG_ERROR, "kill %d returned %d errno=%d\n", atoi(pid), ret, errno);
keir@20462 353 }
keir@20462 354 return ret;
keir@20462 355 }
keir@20462 356
keir@20462 357 int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force)
keir@20462 358 {
keir@20462 359 char *dom_path, vm_path[41];
keir@20468 360 xen_uuid_t *uuid;
keir@20462 361
keir@20462 362 dom_path = libxl_xs_get_dompath(ctx, domid);
keir@20462 363 if (!dom_path) {
keir@20462 364 XL_LOG(ctx, XL_LOG_ERROR, "dompath doesn't exist for %d\n", domid);
keir@20462 365 return -1;
keir@20462 366 }
keir@20462 367 if (libxl_domid_to_uuid(ctx, &uuid, domid) < 0) {
keir@20462 368 XL_LOG(ctx, XL_LOG_ERROR, "failed ot get uuid for %d\n", domid);
keir@20462 369 return -1;
keir@20462 370 }
keir@20462 371 xs_write(ctx->xsh, XBT_NULL,
keir@20462 372 libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid),
keir@20462 373 "shutdown", strlen("shutdown"));
keir@20462 374 if (xc_domain_pause(ctx->xch, domid) < 0) {
keir@20462 375 XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_pause failed for %d\n", domid);
keir@20462 376 return -1;
keir@20462 377 }
keir@20462 378 /* do_FLR */
keir@20462 379 if (xc_domain_destroy(ctx->xch, domid) < 0) {
keir@20462 380 XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_destroy failed for %d\n", domid);
keir@20462 381 return -1;
keir@20462 382 }
keir@20462 383 if (libxl_devices_destroy(ctx, domid, force) < 0)
keir@20462 384 XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d\n", domid);
keir@20462 385 if (libxl_destroy_device_model(ctx, domid) < 0)
keir@20462 386 XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d\n", domid);
keir@20462 387 if (!xs_rm(ctx->xsh, XBT_NULL, dom_path))
keir@20462 388 XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", dom_path);
keir@20468 389 snprintf(vm_path, sizeof(vm_path), "/vm/%s", libxl_uuid_to_string(ctx, uuid));
keir@20462 390 if (!xs_rm(ctx->xsh, XBT_NULL, vm_path))
keir@20462 391 XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", vm_path);
keir@20462 392 return 0;
keir@20462 393 }
keir@20462 394
keir@20462 395 static char ** libxl_build_device_model_args(struct libxl_ctx *ctx,
keir@20462 396 libxl_device_model_info *info,
keir@20462 397 libxl_device_nic *vifs,
keir@20462 398 int num_vifs)
keir@20462 399 {
keir@20462 400 int num = 0, i;
keir@20462 401 flexarray_t *dm_args;
keir@20462 402 dm_args = flexarray_make(16, 1);
keir@20462 403 if (!dm_args)
keir@20462 404 return NULL;
keir@20462 405
keir@20462 406 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "qemu-dm"));
keir@20462 407 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-d"));
keir@20462 408
keir@20462 409 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid));
keir@20462 410
keir@20462 411 if (info->dom_name) {
keir@20462 412 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-domain-name"));
keir@20462 413 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->dom_name));
keir@20462 414 }
keir@20462 415 if (info->videoram) {
keir@20462 416 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram"));
keir@20462 417 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram));
keir@20462 418 }
keir@20462 419 if (info->stdvga) {
keir@20462 420 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga"));
keir@20462 421 }
keir@20462 422 if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
keir@20462 423 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vnc"));
keir@20462 424 if (info->vncdisplay) {
keir@20462 425 if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
keir@20462 426 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:%d", info->vnclisten, info->vncdisplay));
keir@20462 427 } else {
keir@20462 428 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay));
keir@20462 429 }
keir@20462 430 } else if (info->vnclisten) {
keir@20462 431 if (strchr(info->vnclisten, ':') != NULL) {
keir@20462 432 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->vnclisten));
keir@20462 433 } else {
keir@20462 434 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten));
keir@20462 435 }
keir@20462 436 } else {
keir@20462 437 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:0"));
keir@20462 438 }
keir@20462 439 if (info->vncunused) {
keir@20462 440 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vncunused"));
keir@20462 441 }
keir@20462 442 }
keir@20462 443 if (info->sdl || info->opengl) {
keir@20462 444 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-sdl"));
keir@20462 445 if (info->opengl) {
keir@20462 446 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-disable-opengl"));
keir@20462 447 }
keir@20462 448 }
keir@20462 449 if (info->keymap) {
keir@20462 450 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-k"));
keir@20462 451 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->keymap));
keir@20462 452 }
keir@20462 453 if (info->nographic && (!info->sdl && !info->vnc)) {
keir@20462 454 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-nographic"));
keir@20462 455 }
keir@20462 456 if (info->serial) {
keir@20462 457 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-serial"));
keir@20462 458 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->serial));
keir@20462 459 }
keir@20462 460 if (info->boot) {
keir@20462 461 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot"));
keir@20462 462 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot));
keir@20462 463 }
keir@20462 464 if (info->usb) {
keir@20462 465 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb"));
keir@20462 466 if (info->usbdevice) {
keir@20462 467 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice"));
keir@20462 468 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->usbdevice));
keir@20462 469 }
keir@20462 470 }
keir@20462 471 if (info->apic) {
keir@20462 472 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi"));
keir@20462 473 }
keir@20462 474 if (info->extra) {
keir@20462 475 int i = 0;
keir@20462 476 while (info->extra[i] != NULL) {
keir@20462 477 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->extra[i]));
keir@20462 478 }
keir@20462 479 }
keir@20462 480 for (i = 0; i < num_vifs; i++) {
keir@20462 481 if (vifs[i].nictype == NICTYPE_IOEMU) {
keir@20462 482 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
keir@20462 483 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s",
keir@20462 484 vifs[i].devid, vifs[i].smac, vifs[i].model));
keir@20462 485 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
keir@20462 486 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s",
keir@20462 487 vifs[i].devid, vifs[i].ifname, vifs[i].bridge));
keir@20462 488 }
keir@20462 489 }
keir@20462 490 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-M"));
keir@20462 491 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv"));
keir@20462 492 flexarray_set(dm_args, num++, NULL);
keir@20462 493
keir@20462 494 return (char **) flexarray_contents(dm_args);
keir@20462 495 }
keir@20462 496
keir@20462 497 int libxl_create_device_model(struct libxl_ctx *ctx,
keir@20462 498 libxl_device_model_info *info,
keir@20462 499 libxl_device_nic *vifs, int num_vifs)
keir@20462 500 {
keir@20462 501 char *dom_path, *path, *logfile, *logfile_new;
keir@20462 502 char *kvs[3];
keir@20462 503 struct stat stat_buf;
keir@20462 504 int logfile_w, null, pid;
keir@20462 505 int i;
keir@20462 506 char **args;
keir@20462 507
keir@20462 508 args = libxl_build_device_model_args(ctx, info, vifs, num_vifs);
keir@20462 509 if (!args)
keir@20462 510 return ERROR_FAIL;
keir@20462 511
keir@20462 512 dom_path = libxl_xs_get_dompath(ctx, info->domid);
keir@20462 513
keir@20462 514 path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid);
keir@20462 515 xs_mkdir(ctx->xsh, XBT_NULL, path);
keir@20462 516
keir@20462 517 logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name);
keir@20462 518 if (stat(logfile, &stat_buf) == 0) {
keir@20462 519 /* file exists, rotate */
keir@20462 520 logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.10", info->dom_name);
keir@20462 521 unlink(logfile);
keir@20462 522 for (i = 9; i > 0; i--) {
keir@20462 523 logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i);
keir@20462 524 logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i + 1);
keir@20462 525 rename(logfile, logfile_new);
keir@20462 526 }
keir@20462 527 logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name);
keir@20462 528 logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.1", info->dom_name);
keir@20462 529 rename(logfile, logfile_new);
keir@20462 530 }
keir@20462 531 logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name);
keir@20467 532 logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
keir@20462 533 null = open("/dev/null", O_RDONLY);
keir@20462 534 pid = libxl_exec(ctx, null, logfile_w, logfile_w, info->device_model, args);
keir@20462 535 close(null);
keir@20462 536 close(logfile_w);
keir@20462 537
keir@20462 538 kvs[0] = libxl_sprintf(ctx, "image/device-model-pid");
keir@20462 539 kvs[1] = libxl_sprintf(ctx, "%d", pid);
keir@20462 540 kvs[2] = NULL;
keir@20462 541 libxl_xs_writev(ctx, XBT_NULL, dom_path, kvs);
keir@20462 542
keir@20462 543 return 0;
keir@20462 544 }
keir@20462 545
keir@20462 546 /******************************************************************************/
keir@20462 547 int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk)
keir@20462 548 {
keir@20462 549 flexarray_t *front;
keir@20462 550 flexarray_t *back;
keir@20462 551 char *backend_type;
keir@20462 552 unsigned int boffset = 0;
keir@20462 553 unsigned int foffset = 0;
keir@20462 554 int devid;
keir@20462 555 libxl_device device;
keir@20462 556
keir@20462 557 front = flexarray_make(16, 1);
keir@20462 558 if (!front)
keir@20462 559 return ERROR_NOMEM;
keir@20462 560 back = flexarray_make(16, 1);
keir@20462 561 if (!back) /* leaks front if error */
keir@20462 562 return ERROR_NOMEM;
keir@20462 563
keir@20462 564 backend_type = device_disk_backend_type_of_phystype(disk->phystype);
keir@20462 565 devid = device_disk_dev_number(disk->virtpath);
keir@20462 566
keir@20462 567 device.backend_devid = devid;
keir@20462 568 device.backend_domid = disk->backend_domid;
keir@20462 569 device.devid = devid;
keir@20462 570 device.domid = disk->domid;
keir@20462 571 device.kind = DEVICE_VBD;
keir@20462 572
keir@20462 573 switch (disk->phystype) {
keir@20462 574 case PHYSTYPE_FILE:
keir@20462 575 return ERROR_NI; /* FIXME */
keir@20462 576 break;
keir@20462 577 case PHYSTYPE_PHY: {
keir@20462 578 int major, minor;
keir@20462 579
keir@20462 580 device_disk_major_minor(disk->virtpath, &major, &minor);
keir@20462 581 flexarray_set(back, boffset++, libxl_sprintf(ctx, "physical-device"));
keir@20462 582 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor));
keir@20462 583
keir@20462 584 flexarray_set(back, boffset++, libxl_sprintf(ctx, "params"));
keir@20462 585 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->physpath));
keir@20462 586
keir@20462 587 device.backend_kind = DEVICE_VBD;
keir@20462 588 break;
keir@20462 589 }
keir@20462 590 case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case PHYSTYPE_VHD:
keir@20462 591 flexarray_set(back, boffset++, libxl_sprintf(ctx, "params"));
keir@20462 592 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s",
keir@20462 593 device_disk_string_of_phystype(disk->phystype), disk->physpath));
keir@20462 594
keir@20462 595 device.backend_kind = DEVICE_TAP;
keir@20462 596 break;
keir@20462 597 }
keir@20462 598
keir@20462 599 flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
keir@20462 600 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid));
keir@20462 601 flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
keir@20462 602 flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
keir@20462 603 flexarray_set(back, boffset++, libxl_sprintf(ctx, "removable"));
keir@20462 604 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0));
keir@20462 605 flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
keir@20462 606 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
keir@20462 607 flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev"));
keir@20462 608 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->virtpath));
keir@20462 609 flexarray_set(back, boffset++, libxl_sprintf(ctx, "type"));
keir@20462 610 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", backend_type));
keir@20462 611 flexarray_set(back, boffset++, libxl_sprintf(ctx, "mode"));
keir@20462 612 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", (disk->readwrite) ? "w" : "r"));
keir@20462 613
keir@20462 614 flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
keir@20462 615 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid));
keir@20462 616 flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
keir@20462 617 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
keir@20462 618 flexarray_set(front, foffset++, libxl_sprintf(ctx, "virtual-device"));
keir@20462 619 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid));
keir@20462 620 flexarray_set(front, foffset++, libxl_sprintf(ctx, "device-type"));
keir@20462 621 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%s", (disk->is_cdrom) ? "cdrom" : "disk"));
keir@20462 622
keir@20462 623 if (0 /* protocol != native*/) {
keir@20462 624 flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol"));
keir@20462 625 flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */
keir@20462 626 }
keir@20462 627
keir@20462 628 libxl_device_generic_add(ctx, &device,
keir@20462 629 libxl_xs_kvs_of_flexarray(ctx, back, boffset),
keir@20462 630 libxl_xs_kvs_of_flexarray(ctx, front, foffset));
keir@20462 631 /* leaks both flexarray here */
keir@20462 632 return 0;
keir@20462 633 }
keir@20462 634
keir@20462 635 int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 636 {
keir@20462 637 return ERROR_NI;
keir@20462 638 }
keir@20462 639
keir@20462 640 int libxl_device_disk_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 641 {
keir@20462 642 return ERROR_NI;
keir@20462 643 }
keir@20462 644
keir@20462 645 /******************************************************************************/
keir@20462 646 int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
keir@20462 647 {
keir@20462 648 flexarray_t *front;
keir@20462 649 flexarray_t *back;
keir@20462 650 unsigned int boffset = 0;
keir@20462 651 unsigned int foffset = 0;
keir@20462 652 libxl_device device;
keir@20462 653
keir@20462 654 front = flexarray_make(16, 1);
keir@20462 655 if (!front)
keir@20462 656 return ERROR_NOMEM;
keir@20462 657 back = flexarray_make(16, 1);
keir@20462 658 if (!back)
keir@20462 659 return ERROR_NOMEM;
keir@20462 660
keir@20462 661 device.backend_devid = nic->devid;
keir@20462 662 device.backend_domid = nic->backend_domid;
keir@20462 663 device.backend_kind = DEVICE_VIF;
keir@20462 664 device.devid = nic->devid;
keir@20462 665 device.domid = nic->domid;
keir@20462 666 device.kind = DEVICE_VIF;
keir@20462 667
keir@20462 668 flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
keir@20462 669 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid));
keir@20462 670 flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
keir@20462 671 flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
keir@20462 672 flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
keir@20462 673 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
keir@20462 674 flexarray_set(back, boffset++, libxl_sprintf(ctx, "script"));
keir@20462 675 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", nic->script));
keir@20462 676 flexarray_set(back, boffset++, libxl_sprintf(ctx, "mac"));
keir@20462 677 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x",
keir@20462 678 nic->mac[0], nic->mac[1], nic->mac[2],
keir@20462 679 nic->mac[3], nic->mac[4], nic->mac[5]));
keir@20462 680 flexarray_set(back, boffset++, libxl_sprintf(ctx, "handle"));
keir@20462 681 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid));
keir@20462 682
keir@20462 683 flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
keir@20462 684 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid));
keir@20462 685 flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
keir@20462 686 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
keir@20462 687 flexarray_set(front, foffset++, libxl_sprintf(ctx, "handle"));
keir@20462 688 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid));
keir@20462 689 flexarray_set(front, foffset++, libxl_sprintf(ctx, "mac"));
keir@20462 690 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x",
keir@20462 691 nic->mac[0], nic->mac[1], nic->mac[2],
keir@20462 692 nic->mac[3], nic->mac[4], nic->mac[5]));
keir@20462 693 if (0 /* protocol != native*/) {
keir@20462 694 flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol"));
keir@20462 695 flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */
keir@20462 696 }
keir@20462 697
keir@20462 698 libxl_device_generic_add(ctx, &device,
keir@20462 699 libxl_xs_kvs_of_flexarray(ctx, back, boffset),
keir@20462 700 libxl_xs_kvs_of_flexarray(ctx, front, foffset));
keir@20462 701
keir@20462 702 /* FIXME: wait for plug */
keir@20462 703 return 0;
keir@20462 704 }
keir@20462 705
keir@20462 706 int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 707 {
keir@20462 708 return ERROR_NI;
keir@20462 709 }
keir@20462 710
keir@20462 711 int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 712 {
keir@20462 713 return ERROR_NI;
keir@20462 714 }
keir@20462 715
keir@20462 716 /******************************************************************************/
keir@20462 717 int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 718 {
keir@20462 719 return ERROR_NI;
keir@20462 720 }
keir@20462 721
keir@20462 722 int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 723 {
keir@20462 724 return ERROR_NI;
keir@20462 725 }
keir@20462 726
keir@20462 727 int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 728 {
keir@20462 729 return ERROR_NI;
keir@20462 730 }
keir@20462 731
keir@20462 732 /******************************************************************************/
keir@20462 733 int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 734 {
keir@20462 735 return ERROR_NI;
keir@20462 736 }
keir@20462 737
keir@20462 738 int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 739 {
keir@20462 740 return ERROR_NI;
keir@20462 741 }
keir@20462 742
keir@20462 743 int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 744 {
keir@20462 745 return ERROR_NI;
keir@20462 746 }
keir@20462 747
keir@20462 748 /******************************************************************************/
keir@20462 749 int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 750 {
keir@20462 751 return ERROR_NI;
keir@20462 752 }
keir@20462 753
keir@20462 754 int libxl_device_pci_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 755 {
keir@20462 756 return ERROR_NI;
keir@20462 757 }
keir@20462 758
keir@20462 759 int libxl_device_pci_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
keir@20462 760 {
keir@20462 761 return ERROR_NI;
keir@20462 762 }