debuggers.hg

view tools/libxl/libxl.c @ 20467:494ad84ad38c

libxl: Call to open() must specify mode with O_CREAT.

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