debuggers.hg

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

tools: Make build again on netbsd

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