debuggers.hg
diff tools/libxl/libxl.c @ 20462:8a91056bea81
libxenlight: initial libxenlight implementation under tools/libxl
Signed-off-by: Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Nov 09 19:54:28 2009 +0000 (2009-11-09) |
parents | |
children | 494ad84ad38c |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/libxl/libxl.c Mon Nov 09 19:54:28 2009 +0000 1.3 @@ -0,0 +1,742 @@ 1.4 +/* 1.5 + * Copyright (C) 2009 Citrix Ltd. 1.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 1.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 1.8 + * 1.9 + * This program is free software; you can redistribute it and/or modify 1.10 + * it under the terms of the GNU Lesser General Public License as published 1.11 + * by the Free Software Foundation; version 2.1 only. with the special 1.12 + * exception on linking described in file LICENSE. 1.13 + * 1.14 + * This program is distributed in the hope that it will be useful, 1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.17 + * GNU Lesser General Public License for more details. 1.18 + */ 1.19 + 1.20 +#include <stdio.h> 1.21 +#include <string.h> 1.22 +#include <stdlib.h> 1.23 +#include <sys/stat.h> 1.24 +#include <sys/types.h> 1.25 +#include <fcntl.h> 1.26 +#include <sys/select.h> 1.27 +#include <signal.h> 1.28 +#include "libxl.h" 1.29 +#include "libxl_utils.h" 1.30 +#include "libxl_internal.h" 1.31 +#include "flexarray.h" 1.32 + 1.33 +int libxl_ctx_init(struct libxl_ctx *ctx) 1.34 +{ 1.35 + memset(ctx, 0, sizeof(struct libxl_ctx)); 1.36 + ctx->alloc_maxsize = 256; 1.37 + ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); 1.38 + if (!ctx->alloc_ptrs) 1.39 + return ERROR_NOMEM; 1.40 + 1.41 + ctx->xch = xc_interface_open(); 1.42 + ctx->xsh = xs_daemon_open(); 1.43 + return 0; 1.44 +} 1.45 + 1.46 +int libxl_ctx_free(struct libxl_ctx *ctx) 1.47 +{ 1.48 + libxl_free_all(ctx); 1.49 + free(ctx->alloc_ptrs); 1.50 + ctx->alloc_ptrs = NULL; 1.51 + xc_interface_close(ctx->xch); 1.52 + xs_daemon_close(ctx->xsh); 1.53 + return 0; 1.54 +} 1.55 + 1.56 +int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data) 1.57 +{ 1.58 + ctx->log_callback = log_callback; 1.59 + ctx->log_userdata = log_data; 1.60 + return 0; 1.61 +} 1.62 + 1.63 +/******************************************************************************/ 1.64 + 1.65 +int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, 1.66 + uint32_t *domid) 1.67 +{ 1.68 + int flags, ret, i; 1.69 + char *uuid_string; 1.70 + char *rw_paths[] = { "device" }; 1.71 + char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", 1.72 + "control", "attr", "data", "messages" }; 1.73 + char *dom_path, *vm_path, *vss_path; 1.74 + struct xs_permissions roperm[2]; 1.75 + struct xs_permissions rwperm[1]; 1.76 + xs_transaction_t t; 1.77 + 1.78 + uuid_string = uuid_to_string(ctx, info->uuid); 1.79 + if (!uuid_string) { 1.80 + XL_LOG(ctx, XL_LOG_ERROR, "missing uuid"); 1.81 + return ERROR_FAIL; 1.82 + } 1.83 + 1.84 + flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; 1.85 + flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; 1.86 + *domid = 0; 1.87 + 1.88 + ret = xc_domain_create(ctx->xch, info->ssidref, info->uuid, flags, domid); 1.89 + if (ret < 0) { 1.90 + XL_LOG(ctx, XL_LOG_ERROR, "domain creation fail: %d", ret); 1.91 + return ERROR_FAIL; 1.92 + } 1.93 + 1.94 + dom_path = libxl_xs_get_dompath(ctx, *domid); 1.95 + vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); 1.96 + vss_path = libxl_sprintf(ctx, "/vss/%s", uuid_string); 1.97 + if (!dom_path || !vm_path || !vss_path) { 1.98 + XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths"); 1.99 + return ERROR_FAIL; 1.100 + } 1.101 + 1.102 + roperm[0].id = 0; 1.103 + roperm[0].perms = XS_PERM_NONE; 1.104 + roperm[1].id = *domid; 1.105 + roperm[1].perms = XS_PERM_READ; 1.106 + rwperm[0].id = *domid; 1.107 + rwperm[0].perms = XS_PERM_NONE; 1.108 + 1.109 +retry_transaction: 1.110 + t = xs_transaction_start(ctx->xsh); 1.111 + xs_rm(ctx->xsh, t, dom_path); 1.112 + xs_mkdir(ctx->xsh, t, dom_path); 1.113 + xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); 1.114 + 1.115 + xs_rm(ctx->xsh, t, vm_path); 1.116 + xs_mkdir(ctx->xsh, t, vm_path); 1.117 + xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); 1.118 + 1.119 + xs_rm(ctx->xsh, t, vss_path); 1.120 + xs_mkdir(ctx->xsh, t, vss_path); 1.121 + xs_set_permissions(ctx->xsh, t, vss_path, rwperm, ARRAY_SIZE(rwperm)); 1.122 + 1.123 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); 1.124 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, strlen(vss_path)); 1.125 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, strlen(info->name)); 1.126 + 1.127 + for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { 1.128 + char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]); 1.129 + xs_mkdir(ctx->xsh, t, path); 1.130 + xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); 1.131 + libxl_free(ctx, path); 1.132 + } 1.133 + for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { 1.134 + char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]); 1.135 + xs_mkdir(ctx->xsh, t, path); 1.136 + xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); 1.137 + libxl_free(ctx, path); 1.138 + } 1.139 + 1.140 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); 1.141 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name)); 1.142 + 1.143 + libxl_xs_writev(ctx, t, dom_path, info->xsdata); 1.144 + libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata); 1.145 + 1.146 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); 1.147 + 1.148 + if (!xs_transaction_end(ctx->xsh, t, 0)) 1.149 + if (errno == EAGAIN) 1.150 + goto retry_transaction; 1.151 + return 0; 1.152 +} 1.153 + 1.154 +int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid) 1.155 +{ 1.156 + libxl_domain_build_state state; 1.157 + char **vments = NULL, **localents = NULL; 1.158 + 1.159 + memset(&state, '\0', sizeof(state)); 1.160 + 1.161 + build_pre(ctx, domid, info, &state); 1.162 + if (info->hvm) { 1.163 + build_hvm(ctx, domid, info, &state); 1.164 + vments = libxl_calloc(ctx, 4, sizeof(char *)); 1.165 + vments[0] = libxl_sprintf(ctx, "rtc/timeoffset"); 1.166 + vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""); 1.167 + } else { 1.168 + build_pv(ctx, domid, info, &state); 1.169 + } 1.170 + build_post(ctx, domid, info, &state, vments, localents); 1.171 + return 0; 1.172 +} 1.173 + 1.174 +int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info, 1.175 + uint32_t domid, int fd) 1.176 +{ 1.177 + libxl_domain_build_state state; 1.178 + char **vments = NULL, **localents = NULL; 1.179 + 1.180 + memset(&state, '\0', sizeof(state)); 1.181 + 1.182 + build_pre(ctx, domid, info, &state); 1.183 + restore_common(ctx, domid, info, &state, fd); 1.184 + if (info->hvm) { 1.185 + vments = libxl_calloc(ctx, 4, sizeof(char *)); 1.186 + vments[0] = libxl_sprintf(ctx, "rtc/timeoffset"); 1.187 + vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""); 1.188 + } else { 1.189 + localents = libxl_calloc(ctx, 4 * 2, sizeof(char *)); 1.190 + localents[0] = libxl_sprintf(ctx, "serial/0/limit"); 1.191 + localents[1] = libxl_sprintf(ctx, "%d", 65536); 1.192 + localents[2] = libxl_sprintf(ctx, "console/port"); 1.193 + localents[3] = libxl_sprintf(ctx, "%d", state.console_port); 1.194 + localents[4] = libxl_sprintf(ctx, "console/ring-ref"); 1.195 + localents[5] = libxl_sprintf(ctx, "%ld", state.console_mfn); 1.196 + } 1.197 + build_post(ctx, domid, info, &state, vments, localents); 1.198 + return 0; 1.199 +} 1.200 + 1.201 +struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain) 1.202 +{ 1.203 + struct libxl_dominfo *ptr; 1.204 + int index, i, ret, first_domain; 1.205 + xc_domaininfo_t info[16]; 1.206 + int size = 16; 1.207 + 1.208 + first_domain = 1; 1.209 + index = 0; 1.210 + ptr = libxl_calloc(ctx, size, sizeof(struct libxl_dominfo)); 1.211 + if (!ptr) 1.212 + return NULL; 1.213 +redo: 1.214 + ret = xc_domain_getinfolist(ctx->xch, first_domain, 16, info); 1.215 + for (i = 0; i < ret; i++) { 1.216 + if (index == size) { 1.217 + struct libxl_dominfo *ptr2; 1.218 + 1.219 + ptr2 = libxl_calloc(ctx, size * 2, sizeof(struct libxl_dominfo)); 1.220 + if (!ptr2) { 1.221 + libxl_free(ctx, ptr); 1.222 + return NULL; 1.223 + } 1.224 + memcpy(ptr2, ptr, sizeof(struct libxl_dominfo) * size); 1.225 + libxl_free(ctx, ptr); 1.226 + ptr = ptr2; 1.227 + size *= 2; 1.228 + } 1.229 + memcpy(ptr[index].uuid, info[i].handle, 16 * sizeof(uint8_t)); 1.230 + ptr[index].domid = info[i].domain; 1.231 + first_domain = info[i].domain + 1; 1.232 + index++; 1.233 + } 1.234 + if (ret == 16) 1.235 + goto redo; 1.236 + *nb_domain = index; 1.237 + return ptr; 1.238 +} 1.239 + 1.240 +xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain) 1.241 +{ 1.242 + int index, first_domain; 1.243 + xc_dominfo_t *info; 1.244 + int size = 1024; 1.245 + 1.246 + first_domain = 0; 1.247 + index = 0; 1.248 + info = (xc_dominfo_t *) libxl_calloc(ctx, size, sizeof(xc_dominfo_t)); 1.249 + if (!info) { 1.250 + *nb_domain = 0; 1.251 + return NULL; 1.252 + } 1.253 + *nb_domain = xc_domain_getinfo(ctx->xch, first_domain, 1024, info); 1.254 + return info; 1.255 +} 1.256 + 1.257 +int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info, 1.258 + uint32_t domid, int fd) 1.259 +{ 1.260 + int hvm = 1; 1.261 + int live = 0; 1.262 + int debug = 0; 1.263 + char savesig[] = "XenSavedDomain\n"; 1.264 + 1.265 + write(fd, savesig, strlen(savesig)); 1.266 + 1.267 + core_suspend(ctx, domid, fd, hvm, live, debug); 1.268 + 1.269 + return 0; 1.270 +} 1.271 + 1.272 +int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid) 1.273 +{ 1.274 + xc_domain_pause(ctx->xch, domid); 1.275 + return 0; 1.276 +} 1.277 + 1.278 +int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid) 1.279 +{ 1.280 + xc_domain_unpause(ctx->xch, domid); 1.281 + return 0; 1.282 +} 1.283 + 1.284 +static char *req_table[] = { 1.285 + [0] = "poweroff", 1.286 + [1] = "reboot", 1.287 + [2] = "suspend", 1.288 + [3] = "crash", 1.289 + [4] = "halt", 1.290 +}; 1.291 + 1.292 +int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req) 1.293 +{ 1.294 + char *shutdown_path; 1.295 + char *dom_path; 1.296 + 1.297 + if (req > ARRAY_SIZE(req_table)) 1.298 + return ERROR_INVAL; 1.299 + 1.300 + dom_path = libxl_xs_get_dompath(ctx, domid); 1.301 + shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path); 1.302 + 1.303 + xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req])); 1.304 + if (/* hvm */ 0) { 1.305 + unsigned long acpi_s_state = 0; 1.306 + unsigned long pvdriver = 0; 1.307 + xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state); 1.308 + xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver); 1.309 + if (!pvdriver && acpi_s_state != 0) 1.310 + xc_domain_shutdown(ctx->xch, domid, req); 1.311 + } 1.312 + return 0; 1.313 +} 1.314 + 1.315 +static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid) 1.316 +{ 1.317 + char *pid; 1.318 + int ret; 1.319 + 1.320 + pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); 1.321 + if (!pid) { 1.322 + XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find device model's pid\n"); 1.323 + return -1; 1.324 + } 1.325 + xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid)); 1.326 + 1.327 + ret = kill(atoi(pid), SIGHUP); 1.328 + if (ret < 0 && errno == ESRCH) { 1.329 + XL_LOG(ctx, XL_LOG_DEBUG, "Device Model already exited\n"); 1.330 + ret = 0; 1.331 + } else if (ret == 0) { 1.332 + XL_LOG(ctx, XL_LOG_DEBUG, "Device Model signaled\n"); 1.333 + ret = 0; 1.334 + } else { 1.335 + XL_LOG(ctx, XL_LOG_ERROR, "kill %d returned %d errno=%d\n", atoi(pid), ret, errno); 1.336 + } 1.337 + return ret; 1.338 +} 1.339 + 1.340 +int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force) 1.341 +{ 1.342 + char *dom_path, vm_path[41]; 1.343 + uint8_t *uuid; 1.344 + 1.345 + dom_path = libxl_xs_get_dompath(ctx, domid); 1.346 + if (!dom_path) { 1.347 + XL_LOG(ctx, XL_LOG_ERROR, "dompath doesn't exist for %d\n", domid); 1.348 + return -1; 1.349 + } 1.350 + if (libxl_domid_to_uuid(ctx, &uuid, domid) < 0) { 1.351 + XL_LOG(ctx, XL_LOG_ERROR, "failed ot get uuid for %d\n", domid); 1.352 + return -1; 1.353 + } 1.354 + xs_write(ctx->xsh, XBT_NULL, 1.355 + libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), 1.356 + "shutdown", strlen("shutdown")); 1.357 + if (xc_domain_pause(ctx->xch, domid) < 0) { 1.358 + XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_pause failed for %d\n", domid); 1.359 + return -1; 1.360 + } 1.361 + /* do_FLR */ 1.362 + if (xc_domain_destroy(ctx->xch, domid) < 0) { 1.363 + XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_destroy failed for %d\n", domid); 1.364 + return -1; 1.365 + } 1.366 + if (libxl_devices_destroy(ctx, domid, force) < 0) 1.367 + XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d\n", domid); 1.368 + if (libxl_destroy_device_model(ctx, domid) < 0) 1.369 + XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d\n", domid); 1.370 + if (!xs_rm(ctx->xsh, XBT_NULL, dom_path)) 1.371 + XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", dom_path); 1.372 + snprintf(vm_path, sizeof(vm_path), "/vm/%s", uuid_to_string(ctx, uuid)); 1.373 + if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) 1.374 + XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", vm_path); 1.375 + return 0; 1.376 +} 1.377 + 1.378 +static char ** libxl_build_device_model_args(struct libxl_ctx *ctx, 1.379 + libxl_device_model_info *info, 1.380 + libxl_device_nic *vifs, 1.381 + int num_vifs) 1.382 +{ 1.383 + int num = 0, i; 1.384 + flexarray_t *dm_args; 1.385 + dm_args = flexarray_make(16, 1); 1.386 + if (!dm_args) 1.387 + return NULL; 1.388 + 1.389 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "qemu-dm")); 1.390 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-d")); 1.391 + 1.392 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); 1.393 + 1.394 + if (info->dom_name) { 1.395 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-domain-name")); 1.396 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->dom_name)); 1.397 + } 1.398 + if (info->videoram) { 1.399 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram")); 1.400 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); 1.401 + } 1.402 + if (info->stdvga) { 1.403 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga")); 1.404 + } 1.405 + if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { 1.406 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vnc")); 1.407 + if (info->vncdisplay) { 1.408 + if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { 1.409 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:%d", info->vnclisten, info->vncdisplay)); 1.410 + } else { 1.411 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay)); 1.412 + } 1.413 + } else if (info->vnclisten) { 1.414 + if (strchr(info->vnclisten, ':') != NULL) { 1.415 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->vnclisten)); 1.416 + } else { 1.417 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten)); 1.418 + } 1.419 + } else { 1.420 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:0")); 1.421 + } 1.422 + if (info->vncunused) { 1.423 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vncunused")); 1.424 + } 1.425 + } 1.426 + if (info->sdl || info->opengl) { 1.427 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-sdl")); 1.428 + if (info->opengl) { 1.429 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-disable-opengl")); 1.430 + } 1.431 + } 1.432 + if (info->keymap) { 1.433 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-k")); 1.434 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->keymap)); 1.435 + } 1.436 + if (info->nographic && (!info->sdl && !info->vnc)) { 1.437 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-nographic")); 1.438 + } 1.439 + if (info->serial) { 1.440 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-serial")); 1.441 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->serial)); 1.442 + } 1.443 + if (info->boot) { 1.444 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot")); 1.445 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot)); 1.446 + } 1.447 + if (info->usb) { 1.448 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb")); 1.449 + if (info->usbdevice) { 1.450 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice")); 1.451 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->usbdevice)); 1.452 + } 1.453 + } 1.454 + if (info->apic) { 1.455 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi")); 1.456 + } 1.457 + if (info->extra) { 1.458 + int i = 0; 1.459 + while (info->extra[i] != NULL) { 1.460 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->extra[i])); 1.461 + } 1.462 + } 1.463 + for (i = 0; i < num_vifs; i++) { 1.464 + if (vifs[i].nictype == NICTYPE_IOEMU) { 1.465 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); 1.466 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", 1.467 + vifs[i].devid, vifs[i].smac, vifs[i].model)); 1.468 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); 1.469 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s", 1.470 + vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); 1.471 + } 1.472 + } 1.473 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-M")); 1.474 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv")); 1.475 + flexarray_set(dm_args, num++, NULL); 1.476 + 1.477 + return (char **) flexarray_contents(dm_args); 1.478 +} 1.479 + 1.480 +int libxl_create_device_model(struct libxl_ctx *ctx, 1.481 + libxl_device_model_info *info, 1.482 + libxl_device_nic *vifs, int num_vifs) 1.483 +{ 1.484 + char *dom_path, *path, *logfile, *logfile_new; 1.485 + char *kvs[3]; 1.486 + struct stat stat_buf; 1.487 + int logfile_w, null, pid; 1.488 + int i; 1.489 + char **args; 1.490 + 1.491 + args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); 1.492 + if (!args) 1.493 + return ERROR_FAIL; 1.494 + 1.495 + dom_path = libxl_xs_get_dompath(ctx, info->domid); 1.496 + 1.497 + path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid); 1.498 + xs_mkdir(ctx->xsh, XBT_NULL, path); 1.499 + 1.500 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name); 1.501 + if (stat(logfile, &stat_buf) == 0) { 1.502 + /* file exists, rotate */ 1.503 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.10", info->dom_name); 1.504 + unlink(logfile); 1.505 + for (i = 9; i > 0; i--) { 1.506 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i); 1.507 + logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i + 1); 1.508 + rename(logfile, logfile_new); 1.509 + } 1.510 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name); 1.511 + logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.1", info->dom_name); 1.512 + rename(logfile, logfile_new); 1.513 + } 1.514 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name); 1.515 + logfile_w = open(logfile, O_WRONLY|O_CREAT); 1.516 + null = open("/dev/null", O_RDONLY); 1.517 + pid = libxl_exec(ctx, null, logfile_w, logfile_w, info->device_model, args); 1.518 + close(null); 1.519 + close(logfile_w); 1.520 + 1.521 + kvs[0] = libxl_sprintf(ctx, "image/device-model-pid"); 1.522 + kvs[1] = libxl_sprintf(ctx, "%d", pid); 1.523 + kvs[2] = NULL; 1.524 + libxl_xs_writev(ctx, XBT_NULL, dom_path, kvs); 1.525 + 1.526 + return 0; 1.527 +} 1.528 + 1.529 +/******************************************************************************/ 1.530 +int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) 1.531 +{ 1.532 + flexarray_t *front; 1.533 + flexarray_t *back; 1.534 + char *backend_type; 1.535 + unsigned int boffset = 0; 1.536 + unsigned int foffset = 0; 1.537 + int devid; 1.538 + libxl_device device; 1.539 + 1.540 + front = flexarray_make(16, 1); 1.541 + if (!front) 1.542 + return ERROR_NOMEM; 1.543 + back = flexarray_make(16, 1); 1.544 + if (!back) /* leaks front if error */ 1.545 + return ERROR_NOMEM; 1.546 + 1.547 + backend_type = device_disk_backend_type_of_phystype(disk->phystype); 1.548 + devid = device_disk_dev_number(disk->virtpath); 1.549 + 1.550 + device.backend_devid = devid; 1.551 + device.backend_domid = disk->backend_domid; 1.552 + device.devid = devid; 1.553 + device.domid = disk->domid; 1.554 + device.kind = DEVICE_VBD; 1.555 + 1.556 + switch (disk->phystype) { 1.557 + case PHYSTYPE_FILE: 1.558 + return ERROR_NI; /* FIXME */ 1.559 + break; 1.560 + case PHYSTYPE_PHY: { 1.561 + int major, minor; 1.562 + 1.563 + device_disk_major_minor(disk->virtpath, &major, &minor); 1.564 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "physical-device")); 1.565 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); 1.566 + 1.567 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "params")); 1.568 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->physpath)); 1.569 + 1.570 + device.backend_kind = DEVICE_VBD; 1.571 + break; 1.572 + } 1.573 + case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case PHYSTYPE_VHD: 1.574 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "params")); 1.575 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", 1.576 + device_disk_string_of_phystype(disk->phystype), disk->physpath)); 1.577 + 1.578 + device.backend_kind = DEVICE_TAP; 1.579 + break; 1.580 + } 1.581 + 1.582 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); 1.583 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid)); 1.584 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); 1.585 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); 1.586 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "removable")); 1.587 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0)); 1.588 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); 1.589 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); 1.590 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev")); 1.591 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->virtpath)); 1.592 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "type")); 1.593 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", backend_type)); 1.594 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "mode")); 1.595 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", (disk->readwrite) ? "w" : "r")); 1.596 + 1.597 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); 1.598 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid)); 1.599 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); 1.600 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); 1.601 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "virtual-device")); 1.602 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid)); 1.603 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "device-type")); 1.604 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%s", (disk->is_cdrom) ? "cdrom" : "disk")); 1.605 + 1.606 + if (0 /* protocol != native*/) { 1.607 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol")); 1.608 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */ 1.609 + } 1.610 + 1.611 + libxl_device_generic_add(ctx, &device, 1.612 + libxl_xs_kvs_of_flexarray(ctx, back, boffset), 1.613 + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); 1.614 + /* leaks both flexarray here */ 1.615 + return 0; 1.616 +} 1.617 + 1.618 +int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.619 +{ 1.620 + return ERROR_NI; 1.621 +} 1.622 + 1.623 +int libxl_device_disk_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.624 +{ 1.625 + return ERROR_NI; 1.626 +} 1.627 + 1.628 +/******************************************************************************/ 1.629 +int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) 1.630 +{ 1.631 + flexarray_t *front; 1.632 + flexarray_t *back; 1.633 + unsigned int boffset = 0; 1.634 + unsigned int foffset = 0; 1.635 + libxl_device device; 1.636 + 1.637 + front = flexarray_make(16, 1); 1.638 + if (!front) 1.639 + return ERROR_NOMEM; 1.640 + back = flexarray_make(16, 1); 1.641 + if (!back) 1.642 + return ERROR_NOMEM; 1.643 + 1.644 + device.backend_devid = nic->devid; 1.645 + device.backend_domid = nic->backend_domid; 1.646 + device.backend_kind = DEVICE_VIF; 1.647 + device.devid = nic->devid; 1.648 + device.domid = nic->domid; 1.649 + device.kind = DEVICE_VIF; 1.650 + 1.651 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); 1.652 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid)); 1.653 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); 1.654 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); 1.655 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); 1.656 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); 1.657 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "script")); 1.658 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", nic->script)); 1.659 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "mac")); 1.660 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", 1.661 + nic->mac[0], nic->mac[1], nic->mac[2], 1.662 + nic->mac[3], nic->mac[4], nic->mac[5])); 1.663 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "handle")); 1.664 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid)); 1.665 + 1.666 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); 1.667 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid)); 1.668 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); 1.669 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); 1.670 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "handle")); 1.671 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid)); 1.672 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "mac")); 1.673 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", 1.674 + nic->mac[0], nic->mac[1], nic->mac[2], 1.675 + nic->mac[3], nic->mac[4], nic->mac[5])); 1.676 + if (0 /* protocol != native*/) { 1.677 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol")); 1.678 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */ 1.679 + } 1.680 + 1.681 + libxl_device_generic_add(ctx, &device, 1.682 + libxl_xs_kvs_of_flexarray(ctx, back, boffset), 1.683 + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); 1.684 + 1.685 + /* FIXME: wait for plug */ 1.686 + return 0; 1.687 +} 1.688 + 1.689 +int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.690 +{ 1.691 + return ERROR_NI; 1.692 +} 1.693 + 1.694 +int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.695 +{ 1.696 + return ERROR_NI; 1.697 +} 1.698 + 1.699 +/******************************************************************************/ 1.700 +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid) 1.701 +{ 1.702 + return ERROR_NI; 1.703 +} 1.704 + 1.705 +int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.706 +{ 1.707 + return ERROR_NI; 1.708 +} 1.709 + 1.710 +int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.711 +{ 1.712 + return ERROR_NI; 1.713 +} 1.714 + 1.715 +/******************************************************************************/ 1.716 +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid) 1.717 +{ 1.718 + return ERROR_NI; 1.719 +} 1.720 + 1.721 +int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.722 +{ 1.723 + return ERROR_NI; 1.724 +} 1.725 + 1.726 +int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.727 +{ 1.728 + return ERROR_NI; 1.729 +} 1.730 + 1.731 +/******************************************************************************/ 1.732 +int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid) 1.733 +{ 1.734 + return ERROR_NI; 1.735 +} 1.736 + 1.737 +int libxl_device_pci_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.738 +{ 1.739 + return ERROR_NI; 1.740 +} 1.741 + 1.742 +int libxl_device_pci_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 1.743 +{ 1.744 + return ERROR_NI; 1.745 +}