debuggers.hg
annotate tools/libxl/libxl.c @ 20632:e0351b16a747
libxenlight: physmap slack for pv domains
Contemplate a memory space slack for PV domains,
since they do ballooning (or flipping network rx)
and need some extra room in their pfn space.
Note that this does not allocate any extra memory
to the domain, it simply extends the physmap with
some extra room for "bounce bufffering back" pfn's
that are yielded to dom0.
The default slack is set at 8MB.
Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.com>
Acked-by: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
Contemplate a memory space slack for PV domains,
since they do ballooning (or flipping network rx)
and need some extra room in their pfn space.
Note that this does not allocate any extra memory
to the domain, it simply extends the physmap with
some extra room for "bounce bufffering back" pfn's
that are yielded to dom0.
The default slack is set at 8MB.
Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.com>
Acked-by: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Sat Dec 05 12:30:46 2009 +0000 (2009-12-05) |
parents | fde8e69858b0 |
children | 696f94dfad26 |
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@20513 | 17 #include "libxl_osdeps.h" |
keir@20513 | 18 |
keir@20462 | 19 #include <stdio.h> |
keir@20462 | 20 #include <string.h> |
keir@20462 | 21 #include <stdlib.h> |
keir@20462 | 22 #include <sys/types.h> |
keir@20462 | 23 #include <fcntl.h> |
keir@20462 | 24 #include <sys/select.h> |
keir@20514 | 25 #include <sys/wait.h> |
keir@20462 | 26 #include <signal.h> |
keir@20468 | 27 #include <unistd.h> /* for write, unlink and close */ |
keir@20509 | 28 #include <stdint.h> |
keir@20509 | 29 #include <inttypes.h> |
keir@20514 | 30 #include <assert.h> |
keir@20513 | 31 |
keir@20462 | 32 #include "libxl.h" |
keir@20462 | 33 #include "libxl_utils.h" |
keir@20462 | 34 #include "libxl_internal.h" |
keir@20462 | 35 #include "flexarray.h" |
keir@20462 | 36 |
keir@20462 | 37 int libxl_ctx_init(struct libxl_ctx *ctx) |
keir@20462 | 38 { |
keir@20462 | 39 memset(ctx, 0, sizeof(struct libxl_ctx)); |
keir@20462 | 40 ctx->alloc_maxsize = 256; |
keir@20462 | 41 ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); |
keir@20462 | 42 if (!ctx->alloc_ptrs) |
keir@20462 | 43 return ERROR_NOMEM; |
keir@20462 | 44 |
keir@20462 | 45 ctx->xch = xc_interface_open(); |
keir@20462 | 46 ctx->xsh = xs_daemon_open(); |
keir@20514 | 47 |
keir@20514 | 48 ctx->waitpid_instead= libxl_waitpid_instead_default; |
keir@20462 | 49 return 0; |
keir@20462 | 50 } |
keir@20462 | 51 |
keir@20462 | 52 int libxl_ctx_free(struct libxl_ctx *ctx) |
keir@20462 | 53 { |
keir@20462 | 54 libxl_free_all(ctx); |
keir@20462 | 55 free(ctx->alloc_ptrs); |
keir@20545 | 56 ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); |
keir@20545 | 57 if (!ctx->alloc_ptrs) |
keir@20545 | 58 return ERROR_NOMEM; |
keir@20545 | 59 return 0; |
keir@20545 | 60 } |
keir@20545 | 61 |
keir@20545 | 62 int libxl_ctx_close(struct libxl_ctx *ctx) |
keir@20545 | 63 { |
keir@20545 | 64 libxl_ctx_free(ctx); |
keir@20545 | 65 free(ctx->alloc_ptrs); |
keir@20462 | 66 xc_interface_close(ctx->xch); |
keir@20545 | 67 xs_daemon_close(ctx->xsh); |
keir@20462 | 68 return 0; |
keir@20462 | 69 } |
keir@20462 | 70 |
keir@20462 | 71 int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data) |
keir@20462 | 72 { |
keir@20462 | 73 ctx->log_callback = log_callback; |
keir@20462 | 74 ctx->log_userdata = log_data; |
keir@20462 | 75 return 0; |
keir@20462 | 76 } |
keir@20462 | 77 |
keir@20462 | 78 /******************************************************************************/ |
keir@20462 | 79 |
keir@20462 | 80 int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, |
keir@20462 | 81 uint32_t *domid) |
keir@20462 | 82 { |
keir@20462 | 83 int flags, ret, i; |
keir@20468 | 84 char *uuid_string; |
keir@20583 | 85 char *rw_paths[] = { "device", "device/suspend/event-channel" }; |
keir@20462 | 86 char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", |
keir@20462 | 87 "control", "attr", "data", "messages" }; |
keir@20462 | 88 char *dom_path, *vm_path, *vss_path; |
keir@20462 | 89 struct xs_permissions roperm[2]; |
keir@20462 | 90 struct xs_permissions rwperm[1]; |
keir@20462 | 91 xs_transaction_t t; |
keir@20468 | 92 xen_domain_handle_t handle; |
keir@20462 | 93 |
keir@20468 | 94 uuid_string = libxl_uuid_to_string(ctx, info->uuid); |
keir@20462 | 95 if (!uuid_string) { |
keir@20462 | 96 XL_LOG(ctx, XL_LOG_ERROR, "missing uuid"); |
keir@20462 | 97 return ERROR_FAIL; |
keir@20462 | 98 } |
keir@20462 | 99 |
keir@20462 | 100 flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; |
keir@20462 | 101 flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; |
keir@20462 | 102 *domid = 0; |
keir@20462 | 103 |
keir@20580 | 104 /* |
keir@20468 | 105 * info->uuid != xen_domain_handle_t |
keir@20468 | 106 * See: |
keir@20468 | 107 * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt |
keir@20468 | 108 * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm |
keir@20468 | 109 * |
keir@20468 | 110 * A DCE 1.1 compatible source representation of UUIDs. |
keir@20468 | 111 * |
keir@20468 | 112 * struct uuid { |
keir@20468 | 113 * uint32_t time_low; |
keir@20468 | 114 * uint16_t time_mid; |
keir@20468 | 115 * uint16_t time_hi_and_version; |
keir@20468 | 116 * uint8_t clock_seq_hi_and_reserved; |
keir@20468 | 117 * uint8_t clock_seq_low; |
keir@20468 | 118 * uint8_t node[_UUID_NODE_LEN]; |
keir@20468 | 119 * }; |
keir@20468 | 120 */ |
keir@20580 | 121 /* Ultimately, handle is an array of 16 uint8_t, same as uuid */ |
keir@20580 | 122 memcpy(handle, info->uuid, sizeof(xen_domain_handle_t)); |
keir@20468 | 123 |
keir@20468 | 124 ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); |
keir@20462 | 125 if (ret < 0) { |
keir@20512 | 126 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain creation fail"); |
keir@20462 | 127 return ERROR_FAIL; |
keir@20462 | 128 } |
keir@20462 | 129 |
keir@20462 | 130 dom_path = libxl_xs_get_dompath(ctx, *domid); |
keir@20512 | 131 if (!dom_path) |
keir@20512 | 132 return ERROR_FAIL; |
keir@20512 | 133 |
keir@20462 | 134 vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); |
keir@20462 | 135 vss_path = libxl_sprintf(ctx, "/vss/%s", uuid_string); |
keir@20512 | 136 if (!vm_path || !vss_path) { |
keir@20462 | 137 XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths"); |
keir@20462 | 138 return ERROR_FAIL; |
keir@20462 | 139 } |
keir@20462 | 140 |
keir@20462 | 141 roperm[0].id = 0; |
keir@20462 | 142 roperm[0].perms = XS_PERM_NONE; |
keir@20462 | 143 roperm[1].id = *domid; |
keir@20462 | 144 roperm[1].perms = XS_PERM_READ; |
keir@20462 | 145 rwperm[0].id = *domid; |
keir@20462 | 146 rwperm[0].perms = XS_PERM_NONE; |
keir@20462 | 147 |
keir@20462 | 148 retry_transaction: |
keir@20462 | 149 t = xs_transaction_start(ctx->xsh); |
keir@20462 | 150 xs_rm(ctx->xsh, t, dom_path); |
keir@20462 | 151 xs_mkdir(ctx->xsh, t, dom_path); |
keir@20462 | 152 xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); |
keir@20462 | 153 |
keir@20462 | 154 xs_rm(ctx->xsh, t, vm_path); |
keir@20462 | 155 xs_mkdir(ctx->xsh, t, vm_path); |
keir@20462 | 156 xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); |
keir@20462 | 157 |
keir@20462 | 158 xs_rm(ctx->xsh, t, vss_path); |
keir@20462 | 159 xs_mkdir(ctx->xsh, t, vss_path); |
keir@20462 | 160 xs_set_permissions(ctx->xsh, t, vss_path, rwperm, ARRAY_SIZE(rwperm)); |
keir@20462 | 161 |
keir@20462 | 162 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); |
keir@20462 | 163 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, strlen(vss_path)); |
keir@20462 | 164 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, strlen(info->name)); |
keir@20462 | 165 |
keir@20462 | 166 for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { |
keir@20462 | 167 char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]); |
keir@20462 | 168 xs_mkdir(ctx->xsh, t, path); |
keir@20462 | 169 xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); |
keir@20462 | 170 libxl_free(ctx, path); |
keir@20462 | 171 } |
keir@20462 | 172 for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { |
keir@20462 | 173 char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]); |
keir@20462 | 174 xs_mkdir(ctx->xsh, t, path); |
keir@20462 | 175 xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); |
keir@20462 | 176 libxl_free(ctx, path); |
keir@20462 | 177 } |
keir@20462 | 178 |
keir@20462 | 179 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); |
keir@20462 | 180 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name)); |
keir@20462 | 181 |
keir@20462 | 182 libxl_xs_writev(ctx, t, dom_path, info->xsdata); |
keir@20462 | 183 libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata); |
keir@20462 | 184 |
keir@20462 | 185 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); |
keir@20462 | 186 |
keir@20462 | 187 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20462 | 188 if (errno == EAGAIN) |
keir@20462 | 189 goto retry_transaction; |
keir@20462 | 190 return 0; |
keir@20462 | 191 } |
keir@20462 | 192 |
keir@20516 | 193 int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) |
keir@20462 | 194 { |
keir@20462 | 195 char **vments = NULL, **localents = NULL; |
keir@20578 | 196 int i; |
keir@20462 | 197 |
keir@20509 | 198 build_pre(ctx, domid, info, state); |
keir@20462 | 199 if (info->hvm) { |
keir@20509 | 200 build_hvm(ctx, domid, info, state); |
keir@20509 | 201 vments = libxl_calloc(ctx, 5, sizeof(char *)); |
keir@20516 | 202 vments[0] = "rtc/timeoffset"; |
keir@20516 | 203 vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; |
keir@20516 | 204 vments[2] = "image/ostype"; |
keir@20516 | 205 vments[3] = "hvm"; |
keir@20462 | 206 } else { |
keir@20509 | 207 build_pv(ctx, domid, info, state); |
keir@20509 | 208 vments = libxl_calloc(ctx, 9, sizeof(char *)); |
keir@20578 | 209 i = 0; |
keir@20578 | 210 vments[i++] = "image/ostype"; |
keir@20578 | 211 vments[i++] = "linux"; |
keir@20578 | 212 vments[i++] = "image/kernel"; |
keir@20578 | 213 vments[i++] = (char*) info->kernel; |
keir@20578 | 214 if (info->u.pv.ramdisk) { |
keir@20578 | 215 vments[i++] = "image/ramdisk"; |
keir@20578 | 216 vments[i++] = (char*) info->u.pv.ramdisk; |
keir@20578 | 217 } |
keir@20578 | 218 if (info->u.pv.cmdline) { |
keir@20578 | 219 vments[i++] = "image/cmdline"; |
keir@20578 | 220 vments[i++] = (char*) info->u.pv.cmdline; |
keir@20578 | 221 } |
keir@20462 | 222 } |
keir@20509 | 223 build_post(ctx, domid, info, state, vments, localents); |
keir@20516 | 224 return 0; |
keir@20462 | 225 } |
keir@20462 | 226 |
keir@20462 | 227 int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info, |
keir@20565 | 228 uint32_t domid, int fd, libxl_domain_build_state *state, |
keir@20565 | 229 libxl_device_model_info *dm_info) |
keir@20462 | 230 { |
keir@20462 | 231 char **vments = NULL, **localents = NULL; |
keir@20627 | 232 int i; |
keir@20462 | 233 |
keir@20565 | 234 build_pre(ctx, domid, info, state); |
keir@20565 | 235 restore_common(ctx, domid, info, state, fd); |
keir@20462 | 236 if (info->hvm) { |
keir@20565 | 237 vments = libxl_calloc(ctx, 5, sizeof(char *)); |
keir@20516 | 238 vments[0] = "rtc/timeoffset"; |
keir@20516 | 239 vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; |
keir@20565 | 240 vments[2] = "image/ostype"; |
keir@20565 | 241 vments[3] = "hvm"; |
keir@20462 | 242 } else { |
keir@20565 | 243 vments = libxl_calloc(ctx, 9, sizeof(char *)); |
keir@20627 | 244 i = 0; |
keir@20627 | 245 vments[i++] = "image/ostype"; |
keir@20627 | 246 vments[i++] = "linux"; |
keir@20627 | 247 vments[i++] = "image/kernel"; |
keir@20627 | 248 vments[i++] = (char*) info->kernel; |
keir@20627 | 249 if (info->u.pv.ramdisk) { |
keir@20627 | 250 vments[i++] = "image/ramdisk"; |
keir@20627 | 251 vments[i++] = (char*) info->u.pv.ramdisk; |
keir@20627 | 252 } |
keir@20627 | 253 if (info->u.pv.cmdline) { |
keir@20627 | 254 vments[i++] = "image/cmdline"; |
keir@20627 | 255 vments[i++] = (char*) info->u.pv.cmdline; |
keir@20627 | 256 } |
keir@20462 | 257 } |
keir@20565 | 258 build_post(ctx, domid, info, state, vments, localents); |
keir@20565 | 259 if (info->hvm) |
keir@20565 | 260 asprintf(&(dm_info->saved_state), "/var/lib/xen/qemu-save.%d", domid); |
keir@20565 | 261 else |
keir@20565 | 262 dm_info->saved_state = NULL; |
keir@20565 | 263 |
keir@20462 | 264 return 0; |
keir@20462 | 265 } |
keir@20462 | 266 |
keir@20629 | 267 int libxl_domain_resume(struct libxl_ctx *ctx, uint32_t domid) |
keir@20629 | 268 { |
keir@20629 | 269 if (is_hvm(ctx, domid)) { |
keir@20629 | 270 XL_LOG(ctx, XL_LOG_DEBUG, "Called domain_resume on " |
keir@20629 | 271 "non-cooperative hvm domain %u", domid); |
keir@20629 | 272 return ERROR_NI; |
keir@20629 | 273 } |
keir@20629 | 274 if (xc_domain_resume(ctx->xch, domid, 1)) { |
keir@20629 | 275 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, |
keir@20629 | 276 "xc_domain_resume failed for domain %u", |
keir@20629 | 277 domid); |
keir@20629 | 278 return ERROR_FAIL; |
keir@20629 | 279 } |
keir@20629 | 280 if (!xs_resume_domain(ctx->xsh, domid)) { |
keir@20629 | 281 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, |
keir@20629 | 282 "xs_resume_domain failed for domain %u", |
keir@20629 | 283 domid); |
keir@20629 | 284 return ERROR_FAIL; |
keir@20629 | 285 } |
keir@20629 | 286 return 0; |
keir@20629 | 287 } |
keir@20629 | 288 |
keir@20462 | 289 struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain) |
keir@20462 | 290 { |
keir@20462 | 291 struct libxl_dominfo *ptr; |
keir@20462 | 292 int index, i, ret, first_domain; |
keir@20462 | 293 xc_domaininfo_t info[16]; |
keir@20462 | 294 int size = 16; |
keir@20462 | 295 |
keir@20462 | 296 first_domain = 1; |
keir@20462 | 297 index = 0; |
keir@20516 | 298 ptr = calloc(size, sizeof(struct libxl_dominfo)); |
keir@20462 | 299 if (!ptr) |
keir@20462 | 300 return NULL; |
keir@20462 | 301 redo: |
keir@20462 | 302 ret = xc_domain_getinfolist(ctx->xch, first_domain, 16, info); |
keir@20462 | 303 for (i = 0; i < ret; i++) { |
keir@20462 | 304 if (index == size) { |
keir@20462 | 305 struct libxl_dominfo *ptr2; |
keir@20462 | 306 |
keir@20516 | 307 ptr2 = calloc(size * 2, sizeof(struct libxl_dominfo)); |
keir@20462 | 308 if (!ptr2) { |
keir@20516 | 309 free(ptr); |
keir@20462 | 310 return NULL; |
keir@20462 | 311 } |
keir@20462 | 312 memcpy(ptr2, ptr, sizeof(struct libxl_dominfo) * size); |
keir@20516 | 313 free(ptr); |
keir@20462 | 314 ptr = ptr2; |
keir@20462 | 315 size *= 2; |
keir@20462 | 316 } |
keir@20579 | 317 memcpy(&(ptr[index].uuid), info[i].handle, sizeof(xen_domain_handle_t)); |
keir@20462 | 318 ptr[index].domid = info[i].domain; |
keir@20462 | 319 first_domain = info[i].domain + 1; |
keir@20462 | 320 index++; |
keir@20462 | 321 } |
keir@20462 | 322 if (ret == 16) |
keir@20462 | 323 goto redo; |
keir@20462 | 324 *nb_domain = index; |
keir@20462 | 325 return ptr; |
keir@20462 | 326 } |
keir@20462 | 327 |
keir@20462 | 328 xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain) |
keir@20462 | 329 { |
keir@20462 | 330 int index, first_domain; |
keir@20462 | 331 xc_dominfo_t *info; |
keir@20462 | 332 int size = 1024; |
keir@20462 | 333 |
keir@20462 | 334 first_domain = 0; |
keir@20462 | 335 index = 0; |
keir@20516 | 336 info = (xc_dominfo_t *) calloc(size, sizeof(xc_dominfo_t)); |
keir@20462 | 337 if (!info) { |
keir@20462 | 338 *nb_domain = 0; |
keir@20462 | 339 return NULL; |
keir@20462 | 340 } |
keir@20462 | 341 *nb_domain = xc_domain_getinfo(ctx->xch, first_domain, 1024, info); |
keir@20462 | 342 return info; |
keir@20462 | 343 } |
keir@20462 | 344 |
keir@20565 | 345 static int libxl_save_device_model(struct libxl_ctx *ctx, uint32_t domid, int fd) |
keir@20565 | 346 { |
keir@20565 | 347 int fd2, c; |
keir@20565 | 348 char buf[1024]; |
keir@20565 | 349 char *filename = libxl_sprintf(ctx, "/var/lib/xen/qemu-save.%d", domid); |
keir@20565 | 350 |
keir@20565 | 351 XL_LOG(ctx, XL_LOG_DEBUG, "Saving device model state to %s", filename); |
keir@20565 | 352 libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "save", strlen("save")); |
keir@20565 | 353 libxl_wait_for_device_model(ctx, domid, "paused", NULL, NULL); |
keir@20565 | 354 |
keir@20565 | 355 write(fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE)); |
keir@20565 | 356 fd2 = open(filename, O_RDONLY); |
keir@20565 | 357 while ((c = read(fd2, buf, sizeof(buf))) != 0) { |
keir@20565 | 358 write(fd, buf, c); |
keir@20565 | 359 } |
keir@20565 | 360 close(fd2); |
keir@20565 | 361 unlink(filename); |
keir@20565 | 362 return 0; |
keir@20565 | 363 } |
keir@20565 | 364 |
keir@20630 | 365 xc_dominfo_t *libxl_domain_info(struct libxl_ctx *ctx, uint32_t domid) |
keir@20630 | 366 { |
keir@20630 | 367 xc_dominfo_t *info; |
keir@20630 | 368 int rc; |
keir@20630 | 369 |
keir@20630 | 370 info = (xc_dominfo_t *) calloc(1, sizeof(xc_dominfo_t)); |
keir@20630 | 371 if (!info) { |
keir@20630 | 372 return NULL; |
keir@20630 | 373 } |
keir@20630 | 374 rc = xc_domain_getinfo(ctx->xch, domid, 1, info); |
keir@20630 | 375 if (rc != 1) { |
keir@20630 | 376 free(info); |
keir@20630 | 377 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to get info for domain %u", |
keir@20630 | 378 domid); |
keir@20630 | 379 return NULL; |
keir@20630 | 380 } |
keir@20630 | 381 if (info->domid != domid) { |
keir@20630 | 382 free(info); |
keir@20630 | 383 XL_LOG(ctx, XL_LOG_ERROR, "Failed to get info for domain %u" |
keir@20630 | 384 ", seems to not exist anymore", domid); |
keir@20630 | 385 return NULL; |
keir@20630 | 386 } |
keir@20630 | 387 |
keir@20630 | 388 return info; |
keir@20630 | 389 } |
keir@20462 | 390 int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info, |
keir@20462 | 391 uint32_t domid, int fd) |
keir@20462 | 392 { |
keir@20565 | 393 int hvm = is_hvm(ctx, domid); |
keir@20565 | 394 int live = info != NULL && info->flags & XL_SUSPEND_LIVE; |
keir@20565 | 395 int debug = info != NULL && info->flags & XL_SUSPEND_LIVE; |
keir@20462 | 396 |
keir@20462 | 397 |
keir@20462 | 398 core_suspend(ctx, domid, fd, hvm, live, debug); |
keir@20565 | 399 if (hvm) |
keir@20565 | 400 libxl_save_device_model(ctx, domid, fd); |
keir@20462 | 401 |
keir@20462 | 402 return 0; |
keir@20462 | 403 } |
keir@20462 | 404 |
keir@20462 | 405 int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 406 { |
keir@20462 | 407 xc_domain_pause(ctx->xch, domid); |
keir@20462 | 408 return 0; |
keir@20462 | 409 } |
keir@20462 | 410 |
keir@20462 | 411 int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 412 { |
keir@20565 | 413 char path[50]; |
keir@20565 | 414 char *state; |
keir@20565 | 415 |
keir@20565 | 416 if (is_hvm(ctx, domid)) { |
keir@20565 | 417 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/state", domid); |
keir@20565 | 418 state = libxl_xs_read(ctx, XBT_NULL, path); |
keir@20565 | 419 if (state != NULL && !strcmp(state, "paused")) { |
keir@20565 | 420 libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "continue", strlen("continue")); |
keir@20565 | 421 libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL); |
keir@20565 | 422 } |
keir@20565 | 423 } |
keir@20462 | 424 xc_domain_unpause(ctx->xch, domid); |
keir@20565 | 425 |
keir@20462 | 426 return 0; |
keir@20462 | 427 } |
keir@20462 | 428 |
keir@20462 | 429 static char *req_table[] = { |
keir@20462 | 430 [0] = "poweroff", |
keir@20462 | 431 [1] = "reboot", |
keir@20462 | 432 [2] = "suspend", |
keir@20462 | 433 [3] = "crash", |
keir@20462 | 434 [4] = "halt", |
keir@20462 | 435 }; |
keir@20462 | 436 |
keir@20462 | 437 int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req) |
keir@20462 | 438 { |
keir@20462 | 439 char *shutdown_path; |
keir@20462 | 440 char *dom_path; |
keir@20462 | 441 |
keir@20462 | 442 if (req > ARRAY_SIZE(req_table)) |
keir@20462 | 443 return ERROR_INVAL; |
keir@20462 | 444 |
keir@20462 | 445 dom_path = libxl_xs_get_dompath(ctx, domid); |
keir@20512 | 446 if (!dom_path) |
keir@20512 | 447 return ERROR_FAIL; |
keir@20512 | 448 |
keir@20462 | 449 shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path); |
keir@20462 | 450 |
keir@20462 | 451 xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req])); |
keir@20462 | 452 if (/* hvm */ 0) { |
keir@20462 | 453 unsigned long acpi_s_state = 0; |
keir@20462 | 454 unsigned long pvdriver = 0; |
keir@20462 | 455 xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state); |
keir@20462 | 456 xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver); |
keir@20462 | 457 if (!pvdriver && acpi_s_state != 0) |
keir@20462 | 458 xc_domain_shutdown(ctx->xch, domid, req); |
keir@20462 | 459 } |
keir@20462 | 460 return 0; |
keir@20462 | 461 } |
keir@20462 | 462 |
keir@20545 | 463 int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int *fd) |
keir@20545 | 464 { |
keir@20545 | 465 if (!xs_watch(ctx->xsh, "@releaseDomain", "domain_death")) |
keir@20545 | 466 return -1; |
keir@20545 | 467 *fd = xs_fileno(ctx->xsh); |
keir@20545 | 468 return 0; |
keir@20545 | 469 } |
keir@20545 | 470 |
keir@20545 | 471 int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t *info) |
keir@20545 | 472 { |
keir@20545 | 473 unsigned int num; |
keir@20545 | 474 int nb_domain, i, rc = 0; |
keir@20545 | 475 char **vec = NULL; |
keir@20545 | 476 xc_dominfo_t *list = NULL; |
keir@20545 | 477 |
keir@20545 | 478 vec = xs_read_watch(ctx->xsh, &num); |
keir@20545 | 479 if (!vec) |
keir@20545 | 480 return 0; |
keir@20545 | 481 if (!strcmp(vec[XS_WATCH_TOKEN], "domain_death")) { |
keir@20545 | 482 list = libxl_domain_infolist(ctx, &nb_domain); |
keir@20545 | 483 for (i = 0; i < nb_domain; i++) { |
keir@20545 | 484 if (domid == list[i].domid) { |
keir@20545 | 485 if (list[i].running || (!list[i].shutdown && !list[i].crashed && !list[i].dying)) |
keir@20545 | 486 goto out; |
keir@20545 | 487 *info = list[i]; |
keir@20545 | 488 rc = 1; |
keir@20545 | 489 goto out; |
keir@20545 | 490 } |
keir@20545 | 491 } |
keir@20545 | 492 memset(info, 0x00, sizeof(xc_dominfo_t)); |
keir@20545 | 493 rc = 1; |
keir@20545 | 494 goto out; |
keir@20545 | 495 } |
keir@20545 | 496 |
keir@20545 | 497 out: |
keir@20545 | 498 free(list); |
keir@20545 | 499 free(vec); |
keir@20545 | 500 return rc; |
keir@20545 | 501 } |
keir@20545 | 502 |
keir@20462 | 503 static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 504 { |
keir@20462 | 505 char *pid; |
keir@20462 | 506 int ret; |
keir@20462 | 507 |
keir@20462 | 508 pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); |
keir@20462 | 509 if (!pid) { |
keir@20542 | 510 int stubdomid = libxl_get_stubdom_id(ctx, domid); |
keir@20542 | 511 if (!stubdomid) { |
keir@20542 | 512 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't find device model's pid"); |
keir@20542 | 513 return -1; |
keir@20542 | 514 } |
keir@20542 | 515 XL_LOG(ctx, XL_LOG_ERROR, "Device model is a stubdom, domid=%d\n", stubdomid); |
keir@20542 | 516 return libxl_domain_destroy(ctx, stubdomid, 0); |
keir@20462 | 517 } |
keir@20462 | 518 xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid)); |
keir@20462 | 519 |
keir@20462 | 520 ret = kill(atoi(pid), SIGHUP); |
keir@20462 | 521 if (ret < 0 && errno == ESRCH) { |
keir@20512 | 522 XL_LOG(ctx, XL_LOG_DEBUG, "Device Model already exited"); |
keir@20462 | 523 ret = 0; |
keir@20462 | 524 } else if (ret == 0) { |
keir@20512 | 525 XL_LOG(ctx, XL_LOG_DEBUG, "Device Model signaled"); |
keir@20462 | 526 ret = 0; |
keir@20462 | 527 } else { |
keir@20512 | 528 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to kill Device Model [%d]", |
keir@20512 | 529 atoi(pid)); |
keir@20462 | 530 } |
keir@20462 | 531 return ret; |
keir@20462 | 532 } |
keir@20462 | 533 |
keir@20462 | 534 int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force) |
keir@20462 | 535 { |
keir@20581 | 536 char *dom_path, *uuid_str; |
keir@20581 | 537 char vm_path[UUID_LEN_STR + 5], vss_path[UUID_LEN_STR + 6], xapi_path[20]; |
keir@20468 | 538 xen_uuid_t *uuid; |
keir@20628 | 539 int rc, dm_present; |
keir@20628 | 540 |
keir@20628 | 541 if (is_hvm(ctx, domid)) { |
keir@20628 | 542 dm_present = 1; |
keir@20628 | 543 } else { |
keir@20628 | 544 char *pid; |
keir@20628 | 545 pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); |
keir@20628 | 546 dm_present = (pid != NULL); |
keir@20628 | 547 libxl_free(ctx, pid); |
keir@20628 | 548 } |
keir@20462 | 549 |
keir@20462 | 550 dom_path = libxl_xs_get_dompath(ctx, domid); |
keir@20512 | 551 if (!dom_path) |
keir@20462 | 552 return -1; |
keir@20512 | 553 |
keir@20462 | 554 if (libxl_domid_to_uuid(ctx, &uuid, domid) < 0) { |
keir@20512 | 555 XL_LOG(ctx, XL_LOG_ERROR, "failed ot get uuid for %d", domid); |
keir@20462 | 556 return -1; |
keir@20462 | 557 } |
keir@20482 | 558 if (libxl_device_pci_shutdown(ctx, domid) < 0) |
keir@20512 | 559 XL_LOG(ctx, XL_LOG_ERROR, "pci shutdown failed for domid %d", domid); |
keir@20628 | 560 if (dm_present) { |
keir@20628 | 561 xs_write(ctx->xsh, XBT_NULL, |
keir@20628 | 562 libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), |
keir@20628 | 563 "shutdown", strlen("shutdown")); |
keir@20628 | 564 } |
keir@20512 | 565 rc = xc_domain_pause(ctx->xch, domid); |
keir@20512 | 566 if (rc < 0) { |
keir@20512 | 567 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); |
keir@20462 | 568 return -1; |
keir@20462 | 569 } |
keir@20628 | 570 if (dm_present) { |
keir@20628 | 571 if (libxl_destroy_device_model(ctx, domid) < 0) |
keir@20628 | 572 XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d", domid); |
keir@20628 | 573 } |
keir@20462 | 574 if (libxl_devices_destroy(ctx, domid, force) < 0) |
keir@20512 | 575 XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", domid); |
keir@20462 | 576 if (!xs_rm(ctx->xsh, XBT_NULL, dom_path)) |
keir@20512 | 577 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", dom_path); |
keir@20581 | 578 uuid_str = libxl_uuid_to_string(ctx, uuid); |
keir@20581 | 579 snprintf(vm_path, sizeof(vm_path), "/vm/%s", uuid_str); |
keir@20462 | 580 if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) |
keir@20512 | 581 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path); |
keir@20581 | 582 snprintf(vss_path, sizeof(vss_path), "/vss/%s", uuid_str); |
keir@20581 | 583 if (!xs_rm(ctx->xsh, XBT_NULL, vss_path)) |
keir@20581 | 584 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vss_path); |
keir@20581 | 585 libxl_free(ctx, uuid_str); |
keir@20581 | 586 snprintf(xapi_path, sizeof(xapi_path), "/xapi/%u", domid); |
keir@20581 | 587 if (!xs_rm(ctx->xsh, XBT_NULL, xapi_path)) |
keir@20581 | 588 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", xapi_path); |
keir@20545 | 589 rc = xc_domain_destroy(ctx->xch, domid); |
keir@20545 | 590 if (rc < 0) { |
keir@20545 | 591 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); |
keir@20545 | 592 return -1; |
keir@20545 | 593 } |
keir@20462 | 594 return 0; |
keir@20462 | 595 } |
keir@20462 | 596 |
keir@20564 | 597 int libxl_console_attach(struct libxl_ctx *ctx, uint32_t domid, int cons_num) |
keir@20564 | 598 { |
keir@20564 | 599 struct stat st; |
keir@20564 | 600 const char *XENCONSOLE = "/usr/lib/xen/bin/xenconsole"; |
keir@20564 | 601 char *cmd; |
keir@20564 | 602 |
keir@20564 | 603 if (stat(XENCONSOLE, &st) != 0) { |
keir@20564 | 604 XL_LOG(ctx, XL_LOG_ERROR, "could not access %s", XENCONSOLE); |
keir@20564 | 605 return ERROR_FAIL; |
keir@20564 | 606 } |
keir@20564 | 607 |
keir@20564 | 608 cmd = libxl_sprintf(ctx, "%s %d --num %d", XENCONSOLE, domid, cons_num); |
keir@20564 | 609 return (system(cmd) != 0) ? ERROR_FAIL : 0; |
keir@20564 | 610 } |
keir@20564 | 611 |
keir@20462 | 612 static char ** libxl_build_device_model_args(struct libxl_ctx *ctx, |
keir@20462 | 613 libxl_device_model_info *info, |
keir@20462 | 614 libxl_device_nic *vifs, |
keir@20462 | 615 int num_vifs) |
keir@20462 | 616 { |
keir@20462 | 617 int num = 0, i; |
keir@20462 | 618 flexarray_t *dm_args; |
keir@20462 | 619 dm_args = flexarray_make(16, 1); |
keir@20462 | 620 if (!dm_args) |
keir@20462 | 621 return NULL; |
keir@20462 | 622 |
keir@20516 | 623 flexarray_set(dm_args, num++, "qemu-dm"); |
keir@20516 | 624 flexarray_set(dm_args, num++, "-d"); |
keir@20462 | 625 |
keir@20462 | 626 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); |
keir@20462 | 627 |
keir@20462 | 628 if (info->dom_name) { |
keir@20516 | 629 flexarray_set(dm_args, num++, "-domain-name"); |
keir@20516 | 630 flexarray_set(dm_args, num++, info->dom_name); |
keir@20462 | 631 } |
keir@20462 | 632 if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { |
keir@20516 | 633 flexarray_set(dm_args, num++, "-vnc"); |
keir@20462 | 634 if (info->vncdisplay) { |
keir@20462 | 635 if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { |
keir@20462 | 636 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:%d", info->vnclisten, info->vncdisplay)); |
keir@20462 | 637 } else { |
keir@20462 | 638 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay)); |
keir@20462 | 639 } |
keir@20462 | 640 } else if (info->vnclisten) { |
keir@20462 | 641 if (strchr(info->vnclisten, ':') != NULL) { |
keir@20516 | 642 flexarray_set(dm_args, num++, info->vnclisten); |
keir@20462 | 643 } else { |
keir@20462 | 644 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten)); |
keir@20462 | 645 } |
keir@20462 | 646 } else { |
keir@20516 | 647 flexarray_set(dm_args, num++, "127.0.0.1:0"); |
keir@20462 | 648 } |
keir@20462 | 649 if (info->vncunused) { |
keir@20516 | 650 flexarray_set(dm_args, num++, "-vncunused"); |
keir@20462 | 651 } |
keir@20462 | 652 } |
keir@20462 | 653 if (info->sdl || info->opengl) { |
keir@20516 | 654 flexarray_set(dm_args, num++, "-sdl"); |
keir@20462 | 655 if (info->opengl) { |
keir@20516 | 656 flexarray_set(dm_args, num++, "-disable-opengl"); |
keir@20462 | 657 } |
keir@20462 | 658 } |
keir@20462 | 659 if (info->keymap) { |
keir@20516 | 660 flexarray_set(dm_args, num++, "-k"); |
keir@20516 | 661 flexarray_set(dm_args, num++, info->keymap); |
keir@20462 | 662 } |
keir@20462 | 663 if (info->nographic && (!info->sdl && !info->vnc)) { |
keir@20516 | 664 flexarray_set(dm_args, num++, "-nographic"); |
keir@20462 | 665 } |
keir@20462 | 666 if (info->serial) { |
keir@20516 | 667 flexarray_set(dm_args, num++, "-serial"); |
keir@20516 | 668 flexarray_set(dm_args, num++, info->serial); |
keir@20462 | 669 } |
keir@20509 | 670 if (info->type == XENFV) { |
keir@20509 | 671 if (info->videoram) { |
keir@20516 | 672 flexarray_set(dm_args, num++, "-videoram"); |
keir@20509 | 673 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); |
keir@20509 | 674 } |
keir@20509 | 675 if (info->stdvga) { |
keir@20516 | 676 flexarray_set(dm_args, num++, "-std-vga"); |
keir@20509 | 677 } |
keir@20509 | 678 |
keir@20509 | 679 if (info->boot) { |
keir@20516 | 680 flexarray_set(dm_args, num++, "-boot"); |
keir@20516 | 681 flexarray_set(dm_args, num++, info->boot); |
keir@20509 | 682 } |
keir@20509 | 683 if (info->usb) { |
keir@20516 | 684 flexarray_set(dm_args, num++, "-usb"); |
keir@20509 | 685 if (info->usbdevice) { |
keir@20516 | 686 flexarray_set(dm_args, num++, "-usbdevice"); |
keir@20516 | 687 flexarray_set(dm_args, num++, info->usbdevice); |
keir@20509 | 688 } |
keir@20509 | 689 } |
keir@20509 | 690 if (info->apic) { |
keir@20516 | 691 flexarray_set(dm_args, num++, "-acpi"); |
keir@20509 | 692 } |
keir@20509 | 693 for (i = 0; i < num_vifs; i++) { |
keir@20509 | 694 if (vifs[i].nictype == NICTYPE_IOEMU) { |
keir@20516 | 695 flexarray_set(dm_args, num++, "-net"); |
keir@20509 | 696 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", |
keir@20509 | 697 vifs[i].devid, vifs[i].smac, vifs[i].model)); |
keir@20516 | 698 flexarray_set(dm_args, num++, "-net"); |
keir@20509 | 699 flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s", |
keir@20509 | 700 vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); |
keir@20509 | 701 } |
keir@20462 | 702 } |
keir@20462 | 703 } |
keir@20565 | 704 if (info->saved_state) { |
keir@20565 | 705 flexarray_set(dm_args, num++, "-loadvm"); |
keir@20565 | 706 flexarray_set(dm_args, num++, info->saved_state); |
keir@20565 | 707 } |
keir@20509 | 708 for (i = 0; info->extra && info->extra[i] != NULL; i++) |
keir@20509 | 709 flexarray_set(dm_args, num++, info->extra[i]); |
keir@20516 | 710 flexarray_set(dm_args, num++, "-M"); |
keir@20509 | 711 if (info->type == XENPV) |
keir@20516 | 712 flexarray_set(dm_args, num++, "xenpv"); |
keir@20509 | 713 else |
keir@20516 | 714 flexarray_set(dm_args, num++, "xenfv"); |
keir@20462 | 715 flexarray_set(dm_args, num++, NULL); |
keir@20462 | 716 |
keir@20462 | 717 return (char **) flexarray_contents(dm_args); |
keir@20462 | 718 } |
keir@20462 | 719 |
keir@20514 | 720 void dm_xenstore_record_pid(struct libxl_ctx *ctx, void *for_spawn, |
keir@20514 | 721 pid_t innerchild) { |
keir@20514 | 722 struct libxl_device_model_starting *starting = for_spawn; |
keir@20514 | 723 struct libxl_ctx clone; |
keir@20514 | 724 char *kvs[3]; |
keir@20624 | 725 int rc, cloned; |
keir@20514 | 726 |
keir@20624 | 727 if (libxl_clone_context_xs(ctx, &clone)) { |
keir@20624 | 728 XL_LOG(ctx, XL_LOG_ERROR, "Out of memory when cloning context"); |
keir@20624 | 729 /* Throw a prayer fallback */ |
keir@20624 | 730 clone = *ctx; |
keir@20624 | 731 clone.xsh = xs_daemon_open(); |
keir@20624 | 732 cloned = 0; |
keir@20624 | 733 } else { |
keir@20624 | 734 cloned = 1; |
keir@20624 | 735 } |
keir@20514 | 736 /* we mustn't use the parent's handle in the child */ |
keir@20514 | 737 |
keir@20514 | 738 kvs[0] = "image/device-model-pid"; |
keir@20610 | 739 kvs[1] = libxl_sprintf(&clone, "%d", innerchild); |
keir@20514 | 740 kvs[2] = NULL; |
keir@20610 | 741 rc = libxl_xs_writev(&clone, XBT_NULL, starting->dom_path, kvs); |
keir@20610 | 742 if (rc) XL_LOG_ERRNO(&clone, XL_LOG_ERROR, |
keir@20514 | 743 "Couldn't record device model pid %ld at %s/%s", |
keir@20514 | 744 (unsigned long)innerchild, starting->dom_path, kvs); |
keir@20624 | 745 if (cloned) { |
keir@20624 | 746 libxl_discard_cloned_context_xs(&clone); |
keir@20624 | 747 } else { |
keir@20624 | 748 xs_daemon_close(clone.xsh); |
keir@20624 | 749 } |
keir@20514 | 750 } |
keir@20514 | 751 |
keir@20542 | 752 static int libxl_vfb_and_vkb_from_device_model_info(struct libxl_ctx *ctx, |
keir@20542 | 753 libxl_device_model_info *info, |
keir@20542 | 754 libxl_device_vfb *vfb, |
keir@20542 | 755 libxl_device_vkb *vkb) |
keir@20542 | 756 { |
keir@20542 | 757 memset(vfb, 0x00, sizeof(libxl_device_vfb)); |
keir@20542 | 758 memset(vkb, 0x00, sizeof(libxl_device_vkb)); |
keir@20542 | 759 |
keir@20542 | 760 vfb->backend_domid = 0; |
keir@20542 | 761 vfb->devid = 0; |
keir@20542 | 762 vfb->vnc = info->vnc; |
keir@20542 | 763 vfb->vnclisten = info->vnclisten; |
keir@20542 | 764 vfb->vncdisplay = info->vncdisplay; |
keir@20542 | 765 vfb->vncunused = info->vncunused; |
keir@20542 | 766 vfb->keymap = info->keymap; |
keir@20542 | 767 vfb->sdl = info->sdl; |
keir@20542 | 768 vfb->opengl = info->opengl; |
keir@20542 | 769 |
keir@20542 | 770 vkb->backend_domid = 0; |
keir@20542 | 771 vkb->devid = 0; |
keir@20542 | 772 return 0; |
keir@20542 | 773 } |
keir@20542 | 774 |
keir@20542 | 775 static int libxl_write_dmargs(struct libxl_ctx *ctx, int domid, int guest_domid, char **args) |
keir@20542 | 776 { |
keir@20542 | 777 int i; |
keir@20542 | 778 char *vm_path; |
keir@20542 | 779 char *dmargs, *path; |
keir@20542 | 780 int dmargs_size; |
keir@20542 | 781 struct xs_permissions roperm[2]; |
keir@20542 | 782 xs_transaction_t t; |
keir@20542 | 783 |
keir@20542 | 784 roperm[0].id = 0; |
keir@20542 | 785 roperm[0].perms = XS_PERM_NONE; |
keir@20542 | 786 roperm[1].id = domid; |
keir@20542 | 787 roperm[1].perms = XS_PERM_READ; |
keir@20542 | 788 |
keir@20542 | 789 vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/vm", guest_domid)); |
keir@20542 | 790 |
keir@20542 | 791 i = 0; |
keir@20542 | 792 dmargs_size = 0; |
keir@20542 | 793 while (args[i] != NULL) { |
keir@20542 | 794 dmargs_size = dmargs_size + strlen(args[i]) + 1; |
keir@20542 | 795 i++; |
keir@20542 | 796 } |
keir@20542 | 797 dmargs_size++; |
keir@20542 | 798 dmargs = (char *) malloc(dmargs_size); |
keir@20542 | 799 i = 1; |
keir@20542 | 800 dmargs[0] = '\0'; |
keir@20542 | 801 while (args[i] != NULL) { |
keir@20542 | 802 if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) { |
keir@20542 | 803 strcat(dmargs, " "); |
keir@20542 | 804 strcat(dmargs, args[i]); |
keir@20542 | 805 } |
keir@20542 | 806 i++; |
keir@20542 | 807 } |
keir@20542 | 808 path = libxl_sprintf(ctx, "%s/image/dmargs", vm_path); |
keir@20542 | 809 |
keir@20542 | 810 retry_transaction: |
keir@20542 | 811 t = xs_transaction_start(ctx->xsh); |
keir@20542 | 812 xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs)); |
keir@20542 | 813 xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); |
keir@20542 | 814 xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm)); |
keir@20542 | 815 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20542 | 816 if (errno == EAGAIN) |
keir@20542 | 817 goto retry_transaction; |
keir@20542 | 818 free(dmargs); |
keir@20542 | 819 return 0; |
keir@20542 | 820 } |
keir@20542 | 821 |
keir@20542 | 822 static int libxl_create_stubdom(struct libxl_ctx *ctx, |
keir@20542 | 823 libxl_device_model_info *info, |
keir@20542 | 824 libxl_device_disk *disks, int num_disks, |
keir@20542 | 825 libxl_device_nic *vifs, int num_vifs, |
keir@20542 | 826 libxl_device_vfb *vfb, |
keir@20542 | 827 libxl_device_vkb *vkb, |
keir@20542 | 828 libxl_device_model_starting **starting_r) |
keir@20542 | 829 { |
keir@20570 | 830 int i, num_console = 1; |
keir@20570 | 831 libxl_device_console *console; |
keir@20542 | 832 libxl_domain_create_info c_info; |
keir@20542 | 833 libxl_domain_build_info b_info; |
keir@20542 | 834 libxl_domain_build_state state; |
keir@20542 | 835 uint32_t domid; |
keir@20542 | 836 char **args; |
keir@20542 | 837 xen_uuid_t uuid[16]; |
keir@20542 | 838 struct xs_permissions perm[2]; |
keir@20542 | 839 xs_transaction_t t; |
keir@20594 | 840 libxl_device_model_starting *dm_starting = 0; |
keir@20542 | 841 |
keir@20542 | 842 args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); |
keir@20542 | 843 if (!args) |
keir@20542 | 844 return ERROR_FAIL; |
keir@20542 | 845 |
keir@20542 | 846 memset(&c_info, 0x00, sizeof(libxl_domain_create_info)); |
keir@20542 | 847 c_info.hvm = 0; |
keir@20542 | 848 c_info.name = libxl_sprintf(ctx, "%s-dm", libxl_domid_to_name(ctx, info->domid)); |
keir@20542 | 849 xen_uuid_generate(uuid); |
keir@20542 | 850 c_info.uuid = uuid; |
keir@20542 | 851 |
keir@20542 | 852 memset(&b_info, 0x00, sizeof(libxl_domain_build_info)); |
keir@20542 | 853 b_info.max_vcpus = 1; |
keir@20542 | 854 b_info.max_memkb = 32 * 1024; |
keir@20542 | 855 b_info.kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"; |
keir@20542 | 856 b_info.u.pv.cmdline = libxl_sprintf(ctx, " -d %d", info->domid); |
keir@20542 | 857 b_info.u.pv.ramdisk = ""; |
keir@20542 | 858 b_info.u.pv.features = ""; |
keir@20542 | 859 b_info.hvm = 0; |
keir@20542 | 860 |
keir@20542 | 861 libxl_domain_make(ctx, &c_info, &domid); |
keir@20542 | 862 libxl_domain_build(ctx, &b_info, domid, &state); |
keir@20542 | 863 |
keir@20542 | 864 libxl_write_dmargs(ctx, domid, info->domid, args); |
keir@20542 | 865 libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, info->domid)), "%d", domid); |
keir@20542 | 866 libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid)), "%d", info->domid); |
keir@20542 | 867 xc_domain_set_target(ctx->xch, domid, info->domid); |
keir@20542 | 868 xs_set_target(ctx->xsh, domid, info->domid); |
keir@20542 | 869 |
keir@20542 | 870 perm[0].id = domid; |
keir@20542 | 871 perm[0].perms = XS_PERM_NONE; |
keir@20542 | 872 perm[1].id = info->domid; |
keir@20542 | 873 perm[1].perms = XS_PERM_READ; |
keir@20542 | 874 retry_transaction: |
keir@20542 | 875 t = xs_transaction_start(ctx->xsh); |
keir@20542 | 876 xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid)); |
keir@20542 | 877 xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm)); |
keir@20542 | 878 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20542 | 879 if (errno == EAGAIN) |
keir@20542 | 880 goto retry_transaction; |
keir@20542 | 881 |
keir@20542 | 882 for (i = 0; i < num_disks; i++) { |
keir@20542 | 883 libxl_device_disk disk = disks[i]; |
keir@20542 | 884 disk_info_domid_fixup(&disk, domid); |
keir@20542 | 885 libxl_device_disk_add(ctx, domid, &disk); |
keir@20542 | 886 } |
keir@20542 | 887 for (i = 0; i < num_vifs; i++) { |
keir@20542 | 888 libxl_device_nic nic = vifs[i]; |
keir@20542 | 889 nic_info_domid_fixup(&nic, domid); |
keir@20542 | 890 libxl_device_nic_add(ctx, domid, &nic); |
keir@20542 | 891 } |
keir@20542 | 892 vfb_info_domid_fixup(vfb, domid); |
keir@20542 | 893 libxl_device_vfb_add(ctx, domid, vfb); |
keir@20542 | 894 vkb_info_domid_fixup(vkb, domid); |
keir@20542 | 895 libxl_device_vkb_add(ctx, domid, vkb); |
keir@20542 | 896 |
keir@20570 | 897 if (info->serial) |
keir@20570 | 898 num_console++; |
keir@20570 | 899 console = libxl_calloc(ctx, num_console, sizeof(libxl_device_console)); |
keir@20570 | 900 for (i = 0; i < num_console; i++) { |
keir@20570 | 901 if (!i) |
keir@20570 | 902 init_console_info(&console[i], i, &state); |
keir@20570 | 903 else |
keir@20570 | 904 init_console_info(&console[i], i, NULL); |
keir@20570 | 905 console_info_domid_fixup(&console[i], domid); |
keir@20570 | 906 console[i].constype = CONSTYPE_IOEMU; |
keir@20570 | 907 libxl_device_console_add(ctx, domid, &console[i]); |
keir@20570 | 908 } |
keir@20594 | 909 if (libxl_create_xenpv_qemu(ctx, vfb, num_console, console, &dm_starting) < 0) { |
keir@20594 | 910 free(args); |
keir@20594 | 911 return -1; |
keir@20594 | 912 } |
keir@20594 | 913 if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { |
keir@20594 | 914 free(args); |
keir@20594 | 915 return -1; |
keir@20594 | 916 } |
keir@20542 | 917 |
keir@20542 | 918 libxl_domain_unpause(ctx, domid); |
keir@20542 | 919 |
keir@20594 | 920 if (starting_r) { |
keir@20594 | 921 *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 1); |
keir@20598 | 922 (*starting_r)->domid = info->domid; |
keir@20594 | 923 (*starting_r)->dom_path = libxl_xs_get_dompath(ctx, info->domid); |
keir@20594 | 924 (*starting_r)->for_spawn = NULL; |
keir@20594 | 925 } |
keir@20594 | 926 |
keir@20542 | 927 free(args); |
keir@20542 | 928 return 0; |
keir@20542 | 929 } |
keir@20542 | 930 |
keir@20462 | 931 int libxl_create_device_model(struct libxl_ctx *ctx, |
keir@20462 | 932 libxl_device_model_info *info, |
keir@20542 | 933 libxl_device_disk *disks, int num_disks, |
keir@20514 | 934 libxl_device_nic *vifs, int num_vifs, |
keir@20514 | 935 libxl_device_model_starting **starting_r) |
keir@20462 | 936 { |
keir@20546 | 937 char *path, *logfile; |
keir@20514 | 938 int logfile_w, null; |
keir@20546 | 939 int rc; |
keir@20462 | 940 char **args; |
keir@20594 | 941 struct libxl_device_model_starting buf_starting, *p; |
keir@20514 | 942 |
keir@20542 | 943 if (strstr(info->device_model, "stubdom-dm")) { |
keir@20542 | 944 libxl_device_vfb vfb; |
keir@20542 | 945 libxl_device_vkb vkb; |
keir@20542 | 946 |
keir@20542 | 947 libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb); |
keir@20542 | 948 return libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r); |
keir@20542 | 949 } |
keir@20542 | 950 |
keir@20462 | 951 args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); |
keir@20462 | 952 if (!args) |
keir@20462 | 953 return ERROR_FAIL; |
keir@20462 | 954 |
keir@20462 | 955 path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid); |
keir@20462 | 956 xs_mkdir(ctx->xsh, XBT_NULL, path); |
keir@20462 | 957 |
keir@20546 | 958 libxl_create_logfile(ctx, libxl_sprintf(ctx, "qemu-dm-%s", info->dom_name), &logfile); |
keir@20467 | 959 logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); |
keir@20546 | 960 free(logfile); |
keir@20462 | 961 null = open("/dev/null", O_RDONLY); |
keir@20514 | 962 |
keir@20514 | 963 if (starting_r) { |
keir@20516 | 964 rc = ERROR_NOMEM; |
keir@20594 | 965 *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 1); |
keir@20516 | 966 if (!*starting_r) goto xit; |
keir@20594 | 967 p = *starting_r; |
keir@20611 | 968 p->for_spawn = libxl_calloc(ctx, sizeof(struct libxl_spawn_starting), 1); |
keir@20594 | 969 } else { |
keir@20594 | 970 p = &buf_starting; |
keir@20594 | 971 p->for_spawn = NULL; |
keir@20594 | 972 } |
keir@20514 | 973 |
keir@20594 | 974 p->domid = info->domid; |
keir@20594 | 975 p->dom_path = libxl_xs_get_dompath(ctx, info->domid); |
keir@20594 | 976 if (!p->dom_path) { libxl_free(ctx, p); return ERROR_FAIL; } |
keir@20594 | 977 |
keir@20594 | 978 rc = libxl_spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid); |
keir@20514 | 979 if (rc < 0) goto xit; |
keir@20514 | 980 if (!rc) { /* inner child */ |
keir@20514 | 981 libxl_exec(ctx, null, logfile_w, logfile_w, |
keir@20514 | 982 info->device_model, args); |
keir@20514 | 983 } |
keir@20514 | 984 |
keir@20514 | 985 rc = 0; |
keir@20514 | 986 xit: |
keir@20516 | 987 free(args); |
keir@20462 | 988 close(null); |
keir@20462 | 989 close(logfile_w); |
keir@20462 | 990 |
keir@20514 | 991 return rc; |
keir@20514 | 992 } |
keir@20514 | 993 |
keir@20514 | 994 int libxl_detach_device_model(struct libxl_ctx *ctx, |
keir@20514 | 995 libxl_device_model_starting *starting) { |
keir@20514 | 996 int rc; |
keir@20594 | 997 rc = libxl_spawn_detach(ctx, starting->for_spawn); |
keir@20594 | 998 if (starting->for_spawn) libxl_free(ctx, starting->for_spawn); |
keir@20514 | 999 libxl_free(ctx, starting); |
keir@20514 | 1000 return rc; |
keir@20514 | 1001 } |
keir@20462 | 1002 |
keir@20514 | 1003 |
keir@20514 | 1004 int libxl_confirm_device_model_startup(struct libxl_ctx *ctx, |
keir@20514 | 1005 libxl_device_model_starting *starting) { |
keir@20514 | 1006 int problem = libxl_wait_for_device_model(ctx, starting->domid, "running", |
keir@20514 | 1007 libxl_spawn_check, |
keir@20594 | 1008 starting->for_spawn); |
keir@20514 | 1009 int detach = libxl_detach_device_model(ctx, starting); |
keir@20514 | 1010 return problem ? problem : detach; |
keir@20542 | 1011 return 0; |
keir@20462 | 1012 } |
keir@20462 | 1013 |
keir@20514 | 1014 |
keir@20462 | 1015 /******************************************************************************/ |
keir@20566 | 1016 |
keir@20566 | 1017 static int is_blktap2_supported(void) |
keir@20566 | 1018 { |
keir@20566 | 1019 char buf[1024]; |
keir@20566 | 1020 FILE *f = fopen("/proc/devices", "r"); |
keir@20566 | 1021 |
keir@20566 | 1022 |
keir@20566 | 1023 while (fgets(buf, sizeof(buf), f) != NULL) { |
keir@20566 | 1024 if (strstr(buf, "blktap2")) { |
keir@20566 | 1025 fclose(f); |
keir@20566 | 1026 return 1; |
keir@20566 | 1027 } |
keir@20566 | 1028 } |
keir@20566 | 1029 fclose(f); |
keir@20566 | 1030 return 0; |
keir@20566 | 1031 } |
keir@20566 | 1032 |
keir@20566 | 1033 static char *get_blktap2_device(struct libxl_ctx *ctx, char *name, char *type) |
keir@20566 | 1034 { |
keir@20566 | 1035 char buf[1024]; |
keir@20566 | 1036 char *p; |
keir@20566 | 1037 int devnum; |
keir@20566 | 1038 FILE *f = fopen("/sys/class/blktap2/devices", "r"); |
keir@20566 | 1039 |
keir@20566 | 1040 |
keir@20566 | 1041 while (!feof(f)) { |
keir@20566 | 1042 fscanf(f, "%d %s", &devnum, buf); |
keir@20566 | 1043 p = strchr(buf, ':'); |
keir@20571 | 1044 if (p == NULL) |
keir@20571 | 1045 continue; |
keir@20566 | 1046 p++; |
keir@20566 | 1047 if (!strcmp(p, name) && !strncmp(buf, type, 3)) { |
keir@20566 | 1048 fclose(f); |
keir@20566 | 1049 return libxl_sprintf(ctx, "/dev/xen/blktap-2/tapdev%d", devnum); |
keir@20566 | 1050 } |
keir@20566 | 1051 } |
keir@20566 | 1052 fclose(f); |
keir@20566 | 1053 return NULL; |
keir@20566 | 1054 } |
keir@20566 | 1055 |
keir@20462 | 1056 int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) |
keir@20462 | 1057 { |
keir@20462 | 1058 flexarray_t *front; |
keir@20462 | 1059 flexarray_t *back; |
keir@20462 | 1060 char *backend_type; |
keir@20462 | 1061 unsigned int boffset = 0; |
keir@20462 | 1062 unsigned int foffset = 0; |
keir@20462 | 1063 int devid; |
keir@20462 | 1064 libxl_device device; |
keir@20566 | 1065 int major, minor; |
keir@20462 | 1066 |
keir@20462 | 1067 front = flexarray_make(16, 1); |
keir@20462 | 1068 if (!front) |
keir@20462 | 1069 return ERROR_NOMEM; |
keir@20462 | 1070 back = flexarray_make(16, 1); |
keir@20462 | 1071 if (!back) /* leaks front if error */ |
keir@20462 | 1072 return ERROR_NOMEM; |
keir@20462 | 1073 |
keir@20462 | 1074 backend_type = device_disk_backend_type_of_phystype(disk->phystype); |
keir@20462 | 1075 devid = device_disk_dev_number(disk->virtpath); |
keir@20462 | 1076 |
keir@20462 | 1077 device.backend_devid = devid; |
keir@20462 | 1078 device.backend_domid = disk->backend_domid; |
keir@20462 | 1079 device.devid = devid; |
keir@20462 | 1080 device.domid = disk->domid; |
keir@20462 | 1081 device.kind = DEVICE_VBD; |
keir@20462 | 1082 |
keir@20462 | 1083 switch (disk->phystype) { |
keir@20462 | 1084 case PHYSTYPE_PHY: { |
keir@20462 | 1085 |
keir@20509 | 1086 device_physdisk_major_minor(disk->physpath, &major, &minor); |
keir@20516 | 1087 flexarray_set(back, boffset++, "physical-device"); |
keir@20462 | 1088 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); |
keir@20462 | 1089 |
keir@20516 | 1090 flexarray_set(back, boffset++, "params"); |
keir@20516 | 1091 flexarray_set(back, boffset++, disk->physpath); |
keir@20462 | 1092 |
keir@20462 | 1093 device.backend_kind = DEVICE_VBD; |
keir@20462 | 1094 break; |
keir@20462 | 1095 } |
keir@20566 | 1096 case PHYSTYPE_FILE: |
keir@20566 | 1097 /* let's pretend is tap:aio for the moment */ |
keir@20566 | 1098 disk->phystype = PHYSTYPE_AIO; |
keir@20462 | 1099 case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case PHYSTYPE_VHD: |
keir@20566 | 1100 if (is_blktap2_supported()) { |
keir@20566 | 1101 int rc, c, p[2], tot; |
keir@20566 | 1102 char buf[1024], *dev; |
keir@20566 | 1103 if ((dev = get_blktap2_device(ctx, disk->physpath, device_disk_string_of_phystype(disk->phystype))) == NULL) { |
keir@20566 | 1104 if (pipe(p) < 0) { |
keir@20566 | 1105 XL_LOG(ctx, XL_LOG_ERROR, "Failed to create a pipe"); |
keir@20566 | 1106 return -1; |
keir@20566 | 1107 } |
keir@20566 | 1108 rc = fork(); |
keir@20566 | 1109 if (rc < 0) { |
keir@20566 | 1110 XL_LOG(ctx, XL_LOG_ERROR, "Failed to fork a new process"); |
keir@20566 | 1111 return -1; |
keir@20566 | 1112 } else if (!rc) { /* child */ |
keir@20566 | 1113 int null_r, null_w; |
keir@20566 | 1114 char *args[4]; |
keir@20566 | 1115 args[0] = "tapdisk2"; |
keir@20566 | 1116 args[1] = "-n"; |
keir@20566 | 1117 args[2] = libxl_sprintf(ctx, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath); |
keir@20566 | 1118 args[3] = NULL; |
keir@20566 | 1119 |
keir@20566 | 1120 null_r = open("/dev/null", O_RDONLY); |
keir@20566 | 1121 null_w = open("/dev/null", O_WRONLY); |
keir@20566 | 1122 libxl_exec(ctx, null_r, p[1], null_w, "/usr/sbin/tapdisk2", args); |
keir@20566 | 1123 XL_LOG(ctx, XL_LOG_ERROR, "Error execing tapdisk2"); |
keir@20566 | 1124 } |
keir@20566 | 1125 close(p[1]); |
keir@20566 | 1126 tot = 0; |
keir@20566 | 1127 while ((c = read(p[0], buf + tot, sizeof(buf) - tot)) > 0) |
keir@20566 | 1128 tot = tot + c; |
keir@20566 | 1129 close(p[0]); |
keir@20566 | 1130 buf[tot - 1] = '\0'; |
keir@20566 | 1131 dev = buf; |
keir@20566 | 1132 } |
keir@20566 | 1133 flexarray_set(back, boffset++, "tapdisk-params"); |
keir@20566 | 1134 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); |
keir@20566 | 1135 flexarray_set(back, boffset++, "params"); |
keir@20566 | 1136 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", dev)); |
keir@20566 | 1137 backend_type = "phy"; |
keir@20566 | 1138 device_physdisk_major_minor(dev, &major, &minor); |
keir@20566 | 1139 flexarray_set(back, boffset++, "physical-device"); |
keir@20566 | 1140 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); |
keir@20566 | 1141 device.backend_kind = DEVICE_VBD; |
keir@20566 | 1142 |
keir@20566 | 1143 break; |
keir@20566 | 1144 } |
keir@20516 | 1145 flexarray_set(back, boffset++, "params"); |
keir@20462 | 1146 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", |
keir@20462 | 1147 device_disk_string_of_phystype(disk->phystype), disk->physpath)); |
keir@20462 | 1148 |
keir@20462 | 1149 device.backend_kind = DEVICE_TAP; |
keir@20462 | 1150 break; |
keir@20462 | 1151 } |
keir@20462 | 1152 |
keir@20516 | 1153 flexarray_set(back, boffset++, "frontend-id"); |
keir@20462 | 1154 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid)); |
keir@20516 | 1155 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1156 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1157 flexarray_set(back, boffset++, "removable"); |
keir@20462 | 1158 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0)); |
keir@20516 | 1159 flexarray_set(back, boffset++, "bootable"); |
keir@20509 | 1160 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1161 flexarray_set(back, boffset++, "state"); |
keir@20462 | 1162 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1163 flexarray_set(back, boffset++, "dev"); |
keir@20516 | 1164 flexarray_set(back, boffset++, disk->virtpath); |
keir@20516 | 1165 flexarray_set(back, boffset++, "type"); |
keir@20516 | 1166 flexarray_set(back, boffset++, backend_type); |
keir@20516 | 1167 flexarray_set(back, boffset++, "mode"); |
keir@20516 | 1168 flexarray_set(back, boffset++, disk->readwrite ? "w" : "r"); |
keir@20462 | 1169 |
keir@20516 | 1170 flexarray_set(front, foffset++, "backend-id"); |
keir@20462 | 1171 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid)); |
keir@20516 | 1172 flexarray_set(front, foffset++, "state"); |
keir@20462 | 1173 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1174 flexarray_set(front, foffset++, "virtual-device"); |
keir@20462 | 1175 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid)); |
keir@20516 | 1176 flexarray_set(front, foffset++, "device-type"); |
keir@20516 | 1177 flexarray_set(front, foffset++, disk->is_cdrom ? "cdrom" : "disk"); |
keir@20462 | 1178 |
keir@20462 | 1179 if (0 /* protocol != native*/) { |
keir@20516 | 1180 flexarray_set(front, foffset++, "protocol"); |
keir@20516 | 1181 flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */ |
keir@20462 | 1182 } |
keir@20462 | 1183 |
keir@20462 | 1184 libxl_device_generic_add(ctx, &device, |
keir@20462 | 1185 libxl_xs_kvs_of_flexarray(ctx, back, boffset), |
keir@20462 | 1186 libxl_xs_kvs_of_flexarray(ctx, front, foffset)); |
keir@20516 | 1187 flexarray_free(back); |
keir@20516 | 1188 flexarray_free(front); |
keir@20462 | 1189 return 0; |
keir@20462 | 1190 } |
keir@20462 | 1191 |
keir@20626 | 1192 int libxl_device_disk_del(struct libxl_ctx *ctx, |
keir@20626 | 1193 libxl_device_disk *disk, int wait) |
keir@20462 | 1194 { |
keir@20626 | 1195 libxl_device device; |
keir@20626 | 1196 int devid; |
keir@20462 | 1197 |
keir@20626 | 1198 devid = device_disk_dev_number(disk->virtpath); |
keir@20626 | 1199 device.backend_domid = disk->backend_domid; |
keir@20626 | 1200 device.backend_devid = devid; |
keir@20626 | 1201 device.backend_kind = |
keir@20626 | 1202 (disk->phystype == PHYSTYPE_PHY) ? DEVICE_VBD : DEVICE_TAP; |
keir@20626 | 1203 device.domid = disk->domid; |
keir@20626 | 1204 device.devid = devid; |
keir@20626 | 1205 device.kind = DEVICE_VBD; |
keir@20626 | 1206 return libxl_device_del(ctx, &device, wait); |
keir@20462 | 1207 } |
keir@20462 | 1208 |
keir@20462 | 1209 /******************************************************************************/ |
keir@20462 | 1210 int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) |
keir@20462 | 1211 { |
keir@20462 | 1212 flexarray_t *front; |
keir@20462 | 1213 flexarray_t *back; |
keir@20462 | 1214 unsigned int boffset = 0; |
keir@20462 | 1215 unsigned int foffset = 0; |
keir@20462 | 1216 libxl_device device; |
keir@20462 | 1217 |
keir@20462 | 1218 front = flexarray_make(16, 1); |
keir@20462 | 1219 if (!front) |
keir@20462 | 1220 return ERROR_NOMEM; |
keir@20462 | 1221 back = flexarray_make(16, 1); |
keir@20462 | 1222 if (!back) |
keir@20462 | 1223 return ERROR_NOMEM; |
keir@20462 | 1224 |
keir@20462 | 1225 device.backend_devid = nic->devid; |
keir@20462 | 1226 device.backend_domid = nic->backend_domid; |
keir@20462 | 1227 device.backend_kind = DEVICE_VIF; |
keir@20462 | 1228 device.devid = nic->devid; |
keir@20462 | 1229 device.domid = nic->domid; |
keir@20462 | 1230 device.kind = DEVICE_VIF; |
keir@20462 | 1231 |
keir@20516 | 1232 flexarray_set(back, boffset++, "frontend-id"); |
keir@20462 | 1233 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid)); |
keir@20516 | 1234 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1235 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1236 flexarray_set(back, boffset++, "state"); |
keir@20462 | 1237 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1238 flexarray_set(back, boffset++, "script"); |
keir@20516 | 1239 flexarray_set(back, boffset++, nic->script); |
keir@20516 | 1240 flexarray_set(back, boffset++, "mac"); |
keir@20462 | 1241 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@20462 | 1242 nic->mac[0], nic->mac[1], nic->mac[2], |
keir@20462 | 1243 nic->mac[3], nic->mac[4], nic->mac[5])); |
keir@20516 | 1244 flexarray_set(back, boffset++, "handle"); |
keir@20462 | 1245 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid)); |
keir@20462 | 1246 |
keir@20516 | 1247 flexarray_set(front, foffset++, "backend-id"); |
keir@20462 | 1248 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid)); |
keir@20516 | 1249 flexarray_set(front, foffset++, "state"); |
keir@20462 | 1250 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1251 flexarray_set(front, foffset++, "handle"); |
keir@20462 | 1252 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid)); |
keir@20516 | 1253 flexarray_set(front, foffset++, "mac"); |
keir@20462 | 1254 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@20462 | 1255 nic->mac[0], nic->mac[1], nic->mac[2], |
keir@20462 | 1256 nic->mac[3], nic->mac[4], nic->mac[5])); |
keir@20462 | 1257 if (0 /* protocol != native*/) { |
keir@20516 | 1258 flexarray_set(front, foffset++, "protocol"); |
keir@20516 | 1259 flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */ |
keir@20462 | 1260 } |
keir@20462 | 1261 |
keir@20462 | 1262 libxl_device_generic_add(ctx, &device, |
keir@20462 | 1263 libxl_xs_kvs_of_flexarray(ctx, back, boffset), |
keir@20462 | 1264 libxl_xs_kvs_of_flexarray(ctx, front, foffset)); |
keir@20462 | 1265 |
keir@20462 | 1266 /* FIXME: wait for plug */ |
keir@20516 | 1267 flexarray_free(back); |
keir@20516 | 1268 flexarray_free(front); |
keir@20462 | 1269 return 0; |
keir@20462 | 1270 } |
keir@20462 | 1271 |
keir@20626 | 1272 int libxl_device_nic_del(struct libxl_ctx *ctx, |
keir@20626 | 1273 libxl_device_nic *nic, int wait) |
keir@20462 | 1274 { |
keir@20626 | 1275 libxl_device device; |
keir@20462 | 1276 |
keir@20626 | 1277 device.backend_devid = nic->devid; |
keir@20626 | 1278 device.backend_domid = nic->backend_domid; |
keir@20626 | 1279 device.backend_kind = DEVICE_VIF; |
keir@20626 | 1280 device.devid = nic->devid; |
keir@20626 | 1281 device.domid = nic->domid; |
keir@20626 | 1282 device.kind = DEVICE_VIF; |
keir@20626 | 1283 |
keir@20626 | 1284 return libxl_device_del(ctx, &device, wait); |
keir@20462 | 1285 } |
keir@20462 | 1286 |
keir@20462 | 1287 /******************************************************************************/ |
keir@20509 | 1288 int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_console *console) |
keir@20462 | 1289 { |
keir@20509 | 1290 flexarray_t *front; |
keir@20509 | 1291 flexarray_t *back; |
keir@20509 | 1292 unsigned int boffset = 0; |
keir@20509 | 1293 unsigned int foffset = 0; |
keir@20509 | 1294 libxl_device device; |
keir@20509 | 1295 |
keir@20509 | 1296 if (console->build_state) { |
keir@20509 | 1297 xs_transaction_t t; |
keir@20509 | 1298 char **ents = (char **) libxl_calloc(ctx, 9, sizeof(char *)); |
keir@20516 | 1299 ents[0] = "console/port"; |
keir@20509 | 1300 ents[1] = libxl_sprintf(ctx, "%"PRIu32, console->build_state->console_port); |
keir@20516 | 1301 ents[2] = "console/ring-ref"; |
keir@20509 | 1302 ents[3] = libxl_sprintf(ctx, "%lu", console->build_state->console_mfn); |
keir@20516 | 1303 ents[4] = "console/limit"; |
keir@20509 | 1304 ents[5] = libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT); |
keir@20516 | 1305 ents[6] = "console/type"; |
keir@20509 | 1306 if (console->constype == CONSTYPE_XENCONSOLED) |
keir@20509 | 1307 ents[7] = "xenconsoled"; |
keir@20509 | 1308 else |
keir@20509 | 1309 ents[7] = "ioemu"; |
keir@20509 | 1310 retry_transaction: |
keir@20509 | 1311 t = xs_transaction_start(ctx->xsh); |
keir@20516 | 1312 libxl_xs_writev(ctx, t, libxl_xs_get_dompath(ctx, console->domid), ents); |
keir@20509 | 1313 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20509 | 1314 if (errno == EAGAIN) |
keir@20509 | 1315 goto retry_transaction; |
keir@20509 | 1316 } |
keir@20509 | 1317 |
keir@20509 | 1318 front = flexarray_make(16, 1); |
keir@20509 | 1319 if (!front) |
keir@20509 | 1320 return ERROR_NOMEM; |
keir@20509 | 1321 back = flexarray_make(16, 1); |
keir@20509 | 1322 if (!back) |
keir@20509 | 1323 return ERROR_NOMEM; |
keir@20509 | 1324 |
keir@20509 | 1325 device.backend_devid = console->devid; |
keir@20509 | 1326 device.backend_domid = console->backend_domid; |
keir@20509 | 1327 device.backend_kind = DEVICE_CONSOLE; |
keir@20509 | 1328 device.devid = console->devid; |
keir@20509 | 1329 device.domid = console->domid; |
keir@20509 | 1330 device.kind = DEVICE_CONSOLE; |
keir@20509 | 1331 |
keir@20516 | 1332 flexarray_set(back, boffset++, "frontend-id"); |
keir@20509 | 1333 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", console->domid)); |
keir@20516 | 1334 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1335 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1336 flexarray_set(back, boffset++, "state"); |
keir@20509 | 1337 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1338 flexarray_set(back, boffset++, "domain"); |
keir@20516 | 1339 flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid)); |
keir@20516 | 1340 flexarray_set(back, boffset++, "protocol"); |
keir@20516 | 1341 flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL); |
keir@20509 | 1342 |
keir@20516 | 1343 flexarray_set(front, foffset++, "backend-id"); |
keir@20509 | 1344 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", console->backend_domid)); |
keir@20516 | 1345 flexarray_set(front, foffset++, "state"); |
keir@20509 | 1346 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1347 flexarray_set(front, foffset++, "limit"); |
keir@20509 | 1348 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT)); |
keir@20516 | 1349 flexarray_set(front, foffset++, "protocol"); |
keir@20516 | 1350 flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL); |
keir@20516 | 1351 flexarray_set(front, foffset++, "type"); |
keir@20509 | 1352 if (console->constype == CONSTYPE_XENCONSOLED) |
keir@20516 | 1353 flexarray_set(front, foffset++, "xenconsoled"); |
keir@20509 | 1354 else |
keir@20516 | 1355 flexarray_set(front, foffset++, "ioemu"); |
keir@20509 | 1356 |
keir@20509 | 1357 libxl_device_generic_add(ctx, &device, |
keir@20509 | 1358 libxl_xs_kvs_of_flexarray(ctx, back, boffset), |
keir@20509 | 1359 libxl_xs_kvs_of_flexarray(ctx, front, foffset)); |
keir@20516 | 1360 flexarray_free(back); |
keir@20516 | 1361 flexarray_free(front); |
keir@20509 | 1362 |
keir@20509 | 1363 return 0; |
keir@20509 | 1364 } |
keir@20509 | 1365 |
keir@20509 | 1366 /******************************************************************************/ |
keir@20509 | 1367 int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) |
keir@20509 | 1368 { |
keir@20509 | 1369 flexarray_t *front; |
keir@20509 | 1370 flexarray_t *back; |
keir@20509 | 1371 unsigned int boffset = 0; |
keir@20509 | 1372 unsigned int foffset = 0; |
keir@20509 | 1373 libxl_device device; |
keir@20509 | 1374 |
keir@20509 | 1375 front = flexarray_make(16, 1); |
keir@20509 | 1376 if (!front) |
keir@20509 | 1377 return ERROR_NOMEM; |
keir@20509 | 1378 back = flexarray_make(16, 1); |
keir@20509 | 1379 if (!back) |
keir@20509 | 1380 return ERROR_NOMEM; |
keir@20509 | 1381 |
keir@20509 | 1382 device.backend_devid = vkb->devid; |
keir@20509 | 1383 device.backend_domid = vkb->backend_domid; |
keir@20509 | 1384 device.backend_kind = DEVICE_VKBD; |
keir@20509 | 1385 device.devid = vkb->devid; |
keir@20509 | 1386 device.domid = vkb->domid; |
keir@20509 | 1387 device.kind = DEVICE_VKBD; |
keir@20509 | 1388 |
keir@20516 | 1389 flexarray_set(back, boffset++, "frontend-id"); |
keir@20509 | 1390 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vkb->domid)); |
keir@20516 | 1391 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1392 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1393 flexarray_set(back, boffset++, "state"); |
keir@20509 | 1394 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1395 flexarray_set(back, boffset++, "domain"); |
keir@20516 | 1396 flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid)); |
keir@20509 | 1397 |
keir@20516 | 1398 flexarray_set(front, foffset++, "backend-id"); |
keir@20509 | 1399 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vkb->backend_domid)); |
keir@20516 | 1400 flexarray_set(front, foffset++, "state"); |
keir@20509 | 1401 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20509 | 1402 |
keir@20509 | 1403 libxl_device_generic_add(ctx, &device, |
keir@20509 | 1404 libxl_xs_kvs_of_flexarray(ctx, back, boffset), |
keir@20509 | 1405 libxl_xs_kvs_of_flexarray(ctx, front, foffset)); |
keir@20516 | 1406 flexarray_free(back); |
keir@20516 | 1407 flexarray_free(front); |
keir@20509 | 1408 |
keir@20509 | 1409 return 0; |
keir@20462 | 1410 } |
keir@20462 | 1411 |
keir@20462 | 1412 int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 1413 { |
keir@20462 | 1414 return ERROR_NI; |
keir@20462 | 1415 } |
keir@20462 | 1416 |
keir@20462 | 1417 int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 1418 { |
keir@20462 | 1419 return ERROR_NI; |
keir@20462 | 1420 } |
keir@20462 | 1421 |
keir@20462 | 1422 /******************************************************************************/ |
keir@20509 | 1423 static int libxl_build_xenpv_qemu_args(struct libxl_ctx *ctx, |
keir@20509 | 1424 libxl_device_vfb *vfb, |
keir@20509 | 1425 int num_console, |
keir@20509 | 1426 libxl_device_console *console, |
keir@20509 | 1427 libxl_device_model_info *info) { |
keir@20509 | 1428 int i = 0, j = 0, num = 0; |
keir@20509 | 1429 memset(info, 0x00, sizeof(libxl_device_model_info)); |
keir@20509 | 1430 |
keir@20509 | 1431 info->vnc = vfb->vnc; |
keir@20509 | 1432 if (vfb->vnclisten) |
keir@20509 | 1433 info->vnclisten = libxl_sprintf(ctx, "%s", vfb->vnclisten); |
keir@20509 | 1434 info->vncdisplay = vfb->vncdisplay; |
keir@20509 | 1435 info->vncunused = vfb->vncunused; |
keir@20509 | 1436 if (vfb->keymap) |
keir@20509 | 1437 info->keymap = libxl_sprintf(ctx, "%s", vfb->keymap); |
keir@20509 | 1438 info->sdl = vfb->sdl; |
keir@20509 | 1439 info->opengl = vfb->opengl; |
keir@20509 | 1440 for (i = 0; i < num_console; i++) { |
keir@20509 | 1441 if (console->constype == CONSTYPE_IOEMU) |
keir@20509 | 1442 num++; |
keir@20509 | 1443 } |
keir@20509 | 1444 if (num > 0) { |
keir@20599 | 1445 uint32_t guest_domid = libxl_is_stubdom(ctx, vfb->domid); |
keir@20599 | 1446 if (guest_domid) { |
keir@20599 | 1447 char *filename; |
keir@20599 | 1448 char *name = libxl_sprintf(ctx, "qemu-dm-%s", libxl_domid_to_name(ctx, guest_domid)); |
keir@20599 | 1449 libxl_create_logfile(ctx, name, &filename); |
keir@20599 | 1450 info->serial = libxl_sprintf(ctx, "file:%s", filename); |
keir@20599 | 1451 free(filename); |
keir@20599 | 1452 } else { |
keir@20599 | 1453 info->serial = "pty"; |
keir@20599 | 1454 } |
keir@20509 | 1455 num--; |
keir@20509 | 1456 } |
keir@20509 | 1457 if (num > 0) { |
keir@20509 | 1458 info->extra = (char **) libxl_calloc(ctx, num * 2 + 1, sizeof(char *)); |
keir@20509 | 1459 for (j = 0; j < num * 2; j = j + 2) { |
keir@20509 | 1460 info->extra[j] = "-serial"; |
keir@20509 | 1461 info->extra[j + 1] = "pty"; |
keir@20509 | 1462 } |
keir@20509 | 1463 info->extra[j] = NULL; |
keir@20509 | 1464 } |
keir@20509 | 1465 info->domid = vfb->domid; |
keir@20509 | 1466 info->dom_name = libxl_domid_to_name(ctx, vfb->domid); |
keir@20509 | 1467 info->device_model = "/usr/lib/xen/bin/qemu-dm"; |
keir@20509 | 1468 info->type = XENPV; |
keir@20509 | 1469 return 0; |
keir@20509 | 1470 } |
keir@20509 | 1471 |
keir@20509 | 1472 int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb, |
keir@20514 | 1473 int num_console, libxl_device_console *console, |
keir@20514 | 1474 struct libxl_device_model_starting **starting_r) |
keir@20509 | 1475 { |
keir@20509 | 1476 libxl_device_model_info info; |
keir@20509 | 1477 |
keir@20509 | 1478 libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info); |
keir@20542 | 1479 libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); |
keir@20509 | 1480 return 0; |
keir@20509 | 1481 } |
keir@20509 | 1482 |
keir@20509 | 1483 int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) |
keir@20462 | 1484 { |
keir@20509 | 1485 flexarray_t *front; |
keir@20509 | 1486 flexarray_t *back; |
keir@20509 | 1487 unsigned int boffset = 0; |
keir@20509 | 1488 unsigned int foffset = 0; |
keir@20509 | 1489 libxl_device device; |
keir@20509 | 1490 |
keir@20509 | 1491 front = flexarray_make(16, 1); |
keir@20509 | 1492 if (!front) |
keir@20509 | 1493 return ERROR_NOMEM; |
keir@20509 | 1494 back = flexarray_make(16, 1); |
keir@20509 | 1495 if (!back) |
keir@20509 | 1496 return ERROR_NOMEM; |
keir@20509 | 1497 |
keir@20509 | 1498 device.backend_devid = vfb->devid; |
keir@20509 | 1499 device.backend_domid = vfb->backend_domid; |
keir@20509 | 1500 device.backend_kind = DEVICE_VFB; |
keir@20509 | 1501 device.devid = vfb->devid; |
keir@20509 | 1502 device.domid = vfb->domid; |
keir@20509 | 1503 device.kind = DEVICE_VFB; |
keir@20509 | 1504 |
keir@20516 | 1505 flexarray_set(back, boffset++, "frontend-id"); |
keir@20509 | 1506 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->domid)); |
keir@20516 | 1507 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1508 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1509 flexarray_set(back, boffset++, "state"); |
keir@20509 | 1510 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1511 flexarray_set(back, boffset++, "domain"); |
keir@20516 | 1512 flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid)); |
keir@20516 | 1513 flexarray_set(back, boffset++, "vnc"); |
keir@20509 | 1514 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vnc)); |
keir@20516 | 1515 flexarray_set(back, boffset++, "vnclisten"); |
keir@20516 | 1516 flexarray_set(back, boffset++, vfb->vnclisten); |
keir@20516 | 1517 flexarray_set(back, boffset++, "vncdisplay"); |
keir@20509 | 1518 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncdisplay)); |
keir@20516 | 1519 flexarray_set(back, boffset++, "vncunused"); |
keir@20509 | 1520 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncunused)); |
keir@20516 | 1521 flexarray_set(back, boffset++, "sdl"); |
keir@20509 | 1522 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->sdl)); |
keir@20516 | 1523 flexarray_set(back, boffset++, "opengl"); |
keir@20509 | 1524 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->opengl)); |
keir@20509 | 1525 if (vfb->xauthority) { |
keir@20516 | 1526 flexarray_set(back, boffset++, "xauthority"); |
keir@20516 | 1527 flexarray_set(back, boffset++, vfb->xauthority); |
keir@20509 | 1528 } |
keir@20509 | 1529 if (vfb->display) { |
keir@20516 | 1530 flexarray_set(back, boffset++, "display"); |
keir@20516 | 1531 flexarray_set(back, boffset++, vfb->display); |
keir@20509 | 1532 } |
keir@20509 | 1533 |
keir@20516 | 1534 flexarray_set(front, foffset++, "backend-id"); |
keir@20509 | 1535 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vfb->backend_domid)); |
keir@20516 | 1536 flexarray_set(front, foffset++, "state"); |
keir@20509 | 1537 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20509 | 1538 |
keir@20509 | 1539 libxl_device_generic_add(ctx, &device, |
keir@20509 | 1540 libxl_xs_kvs_of_flexarray(ctx, back, boffset), |
keir@20509 | 1541 libxl_xs_kvs_of_flexarray(ctx, front, foffset)); |
keir@20509 | 1542 flexarray_free(front); |
keir@20509 | 1543 flexarray_free(back); |
keir@20509 | 1544 |
keir@20509 | 1545 return 0; |
keir@20462 | 1546 } |
keir@20462 | 1547 |
keir@20462 | 1548 int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 1549 { |
keir@20462 | 1550 return ERROR_NI; |
keir@20462 | 1551 } |
keir@20462 | 1552 |
keir@20462 | 1553 int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 1554 { |
keir@20462 | 1555 return ERROR_NI; |
keir@20462 | 1556 } |
keir@20462 | 1557 |
keir@20462 | 1558 /******************************************************************************/ |
keir@20482 | 1559 |
keir@20482 | 1560 int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain, |
keir@20482 | 1561 unsigned int bus, unsigned int dev, |
keir@20482 | 1562 unsigned int func, unsigned int vdevfn) |
keir@20482 | 1563 { |
keir@20482 | 1564 pcidev->domain = domain; |
keir@20482 | 1565 pcidev->bus = bus; |
keir@20482 | 1566 pcidev->dev = dev; |
keir@20482 | 1567 pcidev->func = func; |
keir@20482 | 1568 pcidev->vdevfn = vdevfn; |
keir@20482 | 1569 return 0; |
keir@20482 | 1570 } |
keir@20482 | 1571 |
keir@20482 | 1572 static int libxl_create_pci_backend(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev, int num) |
keir@20482 | 1573 { |
keir@20482 | 1574 flexarray_t *front; |
keir@20482 | 1575 flexarray_t *back; |
keir@20482 | 1576 unsigned int boffset = 0; |
keir@20482 | 1577 unsigned int foffset = 0; |
keir@20482 | 1578 libxl_device device; |
keir@20482 | 1579 int i; |
keir@20482 | 1580 |
keir@20482 | 1581 front = flexarray_make(16, 1); |
keir@20482 | 1582 if (!front) |
keir@20482 | 1583 return ERROR_NOMEM; |
keir@20482 | 1584 back = flexarray_make(16, 1); |
keir@20482 | 1585 if (!back) |
keir@20482 | 1586 return ERROR_NOMEM; |
keir@20482 | 1587 |
keir@20512 | 1588 XL_LOG(ctx, XL_LOG_DEBUG, "Creating pci backend"); |
keir@20482 | 1589 |
keir@20482 | 1590 /* add pci device */ |
keir@20482 | 1591 device.backend_devid = 0; |
keir@20482 | 1592 device.backend_domid = 0; |
keir@20482 | 1593 device.backend_kind = DEVICE_PCI; |
keir@20482 | 1594 device.devid = 0; |
keir@20482 | 1595 device.domid = domid; |
keir@20482 | 1596 device.kind = DEVICE_PCI; |
keir@20482 | 1597 |
keir@20516 | 1598 flexarray_set(back, boffset++, "frontend-id"); |
keir@20482 | 1599 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", domid)); |
keir@20516 | 1600 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1601 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1602 flexarray_set(back, boffset++, "state"); |
keir@20482 | 1603 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1604 flexarray_set(back, boffset++, "domain"); |
keir@20516 | 1605 flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid)); |
keir@20482 | 1606 for (i = 0; i < num; i++) { |
keir@20482 | 1607 flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", i)); |
keir@20482 | 1608 flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); |
keir@20482 | 1609 flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", i)); |
keir@20482 | 1610 flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); |
keir@20482 | 1611 if (pcidev->vdevfn) { |
keir@20482 | 1612 flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", i)); |
keir@20482 | 1613 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", pcidev->vdevfn)); |
keir@20482 | 1614 } |
keir@20482 | 1615 flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", i)); |
keir@20482 | 1616 flexarray_set(back, boffset++, libxl_sprintf(ctx, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); |
keir@20482 | 1617 flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", i)); |
keir@20482 | 1618 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20482 | 1619 } |
keir@20516 | 1620 flexarray_set(back, boffset++, "num_devs"); |
keir@20482 | 1621 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num)); |
keir@20482 | 1622 |
keir@20516 | 1623 flexarray_set(front, foffset++, "backend-id"); |
keir@20482 | 1624 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 0)); |
keir@20516 | 1625 flexarray_set(front, foffset++, "state"); |
keir@20482 | 1626 flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20482 | 1627 |
keir@20482 | 1628 libxl_device_generic_add(ctx, &device, |
keir@20482 | 1629 libxl_xs_kvs_of_flexarray(ctx, back, boffset), |
keir@20482 | 1630 libxl_xs_kvs_of_flexarray(ctx, front, foffset)); |
keir@20482 | 1631 |
keir@20482 | 1632 flexarray_free(back); |
keir@20482 | 1633 flexarray_free(front); |
keir@20482 | 1634 return 0; |
keir@20482 | 1635 } |
keir@20482 | 1636 |
keir@20482 | 1637 static int libxl_device_pci_add_xenstore(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) |
keir@20462 | 1638 { |
keir@20482 | 1639 flexarray_t *back; |
keir@20482 | 1640 char *num_devs, *be_path; |
keir@20482 | 1641 int num = 0; |
keir@20482 | 1642 unsigned int boffset = 0; |
keir@20482 | 1643 xs_transaction_t t; |
keir@20482 | 1644 |
keir@20516 | 1645 be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); |
keir@20482 | 1646 num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", be_path)); |
keir@20482 | 1647 if (!num_devs) |
keir@20482 | 1648 return libxl_create_pci_backend(ctx, domid, pcidev, 1); |
keir@20482 | 1649 |
keir@20482 | 1650 if (!is_hvm(ctx, domid)) { |
keir@20482 | 1651 if (libxl_wait_for_backend(ctx, be_path, "4") < 0) |
keir@20482 | 1652 return -1; |
keir@20482 | 1653 } |
keir@20482 | 1654 |
keir@20482 | 1655 back = flexarray_make(16, 1); |
keir@20482 | 1656 if (!back) |
keir@20482 | 1657 return ERROR_NOMEM; |
keir@20482 | 1658 |
keir@20512 | 1659 XL_LOG(ctx, XL_LOG_DEBUG, "Adding new pci device to xenstore"); |
keir@20482 | 1660 num = atoi(num_devs); |
keir@20482 | 1661 flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", num)); |
keir@20482 | 1662 flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); |
keir@20482 | 1663 flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", num)); |
keir@20482 | 1664 flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); |
keir@20482 | 1665 if (pcidev->vdevfn) { |
keir@20482 | 1666 flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", num)); |
keir@20482 | 1667 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", pcidev->vdevfn)); |
keir@20482 | 1668 } |
keir@20482 | 1669 flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", num)); |
keir@20482 | 1670 flexarray_set(back, boffset++, libxl_sprintf(ctx, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); |
keir@20482 | 1671 flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", num)); |
keir@20482 | 1672 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); |
keir@20516 | 1673 flexarray_set(back, boffset++, "num_devs"); |
keir@20482 | 1674 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num + 1)); |
keir@20516 | 1675 flexarray_set(back, boffset++, "state"); |
keir@20482 | 1676 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 7)); |
keir@20482 | 1677 |
keir@20482 | 1678 retry_transaction: |
keir@20482 | 1679 t = xs_transaction_start(ctx->xsh); |
keir@20482 | 1680 libxl_xs_writev(ctx, t, be_path, |
keir@20482 | 1681 libxl_xs_kvs_of_flexarray(ctx, back, boffset)); |
keir@20482 | 1682 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20482 | 1683 if (errno == EAGAIN) |
keir@20482 | 1684 goto retry_transaction; |
keir@20482 | 1685 |
keir@20482 | 1686 flexarray_free(back); |
keir@20482 | 1687 return 0; |
keir@20482 | 1688 } |
keir@20482 | 1689 |
keir@20482 | 1690 static int libxl_device_pci_remove_xenstore(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) |
keir@20482 | 1691 { |
keir@20542 | 1692 char *be_path, *num_devs_path, *num_devs, *xsdev, *tmp, *tmppath; |
keir@20542 | 1693 int num, i, j; |
keir@20482 | 1694 xs_transaction_t t; |
keir@20482 | 1695 unsigned int domain = 0, bus = 0, dev = 0, func = 0; |
keir@20482 | 1696 |
keir@20516 | 1697 be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); |
keir@20482 | 1698 num_devs_path = libxl_sprintf(ctx, "%s/num_devs", be_path); |
keir@20482 | 1699 num_devs = libxl_xs_read(ctx, XBT_NULL, num_devs_path); |
keir@20482 | 1700 if (!num_devs) |
keir@20482 | 1701 return -1; |
keir@20482 | 1702 num = atoi(num_devs); |
keir@20482 | 1703 |
keir@20482 | 1704 if (!is_hvm(ctx, domid)) { |
keir@20482 | 1705 if (libxl_wait_for_backend(ctx, be_path, "4") < 0) { |
keir@20542 | 1706 XL_LOG(ctx, XL_LOG_DEBUG, "pci backend at %s is not ready", be_path); |
keir@20482 | 1707 return -1; |
keir@20482 | 1708 } |
keir@20482 | 1709 } |
keir@20482 | 1710 |
keir@20482 | 1711 for (i = 0; i < num; i++) { |
keir@20482 | 1712 xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); |
keir@20482 | 1713 sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); |
keir@20482 | 1714 if (domain == pcidev->domain && bus == pcidev->bus && |
keir@20482 | 1715 pcidev->dev == dev && pcidev->func == func) { |
keir@20482 | 1716 break; |
keir@20482 | 1717 } |
keir@20482 | 1718 } |
keir@20482 | 1719 if (i == num) { |
keir@20512 | 1720 XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find the device on xenstore"); |
keir@20482 | 1721 return -1; |
keir@20482 | 1722 } |
keir@20482 | 1723 |
keir@20482 | 1724 retry_transaction: |
keir@20482 | 1725 t = xs_transaction_start(ctx->xsh); |
keir@20542 | 1726 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i), "5", strlen("5")); |
keir@20482 | 1727 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state", be_path), "7", strlen("7")); |
keir@20482 | 1728 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20482 | 1729 if (errno == EAGAIN) |
keir@20482 | 1730 goto retry_transaction; |
keir@20542 | 1731 |
keir@20542 | 1732 if (!is_hvm(ctx, domid)) { |
keir@20542 | 1733 if (libxl_wait_for_backend(ctx, be_path, "4") < 0) { |
keir@20542 | 1734 XL_LOG(ctx, XL_LOG_DEBUG, "pci backend at %s is not ready", be_path); |
keir@20542 | 1735 return -1; |
keir@20542 | 1736 } |
keir@20542 | 1737 } |
keir@20542 | 1738 |
keir@20542 | 1739 retry_transaction2: |
keir@20542 | 1740 t = xs_transaction_start(ctx->xsh); |
keir@20542 | 1741 xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i)); |
keir@20542 | 1742 xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, i)); |
keir@20542 | 1743 xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); |
keir@20542 | 1744 xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, i)); |
keir@20542 | 1745 xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, i)); |
keir@20542 | 1746 xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i)); |
keir@20542 | 1747 libxl_xs_write(ctx, t, num_devs_path, "%d", num - 1); |
keir@20542 | 1748 for (j = i + 1; j < num; j++) { |
keir@20542 | 1749 tmppath = libxl_sprintf(ctx, "%s/state-%d", be_path, j); |
keir@20542 | 1750 tmp = libxl_xs_read(ctx, t, tmppath); |
keir@20542 | 1751 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, j - 1), tmp, strlen(tmp)); |
keir@20542 | 1752 xs_rm(ctx->xsh, t, tmppath); |
keir@20542 | 1753 tmppath = libxl_sprintf(ctx, "%s/dev-%d", be_path, j); |
keir@20542 | 1754 tmp = libxl_xs_read(ctx, t, tmppath); |
keir@20542 | 1755 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, j - 1), tmp, strlen(tmp)); |
keir@20542 | 1756 xs_rm(ctx->xsh, t, tmppath); |
keir@20542 | 1757 tmppath = libxl_sprintf(ctx, "%s/key-%d", be_path, j); |
keir@20542 | 1758 tmp = libxl_xs_read(ctx, t, tmppath); |
keir@20542 | 1759 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, j - 1), tmp, strlen(tmp)); |
keir@20542 | 1760 xs_rm(ctx->xsh, t, tmppath); |
keir@20542 | 1761 tmppath = libxl_sprintf(ctx, "%s/vdev-%d", be_path, j); |
keir@20542 | 1762 tmp = libxl_xs_read(ctx, t, tmppath); |
keir@20542 | 1763 if (tmp) { |
keir@20542 | 1764 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, j - 1), tmp, strlen(tmp)); |
keir@20542 | 1765 xs_rm(ctx->xsh, t, tmppath); |
keir@20542 | 1766 } |
keir@20542 | 1767 tmppath = libxl_sprintf(ctx, "%s/opts-%d", be_path, j); |
keir@20542 | 1768 tmp = libxl_xs_read(ctx, t, tmppath); |
keir@20542 | 1769 if (tmp) { |
keir@20542 | 1770 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, j - 1), tmp, strlen(tmp)); |
keir@20542 | 1771 xs_rm(ctx->xsh, t, tmppath); |
keir@20542 | 1772 } |
keir@20542 | 1773 tmppath = libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j); |
keir@20542 | 1774 tmp = libxl_xs_read(ctx, t, tmppath); |
keir@20542 | 1775 if (tmp) { |
keir@20542 | 1776 xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp)); |
keir@20542 | 1777 xs_rm(ctx->xsh, t, tmppath); |
keir@20542 | 1778 } |
keir@20542 | 1779 } |
keir@20542 | 1780 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20542 | 1781 if (errno == EAGAIN) |
keir@20542 | 1782 goto retry_transaction2; |
keir@20542 | 1783 |
keir@20542 | 1784 if (num == 1) { |
keir@20542 | 1785 char *fe_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend", be_path)); |
keir@20542 | 1786 libxl_device_destroy(ctx, be_path, 1); |
keir@20542 | 1787 xs_rm(ctx->xsh, XBT_NULL, be_path); |
keir@20542 | 1788 xs_rm(ctx->xsh, XBT_NULL, fe_path); |
keir@20542 | 1789 return 0; |
keir@20542 | 1790 } |
keir@20542 | 1791 |
keir@20482 | 1792 return 0; |
keir@20462 | 1793 } |
keir@20462 | 1794 |
keir@20482 | 1795 int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) |
keir@20462 | 1796 { |
keir@20482 | 1797 char path[50]; |
keir@20482 | 1798 char *state, *vdevfn; |
keir@20482 | 1799 int rc, hvm; |
keir@20542 | 1800 int stubdomid = 0; |
keir@20482 | 1801 |
keir@20482 | 1802 /* TODO: check if the device can be assigned */ |
keir@20482 | 1803 |
keir@20482 | 1804 libxl_device_pci_flr(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1805 |
keir@20542 | 1806 if ((stubdomid = libxl_get_stubdom_id(ctx, domid)) != 0) { |
keir@20542 | 1807 libxl_device_pci pcidev_s = *pcidev; |
keir@20542 | 1808 libxl_device_pci_add(ctx, stubdomid, &pcidev_s); |
keir@20542 | 1809 } |
keir@20542 | 1810 |
keir@20482 | 1811 hvm = is_hvm(ctx, domid); |
keir@20482 | 1812 if (hvm) { |
keir@20514 | 1813 if (libxl_wait_for_device_model(ctx, domid, "running", 0,0) < 0) { |
keir@20482 | 1814 return -1; |
keir@20482 | 1815 } |
keir@20482 | 1816 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/state", domid); |
keir@20482 | 1817 state = libxl_xs_read(ctx, XBT_NULL, path); |
keir@20482 | 1818 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/parameter", domid); |
keir@20482 | 1819 if (pcidev->vdevfn) |
keir@20482 | 1820 libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain, |
keir@20482 | 1821 pcidev->bus, pcidev->dev, pcidev->func, pcidev->vdevfn); |
keir@20482 | 1822 else |
keir@20482 | 1823 libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, |
keir@20482 | 1824 pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1825 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/command", domid); |
keir@20482 | 1826 xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins")); |
keir@20514 | 1827 if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", 0,0) < 0) |
keir@20512 | 1828 XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); |
keir@20482 | 1829 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/parameter", domid); |
keir@20482 | 1830 vdevfn = libxl_xs_read(ctx, XBT_NULL, path); |
keir@20482 | 1831 sscanf(vdevfn + 2, "%x", &pcidev->vdevfn); |
keir@20482 | 1832 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/state", domid); |
keir@20482 | 1833 xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); |
keir@20482 | 1834 } else { |
keir@20542 | 1835 char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, |
keir@20482 | 1836 pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1837 FILE *f = fopen(sysfs_path, "r"); |
keir@20482 | 1838 unsigned int start = 0, end = 0, flags = 0, size = 0; |
keir@20482 | 1839 int irq = 0; |
keir@20482 | 1840 int i; |
keir@20482 | 1841 |
keir@20482 | 1842 if (f == NULL) { |
keir@20512 | 1843 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", sysfs_path); |
keir@20482 | 1844 return -1; |
keir@20482 | 1845 } |
keir@20482 | 1846 for (i = 0; i < PROC_PCI_NUM_RESOURCES; i++) { |
keir@20512 | 1847 fscanf(f, "0x%x 0x%x 0x%x", &start, &end, &flags); |
keir@20482 | 1848 size = end - start + 1; |
keir@20482 | 1849 if (start) { |
keir@20482 | 1850 if (flags & PCI_BAR_IO) { |
keir@20482 | 1851 rc = xc_domain_ioport_permission(ctx->xch, domid, start, size, 1); |
keir@20482 | 1852 if (rc < 0) |
keir@20512 | 1853 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Error: xc_domain_ioport_permission error 0x%x/0x%x", start, size); |
keir@20482 | 1854 } else { |
keir@20482 | 1855 rc = xc_domain_iomem_permission(ctx->xch, domid, start>>XC_PAGE_SHIFT, |
keir@20482 | 1856 (size+(XC_PAGE_SIZE-1))>>XC_PAGE_SHIFT, 1); |
keir@20482 | 1857 if (rc < 0) |
keir@20512 | 1858 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Error: xc_domain_iomem_permission error 0x%x/0x%x", start, size); |
keir@20482 | 1859 } |
keir@20482 | 1860 } |
keir@20482 | 1861 } |
keir@20482 | 1862 fclose(f); |
keir@20542 | 1863 sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, |
keir@20482 | 1864 pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1865 f = fopen(sysfs_path, "r"); |
keir@20482 | 1866 if (f == NULL) { |
keir@20512 | 1867 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", sysfs_path); |
keir@20482 | 1868 goto out; |
keir@20482 | 1869 } |
keir@20482 | 1870 fscanf(f, "%u", &irq); |
keir@20482 | 1871 if (irq) { |
keir@20482 | 1872 rc = xc_physdev_map_pirq(ctx->xch, domid, irq, &irq); |
keir@20482 | 1873 if (rc < 0) { |
keir@20512 | 1874 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Error: xc_physdev_map_pirq irq=%d", irq); |
keir@20482 | 1875 } |
keir@20482 | 1876 rc = xc_domain_irq_permission(ctx->xch, domid, irq, 1); |
keir@20482 | 1877 if (rc < 0) { |
keir@20512 | 1878 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Error: xc_domain_irq_permission irq=%d", irq); |
keir@20482 | 1879 } |
keir@20482 | 1880 } |
keir@20482 | 1881 fclose(f); |
keir@20482 | 1882 } |
keir@20482 | 1883 out: |
keir@20542 | 1884 if (!libxl_is_stubdom(ctx, domid)) { |
keir@20542 | 1885 if ((rc = xc_assign_device(ctx->xch, domid, pcidev->value)) < 0) |
keir@20542 | 1886 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_assign_device failed"); |
keir@20542 | 1887 } |
keir@20482 | 1888 |
keir@20482 | 1889 libxl_device_pci_add_xenstore(ctx, domid, pcidev); |
keir@20482 | 1890 return 0; |
keir@20462 | 1891 } |
keir@20462 | 1892 |
keir@20482 | 1893 int libxl_device_pci_remove(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) |
keir@20462 | 1894 { |
keir@20482 | 1895 char path[50]; |
keir@20482 | 1896 char *state; |
keir@20482 | 1897 int hvm, rc; |
keir@20542 | 1898 int stubdomid = 0; |
keir@20482 | 1899 |
keir@20482 | 1900 /* TODO: check if the device can be detached */ |
keir@20542 | 1901 libxl_device_pci_remove_xenstore(ctx, domid, pcidev); |
keir@20482 | 1902 |
keir@20482 | 1903 hvm = is_hvm(ctx, domid); |
keir@20482 | 1904 if (hvm) { |
keir@20514 | 1905 if (libxl_wait_for_device_model(ctx, domid, "running", 0,0) < 0) { |
keir@20482 | 1906 return -1; |
keir@20482 | 1907 } |
keir@20482 | 1908 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/state", domid); |
keir@20482 | 1909 state = libxl_xs_read(ctx, XBT_NULL, path); |
keir@20482 | 1910 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/parameter", domid); |
keir@20482 | 1911 libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, |
keir@20482 | 1912 pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1913 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/command", domid); |
keir@20482 | 1914 xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem")); |
keir@20514 | 1915 if (libxl_wait_for_device_model(ctx, domid, "pci-removed", 0,0) < 0) { |
keir@20512 | 1916 XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); |
keir@20482 | 1917 return -1; |
keir@20482 | 1918 } |
keir@20482 | 1919 snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/state", domid); |
keir@20482 | 1920 xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); |
keir@20482 | 1921 } else { |
keir@20542 | 1922 char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, |
keir@20482 | 1923 pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1924 FILE *f = fopen(sysfs_path, "r"); |
keir@20482 | 1925 unsigned int start = 0, end = 0, flags = 0, size = 0; |
keir@20482 | 1926 int irq = 0; |
keir@20482 | 1927 int i; |
keir@20482 | 1928 |
keir@20482 | 1929 if (f == NULL) { |
keir@20512 | 1930 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", sysfs_path); |
keir@20482 | 1931 goto skip1; |
keir@20482 | 1932 } |
keir@20482 | 1933 for (i = 0; i < PROC_PCI_NUM_RESOURCES; i++) { |
keir@20482 | 1934 fscanf(f, "0x%x 0x%x 0x%x\n", &start, &end, &flags); |
keir@20482 | 1935 size = end - start + 1; |
keir@20482 | 1936 if (start) { |
keir@20482 | 1937 if (flags & PCI_BAR_IO) { |
keir@20482 | 1938 rc = xc_domain_ioport_permission(ctx->xch, domid, start, size, 0); |
keir@20482 | 1939 if (rc < 0) |
keir@20512 | 1940 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_ioport_permission error 0x%x/0x%x", start, size); |
keir@20482 | 1941 } else { |
keir@20482 | 1942 rc = xc_domain_iomem_permission(ctx->xch, domid, start>>XC_PAGE_SHIFT, |
keir@20482 | 1943 (size+(XC_PAGE_SIZE-1))>>XC_PAGE_SHIFT, 0); |
keir@20482 | 1944 if (rc < 0) |
keir@20512 | 1945 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_iomem_permission error 0x%x/0x%x", start, size); |
keir@20482 | 1946 } |
keir@20482 | 1947 } |
keir@20482 | 1948 } |
keir@20482 | 1949 fclose(f); |
keir@20482 | 1950 skip1: |
keir@20542 | 1951 sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, |
keir@20482 | 1952 pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1953 f = fopen(sysfs_path, "r"); |
keir@20482 | 1954 if (f == NULL) { |
keir@20512 | 1955 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", sysfs_path); |
keir@20482 | 1956 goto out; |
keir@20482 | 1957 } |
keir@20482 | 1958 fscanf(f, "%u", &irq); |
keir@20482 | 1959 if (irq) { |
keir@20482 | 1960 rc = xc_physdev_unmap_pirq(ctx->xch, domid, irq); |
keir@20482 | 1961 if (rc < 0) { |
keir@20512 | 1962 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_physdev_map_pirq irq=%d", irq); |
keir@20482 | 1963 } |
keir@20482 | 1964 rc = xc_domain_irq_permission(ctx->xch, domid, irq, 0); |
keir@20482 | 1965 if (rc < 0) { |
keir@20512 | 1966 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_irq_permission irq=%d", irq); |
keir@20482 | 1967 } |
keir@20482 | 1968 } |
keir@20482 | 1969 fclose(f); |
keir@20482 | 1970 } |
keir@20482 | 1971 out: |
keir@20482 | 1972 libxl_device_pci_flr(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); |
keir@20482 | 1973 |
keir@20542 | 1974 if (!libxl_is_stubdom(ctx, domid)) { |
keir@20542 | 1975 if ((rc = xc_deassign_device(ctx->xch, domid, pcidev->value)) < 0) |
keir@20542 | 1976 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_deassign_device failed"); |
keir@20542 | 1977 } |
keir@20542 | 1978 |
keir@20542 | 1979 if ((stubdomid = libxl_get_stubdom_id(ctx, domid)) != 0) { |
keir@20542 | 1980 libxl_device_pci pcidev_s = *pcidev; |
keir@20542 | 1981 libxl_device_pci_remove(ctx, stubdomid, &pcidev_s); |
keir@20542 | 1982 } |
keir@20542 | 1983 |
keir@20482 | 1984 return 0; |
keir@20462 | 1985 } |
keir@20482 | 1986 |
keir@20482 | 1987 libxl_device_pci *libxl_device_pci_list(struct libxl_ctx *ctx, uint32_t domid, int *num) |
keir@20482 | 1988 { |
keir@20482 | 1989 char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts; |
keir@20482 | 1990 int n, i; |
keir@20482 | 1991 unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0; |
keir@20482 | 1992 libxl_device_pci *pcidevs; |
keir@20482 | 1993 |
keir@20516 | 1994 be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); |
keir@20482 | 1995 num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", be_path)); |
keir@20482 | 1996 if (!num_devs) { |
keir@20482 | 1997 *num = 0; |
keir@20482 | 1998 return NULL; |
keir@20482 | 1999 } |
keir@20482 | 2000 n = atoi(num_devs); |
keir@20516 | 2001 pcidevs = (libxl_device_pci *) calloc(n, sizeof(libxl_device_pci)); |
keir@20482 | 2002 *num = n; |
keir@20482 | 2003 |
keir@20482 | 2004 for (i = 0; i < n; i++) { |
keir@20482 | 2005 xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); |
keir@20482 | 2006 sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); |
keir@20482 | 2007 xsvdevfn = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i)); |
keir@20482 | 2008 if (xsvdevfn) |
keir@20482 | 2009 vdevfn = strtol(xsvdevfn, (char **) NULL, 16); |
keir@20482 | 2010 libxl_device_pci_init(pcidevs + i, domain, bus, dev, func, vdevfn); |
keir@20482 | 2011 xsopts = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/opts-%d", be_path, i)); |
keir@20482 | 2012 if (xsopts) { |
keir@20482 | 2013 char *saveptr; |
keir@20482 | 2014 char *p = strtok_r(xsopts, ",=", &saveptr); |
keir@20482 | 2015 do { |
keir@20482 | 2016 while (*p == ' ') |
keir@20482 | 2017 p++; |
keir@20482 | 2018 if (!strcmp(p, "msitranslate")) { |
keir@20482 | 2019 p = strtok_r(NULL, ",=", &saveptr); |
keir@20482 | 2020 pcidevs[i].msitranslate = atoi(p); |
keir@20482 | 2021 } else if (!strcmp(p, "power_mgmt")) { |
keir@20482 | 2022 p = strtok_r(NULL, ",=", &saveptr); |
keir@20482 | 2023 pcidevs[i].power_mgmt = atoi(p); |
keir@20482 | 2024 } |
keir@20482 | 2025 } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL); |
keir@20482 | 2026 } |
keir@20482 | 2027 } |
keir@20482 | 2028 return pcidevs; |
keir@20482 | 2029 } |
keir@20482 | 2030 |
keir@20482 | 2031 int libxl_device_pci_shutdown(struct libxl_ctx *ctx, uint32_t domid) |
keir@20482 | 2032 { |
keir@20482 | 2033 libxl_device_pci *pcidevs; |
keir@20482 | 2034 int num, i; |
keir@20482 | 2035 |
keir@20482 | 2036 pcidevs = libxl_device_pci_list(ctx, domid, &num); |
keir@20482 | 2037 for (i = 0; i < num; i++) { |
keir@20482 | 2038 if (libxl_device_pci_remove(ctx, domid, pcidevs + i) < 0) |
keir@20482 | 2039 return -1; |
keir@20482 | 2040 } |
keir@20516 | 2041 free(pcidevs); |
keir@20482 | 2042 return 0; |
keir@20482 | 2043 } |
keir@20482 | 2044 |
keir@20542 | 2045 void nic_info_domid_fixup(libxl_device_nic *nic_info, int domid) |
keir@20542 | 2046 { |
keir@20542 | 2047 nic_info->domid = domid; |
keir@20542 | 2048 asprintf(&(nic_info->ifname), "tap%d.%d", domid, nic_info->devid - 1); |
keir@20542 | 2049 } |
keir@20542 | 2050 |
keir@20542 | 2051 void disk_info_domid_fixup(libxl_device_disk *disk_info, int domid) |
keir@20542 | 2052 { |
keir@20542 | 2053 disk_info->domid = domid; |
keir@20542 | 2054 } |
keir@20542 | 2055 |
keir@20542 | 2056 void vfb_info_domid_fixup(libxl_device_vfb *vfb, int domid) |
keir@20542 | 2057 { |
keir@20542 | 2058 vfb->domid = domid; |
keir@20542 | 2059 } |
keir@20542 | 2060 |
keir@20542 | 2061 void vkb_info_domid_fixup(libxl_device_vkb *vkb, int domid) |
keir@20542 | 2062 { |
keir@20542 | 2063 vkb->domid = domid; |
keir@20542 | 2064 } |
keir@20542 | 2065 |
keir@20542 | 2066 void console_info_domid_fixup(libxl_device_console *console, int domid) |
keir@20542 | 2067 { |
keir@20542 | 2068 console->domid = domid; |
keir@20542 | 2069 } |
keir@20542 | 2070 |
keir@20542 | 2071 void device_model_info_domid_fixup(libxl_device_model_info *dm_info, int domid) |
keir@20542 | 2072 { |
keir@20542 | 2073 dm_info->domid = domid; |
keir@20542 | 2074 } |
keir@20542 | 2075 |
keir@20542 | 2076 void init_create_info(libxl_domain_create_info *c_info) |
keir@20542 | 2077 { |
keir@20542 | 2078 memset(c_info, '\0', sizeof(*c_info)); |
keir@20542 | 2079 c_info->xsdata = NULL; |
keir@20542 | 2080 c_info->platformdata = NULL; |
keir@20542 | 2081 c_info->hvm = 1; |
keir@20542 | 2082 c_info->ssidref = 0; |
keir@20542 | 2083 } |
keir@20542 | 2084 |
keir@20542 | 2085 void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info) |
keir@20542 | 2086 { |
keir@20542 | 2087 memset(b_info, '\0', sizeof(*b_info)); |
keir@20542 | 2088 b_info->timer_mode = -1; |
keir@20542 | 2089 b_info->hpet = 1; |
keir@20542 | 2090 b_info->vpt_align = -1; |
keir@20542 | 2091 b_info->max_vcpus = 1; |
keir@20542 | 2092 b_info->max_memkb = 32 * 1024; |
keir@20542 | 2093 if (c_info->hvm) { |
keir@20542 | 2094 b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus); |
keir@20542 | 2095 b_info->video_memkb = 8 * 1024; |
keir@20542 | 2096 b_info->kernel = "/usr/lib/xen/boot/hvmloader"; |
keir@20542 | 2097 b_info->hvm = 1; |
keir@20542 | 2098 b_info->u.hvm.pae = 1; |
keir@20542 | 2099 b_info->u.hvm.apic = 1; |
keir@20542 | 2100 b_info->u.hvm.acpi = 1; |
keir@20542 | 2101 b_info->u.hvm.nx = 1; |
keir@20542 | 2102 b_info->u.hvm.viridian = 0; |
keir@20632 | 2103 } else { |
keir@20632 | 2104 b_info->u.pv.slack_memkb = 8 * 1024; |
keir@20542 | 2105 } |
keir@20542 | 2106 } |
keir@20542 | 2107 |
keir@20542 | 2108 void init_dm_info(libxl_device_model_info *dm_info, |
keir@20542 | 2109 libxl_domain_create_info *c_info, libxl_domain_build_info *b_info) |
keir@20542 | 2110 { |
keir@20542 | 2111 memset(dm_info, '\0', sizeof(*dm_info)); |
keir@20542 | 2112 |
keir@20542 | 2113 dm_info->dom_name = c_info->name; |
keir@20542 | 2114 dm_info->device_model = "/usr/lib/xen/bin/qemu-dm"; |
keir@20542 | 2115 dm_info->videoram = b_info->video_memkb / 1024; |
keir@20542 | 2116 dm_info->apic = b_info->u.hvm.apic; |
keir@20542 | 2117 |
keir@20542 | 2118 dm_info->stdvga = 0; |
keir@20542 | 2119 dm_info->vnc = 1; |
keir@20542 | 2120 dm_info->vnclisten = "127.0.0.1"; |
keir@20542 | 2121 dm_info->vncdisplay = 0; |
keir@20542 | 2122 dm_info->vncunused = 0; |
keir@20542 | 2123 dm_info->keymap = NULL; |
keir@20542 | 2124 dm_info->sdl = 0; |
keir@20542 | 2125 dm_info->opengl = 0; |
keir@20542 | 2126 dm_info->nographic = 0; |
keir@20542 | 2127 dm_info->serial = NULL; |
keir@20542 | 2128 dm_info->boot = "cda"; |
keir@20542 | 2129 dm_info->usb = 0; |
keir@20542 | 2130 dm_info->usbdevice = NULL; |
keir@20542 | 2131 } |
keir@20542 | 2132 |
keir@20542 | 2133 void init_nic_info(libxl_device_nic *nic_info, int devnum) |
keir@20542 | 2134 { |
keir@20542 | 2135 memset(nic_info, '\0', sizeof(*nic_info)); |
keir@20542 | 2136 |
keir@20542 | 2137 |
keir@20542 | 2138 nic_info->backend_domid = 0; |
keir@20542 | 2139 nic_info->domid = 0; |
keir@20542 | 2140 nic_info->devid = devnum; |
keir@20542 | 2141 nic_info->mtu = 1492; |
keir@20542 | 2142 nic_info->model = "e1000"; |
keir@20542 | 2143 srand(time(0)); |
keir@20542 | 2144 nic_info->mac[0] = 0x00; |
keir@20542 | 2145 nic_info->mac[1] = 0x16; |
keir@20542 | 2146 nic_info->mac[2] = 0x3e; |
keir@20542 | 2147 nic_info->mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0))); |
keir@20542 | 2148 nic_info->mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0))); |
keir@20542 | 2149 nic_info->mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0))); |
keir@20542 | 2150 asprintf(&(nic_info->smac), "%02x:%02x:%02x:%02x:%02x:%02x", nic_info->mac[0], nic_info->mac[1], nic_info->mac[2], nic_info->mac[3], nic_info->mac[4], nic_info->mac[5]); |
keir@20542 | 2151 nic_info->ifname = NULL; |
keir@20542 | 2152 nic_info->bridge = "xenbr0"; |
keir@20542 | 2153 nic_info->script = "/etc/xen/scripts/vif-bridge"; |
keir@20542 | 2154 nic_info->nictype = NICTYPE_IOEMU; |
keir@20542 | 2155 } |
keir@20542 | 2156 |
keir@20542 | 2157 void init_vfb_info(libxl_device_vfb *vfb, int dev_num) |
keir@20542 | 2158 { |
keir@20542 | 2159 memset(vfb, 0x00, sizeof(libxl_device_vfb)); |
keir@20542 | 2160 vfb->devid = dev_num; |
keir@20542 | 2161 vfb->vnc = 1; |
keir@20542 | 2162 vfb->vnclisten = "127.0.0.1"; |
keir@20542 | 2163 vfb->vncdisplay = 0; |
keir@20542 | 2164 vfb->vncunused = 1; |
keir@20542 | 2165 vfb->keymap = NULL; |
keir@20542 | 2166 vfb->sdl = 0; |
keir@20542 | 2167 vfb->opengl = 0; |
keir@20542 | 2168 } |
keir@20542 | 2169 |
keir@20542 | 2170 void init_vkb_info(libxl_device_vkb *vkb, int dev_num) |
keir@20542 | 2171 { |
keir@20542 | 2172 memset(vkb, 0x00, sizeof(libxl_device_vkb)); |
keir@20542 | 2173 vkb->devid = dev_num; |
keir@20542 | 2174 } |
keir@20542 | 2175 |
keir@20542 | 2176 void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state) |
keir@20542 | 2177 { |
keir@20542 | 2178 memset(console, 0x00, sizeof(libxl_device_console)); |
keir@20542 | 2179 console->devid = dev_num; |
keir@20542 | 2180 console->constype = CONSTYPE_XENCONSOLED; |
keir@20542 | 2181 if (state) |
keir@20542 | 2182 console->build_state = state; |
keir@20542 | 2183 } |
keir@20542 | 2184 |
keir@20542 | 2185 |