debuggers.hg
annotate tools/libxl/libxl.c @ 22062:e5a9221bdd3f
tools/libxl: compile with -Wmissing-declarations
Since the recent build error caused by mismatch of symbol types due to
missing declarations, build libxl with -Wmissing-declarations.
The patch is mostly straightforward, a one liner in the makefile enables
the flag, a lot of functions in xl_cmdimpl.c needed to be made static
and libxl_paths.c needed to include libxl.h.
The one wart on the patch-set is that flex has a bug where it emits code
with missing declarations for yy(set|get)_column. This can be worked
around by providing the declarations ourselves regardless.
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Since the recent build error caused by mismatch of symbol types due to
missing declarations, build libxl with -Wmissing-declarations.
The patch is mostly straightforward, a one liner in the makefile enables
the flag, a lot of functions in xl_cmdimpl.c needed to be made static
and libxl_paths.c needed to include libxl.h.
The one wart on the patch-set is that flex has a bug where it emits code
with missing declarations for yy(set|get)_column. This can be worked
around by providing the declarations ourselves regardless.
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
author | Ian Jackson <Ian.Jackson@eu.citrix.com> |
---|---|
date | Tue Aug 17 17:20:53 2010 +0100 (2010-08-17) |
parents | 251dae6ee4a9 |
children | 9a4acc688e9f |
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> |
zhigang@21941 | 23 #include <sys/stat.h> |
keir@20462 | 24 #include <fcntl.h> |
keir@20462 | 25 #include <sys/select.h> |
Ian@21848 | 26 #include <sys/mman.h> |
keir@20514 | 27 #include <sys/wait.h> |
ian@22032 | 28 #include <sys/time.h> |
keir@20462 | 29 #include <signal.h> |
keir@20468 | 30 #include <unistd.h> /* for write, unlink and close */ |
keir@20509 | 31 #include <stdint.h> |
keir@20509 | 32 #include <inttypes.h> |
keir@20514 | 33 #include <assert.h> |
keir@20513 | 34 |
keir@20462 | 35 #include "libxl.h" |
keir@20462 | 36 #include "libxl_utils.h" |
keir@20462 | 37 #include "libxl_internal.h" |
keir@20462 | 38 #include "flexarray.h" |
keir@20462 | 39 |
keir@20860 | 40 #define PAGE_TO_MEMKB(pages) ((pages) * 4) |
keir@20860 | 41 |
ian@21930 | 42 int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger *lg) |
keir@20462 | 43 { |
keir@20788 | 44 if (version != LIBXL_VERSION) |
keir@20788 | 45 return ERROR_VERSION; |
ian@21930 | 46 memset(ctx, 0, sizeof(libxl_ctx)); |
keir@21532 | 47 ctx->lg = lg; |
keir@21266 | 48 memset(&ctx->version_info, 0, sizeof(libxl_version_info)); |
keir@20462 | 49 |
keir@21532 | 50 ctx->xch = xc_interface_open(lg,lg,0); |
keir@21529 | 51 if (!ctx->xch) { |
keir@21681 | 52 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, |
keir@21681 | 53 "cannot open libxc handle"); |
keir@20819 | 54 return ERROR_FAIL; |
keir@20819 | 55 } |
keir@20819 | 56 |
keir@20462 | 57 ctx->xsh = xs_daemon_open(); |
keir@20819 | 58 if (!ctx->xsh) { |
keir@21681 | 59 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, |
keir@21681 | 60 "cannot connect to xenstore"); |
keir@20819 | 61 xc_interface_close(ctx->xch); |
keir@20819 | 62 return ERROR_FAIL; |
keir@20819 | 63 } |
keir@20462 | 64 return 0; |
keir@20462 | 65 } |
keir@20462 | 66 |
gianni@22008 | 67 static void do_free_version_info(libxl_version_info *info); |
ian@21930 | 68 int libxl_ctx_free(libxl_ctx *ctx) |
keir@20462 | 69 { |
keir@20462 | 70 xc_interface_close(ctx->xch); |
gianni@22008 | 71 do_free_version_info(&ctx->version_info); |
keir@21186 | 72 if (ctx->xsh) xs_daemon_close(ctx->xsh); |
keir@20462 | 73 return 0; |
keir@20462 | 74 } |
keir@20462 | 75 |
keir@20462 | 76 /******************************************************************************/ |
keir@20462 | 77 |
ian@21930 | 78 int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, |
keir@20462 | 79 uint32_t *domid) |
keir@20462 | 80 { |
gianni@22023 | 81 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21184 | 82 int flags, ret, i, rc; |
keir@20468 | 83 char *uuid_string; |
keir@20646 | 84 char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; |
keir@20462 | 85 char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", |
keir@20646 | 86 "control", "attr", "messages" }; |
ian@21894 | 87 char *dom_path, *vm_path; |
keir@20462 | 88 struct xs_permissions roperm[2]; |
keir@20462 | 89 struct xs_permissions rwperm[1]; |
keir@20462 | 90 xs_transaction_t t; |
keir@20468 | 91 xen_domain_handle_t handle; |
keir@20462 | 92 |
gianni@22047 | 93 uuid_string = libxl_uuid2string(&gc, info->uuid); |
gianni@22023 | 94 if (!uuid_string) { |
gianni@22023 | 95 libxl_free_all(&gc); |
gianni@22023 | 96 return ERROR_NOMEM; |
gianni@22023 | 97 } |
keir@20462 | 98 |
keir@20462 | 99 flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; |
keir@20462 | 100 flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; |
keir@21274 | 101 flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off; |
keir@20824 | 102 *domid = -1; |
keir@20462 | 103 |
keir@20580 | 104 /* Ultimately, handle is an array of 16 uint8_t, same as uuid */ |
keir@20580 | 105 memcpy(handle, info->uuid, sizeof(xen_domain_handle_t)); |
keir@20468 | 106 |
keir@20468 | 107 ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); |
keir@20462 | 108 if (ret < 0) { |
keir@20512 | 109 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain creation fail"); |
gianni@22023 | 110 libxl_free_all(&gc); |
keir@20462 | 111 return ERROR_FAIL; |
keir@20462 | 112 } |
keir@20462 | 113 |
keir@21368 | 114 ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); |
keir@21368 | 115 if (ret < 0) { |
keir@21368 | 116 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain move fail"); |
gianni@22023 | 117 libxl_free_all(&gc); |
keir@21368 | 118 return ERROR_FAIL; |
keir@21368 | 119 } |
keir@21368 | 120 |
gianni@22023 | 121 dom_path = libxl_xs_get_dompath(&gc, *domid); |
gianni@22023 | 122 if (!dom_path) { |
gianni@22023 | 123 libxl_free_all(&gc); |
keir@20512 | 124 return ERROR_FAIL; |
gianni@22023 | 125 } |
gianni@22023 | 126 |
gianni@22023 | 127 vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string); |
ian@21894 | 128 if (!vm_path) { |
keir@20462 | 129 XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths"); |
gianni@22023 | 130 libxl_free_all(&gc); |
keir@20462 | 131 return ERROR_FAIL; |
keir@20462 | 132 } |
keir@20462 | 133 |
keir@20462 | 134 roperm[0].id = 0; |
keir@20462 | 135 roperm[0].perms = XS_PERM_NONE; |
keir@20462 | 136 roperm[1].id = *domid; |
keir@20462 | 137 roperm[1].perms = XS_PERM_READ; |
keir@20462 | 138 rwperm[0].id = *domid; |
keir@20462 | 139 rwperm[0].perms = XS_PERM_NONE; |
keir@20462 | 140 |
keir@20462 | 141 retry_transaction: |
keir@20462 | 142 t = xs_transaction_start(ctx->xsh); |
keir@20462 | 143 xs_rm(ctx->xsh, t, dom_path); |
keir@20462 | 144 xs_mkdir(ctx->xsh, t, dom_path); |
keir@20462 | 145 xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); |
keir@20462 | 146 |
keir@20462 | 147 xs_rm(ctx->xsh, t, vm_path); |
keir@20462 | 148 xs_mkdir(ctx->xsh, t, vm_path); |
keir@20462 | 149 xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); |
keir@20462 | 150 |
gianni@22023 | 151 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); |
keir@21184 | 152 rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); |
gianni@22023 | 153 if (rc) { |
gianni@22023 | 154 libxl_free_all(&gc); |
gianni@22023 | 155 return rc; |
gianni@22023 | 156 } |
keir@20462 | 157 |
keir@20462 | 158 for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { |
gianni@22023 | 159 char *path = libxl_sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); |
keir@20462 | 160 xs_mkdir(ctx->xsh, t, path); |
keir@20462 | 161 xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); |
keir@20462 | 162 } |
keir@20462 | 163 for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { |
gianni@22023 | 164 char *path = libxl_sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); |
keir@20462 | 165 xs_mkdir(ctx->xsh, t, path); |
keir@20462 | 166 xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); |
keir@20462 | 167 } |
keir@20462 | 168 |
gianni@22023 | 169 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); |
gianni@22023 | 170 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); |
keir@21389 | 171 if (info->poolname) |
gianni@22023 | 172 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); |
gianni@22023 | 173 |
gianni@22023 | 174 libxl_xs_writev(&gc, t, dom_path, info->xsdata); |
gianni@22023 | 175 libxl_xs_writev(&gc, t, libxl_sprintf(&gc, "%s/platform", dom_path), info->platformdata); |
gianni@22023 | 176 |
gianni@22023 | 177 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); |
keir@20462 | 178 |
keir@20462 | 179 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20462 | 180 if (errno == EAGAIN) |
keir@20462 | 181 goto retry_transaction; |
gianni@22023 | 182 |
gianni@22023 | 183 libxl_free_all(&gc); |
keir@20462 | 184 return 0; |
keir@20462 | 185 } |
keir@20462 | 186 |
ian@21930 | 187 int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, |
keir@21184 | 188 const char *old_name, const char *new_name, |
gianni@22023 | 189 xs_transaction_t trans) |
gianni@22023 | 190 { |
gianni@22023 | 191 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21184 | 192 char *dom_path = 0; |
keir@21184 | 193 const char *name_path; |
keir@21184 | 194 char *got_old_name; |
keir@21184 | 195 unsigned int got_old_len; |
keir@21184 | 196 xs_transaction_t our_trans = 0; |
keir@21184 | 197 int rc; |
keir@21184 | 198 |
gianni@22023 | 199 dom_path = libxl_xs_get_dompath(&gc, domid); |
keir@21184 | 200 if (!dom_path) goto x_nomem; |
keir@21184 | 201 |
gianni@22023 | 202 name_path= libxl_sprintf(&gc, "%s/name", dom_path); |
keir@21184 | 203 if (!name_path) goto x_nomem; |
keir@21184 | 204 |
keir@21184 | 205 retry_transaction: |
keir@21184 | 206 if (!trans) { |
keir@21184 | 207 trans = our_trans = xs_transaction_start(ctx->xsh); |
keir@21184 | 208 if (!our_trans) { |
keir@21184 | 209 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, |
keir@21184 | 210 "create xs transaction for domain (re)name"); |
keir@21184 | 211 goto x_fail; |
keir@21184 | 212 } |
keir@21184 | 213 } |
keir@21184 | 214 |
keir@21184 | 215 if (old_name) { |
keir@21184 | 216 got_old_name = xs_read(ctx->xsh, trans, name_path, &got_old_len); |
keir@21184 | 217 if (!got_old_name) { |
keir@21184 | 218 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "check old name" |
keir@21184 | 219 " for domain %"PRIu32" allegedly named `%s'", |
keir@21184 | 220 domid, old_name); |
keir@21184 | 221 goto x_fail; |
keir@21184 | 222 } |
keir@21184 | 223 if (strcmp(old_name, got_old_name)) { |
keir@21184 | 224 XL_LOG(ctx, XL_LOG_ERROR, "domain %"PRIu32" allegedly named " |
keir@21184 | 225 "`%s' is actually named `%s' - racing ?", |
keir@21184 | 226 domid, old_name, got_old_name); |
keir@21184 | 227 free(got_old_name); |
keir@21184 | 228 goto x_fail; |
keir@21184 | 229 } |
keir@21184 | 230 free(got_old_name); |
keir@21184 | 231 } |
keir@21184 | 232 if (!xs_write(ctx->xsh, trans, name_path, |
keir@21184 | 233 new_name, strlen(new_name))) { |
keir@21184 | 234 XL_LOG(ctx, XL_LOG_ERROR, "failed to write new name `%s'" |
keir@21184 | 235 " for domain %"PRIu32" previously named `%s'", |
keir@21531 | 236 new_name, domid, old_name); |
keir@21184 | 237 goto x_fail; |
keir@21184 | 238 } |
keir@21184 | 239 |
keir@21184 | 240 if (our_trans) { |
keir@21184 | 241 if (!xs_transaction_end(ctx->xsh, our_trans, 0)) { |
keir@21184 | 242 trans = our_trans = 0; |
keir@21184 | 243 if (errno != EAGAIN) { |
keir@21184 | 244 XL_LOG(ctx, XL_LOG_ERROR, "failed to commit new name `%s'" |
keir@21184 | 245 " for domain %"PRIu32" previously named `%s'", |
keir@21531 | 246 new_name, domid, old_name); |
keir@21184 | 247 goto x_fail; |
keir@21184 | 248 } |
keir@21184 | 249 XL_LOG(ctx, XL_LOG_DEBUG, "need to retry rename transaction" |
keir@21184 | 250 " for domain %"PRIu32" (name_path=\"%s\", new_name=\"%s\")", |
keir@21184 | 251 domid, name_path, new_name); |
keir@21184 | 252 goto retry_transaction; |
keir@21184 | 253 } |
keir@21184 | 254 our_trans = 0; |
keir@21184 | 255 } |
keir@21184 | 256 |
keir@21184 | 257 rc = 0; |
keir@21184 | 258 x_rc: |
keir@21184 | 259 if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1); |
gianni@22023 | 260 libxl_free_all(&gc); |
keir@21184 | 261 return rc; |
keir@21184 | 262 |
keir@21184 | 263 x_fail: rc = ERROR_FAIL; goto x_rc; |
keir@21184 | 264 x_nomem: rc = ERROR_NOMEM; goto x_rc; |
keir@21184 | 265 } |
keir@21184 | 266 |
ian@21930 | 267 int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) |
keir@20462 | 268 { |
gianni@22023 | 269 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20462 | 270 char **vments = NULL, **localents = NULL; |
keir@21438 | 271 struct timeval start_time; |
keir@20829 | 272 int i, ret; |
keir@20829 | 273 |
keir@20829 | 274 ret = build_pre(ctx, domid, info, state); |
gianni@22023 | 275 if (ret) |
gianni@22023 | 276 goto out; |
keir@20462 | 277 |
keir@21438 | 278 gettimeofday(&start_time, NULL); |
keir@21438 | 279 |
keir@20462 | 280 if (info->hvm) { |
keir@20829 | 281 ret = build_hvm(ctx, domid, info, state); |
gianni@22023 | 282 if (ret) |
gianni@22023 | 283 goto out; |
gianni@22023 | 284 |
gianni@22023 | 285 vments = libxl_calloc(&gc, 7, sizeof(char *)); |
keir@20516 | 286 vments[0] = "rtc/timeoffset"; |
keir@20516 | 287 vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; |
keir@20516 | 288 vments[2] = "image/ostype"; |
keir@20516 | 289 vments[3] = "hvm"; |
keir@21438 | 290 vments[4] = "start_time"; |
gianni@22023 | 291 vments[5] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); |
keir@20462 | 292 } else { |
keir@20829 | 293 ret = build_pv(ctx, domid, info, state); |
gianni@22023 | 294 if (ret) |
gianni@22023 | 295 goto out; |
gianni@22023 | 296 |
gianni@22023 | 297 vments = libxl_calloc(&gc, 11, sizeof(char *)); |
keir@20578 | 298 i = 0; |
keir@20578 | 299 vments[i++] = "image/ostype"; |
keir@20578 | 300 vments[i++] = "linux"; |
keir@20578 | 301 vments[i++] = "image/kernel"; |
Ian@21848 | 302 vments[i++] = (char*) info->kernel.path; |
keir@21438 | 303 vments[i++] = "start_time"; |
gianni@22023 | 304 vments[i++] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); |
Ian@21848 | 305 if (info->u.pv.ramdisk.path) { |
keir@20578 | 306 vments[i++] = "image/ramdisk"; |
Ian@21848 | 307 vments[i++] = (char*) info->u.pv.ramdisk.path; |
keir@20578 | 308 } |
keir@20578 | 309 if (info->u.pv.cmdline) { |
keir@20578 | 310 vments[i++] = "image/cmdline"; |
keir@20578 | 311 vments[i++] = (char*) info->u.pv.cmdline; |
keir@20578 | 312 } |
keir@20462 | 313 } |
keir@20829 | 314 ret = build_post(ctx, domid, info, state, vments, localents); |
keir@20829 | 315 out: |
Ian@21848 | 316 libxl_file_reference_unmap(ctx, &info->kernel); |
Ian@21848 | 317 if (!info->hvm) |
Ian@21848 | 318 libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk); |
Ian@21848 | 319 |
gianni@22023 | 320 libxl_free_all(&gc); |
keir@20829 | 321 return ret; |
keir@20462 | 322 } |
keir@20462 | 323 |
ian@21930 | 324 int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, |
keir@20565 | 325 uint32_t domid, int fd, libxl_domain_build_state *state, |
keir@20565 | 326 libxl_device_model_info *dm_info) |
keir@20462 | 327 { |
gianni@22023 | 328 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20462 | 329 char **vments = NULL, **localents = NULL; |
keir@21438 | 330 struct timeval start_time; |
keir@21183 | 331 int i, ret, esave, flags; |
keir@20462 | 332 |
keir@20829 | 333 ret = build_pre(ctx, domid, info, state); |
gianni@22023 | 334 if (ret) |
gianni@22023 | 335 goto out; |
keir@20829 | 336 |
keir@20829 | 337 ret = restore_common(ctx, domid, info, state, fd); |
gianni@22023 | 338 if (ret) |
gianni@22023 | 339 goto out; |
keir@20829 | 340 |
keir@21438 | 341 gettimeofday(&start_time, NULL); |
keir@21438 | 342 |
keir@20462 | 343 if (info->hvm) { |
gianni@22023 | 344 vments = libxl_calloc(&gc, 7, sizeof(char *)); |
keir@20516 | 345 vments[0] = "rtc/timeoffset"; |
keir@20516 | 346 vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; |
keir@20565 | 347 vments[2] = "image/ostype"; |
keir@20565 | 348 vments[3] = "hvm"; |
keir@21438 | 349 vments[4] = "start_time"; |
gianni@22023 | 350 vments[5] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); |
keir@20462 | 351 } else { |
gianni@22023 | 352 vments = libxl_calloc(&gc, 11, sizeof(char *)); |
keir@20627 | 353 i = 0; |
keir@20627 | 354 vments[i++] = "image/ostype"; |
keir@20627 | 355 vments[i++] = "linux"; |
keir@20627 | 356 vments[i++] = "image/kernel"; |
Ian@21848 | 357 vments[i++] = (char*) info->kernel.path; |
keir@21438 | 358 vments[i++] = "start_time"; |
gianni@22023 | 359 vments[i++] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); |
Ian@21848 | 360 if (info->u.pv.ramdisk.path) { |
keir@20627 | 361 vments[i++] = "image/ramdisk"; |
Ian@21848 | 362 vments[i++] = (char*) info->u.pv.ramdisk.path; |
keir@20627 | 363 } |
keir@20627 | 364 if (info->u.pv.cmdline) { |
keir@20627 | 365 vments[i++] = "image/cmdline"; |
keir@20627 | 366 vments[i++] = (char*) info->u.pv.cmdline; |
keir@20627 | 367 } |
keir@20462 | 368 } |
keir@20829 | 369 ret = build_post(ctx, domid, info, state, vments, localents); |
gianni@22023 | 370 if (ret) |
gianni@22023 | 371 goto out; |
keir@20829 | 372 |
keir@21417 | 373 dm_info->saved_state = NULL; |
keir@21417 | 374 if (info->hvm) { |
keir@21417 | 375 ret = asprintf(&dm_info->saved_state, |
keir@21417 | 376 "/var/lib/xen/qemu-save.%d", domid); |
keir@21417 | 377 ret = (ret < 0) ? ERROR_FAIL : 0; |
keir@21417 | 378 } |
keir@21417 | 379 |
keir@20829 | 380 out: |
Ian@21848 | 381 libxl_file_reference_unmap(ctx, &info->kernel); |
Ian@21848 | 382 if (!info->hvm) |
Ian@21848 | 383 libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk); |
Ian@21848 | 384 |
keir@21183 | 385 esave = errno; |
keir@21183 | 386 |
keir@21183 | 387 flags = fcntl(fd, F_GETFL); |
keir@21183 | 388 if (flags == -1) { |
keir@21183 | 389 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unable to get flags on restore fd"); |
keir@21183 | 390 } else { |
keir@21183 | 391 flags &= ~O_NONBLOCK; |
keir@21183 | 392 if (fcntl(fd, F_SETFL, flags) == -1) |
keir@21183 | 393 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unable to put restore fd" |
keir@21183 | 394 " back to blocking mode"); |
keir@21183 | 395 } |
keir@21183 | 396 |
keir@21183 | 397 errno = esave; |
gianni@22023 | 398 libxl_free_all(&gc); |
keir@20829 | 399 return ret; |
keir@20462 | 400 } |
keir@20462 | 401 |
ian@21930 | 402 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) |
keir@20629 | 403 { |
gianni@22023 | 404 libxl_gc gc = LIBXL_INIT_GC(ctx); |
gianni@22023 | 405 int rc = 0; |
gianni@22023 | 406 |
keir@20629 | 407 if (is_hvm(ctx, domid)) { |
keir@20629 | 408 XL_LOG(ctx, XL_LOG_DEBUG, "Called domain_resume on " |
keir@20629 | 409 "non-cooperative hvm domain %u", domid); |
gianni@22023 | 410 rc = ERROR_NI; |
gianni@22023 | 411 goto out; |
keir@20629 | 412 } |
keir@20629 | 413 if (xc_domain_resume(ctx->xch, domid, 1)) { |
keir@20629 | 414 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, |
keir@20629 | 415 "xc_domain_resume failed for domain %u", |
keir@20629 | 416 domid); |
gianni@22023 | 417 rc = ERROR_FAIL; |
gianni@22023 | 418 goto out; |
keir@20629 | 419 } |
keir@20629 | 420 if (!xs_resume_domain(ctx->xsh, domid)) { |
keir@20629 | 421 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, |
keir@20629 | 422 "xs_resume_domain failed for domain %u", |
keir@20629 | 423 domid); |
gianni@22023 | 424 rc = ERROR_FAIL; |
keir@20629 | 425 } |
gianni@22023 | 426 out: |
gianni@22023 | 427 libxl_free_all(&gc); |
keir@20629 | 428 return 0; |
keir@20629 | 429 } |
keir@20629 | 430 |
ian@21920 | 431 /* |
ian@21920 | 432 * Preserves a domain but rewrites xenstore etc to make it unique so |
ian@21920 | 433 * that the domain can be restarted. |
ian@21920 | 434 * |
ian@21920 | 435 * Does not modify info so that it may be reused. |
ian@21920 | 436 */ |
ian@21930 | 437 int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, |
Ian@21969 | 438 libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid) |
ian@21920 | 439 { |
gianni@22023 | 440 libxl_gc gc = LIBXL_INIT_GC(ctx); |
ian@21920 | 441 struct xs_permissions roperm[2]; |
ian@21920 | 442 xs_transaction_t t; |
ian@21920 | 443 char *preserved_name; |
ian@21920 | 444 char *uuid_string; |
ian@21920 | 445 char *vm_path; |
ian@21920 | 446 char *dom_path; |
ian@21920 | 447 |
ian@21920 | 448 int rc; |
ian@21920 | 449 |
gianni@22023 | 450 preserved_name = libxl_sprintf(&gc, "%s%s", info->name, name_suffix); |
gianni@22023 | 451 if (!preserved_name) { |
gianni@22023 | 452 libxl_free_all(&gc); |
gianni@22023 | 453 return ERROR_NOMEM; |
gianni@22023 | 454 } |
ian@21920 | 455 |
gianni@22047 | 456 uuid_string = libxl_uuid2string(&gc, new_uuid); |
gianni@22023 | 457 if (!uuid_string) { |
gianni@22023 | 458 libxl_free_all(&gc); |
gianni@22023 | 459 return ERROR_NOMEM; |
gianni@22023 | 460 } |
gianni@22023 | 461 |
gianni@22023 | 462 dom_path = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 463 if (!dom_path) { |
gianni@22023 | 464 libxl_free_all(&gc); |
gianni@22023 | 465 return ERROR_FAIL; |
gianni@22023 | 466 } |
gianni@22023 | 467 |
gianni@22023 | 468 vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string); |
gianni@22023 | 469 if (!vm_path) { |
gianni@22023 | 470 libxl_free_all(&gc); |
gianni@22023 | 471 return ERROR_FAIL; |
gianni@22023 | 472 } |
ian@21920 | 473 |
ian@21920 | 474 roperm[0].id = 0; |
ian@21920 | 475 roperm[0].perms = XS_PERM_NONE; |
ian@21920 | 476 roperm[1].id = domid; |
ian@21920 | 477 roperm[1].perms = XS_PERM_READ; |
ian@21920 | 478 |
ian@21920 | 479 retry_transaction: |
ian@21920 | 480 t = xs_transaction_start(ctx->xsh); |
ian@21920 | 481 |
ian@21920 | 482 xs_rm(ctx->xsh, t, vm_path); |
ian@21920 | 483 xs_mkdir(ctx->xsh, t, vm_path); |
ian@21920 | 484 xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); |
ian@21920 | 485 |
gianni@22023 | 486 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); |
ian@21920 | 487 rc = libxl_domain_rename(ctx, domid, info->name, preserved_name, t); |
ian@21920 | 488 if (rc) return rc; |
ian@21920 | 489 |
gianni@22023 | 490 xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); |
ian@21920 | 491 |
ian@21920 | 492 if (!xs_transaction_end(ctx->xsh, t, 0)) |
ian@21920 | 493 if (errno == EAGAIN) |
ian@21920 | 494 goto retry_transaction; |
ian@21920 | 495 |
gianni@22023 | 496 libxl_free_all(&gc); |
ian@21920 | 497 return 0; |
ian@21920 | 498 } |
ian@21920 | 499 |
keir@21189 | 500 static void xcinfo2xlinfo(const xc_domaininfo_t *xcinfo, |
ian@21930 | 501 libxl_dominfo *xlinfo) |
ian@21895 | 502 { |
keir@21189 | 503 memcpy(&(xlinfo->uuid), xcinfo->handle, sizeof(xen_domain_handle_t)); |
keir@21189 | 504 xlinfo->domid = xcinfo->domain; |
keir@21189 | 505 |
ian@21895 | 506 xlinfo->dying = !!(xcinfo->flags&XEN_DOMINF_dying); |
ian@21895 | 507 xlinfo->shutdown = !!(xcinfo->flags&XEN_DOMINF_shutdown); |
ian@21895 | 508 xlinfo->paused = !!(xcinfo->flags&XEN_DOMINF_paused); |
ian@21895 | 509 xlinfo->blocked = !!(xcinfo->flags&XEN_DOMINF_blocked); |
ian@21895 | 510 xlinfo->running = !!(xcinfo->flags&XEN_DOMINF_running); |
ian@21914 | 511 |
ian@21914 | 512 if (xlinfo->shutdown || xlinfo->dying) |
ian@21914 | 513 xlinfo->shutdown_reason = (xcinfo->flags>>XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask; |
ian@21914 | 514 else |
ian@21914 | 515 xlinfo->shutdown_reason = ~0; |
ian@21895 | 516 |
keir@21189 | 517 xlinfo->max_memkb = PAGE_TO_MEMKB(xcinfo->tot_pages); |
keir@21189 | 518 xlinfo->cpu_time = xcinfo->cpu_time; |
keir@21189 | 519 xlinfo->vcpu_max_id = xcinfo->max_vcpu_id; |
keir@21189 | 520 xlinfo->vcpu_online = xcinfo->nr_online_vcpus; |
keir@21189 | 521 } |
keir@21189 | 522 |
ian@21930 | 523 libxl_dominfo * libxl_list_domain(libxl_ctx *ctx, int *nb_domain) |
keir@20462 | 524 { |
ian@21930 | 525 libxl_dominfo *ptr; |
keir@20867 | 526 int i, ret; |
keir@20822 | 527 xc_domaininfo_t info[1024]; |
keir@20822 | 528 int size = 1024; |
keir@20462 | 529 |
ian@21930 | 530 ptr = calloc(size, sizeof(libxl_dominfo)); |
gianni@21892 | 531 if (!ptr) { |
gianni@21892 | 532 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "allocating domain info"); |
gianni@21892 | 533 return NULL; |
gianni@21892 | 534 } |
keir@20822 | 535 |
keir@20860 | 536 ret = xc_domain_getinfolist(ctx->xch, 0, 1024, info); |
gianni@21892 | 537 if (ret<0) { |
gianni@21892 | 538 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "geting domain info list"); |
gianni@21892 | 539 return NULL; |
gianni@21892 | 540 } |
keir@20784 | 541 |
keir@21189 | 542 for (i = 0; i < ret; i++) { |
keir@21189 | 543 xcinfo2xlinfo(&info[i], &ptr[i]); |
keir@20462 | 544 } |
keir@20867 | 545 *nb_domain = ret; |
keir@20462 | 546 return ptr; |
keir@20462 | 547 } |
keir@20462 | 548 |
ian@21930 | 549 int libxl_domain_info(libxl_ctx *ctx, libxl_dominfo *info_r, |
keir@21189 | 550 uint32_t domid) { |
keir@21189 | 551 xc_domaininfo_t xcinfo; |
keir@21189 | 552 int ret; |
keir@21189 | 553 |
keir@21189 | 554 ret = xc_domain_getinfolist(ctx->xch, domid, 1, &xcinfo); |
gianni@21892 | 555 if (ret<0) { |
gianni@21892 | 556 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "geting domain info list"); |
gianni@21892 | 557 return ERROR_FAIL; |
gianni@21892 | 558 } |
keir@21189 | 559 if (ret==0 || xcinfo.domain != domid) return ERROR_INVAL; |
keir@21189 | 560 |
keir@21189 | 561 xcinfo2xlinfo(&xcinfo, info_r); |
keir@21189 | 562 return 0; |
keir@21189 | 563 } |
keir@21189 | 564 |
ian@21930 | 565 libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool) |
keir@21368 | 566 { |
ian@21930 | 567 libxl_poolinfo *ptr; |
keir@21368 | 568 int i, ret; |
keir@21368 | 569 xc_cpupoolinfo_t info[256]; |
keir@21368 | 570 int size = 256; |
keir@21368 | 571 |
ian@21930 | 572 ptr = calloc(size, sizeof(libxl_poolinfo)); |
gianni@21892 | 573 if (!ptr) { |
gianni@21892 | 574 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "allocating cpupool info"); |
gianni@21892 | 575 return NULL; |
gianni@21892 | 576 } |
keir@21368 | 577 |
keir@21368 | 578 ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info); |
gianni@21892 | 579 if (ret<0) { |
gianni@21892 | 580 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting cpupool info"); |
gianni@21892 | 581 return NULL; |
gianni@21892 | 582 } |
keir@21368 | 583 |
keir@21368 | 584 for (i = 0; i < ret; i++) { |
keir@21368 | 585 ptr[i].poolid = info[i].cpupool_id; |
keir@21368 | 586 } |
keir@21368 | 587 *nb_pool = ret; |
keir@21368 | 588 return ptr; |
keir@21368 | 589 } |
keir@21368 | 590 |
keir@20860 | 591 /* this API call only list VM running on this host. a VM can be an aggregate of multiple domains. */ |
ian@21930 | 592 libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm) |
keir@20860 | 593 { |
ian@21930 | 594 libxl_vminfo *ptr; |
keir@20860 | 595 int index, i, ret; |
keir@20860 | 596 xc_domaininfo_t info[1024]; |
keir@20860 | 597 int size = 1024; |
keir@20860 | 598 |
ian@21930 | 599 ptr = calloc(size, sizeof(libxl_dominfo)); |
keir@20860 | 600 if (!ptr) |
keir@20860 | 601 return NULL; |
keir@20860 | 602 |
keir@20860 | 603 ret = xc_domain_getinfolist(ctx->xch, 1, 1024, info); |
gianni@21892 | 604 if (ret<0) { |
gianni@21892 | 605 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "geting domain info list"); |
gianni@21892 | 606 return NULL; |
gianni@21892 | 607 } |
keir@20860 | 608 for (index = i = 0; i < ret; i++) { |
keir@20860 | 609 if (libxl_is_stubdom(ctx, info[i].domain, NULL)) |
keir@20860 | 610 continue; |
keir@20860 | 611 memcpy(&(ptr[index].uuid), info[i].handle, sizeof(xen_domain_handle_t)); |
keir@20860 | 612 ptr[index].domid = info[i].domain; |
keir@20860 | 613 |
keir@20860 | 614 index++; |
keir@20860 | 615 } |
keir@20860 | 616 *nb_vm = index; |
keir@20860 | 617 return ptr; |
keir@20860 | 618 } |
keir@20860 | 619 |
ian@21930 | 620 int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, |
keir@20462 | 621 uint32_t domid, int fd) |
keir@20462 | 622 { |
keir@20565 | 623 int hvm = is_hvm(ctx, domid); |
keir@20565 | 624 int live = info != NULL && info->flags & XL_SUSPEND_LIVE; |
keir@21543 | 625 int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG; |
gianni@22023 | 626 int rc = 0; |
keir@20462 | 627 |
keir@20462 | 628 core_suspend(ctx, domid, fd, hvm, live, debug); |
keir@20565 | 629 if (hvm) |
gianni@22023 | 630 rc = save_device_model(ctx, domid, fd); |
gianni@22023 | 631 return rc; |
keir@20462 | 632 } |
keir@20462 | 633 |
ian@21930 | 634 int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 635 { |
gianni@21892 | 636 int ret; |
gianni@21892 | 637 ret = xc_domain_pause(ctx->xch, domid); |
gianni@21892 | 638 if (ret<0) { |
gianni@21892 | 639 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "pausing domain %d", domid); |
gianni@21892 | 640 return ERROR_FAIL; |
gianni@21892 | 641 } |
Ian@21888 | 642 return 0; |
keir@20462 | 643 } |
keir@20462 | 644 |
ian@21930 | 645 int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid, |
gianni@21892 | 646 const char *filename) |
sstabellini@21870 | 647 { |
gianni@21892 | 648 int ret; |
gianni@21892 | 649 ret = xc_domain_dumpcore(ctx->xch, domid, filename); |
gianni@21892 | 650 if (ret<0) { |
gianni@21892 | 651 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "core dumping domain %d to %s", |
gianni@21892 | 652 domid, filename); |
Ian@21888 | 653 return ERROR_FAIL; |
gianni@21892 | 654 } |
Ian@21888 | 655 return 0; |
sstabellini@21870 | 656 } |
sstabellini@21870 | 657 |
ian@21930 | 658 int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 659 { |
gianni@22023 | 660 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20779 | 661 char *path; |
keir@20565 | 662 char *state; |
gianni@22023 | 663 int ret, rc = 0; |
keir@20565 | 664 |
keir@20565 | 665 if (is_hvm(ctx, domid)) { |
gianni@22023 | 666 path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d/state", domid); |
gianni@22023 | 667 state = libxl_xs_read(&gc, XBT_NULL, path); |
keir@20565 | 668 if (state != NULL && !strcmp(state, "paused")) { |
gianni@22023 | 669 libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "continue"); |
keir@20565 | 670 libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL); |
keir@20565 | 671 } |
keir@20565 | 672 } |
gianni@21892 | 673 ret = xc_domain_unpause(ctx->xch, domid); |
gianni@21892 | 674 if (ret<0) { |
gianni@21892 | 675 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unpausing domain %d", domid); |
gianni@22023 | 676 rc = ERROR_FAIL; |
gianni@21892 | 677 } |
gianni@22023 | 678 libxl_free_all(&gc); |
gianni@22023 | 679 return rc; |
keir@20462 | 680 } |
keir@20462 | 681 |
keir@20462 | 682 static char *req_table[] = { |
keir@20462 | 683 [0] = "poweroff", |
keir@20462 | 684 [1] = "reboot", |
keir@20462 | 685 [2] = "suspend", |
keir@20462 | 686 [3] = "crash", |
keir@20462 | 687 [4] = "halt", |
keir@20462 | 688 }; |
keir@20462 | 689 |
ian@21930 | 690 int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req) |
keir@20462 | 691 { |
gianni@22023 | 692 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20462 | 693 char *shutdown_path; |
keir@20462 | 694 char *dom_path; |
keir@20462 | 695 |
gianni@22023 | 696 if (req > ARRAY_SIZE(req_table)) { |
gianni@22023 | 697 libxl_free_all(&gc); |
keir@20462 | 698 return ERROR_INVAL; |
gianni@22023 | 699 } |
gianni@22023 | 700 |
gianni@22023 | 701 dom_path = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 702 if (!dom_path) { |
gianni@22023 | 703 libxl_free_all(&gc); |
keir@20512 | 704 return ERROR_FAIL; |
gianni@22023 | 705 } |
gianni@22023 | 706 |
gianni@22023 | 707 shutdown_path = libxl_sprintf(&gc, "%s/control/shutdown", dom_path); |
keir@20462 | 708 |
keir@20462 | 709 xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req])); |
keir@21552 | 710 if (is_hvm(ctx,domid)) { |
keir@20462 | 711 unsigned long acpi_s_state = 0; |
keir@20462 | 712 unsigned long pvdriver = 0; |
gianni@21892 | 713 int ret; |
gianni@21892 | 714 ret = xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state); |
gianni@21892 | 715 if (ret<0) { |
gianni@21892 | 716 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting ACPI S-state"); |
gianni@21892 | 717 return ERROR_FAIL; |
gianni@21892 | 718 } |
gianni@21892 | 719 ret = xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver); |
gianni@21892 | 720 if (ret<0) { |
gianni@21892 | 721 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting HVM callback IRQ"); |
gianni@21892 | 722 return ERROR_FAIL; |
gianni@21892 | 723 } |
gianni@21892 | 724 if (!pvdriver || acpi_s_state != 0) { |
gianni@21892 | 725 ret = xc_domain_shutdown(ctx->xch, domid, req); |
gianni@21892 | 726 if (ret<0) { |
gianni@21892 | 727 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unpausing domain"); |
gianni@21892 | 728 return ERROR_FAIL; |
gianni@21892 | 729 } |
gianni@21892 | 730 } |
keir@20462 | 731 } |
gianni@22023 | 732 libxl_free_all(&gc); |
Ian@21888 | 733 return 0; |
keir@20462 | 734 } |
keir@20462 | 735 |
ian@21930 | 736 int libxl_get_wait_fd(libxl_ctx *ctx, int *fd) |
keir@20545 | 737 { |
keir@20545 | 738 *fd = xs_fileno(ctx->xsh); |
keir@20545 | 739 return 0; |
keir@20545 | 740 } |
keir@20545 | 741 |
ian@21930 | 742 int libxl_wait_for_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter) |
keir@20637 | 743 { |
keir@20637 | 744 waiter->path = strdup("@releaseDomain"); |
ian@21913 | 745 if (asprintf(&(waiter->token), "%d", LIBXL_EVENT_DOMAIN_DEATH) < 0) |
keir@21417 | 746 return -1; |
keir@20637 | 747 if (!xs_watch(ctx->xsh, waiter->path, waiter->token)) |
keir@20637 | 748 return -1; |
keir@20637 | 749 return 0; |
keir@20637 | 750 } |
keir@20637 | 751 |
ian@21930 | 752 int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t guest_domid, libxl_device_disk *disks, int num_disks, libxl_waiter *waiter) |
keir@20637 | 753 { |
gianni@22023 | 754 libxl_gc gc = LIBXL_INIT_GC(ctx); |
gianni@22023 | 755 int i, rc = -1; |
keir@20637 | 756 uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid); |
keir@20637 | 757 |
keir@20637 | 758 if (!domid) |
keir@20637 | 759 domid = guest_domid; |
keir@20637 | 760 |
keir@20637 | 761 for (i = 0; i < num_disks; i++) { |
keir@21417 | 762 if (asprintf(&(waiter[i].path), "%s/device/vbd/%d/eject", |
gianni@22023 | 763 libxl_xs_get_dompath(&gc, domid), |
keir@21417 | 764 device_disk_dev_number(disks[i].virtpath)) < 0) |
gianni@22023 | 765 goto out; |
ian@21913 | 766 if (asprintf(&(waiter[i].token), "%d", LIBXL_EVENT_DISK_EJECT) < 0) |
gianni@22023 | 767 goto out; |
keir@20637 | 768 xs_watch(ctx->xsh, waiter->path, waiter->token); |
keir@20637 | 769 } |
gianni@22023 | 770 rc = 0; |
gianni@22023 | 771 out: |
gianni@22023 | 772 libxl_free_all(&gc); |
gianni@22023 | 773 return rc; |
keir@20637 | 774 } |
keir@20637 | 775 |
ian@21930 | 776 int libxl_get_event(libxl_ctx *ctx, libxl_event *event) |
keir@20545 | 777 { |
keir@20545 | 778 unsigned int num; |
keir@20637 | 779 char **events = xs_read_watch(ctx->xsh, &num); |
keir@20637 | 780 if (num != 2) { |
keir@20637 | 781 free(events); |
gianni@21892 | 782 return ERROR_FAIL; |
keir@20637 | 783 } |
keir@20637 | 784 event->path = strdup(events[XS_WATCH_PATH]); |
keir@20637 | 785 event->token = strdup(events[XS_WATCH_TOKEN]); |
keir@20637 | 786 event->type = atoi(event->token); |
keir@20637 | 787 free(events); |
keir@20637 | 788 return 0; |
keir@20637 | 789 } |
keir@20637 | 790 |
ian@21930 | 791 int libxl_stop_waiting(libxl_ctx *ctx, libxl_waiter *waiter) |
keir@20637 | 792 { |
keir@20637 | 793 if (!xs_unwatch(ctx->xsh, waiter->path, waiter->token)) |
gianni@21892 | 794 return ERROR_FAIL; |
keir@20637 | 795 else |
keir@20637 | 796 return 0; |
keir@20637 | 797 } |
keir@20637 | 798 |
keir@20637 | 799 int libxl_free_event(libxl_event *event) |
keir@20637 | 800 { |
keir@20637 | 801 free(event->path); |
keir@20637 | 802 free(event->token); |
keir@20637 | 803 return 0; |
keir@20637 | 804 } |
keir@20637 | 805 |
keir@20637 | 806 int libxl_free_waiter(libxl_waiter *waiter) |
keir@20637 | 807 { |
keir@20637 | 808 free(waiter->path); |
keir@20637 | 809 free(waiter->token); |
keir@20637 | 810 return 0; |
keir@20637 | 811 } |
keir@20637 | 812 |
ian@21930 | 813 int libxl_event_get_domain_death_info(libxl_ctx *ctx, uint32_t domid, libxl_event *event, libxl_dominfo *info) |
keir@20637 | 814 { |
ian@21916 | 815 if (libxl_domain_info(ctx, info, domid) < 0) |
ian@21916 | 816 return 0; |
ian@21916 | 817 |
ian@21916 | 818 if (info->running || (!info->shutdown && !info->dying)) |
ian@21916 | 819 return ERROR_INVAL; |
ian@21916 | 820 |
ian@21916 | 821 return 1; |
keir@20545 | 822 } |
keir@20545 | 823 |
ian@21930 | 824 int libxl_event_get_disk_eject_info(libxl_ctx *ctx, uint32_t domid, libxl_event *event, libxl_device_disk *disk) |
keir@20637 | 825 { |
gianni@22023 | 826 libxl_gc gc = LIBXL_INIT_GC(ctx); |
ian@21916 | 827 char *path; |
ian@21916 | 828 char *backend; |
ian@21916 | 829 char *value; |
ian@21916 | 830 |
gianni@22023 | 831 value = libxl_xs_read(&gc, XBT_NULL, event->path); |
gianni@22023 | 832 |
gianni@22023 | 833 if (!value || strcmp(value, "eject")) { |
gianni@22023 | 834 libxl_free_all(&gc); |
ian@21916 | 835 return 0; |
gianni@22023 | 836 } |
ian@21916 | 837 |
ian@21916 | 838 path = strdup(event->path); |
ian@21916 | 839 path[strlen(path) - 6] = '\0'; |
gianni@22023 | 840 backend = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", path)); |
ian@21916 | 841 |
ian@21916 | 842 disk->backend_domid = 0; |
ian@21916 | 843 disk->domid = domid; |
ian@21916 | 844 disk->physpath = NULL; |
ian@21916 | 845 disk->phystype = 0; |
ian@21916 | 846 /* this value is returned to the user: do not free right away */ |
gianni@22023 | 847 disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", backend)); |
ian@21916 | 848 disk->unpluggable = 1; |
ian@21916 | 849 disk->readwrite = 0; |
ian@21916 | 850 disk->is_cdrom = 1; |
ian@21916 | 851 |
ian@21916 | 852 free(path); |
gianni@22023 | 853 libxl_free_all(&gc); |
ian@21916 | 854 return 1; |
keir@20637 | 855 } |
keir@20637 | 856 |
ian@21930 | 857 static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 858 { |
gianni@22023 | 859 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20462 | 860 char *pid; |
keir@20462 | 861 int ret; |
keir@20462 | 862 |
gianni@22023 | 863 pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid)); |
keir@20462 | 864 if (!pid) { |
keir@20542 | 865 int stubdomid = libxl_get_stubdom_id(ctx, domid); |
keir@20542 | 866 if (!stubdomid) { |
keir@20542 | 867 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't find device model's pid"); |
gianni@22023 | 868 ret = ERROR_INVAL; |
gianni@22023 | 869 goto out; |
keir@20542 | 870 } |
keir@20542 | 871 XL_LOG(ctx, XL_LOG_ERROR, "Device model is a stubdom, domid=%d\n", stubdomid); |
gianni@22023 | 872 ret = libxl_domain_destroy(ctx, stubdomid, 0); |
gianni@22023 | 873 goto out; |
keir@20462 | 874 } |
gianni@22023 | 875 xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", domid)); |
keir@20462 | 876 |
keir@20462 | 877 ret = kill(atoi(pid), SIGHUP); |
keir@20462 | 878 if (ret < 0 && errno == ESRCH) { |
keir@20512 | 879 XL_LOG(ctx, XL_LOG_DEBUG, "Device Model already exited"); |
keir@20462 | 880 ret = 0; |
keir@20462 | 881 } else if (ret == 0) { |
keir@20512 | 882 XL_LOG(ctx, XL_LOG_DEBUG, "Device Model signaled"); |
keir@20462 | 883 ret = 0; |
keir@20462 | 884 } else { |
keir@20512 | 885 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to kill Device Model [%d]", |
keir@20512 | 886 atoi(pid)); |
keir@20462 | 887 } |
gianni@22023 | 888 out: |
gianni@22023 | 889 libxl_free_all(&gc); |
keir@20462 | 890 return ret; |
keir@20462 | 891 } |
keir@20462 | 892 |
ian@21930 | 893 int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force) |
keir@20462 | 894 { |
gianni@22023 | 895 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20801 | 896 char *dom_path; |
ian@21894 | 897 char *vm_path; |
keir@20628 | 898 int rc, dm_present; |
keir@20628 | 899 |
keir@20628 | 900 if (is_hvm(ctx, domid)) { |
keir@20628 | 901 dm_present = 1; |
keir@20628 | 902 } else { |
keir@20628 | 903 char *pid; |
gianni@22023 | 904 pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid)); |
keir@20628 | 905 dm_present = (pid != NULL); |
keir@20628 | 906 } |
keir@20462 | 907 |
gianni@22023 | 908 dom_path = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 909 if (!dom_path) { |
gianni@22023 | 910 rc = ERROR_FAIL; |
gianni@22023 | 911 goto out; |
gianni@22023 | 912 } |
keir@20512 | 913 |
keir@20482 | 914 if (libxl_device_pci_shutdown(ctx, domid) < 0) |
keir@20512 | 915 XL_LOG(ctx, XL_LOG_ERROR, "pci shutdown failed for domid %d", domid); |
keir@20628 | 916 if (dm_present) { |
keir@20628 | 917 xs_write(ctx->xsh, XBT_NULL, |
gianni@22023 | 918 libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), |
keir@20628 | 919 "shutdown", strlen("shutdown")); |
keir@20628 | 920 } |
keir@20512 | 921 rc = xc_domain_pause(ctx->xch, domid); |
keir@20512 | 922 if (rc < 0) { |
keir@20512 | 923 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); |
keir@20462 | 924 } |
keir@20628 | 925 if (dm_present) { |
keir@20628 | 926 if (libxl_destroy_device_model(ctx, domid) < 0) |
keir@20628 | 927 XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d", domid); |
keir@20628 | 928 } |
keir@20462 | 929 if (libxl_devices_destroy(ctx, domid, force) < 0) |
keir@20512 | 930 XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", domid); |
ian@21891 | 931 |
gianni@22023 | 932 vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dom_path)); |
keir@20823 | 933 if (vm_path) |
keir@20823 | 934 if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) |
keir@20823 | 935 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path); |
keir@20779 | 936 |
ian@21891 | 937 if (!xs_rm(ctx->xsh, XBT_NULL, dom_path)) |
ian@21891 | 938 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", dom_path); |
ian@21891 | 939 |
keir@21190 | 940 libxl__userdata_destroyall(ctx, domid); |
keir@21190 | 941 |
keir@20545 | 942 rc = xc_domain_destroy(ctx->xch, domid); |
keir@20545 | 943 if (rc < 0) { |
keir@20545 | 944 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); |
gianni@22023 | 945 rc = ERROR_FAIL; |
gianni@22023 | 946 goto out; |
keir@20545 | 947 } |
gianni@22023 | 948 rc = 0; |
gianni@22023 | 949 out: |
gianni@22023 | 950 libxl_free_all(&gc); |
keir@20462 | 951 return 0; |
keir@20462 | 952 } |
keir@20462 | 953 |
stefano@22040 | 954 int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, libxl_console_constype type) |
keir@20564 | 955 { |
gianni@22023 | 956 libxl_gc gc = LIBXL_INIT_GC(ctx); |
gianni@22023 | 957 char *p = libxl_sprintf(&gc, "%s/xenconsole", libxl_private_bindir_path()); |
gianni@22023 | 958 char *domid_s = libxl_sprintf(&gc, "%d", domid); |
gianni@22023 | 959 char *cons_num_s = libxl_sprintf(&gc, "%d", cons_num); |
stefano@22040 | 960 char *cons_type_s; |
stefano@22040 | 961 |
stefano@22040 | 962 if (type == LIBXL_CONSTYPE_PV) |
stefano@22040 | 963 cons_type_s = "pv"; |
stefano@22040 | 964 else |
stefano@22040 | 965 cons_type_s = "serial"; |
stefano@22040 | 966 |
stefano@22040 | 967 execl(p, p, domid_s, "--num", cons_num_s, "--type", cons_type_s, (void *)NULL); |
gianni@22023 | 968 libxl_free_all(&gc); |
gianni@22023 | 969 return ERROR_FAIL; |
keir@20564 | 970 } |
keir@20564 | 971 |
ian@21930 | 972 int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) |
sstabellini@21867 | 973 { |
sstabellini@21867 | 974 uint32_t stubdomid = libxl_get_stubdom_id(ctx, domid_vm); |
sstabellini@21867 | 975 if (stubdomid) |
stefano@22040 | 976 return libxl_console_exec(ctx, stubdomid, 1, LIBXL_CONSTYPE_PV); |
stefano@22040 | 977 else { |
stefano@22040 | 978 if (is_hvm(ctx, domid_vm)) |
stefano@22040 | 979 return libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSTYPE_SERIAL); |
stefano@22040 | 980 else |
stefano@22040 | 981 return libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSTYPE_PV); |
stefano@22040 | 982 } |
sstabellini@21867 | 983 } |
sstabellini@21867 | 984 |
ian@21930 | 985 int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) |
sstabellini@21879 | 986 { |
gianni@22023 | 987 libxl_gc gc = LIBXL_INIT_GC(ctx); |
sstabellini@21879 | 988 const char *vnc_port, *vfb_back; |
sstabellini@21879 | 989 const char *vnc_listen = NULL, *vnc_pass = NULL; |
sstabellini@21879 | 990 int port = 0, autopass_fd = -1; |
sstabellini@21879 | 991 char *vnc_bin, *args[] = { |
sstabellini@21879 | 992 "vncviewer", |
sstabellini@21879 | 993 NULL, /* hostname:display */ |
sstabellini@21879 | 994 NULL, /* -autopass */ |
sstabellini@21879 | 995 NULL, |
sstabellini@21879 | 996 }; |
sstabellini@21879 | 997 |
gianni@22023 | 998 vnc_port = libxl_xs_read(&gc, XBT_NULL, |
gianni@22023 | 999 libxl_sprintf(&gc, |
sstabellini@21879 | 1000 "/local/domain/%d/console/vnc-port", domid)); |
sstabellini@21879 | 1001 if ( vnc_port ) |
sstabellini@21879 | 1002 port = atoi(vnc_port) - 5900; |
sstabellini@21879 | 1003 |
gianni@22023 | 1004 vfb_back = libxl_xs_read(&gc, XBT_NULL, |
gianni@22023 | 1005 libxl_sprintf(&gc, |
sstabellini@21879 | 1006 "/local/domain/%d/device/vfb/0/backend", domid)); |
sstabellini@21879 | 1007 if ( vfb_back ) { |
gianni@22023 | 1008 vnc_listen = libxl_xs_read(&gc, XBT_NULL, |
gianni@22023 | 1009 libxl_sprintf(&gc, |
sstabellini@21879 | 1010 "/local/domain/%d/console/vnc-listen", domid)); |
sstabellini@21879 | 1011 if ( autopass ) |
gianni@22023 | 1012 vnc_pass = libxl_xs_read(&gc, XBT_NULL, |
gianni@22023 | 1013 libxl_sprintf(&gc, |
sstabellini@21879 | 1014 "/local/domain/%d/console/vnc-pass", domid)); |
sstabellini@21879 | 1015 } |
sstabellini@21879 | 1016 |
sstabellini@21879 | 1017 if ( NULL == vnc_listen ) |
sstabellini@21879 | 1018 vnc_listen = "localhost"; |
sstabellini@21879 | 1019 |
sstabellini@21879 | 1020 if ( (vnc_bin = getenv("VNCVIEWER")) ) |
sstabellini@21879 | 1021 args[0] = vnc_bin; |
sstabellini@21879 | 1022 |
gianni@22023 | 1023 args[1] = libxl_sprintf(&gc, "%s:%d", vnc_listen, port); |
sstabellini@21879 | 1024 |
sstabellini@21879 | 1025 if ( vnc_pass ) { |
sstabellini@21879 | 1026 char tmpname[] = "/tmp/vncautopass.XXXXXX"; |
sstabellini@21879 | 1027 autopass_fd = mkstemp(tmpname); |
sstabellini@21879 | 1028 if ( autopass_fd < 0 ) |
sstabellini@21879 | 1029 goto skip_autopass; |
sstabellini@21879 | 1030 |
sstabellini@21879 | 1031 if ( unlink(tmpname) ) |
sstabellini@21879 | 1032 /* should never happen */ |
sstabellini@21879 | 1033 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unlink %s failed", tmpname); |
sstabellini@21879 | 1034 |
sstabellini@21879 | 1035 if ( libxl_write_exactly(ctx, autopass_fd, vnc_pass, strlen(vnc_pass), |
sstabellini@21879 | 1036 tmpname, "vnc password") ) { |
sstabellini@21879 | 1037 do { close(autopass_fd); } while(errno == EINTR); |
sstabellini@21879 | 1038 goto skip_autopass; |
sstabellini@21879 | 1039 } |
sstabellini@21879 | 1040 |
sstabellini@21879 | 1041 args[2] = "-autopass"; |
sstabellini@21879 | 1042 } |
sstabellini@21879 | 1043 |
sstabellini@21879 | 1044 skip_autopass: |
gianni@22023 | 1045 libxl_free_all(&gc); |
sstabellini@21879 | 1046 libxl_exec(autopass_fd, -1, -1, args[0], args); |
sstabellini@21879 | 1047 return 0; |
sstabellini@21879 | 1048 } |
sstabellini@21879 | 1049 |
gianni@22023 | 1050 static char ** libxl_build_device_model_args_old(libxl_gc *gc, |
keir@20462 | 1051 libxl_device_model_info *info, |
keir@20462 | 1052 libxl_device_nic *vifs, |
keir@20462 | 1053 int num_vifs) |
keir@20462 | 1054 { |
keir@20462 | 1055 int num = 0, i; |
keir@20462 | 1056 flexarray_t *dm_args; |
keir@20462 | 1057 dm_args = flexarray_make(16, 1); |
gianni@22023 | 1058 |
keir@20462 | 1059 if (!dm_args) |
keir@20462 | 1060 return NULL; |
keir@20462 | 1061 |
keir@20516 | 1062 flexarray_set(dm_args, num++, "qemu-dm"); |
keir@20516 | 1063 flexarray_set(dm_args, num++, "-d"); |
keir@20462 | 1064 |
gianni@22023 | 1065 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid)); |
keir@20462 | 1066 |
keir@20462 | 1067 if (info->dom_name) { |
keir@20516 | 1068 flexarray_set(dm_args, num++, "-domain-name"); |
keir@20516 | 1069 flexarray_set(dm_args, num++, info->dom_name); |
keir@20462 | 1070 } |
keir@20462 | 1071 if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { |
keir@20516 | 1072 flexarray_set(dm_args, num++, "-vnc"); |
keir@20462 | 1073 if (info->vncdisplay) { |
keir@20462 | 1074 if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { |
keir@21362 | 1075 flexarray_set( |
keir@21362 | 1076 dm_args, num++, |
gianni@22023 | 1077 libxl_sprintf(gc, "%s:%d%s", |
keir@21362 | 1078 info->vnclisten, |
keir@21362 | 1079 info->vncdisplay, |
keir@21362 | 1080 info->vncpasswd ? ",password" : "")); |
keir@20462 | 1081 } else { |
gianni@22023 | 1082 flexarray_set(dm_args, num++, libxl_sprintf(gc, "127.0.0.1:%d", info->vncdisplay)); |
keir@20462 | 1083 } |
keir@20462 | 1084 } else if (info->vnclisten) { |
keir@20462 | 1085 if (strchr(info->vnclisten, ':') != NULL) { |
keir@20516 | 1086 flexarray_set(dm_args, num++, info->vnclisten); |
keir@20462 | 1087 } else { |
gianni@22023 | 1088 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%s:0", info->vnclisten)); |
keir@20462 | 1089 } |
keir@20462 | 1090 } else { |
keir@20516 | 1091 flexarray_set(dm_args, num++, "127.0.0.1:0"); |
keir@20462 | 1092 } |
keir@20462 | 1093 if (info->vncunused) { |
keir@20516 | 1094 flexarray_set(dm_args, num++, "-vncunused"); |
keir@20462 | 1095 } |
keir@20462 | 1096 } |
keir@21378 | 1097 if (info->sdl) { |
keir@20516 | 1098 flexarray_set(dm_args, num++, "-sdl"); |
keir@20462 | 1099 if (info->opengl) { |
keir@20516 | 1100 flexarray_set(dm_args, num++, "-disable-opengl"); |
keir@20462 | 1101 } |
keir@20462 | 1102 } |
keir@20462 | 1103 if (info->keymap) { |
keir@20516 | 1104 flexarray_set(dm_args, num++, "-k"); |
keir@20516 | 1105 flexarray_set(dm_args, num++, info->keymap); |
keir@20462 | 1106 } |
keir@20462 | 1107 if (info->nographic && (!info->sdl && !info->vnc)) { |
keir@20516 | 1108 flexarray_set(dm_args, num++, "-nographic"); |
keir@20462 | 1109 } |
keir@20462 | 1110 if (info->serial) { |
keir@20516 | 1111 flexarray_set(dm_args, num++, "-serial"); |
keir@20516 | 1112 flexarray_set(dm_args, num++, info->serial); |
keir@20462 | 1113 } |
keir@20509 | 1114 if (info->type == XENFV) { |
Ian@21733 | 1115 int ioemu_vifs = 0; |
Ian@21733 | 1116 |
keir@20509 | 1117 if (info->videoram) { |
keir@20516 | 1118 flexarray_set(dm_args, num++, "-videoram"); |
gianni@22023 | 1119 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->videoram)); |
keir@20509 | 1120 } |
keir@20509 | 1121 if (info->stdvga) { |
keir@20516 | 1122 flexarray_set(dm_args, num++, "-std-vga"); |
keir@20509 | 1123 } |
keir@20509 | 1124 |
keir@20509 | 1125 if (info->boot) { |
keir@20516 | 1126 flexarray_set(dm_args, num++, "-boot"); |
keir@20516 | 1127 flexarray_set(dm_args, num++, info->boot); |
keir@20509 | 1128 } |
stefano@21890 | 1129 if (info->usb || info->usbdevice) { |
keir@20516 | 1130 flexarray_set(dm_args, num++, "-usb"); |
keir@20509 | 1131 if (info->usbdevice) { |
keir@20516 | 1132 flexarray_set(dm_args, num++, "-usbdevice"); |
keir@20516 | 1133 flexarray_set(dm_args, num++, info->usbdevice); |
keir@20509 | 1134 } |
keir@20509 | 1135 } |
Ian@21801 | 1136 if (info->soundhw) { |
Ian@21801 | 1137 flexarray_set(dm_args, num++, "-soundhw"); |
Ian@21801 | 1138 flexarray_set(dm_args, num++, info->soundhw); |
Ian@21801 | 1139 } |
keir@20509 | 1140 if (info->apic) { |
keir@20516 | 1141 flexarray_set(dm_args, num++, "-acpi"); |
keir@20509 | 1142 } |
keir@21570 | 1143 if (info->vcpus > 1) { |
keir@21570 | 1144 flexarray_set(dm_args, num++, "-vcpus"); |
gianni@22023 | 1145 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->vcpus)); |
keir@21570 | 1146 } |
keir@21570 | 1147 if (info->vcpu_avail) { |
keir@21570 | 1148 flexarray_set(dm_args, num++, "-vcpu_avail"); |
gianni@22023 | 1149 flexarray_set(dm_args, num++, libxl_sprintf(gc, "0x%x", info->vcpu_avail)); |
keir@21570 | 1150 } |
keir@20509 | 1151 for (i = 0; i < num_vifs; i++) { |
keir@20509 | 1152 if (vifs[i].nictype == NICTYPE_IOEMU) { |
gianni@22023 | 1153 char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@20780 | 1154 vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], |
keir@20780 | 1155 vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); |
keir@20781 | 1156 if (!vifs[i].ifname) |
gianni@22023 | 1157 vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid); |
keir@20516 | 1158 flexarray_set(dm_args, num++, "-net"); |
gianni@22023 | 1159 flexarray_set(dm_args, num++, libxl_sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s", |
keir@20780 | 1160 vifs[i].devid, smac, vifs[i].model)); |
keir@20516 | 1161 flexarray_set(dm_args, num++, "-net"); |
gianni@22023 | 1162 flexarray_set(dm_args, num++, libxl_sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no", |
keir@20509 | 1163 vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); |
Ian@21733 | 1164 ioemu_vifs++; |
keir@20509 | 1165 } |
keir@20462 | 1166 } |
Ian@21733 | 1167 /* If we have no emulated nics, tell qemu not to create any */ |
Ian@21733 | 1168 if ( ioemu_vifs == 0 ) { |
Ian@21733 | 1169 flexarray_set(dm_args, num++, "-net"); |
Ian@21733 | 1170 flexarray_set(dm_args, num++, "none"); |
Ian@21733 | 1171 } |
keir@20462 | 1172 } |
keir@20565 | 1173 if (info->saved_state) { |
keir@20565 | 1174 flexarray_set(dm_args, num++, "-loadvm"); |
keir@20565 | 1175 flexarray_set(dm_args, num++, info->saved_state); |
keir@20565 | 1176 } |
keir@20509 | 1177 for (i = 0; info->extra && info->extra[i] != NULL; i++) |
keir@20509 | 1178 flexarray_set(dm_args, num++, info->extra[i]); |
keir@20516 | 1179 flexarray_set(dm_args, num++, "-M"); |
keir@20509 | 1180 if (info->type == XENPV) |
keir@20516 | 1181 flexarray_set(dm_args, num++, "xenpv"); |
keir@20509 | 1182 else |
keir@20516 | 1183 flexarray_set(dm_args, num++, "xenfv"); |
keir@20462 | 1184 flexarray_set(dm_args, num++, NULL); |
keir@20462 | 1185 return (char **) flexarray_contents(dm_args); |
keir@20462 | 1186 } |
keir@20462 | 1187 |
gianni@22023 | 1188 static char ** libxl_build_device_model_args_new(libxl_gc *gc, |
anthony@21989 | 1189 libxl_device_model_info *info, |
anthony@21989 | 1190 libxl_device_nic *vifs, |
anthony@21989 | 1191 int num_vifs) |
anthony@21989 | 1192 { |
anthony@21989 | 1193 int num = 0, i; |
anthony@21989 | 1194 flexarray_t *dm_args; |
anthony@21989 | 1195 int nb; |
anthony@21989 | 1196 libxl_device_disk *disks; |
anthony@21989 | 1197 |
anthony@21989 | 1198 dm_args = flexarray_make(16, 1); |
anthony@21989 | 1199 if (!dm_args) |
anthony@21989 | 1200 return NULL; |
anthony@21989 | 1201 |
anthony@21989 | 1202 flexarray_set(dm_args, num++, "qemu-system-xen"); |
anthony@21989 | 1203 flexarray_set(dm_args, num++, "-xen-domid"); |
anthony@21989 | 1204 |
gianni@22023 | 1205 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid)); |
anthony@21989 | 1206 |
anthony@21989 | 1207 if (info->dom_name) { |
anthony@21989 | 1208 flexarray_set(dm_args, num++, "-name"); |
anthony@21989 | 1209 flexarray_set(dm_args, num++, info->dom_name); |
anthony@21989 | 1210 } |
anthony@21989 | 1211 if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { |
anthony@21989 | 1212 int display = 0; |
anthony@21989 | 1213 const char *listen = "127.0.0.1"; |
anthony@21989 | 1214 |
anthony@21989 | 1215 flexarray_set(dm_args, num++, "-vnc"); |
anthony@21989 | 1216 |
anthony@21989 | 1217 if (info->vncdisplay) { |
anthony@21989 | 1218 display = info->vncdisplay; |
anthony@21989 | 1219 if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { |
anthony@21989 | 1220 listen = info->vnclisten; |
anthony@21989 | 1221 } |
anthony@21989 | 1222 } else if (info->vnclisten) { |
anthony@21989 | 1223 listen = info->vnclisten; |
anthony@21989 | 1224 } |
anthony@21989 | 1225 |
anthony@21989 | 1226 if (strchr(listen, ':') != NULL) |
anthony@21989 | 1227 flexarray_set(dm_args, num++, |
gianni@22023 | 1228 libxl_sprintf(gc, "%s%s", listen, |
anthony@21989 | 1229 info->vncunused ? ",to=99" : "")); |
anthony@21989 | 1230 else |
anthony@21989 | 1231 flexarray_set(dm_args, num++, |
gianni@22023 | 1232 libxl_sprintf(gc, "%s:%d%s", listen, display, |
anthony@21989 | 1233 info->vncunused ? ",to=99" : "")); |
anthony@21989 | 1234 } |
anthony@21989 | 1235 if (info->sdl) { |
anthony@21989 | 1236 flexarray_set(dm_args, num++, "-sdl"); |
anthony@21989 | 1237 } |
anthony@21989 | 1238 if (info->keymap) { |
anthony@21989 | 1239 flexarray_set(dm_args, num++, "-k"); |
anthony@21989 | 1240 flexarray_set(dm_args, num++, info->keymap); |
anthony@21989 | 1241 } |
anthony@21989 | 1242 if (info->nographic && (!info->sdl && !info->vnc)) { |
anthony@21989 | 1243 flexarray_set(dm_args, num++, "-nographic"); |
anthony@21989 | 1244 } |
anthony@21989 | 1245 if (info->serial) { |
anthony@21989 | 1246 flexarray_set(dm_args, num++, "-serial"); |
anthony@21989 | 1247 flexarray_set(dm_args, num++, info->serial); |
anthony@21989 | 1248 } |
anthony@21989 | 1249 if (info->type == XENFV) { |
anthony@21989 | 1250 int ioemu_vifs = 0; |
anthony@21989 | 1251 |
anthony@21989 | 1252 if (info->stdvga) { |
anthony@21989 | 1253 flexarray_set(dm_args, num++, "-vga"); |
anthony@21989 | 1254 flexarray_set(dm_args, num++, "std"); |
anthony@21989 | 1255 } |
anthony@21989 | 1256 |
anthony@21989 | 1257 if (info->boot) { |
anthony@21989 | 1258 flexarray_set(dm_args, num++, "-boot"); |
gianni@22023 | 1259 flexarray_set(dm_args, num++, libxl_sprintf(gc, "order=%s", info->boot)); |
anthony@21989 | 1260 } |
anthony@21989 | 1261 if (info->usb || info->usbdevice) { |
anthony@21989 | 1262 flexarray_set(dm_args, num++, "-usb"); |
anthony@21989 | 1263 if (info->usbdevice) { |
anthony@21989 | 1264 flexarray_set(dm_args, num++, "-usbdevice"); |
anthony@21989 | 1265 flexarray_set(dm_args, num++, info->usbdevice); |
anthony@21989 | 1266 } |
anthony@21989 | 1267 } |
anthony@21989 | 1268 if (info->soundhw) { |
anthony@21989 | 1269 flexarray_set(dm_args, num++, "-soundhw"); |
anthony@21989 | 1270 flexarray_set(dm_args, num++, info->soundhw); |
anthony@21989 | 1271 } |
anthony@21989 | 1272 if (!info->apic) { |
anthony@21989 | 1273 flexarray_set(dm_args, num++, "-no-acpi"); |
anthony@21989 | 1274 } |
anthony@21989 | 1275 if (info->vcpus > 1) { |
anthony@21989 | 1276 flexarray_set(dm_args, num++, "-smp"); |
anthony@21989 | 1277 if (info->vcpu_avail) |
gianni@22023 | 1278 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail)); |
anthony@21989 | 1279 else |
gianni@22023 | 1280 flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->vcpus)); |
anthony@21989 | 1281 } |
anthony@21989 | 1282 for (i = 0; i < num_vifs; i++) { |
anthony@21989 | 1283 if (vifs[i].nictype == NICTYPE_IOEMU) { |
gianni@22023 | 1284 char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
anthony@21989 | 1285 vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], |
anthony@21989 | 1286 vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); |
anthony@21989 | 1287 if (!vifs[i].ifname) |
gianni@22023 | 1288 vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid); |
anthony@21989 | 1289 flexarray_set(dm_args, num++, "-net"); |
gianni@22023 | 1290 flexarray_set(dm_args, num++, libxl_sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s", |
anthony@21989 | 1291 vifs[i].devid, smac, vifs[i].model)); |
anthony@21989 | 1292 flexarray_set(dm_args, num++, "-net"); |
gianni@22023 | 1293 flexarray_set(dm_args, num++, libxl_sprintf(gc, "tap,vlan=%d,ifname=%s,script=no", |
anthony@21990 | 1294 vifs[i].devid, vifs[i].ifname)); |
anthony@21989 | 1295 ioemu_vifs++; |
anthony@21989 | 1296 } |
anthony@21989 | 1297 } |
anthony@21989 | 1298 /* If we have no emulated nics, tell qemu not to create any */ |
anthony@21989 | 1299 if ( ioemu_vifs == 0 ) { |
anthony@21989 | 1300 flexarray_set(dm_args, num++, "-net"); |
anthony@21989 | 1301 flexarray_set(dm_args, num++, "none"); |
anthony@21989 | 1302 } |
anthony@21989 | 1303 } |
anthony@21989 | 1304 if (info->saved_state) { |
anthony@21989 | 1305 flexarray_set(dm_args, num++, "-loadvm"); |
anthony@21989 | 1306 flexarray_set(dm_args, num++, info->saved_state); |
anthony@21989 | 1307 } |
anthony@21989 | 1308 for (i = 0; info->extra && info->extra[i] != NULL; i++) |
anthony@21989 | 1309 flexarray_set(dm_args, num++, info->extra[i]); |
anthony@21989 | 1310 flexarray_set(dm_args, num++, "-M"); |
anthony@21989 | 1311 if (info->type == XENPV) |
anthony@21989 | 1312 flexarray_set(dm_args, num++, "xenpv"); |
anthony@21989 | 1313 else |
anthony@21989 | 1314 flexarray_set(dm_args, num++, "xenfv"); |
anthony@21989 | 1315 |
gianni@22023 | 1316 disks = libxl_device_disk_list(libxl_gc_owner(gc), info->domid, &nb); |
gianni@22042 | 1317 for (i; i < nb; i++) { |
gianni@22042 | 1318 if ( disks[i].is_cdrom ) { |
anthony@21989 | 1319 flexarray_set(dm_args, num++, "-cdrom"); |
gianni@22042 | 1320 flexarray_set(dm_args, num++, disks[i].physpath); |
anthony@21989 | 1321 }else{ |
gianni@22042 | 1322 flexarray_set(dm_args, num++, libxl_sprintf(gc, "-%s", disks[i].virtpath)); |
gianni@22042 | 1323 flexarray_set(dm_args, num++, disks[i].physpath); |
anthony@21989 | 1324 } |
anthony@21989 | 1325 } |
gianni@22042 | 1326 /* FIXME: leaks disk paths */ |
gianni@22023 | 1327 free(disks); |
anthony@21989 | 1328 flexarray_set(dm_args, num++, NULL); |
anthony@21989 | 1329 return (char **) flexarray_contents(dm_args); |
anthony@21989 | 1330 } |
anthony@21989 | 1331 |
gianni@22023 | 1332 static char ** libxl_build_device_model_args(libxl_gc *gc, |
anthony@21989 | 1333 libxl_device_model_info *info, |
anthony@21989 | 1334 libxl_device_nic *vifs, |
anthony@21989 | 1335 int num_vifs) |
anthony@21989 | 1336 { |
gianni@22023 | 1337 libxl_ctx *ctx = libxl_gc_owner(gc); |
anthony@21989 | 1338 int new_qemu; |
anthony@21989 | 1339 |
anthony@21989 | 1340 new_qemu = libxl_check_device_model_version(ctx, info->device_model); |
anthony@21989 | 1341 |
anthony@21989 | 1342 if (new_qemu == 1) { |
gianni@22023 | 1343 return libxl_build_device_model_args_new(gc, info, vifs, num_vifs); |
anthony@21989 | 1344 } else { |
gianni@22023 | 1345 return libxl_build_device_model_args_old(gc, info, vifs, num_vifs); |
anthony@21989 | 1346 } |
anthony@21989 | 1347 } |
anthony@21989 | 1348 |
Ian@22062 | 1349 static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild) |
keir@20834 | 1350 { |
ian@21930 | 1351 libxl_device_model_starting *starting = for_spawn; |
keir@20514 | 1352 char *kvs[3]; |
keir@20820 | 1353 int rc; |
keir@20820 | 1354 struct xs_handle *xsh; |
keir@20514 | 1355 |
keir@20820 | 1356 xsh = xs_daemon_open(); |
keir@20514 | 1357 /* we mustn't use the parent's handle in the child */ |
keir@20514 | 1358 |
keir@20514 | 1359 kvs[0] = "image/device-model-pid"; |
keir@21417 | 1360 if (asprintf(&kvs[1], "%d", innerchild) < 0) |
keir@21417 | 1361 return; |
keir@20514 | 1362 kvs[2] = NULL; |
keir@20820 | 1363 |
keir@20820 | 1364 rc = xs_writev(xsh, XBT_NULL, starting->dom_path, kvs); |
keir@20820 | 1365 if (rc) |
keir@20820 | 1366 return; |
keir@20820 | 1367 xs_daemon_close(xsh); |
keir@20514 | 1368 } |
keir@20514 | 1369 |
ian@21930 | 1370 static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx, |
keir@20542 | 1371 libxl_device_model_info *info, |
keir@20542 | 1372 libxl_device_vfb *vfb, |
keir@20542 | 1373 libxl_device_vkb *vkb) |
keir@20542 | 1374 { |
keir@20542 | 1375 memset(vfb, 0x00, sizeof(libxl_device_vfb)); |
keir@20542 | 1376 memset(vkb, 0x00, sizeof(libxl_device_vkb)); |
keir@20542 | 1377 |
keir@20542 | 1378 vfb->backend_domid = 0; |
keir@20542 | 1379 vfb->devid = 0; |
keir@20542 | 1380 vfb->vnc = info->vnc; |
keir@20542 | 1381 vfb->vnclisten = info->vnclisten; |
keir@20542 | 1382 vfb->vncdisplay = info->vncdisplay; |
keir@20542 | 1383 vfb->vncunused = info->vncunused; |
keir@21362 | 1384 vfb->vncpasswd = info->vncpasswd; |
keir@20542 | 1385 vfb->keymap = info->keymap; |
keir@20542 | 1386 vfb->sdl = info->sdl; |
keir@20542 | 1387 vfb->opengl = info->opengl; |
keir@20542 | 1388 |
keir@20542 | 1389 vkb->backend_domid = 0; |
keir@20542 | 1390 vkb->devid = 0; |
keir@20542 | 1391 return 0; |
keir@20542 | 1392 } |
keir@20542 | 1393 |
ian@21930 | 1394 static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args) |
keir@20542 | 1395 { |
gianni@22023 | 1396 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20542 | 1397 int i; |
keir@20542 | 1398 char *vm_path; |
keir@20542 | 1399 char *dmargs, *path; |
keir@20542 | 1400 int dmargs_size; |
keir@20542 | 1401 struct xs_permissions roperm[2]; |
keir@20542 | 1402 xs_transaction_t t; |
keir@20542 | 1403 |
keir@20542 | 1404 roperm[0].id = 0; |
keir@20542 | 1405 roperm[0].perms = XS_PERM_NONE; |
keir@20542 | 1406 roperm[1].id = domid; |
keir@20542 | 1407 roperm[1].perms = XS_PERM_READ; |
keir@20542 | 1408 |
gianni@22023 | 1409 vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/vm", guest_domid)); |
keir@20542 | 1410 |
keir@20542 | 1411 i = 0; |
keir@20542 | 1412 dmargs_size = 0; |
keir@20542 | 1413 while (args[i] != NULL) { |
keir@20542 | 1414 dmargs_size = dmargs_size + strlen(args[i]) + 1; |
keir@20542 | 1415 i++; |
keir@20542 | 1416 } |
keir@20542 | 1417 dmargs_size++; |
keir@20542 | 1418 dmargs = (char *) malloc(dmargs_size); |
keir@20542 | 1419 i = 1; |
keir@20542 | 1420 dmargs[0] = '\0'; |
keir@20542 | 1421 while (args[i] != NULL) { |
keir@20542 | 1422 if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) { |
keir@20542 | 1423 strcat(dmargs, " "); |
keir@20542 | 1424 strcat(dmargs, args[i]); |
keir@20542 | 1425 } |
keir@20542 | 1426 i++; |
keir@20542 | 1427 } |
gianni@22023 | 1428 path = libxl_sprintf(&gc, "%s/image/dmargs", vm_path); |
keir@20542 | 1429 |
keir@20542 | 1430 retry_transaction: |
keir@20542 | 1431 t = xs_transaction_start(ctx->xsh); |
keir@20542 | 1432 xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs)); |
keir@20542 | 1433 xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); |
gianni@22023 | 1434 xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm)); |
keir@20542 | 1435 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20542 | 1436 if (errno == EAGAIN) |
keir@20542 | 1437 goto retry_transaction; |
keir@20542 | 1438 free(dmargs); |
gianni@22023 | 1439 libxl_free_all(&gc); |
keir@20542 | 1440 return 0; |
keir@20542 | 1441 } |
keir@20542 | 1442 |
ian@21930 | 1443 static int libxl_create_stubdom(libxl_ctx *ctx, |
keir@20542 | 1444 libxl_device_model_info *info, |
keir@20542 | 1445 libxl_device_disk *disks, int num_disks, |
keir@20542 | 1446 libxl_device_nic *vifs, int num_vifs, |
keir@20542 | 1447 libxl_device_vfb *vfb, |
keir@20542 | 1448 libxl_device_vkb *vkb, |
keir@20542 | 1449 libxl_device_model_starting **starting_r) |
keir@20542 | 1450 { |
gianni@22023 | 1451 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20843 | 1452 int i, num_console = 1, ret; |
keir@20570 | 1453 libxl_device_console *console; |
keir@20542 | 1454 libxl_domain_create_info c_info; |
keir@20542 | 1455 libxl_domain_build_info b_info; |
keir@20542 | 1456 libxl_domain_build_state state; |
keir@20542 | 1457 uint32_t domid; |
keir@20542 | 1458 char **args; |
keir@20542 | 1459 struct xs_permissions perm[2]; |
keir@20542 | 1460 xs_transaction_t t; |
keir@20594 | 1461 libxl_device_model_starting *dm_starting = 0; |
keir@20542 | 1462 |
gianni@22023 | 1463 args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); |
gianni@22023 | 1464 if (!args) { |
gianni@22023 | 1465 ret = ERROR_FAIL; |
gianni@22023 | 1466 goto out; |
gianni@22023 | 1467 } |
keir@20542 | 1468 |
keir@20542 | 1469 memset(&c_info, 0x00, sizeof(libxl_domain_create_info)); |
keir@20542 | 1470 c_info.hvm = 0; |
gianni@22023 | 1471 c_info.name = libxl_sprintf(&gc, "%s-dm", _libxl_domid_to_name(&gc, info->domid)); |
keir@20801 | 1472 for (i = 0; i < 16; i++) |
keir@20801 | 1473 c_info.uuid[i] = info->uuid[i]; |
keir@20542 | 1474 |
keir@20542 | 1475 memset(&b_info, 0x00, sizeof(libxl_domain_build_info)); |
keir@20542 | 1476 b_info.max_vcpus = 1; |
keir@20542 | 1477 b_info.max_memkb = 32 * 1024; |
keir@20647 | 1478 b_info.target_memkb = b_info.max_memkb; |
gianni@22023 | 1479 b_info.kernel.path = libxl_abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path()); |
gianni@22023 | 1480 b_info.u.pv.cmdline = libxl_sprintf(&gc, " -d %d", info->domid); |
Ian@21848 | 1481 b_info.u.pv.ramdisk.path = ""; |
keir@20542 | 1482 b_info.u.pv.features = ""; |
keir@20542 | 1483 b_info.hvm = 0; |
keir@20542 | 1484 |
keir@20843 | 1485 ret = libxl_domain_make(ctx, &c_info, &domid); |
gianni@22023 | 1486 if (ret) |
gianni@22023 | 1487 goto out_free; |
keir@20843 | 1488 ret = libxl_domain_build(ctx, &b_info, domid, &state); |
gianni@22023 | 1489 if (ret) |
gianni@22023 | 1490 goto out_free; |
keir@20542 | 1491 |
keir@20542 | 1492 libxl_write_dmargs(ctx, domid, info->domid, args); |
gianni@22023 | 1493 libxl_xs_write(&gc, XBT_NULL, |
gianni@22023 | 1494 libxl_sprintf(&gc, "%s/image/device-model-domid", libxl_xs_get_dompath(&gc, info->domid)), |
keir@20843 | 1495 "%d", domid); |
gianni@22023 | 1496 libxl_xs_write(&gc, XBT_NULL, |
gianni@22023 | 1497 libxl_sprintf(&gc, "%s/target", libxl_xs_get_dompath(&gc, domid)), |
keir@20843 | 1498 "%d", info->domid); |
gianni@21892 | 1499 ret = xc_domain_set_target(ctx->xch, domid, info->domid); |
gianni@21892 | 1500 if (ret<0) { |
gianni@21892 | 1501 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "setting target domain %d -> %d", domid, info->domid); |
gianni@22023 | 1502 ret = ERROR_FAIL; |
gianni@22023 | 1503 goto out_free; |
gianni@21892 | 1504 } |
keir@20542 | 1505 xs_set_target(ctx->xsh, domid, info->domid); |
keir@20542 | 1506 |
keir@20542 | 1507 perm[0].id = domid; |
keir@20542 | 1508 perm[0].perms = XS_PERM_NONE; |
keir@20542 | 1509 perm[1].id = info->domid; |
keir@20542 | 1510 perm[1].perms = XS_PERM_READ; |
keir@20542 | 1511 retry_transaction: |
keir@20542 | 1512 t = xs_transaction_start(ctx->xsh); |
gianni@22023 | 1513 xs_mkdir(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid)); |
gianni@22023 | 1514 xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm)); |
gianni@22023 | 1515 xs_mkdir(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/%d/device/vfs", domid)); |
gianni@22023 | 1516 xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm)); |
keir@20542 | 1517 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20542 | 1518 if (errno == EAGAIN) |
keir@20542 | 1519 goto retry_transaction; |
keir@20542 | 1520 |
keir@20542 | 1521 for (i = 0; i < num_disks; i++) { |
keir@20781 | 1522 disks[i].domid = domid; |
keir@20843 | 1523 ret = libxl_device_disk_add(ctx, domid, &disks[i]); |
gianni@22023 | 1524 if (ret) |
gianni@22023 | 1525 goto out_free; |
keir@20542 | 1526 } |
keir@20542 | 1527 for (i = 0; i < num_vifs; i++) { |
keir@20781 | 1528 vifs[i].domid = domid; |
keir@20843 | 1529 ret = libxl_device_nic_add(ctx, domid, &vifs[i]); |
gianni@22023 | 1530 if (ret) |
gianni@22023 | 1531 goto out_free; |
keir@20542 | 1532 } |
keir@20781 | 1533 vfb->domid = domid; |
keir@20843 | 1534 ret = libxl_device_vfb_add(ctx, domid, vfb); |
gianni@22023 | 1535 if (ret) |
gianni@22023 | 1536 goto out_free; |
keir@20781 | 1537 vkb->domid = domid; |
keir@20843 | 1538 ret = libxl_device_vkb_add(ctx, domid, vkb); |
gianni@22023 | 1539 if (ret) |
gianni@22023 | 1540 goto out_free; |
keir@20542 | 1541 |
keir@20570 | 1542 if (info->serial) |
keir@20570 | 1543 num_console++; |
keir@20843 | 1544 |
gianni@22023 | 1545 console = libxl_calloc(&gc, num_console, sizeof(libxl_device_console)); |
gianni@22023 | 1546 if (!console) { |
gianni@22023 | 1547 ret = ERROR_NOMEM; |
gianni@22023 | 1548 goto out_free; |
gianni@22023 | 1549 } |
keir@20843 | 1550 |
keir@20570 | 1551 for (i = 0; i < num_console; i++) { |
keir@20781 | 1552 console[i].devid = i; |
stefano@22040 | 1553 console[i].consback = LIBXL_CONSBACK_IOEMU; |
keir@20781 | 1554 console[i].domid = domid; |
stefano@22040 | 1555 if (!i) { |
stefano@22040 | 1556 char *filename; |
stefano@22040 | 1557 char *name = libxl_sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid)); |
stefano@22040 | 1558 libxl_create_logfile(ctx, name, &filename); |
stefano@22040 | 1559 console[i].output = libxl_sprintf(&gc, "file:%s", filename); |
keir@20781 | 1560 console[i].build_state = &state; |
stefano@22040 | 1561 free(filename); |
stefano@22040 | 1562 } else |
stefano@22040 | 1563 console[i].output = "pty"; |
keir@20843 | 1564 ret = libxl_device_console_add(ctx, domid, &console[i]); |
gianni@22023 | 1565 if (ret) |
gianni@22023 | 1566 goto out_free; |
keir@20570 | 1567 } |
stefano@22040 | 1568 if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) { |
gianni@22023 | 1569 ret = ERROR_FAIL; |
gianni@22023 | 1570 goto out_free; |
keir@20594 | 1571 } |
keir@20594 | 1572 if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { |
gianni@22023 | 1573 ret = ERROR_FAIL; |
gianni@22023 | 1574 goto out_free; |
keir@20594 | 1575 } |
keir@20542 | 1576 |
keir@20542 | 1577 libxl_domain_unpause(ctx, domid); |
keir@20542 | 1578 |
keir@20594 | 1579 if (starting_r) { |
gianni@22023 | 1580 *starting_r = calloc(sizeof(libxl_device_model_starting), 1); |
keir@20598 | 1581 (*starting_r)->domid = info->domid; |
gianni@22023 | 1582 (*starting_r)->dom_path = libxl_xs_get_dompath(&gc, info->domid); |
keir@20594 | 1583 (*starting_r)->for_spawn = NULL; |
keir@20594 | 1584 } |
keir@20594 | 1585 |
gianni@22023 | 1586 ret = 0; |
gianni@22023 | 1587 |
gianni@22023 | 1588 out_free: |
keir@20542 | 1589 free(args); |
gianni@22023 | 1590 out: |
gianni@22023 | 1591 libxl_free_all(&gc); |
gianni@22023 | 1592 return ret; |
keir@20542 | 1593 } |
keir@20542 | 1594 |
ian@21930 | 1595 int libxl_create_device_model(libxl_ctx *ctx, |
keir@20462 | 1596 libxl_device_model_info *info, |
keir@20542 | 1597 libxl_device_disk *disks, int num_disks, |
keir@20514 | 1598 libxl_device_nic *vifs, int num_vifs, |
keir@20514 | 1599 libxl_device_model_starting **starting_r) |
keir@20462 | 1600 { |
gianni@22023 | 1601 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20546 | 1602 char *path, *logfile; |
keir@20514 | 1603 int logfile_w, null; |
keir@20546 | 1604 int rc; |
keir@20462 | 1605 char **args; |
ian@21930 | 1606 libxl_device_model_starting buf_starting, *p; |
keir@21362 | 1607 xs_transaction_t t; |
keir@21362 | 1608 char *vm_path; |
keir@21362 | 1609 char **pass_stuff; |
keir@20514 | 1610 |
keir@20542 | 1611 if (strstr(info->device_model, "stubdom-dm")) { |
keir@20542 | 1612 libxl_device_vfb vfb; |
keir@20542 | 1613 libxl_device_vkb vkb; |
keir@20542 | 1614 |
keir@20542 | 1615 libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb); |
gianni@22023 | 1616 rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r); |
gianni@22023 | 1617 goto out; |
keir@20542 | 1618 } |
keir@20542 | 1619 |
gianni@22023 | 1620 args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); |
gianni@22023 | 1621 if (!args) { |
gianni@22023 | 1622 rc = ERROR_FAIL; |
gianni@22023 | 1623 goto out; |
gianni@22023 | 1624 } |
gianni@22023 | 1625 |
gianni@22023 | 1626 path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid); |
keir@20462 | 1627 xs_mkdir(ctx->xsh, XBT_NULL, path); |
gianni@22023 | 1628 libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci); |
gianni@22023 | 1629 |
gianni@22023 | 1630 libxl_create_logfile(ctx, libxl_sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile); |
keir@20467 | 1631 logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); |
keir@20546 | 1632 free(logfile); |
keir@20462 | 1633 null = open("/dev/null", O_RDONLY); |
keir@20514 | 1634 |
keir@20514 | 1635 if (starting_r) { |
keir@20516 | 1636 rc = ERROR_NOMEM; |
gianni@22023 | 1637 *starting_r = calloc(sizeof(libxl_device_model_starting), 1); |
gianni@22023 | 1638 if (!*starting_r) |
gianni@22023 | 1639 goto out_close; |
keir@20594 | 1640 p = *starting_r; |
gianni@22023 | 1641 p->for_spawn = calloc(sizeof(libxl_spawn_starting), 1); |
keir@20594 | 1642 } else { |
keir@20594 | 1643 p = &buf_starting; |
keir@20594 | 1644 p->for_spawn = NULL; |
keir@20594 | 1645 } |
keir@20514 | 1646 |
keir@20594 | 1647 p->domid = info->domid; |
gianni@22023 | 1648 p->dom_path = libxl_xs_get_dompath(&gc, info->domid); |
gianni@22023 | 1649 if (!p->dom_path) { |
gianni@22023 | 1650 rc = ERROR_FAIL; |
gianni@22023 | 1651 goto out_close; |
gianni@22023 | 1652 } |
keir@20594 | 1653 |
keir@21362 | 1654 if (info->vncpasswd) { |
gianni@22023 | 1655 retry_transaction: |
keir@21362 | 1656 /* Find uuid and the write the vnc password to xenstore for qemu. */ |
keir@21362 | 1657 t = xs_transaction_start(ctx->xsh); |
gianni@22023 | 1658 vm_path = libxl_xs_read(&gc,t,libxl_sprintf(&gc, "%s/vm", p->dom_path)); |
keir@21362 | 1659 if (vm_path) { |
keir@21362 | 1660 /* Now write the vncpassword into it. */ |
gianni@22023 | 1661 pass_stuff = libxl_calloc(&gc, 2, sizeof(char *)); |
keir@21362 | 1662 pass_stuff[0] = "vncpasswd"; |
keir@21362 | 1663 pass_stuff[1] = info->vncpasswd; |
gianni@22023 | 1664 libxl_xs_writev(&gc,t,vm_path,pass_stuff); |
keir@21362 | 1665 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@21362 | 1666 if (errno == EAGAIN) |
keir@21362 | 1667 goto retry_transaction; |
keir@21362 | 1668 } |
keir@21362 | 1669 } |
keir@21362 | 1670 |
keir@20594 | 1671 rc = libxl_spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid); |
gianni@22023 | 1672 if (rc < 0) |
gianni@22023 | 1673 goto out_close; |
keir@20514 | 1674 if (!rc) { /* inner child */ |
keir@20833 | 1675 libxl_exec(null, logfile_w, logfile_w, |
gianni@22023 | 1676 libxl_abs_path(&gc, info->device_model, libxl_private_bindir_path()), |
keir@21353 | 1677 args); |
keir@20514 | 1678 } |
keir@20514 | 1679 |
keir@20514 | 1680 rc = 0; |
gianni@22023 | 1681 |
gianni@22023 | 1682 out_close: |
keir@20462 | 1683 close(null); |
keir@20462 | 1684 close(logfile_w); |
gianni@22023 | 1685 free(args); |
gianni@22023 | 1686 out: |
gianni@22023 | 1687 libxl_free_all(&gc); |
keir@20514 | 1688 return rc; |
keir@20514 | 1689 } |
keir@20514 | 1690 |
ian@21930 | 1691 int libxl_detach_device_model(libxl_ctx *ctx, |
keir@20779 | 1692 libxl_device_model_starting *starting) |
keir@20779 | 1693 { |
keir@20514 | 1694 int rc; |
keir@20594 | 1695 rc = libxl_spawn_detach(ctx, starting->for_spawn); |
gianni@22023 | 1696 if (starting->for_spawn) |
gianni@22023 | 1697 free(starting->for_spawn); |
gianni@22023 | 1698 free(starting); |
keir@20514 | 1699 return rc; |
keir@20514 | 1700 } |
keir@20462 | 1701 |
keir@20514 | 1702 |
ian@21930 | 1703 int libxl_confirm_device_model_startup(libxl_ctx *ctx, |
keir@20779 | 1704 libxl_device_model_starting *starting) |
keir@20779 | 1705 { |
gianni@21965 | 1706 int problem = libxl_wait_for_device_model(ctx, starting->domid, "running", NULL, NULL); |
gianni@21965 | 1707 int detach; |
gianni@21965 | 1708 if ( !problem ) |
gianni@21965 | 1709 problem = libxl_spawn_check(ctx, starting->for_spawn); |
gianni@21965 | 1710 detach = libxl_detach_device_model(ctx, starting); |
keir@20514 | 1711 return problem ? problem : detach; |
keir@20462 | 1712 } |
keir@20462 | 1713 |
keir@20514 | 1714 |
keir@20462 | 1715 /******************************************************************************/ |
keir@20566 | 1716 |
ian@21930 | 1717 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) |
keir@20462 | 1718 { |
gianni@22023 | 1719 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20462 | 1720 flexarray_t *front; |
keir@20462 | 1721 flexarray_t *back; |
keir@20462 | 1722 char *backend_type; |
keir@20462 | 1723 unsigned int boffset = 0; |
keir@20462 | 1724 unsigned int foffset = 0; |
keir@20462 | 1725 int devid; |
keir@20462 | 1726 libxl_device device; |
gianni@22023 | 1727 int major, minor, rc; |
keir@20462 | 1728 |
keir@20462 | 1729 front = flexarray_make(16, 1); |
gianni@22023 | 1730 if (!front) { |
gianni@22023 | 1731 rc = ERROR_NOMEM; |
gianni@22023 | 1732 goto out; |
gianni@22023 | 1733 } |
keir@20462 | 1734 back = flexarray_make(16, 1); |
gianni@22023 | 1735 if (!back) { |
gianni@22023 | 1736 rc = ERROR_NOMEM; |
gianni@22023 | 1737 goto out_free; |
gianni@22023 | 1738 } |
keir@20462 | 1739 |
keir@20462 | 1740 backend_type = device_disk_backend_type_of_phystype(disk->phystype); |
keir@20462 | 1741 devid = device_disk_dev_number(disk->virtpath); |
keir@20947 | 1742 if (devid==-1) { |
Christoph@21953 | 1743 XL_LOG(ctx, XL_LOG_ERROR, "Invalid or unsupported" |
keir@20947 | 1744 " virtual disk identifier %s", disk->virtpath); |
gianni@22023 | 1745 rc = ERROR_INVAL; |
gianni@22023 | 1746 goto out_free; |
keir@20947 | 1747 } |
keir@20462 | 1748 |
keir@20462 | 1749 device.backend_devid = devid; |
keir@20462 | 1750 device.backend_domid = disk->backend_domid; |
keir@20462 | 1751 device.devid = devid; |
keir@20462 | 1752 device.domid = disk->domid; |
keir@20462 | 1753 device.kind = DEVICE_VBD; |
keir@20462 | 1754 |
keir@20462 | 1755 switch (disk->phystype) { |
keir@20462 | 1756 case PHYSTYPE_PHY: { |
keir@20462 | 1757 |
keir@20509 | 1758 device_physdisk_major_minor(disk->physpath, &major, &minor); |
keir@20516 | 1759 flexarray_set(back, boffset++, "physical-device"); |
gianni@22023 | 1760 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, minor)); |
keir@20462 | 1761 |
keir@20516 | 1762 flexarray_set(back, boffset++, "params"); |
keir@20516 | 1763 flexarray_set(back, boffset++, disk->physpath); |
keir@20462 | 1764 |
keir@20462 | 1765 device.backend_kind = DEVICE_VBD; |
keir@20462 | 1766 break; |
keir@20462 | 1767 } |
keir@20566 | 1768 case PHYSTYPE_FILE: |
keir@20566 | 1769 /* let's pretend is tap:aio for the moment */ |
keir@20566 | 1770 disk->phystype = PHYSTYPE_AIO; |
Christoph@22044 | 1771 case PHYSTYPE_AIO: |
Christoph@22044 | 1772 case PHYSTYPE_QCOW: |
Christoph@22044 | 1773 case PHYSTYPE_QCOW2: |
Christoph@22044 | 1774 case PHYSTYPE_VHD: |
Christoph@22044 | 1775 if (libxl_blktap_enabled(&gc)) { |
Christoph@22044 | 1776 const char *dev = libxl_blktap_devpath(&gc, |
Christoph@22044 | 1777 disk->physpath, disk->phystype); |
gianni@22023 | 1778 if (!dev) { |
gianni@22023 | 1779 rc = ERROR_FAIL; |
gianni@22023 | 1780 goto out_free; |
gianni@22023 | 1781 } |
keir@20566 | 1782 flexarray_set(back, boffset++, "tapdisk-params"); |
gianni@22023 | 1783 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); |
keir@20566 | 1784 flexarray_set(back, boffset++, "params"); |
gianni@22023 | 1785 flexarray_set(back, boffset++, libxl_strdup(&gc, dev)); |
keir@20566 | 1786 backend_type = "phy"; |
keir@20566 | 1787 device_physdisk_major_minor(dev, &major, &minor); |
keir@20566 | 1788 flexarray_set(back, boffset++, "physical-device"); |
gianni@22023 | 1789 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, minor)); |
keir@20566 | 1790 device.backend_kind = DEVICE_VBD; |
keir@20566 | 1791 |
keir@20566 | 1792 break; |
keir@20566 | 1793 } |
keir@20516 | 1794 flexarray_set(back, boffset++, "params"); |
gianni@22023 | 1795 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s", |
keir@20462 | 1796 device_disk_string_of_phystype(disk->phystype), disk->physpath)); |
keir@20462 | 1797 |
keir@20462 | 1798 device.backend_kind = DEVICE_TAP; |
keir@20462 | 1799 break; |
Christoph@22044 | 1800 |
keir@20846 | 1801 default: |
keir@20846 | 1802 XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", disk->phystype); |
gianni@22023 | 1803 rc = ERROR_INVAL; |
gianni@22023 | 1804 goto out_free; |
keir@20462 | 1805 } |
keir@20462 | 1806 |
keir@20516 | 1807 flexarray_set(back, boffset++, "frontend-id"); |
gianni@22023 | 1808 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", disk->domid)); |
keir@20516 | 1809 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1810 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1811 flexarray_set(back, boffset++, "removable"); |
gianni@22023 | 1812 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", (disk->unpluggable) ? 1 : 0)); |
keir@20516 | 1813 flexarray_set(back, boffset++, "bootable"); |
gianni@22023 | 1814 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 1815 flexarray_set(back, boffset++, "state"); |
gianni@22023 | 1816 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 1817 flexarray_set(back, boffset++, "dev"); |
keir@20516 | 1818 flexarray_set(back, boffset++, disk->virtpath); |
keir@20516 | 1819 flexarray_set(back, boffset++, "type"); |
keir@20516 | 1820 flexarray_set(back, boffset++, backend_type); |
keir@20516 | 1821 flexarray_set(back, boffset++, "mode"); |
keir@20516 | 1822 flexarray_set(back, boffset++, disk->readwrite ? "w" : "r"); |
keir@20462 | 1823 |
keir@20516 | 1824 flexarray_set(front, foffset++, "backend-id"); |
gianni@22023 | 1825 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", disk->backend_domid)); |
keir@20516 | 1826 flexarray_set(front, foffset++, "state"); |
gianni@22023 | 1827 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 1828 flexarray_set(front, foffset++, "virtual-device"); |
gianni@22023 | 1829 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", devid)); |
keir@20516 | 1830 flexarray_set(front, foffset++, "device-type"); |
keir@20516 | 1831 flexarray_set(front, foffset++, disk->is_cdrom ? "cdrom" : "disk"); |
keir@20462 | 1832 |
keir@20462 | 1833 if (0 /* protocol != native*/) { |
keir@20516 | 1834 flexarray_set(front, foffset++, "protocol"); |
keir@20516 | 1835 flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */ |
keir@20462 | 1836 } |
keir@20462 | 1837 |
keir@20462 | 1838 libxl_device_generic_add(ctx, &device, |
gianni@22023 | 1839 libxl_xs_kvs_of_flexarray(&gc, back, boffset), |
gianni@22023 | 1840 libxl_xs_kvs_of_flexarray(&gc, front, foffset)); |
gianni@22023 | 1841 |
gianni@22023 | 1842 rc = 0; |
gianni@22023 | 1843 |
gianni@22023 | 1844 out_free: |
keir@20516 | 1845 flexarray_free(back); |
keir@20516 | 1846 flexarray_free(front); |
gianni@22023 | 1847 out: |
gianni@22023 | 1848 libxl_free_all(&gc); |
gianni@22023 | 1849 return rc; |
keir@20462 | 1850 } |
keir@20462 | 1851 |
ian@21930 | 1852 int libxl_device_disk_del(libxl_ctx *ctx, |
keir@20626 | 1853 libxl_device_disk *disk, int wait) |
keir@20462 | 1854 { |
keir@20626 | 1855 libxl_device device; |
keir@20626 | 1856 int devid; |
keir@20462 | 1857 |
keir@20626 | 1858 devid = device_disk_dev_number(disk->virtpath); |
keir@20626 | 1859 device.backend_domid = disk->backend_domid; |
keir@20626 | 1860 device.backend_devid = devid; |
keir@20626 | 1861 device.backend_kind = |
keir@20626 | 1862 (disk->phystype == PHYSTYPE_PHY) ? DEVICE_VBD : DEVICE_TAP; |
keir@20626 | 1863 device.domid = disk->domid; |
keir@20626 | 1864 device.devid = devid; |
keir@20626 | 1865 device.kind = DEVICE_VBD; |
keir@20626 | 1866 return libxl_device_del(ctx, &device, wait); |
keir@20462 | 1867 } |
keir@20462 | 1868 |
gianni@22023 | 1869 char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) |
Ian@21849 | 1870 { |
gianni@22023 | 1871 libxl_gc gc = LIBXL_INIT_GC(ctx); |
Christoph@22044 | 1872 const char *dev = NULL; |
Christoph@22044 | 1873 char *ret; |
Ian@21849 | 1874 int phystype = disk->phystype; |
Ian@21849 | 1875 switch (phystype) { |
Ian@21849 | 1876 case PHYSTYPE_PHY: { |
Ian@21849 | 1877 fprintf(stderr, "attaching PHY disk %s to domain 0\n", disk->physpath); |
Ian@21849 | 1878 dev = disk->physpath; |
Ian@21849 | 1879 break; |
Ian@21849 | 1880 } |
Ian@21849 | 1881 case PHYSTYPE_FILE: |
Ian@21849 | 1882 /* let's pretend is tap:aio for the moment */ |
Ian@21849 | 1883 phystype = PHYSTYPE_AIO; |
Christoph@22044 | 1884 case PHYSTYPE_AIO: |
Christoph@22044 | 1885 case PHYSTYPE_QCOW: |
Christoph@22044 | 1886 case PHYSTYPE_QCOW2: |
Christoph@22044 | 1887 case PHYSTYPE_VHD: |
Christoph@22044 | 1888 if (libxl_blktap_enabled(&gc)) |
Christoph@22044 | 1889 dev = libxl_blktap_devpath(&gc, disk->physpath, phystype); |
Ian@21849 | 1890 break; |
Christoph@22044 | 1891 |
Ian@21849 | 1892 default: |
Ian@21849 | 1893 XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", phystype); |
Ian@21849 | 1894 break; |
Ian@21849 | 1895 } |
gianni@22023 | 1896 ret = strdup(dev); |
gianni@22023 | 1897 libxl_free_all(&gc); |
gianni@22023 | 1898 return ret; |
Ian@21849 | 1899 } |
Ian@21849 | 1900 |
ian@21930 | 1901 int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk) |
Ian@21849 | 1902 { |
Ian@21849 | 1903 /* Nothing to do for PHYSTYPE_PHY. */ |
Ian@21849 | 1904 |
Ian@21849 | 1905 /* |
Ian@21849 | 1906 * For other device types assume that the blktap2 process is |
Ian@21849 | 1907 * needed by the soon to be started domain and do nothing. |
Ian@21849 | 1908 */ |
Ian@21849 | 1909 |
Ian@21849 | 1910 return 0; |
Ian@21849 | 1911 } |
Ian@21849 | 1912 |
keir@20462 | 1913 /******************************************************************************/ |
ian@21930 | 1914 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) |
keir@20462 | 1915 { |
gianni@22023 | 1916 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20462 | 1917 flexarray_t *front; |
keir@20462 | 1918 flexarray_t *back; |
keir@20462 | 1919 unsigned int boffset = 0; |
keir@20462 | 1920 unsigned int foffset = 0; |
keir@20462 | 1921 libxl_device device; |
keir@21407 | 1922 char *dompath, **l; |
gianni@22023 | 1923 unsigned int nb, rc; |
keir@20462 | 1924 |
keir@20462 | 1925 front = flexarray_make(16, 1); |
gianni@22023 | 1926 if (!front) { |
gianni@22023 | 1927 rc = ERROR_NOMEM; |
gianni@22023 | 1928 goto out; |
gianni@22023 | 1929 } |
keir@20462 | 1930 back = flexarray_make(16, 1); |
gianni@22023 | 1931 if (!back) { |
gianni@22023 | 1932 rc = ERROR_NOMEM; |
gianni@22023 | 1933 goto out_free; |
gianni@22023 | 1934 } |
keir@20462 | 1935 |
keir@21407 | 1936 if (nic->devid == -1) { |
gianni@22023 | 1937 if (!(dompath = libxl_xs_get_dompath(&gc, domid))) { |
gianni@22023 | 1938 rc = ERROR_FAIL; |
gianni@22023 | 1939 goto out_free; |
keir@21407 | 1940 } |
gianni@22023 | 1941 if (!(l = libxl_xs_directory(&gc, XBT_NULL, |
gianni@22023 | 1942 libxl_sprintf(&gc, "%s/device/vif", dompath), &nb))) { |
keir@21407 | 1943 nic->devid = 0; |
keir@21407 | 1944 } else { |
keir@21407 | 1945 nic->devid = strtoul(l[nb - 1], NULL, 10) + 1; |
keir@21407 | 1946 } |
keir@21407 | 1947 } |
keir@21407 | 1948 |
keir@20462 | 1949 device.backend_devid = nic->devid; |
keir@20462 | 1950 device.backend_domid = nic->backend_domid; |
keir@20462 | 1951 device.backend_kind = DEVICE_VIF; |
keir@20462 | 1952 device.devid = nic->devid; |
keir@20462 | 1953 device.domid = nic->domid; |
keir@20462 | 1954 device.kind = DEVICE_VIF; |
keir@20462 | 1955 |
keir@20516 | 1956 flexarray_set(back, boffset++, "frontend-id"); |
gianni@22023 | 1957 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->domid)); |
keir@20516 | 1958 flexarray_set(back, boffset++, "online"); |
keir@20516 | 1959 flexarray_set(back, boffset++, "1"); |
keir@20516 | 1960 flexarray_set(back, boffset++, "state"); |
gianni@22023 | 1961 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 1962 flexarray_set(back, boffset++, "script"); |
keir@20516 | 1963 flexarray_set(back, boffset++, nic->script); |
keir@20516 | 1964 flexarray_set(back, boffset++, "mac"); |
gianni@22023 | 1965 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@20462 | 1966 nic->mac[0], nic->mac[1], nic->mac[2], |
keir@20462 | 1967 nic->mac[3], nic->mac[4], nic->mac[5])); |
Ian@21732 | 1968 flexarray_set(back, boffset++, "bridge"); |
gianni@22023 | 1969 flexarray_set(back, boffset++, libxl_strdup(&gc, nic->bridge)); |
keir@20516 | 1970 flexarray_set(back, boffset++, "handle"); |
gianni@22023 | 1971 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->devid)); |
keir@20462 | 1972 |
keir@20516 | 1973 flexarray_set(front, foffset++, "backend-id"); |
gianni@22023 | 1974 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->backend_domid)); |
keir@20516 | 1975 flexarray_set(front, foffset++, "state"); |
gianni@22023 | 1976 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 1977 flexarray_set(front, foffset++, "handle"); |
gianni@22023 | 1978 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->devid)); |
keir@20516 | 1979 flexarray_set(front, foffset++, "mac"); |
gianni@22023 | 1980 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@20462 | 1981 nic->mac[0], nic->mac[1], nic->mac[2], |
keir@20462 | 1982 nic->mac[3], nic->mac[4], nic->mac[5])); |
keir@20462 | 1983 if (0 /* protocol != native*/) { |
keir@20516 | 1984 flexarray_set(front, foffset++, "protocol"); |
keir@20516 | 1985 flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */ |
keir@20462 | 1986 } |
keir@20462 | 1987 |
keir@20462 | 1988 libxl_device_generic_add(ctx, &device, |
gianni@22023 | 1989 libxl_xs_kvs_of_flexarray(&gc, back, boffset), |
gianni@22023 | 1990 libxl_xs_kvs_of_flexarray(&gc, front, foffset)); |
keir@20462 | 1991 |
keir@20462 | 1992 /* FIXME: wait for plug */ |
gianni@22023 | 1993 rc = 0; |
gianni@22023 | 1994 out_free: |
keir@20516 | 1995 flexarray_free(back); |
keir@20516 | 1996 flexarray_free(front); |
gianni@22023 | 1997 out: |
gianni@22023 | 1998 libxl_free_all(&gc); |
gianni@22023 | 1999 return rc; |
keir@20462 | 2000 } |
keir@20462 | 2001 |
ian@21930 | 2002 int libxl_device_nic_del(libxl_ctx *ctx, |
keir@20626 | 2003 libxl_device_nic *nic, int wait) |
keir@20462 | 2004 { |
keir@20626 | 2005 libxl_device device; |
keir@20462 | 2006 |
keir@20626 | 2007 device.backend_devid = nic->devid; |
keir@20626 | 2008 device.backend_domid = nic->backend_domid; |
keir@20626 | 2009 device.backend_kind = DEVICE_VIF; |
keir@20626 | 2010 device.devid = nic->devid; |
keir@20626 | 2011 device.domid = nic->domid; |
keir@20626 | 2012 device.kind = DEVICE_VIF; |
keir@20626 | 2013 |
keir@20626 | 2014 return libxl_device_del(ctx, &device, wait); |
keir@20462 | 2015 } |
keir@20462 | 2016 |
gianni@22009 | 2017 void libxl_free_nics_list(libxl_nicinfo *nics, unsigned int nb) |
gianni@22009 | 2018 { |
gianni@22009 | 2019 unsigned int i; |
gianni@22009 | 2020 for(i = 0; i < nb; i++) { |
gianni@22009 | 2021 free(nics[i].backend); |
gianni@22009 | 2022 free(nics[i].frontend); |
gianni@22009 | 2023 free(nics[i].script); |
gianni@22009 | 2024 } |
gianni@22009 | 2025 free(nics); |
gianni@22009 | 2026 } |
gianni@22009 | 2027 |
ian@21930 | 2028 libxl_nicinfo *libxl_list_nics(libxl_ctx *ctx, uint32_t domid, unsigned int *nb) |
keir@21408 | 2029 { |
gianni@22023 | 2030 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21408 | 2031 char *dompath, *nic_path_fe; |
gianni@22009 | 2032 char **l, **list; |
keir@21408 | 2033 char *val, *tok; |
keir@21408 | 2034 unsigned int nb_nics, i; |
keir@21408 | 2035 libxl_nicinfo *res, *nics; |
keir@21408 | 2036 |
gianni@22023 | 2037 dompath = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 2038 if (!dompath) |
gianni@22023 | 2039 goto err; |
gianni@22023 | 2040 list = l = libxl_xs_directory(&gc, XBT_NULL, |
gianni@22023 | 2041 libxl_sprintf(&gc, "%s/device/vif", dompath), &nb_nics); |
gianni@22023 | 2042 if (!l) |
gianni@22023 | 2043 goto err; |
gianni@22009 | 2044 nics = res = calloc(nb_nics, sizeof (libxl_device_nic)); |
gianni@22023 | 2045 if (!res) |
gianni@22023 | 2046 goto err; |
keir@21408 | 2047 for (*nb = nb_nics; nb_nics > 0; --nb_nics, ++l, ++nics) { |
gianni@22023 | 2048 nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, *l); |
keir@21408 | 2049 |
gianni@22009 | 2050 nics->backend = xs_read(ctx->xsh, XBT_NULL, |
gianni@22023 | 2051 libxl_sprintf(&gc, "%s/backend", nic_path_fe), NULL); |
gianni@22023 | 2052 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", nic_path_fe)); |
keir@21408 | 2053 nics->backend_id = val ? strtoul(val, NULL, 10) : -1; |
keir@21408 | 2054 |
keir@21408 | 2055 nics->devid = strtoul(*l, NULL, 10); |
gianni@22023 | 2056 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", nic_path_fe)); |
keir@21408 | 2057 nics->state = val ? strtoul(val, NULL, 10) : -1; |
gianni@22023 | 2058 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", nic_path_fe)); |
keir@21408 | 2059 for (i = 0, tok = strtok(val, ":"); tok && (i < 6); |
keir@21408 | 2060 ++i, tok = strtok(NULL, ":")) { |
keir@21408 | 2061 nics->mac[i] = strtoul(tok, NULL, 16); |
keir@21408 | 2062 } |
gianni@22023 | 2063 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", nic_path_fe)); |
keir@21408 | 2064 nics->evtch = val ? strtol(val, NULL, 10) : -1; |
gianni@22023 | 2065 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/tx-ring-ref", nic_path_fe)); |
keir@21408 | 2066 nics->rref_tx = val ? strtol(val, NULL, 10) : -1; |
gianni@22023 | 2067 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/rx-ring-ref", nic_path_fe)); |
keir@21408 | 2068 nics->rref_rx = val ? strtol(val, NULL, 10) : -1; |
gianni@22009 | 2069 nics->frontend = xs_read(ctx->xsh, XBT_NULL, |
gianni@22023 | 2070 libxl_sprintf(&gc, "%s/frontend", nics->backend), NULL); |
gianni@22023 | 2071 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", nics->backend)); |
keir@21408 | 2072 nics->frontend_id = val ? strtoul(val, NULL, 10) : -1; |
gianni@22009 | 2073 nics->script = xs_read(ctx->xsh, XBT_NULL, |
gianni@22023 | 2074 libxl_sprintf(&gc, "%s/script", nics->backend), NULL); |
keir@21408 | 2075 } |
keir@21408 | 2076 |
gianni@22023 | 2077 libxl_free_all(&gc); |
keir@21408 | 2078 return res; |
gianni@22023 | 2079 err: |
gianni@22023 | 2080 libxl_free_all(&gc); |
gianni@22023 | 2081 return NULL; |
keir@21408 | 2082 } |
keir@21408 | 2083 |
keir@21580 | 2084 /******************************************************************************/ |
ian@21930 | 2085 int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 *net2) |
keir@21580 | 2086 { |
gianni@22023 | 2087 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21580 | 2088 flexarray_t *front, *back; |
keir@21580 | 2089 unsigned int boffset = 0, foffset = 0; |
keir@21580 | 2090 libxl_device device; |
keir@21580 | 2091 char *dompath, *dom, **l; |
keir@21580 | 2092 unsigned int nb; |
gianni@22023 | 2093 int rc; |
keir@21580 | 2094 |
keir@21580 | 2095 front = flexarray_make(16, 1); |
gianni@22023 | 2096 if (!front) { |
gianni@22023 | 2097 rc = ERROR_NOMEM; |
gianni@22023 | 2098 goto err; |
gianni@22023 | 2099 } |
keir@21580 | 2100 back = flexarray_make(16, 1); |
gianni@22023 | 2101 if (!back) { |
gianni@22023 | 2102 rc = ERROR_NOMEM; |
gianni@22023 | 2103 goto err_free; |
keir@21580 | 2104 } |
gianni@22023 | 2105 |
gianni@22023 | 2106 if (!(dompath = libxl_xs_get_dompath(&gc, domid))) { |
gianni@22023 | 2107 rc = ERROR_FAIL; |
gianni@22023 | 2108 goto err_free; |
gianni@22023 | 2109 } |
gianni@22023 | 2110 dom = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/name", dompath)); |
keir@21580 | 2111 |
keir@21580 | 2112 if (net2->devid == -1) { |
gianni@22023 | 2113 if (!(l = libxl_xs_directory(&gc, XBT_NULL, |
gianni@22023 | 2114 libxl_sprintf(&gc, "%s/device/vif2", dompath), &nb))) { |
keir@21580 | 2115 net2->devid = 0; |
keir@21580 | 2116 } else { |
keir@21580 | 2117 net2->devid = strtoul(l[nb - 1], NULL, 10) + 1; |
keir@21580 | 2118 } |
keir@21580 | 2119 } |
keir@21580 | 2120 |
keir@21580 | 2121 device.backend_devid = net2->devid; |
keir@21580 | 2122 device.backend_domid = net2->backend_domid; |
keir@21580 | 2123 device.backend_kind = DEVICE_VIF2; |
keir@21580 | 2124 device.devid = net2->devid; |
keir@21580 | 2125 device.domid = net2->domid; |
keir@21580 | 2126 device.kind = DEVICE_VIF2; |
keir@21580 | 2127 |
keir@21580 | 2128 flexarray_set(back, boffset++, "domain"); |
keir@21580 | 2129 flexarray_set(back, boffset++, dom); |
keir@21580 | 2130 flexarray_set(back, boffset++, "frontend-id"); |
gianni@22023 | 2131 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->domid)); |
keir@21580 | 2132 |
keir@21580 | 2133 flexarray_set(back, boffset++, "local-trusted"); |
gianni@22023 | 2134 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->back_trusted)); |
keir@21580 | 2135 flexarray_set(back, boffset++, "mac"); |
gianni@22023 | 2136 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@21580 | 2137 net2->back_mac[0], net2->back_mac[1], |
keir@21580 | 2138 net2->back_mac[2], net2->back_mac[3], |
keir@21580 | 2139 net2->back_mac[4], net2->back_mac[5])); |
keir@21580 | 2140 |
keir@21580 | 2141 flexarray_set(back, boffset++, "remote-trusted"); |
gianni@22023 | 2142 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->trusted)); |
keir@21580 | 2143 flexarray_set(back, boffset++, "remote-mac"); |
gianni@22023 | 2144 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@21580 | 2145 net2->front_mac[0], net2->front_mac[1], |
keir@21580 | 2146 net2->front_mac[2], net2->front_mac[3], |
keir@21580 | 2147 net2->front_mac[4], net2->front_mac[5])); |
keir@21580 | 2148 |
keir@21580 | 2149 flexarray_set(back, boffset++, "max-bypasses"); |
gianni@22023 | 2150 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->max_bypasses)); |
keir@21580 | 2151 flexarray_set(back, boffset++, "filter-mac"); |
gianni@22023 | 2152 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", !!(net2->filter_mac))); |
keir@21580 | 2153 flexarray_set(back, boffset++, "handle"); |
gianni@22023 | 2154 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->devid)); |
keir@21580 | 2155 flexarray_set(back, boffset++, "online"); |
keir@21580 | 2156 flexarray_set(back, boffset++, "1"); |
keir@21580 | 2157 flexarray_set(back, boffset++, "state"); |
keir@21580 | 2158 flexarray_set(back, boffset++, "1"); |
keir@21580 | 2159 |
keir@21580 | 2160 flexarray_set(front, foffset++, "backend-id"); |
gianni@22023 | 2161 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->backend_domid)); |
keir@21580 | 2162 |
keir@21580 | 2163 flexarray_set(front, foffset++, "local-trusted"); |
gianni@22023 | 2164 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->trusted)); |
keir@21580 | 2165 flexarray_set(front, foffset++, "mac"); |
gianni@22023 | 2166 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@21580 | 2167 net2->front_mac[0], net2->front_mac[1], |
keir@21580 | 2168 net2->front_mac[2], net2->front_mac[3], |
keir@21580 | 2169 net2->front_mac[4], net2->front_mac[5])); |
keir@21580 | 2170 |
keir@21580 | 2171 flexarray_set(front, foffset++, "remote-trusted"); |
gianni@22023 | 2172 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->back_trusted)); |
keir@21580 | 2173 flexarray_set(front, foffset++, "remote-mac"); |
gianni@22023 | 2174 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", |
keir@21580 | 2175 net2->back_mac[0], net2->back_mac[1], |
keir@21580 | 2176 net2->back_mac[2], net2->back_mac[3], |
keir@21580 | 2177 net2->back_mac[4], net2->back_mac[5])); |
keir@21580 | 2178 |
keir@21580 | 2179 flexarray_set(front, foffset++, "filter-mac"); |
gianni@22023 | 2180 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", !!(net2->filter_mac))); |
keir@21580 | 2181 flexarray_set(front, foffset++, "state"); |
keir@21580 | 2182 flexarray_set(front, foffset++, "1"); |
keir@21580 | 2183 |
keir@21580 | 2184 libxl_device_generic_add(ctx, &device, |
gianni@22023 | 2185 libxl_xs_kvs_of_flexarray(&gc, back, boffset), |
gianni@22023 | 2186 libxl_xs_kvs_of_flexarray(&gc, front, foffset)); |
keir@21580 | 2187 |
keir@21580 | 2188 /* FIXME: wait for plug */ |
gianni@22023 | 2189 rc = 0; |
gianni@22023 | 2190 err_free: |
keir@21580 | 2191 flexarray_free(back); |
keir@21580 | 2192 flexarray_free(front); |
gianni@22023 | 2193 err: |
gianni@22023 | 2194 libxl_free_all(&gc); |
gianni@22023 | 2195 return rc; |
keir@21580 | 2196 } |
keir@21408 | 2197 |
ian@21930 | 2198 libxl_net2info *libxl_device_net2_list(libxl_ctx *ctx, uint32_t domid, unsigned int *nb) |
keir@21581 | 2199 { |
gianni@22023 | 2200 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21581 | 2201 char *dompath, *net2_path_fe; |
keir@21581 | 2202 char **l; |
keir@21581 | 2203 char *val, *tok; |
keir@21581 | 2204 unsigned int nb_net2s, i; |
keir@21581 | 2205 libxl_net2info *res, *net2s; |
keir@21581 | 2206 |
gianni@22023 | 2207 dompath = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 2208 if (!dompath) |
gianni@22023 | 2209 goto err; |
gianni@22023 | 2210 l = libxl_xs_directory(&gc, XBT_NULL, |
gianni@22023 | 2211 libxl_sprintf(&gc, "%s/device/vif2", dompath), &nb_net2s); |
gianni@22023 | 2212 if (!l) |
gianni@22023 | 2213 goto err; |
gianni@22023 | 2214 res = calloc(nb_net2s, sizeof (libxl_net2info)); |
gianni@22023 | 2215 if (!res) |
gianni@22023 | 2216 goto err; |
keir@21581 | 2217 net2s = res; |
keir@21581 | 2218 for (*nb = nb_net2s; nb_net2s > 0; --nb_net2s, ++l, ++net2s) { |
gianni@22023 | 2219 net2_path_fe = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, *l); |
gianni@22023 | 2220 |
gianni@22023 | 2221 net2s->backend = libxl_xs_read(&gc, XBT_NULL, |
gianni@22023 | 2222 libxl_sprintf(&gc, "%s/backend", net2_path_fe)); |
gianni@22023 | 2223 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", net2_path_fe)); |
keir@21581 | 2224 net2s->backend_id = val ? strtoul(val, NULL, 10) : -1; |
keir@21581 | 2225 |
keir@21581 | 2226 net2s->devid = strtoul(*l, NULL, 10); |
gianni@22023 | 2227 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", net2_path_fe)); |
keir@21581 | 2228 net2s->state = val ? strtoul(val, NULL, 10) : -1; |
keir@21581 | 2229 |
gianni@22023 | 2230 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", net2_path_fe)); |
keir@21581 | 2231 for (i = 0, tok = strtok(val, ":"); tok && (i < 6); |
keir@21581 | 2232 ++i, tok = strtok(NULL, ":")) { |
keir@21581 | 2233 net2s->mac[i] = strtoul(tok, NULL, 16); |
keir@21581 | 2234 } |
gianni@22023 | 2235 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-trusted", net2_path_fe)); |
keir@21581 | 2236 net2s->trusted = val ? strtoul(val, NULL, 10) : -1; |
keir@21581 | 2237 |
gianni@22023 | 2238 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", net2_path_fe)); |
keir@21581 | 2239 for (i = 0, tok = strtok(val, ":"); tok && (i < 6); |
keir@21581 | 2240 ++i, tok = strtok(NULL, ":")) { |
keir@21581 | 2241 net2s->back_mac[i] = strtoul(tok, NULL, 16); |
keir@21581 | 2242 } |
gianni@22023 | 2243 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", net2_path_fe)); |
keir@21581 | 2244 net2s->filter_mac = val ? strtoul(val, NULL, 10) : -1; |
keir@21581 | 2245 |
gianni@22023 | 2246 net2s->frontend = libxl_xs_read(&gc, XBT_NULL, |
gianni@22023 | 2247 libxl_sprintf(&gc, "%s/frontend", net2s->backend)); |
gianni@22023 | 2248 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", net2s->backend)); |
keir@21581 | 2249 net2s->frontend_id = val ? strtoul(val, NULL, 10) : -1; |
keir@21581 | 2250 } |
keir@21581 | 2251 |
gianni@22023 | 2252 libxl_free_all(&gc); |
keir@21581 | 2253 return res; |
gianni@22023 | 2254 err: |
gianni@22023 | 2255 libxl_free_all(&gc); |
gianni@22023 | 2256 return NULL; |
keir@21581 | 2257 } |
keir@21581 | 2258 |
ian@21930 | 2259 int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait) |
keir@21582 | 2260 { |
keir@21582 | 2261 libxl_device device; |
keir@21582 | 2262 |
keir@21582 | 2263 device.backend_devid = net2->devid; |
keir@21582 | 2264 device.backend_domid = net2->backend_domid; |
keir@21582 | 2265 device.backend_kind = DEVICE_VIF2; |
keir@21582 | 2266 device.devid = net2->devid; |
keir@21582 | 2267 device.domid = net2->domid; |
keir@21582 | 2268 device.kind = DEVICE_VIF2; |
keir@21582 | 2269 |
keir@21582 | 2270 return libxl_device_del(ctx, &device, wait); |
keir@21582 | 2271 } |
keir@21582 | 2272 |
keir@21581 | 2273 |
keir@20462 | 2274 /******************************************************************************/ |
ian@21930 | 2275 int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, libxl_device_console *console) |
keir@20462 | 2276 { |
gianni@22023 | 2277 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20509 | 2278 flexarray_t *front; |
keir@20509 | 2279 flexarray_t *back; |
keir@20509 | 2280 unsigned int boffset = 0; |
keir@20509 | 2281 unsigned int foffset = 0; |
keir@20509 | 2282 libxl_device device; |
gianni@22023 | 2283 int rc; |
keir@20509 | 2284 |
keir@20509 | 2285 if (console->build_state) { |
keir@20509 | 2286 xs_transaction_t t; |
stefano@22040 | 2287 char **ents = (char **) libxl_calloc(&gc, 11, sizeof(char *)); |
keir@20516 | 2288 ents[0] = "console/port"; |
gianni@22023 | 2289 ents[1] = libxl_sprintf(&gc, "%"PRIu32, console->build_state->console_port); |
keir@20516 | 2290 ents[2] = "console/ring-ref"; |
gianni@22023 | 2291 ents[3] = libxl_sprintf(&gc, "%lu", console->build_state->console_mfn); |
keir@20516 | 2292 ents[4] = "console/limit"; |
gianni@22023 | 2293 ents[5] = libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT); |
keir@20516 | 2294 ents[6] = "console/type"; |
stefano@22040 | 2295 if (console->consback == LIBXL_CONSBACK_XENCONSOLED) |
keir@20509 | 2296 ents[7] = "xenconsoled"; |
keir@20509 | 2297 else |
keir@20509 | 2298 ents[7] = "ioemu"; |
stefano@22040 | 2299 ents[8] = "console/output"; |
stefano@22040 | 2300 ents[9] = console->output; |
keir@20509 | 2301 retry_transaction: |
keir@20509 | 2302 t = xs_transaction_start(ctx->xsh); |
gianni@22023 | 2303 libxl_xs_writev(&gc, t, libxl_xs_get_dompath(&gc, console->domid), ents); |
keir@20509 | 2304 if (!xs_transaction_end(ctx->xsh, t, 0)) |
keir@20509 | 2305 if (errno == EAGAIN) |
keir@20509 | 2306 goto retry_transaction; |
keir@20509 | 2307 } |
keir@20509 | 2308 |
keir@20509 | 2309 front = flexarray_make(16, 1); |
gianni@22023 | 2310 if (!front) { |
gianni@22023 | 2311 rc = ERROR_NOMEM; |
gianni@22023 | 2312 goto out; |
gianni@22023 | 2313 } |
keir@20509 | 2314 back = flexarray_make(16, 1); |
gianni@22023 | 2315 if (!back) { |
gianni@22023 | 2316 rc = ERROR_NOMEM; |
gianni@22023 | 2317 goto out_free; |
gianni@22023 | 2318 } |
keir@20509 | 2319 |
keir@20509 | 2320 device.backend_devid = console->devid; |
keir@20509 | 2321 device.backend_domid = console->backend_domid; |
keir@20509 | 2322 device.backend_kind = DEVICE_CONSOLE; |
keir@20509 | 2323 device.devid = console->devid; |
keir@20509 | 2324 device.domid = console->domid; |
keir@20509 | 2325 device.kind = DEVICE_CONSOLE; |
keir@20509 | 2326 |
keir@20516 | 2327 flexarray_set(back, boffset++, "frontend-id"); |
gianni@22023 | 2328 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", console->domid)); |
keir@20516 | 2329 flexarray_set(back, boffset++, "online"); |
keir@20516 | 2330 flexarray_set(back, boffset++, "1"); |
keir@20516 | 2331 flexarray_set(back, boffset++, "state"); |
gianni@22023 | 2332 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 2333 flexarray_set(back, boffset++, "domain"); |
gianni@22023 | 2334 flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); |
keir@20516 | 2335 flexarray_set(back, boffset++, "protocol"); |
keir@20516 | 2336 flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL); |
keir@20509 | 2337 |
stefano@22040 | 2338 /* if devid == 0 do not add the frontend to device/console/ because |
stefano@22040 | 2339 * it has already been added to console/ */ |
stefano@22040 | 2340 if (device.devid > 0) { |
stefano@22040 | 2341 flexarray_set(front, foffset++, "backend-id"); |
stefano@22040 | 2342 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", console->backend_domid)); |
stefano@22040 | 2343 flexarray_set(front, foffset++, "state"); |
stefano@22040 | 2344 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); |
stefano@22040 | 2345 flexarray_set(front, foffset++, "limit"); |
stefano@22040 | 2346 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT)); |
stefano@22040 | 2347 flexarray_set(front, foffset++, "protocol"); |
stefano@22040 | 2348 flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL); |
stefano@22040 | 2349 flexarray_set(front, foffset++, "type"); |
stefano@22040 | 2350 if (console->consback == LIBXL_CONSBACK_XENCONSOLED) |
stefano@22040 | 2351 flexarray_set(front, foffset++, "xenconsoled"); |
stefano@22040 | 2352 else |
stefano@22040 | 2353 flexarray_set(front, foffset++, "ioemu"); |
stefano@22040 | 2354 flexarray_set(front, foffset++, "output"); |
stefano@22040 | 2355 flexarray_set(front, foffset++, console->output); |
stefano@22040 | 2356 } |
keir@20509 | 2357 |
keir@20509 | 2358 libxl_device_generic_add(ctx, &device, |
gianni@22023 | 2359 libxl_xs_kvs_of_flexarray(&gc, back, boffset), |
gianni@22023 | 2360 libxl_xs_kvs_of_flexarray(&gc, front, foffset)); |
gianni@22023 | 2361 rc = 0; |
gianni@22023 | 2362 out_free: |
keir@20516 | 2363 flexarray_free(back); |
keir@20516 | 2364 flexarray_free(front); |
gianni@22023 | 2365 out: |
gianni@22023 | 2366 libxl_free_all(&gc); |
gianni@22023 | 2367 return rc; |
keir@20509 | 2368 } |
keir@20509 | 2369 |
keir@20509 | 2370 /******************************************************************************/ |
ian@21930 | 2371 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) |
keir@20509 | 2372 { |
gianni@22023 | 2373 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20509 | 2374 flexarray_t *front; |
keir@20509 | 2375 flexarray_t *back; |
keir@20509 | 2376 unsigned int boffset = 0; |
keir@20509 | 2377 unsigned int foffset = 0; |
keir@20509 | 2378 libxl_device device; |
gianni@22023 | 2379 int rc; |
keir@20509 | 2380 |
keir@20509 | 2381 front = flexarray_make(16, 1); |
gianni@22023 | 2382 if (!front) { |
gianni@22023 | 2383 rc = ERROR_NOMEM; |
gianni@22023 | 2384 goto out; |
gianni@22023 | 2385 } |
keir@20509 | 2386 back = flexarray_make(16, 1); |
gianni@22023 | 2387 if (!back) { |
gianni@22023 | 2388 rc = ERROR_NOMEM; |
gianni@22023 | 2389 goto out_free; |
gianni@22023 | 2390 } |
keir@20509 | 2391 |
keir@20509 | 2392 device.backend_devid = vkb->devid; |
keir@20509 | 2393 device.backend_domid = vkb->backend_domid; |
keir@20509 | 2394 device.backend_kind = DEVICE_VKBD; |
keir@20509 | 2395 device.devid = vkb->devid; |
keir@20509 | 2396 device.domid = vkb->domid; |
keir@20509 | 2397 device.kind = DEVICE_VKBD; |
keir@20509 | 2398 |
keir@20516 | 2399 flexarray_set(back, boffset++, "frontend-id"); |
gianni@22023 | 2400 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vkb->domid)); |
keir@20516 | 2401 flexarray_set(back, boffset++, "online"); |
keir@20516 | 2402 flexarray_set(back, boffset++, "1"); |
keir@20516 | 2403 flexarray_set(back, boffset++, "state"); |
gianni@22023 | 2404 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 2405 flexarray_set(back, boffset++, "domain"); |
gianni@22023 | 2406 flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); |
keir@20509 | 2407 |
keir@20516 | 2408 flexarray_set(front, foffset++, "backend-id"); |
gianni@22023 | 2409 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", vkb->backend_domid)); |
keir@20516 | 2410 flexarray_set(front, foffset++, "state"); |
gianni@22023 | 2411 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20509 | 2412 |
keir@20509 | 2413 libxl_device_generic_add(ctx, &device, |
gianni@22023 | 2414 libxl_xs_kvs_of_flexarray(&gc, back, boffset), |
gianni@22023 | 2415 libxl_xs_kvs_of_flexarray(&gc, front, foffset)); |
gianni@22023 | 2416 rc = 0; |
gianni@22023 | 2417 out_free: |
keir@20516 | 2418 flexarray_free(back); |
keir@20516 | 2419 flexarray_free(front); |
gianni@22023 | 2420 out: |
gianni@22023 | 2421 libxl_free_all(&gc); |
gianni@22023 | 2422 return rc; |
keir@20462 | 2423 } |
keir@20462 | 2424 |
ian@21930 | 2425 int libxl_device_vkb_clean_shutdown(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 2426 { |
keir@20462 | 2427 return ERROR_NI; |
keir@20462 | 2428 } |
keir@20462 | 2429 |
ian@21930 | 2430 int libxl_device_vkb_hard_shutdown(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 2431 { |
keir@20462 | 2432 return ERROR_NI; |
keir@20462 | 2433 } |
keir@20462 | 2434 |
ian@21930 | 2435 libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num) |
keir@20637 | 2436 { |
gianni@22023 | 2437 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20637 | 2438 char *be_path_tap, *be_path_vbd; |
keir@21411 | 2439 libxl_device_disk *dend, *disks, *ret = NULL; |
keir@21411 | 2440 char **b, **l = NULL; |
gianni@22042 | 2441 unsigned int numl, len; |
keir@20637 | 2442 char *type; |
keir@20637 | 2443 |
gianni@22023 | 2444 be_path_vbd = libxl_sprintf(&gc, "%s/backend/vbd/%d", libxl_xs_get_dompath(&gc, 0), domid); |
gianni@22023 | 2445 be_path_tap = libxl_sprintf(&gc, "%s/backend/tap/%d", libxl_xs_get_dompath(&gc, 0), domid); |
gianni@22023 | 2446 |
gianni@22023 | 2447 b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_vbd, &numl); |
keir@20637 | 2448 if (l) { |
keir@21411 | 2449 ret = realloc(ret, sizeof(libxl_device_disk) * numl); |
keir@21411 | 2450 disks = ret; |
keir@21411 | 2451 *num = numl; |
keir@21411 | 2452 dend = ret + *num; |
keir@21411 | 2453 for (; disks < dend; ++disks, ++l) { |
keir@21411 | 2454 disks->backend_domid = 0; |
keir@21411 | 2455 disks->domid = domid; |
gianni@22042 | 2456 disks->physpath = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "%s/%s/params", be_path_vbd, *l), &len); |
gianni@22023 | 2457 libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype)); |
gianni@22042 | 2458 disks->virtpath = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "%s/%s/dev", be_path_vbd, *l), &len); |
gianni@22023 | 2459 disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/removable", be_path_vbd, *l))); |
gianni@22023 | 2460 if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/mode", be_path_vbd, *l)), "w")) |
keir@21411 | 2461 disks->readwrite = 1; |
keir@20637 | 2462 else |
keir@21411 | 2463 disks->readwrite = 0; |
gianni@22023 | 2464 type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/frontend", be_path_vbd, *l)))); |
keir@21411 | 2465 disks->is_cdrom = !strcmp(type, "cdrom"); |
keir@20637 | 2466 } |
keir@20637 | 2467 } |
gianni@22023 | 2468 b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_tap, &numl); |
keir@20637 | 2469 if (l) { |
keir@21411 | 2470 ret = realloc(ret, sizeof(libxl_device_disk) * (*num + numl)); |
keir@21411 | 2471 disks = ret + *num; |
keir@21411 | 2472 *num += numl; |
keir@21411 | 2473 for (dend = ret + *num; disks < dend; ++disks, ++l) { |
keir@21411 | 2474 disks->backend_domid = 0; |
keir@21411 | 2475 disks->domid = domid; |
gianni@22042 | 2476 disks->physpath = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "%s/%s/params", be_path_tap, *l), &len); |
gianni@22023 | 2477 libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/type", be_path_tap, *l)), &(disks->phystype)); |
gianni@22042 | 2478 disks->virtpath = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "%s/%s/dev", be_path_tap, *l), &len); |
gianni@22023 | 2479 disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/removable", be_path_tap, *l))); |
gianni@22023 | 2480 if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/mode", be_path_tap, *l)), "w")) |
keir@21411 | 2481 disks->readwrite = 1; |
keir@20637 | 2482 else |
keir@21411 | 2483 disks->readwrite = 0; |
gianni@22023 | 2484 type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/frontend", be_path_tap, *l)))); |
keir@21411 | 2485 disks->is_cdrom = !strcmp(type, "cdrom"); |
keir@20637 | 2486 } |
keir@20637 | 2487 } |
gianni@22023 | 2488 libxl_free_all(&gc); |
keir@21411 | 2489 return ret; |
keir@21411 | 2490 } |
keir@21411 | 2491 |
ian@21930 | 2492 int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, |
keir@21411 | 2493 libxl_device_disk *disk, libxl_diskinfo *diskinfo) |
keir@21411 | 2494 { |
gianni@22023 | 2495 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21411 | 2496 char *dompath, *diskpath; |
keir@21411 | 2497 char *val; |
keir@21411 | 2498 |
gianni@22023 | 2499 dompath = libxl_xs_get_dompath(&gc, domid); |
keir@21411 | 2500 diskinfo->devid = device_disk_dev_number(disk->virtpath); |
keir@21411 | 2501 |
keir@21411 | 2502 /* tap devices entries in xenstore are written as vbd devices. */ |
gianni@22023 | 2503 diskpath = libxl_sprintf(&gc, "%s/device/vbd/%d", dompath, diskinfo->devid); |
ian@22059 | 2504 diskinfo->backend = xs_read(ctx->xsh, XBT_NULL, |
ian@22059 | 2505 libxl_sprintf(&gc, "%s/backend", diskpath), NULL); |
keir@21411 | 2506 if (!diskinfo->backend) { |
gianni@22023 | 2507 libxl_free_all(&gc); |
keir@21411 | 2508 return ERROR_FAIL; |
keir@21411 | 2509 } |
gianni@22023 | 2510 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", diskpath)); |
keir@21411 | 2511 diskinfo->backend_id = val ? strtoul(val, NULL, 10) : -1; |
gianni@22023 | 2512 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", diskpath)); |
keir@21411 | 2513 diskinfo->state = val ? strtoul(val, NULL, 10) : -1; |
gianni@22023 | 2514 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", diskpath)); |
keir@21411 | 2515 diskinfo->evtch = val ? strtoul(val, NULL, 10) : -1; |
gianni@22023 | 2516 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/ring-ref", diskpath)); |
keir@21411 | 2517 diskinfo->rref = val ? strtoul(val, NULL, 10) : -1; |
ian@22059 | 2518 diskinfo->frontend = xs_read(ctx->xsh, XBT_NULL, |
ian@22059 | 2519 libxl_sprintf(&gc, "%s/frontend", diskinfo->backend), NULL); |
gianni@22023 | 2520 val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", diskinfo->backend)); |
keir@21411 | 2521 diskinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; |
keir@21411 | 2522 |
gianni@22023 | 2523 libxl_free_all(&gc); |
keir@21411 | 2524 return 0; |
keir@20637 | 2525 } |
keir@20637 | 2526 |
ian@21930 | 2527 int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) |
keir@20637 | 2528 { |
keir@20637 | 2529 int num, i; |
keir@20637 | 2530 uint32_t stubdomid; |
keir@20637 | 2531 libxl_device_disk *disks; |
keir@20637 | 2532 |
keir@20637 | 2533 if (!disk->physpath) { |
keir@20637 | 2534 disk->physpath = ""; |
keir@20637 | 2535 disk->phystype = PHYSTYPE_PHY; |
keir@20637 | 2536 } |
keir@20637 | 2537 disks = libxl_device_disk_list(ctx, domid, &num); |
keir@20637 | 2538 for (i = 0; i < num; i++) { |
keir@20637 | 2539 if (disks[i].is_cdrom && !strcmp(disk->virtpath, disks[i].virtpath)) |
keir@20637 | 2540 /* found */ |
keir@20637 | 2541 break; |
keir@20637 | 2542 } |
keir@20637 | 2543 if (i == num) { |
keir@20637 | 2544 XL_LOG(ctx, XL_LOG_ERROR, "Virtual device not found"); |
gianni@22023 | 2545 free(disks); |
gianni@21892 | 2546 return ERROR_FAIL; |
keir@20637 | 2547 } |
keir@20637 | 2548 libxl_device_disk_del(ctx, disks + i, 1); |
keir@20637 | 2549 libxl_device_disk_add(ctx, domid, disk); |
keir@20637 | 2550 stubdomid = libxl_get_stubdom_id(ctx, domid); |
keir@20637 | 2551 if (stubdomid) { |
keir@20781 | 2552 disks[i].domid = stubdomid; |
keir@20637 | 2553 libxl_device_disk_del(ctx, disks + i, 1); |
keir@20781 | 2554 disk->domid = stubdomid; |
keir@20637 | 2555 libxl_device_disk_add(ctx, stubdomid, disk); |
keir@20781 | 2556 disk->domid = domid; |
keir@20637 | 2557 } |
gianni@22042 | 2558 /* FIXME: leaks disk paths */ |
gianni@22023 | 2559 free(disks); |
keir@20637 | 2560 return 0; |
keir@20637 | 2561 } |
keir@20637 | 2562 |
keir@20462 | 2563 /******************************************************************************/ |
gianni@22023 | 2564 static int libxl_build_xenpv_qemu_args(libxl_gc *gc, |
stefano@22040 | 2565 uint32_t domid, |
keir@20509 | 2566 libxl_device_vfb *vfb, |
keir@20860 | 2567 libxl_device_model_info *info) |
keir@20860 | 2568 { |
gianni@22023 | 2569 libxl_ctx *ctx = libxl_gc_owner(gc); |
keir@20509 | 2570 memset(info, 0x00, sizeof(libxl_device_model_info)); |
keir@20509 | 2571 |
stefano@22041 | 2572 if (vfb != NULL) { |
stefano@22041 | 2573 info->vnc = vfb->vnc; |
stefano@22041 | 2574 if (vfb->vnclisten) |
stefano@22041 | 2575 info->vnclisten = libxl_strdup(gc, vfb->vnclisten); |
stefano@22041 | 2576 info->vncdisplay = vfb->vncdisplay; |
stefano@22041 | 2577 info->vncunused = vfb->vncunused; |
stefano@22041 | 2578 if (vfb->vncpasswd) |
stefano@22041 | 2579 info->vncpasswd = vfb->vncpasswd; |
stefano@22041 | 2580 if (vfb->keymap) |
stefano@22041 | 2581 info->keymap = libxl_strdup(gc, vfb->keymap); |
stefano@22041 | 2582 info->sdl = vfb->sdl; |
stefano@22041 | 2583 info->opengl = vfb->opengl; |
stefano@22041 | 2584 } else |
stefano@22041 | 2585 info->nographic = 1; |
stefano@22040 | 2586 info->domid = domid; |
stefano@22040 | 2587 info->dom_name = libxl_domid_to_name(ctx, domid); |
gianni@22023 | 2588 info->device_model = libxl_abs_path(gc, "qemu-dm", libxl_libexec_path()); |
keir@20509 | 2589 info->type = XENPV; |
keir@20509 | 2590 return 0; |
keir@20509 | 2591 } |
keir@20509 | 2592 |
stefano@22040 | 2593 int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, |
ian@21930 | 2594 libxl_device_model_starting **starting_r) |
keir@20509 | 2595 { |
gianni@22023 | 2596 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20509 | 2597 libxl_device_model_info info; |
keir@20509 | 2598 |
stefano@22040 | 2599 libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info); |
keir@20542 | 2600 libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); |
gianni@22023 | 2601 libxl_free_all(&gc); |
keir@20509 | 2602 return 0; |
keir@20509 | 2603 } |
keir@20509 | 2604 |
ian@21930 | 2605 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) |
keir@20462 | 2606 { |
gianni@22023 | 2607 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@20509 | 2608 flexarray_t *front; |
keir@20509 | 2609 flexarray_t *back; |
keir@20509 | 2610 unsigned int boffset = 0; |
keir@20509 | 2611 unsigned int foffset = 0; |
keir@20509 | 2612 libxl_device device; |
gianni@22023 | 2613 int rc; |
keir@20509 | 2614 |
keir@20509 | 2615 front = flexarray_make(16, 1); |
gianni@22023 | 2616 if (!front) { |
gianni@22023 | 2617 rc = ERROR_NOMEM; |
gianni@22023 | 2618 goto out; |
gianni@22023 | 2619 } |
keir@20509 | 2620 back = flexarray_make(16, 1); |
gianni@22023 | 2621 if (!back) { |
gianni@22023 | 2622 rc = ERROR_NOMEM; |
gianni@22023 | 2623 goto out_free; |
gianni@22023 | 2624 } |
keir@20509 | 2625 |
keir@20509 | 2626 device.backend_devid = vfb->devid; |
keir@20509 | 2627 device.backend_domid = vfb->backend_domid; |
keir@20509 | 2628 device.backend_kind = DEVICE_VFB; |
keir@20509 | 2629 device.devid = vfb->devid; |
keir@20509 | 2630 device.domid = vfb->domid; |
keir@20509 | 2631 device.kind = DEVICE_VFB; |
keir@20509 | 2632 |
keir@20516 | 2633 flexarray_set(back, boffset++, "frontend-id"); |
gianni@22023 | 2634 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->domid)); |
keir@20516 | 2635 flexarray_set(back, boffset++, "online"); |
keir@20516 | 2636 flexarray_set(back, boffset++, "1"); |
keir@20516 | 2637 flexarray_set(back, boffset++, "state"); |
gianni@22023 | 2638 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20516 | 2639 flexarray_set(back, boffset++, "domain"); |
gianni@22023 | 2640 flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); |
keir@20516 | 2641 flexarray_set(back, boffset++, "vnc"); |
gianni@22023 | 2642 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vnc)); |
keir@20516 | 2643 flexarray_set(back, boffset++, "vnclisten"); |
keir@20516 | 2644 flexarray_set(back, boffset++, vfb->vnclisten); |
keir@21362 | 2645 flexarray_set(back, boffset++, "vncpasswd"); |
keir@21362 | 2646 flexarray_set(back, boffset++, vfb->vncpasswd); |
keir@20516 | 2647 flexarray_set(back, boffset++, "vncdisplay"); |
gianni@22023 | 2648 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncdisplay)); |
keir@20516 | 2649 flexarray_set(back, boffset++, "vncunused"); |
gianni@22023 | 2650 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncunused)); |
keir@20516 | 2651 flexarray_set(back, boffset++, "sdl"); |
gianni@22023 | 2652 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->sdl)); |
keir@20516 | 2653 flexarray_set(back, boffset++, "opengl"); |
gianni@22023 | 2654 flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->opengl)); |
keir@20509 | 2655 if (vfb->xauthority) { |
keir@20516 | 2656 flexarray_set(back, boffset++, "xauthority"); |
keir@20516 | 2657 flexarray_set(back, boffset++, vfb->xauthority); |
keir@20509 | 2658 } |
keir@20509 | 2659 if (vfb->display) { |
keir@20516 | 2660 flexarray_set(back, boffset++, "display"); |
keir@20516 | 2661 flexarray_set(back, boffset++, vfb->display); |
keir@20509 | 2662 } |
keir@20509 | 2663 |
keir@20516 | 2664 flexarray_set(front, foffset++, "backend-id"); |
gianni@22023 | 2665 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", vfb->backend_domid)); |
keir@20516 | 2666 flexarray_set(front, foffset++, "state"); |
gianni@22023 | 2667 flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); |
keir@20509 | 2668 |
keir@20509 | 2669 libxl_device_generic_add(ctx, &device, |
gianni@22023 | 2670 libxl_xs_kvs_of_flexarray(&gc, back, boffset), |
gianni@22023 | 2671 libxl_xs_kvs_of_flexarray(&gc, front, foffset)); |
gianni@22023 | 2672 rc = 0; |
gianni@22023 | 2673 out_free: |
keir@20509 | 2674 flexarray_free(front); |
keir@20509 | 2675 flexarray_free(back); |
gianni@22023 | 2676 out: |
gianni@22023 | 2677 libxl_free_all(&gc); |
gianni@22023 | 2678 return rc; |
keir@20462 | 2679 } |
keir@20462 | 2680 |
ian@21930 | 2681 int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 2682 { |
keir@20462 | 2683 return ERROR_NI; |
keir@20462 | 2684 } |
keir@20462 | 2685 |
ian@21930 | 2686 int libxl_device_vfb_hard_shutdown(libxl_ctx *ctx, uint32_t domid) |
keir@20462 | 2687 { |
keir@20462 | 2688 return ERROR_NI; |
keir@20462 | 2689 } |
keir@20462 | 2690 |
keir@20462 | 2691 /******************************************************************************/ |
keir@20482 | 2692 |
ian@21930 | 2693 int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb) |
keir@21404 | 2694 { |
gianni@22023 | 2695 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21404 | 2696 char *mem, *endptr; |
keir@21404 | 2697 uint32_t memorykb; |
gianni@22023 | 2698 char *dompath = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 2699 int rc = 1; |
gianni@22023 | 2700 |
gianni@22023 | 2701 mem = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath)); |
keir@21404 | 2702 if (!mem) { |
keir@21404 | 2703 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from %s/memory/target\n", dompath); |
gianni@22023 | 2704 goto out; |
keir@21404 | 2705 } |
keir@21404 | 2706 memorykb = strtoul(mem, &endptr, 10); |
keir@21404 | 2707 if (*endptr != '\0') { |
keir@21404 | 2708 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid memory %s from %s/memory/target\n", mem, dompath); |
gianni@22023 | 2709 goto out; |
keir@21404 | 2710 } |
keir@21404 | 2711 |
keir@21404 | 2712 if (max_memkb < memorykb) { |
keir@21404 | 2713 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "memory_static_max must be greater than or or equal to memory_dynamic_max\n"); |
gianni@22023 | 2714 goto out; |
keir@21404 | 2715 } |
keir@21404 | 2716 |
keir@21404 | 2717 if (domid != 0) |
gianni@22023 | 2718 libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb); |
gianni@22023 | 2719 |
gianni@22023 | 2720 rc = 0; |
gianni@22023 | 2721 out: |
gianni@22023 | 2722 libxl_free_all(&gc); |
gianni@22023 | 2723 return rc; |
keir@21404 | 2724 } |
keir@21404 | 2725 |
ian@21930 | 2726 int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) |
keir@20647 | 2727 { |
gianni@22023 | 2728 libxl_gc gc = LIBXL_INIT_GC(ctx); |
gianni@22023 | 2729 int rc = 1; |
keir@21422 | 2730 uint32_t memorykb = 0, videoram = 0; |
keir@21405 | 2731 char *memmax, *endptr, *videoram_s = NULL; |
gianni@22023 | 2732 char *dompath = libxl_xs_get_dompath(&gc, domid); |
keir@21374 | 2733 xc_domaininfo_t info; |
ian@21930 | 2734 libxl_dominfo ptr; |
keir@21374 | 2735 char *uuid; |
keir@20542 | 2736 |
keir@21405 | 2737 if (domid) { |
gianni@22023 | 2738 memmax = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath)); |
keir@21405 | 2739 if (!memmax) { |
keir@21405 | 2740 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, |
keir@21405 | 2741 "cannot get memory info from %s/memory/static-max\n", dompath); |
gianni@22023 | 2742 goto out; |
keir@21405 | 2743 } |
keir@21405 | 2744 memorykb = strtoul(memmax, &endptr, 10); |
keir@21405 | 2745 if (*endptr != '\0') { |
keir@21405 | 2746 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, |
keir@21405 | 2747 "invalid max memory %s from %s/memory/static-max\n", memmax, dompath); |
gianni@22023 | 2748 goto out; |
keir@21405 | 2749 } |
keir@21405 | 2750 |
keir@21405 | 2751 if (target_memkb > memorykb) { |
keir@21504 | 2752 XL_LOG(ctx, XL_LOG_ERROR, |
keir@21405 | 2753 "memory_dynamic_max must be less than or equal to memory_static_max\n"); |
gianni@22023 | 2754 goto out; |
keir@21405 | 2755 } |
keir@21405 | 2756 } |
keir@21405 | 2757 |
gianni@22023 | 2758 videoram_s = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/videoram", dompath)); |
keir@21314 | 2759 videoram = videoram_s ? atoi(videoram_s) : 0; |
keir@20647 | 2760 |
gianni@22023 | 2761 libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath), "%"PRIu32, target_memkb); |
keir@21374 | 2762 |
keir@21374 | 2763 rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info); |
keir@21374 | 2764 if (rc != 1 || info.domain != domid) |
gianni@22023 | 2765 goto out; |
keir@21374 | 2766 xcinfo2xlinfo(&info, &ptr); |
gianni@22047 | 2767 uuid = libxl_uuid2string(&gc, ptr.uuid); |
gianni@22023 | 2768 libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024); |
keir@21374 | 2769 |
keir@21422 | 2770 if (enforce || !domid) |
keir@21422 | 2771 memorykb = target_memkb; |
keir@21422 | 2772 rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + LIBXL_MAXMEM_CONSTANT); |
keir@21422 | 2773 if (rc != 0) |
gianni@22023 | 2774 goto out; |
keir@20647 | 2775 rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - videoram) / 4, NULL, NULL, NULL); |
gianni@22023 | 2776 |
gianni@22023 | 2777 out: |
gianni@22023 | 2778 libxl_free_all(&gc); |
keir@20647 | 2779 return rc; |
keir@20647 | 2780 } |
keir@20875 | 2781 |
ian@21930 | 2782 int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button) |
keir@20875 | 2783 { |
keir@20875 | 2784 int rc = -1; |
keir@20875 | 2785 |
keir@20875 | 2786 switch (button) { |
keir@20875 | 2787 case POWER_BUTTON: |
keir@20875 | 2788 rc = xc_domain_send_trigger(ctx->xch, domid, XEN_DOMCTL_SENDTRIGGER_POWER, 0); |
keir@20875 | 2789 break; |
keir@20875 | 2790 case SLEEP_BUTTON: |
keir@20875 | 2791 rc = xc_domain_send_trigger(ctx->xch, domid, XEN_DOMCTL_SENDTRIGGER_SLEEP, 0); |
keir@20875 | 2792 break; |
keir@20875 | 2793 default: |
keir@20875 | 2794 break; |
keir@20875 | 2795 } |
keir@20875 | 2796 |
keir@20875 | 2797 return rc; |
keir@20875 | 2798 } |
keir@21141 | 2799 |
ian@21930 | 2800 int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo) |
keir@21141 | 2801 { |
keir@21141 | 2802 xc_physinfo_t xcphysinfo = { 0 }; |
keir@21141 | 2803 int rc; |
keir@21141 | 2804 |
keir@21141 | 2805 rc = xc_physinfo(ctx->xch, &xcphysinfo); |
keir@21141 | 2806 if (rc != 0) { |
gianni@21892 | 2807 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting physinfo"); |
gianni@21892 | 2808 return ERROR_FAIL; |
keir@21141 | 2809 } |
keir@21141 | 2810 physinfo->threads_per_core = xcphysinfo.threads_per_core; |
keir@21141 | 2811 physinfo->cores_per_socket = xcphysinfo.cores_per_socket; |
keir@21142 | 2812 physinfo->max_cpu_id = xcphysinfo.max_cpu_id; |
keir@21141 | 2813 physinfo->nr_cpus = xcphysinfo.nr_cpus; |
keir@21141 | 2814 physinfo->cpu_khz = xcphysinfo.cpu_khz; |
keir@21141 | 2815 physinfo->total_pages = xcphysinfo.total_pages; |
keir@21141 | 2816 physinfo->free_pages = xcphysinfo.free_pages; |
keir@21141 | 2817 physinfo->scrub_pages = xcphysinfo.scrub_pages; |
keir@21264 | 2818 physinfo->nr_nodes = xcphysinfo.nr_nodes; |
keir@21264 | 2819 memcpy(physinfo->hw_cap,xcphysinfo.hw_cap, sizeof(physinfo->hw_cap)); |
keir@21264 | 2820 physinfo->phys_cap = xcphysinfo.capabilities; |
keir@21264 | 2821 |
keir@21141 | 2822 return 0; |
keir@21141 | 2823 } |
keir@21141 | 2824 |
gianni@22008 | 2825 static void do_free_version_info(libxl_version_info *info) |
gianni@22008 | 2826 { |
gianni@22008 | 2827 free(info->xen_version_extra); |
gianni@22008 | 2828 free(info->compiler); |
gianni@22008 | 2829 free(info->compile_by); |
gianni@22008 | 2830 free(info->compile_domain); |
gianni@22008 | 2831 free(info->compile_date); |
gianni@22008 | 2832 free(info->capabilities); |
gianni@22008 | 2833 free(info->changeset); |
gianni@22008 | 2834 free(info->commandline); |
gianni@22008 | 2835 } |
gianni@22008 | 2836 |
ian@21930 | 2837 const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx) |
keir@21266 | 2838 { |
keir@21266 | 2839 union { |
keir@21266 | 2840 xen_extraversion_t xen_extra; |
keir@21266 | 2841 xen_compile_info_t xen_cc; |
keir@21266 | 2842 xen_changeset_info_t xen_chgset; |
keir@21266 | 2843 xen_capabilities_info_t xen_caps; |
keir@21266 | 2844 xen_platform_parameters_t p_parms; |
keir@21266 | 2845 xen_commandline_t xen_commandline; |
keir@21266 | 2846 } u; |
keir@21266 | 2847 long xen_version; |
keir@21266 | 2848 libxl_version_info *info = &ctx->version_info; |
keir@21266 | 2849 |
keir@21266 | 2850 if (info->xen_version_extra != NULL) |
keir@21266 | 2851 return info; |
keir@21266 | 2852 |
keir@21266 | 2853 xen_version = xc_version(ctx->xch, XENVER_version, NULL); |
keir@21266 | 2854 info->xen_version_major = xen_version >> 16; |
keir@21266 | 2855 info->xen_version_minor = xen_version & 0xFF; |
gianni@22008 | 2856 |
keir@21266 | 2857 xc_version(ctx->xch, XENVER_extraversion, &u.xen_extra); |
gianni@22008 | 2858 info->xen_version_extra = strdup(u.xen_extra); |
keir@21266 | 2859 |
keir@21266 | 2860 xc_version(ctx->xch, XENVER_compile_info, &u.xen_cc); |
gianni@22008 | 2861 info->compiler = strdup(u.xen_cc.compiler); |
gianni@22008 | 2862 info->compile_by = strdup(u.xen_cc.compile_by); |
gianni@22008 | 2863 info->compile_domain = strdup(u.xen_cc.compile_domain); |
gianni@22008 | 2864 info->compile_date = strdup(u.xen_cc.compile_date); |
keir@21266 | 2865 |
keir@21266 | 2866 xc_version(ctx->xch, XENVER_capabilities, &u.xen_caps); |
gianni@22008 | 2867 info->capabilities = strdup(u.xen_caps); |
keir@21266 | 2868 |
keir@21266 | 2869 xc_version(ctx->xch, XENVER_changeset, &u.xen_chgset); |
gianni@22008 | 2870 info->changeset = strdup(u.xen_chgset); |
keir@21266 | 2871 |
keir@21266 | 2872 xc_version(ctx->xch, XENVER_platform_parameters, &u.p_parms); |
keir@21266 | 2873 info->virt_start = u.p_parms.virt_start; |
keir@21266 | 2874 |
keir@21266 | 2875 info->pagesize = xc_version(ctx->xch, XENVER_pagesize, NULL); |
keir@21266 | 2876 |
keir@21266 | 2877 xc_version(ctx->xch, XENVER_commandline, &u.xen_commandline); |
gianni@22008 | 2878 info->commandline = strdup(u.xen_commandline); |
keir@21266 | 2879 |
keir@21266 | 2880 return info; |
keir@21266 | 2881 } |
keir@21266 | 2882 |
ian@21930 | 2883 libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, |
sstabellini@22000 | 2884 int *nb_vcpu, int *nrcpus) |
keir@21141 | 2885 { |
ian@21930 | 2886 libxl_vcpuinfo *ptr, *ret; |
keir@21141 | 2887 xc_domaininfo_t domaininfo; |
keir@21141 | 2888 xc_vcpuinfo_t vcpuinfo; |
keir@21141 | 2889 xc_physinfo_t physinfo = { 0 }; |
gianni@22015 | 2890 uint64_t *cpumaps; |
gianni@22015 | 2891 unsigned num_cpuwords; |
keir@21141 | 2892 |
keir@21141 | 2893 if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) { |
gianni@21892 | 2894 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting infolist"); |
keir@21141 | 2895 return NULL; |
keir@21141 | 2896 } |
keir@21141 | 2897 if (xc_physinfo(ctx->xch, &physinfo) == -1) { |
gianni@21892 | 2898 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting physinfo"); |
keir@21141 | 2899 return NULL; |
keir@21141 | 2900 } |
sstabellini@22000 | 2901 *nrcpus = physinfo.max_cpu_id + 1; |
gianni@22015 | 2902 ret = ptr = calloc(domaininfo.max_vcpu_id + 1, sizeof (libxl_vcpuinfo)); |
keir@21141 | 2903 if (!ptr) { |
keir@21141 | 2904 return NULL; |
keir@21141 | 2905 } |
keir@21141 | 2906 |
gianni@22015 | 2907 num_cpuwords = ((physinfo.max_cpu_id + 64) / 64); |
gianni@22015 | 2908 cpumaps = calloc(num_cpuwords * sizeof(*cpumaps), domaininfo.max_vcpu_id + 1); |
keir@21141 | 2909 for (*nb_vcpu = 0; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) { |
gianni@22015 | 2910 ptr->cpumap = cpumaps + (num_cpuwords * *nb_vcpu); |
keir@21141 | 2911 if (!ptr->cpumap) { |
keir@21141 | 2912 return NULL; |
keir@21141 | 2913 } |
keir@21141 | 2914 if (xc_vcpu_getinfo(ctx->xch, domid, *nb_vcpu, &vcpuinfo) == -1) { |
gianni@21892 | 2915 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting vcpu info"); |
keir@21141 | 2916 return NULL; |
keir@21141 | 2917 } |
sstabellini@22000 | 2918 if (xc_vcpu_getaffinity(ctx->xch, domid, *nb_vcpu, |
sstabellini@22000 | 2919 ptr->cpumap, ((*nrcpus) + 7) / 8) == -1) { |
gianni@21892 | 2920 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting vcpu affinity"); |
keir@21141 | 2921 return NULL; |
keir@21141 | 2922 } |
keir@21141 | 2923 ptr->vcpuid = *nb_vcpu; |
keir@21141 | 2924 ptr->cpu = vcpuinfo.cpu; |
keir@21141 | 2925 ptr->online = !!vcpuinfo.online; |
keir@21141 | 2926 ptr->blocked = !!vcpuinfo.blocked; |
keir@21141 | 2927 ptr->running = !!vcpuinfo.running; |
keir@21141 | 2928 ptr->vcpu_time = vcpuinfo.cpu_time; |
keir@21141 | 2929 } |
keir@21141 | 2930 return ret; |
keir@21141 | 2931 } |
keir@21142 | 2932 |
gianni@22015 | 2933 void libxl_free_vcpu_list(libxl_vcpuinfo *vcpu) |
gianni@22015 | 2934 { |
gianni@22015 | 2935 if ( vcpu ) |
gianni@22015 | 2936 free(vcpu[0].cpumap); |
gianni@22015 | 2937 free(vcpu); |
gianni@22015 | 2938 } |
gianni@22015 | 2939 |
ian@21930 | 2940 int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, |
sstabellini@22000 | 2941 uint64_t *cpumap, int nrcpus) |
keir@21142 | 2942 { |
sstabellini@22000 | 2943 if (xc_vcpu_setaffinity(ctx->xch, domid, vcpuid, cpumap, (nrcpus + 7) / 8)) { |
gianni@21892 | 2944 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "setting vcpu affinity"); |
gianni@21892 | 2945 return ERROR_FAIL; |
gianni@21892 | 2946 } |
gianni@21892 | 2947 return 0; |
keir@21142 | 2948 } |
keir@21143 | 2949 |
ian@21930 | 2950 int libxl_set_vcpucount(libxl_ctx *ctx, uint32_t domid, uint32_t count) |
keir@21143 | 2951 { |
gianni@22023 | 2952 libxl_gc gc = LIBXL_INIT_GC(ctx); |
keir@21143 | 2953 xc_domaininfo_t domaininfo; |
keir@21143 | 2954 char *dompath; |
gianni@22023 | 2955 int i, rc = ERROR_FAIL; |
keir@21143 | 2956 |
keir@21143 | 2957 if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) { |
gianni@21892 | 2958 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting domain info list"); |
gianni@22023 | 2959 goto out; |
keir@21143 | 2960 } |
keir@21143 | 2961 if (!count || ((domaininfo.max_vcpu_id + 1) < count)) { |
gianni@22023 | 2962 rc = ERROR_INVAL; |
gianni@22023 | 2963 goto out; |
keir@21143 | 2964 } |
gianni@22023 | 2965 if (!(dompath = libxl_xs_get_dompath(&gc, domid))) |
gianni@22023 | 2966 goto out; |
keir@21143 | 2967 |
keir@21143 | 2968 for (i = 0; i <= domaininfo.max_vcpu_id; ++i) { |
gianni@22023 | 2969 libxl_xs_write(&gc, XBT_NULL, |
gianni@22023 | 2970 libxl_sprintf(&gc, "%s/cpu/%u/availability", dompath, i), |
keir@21143 | 2971 "%s", ((1 << i) & ((1 << count) - 1)) ? "online" : "offline"); |
keir@21143 | 2972 } |
gianni@22023 | 2973 rc = 0; |
gianni@22023 | 2974 out: |
gianni@22023 | 2975 libxl_free_all(&gc); |
gianni@22023 | 2976 return rc; |
keir@21143 | 2977 } |
keir@21265 | 2978 |
keir@21265 | 2979 /* |
keir@21265 | 2980 * returns one of the XEN_SCHEDULER_* constants from public/domctl.h |
keir@21265 | 2981 */ |
ian@21930 | 2982 int libxl_get_sched_id(libxl_ctx *ctx) |
keir@21265 | 2983 { |
keir@21265 | 2984 int sched, ret; |
keir@21265 | 2985 |
gianni@21892 | 2986 if ((ret = xc_sched_id(ctx->xch, &sched)) != 0) { |
gianni@21892 | 2987 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting domain info list"); |
gianni@21892 | 2988 return ERROR_FAIL; |
gianni@21892 | 2989 } |
keir@21265 | 2990 return sched; |
keir@21265 | 2991 } |
keir@21292 | 2992 |
ian@21930 | 2993 int libxl_sched_credit_domain_get(libxl_ctx *ctx, uint32_t domid, libxl_sched_credit *scinfo) |
keir@21292 | 2994 { |
keir@21292 | 2995 struct xen_domctl_sched_credit sdom; |
keir@21292 | 2996 int rc; |
keir@21292 | 2997 |
keir@21292 | 2998 rc = xc_sched_credit_domain_get(ctx->xch, domid, &sdom); |
gianni@21892 | 2999 if (rc != 0) { |
gianni@21892 | 3000 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "setting domain sched credit"); |
gianni@21892 | 3001 return ERROR_FAIL; |
gianni@21892 | 3002 } |
keir@21292 | 3003 |
keir@21292 | 3004 scinfo->weight = sdom.weight; |
keir@21292 | 3005 scinfo->cap = sdom.cap; |
keir@21292 | 3006 |
keir@21292 | 3007 return 0; |
keir@21292 | 3008 } |
keir@21292 | 3009 |
ian@21930 | 3010 int libxl_sched_credit_domain_set(libxl_ctx *ctx, uint32_t domid, libxl_sched_credit *scinfo) |
keir@21292 | 3011 { |
keir@21292 | 3012 struct xen_domctl_sched_credit sdom; |
keir@21292 | 3013 xc_domaininfo_t domaininfo; |
keir@21292 | 3014 int rc; |
keir@21292 | 3015 |
keir@21292 | 3016 rc = xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo); |
gianni@21892 | 3017 if (rc < 0) { |
gianni@21892 | 3018 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting domain info list"); |
gianni@21892 | 3019 return ERROR_FAIL; |
gianni@21892 | 3020 } |
keir@21292 | 3021 if (rc != 1 || domaininfo.domain != domid) |
gianni@21892 | 3022 return ERROR_INVAL; |
keir@21292 | 3023 |
keir@21292 | 3024 |
keir@21292 | 3025 if (scinfo->weight < 1 || scinfo->weight > 65535) { |
keir@21292 | 3026 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21292 | 3027 "Cpu weight out of range, valid values are within range from 1 to 65535"); |
gianni@21892 | 3028 return ERROR_INVAL; |
keir@21292 | 3029 } |
keir@21292 | 3030 |
keir@21292 | 3031 if (scinfo->cap < 0 || scinfo->cap > (domaininfo.max_vcpu_id + 1) * 100) { |
keir@21292 | 3032 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21292 | 3033 "Cpu cap out of range, valid range is from 0 to %d for specified number of vcpus", |
keir@21292 | 3034 ((domaininfo.max_vcpu_id + 1) * 100)); |
gianni@21892 | 3035 return ERROR_INVAL; |
keir@21292 | 3036 } |
keir@21292 | 3037 |
keir@21292 | 3038 sdom.weight = scinfo->weight; |
keir@21292 | 3039 sdom.cap = scinfo->cap; |
keir@21292 | 3040 |
keir@21292 | 3041 rc = xc_sched_credit_domain_set(ctx->xch, domid, &sdom); |
gianni@21892 | 3042 if ( rc < 0 ) { |
gianni@21892 | 3043 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "setting domain sched credit"); |
gianni@21892 | 3044 return ERROR_FAIL; |
gianni@21892 | 3045 } |
keir@21292 | 3046 |
keir@21292 | 3047 return 0; |
keir@21292 | 3048 } |
keir@21292 | 3049 |
keir@21393 | 3050 static int trigger_type_from_string(char *trigger_name) |
keir@21393 | 3051 { |
keir@21393 | 3052 if (!strcmp(trigger_name, "nmi")) |
keir@21393 | 3053 return XEN_DOMCTL_SENDTRIGGER_NMI; |
keir@21393 | 3054 else if (!strcmp(trigger_name, "reset")) |
keir@21393 | 3055 return XEN_DOMCTL_SENDTRIGGER_RESET; |
keir@21393 | 3056 else if (!strcmp(trigger_name, "init")) |
keir@21393 | 3057 return XEN_DOMCTL_SENDTRIGGER_INIT; |
keir@21393 | 3058 else if (!strcmp(trigger_name, "power")) |
keir@21393 | 3059 return XEN_DOMCTL_SENDTRIGGER_POWER; |
keir@21393 | 3060 else if (!strcmp(trigger_name, "sleep")) |
keir@21393 | 3061 return XEN_DOMCTL_SENDTRIGGER_SLEEP; |
keir@21393 | 3062 else |
keir@21393 | 3063 return -1; |
keir@21393 | 3064 } |
keir@21393 | 3065 |
ian@21930 | 3066 int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, char *trigger_name, uint32_t vcpuid) |
keir@21393 | 3067 { |
keir@21393 | 3068 int rc = -1; |
keir@21393 | 3069 int trigger_type = trigger_type_from_string(trigger_name); |
keir@21393 | 3070 |
keir@21393 | 3071 if (trigger_type == -1) { |
keir@21393 | 3072 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, |
keir@21393 | 3073 "Invalid trigger, valid triggers are <nmi|reset|init|power|sleep>"); |
gianni@21892 | 3074 return ERROR_INVAL; |
keir@21393 | 3075 } |
keir@21393 | 3076 |
keir@21393 | 3077 rc = xc_domain_send_trigger(ctx->xch, domid, trigger_type, vcpuid); |
gianni@21892 | 3078 if (rc != 0) { |
keir@21393 | 3079 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21393 | 3080 "Send trigger '%s' failed", trigger_name); |
gianni@21892 | 3081 return ERROR_FAIL; |
gianni@21892 | 3082 } |
gianni@21892 | 3083 |
gianni@21892 | 3084 return 0; |
keir@21393 | 3085 } |
keir@21402 | 3086 |
ian@21930 | 3087 int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq) |
keir@21402 | 3088 { |
gianni@22023 | 3089 libxl_gc gc = LIBXL_INIT_GC(ctx); |
gianni@22023 | 3090 char *dompath = libxl_xs_get_dompath(&gc, domid); |
gianni@22023 | 3091 |
gianni@22023 | 3092 libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/control/sysrq", dompath), "%c", sysrq); |
gianni@22023 | 3093 |
gianni@22023 | 3094 libxl_free_all(&gc); |
keir@21402 | 3095 return 0; |
keir@21402 | 3096 } |
keir@21402 | 3097 |
ian@21930 | 3098 int libxl_send_debug_keys(libxl_ctx *ctx, char *keys) |
keir@21472 | 3099 { |
gianni@21892 | 3100 int ret; |
gianni@21892 | 3101 ret = xc_send_debug_keys(ctx->xch, keys); |
gianni@21892 | 3102 if ( ret < 0 ) { |
gianni@21892 | 3103 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "sending debug keys"); |
gianni@21892 | 3104 return ERROR_FAIL; |
gianni@21892 | 3105 } |
gianni@21892 | 3106 return 0; |
keir@21472 | 3107 } |
keir@21472 | 3108 |
ian@21930 | 3109 libxl_xen_console_reader * |
ian@21930 | 3110 libxl_xen_console_read_start(libxl_ctx *ctx, int clear) |
keir@21496 | 3111 { |
ian@21930 | 3112 libxl_xen_console_reader *cr; |
keir@21496 | 3113 unsigned int size = 16384; |
keir@21496 | 3114 char *buf = malloc(size); |
keir@21496 | 3115 |
keir@21496 | 3116 if (!buf) { |
keir@21496 | 3117 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot malloc buffer for libxl_xen_console_reader," |
keir@21496 | 3118 " size is %u", size); |
keir@21496 | 3119 return NULL; |
keir@21496 | 3120 } |
keir@21496 | 3121 |
ian@21930 | 3122 cr = malloc(sizeof(libxl_xen_console_reader)); |
keir@21496 | 3123 if (!cr) { |
keir@21496 | 3124 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot malloc libxl_xen_console_reader"); |
keir@21496 | 3125 return NULL; |
keir@21496 | 3126 } |
keir@21496 | 3127 |
ian@21930 | 3128 memset(cr, 0, sizeof(libxl_xen_console_reader)); |
keir@21496 | 3129 cr->buffer = buf; |
keir@21496 | 3130 cr->size = size; |
keir@21496 | 3131 cr->count = size; |
keir@21496 | 3132 cr->clear = clear; |
keir@21496 | 3133 cr->incremental = 1; |
keir@21496 | 3134 |
keir@21496 | 3135 return cr; |
keir@21496 | 3136 } |
keir@21496 | 3137 |
keir@21496 | 3138 /* return values: *line_r |
keir@21496 | 3139 * 1 success, whole line obtained from buffer non-0 |
keir@21496 | 3140 * 0 no more lines available right now 0 |
keir@21496 | 3141 * negative error code ERROR_* 0 |
keir@21496 | 3142 * On success *line_r is updated to point to a nul-terminated |
keir@21496 | 3143 * string which is valid until the next call on the same console |
keir@21496 | 3144 * reader. The libxl caller may overwrite parts of the string |
keir@21496 | 3145 * if it wishes. */ |
ian@21930 | 3146 int libxl_xen_console_read_line(libxl_ctx *ctx, |
ian@21930 | 3147 libxl_xen_console_reader *cr, |
keir@21496 | 3148 char **line_r) |
keir@21496 | 3149 { |
keir@21496 | 3150 int ret; |
keir@21496 | 3151 |
keir@21496 | 3152 memset(cr->buffer, 0, cr->size); |
keir@21496 | 3153 ret = xc_readconsolering(ctx->xch, &cr->buffer, &cr->count, |
keir@21496 | 3154 cr->clear, cr->incremental, &cr->index); |
gianni@21892 | 3155 if (ret < 0) { |
gianni@21892 | 3156 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "reading console ring buffer"); |
gianni@21892 | 3157 return ERROR_FAIL; |
gianni@21892 | 3158 } |
keir@21496 | 3159 if (!ret) { |
keir@21496 | 3160 if (cr->count) { |
keir@21496 | 3161 *line_r = cr->buffer; |
keir@21496 | 3162 ret = 1; |
keir@21496 | 3163 } else { |
keir@21496 | 3164 *line_r = NULL; |
keir@21496 | 3165 ret = 0; |
keir@21496 | 3166 } |
keir@21496 | 3167 } |
keir@21496 | 3168 |
keir@21496 | 3169 return ret; |
keir@21496 | 3170 } |
keir@21496 | 3171 |
ian@21930 | 3172 void libxl_xen_console_read_finish(libxl_ctx *ctx, |
ian@21930 | 3173 libxl_xen_console_reader *cr) |
keir@21496 | 3174 { |
keir@21496 | 3175 free(cr->buffer); |
keir@21496 | 3176 free(cr); |
keir@21496 | 3177 } |
keir@21496 | 3178 |
ian@21930 | 3179 uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid) |
keir@21425 | 3180 { |
gianni@22023 | 3181 libxl_gc gc = LIBXL_INIT_GC(ctx); |
gianni@22023 | 3182 char *dompath = libxl_xs_get_dompath(&gc, domid); |
keir@21425 | 3183 char *vm_path, *start_time; |
gianni@22023 | 3184 uint32_t ret; |
keir@21425 | 3185 |
keir@21425 | 3186 vm_path = libxl_xs_read( |
gianni@22023 | 3187 &gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dompath)); |
keir@21425 | 3188 start_time = libxl_xs_read( |
gianni@22023 | 3189 &gc, XBT_NULL, libxl_sprintf(&gc, "%s/start_time", vm_path)); |
keir@21425 | 3190 if (start_time == NULL) { |
keir@21425 | 3191 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, |
keir@21425 | 3192 "Can't get start time of domain '%d'", domid); |
gianni@22023 | 3193 ret = -1; |
gianni@22023 | 3194 }else{ |
gianni@22023 | 3195 ret = strtoul(start_time, NULL, 10); |
keir@21425 | 3196 } |
gianni@22023 | 3197 libxl_free_all(&gc); |
gianni@22023 | 3198 return ret; |
keir@21425 | 3199 } |
keir@21425 | 3200 |
ian@21930 | 3201 char *libxl_tmem_list(libxl_ctx *ctx, uint32_t domid, int use_long) |
keir@21471 | 3202 { |
keir@21471 | 3203 int rc; |
keir@21471 | 3204 char _buf[32768]; |
keir@21471 | 3205 |
keir@21471 | 3206 rc = xc_tmem_control(ctx->xch, -1, TMEMC_LIST, domid, 32768, use_long, |
keir@21471 | 3207 0, _buf); |
keir@21471 | 3208 if (rc < 0) { |
keir@21471 | 3209 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21471 | 3210 "Can not get tmem list"); |
keir@21471 | 3211 return NULL; |
keir@21471 | 3212 } |
keir@21471 | 3213 |
keir@21471 | 3214 return strdup(_buf); |
keir@21471 | 3215 } |
keir@21471 | 3216 |
ian@21930 | 3217 int libxl_tmem_freeze(libxl_ctx *ctx, uint32_t domid) |
keir@21471 | 3218 { |
keir@21471 | 3219 int rc; |
keir@21471 | 3220 |
keir@21471 | 3221 rc = xc_tmem_control(ctx->xch, -1, TMEMC_FREEZE, domid, 0, 0, |
keir@21471 | 3222 0, NULL); |
keir@21471 | 3223 if (rc < 0) { |
keir@21471 | 3224 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21471 | 3225 "Can not freeze tmem pools"); |
gianni@21892 | 3226 return ERROR_FAIL; |
keir@21471 | 3227 } |
keir@21471 | 3228 |
keir@21471 | 3229 return rc; |
keir@21471 | 3230 } |
keir@21471 | 3231 |
ian@21930 | 3232 int libxl_tmem_destroy(libxl_ctx *ctx, uint32_t domid) |
keir@21471 | 3233 { |
keir@21471 | 3234 int rc; |
keir@21471 | 3235 |
keir@21471 | 3236 rc = xc_tmem_control(ctx->xch, -1, TMEMC_DESTROY, domid, 0, 0, |
keir@21471 | 3237 0, NULL); |
keir@21471 | 3238 if (rc < 0) { |
keir@21471 | 3239 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21471 | 3240 "Can not destroy tmem pools"); |
gianni@21892 | 3241 return ERROR_FAIL; |
keir@21471 | 3242 } |
keir@21471 | 3243 |
keir@21471 | 3244 return rc; |
keir@21471 | 3245 } |
keir@21471 | 3246 |
ian@21930 | 3247 int libxl_tmem_thaw(libxl_ctx *ctx, uint32_t domid) |
keir@21471 | 3248 { |
keir@21471 | 3249 int rc; |
keir@21471 | 3250 |
keir@21471 | 3251 rc = xc_tmem_control(ctx->xch, -1, TMEMC_THAW, domid, 0, 0, |
keir@21471 | 3252 0, NULL); |
keir@21471 | 3253 if (rc < 0) { |
keir@21471 | 3254 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21471 | 3255 "Can not thaw tmem pools"); |
gianni@21892 | 3256 return ERROR_FAIL; |
keir@21471 | 3257 } |
keir@21471 | 3258 |
keir@21471 | 3259 return rc; |
keir@21471 | 3260 } |
keir@21471 | 3261 |
keir@21471 | 3262 static int32_t tmem_setop_from_string(char *set_name) |
keir@21471 | 3263 { |
keir@21471 | 3264 if (!strcmp(set_name, "weight")) |
keir@21471 | 3265 return TMEMC_SET_WEIGHT; |
keir@21471 | 3266 else if (!strcmp(set_name, "cap")) |
keir@21471 | 3267 return TMEMC_SET_CAP; |
keir@21471 | 3268 else if (!strcmp(set_name, "compress")) |
keir@21471 | 3269 return TMEMC_SET_COMPRESS; |
keir@21471 | 3270 else |
keir@21471 | 3271 return -1; |
keir@21471 | 3272 } |
keir@21471 | 3273 |
ian@21930 | 3274 int libxl_tmem_set(libxl_ctx *ctx, uint32_t domid, char* name, uint32_t set) |
keir@21471 | 3275 { |
keir@21471 | 3276 int rc; |
keir@21471 | 3277 int32_t subop = tmem_setop_from_string(name); |
keir@21471 | 3278 |
keir@21471 | 3279 if (subop == -1) { |
keir@21471 | 3280 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, |
keir@21471 | 3281 "Invalid set, valid sets are <weight|cap|compress>"); |
gianni@21892 | 3282 return ERROR_INVAL; |
keir@21471 | 3283 } |
keir@21471 | 3284 rc = xc_tmem_control(ctx->xch, -1, subop, domid, set, 0, 0, NULL); |
keir@21471 | 3285 if (rc < 0) { |
keir@21471 | 3286 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21471 | 3287 "Can not set tmem %s", name); |
gianni@21892 | 3288 return ERROR_FAIL; |
keir@21471 | 3289 } |
keir@21471 | 3290 |
keir@21471 | 3291 return rc; |
keir@21471 | 3292 } |
keir@21471 | 3293 |
ian@21930 | 3294 int libxl_tmem_shared_auth(libxl_ctx *ctx, uint32_t domid, |
keir@21471 | 3295 char* uuid, int auth) |
keir@21471 | 3296 { |
keir@21471 | 3297 int rc; |
keir@21471 | 3298 |
keir@21471 | 3299 rc = xc_tmem_auth(ctx->xch, domid, uuid, auth); |
keir@21471 | 3300 if (rc < 0) { |
keir@21471 | 3301 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
keir@21471 | 3302 "Can not set tmem shared auth"); |
gianni@21892 | 3303 return ERROR_FAIL; |
keir@21471 | 3304 } |
keir@21471 | 3305 |
keir@21471 | 3306 return rc; |
keir@21471 | 3307 } |
keir@21471 | 3308 |
ian@21930 | 3309 int libxl_tmem_freeable(libxl_ctx *ctx) |
sstabellini@21863 | 3310 { |
sstabellini@21863 | 3311 int rc; |
sstabellini@21863 | 3312 |
sstabellini@21863 | 3313 rc = xc_tmem_control(ctx->xch, -1, TMEMC_QUERY_FREEABLE_MB, -1, 0, 0, 0, 0); |
sstabellini@21863 | 3314 if (rc < 0) { |
sstabellini@21863 | 3315 XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, |
sstabellini@21863 | 3316 "Can not get tmem freeable memory"); |