debuggers.hg
changeset 20462:8a91056bea81
libxenlight: initial libxenlight implementation under tools/libxl
Signed-off-by: Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Nov 09 19:54:28 2009 +0000 (2009-11-09) |
parents | 9479190566fd |
children | 9b393d47b22a |
files | tools/Makefile tools/libxl/Makefile tools/libxl/flexarray.c tools/libxl/flexarray.h tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_device.c tools/libxl/libxl_dom.c tools/libxl/libxl_exec.c tools/libxl/libxl_internal.c tools/libxl/libxl_internal.h tools/libxl/libxl_utils.c tools/libxl/libxl_utils.h tools/libxl/libxl_xshelp.c tools/libxl/osdeps.c tools/libxl/osdeps.h tools/libxl/xenguest.c tools/libxl/xl.c |
line diff
1.1 --- a/tools/Makefile Mon Nov 09 19:45:06 2009 +0000 1.2 +++ b/tools/Makefile Mon Nov 09 19:54:28 2009 +0000 1.3 @@ -32,6 +32,7 @@ SUBDIRS-$(CONFIG_Linux) += fs-back 1.4 SUBDIRS-$(CONFIG_NetBSD) += fs-back 1.5 SUBDIRS-$(CONFIG_IOEMU) += ioemu-dir 1.6 SUBDIRS-y += xenpmd 1.7 +SUBDIRS-y += libxl 1.8 1.9 # These don't cross-compile 1.10 ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tools/libxl/Makefile Mon Nov 09 19:54:28 2009 +0000 2.3 @@ -0,0 +1,72 @@ 2.4 +# 2.5 +# tools/libxl/Makefile 2.6 +# 2.7 + 2.8 +XEN_ROOT = ../.. 2.9 +include $(XEN_ROOT)/tools/Rules.mk 2.10 + 2.11 +MAJOR = 1.0 2.12 +MINOR = 0 2.13 + 2.14 +#CFLAGS += -Werror 2.15 +CFLAGS += -I. -fPIC 2.16 +CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) 2.17 + 2.18 +LDFLAGS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore) -luuid 2.19 + 2.20 +LIBCONFIG_URL ?= http://www.hyperrealm.com/libconfig 2.21 +LIBCONFIG_SOURCE = libconfig-1.3.2 2.22 +LIBCONFIG_OUTPUT = $(LIBCONFIG_SOURCE)/.libs 2.23 +WGET=wget -c 2.24 + 2.25 +LIBXL_OBJS = flexarray.o libxl.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o xenguest.o osdeps.o libxl_utils.o 2.26 + 2.27 +CLIENTS = xl 2.28 + 2.29 +.PHONY: all 2.30 +all: $(CLIENTS) libxenlight.so libxenlight.a 2.31 + 2.32 +libxenlight.so: libxenlight.so.$(MAJOR) 2.33 + ln -sf $< $@ 2.34 + 2.35 +libxenlight.so.$(MAJOR): libxenlight.so.$(MAJOR).$(MINOR) 2.36 + ln -sf $< $@ 2.37 + 2.38 +libxenlight.so.$(MAJOR).$(MINOR): $(LIBXL_OBJS) 2.39 + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ 2.40 + 2.41 +libxenlight.a: $(LIBXL_OBJS) 2.42 + $(AR) rcs libxenlight.a $^ 2.43 + 2.44 +$(LIBCONFIG_SOURCE).tar.gz: 2.45 + $(WGET) $(LIBCONFIG_URL)/$@ 2.46 + 2.47 +$(LIBCONFIG_SOURCE): $(LIBCONFIG_SOURCE).tar.gz 2.48 + tar xzf $< 2.49 + 2.50 +$(LIBCONFIG_OUTPUT)/libconfig.so: $(LIBCONFIG_SOURCE) 2.51 + cd $(LIBCONFIG_SOURCE) && ./configure --prefix=$(DESTDIR)$(PREFIX) && $(MAKE) 2.52 + 2.53 +xl.o: $(LIBCONFIG_SOURCE) 2.54 + $(CC) $(CFLAGS) -I$(LIBCONFIG_SOURCE) -c xl.c 2.55 + 2.56 +$(CLIENTS): xl.o libxenlight.so $(LIBCONFIG_OUTPUT)/libconfig.so 2.57 + $(CC) $(LDFLAGS) -o $@ $< -L . -lxenlight -L$(LIBCONFIG_OUTPUT) -lconfig 2.58 + 2.59 +.PHONY: install 2.60 +install: all 2.61 + $(INSTALL_PROG) xl $(DESTDIR)$(SBINDIR) 2.62 + $(INSTALL_PROG) libxenlight.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) 2.63 + ln -sf libxenlight.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenlight.so.$(MAJOR) 2.64 + ln -sf libxenlight.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenlight.so 2.65 + $(INSTALL_DATA) libxenlight.a $(DESTDIR)$(LIBDIR) 2.66 + cd $(LIBCONFIG_SOURCE) && DESTDIR= $(MAKE) install 2.67 + 2.68 +.PHONY: clean 2.69 +clean: 2.70 + $(RM) -f *.o *.so* *.a $(CLIENTS) 2.71 + $(RM) -rf $(LIBCONFIG_SOURCE) 2.72 + 2.73 +distclean: clean 2.74 + $(RM) -f $(LIBCONFIG_SOURCE).tar.gz 2.75 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/libxl/flexarray.c Mon Nov 09 19:54:28 2009 +0000 3.3 @@ -0,0 +1,78 @@ 3.4 +/* 3.5 + * Copyright (C) 2009 Citrix Ltd. 3.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 3.7 + * 3.8 + * This program is free software; you can redistribute it and/or modify 3.9 + * it under the terms of the GNU Lesser General Public License as published 3.10 + * by the Free Software Foundation; version 2.1 only. with the special 3.11 + * exception on linking described in file LICENSE. 3.12 + * 3.13 + * This program is distributed in the hope that it will be useful, 3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.16 + * GNU Lesser General Public License for more details. 3.17 + */ 3.18 + 3.19 +#include <stdlib.h> 3.20 +#include "flexarray.h" 3.21 + 3.22 +flexarray_t *flexarray_make(int size, int autogrow) 3.23 +{ 3.24 + flexarray_t *array = malloc(sizeof(struct flexarray)); 3.25 + if (array) { 3.26 + array->size = size; 3.27 + array->autogrow = autogrow; 3.28 + array->data = calloc(size, sizeof(void *)); 3.29 + } 3.30 + return array; 3.31 +} 3.32 + 3.33 +void flexarray_free(flexarray_t *array) 3.34 +{ 3.35 + free(array->data); 3.36 + free(array); 3.37 +} 3.38 + 3.39 +int flexarray_grow(flexarray_t *array, int extents) 3.40 +{ 3.41 + void **data; 3.42 + int newsize; 3.43 + 3.44 + newsize = array->size + extents; 3.45 + data = realloc(array->data, sizeof(void *) * newsize); 3.46 + if (!data) 3.47 + return 1; 3.48 + array->size += extents; 3.49 + array->data = data; 3.50 + return 0; 3.51 +} 3.52 + 3.53 +int flexarray_set(flexarray_t *array, unsigned int index, void *ptr) 3.54 +{ 3.55 + if (index >= array->size) { 3.56 + int newsize; 3.57 + if (!array->autogrow) 3.58 + return 1; 3.59 + newsize = (array->size * 2 < index) ? index + 1 : array->size * 2; 3.60 + if (flexarray_grow(array, newsize - array->size)) 3.61 + return 2; 3.62 + } 3.63 + array->data[index] = ptr; 3.64 + return 0; 3.65 +} 3.66 + 3.67 +int flexarray_get(flexarray_t *array, int index, void **ptr) 3.68 +{ 3.69 + if (index >= array->size) 3.70 + return 1; 3.71 + *ptr = array->data[index]; 3.72 + return 0; 3.73 +} 3.74 + 3.75 +void **flexarray_contents(flexarray_t *array) 3.76 +{ 3.77 + void **data; 3.78 + data = array->data; 3.79 + free(array); 3.80 + return data; 3.81 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/tools/libxl/flexarray.h Mon Nov 09 19:54:28 2009 +0000 4.3 @@ -0,0 +1,33 @@ 4.4 +/* 4.5 + * Copyright (C) 2009 Citrix Ltd. 4.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 4.7 + * 4.8 + * This program is free software; you can redistribute it and/or modify 4.9 + * it under the terms of the GNU Lesser General Public License as published 4.10 + * by the Free Software Foundation; version 2.1 only. with the special 4.11 + * exception on linking described in file LICENSE. 4.12 + * 4.13 + * This program is distributed in the hope that it will be useful, 4.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 4.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 4.16 + * GNU Lesser General Public License for more details. 4.17 + */ 4.18 + 4.19 +#ifndef FLEXARRAY_H 4.20 +#define FLEXARRAY_H 4.21 + 4.22 +typedef struct flexarray { 4.23 + int size; 4.24 + int autogrow; 4.25 + void **data; /* array of pointer */ 4.26 +} flexarray_t; 4.27 + 4.28 +flexarray_t *flexarray_make(int size, int autogrow); 4.29 +void flexarray_free(flexarray_t *array); 4.30 +int flexarray_grow(flexarray_t *array, int extents); 4.31 +int flexarray_set(flexarray_t *array, unsigned int index, void *ptr); 4.32 +int flexarray_get(flexarray_t *array, int index, void **ptr); 4.33 + 4.34 +void **flexarray_contents(flexarray_t *array); 4.35 + 4.36 +#endif
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/tools/libxl/libxl.c Mon Nov 09 19:54:28 2009 +0000 5.3 @@ -0,0 +1,742 @@ 5.4 +/* 5.5 + * Copyright (C) 2009 Citrix Ltd. 5.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 5.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 5.8 + * 5.9 + * This program is free software; you can redistribute it and/or modify 5.10 + * it under the terms of the GNU Lesser General Public License as published 5.11 + * by the Free Software Foundation; version 2.1 only. with the special 5.12 + * exception on linking described in file LICENSE. 5.13 + * 5.14 + * This program is distributed in the hope that it will be useful, 5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5.17 + * GNU Lesser General Public License for more details. 5.18 + */ 5.19 + 5.20 +#include <stdio.h> 5.21 +#include <string.h> 5.22 +#include <stdlib.h> 5.23 +#include <sys/stat.h> 5.24 +#include <sys/types.h> 5.25 +#include <fcntl.h> 5.26 +#include <sys/select.h> 5.27 +#include <signal.h> 5.28 +#include "libxl.h" 5.29 +#include "libxl_utils.h" 5.30 +#include "libxl_internal.h" 5.31 +#include "flexarray.h" 5.32 + 5.33 +int libxl_ctx_init(struct libxl_ctx *ctx) 5.34 +{ 5.35 + memset(ctx, 0, sizeof(struct libxl_ctx)); 5.36 + ctx->alloc_maxsize = 256; 5.37 + ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); 5.38 + if (!ctx->alloc_ptrs) 5.39 + return ERROR_NOMEM; 5.40 + 5.41 + ctx->xch = xc_interface_open(); 5.42 + ctx->xsh = xs_daemon_open(); 5.43 + return 0; 5.44 +} 5.45 + 5.46 +int libxl_ctx_free(struct libxl_ctx *ctx) 5.47 +{ 5.48 + libxl_free_all(ctx); 5.49 + free(ctx->alloc_ptrs); 5.50 + ctx->alloc_ptrs = NULL; 5.51 + xc_interface_close(ctx->xch); 5.52 + xs_daemon_close(ctx->xsh); 5.53 + return 0; 5.54 +} 5.55 + 5.56 +int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data) 5.57 +{ 5.58 + ctx->log_callback = log_callback; 5.59 + ctx->log_userdata = log_data; 5.60 + return 0; 5.61 +} 5.62 + 5.63 +/******************************************************************************/ 5.64 + 5.65 +int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, 5.66 + uint32_t *domid) 5.67 +{ 5.68 + int flags, ret, i; 5.69 + char *uuid_string; 5.70 + char *rw_paths[] = { "device" }; 5.71 + char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", 5.72 + "control", "attr", "data", "messages" }; 5.73 + char *dom_path, *vm_path, *vss_path; 5.74 + struct xs_permissions roperm[2]; 5.75 + struct xs_permissions rwperm[1]; 5.76 + xs_transaction_t t; 5.77 + 5.78 + uuid_string = uuid_to_string(ctx, info->uuid); 5.79 + if (!uuid_string) { 5.80 + XL_LOG(ctx, XL_LOG_ERROR, "missing uuid"); 5.81 + return ERROR_FAIL; 5.82 + } 5.83 + 5.84 + flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; 5.85 + flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; 5.86 + *domid = 0; 5.87 + 5.88 + ret = xc_domain_create(ctx->xch, info->ssidref, info->uuid, flags, domid); 5.89 + if (ret < 0) { 5.90 + XL_LOG(ctx, XL_LOG_ERROR, "domain creation fail: %d", ret); 5.91 + return ERROR_FAIL; 5.92 + } 5.93 + 5.94 + dom_path = libxl_xs_get_dompath(ctx, *domid); 5.95 + vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); 5.96 + vss_path = libxl_sprintf(ctx, "/vss/%s", uuid_string); 5.97 + if (!dom_path || !vm_path || !vss_path) { 5.98 + XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths"); 5.99 + return ERROR_FAIL; 5.100 + } 5.101 + 5.102 + roperm[0].id = 0; 5.103 + roperm[0].perms = XS_PERM_NONE; 5.104 + roperm[1].id = *domid; 5.105 + roperm[1].perms = XS_PERM_READ; 5.106 + rwperm[0].id = *domid; 5.107 + rwperm[0].perms = XS_PERM_NONE; 5.108 + 5.109 +retry_transaction: 5.110 + t = xs_transaction_start(ctx->xsh); 5.111 + xs_rm(ctx->xsh, t, dom_path); 5.112 + xs_mkdir(ctx->xsh, t, dom_path); 5.113 + xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); 5.114 + 5.115 + xs_rm(ctx->xsh, t, vm_path); 5.116 + xs_mkdir(ctx->xsh, t, vm_path); 5.117 + xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); 5.118 + 5.119 + xs_rm(ctx->xsh, t, vss_path); 5.120 + xs_mkdir(ctx->xsh, t, vss_path); 5.121 + xs_set_permissions(ctx->xsh, t, vss_path, rwperm, ARRAY_SIZE(rwperm)); 5.122 + 5.123 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); 5.124 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, strlen(vss_path)); 5.125 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, strlen(info->name)); 5.126 + 5.127 + for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { 5.128 + char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]); 5.129 + xs_mkdir(ctx->xsh, t, path); 5.130 + xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); 5.131 + libxl_free(ctx, path); 5.132 + } 5.133 + for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { 5.134 + char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]); 5.135 + xs_mkdir(ctx->xsh, t, path); 5.136 + xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); 5.137 + libxl_free(ctx, path); 5.138 + } 5.139 + 5.140 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); 5.141 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name)); 5.142 + 5.143 + libxl_xs_writev(ctx, t, dom_path, info->xsdata); 5.144 + libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata); 5.145 + 5.146 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); 5.147 + 5.148 + if (!xs_transaction_end(ctx->xsh, t, 0)) 5.149 + if (errno == EAGAIN) 5.150 + goto retry_transaction; 5.151 + return 0; 5.152 +} 5.153 + 5.154 +int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid) 5.155 +{ 5.156 + libxl_domain_build_state state; 5.157 + char **vments = NULL, **localents = NULL; 5.158 + 5.159 + memset(&state, '\0', sizeof(state)); 5.160 + 5.161 + build_pre(ctx, domid, info, &state); 5.162 + if (info->hvm) { 5.163 + build_hvm(ctx, domid, info, &state); 5.164 + vments = libxl_calloc(ctx, 4, sizeof(char *)); 5.165 + vments[0] = libxl_sprintf(ctx, "rtc/timeoffset"); 5.166 + vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""); 5.167 + } else { 5.168 + build_pv(ctx, domid, info, &state); 5.169 + } 5.170 + build_post(ctx, domid, info, &state, vments, localents); 5.171 + return 0; 5.172 +} 5.173 + 5.174 +int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info, 5.175 + uint32_t domid, int fd) 5.176 +{ 5.177 + libxl_domain_build_state state; 5.178 + char **vments = NULL, **localents = NULL; 5.179 + 5.180 + memset(&state, '\0', sizeof(state)); 5.181 + 5.182 + build_pre(ctx, domid, info, &state); 5.183 + restore_common(ctx, domid, info, &state, fd); 5.184 + if (info->hvm) { 5.185 + vments = libxl_calloc(ctx, 4, sizeof(char *)); 5.186 + vments[0] = libxl_sprintf(ctx, "rtc/timeoffset"); 5.187 + vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""); 5.188 + } else { 5.189 + localents = libxl_calloc(ctx, 4 * 2, sizeof(char *)); 5.190 + localents[0] = libxl_sprintf(ctx, "serial/0/limit"); 5.191 + localents[1] = libxl_sprintf(ctx, "%d", 65536); 5.192 + localents[2] = libxl_sprintf(ctx, "console/port"); 5.193 + localents[3] = libxl_sprintf(ctx, "%d", state.console_port); 5.194 + localents[4] = libxl_sprintf(ctx, "console/ring-ref"); 5.195 + localents[5] = libxl_sprintf(ctx, "%ld", state.console_mfn); 5.196 + } 5.197 + build_post(ctx, domid, info, &state, vments, localents); 5.198 + return 0; 5.199 +} 5.200 + 5.201 +struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain) 5.202 +{ 5.203 + struct libxl_dominfo *ptr; 5.204 + int index, i, ret, first_domain; 5.205 + xc_domaininfo_t info[16]; 5.206 + int size = 16; 5.207 + 5.208 + first_domain = 1; 5.209 + index = 0; 5.210 + ptr = libxl_calloc(ctx, size, sizeof(struct libxl_dominfo)); 5.211 + if (!ptr) 5.212 + return NULL; 5.213 +redo: 5.214 + ret = xc_domain_getinfolist(ctx->xch, first_domain, 16, info); 5.215 + for (i = 0; i < ret; i++) { 5.216 + if (index == size) { 5.217 + struct libxl_dominfo *ptr2; 5.218 + 5.219 + ptr2 = libxl_calloc(ctx, size * 2, sizeof(struct libxl_dominfo)); 5.220 + if (!ptr2) { 5.221 + libxl_free(ctx, ptr); 5.222 + return NULL; 5.223 + } 5.224 + memcpy(ptr2, ptr, sizeof(struct libxl_dominfo) * size); 5.225 + libxl_free(ctx, ptr); 5.226 + ptr = ptr2; 5.227 + size *= 2; 5.228 + } 5.229 + memcpy(ptr[index].uuid, info[i].handle, 16 * sizeof(uint8_t)); 5.230 + ptr[index].domid = info[i].domain; 5.231 + first_domain = info[i].domain + 1; 5.232 + index++; 5.233 + } 5.234 + if (ret == 16) 5.235 + goto redo; 5.236 + *nb_domain = index; 5.237 + return ptr; 5.238 +} 5.239 + 5.240 +xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain) 5.241 +{ 5.242 + int index, first_domain; 5.243 + xc_dominfo_t *info; 5.244 + int size = 1024; 5.245 + 5.246 + first_domain = 0; 5.247 + index = 0; 5.248 + info = (xc_dominfo_t *) libxl_calloc(ctx, size, sizeof(xc_dominfo_t)); 5.249 + if (!info) { 5.250 + *nb_domain = 0; 5.251 + return NULL; 5.252 + } 5.253 + *nb_domain = xc_domain_getinfo(ctx->xch, first_domain, 1024, info); 5.254 + return info; 5.255 +} 5.256 + 5.257 +int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info, 5.258 + uint32_t domid, int fd) 5.259 +{ 5.260 + int hvm = 1; 5.261 + int live = 0; 5.262 + int debug = 0; 5.263 + char savesig[] = "XenSavedDomain\n"; 5.264 + 5.265 + write(fd, savesig, strlen(savesig)); 5.266 + 5.267 + core_suspend(ctx, domid, fd, hvm, live, debug); 5.268 + 5.269 + return 0; 5.270 +} 5.271 + 5.272 +int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid) 5.273 +{ 5.274 + xc_domain_pause(ctx->xch, domid); 5.275 + return 0; 5.276 +} 5.277 + 5.278 +int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid) 5.279 +{ 5.280 + xc_domain_unpause(ctx->xch, domid); 5.281 + return 0; 5.282 +} 5.283 + 5.284 +static char *req_table[] = { 5.285 + [0] = "poweroff", 5.286 + [1] = "reboot", 5.287 + [2] = "suspend", 5.288 + [3] = "crash", 5.289 + [4] = "halt", 5.290 +}; 5.291 + 5.292 +int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req) 5.293 +{ 5.294 + char *shutdown_path; 5.295 + char *dom_path; 5.296 + 5.297 + if (req > ARRAY_SIZE(req_table)) 5.298 + return ERROR_INVAL; 5.299 + 5.300 + dom_path = libxl_xs_get_dompath(ctx, domid); 5.301 + shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path); 5.302 + 5.303 + xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req])); 5.304 + if (/* hvm */ 0) { 5.305 + unsigned long acpi_s_state = 0; 5.306 + unsigned long pvdriver = 0; 5.307 + xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state); 5.308 + xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver); 5.309 + if (!pvdriver && acpi_s_state != 0) 5.310 + xc_domain_shutdown(ctx->xch, domid, req); 5.311 + } 5.312 + return 0; 5.313 +} 5.314 + 5.315 +static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid) 5.316 +{ 5.317 + char *pid; 5.318 + int ret; 5.319 + 5.320 + pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); 5.321 + if (!pid) { 5.322 + XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find device model's pid\n"); 5.323 + return -1; 5.324 + } 5.325 + xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid)); 5.326 + 5.327 + ret = kill(atoi(pid), SIGHUP); 5.328 + if (ret < 0 && errno == ESRCH) { 5.329 + XL_LOG(ctx, XL_LOG_DEBUG, "Device Model already exited\n"); 5.330 + ret = 0; 5.331 + } else if (ret == 0) { 5.332 + XL_LOG(ctx, XL_LOG_DEBUG, "Device Model signaled\n"); 5.333 + ret = 0; 5.334 + } else { 5.335 + XL_LOG(ctx, XL_LOG_ERROR, "kill %d returned %d errno=%d\n", atoi(pid), ret, errno); 5.336 + } 5.337 + return ret; 5.338 +} 5.339 + 5.340 +int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force) 5.341 +{ 5.342 + char *dom_path, vm_path[41]; 5.343 + uint8_t *uuid; 5.344 + 5.345 + dom_path = libxl_xs_get_dompath(ctx, domid); 5.346 + if (!dom_path) { 5.347 + XL_LOG(ctx, XL_LOG_ERROR, "dompath doesn't exist for %d\n", domid); 5.348 + return -1; 5.349 + } 5.350 + if (libxl_domid_to_uuid(ctx, &uuid, domid) < 0) { 5.351 + XL_LOG(ctx, XL_LOG_ERROR, "failed ot get uuid for %d\n", domid); 5.352 + return -1; 5.353 + } 5.354 + xs_write(ctx->xsh, XBT_NULL, 5.355 + libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), 5.356 + "shutdown", strlen("shutdown")); 5.357 + if (xc_domain_pause(ctx->xch, domid) < 0) { 5.358 + XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_pause failed for %d\n", domid); 5.359 + return -1; 5.360 + } 5.361 + /* do_FLR */ 5.362 + if (xc_domain_destroy(ctx->xch, domid) < 0) { 5.363 + XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_destroy failed for %d\n", domid); 5.364 + return -1; 5.365 + } 5.366 + if (libxl_devices_destroy(ctx, domid, force) < 0) 5.367 + XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d\n", domid); 5.368 + if (libxl_destroy_device_model(ctx, domid) < 0) 5.369 + XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d\n", domid); 5.370 + if (!xs_rm(ctx->xsh, XBT_NULL, dom_path)) 5.371 + XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", dom_path); 5.372 + snprintf(vm_path, sizeof(vm_path), "/vm/%s", uuid_to_string(ctx, uuid)); 5.373 + if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) 5.374 + XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", vm_path); 5.375 + return 0; 5.376 +} 5.377 + 5.378 +static char ** libxl_build_device_model_args(struct libxl_ctx *ctx, 5.379 + libxl_device_model_info *info, 5.380 + libxl_device_nic *vifs, 5.381 + int num_vifs) 5.382 +{ 5.383 + int num = 0, i; 5.384 + flexarray_t *dm_args; 5.385 + dm_args = flexarray_make(16, 1); 5.386 + if (!dm_args) 5.387 + return NULL; 5.388 + 5.389 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "qemu-dm")); 5.390 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-d")); 5.391 + 5.392 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); 5.393 + 5.394 + if (info->dom_name) { 5.395 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-domain-name")); 5.396 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->dom_name)); 5.397 + } 5.398 + if (info->videoram) { 5.399 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram")); 5.400 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); 5.401 + } 5.402 + if (info->stdvga) { 5.403 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga")); 5.404 + } 5.405 + if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { 5.406 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vnc")); 5.407 + if (info->vncdisplay) { 5.408 + if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { 5.409 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:%d", info->vnclisten, info->vncdisplay)); 5.410 + } else { 5.411 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay)); 5.412 + } 5.413 + } else if (info->vnclisten) { 5.414 + if (strchr(info->vnclisten, ':') != NULL) { 5.415 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->vnclisten)); 5.416 + } else { 5.417 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten)); 5.418 + } 5.419 + } else { 5.420 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:0")); 5.421 + } 5.422 + if (info->vncunused) { 5.423 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vncunused")); 5.424 + } 5.425 + } 5.426 + if (info->sdl || info->opengl) { 5.427 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-sdl")); 5.428 + if (info->opengl) { 5.429 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-disable-opengl")); 5.430 + } 5.431 + } 5.432 + if (info->keymap) { 5.433 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-k")); 5.434 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->keymap)); 5.435 + } 5.436 + if (info->nographic && (!info->sdl && !info->vnc)) { 5.437 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-nographic")); 5.438 + } 5.439 + if (info->serial) { 5.440 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-serial")); 5.441 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->serial)); 5.442 + } 5.443 + if (info->boot) { 5.444 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot")); 5.445 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot)); 5.446 + } 5.447 + if (info->usb) { 5.448 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb")); 5.449 + if (info->usbdevice) { 5.450 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice")); 5.451 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->usbdevice)); 5.452 + } 5.453 + } 5.454 + if (info->apic) { 5.455 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi")); 5.456 + } 5.457 + if (info->extra) { 5.458 + int i = 0; 5.459 + while (info->extra[i] != NULL) { 5.460 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->extra[i])); 5.461 + } 5.462 + } 5.463 + for (i = 0; i < num_vifs; i++) { 5.464 + if (vifs[i].nictype == NICTYPE_IOEMU) { 5.465 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); 5.466 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", 5.467 + vifs[i].devid, vifs[i].smac, vifs[i].model)); 5.468 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net")); 5.469 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s", 5.470 + vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); 5.471 + } 5.472 + } 5.473 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-M")); 5.474 + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv")); 5.475 + flexarray_set(dm_args, num++, NULL); 5.476 + 5.477 + return (char **) flexarray_contents(dm_args); 5.478 +} 5.479 + 5.480 +int libxl_create_device_model(struct libxl_ctx *ctx, 5.481 + libxl_device_model_info *info, 5.482 + libxl_device_nic *vifs, int num_vifs) 5.483 +{ 5.484 + char *dom_path, *path, *logfile, *logfile_new; 5.485 + char *kvs[3]; 5.486 + struct stat stat_buf; 5.487 + int logfile_w, null, pid; 5.488 + int i; 5.489 + char **args; 5.490 + 5.491 + args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); 5.492 + if (!args) 5.493 + return ERROR_FAIL; 5.494 + 5.495 + dom_path = libxl_xs_get_dompath(ctx, info->domid); 5.496 + 5.497 + path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid); 5.498 + xs_mkdir(ctx->xsh, XBT_NULL, path); 5.499 + 5.500 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name); 5.501 + if (stat(logfile, &stat_buf) == 0) { 5.502 + /* file exists, rotate */ 5.503 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.10", info->dom_name); 5.504 + unlink(logfile); 5.505 + for (i = 9; i > 0; i--) { 5.506 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i); 5.507 + logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i + 1); 5.508 + rename(logfile, logfile_new); 5.509 + } 5.510 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name); 5.511 + logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.1", info->dom_name); 5.512 + rename(logfile, logfile_new); 5.513 + } 5.514 + logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name); 5.515 + logfile_w = open(logfile, O_WRONLY|O_CREAT); 5.516 + null = open("/dev/null", O_RDONLY); 5.517 + pid = libxl_exec(ctx, null, logfile_w, logfile_w, info->device_model, args); 5.518 + close(null); 5.519 + close(logfile_w); 5.520 + 5.521 + kvs[0] = libxl_sprintf(ctx, "image/device-model-pid"); 5.522 + kvs[1] = libxl_sprintf(ctx, "%d", pid); 5.523 + kvs[2] = NULL; 5.524 + libxl_xs_writev(ctx, XBT_NULL, dom_path, kvs); 5.525 + 5.526 + return 0; 5.527 +} 5.528 + 5.529 +/******************************************************************************/ 5.530 +int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) 5.531 +{ 5.532 + flexarray_t *front; 5.533 + flexarray_t *back; 5.534 + char *backend_type; 5.535 + unsigned int boffset = 0; 5.536 + unsigned int foffset = 0; 5.537 + int devid; 5.538 + libxl_device device; 5.539 + 5.540 + front = flexarray_make(16, 1); 5.541 + if (!front) 5.542 + return ERROR_NOMEM; 5.543 + back = flexarray_make(16, 1); 5.544 + if (!back) /* leaks front if error */ 5.545 + return ERROR_NOMEM; 5.546 + 5.547 + backend_type = device_disk_backend_type_of_phystype(disk->phystype); 5.548 + devid = device_disk_dev_number(disk->virtpath); 5.549 + 5.550 + device.backend_devid = devid; 5.551 + device.backend_domid = disk->backend_domid; 5.552 + device.devid = devid; 5.553 + device.domid = disk->domid; 5.554 + device.kind = DEVICE_VBD; 5.555 + 5.556 + switch (disk->phystype) { 5.557 + case PHYSTYPE_FILE: 5.558 + return ERROR_NI; /* FIXME */ 5.559 + break; 5.560 + case PHYSTYPE_PHY: { 5.561 + int major, minor; 5.562 + 5.563 + device_disk_major_minor(disk->virtpath, &major, &minor); 5.564 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "physical-device")); 5.565 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); 5.566 + 5.567 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "params")); 5.568 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->physpath)); 5.569 + 5.570 + device.backend_kind = DEVICE_VBD; 5.571 + break; 5.572 + } 5.573 + case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case PHYSTYPE_VHD: 5.574 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "params")); 5.575 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", 5.576 + device_disk_string_of_phystype(disk->phystype), disk->physpath)); 5.577 + 5.578 + device.backend_kind = DEVICE_TAP; 5.579 + break; 5.580 + } 5.581 + 5.582 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); 5.583 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid)); 5.584 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); 5.585 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); 5.586 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "removable")); 5.587 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0)); 5.588 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); 5.589 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); 5.590 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev")); 5.591 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->virtpath)); 5.592 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "type")); 5.593 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", backend_type)); 5.594 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "mode")); 5.595 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", (disk->readwrite) ? "w" : "r")); 5.596 + 5.597 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); 5.598 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid)); 5.599 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); 5.600 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); 5.601 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "virtual-device")); 5.602 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid)); 5.603 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "device-type")); 5.604 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%s", (disk->is_cdrom) ? "cdrom" : "disk")); 5.605 + 5.606 + if (0 /* protocol != native*/) { 5.607 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol")); 5.608 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */ 5.609 + } 5.610 + 5.611 + libxl_device_generic_add(ctx, &device, 5.612 + libxl_xs_kvs_of_flexarray(ctx, back, boffset), 5.613 + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); 5.614 + /* leaks both flexarray here */ 5.615 + return 0; 5.616 +} 5.617 + 5.618 +int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.619 +{ 5.620 + return ERROR_NI; 5.621 +} 5.622 + 5.623 +int libxl_device_disk_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.624 +{ 5.625 + return ERROR_NI; 5.626 +} 5.627 + 5.628 +/******************************************************************************/ 5.629 +int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) 5.630 +{ 5.631 + flexarray_t *front; 5.632 + flexarray_t *back; 5.633 + unsigned int boffset = 0; 5.634 + unsigned int foffset = 0; 5.635 + libxl_device device; 5.636 + 5.637 + front = flexarray_make(16, 1); 5.638 + if (!front) 5.639 + return ERROR_NOMEM; 5.640 + back = flexarray_make(16, 1); 5.641 + if (!back) 5.642 + return ERROR_NOMEM; 5.643 + 5.644 + device.backend_devid = nic->devid; 5.645 + device.backend_domid = nic->backend_domid; 5.646 + device.backend_kind = DEVICE_VIF; 5.647 + device.devid = nic->devid; 5.648 + device.domid = nic->domid; 5.649 + device.kind = DEVICE_VIF; 5.650 + 5.651 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id")); 5.652 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid)); 5.653 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "online")); 5.654 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "1")); 5.655 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "state")); 5.656 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); 5.657 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "script")); 5.658 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", nic->script)); 5.659 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "mac")); 5.660 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", 5.661 + nic->mac[0], nic->mac[1], nic->mac[2], 5.662 + nic->mac[3], nic->mac[4], nic->mac[5])); 5.663 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "handle")); 5.664 + flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid)); 5.665 + 5.666 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id")); 5.667 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid)); 5.668 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "state")); 5.669 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); 5.670 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "handle")); 5.671 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid)); 5.672 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "mac")); 5.673 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", 5.674 + nic->mac[0], nic->mac[1], nic->mac[2], 5.675 + nic->mac[3], nic->mac[4], nic->mac[5])); 5.676 + if (0 /* protocol != native*/) { 5.677 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol")); 5.678 + flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */ 5.679 + } 5.680 + 5.681 + libxl_device_generic_add(ctx, &device, 5.682 + libxl_xs_kvs_of_flexarray(ctx, back, boffset), 5.683 + libxl_xs_kvs_of_flexarray(ctx, front, foffset)); 5.684 + 5.685 + /* FIXME: wait for plug */ 5.686 + return 0; 5.687 +} 5.688 + 5.689 +int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.690 +{ 5.691 + return ERROR_NI; 5.692 +} 5.693 + 5.694 +int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.695 +{ 5.696 + return ERROR_NI; 5.697 +} 5.698 + 5.699 +/******************************************************************************/ 5.700 +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid) 5.701 +{ 5.702 + return ERROR_NI; 5.703 +} 5.704 + 5.705 +int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.706 +{ 5.707 + return ERROR_NI; 5.708 +} 5.709 + 5.710 +int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.711 +{ 5.712 + return ERROR_NI; 5.713 +} 5.714 + 5.715 +/******************************************************************************/ 5.716 +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid) 5.717 +{ 5.718 + return ERROR_NI; 5.719 +} 5.720 + 5.721 +int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.722 +{ 5.723 + return ERROR_NI; 5.724 +} 5.725 + 5.726 +int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.727 +{ 5.728 + return ERROR_NI; 5.729 +} 5.730 + 5.731 +/******************************************************************************/ 5.732 +int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid) 5.733 +{ 5.734 + return ERROR_NI; 5.735 +} 5.736 + 5.737 +int libxl_device_pci_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.738 +{ 5.739 + return ERROR_NI; 5.740 +} 5.741 + 5.742 +int libxl_device_pci_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid) 5.743 +{ 5.744 + return ERROR_NI; 5.745 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/tools/libxl/libxl.h Mon Nov 09 19:54:28 2009 +0000 6.3 @@ -0,0 +1,200 @@ 6.4 +/* 6.5 + * Copyright (C) 2009 Citrix Ltd. 6.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 6.7 + * 6.8 + * This program is free software; you can redistribute it and/or modify 6.9 + * it under the terms of the GNU Lesser General Public License as published 6.10 + * by the Free Software Foundation; version 2.1 only. with the special 6.11 + * exception on linking described in file LICENSE. 6.12 + * 6.13 + * This program is distributed in the hope that it will be useful, 6.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 6.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 6.16 + * GNU Lesser General Public License for more details. 6.17 + */ 6.18 +#ifndef LIBXL_H 6.19 +#define LIBXL_H 6.20 + 6.21 +#include "osdeps.h" 6.22 +#include <stdint.h> 6.23 +#include <stdarg.h> 6.24 +#include <netinet/in.h> 6.25 +#include <xenctrl.h> 6.26 + 6.27 +typedef int bool; 6.28 + 6.29 +typedef void (*libxl_log_callback)(void *userdata, int loglevel, const char *file, 6.30 + int line, const char *func, char *s); 6.31 + 6.32 +struct libxl_dominfo { 6.33 + uint8_t uuid[16]; 6.34 + uint32_t domid; 6.35 +}; 6.36 + 6.37 +struct libxl_ctx { 6.38 + int xch; 6.39 + struct xs_handle *xsh; 6.40 + /* errors/debug buf */ 6.41 + void *log_userdata; 6.42 + libxl_log_callback log_callback; 6.43 + 6.44 + /* mini-GC */ 6.45 + int alloc_maxsize; 6.46 + void **alloc_ptrs; 6.47 +}; 6.48 + 6.49 +typedef struct { 6.50 + bool hvm; 6.51 + bool hap; 6.52 + int ssidref; 6.53 + char *name; 6.54 + uint8_t *uuid; 6.55 + char **xsdata; 6.56 + char **platformdata; 6.57 +} libxl_domain_create_info; 6.58 + 6.59 +typedef struct { 6.60 + int timer_mode; 6.61 + int hpet; 6.62 + int vpt_align; 6.63 + int max_vcpus; 6.64 + uint32_t max_memkb; 6.65 + uint32_t video_memkb; 6.66 + uint32_t shadow_memkb; 6.67 + const char *kernel; 6.68 + int hvm; 6.69 + union { 6.70 + struct { 6.71 + bool pae; 6.72 + bool apic; 6.73 + bool acpi; 6.74 + bool nx; 6.75 + bool viridian; 6.76 + char *timeoffset; 6.77 + } hvm; 6.78 + struct { 6.79 + const char *cmdline; 6.80 + const char *ramdisk; 6.81 + } pv; 6.82 + } u; 6.83 +} libxl_domain_build_info; 6.84 + 6.85 +typedef struct { 6.86 + int flags; 6.87 + int (*suspend_callback)(void *, int); 6.88 +} libxl_domain_suspend_info; 6.89 + 6.90 +typedef struct { 6.91 + int domid; 6.92 + char *dom_name; 6.93 + char *device_model; 6.94 + int videoram; /* size of the videoram in MB */ 6.95 + bool stdvga; /* stdvga enabled or disabled */ 6.96 + bool vnc; /* vnc enabled or disabled */ 6.97 + char *vnclisten; /* address:port that should be listened on for the VNC server if vnc is set */ 6.98 + int vncdisplay; /* set VNC display number */ 6.99 + bool vncunused; /* try to find an unused port for the VNC server */ 6.100 + char *keymap; /* set keyboard layout, default is en-us keyboard */ 6.101 + bool sdl; /* sdl enabled or disabled */ 6.102 + bool opengl; /* opengl enabled or disabled (if enabled requires sdl enabled) */ 6.103 + bool nographic; /* no graphics, use serial port */ 6.104 + char *serial; /* serial port re-direct to pty deivce */ 6.105 + char *boot; /* boot order, for example dca */ 6.106 + bool usb; /* usb support enabled or disabled */ 6.107 + char *usbdevice; /* enable usb mouse: tablet for absolute mouse, mouse for PS/2 protocol relative mouse */ 6.108 + bool apic; /* apic enabled or disabled */ 6.109 + char **extra; /* extra parameters pass directly to qemu, NULL terminated */ 6.110 + /* Network is missing */ 6.111 +} libxl_device_model_info; 6.112 + 6.113 +typedef enum { 6.114 + PHYSTYPE_QCOW, 6.115 + PHYSTYPE_QCOW2, 6.116 + PHYSTYPE_VHD, 6.117 + PHYSTYPE_AIO, 6.118 + PHYSTYPE_FILE, 6.119 + PHYSTYPE_PHY, 6.120 +} libxl_disk_phystype; 6.121 + 6.122 +typedef struct { 6.123 + uint32_t backend_domid; 6.124 + uint32_t domid; 6.125 + char *physpath; 6.126 + libxl_disk_phystype phystype; 6.127 + char *virtpath; 6.128 + int unpluggable; 6.129 + int readwrite; 6.130 + int is_cdrom; 6.131 +} libxl_device_disk; 6.132 + 6.133 +typedef enum { 6.134 + NICTYPE_IOEMU, 6.135 + NICTYPE_VIF, 6.136 +} libxl_nic_type; 6.137 + 6.138 +typedef struct { 6.139 + uint32_t backend_domid; 6.140 + uint32_t domid; 6.141 + int devid; 6.142 + int mtu; 6.143 + char *model; 6.144 + uint8_t mac[6]; 6.145 + char *smac; 6.146 + struct in_addr ip; 6.147 + char *bridge; 6.148 + char *ifname; 6.149 + char *script; 6.150 + libxl_nic_type nictype; 6.151 +} libxl_device_nic; 6.152 + 6.153 +#define ERROR_FAIL (-2) 6.154 +#define ERROR_NI (-101) 6.155 +#define ERROR_NOMEM (-1032) 6.156 +#define ERROR_INVAL (-1245) 6.157 + 6.158 +/* context functions */ 6.159 +int libxl_ctx_init(struct libxl_ctx *ctx); 6.160 +int libxl_ctx_free(struct libxl_ctx *ctx); 6.161 +int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data); 6.162 + 6.163 +/* domain related functions */ 6.164 +int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid); 6.165 +int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid); 6.166 +int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info, 6.167 + uint32_t domid, int fd); 6.168 +int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info, 6.169 + uint32_t domid, int fd); 6.170 +int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req); 6.171 +int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force); 6.172 + 6.173 +int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid); 6.174 +int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid); 6.175 + 6.176 +struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain); 6.177 +xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain); 6.178 + 6.179 +int libxl_create_device_model(struct libxl_ctx *ctx, 6.180 + libxl_device_model_info *info, 6.181 + libxl_device_nic *vifs, int num_vifs); 6.182 + 6.183 +int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk); 6.184 +int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.185 +int libxl_device_disk_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.186 + 6.187 +int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic); 6.188 +int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.189 +int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.190 + 6.191 +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid); 6.192 +int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.193 +int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.194 + 6.195 +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid); 6.196 +int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.197 +int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.198 + 6.199 +int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid); 6.200 +int libxl_device_pci_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.201 +int libxl_device_pci_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid); 6.202 + 6.203 +#endif
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/tools/libxl/libxl_device.c Mon Nov 09 19:54:28 2009 +0000 7.3 @@ -0,0 +1,241 @@ 7.4 +/* 7.5 + * Copyright (C) 2009 Citrix Ltd. 7.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 7.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 7.8 + * 7.9 + * This program is free software; you can redistribute it and/or modify 7.10 + * it under the terms of the GNU Lesser General Public License as published 7.11 + * by the Free Software Foundation; version 2.1 only. with the special 7.12 + * exception on linking described in file LICENSE. 7.13 + * 7.14 + * This program is distributed in the hope that it will be useful, 7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.17 + * GNU Lesser General Public License for more details. 7.18 + */ 7.19 + 7.20 +#include <string.h> 7.21 +#include "libxl.h" 7.22 +#include "libxl_internal.h" 7.23 + 7.24 +char *string_of_kinds[] = { 7.25 + [DEVICE_VIF] = "vif", 7.26 + [DEVICE_VBD] = "vbd", 7.27 + [DEVICE_TAP] = "tap", 7.28 + [DEVICE_PCI] = "pci", 7.29 + [DEVICE_VFB] = "vfb", 7.30 + [DEVICE_VKBD] = "vkbd", 7.31 +}; 7.32 + 7.33 +int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device, 7.34 + char **bents, char **fents) 7.35 +{ 7.36 + char *dom_path_backend, *dom_path, *frontend_path, *backend_path, *hotplug_path; 7.37 + xs_transaction_t t; 7.38 + struct xs_permissions frontend_perms[2]; 7.39 + struct xs_permissions backend_perms[2]; 7.40 + struct xs_permissions hotplug_perms[1]; 7.41 + 7.42 + dom_path_backend = xs_get_domain_path(ctx->xsh, device->backend_domid); 7.43 + dom_path = xs_get_domain_path(ctx->xsh, device->domid); 7.44 + 7.45 + frontend_path = libxl_sprintf(ctx, "%s/device/%s/%d", 7.46 + dom_path, string_of_kinds[device->kind], device->devid); 7.47 + backend_path = libxl_sprintf(ctx, "%s/backend/%s/%u/%d", 7.48 + dom_path_backend, string_of_kinds[device->backend_kind], device->domid, device->devid); 7.49 + hotplug_path = libxl_sprintf(ctx, "/xapi/%d/hotplug/%s/%d", 7.50 + device->domid, string_of_kinds[device->kind], device->devid); 7.51 + 7.52 + frontend_perms[0].id = device->domid; 7.53 + frontend_perms[0].perms = XS_PERM_NONE; 7.54 + frontend_perms[1].id = device->backend_domid; 7.55 + frontend_perms[1].perms = XS_PERM_READ; 7.56 + 7.57 + backend_perms[0].id = device->backend_domid; 7.58 + backend_perms[0].perms = XS_PERM_NONE; 7.59 + backend_perms[1].id = device->domid; 7.60 + backend_perms[1].perms = XS_PERM_READ; 7.61 + 7.62 + hotplug_perms[0].id = device->backend_domid; 7.63 + hotplug_perms[0].perms = XS_PERM_NONE; 7.64 + 7.65 +retry_transaction: 7.66 + t = xs_transaction_start(ctx->xsh); 7.67 + /* FIXME: read frontend_path and check state before removing stuff */ 7.68 + 7.69 + xs_rm(ctx->xsh, t, frontend_path); 7.70 + xs_rm(ctx->xsh, t, backend_path); 7.71 + 7.72 + xs_mkdir(ctx->xsh, t, frontend_path); 7.73 + xs_set_permissions(ctx->xsh, t, frontend_path, frontend_perms, ARRAY_SIZE(frontend_perms)); 7.74 + 7.75 + xs_mkdir(ctx->xsh, t, backend_path); 7.76 + xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, ARRAY_SIZE(backend_perms)); 7.77 + 7.78 + xs_mkdir(ctx->xsh, t, hotplug_path); 7.79 + xs_set_permissions(ctx->xsh, t, hotplug_path, hotplug_perms, ARRAY_SIZE(hotplug_perms)); 7.80 + 7.81 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/backend", frontend_path), backend_path, strlen(backend_path)); 7.82 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/frontend", backend_path), frontend_path, strlen(frontend_path)); 7.83 + 7.84 + /* and write frontend kvs and backend kvs */ 7.85 + libxl_xs_writev(ctx, t, backend_path, bents); 7.86 + libxl_xs_writev(ctx, t, frontend_path, fents); 7.87 + 7.88 + if (!xs_transaction_end(ctx->xsh, t, 0)) 7.89 + if (errno == EAGAIN) 7.90 + goto retry_transaction; 7.91 + return 0; 7.92 +} 7.93 + 7.94 +char *device_disk_string_of_phystype(libxl_disk_phystype phystype) 7.95 +{ 7.96 + switch (phystype) { 7.97 + case PHYSTYPE_QCOW: return "qcow"; 7.98 + case PHYSTYPE_QCOW2: return "qcow2"; 7.99 + case PHYSTYPE_VHD: return "vhd"; 7.100 + case PHYSTYPE_AIO: return "aio"; 7.101 + case PHYSTYPE_FILE: return "file"; 7.102 + case PHYSTYPE_PHY: return "phy"; 7.103 + default: return NULL; 7.104 + } 7.105 +} 7.106 + 7.107 +char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype) 7.108 +{ 7.109 + switch (phystype) { 7.110 + case PHYSTYPE_QCOW: return "tap"; 7.111 + case PHYSTYPE_VHD: return "tap"; 7.112 + case PHYSTYPE_AIO: return "tap"; 7.113 + case PHYSTYPE_FILE: return "file"; 7.114 + case PHYSTYPE_PHY: return "phy"; 7.115 + default: return NULL; 7.116 + } 7.117 +} 7.118 + 7.119 +int device_disk_major_minor(char *virtpath, int *major, int *minor) 7.120 +{ 7.121 + if (strstr(virtpath, "sd") == virtpath) { 7.122 + return -1; 7.123 + } else if (strstr(virtpath, "xvd") == virtpath) { 7.124 + return -1; 7.125 + } else if (strstr(virtpath, "hd") == virtpath) { 7.126 + char letter, letter2; 7.127 + 7.128 + *major = 0; *minor = 0; 7.129 + letter = virtpath[2]; 7.130 + if (letter < 'a' || letter > 't') 7.131 + return -1; 7.132 + letter2 = virtpath[3]; 7.133 + 7.134 + *major = letter - 'a'; 7.135 + *minor = atoi(virtpath + 3); 7.136 + return 0; 7.137 + } else { 7.138 + return -1; 7.139 + } 7.140 +} 7.141 + 7.142 +int device_disk_dev_number(char *virtpath) 7.143 +{ 7.144 + int majors_table[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 }; 7.145 + int major, minor; 7.146 + 7.147 + if (device_disk_major_minor(virtpath, &major, &minor)) 7.148 + return -1; 7.149 + return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor; 7.150 +} 7.151 + 7.152 +int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force) 7.153 +{ 7.154 + xs_transaction_t t; 7.155 + char *state_path = libxl_sprintf(ctx, "%s/state", be_path); 7.156 + char *state = libxl_xs_read(ctx, XBT_NULL, state_path); 7.157 + if (!state) 7.158 + return 0; 7.159 + if (atoi(state) <= 3) { 7.160 + xs_rm(ctx->xsh, XBT_NULL, be_path); 7.161 + return 0; 7.162 + } 7.163 + 7.164 +retry_transaction: 7.165 + t = xs_transaction_start(ctx->xsh); 7.166 + xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/online", be_path), "0", strlen("0")); 7.167 + xs_write(ctx->xsh, t, state_path, "5", strlen("5")); 7.168 + if (!xs_transaction_end(ctx->xsh, t, 0)) { 7.169 + if (errno == EAGAIN) 7.170 + goto retry_transaction; 7.171 + else 7.172 + return -1; 7.173 + } 7.174 + if (!force) { 7.175 + xs_watch(ctx->xsh, state_path, be_path); 7.176 + return 1; 7.177 + } else 7.178 + return 0; 7.179 +} 7.180 + 7.181 +int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force) 7.182 +{ 7.183 + char *path, *be_path, *fe_path; 7.184 + unsigned int num1, num2; 7.185 + char **l1 = NULL, **l2 = NULL; 7.186 + int i, j, nfds, n = 0, n_watches = 0; 7.187 + fd_set rfds; 7.188 + struct timeval tv; 7.189 + flexarray_t *toremove; 7.190 + 7.191 + toremove = flexarray_make(16, 1); 7.192 + path = libxl_sprintf(ctx, "/local/domain/%d/device", domid); 7.193 + l1 = libxl_xs_directory(ctx, XBT_NULL, path, &num1); 7.194 + if (!l1) { 7.195 + XL_LOG(ctx, XL_LOG_ERROR, "%s is empty\n", path); 7.196 + return -1; 7.197 + } 7.198 + for (i = 0; i < num1; i++) { 7.199 + path = libxl_sprintf(ctx, "/local/domain/%d/device/%s", domid, l1[i]); 7.200 + l2 = libxl_xs_directory(ctx, XBT_NULL, path, &num2); 7.201 + if (!l2) 7.202 + continue; 7.203 + for (j = 0; j < num2; j++) { 7.204 + fe_path = libxl_sprintf(ctx, "/local/domain/%d/device/%s/%s", domid, l1[i], l2[j]); 7.205 + be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", fe_path)); 7.206 + if (be_path != NULL) { 7.207 + if (libxl_device_destroy(ctx, be_path, force) > 0) 7.208 + n_watches++; 7.209 + flexarray_set(toremove, n++, libxl_dirname(ctx, be_path)); 7.210 + } else { 7.211 + xs_rm(ctx->xsh, XBT_NULL, path); 7.212 + } 7.213 + } 7.214 + } 7.215 + if (!force) { 7.216 + nfds = xs_fileno(ctx->xsh) + 1; 7.217 + /* Linux-ism */ 7.218 + tv.tv_sec = LIBXL_DESTROY_TIMEOUT; 7.219 + tv.tv_usec = 0; 7.220 + while (n_watches > 0 && tv.tv_sec > 0) { 7.221 + FD_ZERO(&rfds); 7.222 + FD_SET(xs_fileno(ctx->xsh), &rfds); 7.223 + if (select(nfds, &rfds, NULL, NULL, &tv) > 0) { 7.224 + l1 = xs_read_watch(ctx->xsh, &num1); 7.225 + if (l1 != NULL) { 7.226 + char *state = libxl_xs_read(ctx, XBT_NULL, l1[0]); 7.227 + if (!state || atoi(state) == 6) { 7.228 + xs_unwatch(ctx->xsh, l1[0], l1[1]); 7.229 + xs_rm(ctx->xsh, XBT_NULL, l1[1]); 7.230 + XL_LOG(ctx, XL_LOG_DEBUG, "Destroyed device backend at %s\n", l1[1]); 7.231 + n_watches--; 7.232 + } 7.233 + } 7.234 + } else 7.235 + break; 7.236 + } 7.237 + } 7.238 + for (i = 0; i < n; i++) { 7.239 + flexarray_get(toremove, i, (void**) &path); 7.240 + xs_rm(ctx->xsh, XBT_NULL, path); 7.241 + } 7.242 + flexarray_free(toremove); 7.243 + return 0; 7.244 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/tools/libxl/libxl_dom.c Mon Nov 09 19:54:28 2009 +0000 8.3 @@ -0,0 +1,271 @@ 8.4 +/* 8.5 + * Copyright (C) 2009 Citrix Ltd. 8.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 8.7 + * 8.8 + * This program is free software; you can redistribute it and/or modify 8.9 + * it under the terms of the GNU Lesser General Public License as published 8.10 + * by the Free Software Foundation; version 2.1 only. with the special 8.11 + * exception on linking described in file LICENSE. 8.12 + * 8.13 + * This program is distributed in the hope that it will be useful, 8.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.16 + * GNU Lesser General Public License for more details. 8.17 + */ 8.18 + 8.19 +#include "libxl.h" 8.20 +#include "libxl_internal.h" 8.21 +#include <inttypes.h> 8.22 +#include <xenguest.h> 8.23 +#include <string.h> 8.24 + 8.25 +int is_hvm(struct libxl_ctx *ctx, uint32_t domid) 8.26 +{ 8.27 + xc_domaininfo_t info; 8.28 + int ret; 8.29 + 8.30 + ret = xc_domain_getinfolist(ctx->xch, domid, 1, &info); 8.31 + if (ret != 1) 8.32 + return -1; 8.33 + if (info.domain != domid) 8.34 + return -1; 8.35 + return !!(info.flags & XEN_DOMINF_hvm_guest); 8.36 +} 8.37 + 8.38 +int build_pre(struct libxl_ctx *ctx, uint32_t domid, 8.39 + libxl_domain_build_info *info, libxl_domain_build_state *state) 8.40 +{ 8.41 + unsigned long shadow; 8.42 + if (info->timer_mode != -1) 8.43 + xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_TIMER_MODE, 8.44 + (unsigned long) info->timer_mode); 8.45 + if (info->hpet != -1) 8.46 + xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) info->hpet); 8.47 + if (info->vpt_align != -1) 8.48 + xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->vpt_align); 8.49 + xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus); 8.50 + xc_domain_setmaxmem(ctx->xch, domid, info->max_memkb + info->video_memkb); 8.51 + xc_domain_set_memmap_limit(ctx->xch, domid, info->max_memkb); 8.52 + shadow = (info->shadow_memkb + 1023) / 1024; 8.53 + xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL); 8.54 + 8.55 + state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); 8.56 + state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); 8.57 + return 0; 8.58 +} 8.59 + 8.60 +int build_post(struct libxl_ctx *ctx, uint32_t domid, 8.61 + libxl_domain_build_info *info, libxl_domain_build_state *state, 8.62 + char **vms_ents, char **local_ents) 8.63 +{ 8.64 + char *dom_path, *vm_path; 8.65 + xs_transaction_t t; 8.66 + char **ents; 8.67 + 8.68 + ents = libxl_calloc(ctx, 6 * 2, sizeof(char *)); 8.69 + ents[0] = libxl_sprintf(ctx, "memory/static-max"); 8.70 + ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb); 8.71 + ents[2] = libxl_sprintf(ctx, "memory/target"); 8.72 + ents[3] = libxl_sprintf(ctx, "%d", info->max_memkb); /* PROBABLY WRONG */ 8.73 + ents[4] = libxl_sprintf(ctx, "domid"); 8.74 + ents[5] = libxl_sprintf(ctx, "%d", domid); 8.75 + ents[6] = libxl_sprintf(ctx, "store/port"); 8.76 + ents[7] = libxl_sprintf(ctx, "%"PRIu32, state->store_port); 8.77 + ents[8] = libxl_sprintf(ctx, "store/ring-ref"); 8.78 + ents[9] = libxl_sprintf(ctx, "%lu", state->store_mfn); 8.79 + 8.80 + dom_path = libxl_xs_get_dompath(ctx, domid); 8.81 + vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dom_path), NULL); 8.82 +retry_transaction: 8.83 + t = xs_transaction_start(ctx->xsh); 8.84 + 8.85 + libxl_xs_writev(ctx, t, dom_path, ents); 8.86 + libxl_xs_writev(ctx, t, dom_path, local_ents); 8.87 + libxl_xs_writev(ctx, t, vm_path, vms_ents); 8.88 + 8.89 + if (!xs_transaction_end(ctx->xsh, t, 0)) 8.90 + if (errno == EAGAIN) 8.91 + goto retry_transaction; 8.92 + xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port); 8.93 + return 0; 8.94 +} 8.95 + 8.96 +int build_pv(struct libxl_ctx *ctx, uint32_t domid, 8.97 + libxl_domain_build_info *info, libxl_domain_build_state *state) 8.98 +{ 8.99 + int mem_target_kib = info->max_memkb; 8.100 + char *domid_str = libxl_sprintf(ctx, "%d", domid); 8.101 + char *memsize_str = libxl_sprintf(ctx, "%d", mem_target_kib / 1024); 8.102 + char *store_port_str = libxl_sprintf(ctx, "%d", state->store_port); 8.103 + char *console_port_str = libxl_sprintf(ctx, "%d", state->console_port); 8.104 + return ERROR_NI; 8.105 +} 8.106 + 8.107 +int build_hvm(struct libxl_ctx *ctx, uint32_t domid, 8.108 + libxl_domain_build_info *info, libxl_domain_build_state *state) 8.109 +{ 8.110 + int ret; 8.111 + 8.112 + ret = xc_hvm_build(ctx->xch, domid, info->max_memkb / 1024, info->kernel); 8.113 + if (ret) { 8.114 + XL_LOG(ctx, XL_LOG_ERROR, "hvm building failed: %d", ret); 8.115 + return ERROR_FAIL; 8.116 + } 8.117 + ret = hvm_build_set_params(ctx->xch, domid, info->u.hvm.apic, info->u.hvm.acpi, 8.118 + info->u.hvm.pae, info->u.hvm.nx, info->u.hvm.viridian, 8.119 + info->max_vcpus, 8.120 + state->store_port, &state->store_mfn); 8.121 + if (ret) { 8.122 + XL_LOG(ctx, XL_LOG_ERROR, "hvm build set params failed: %d", ret); 8.123 + return ERROR_FAIL; 8.124 + } 8.125 + xc_cpuid_apply_policy(ctx->xch, domid); 8.126 + return 0; 8.127 +} 8.128 + 8.129 +int restore_common(struct libxl_ctx *ctx, uint32_t domid, 8.130 + libxl_domain_build_info *info, libxl_domain_build_state *state, 8.131 + int fd) 8.132 +{ 8.133 + /* read signature */ 8.134 + xc_domain_restore(ctx->xch, fd, domid, 8.135 + state->store_port, &state->store_mfn, 8.136 + state->console_port, &state->console_mfn, 8.137 + info->hvm, info->u.hvm.pae, 0); 8.138 + return 0; 8.139 +} 8.140 + 8.141 +/* the following code is extremely ugly and racy without forking. 8.142 + we intend to fix the re-entrancy of the underlying code instead of forking */ 8.143 +static struct libxl_ctx *global_suspend_ctx = NULL; 8.144 +static struct suspendinfo { 8.145 + int xch; 8.146 + int xce; /* event channel handle */ 8.147 + int suspend_eventchn; 8.148 + int domid; 8.149 + int hvm; 8.150 + unsigned int flags; 8.151 +} si; 8.152 + 8.153 +void core_suspend_switch_qemu_logdirty(int domid, unsigned int enable) 8.154 +{ 8.155 + struct xs_handle *xs; 8.156 + char *path, *ret_path, *cmd_path, *ret_str, *cmd_str, **watch; 8.157 + unsigned int len; 8.158 + struct timeval tv; 8.159 + fd_set fdset; 8.160 + struct libxl_ctx *ctx = global_suspend_ctx; 8.161 + 8.162 + xs = xs_daemon_open(); 8.163 + if (!xs) 8.164 + return; 8.165 + path = libxl_sprintf(ctx, "/local/domain/0/device-model/%i/logdirty", domid); 8.166 + if (!path) 8.167 + return; 8.168 + ret_path = libxl_sprintf(ctx, "%s/ret", path); 8.169 + if (!ret_path) 8.170 + return; 8.171 + cmd_path = libxl_sprintf(ctx, "%s/cmd", path); 8.172 + if (!ret_path) 8.173 + return; 8.174 + 8.175 + /* Watch for qemu's return value */ 8.176 + if (!xs_watch(xs, ret_path, "qemu-logdirty-ret")) 8.177 + return; 8.178 + 8.179 + cmd_str = (enable == 0) ? "disable" : "enable"; 8.180 + 8.181 + /* Tell qemu that we want it to start logging dirty page to Xen */ 8.182 + if (!xs_write(xs, XBT_NULL, cmd_path, cmd_str, strlen(cmd_str))) 8.183 + return; 8.184 + 8.185 + /* Wait a while for qemu to signal that it has service logdirty command */ 8.186 +read_again: 8.187 + tv.tv_sec = 5; 8.188 + tv.tv_usec = 0; 8.189 + FD_ZERO(&fdset); 8.190 + FD_SET(xs_fileno(xs), &fdset); 8.191 + 8.192 + if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) 8.193 + return; 8.194 + 8.195 + watch = xs_read_watch(xs, &len); 8.196 + free(watch); 8.197 + 8.198 + ret_str = xs_read(xs, XBT_NULL, ret_path, &len); 8.199 + if (ret_str == NULL || strcmp(ret_str, cmd_str)) 8.200 + /* Watch fired but value is not yet right */ 8.201 + goto read_again; 8.202 + free(ret_str); 8.203 +} 8.204 + 8.205 +static int core_suspend_callback(void) 8.206 +{ 8.207 + unsigned long s_state = 0; 8.208 + int ret; 8.209 + 8.210 + if (si.hvm) 8.211 + xc_get_hvm_param(si.xch, si.domid, HVM_PARAM_ACPI_S_STATE, &s_state); 8.212 + if ((s_state == 0) && (si.suspend_eventchn >= 0)) { 8.213 + ret = xc_evtchn_notify(si.xch, si.suspend_eventchn); 8.214 + if (ret < 0) { 8.215 + return 0; 8.216 + } 8.217 + ret = xc_await_suspend(si.xch, si.suspend_eventchn); 8.218 + if (ret < 0) { 8.219 + return 0; 8.220 + } 8.221 + return 1; 8.222 + } 8.223 + /* need to shutdown (to suspend) the domain here */ 8.224 + return 0; 8.225 +} 8.226 + 8.227 +int core_suspend(struct libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, int debug) 8.228 +{ 8.229 + int flags; 8.230 + int port; 8.231 + 8.232 + flags = (live) ? XCFLAGS_LIVE : 0 8.233 + | (debug) ? XCFLAGS_DEBUG : 0; 8.234 + 8.235 + /* crappy global lock until we make everything clean */ 8.236 + while (global_suspend_ctx) { 8.237 + sleep(1); 8.238 + } 8.239 + global_suspend_ctx = ctx; 8.240 + 8.241 + si.domid = domid; 8.242 + si.flags = flags; 8.243 + si.hvm = hvm; 8.244 + si.suspend_eventchn = si.xce = -1; 8.245 + si.xch = ctx->xch; 8.246 + 8.247 + si.xce = xc_evtchn_open(); 8.248 + if (si.xce < 0) 8.249 + return -1; 8.250 + 8.251 + if (si.xce > 0) { 8.252 + port = xs_suspend_evtchn_port(si.domid); 8.253 + 8.254 + if (port < 0) { 8.255 + } else { 8.256 + si.suspend_eventchn = xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port); 8.257 + 8.258 + if (si.suspend_eventchn < 0) { 8.259 + } 8.260 + } 8.261 + } 8.262 + 8.263 + xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, 8.264 + core_suspend_callback, hvm, 8.265 + core_suspend_switch_qemu_logdirty); 8.266 + 8.267 + if (si.suspend_eventchn > 0) 8.268 + xc_suspend_evtchn_release(si.xce, si.suspend_eventchn); 8.269 + if (si.xce > 0) 8.270 + xc_evtchn_close(si.xce); 8.271 + 8.272 + global_suspend_ctx = NULL; 8.273 + return 0; 8.274 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tools/libxl/libxl_exec.c Mon Nov 09 19:54:28 2009 +0000 9.3 @@ -0,0 +1,48 @@ 9.4 + 9.5 +/* 9.6 + * Copyright (C) 2009 Citrix Ltd. 9.7 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 9.8 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 9.9 + * 9.10 + * This program is free software; you can redistribute it and/or modify 9.11 + * it under the terms of the GNU Lesser General Public License as published 9.12 + * by the Free Software Foundation; version 2.1 only. with the special 9.13 + * exception on linking described in file LICENSE. 9.14 + * 9.15 + * This program is distributed in the hope that it will be useful, 9.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.18 + * GNU Lesser General Public License for more details. 9.19 + */ 9.20 + 9.21 +#include <stdio.h> 9.22 +#include <unistd.h> 9.23 +#include <stdlib.h> 9.24 +#include "libxl.h" 9.25 +#include "libxl_internal.h" 9.26 + 9.27 +int libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int stderrfd, 9.28 + char *arg0, char **args) 9.29 +{ 9.30 + int pid, i; 9.31 + 9.32 + pid = fork(); 9.33 + if (pid == -1) { 9.34 + XL_LOG(ctx, XL_LOG_ERROR, "fork failed"); 9.35 + return -1; 9.36 + } 9.37 + if (pid == 0) { 9.38 + /* child */ 9.39 + if (stdinfd != -1) 9.40 + dup2(stdinfd, STDIN_FILENO); 9.41 + if (stdoutfd != -1) 9.42 + dup2(stdoutfd, STDOUT_FILENO); 9.43 + if (stderrfd != -1) 9.44 + dup2(stderrfd, STDERR_FILENO); 9.45 + for (i = 4; i < 256; i++) 9.46 + close(i); 9.47 + execv(arg0, args); 9.48 + exit(256); 9.49 + } 9.50 + return pid; 9.51 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/libxl/libxl_internal.c Mon Nov 09 19:54:28 2009 +0000 10.3 @@ -0,0 +1,159 @@ 10.4 +/* 10.5 + * Copyright (C) 2009 Citrix Ltd. 10.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 10.7 + * 10.8 + * This program is free software; you can redistribute it and/or modify 10.9 + * it under the terms of the GNU Lesser General Public License as published 10.10 + * by the Free Software Foundation; version 2.1 only. with the special 10.11 + * exception on linking described in file LICENSE. 10.12 + * 10.13 + * This program is distributed in the hope that it will be useful, 10.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.16 + * GNU Lesser General Public License for more details. 10.17 + */ 10.18 +#include "libxl.h" 10.19 +#include "libxl_internal.h" 10.20 +#include "libxl_utils.h" 10.21 +#include <stdio.h> 10.22 +#include <stdarg.h> 10.23 +#include <string.h> 10.24 + 10.25 +int libxl_error_set(struct libxl_ctx *ctx, int code) 10.26 +{ 10.27 + return 0; 10.28 +} 10.29 + 10.30 +int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr) 10.31 +{ 10.32 + int i; 10.33 + void **re; 10.34 + 10.35 + if (!ptr) 10.36 + return 0; 10.37 + 10.38 + /* fast case: we have space in the array for storing the pointer */ 10.39 + for (i = 0; i < ctx->alloc_maxsize; i++) { 10.40 + if (!ctx->alloc_ptrs[i]) { 10.41 + ctx->alloc_ptrs[i] = ptr; 10.42 + return 0; 10.43 + } 10.44 + } 10.45 + /* realloc alloc_ptrs manually with calloc/free/replace */ 10.46 + re = calloc(ctx->alloc_maxsize + 25, sizeof(void *)); 10.47 + if (!re) 10.48 + return -1; 10.49 + for (i = 0; i < ctx->alloc_maxsize; i++) 10.50 + re[i] = ctx->alloc_ptrs[i]; 10.51 + /* assign the next pointer */ 10.52 + re[i] = ptr; 10.53 + 10.54 + /* replace the old alloc_ptr */ 10.55 + free(ctx->alloc_ptrs); 10.56 + ctx->alloc_ptrs = re; 10.57 + ctx->alloc_maxsize += 25; 10.58 + return 0; 10.59 +} 10.60 + 10.61 +int libxl_free(struct libxl_ctx *ctx, void *ptr) 10.62 +{ 10.63 + int i; 10.64 + 10.65 + if (!ptr) 10.66 + return 0; 10.67 + 10.68 + /* remove the pointer from the tracked ptrs */ 10.69 + for (i = 0; i < ctx->alloc_maxsize; i++) { 10.70 + if (ctx->alloc_ptrs[i] == ptr) { 10.71 + ctx->alloc_ptrs[i] = NULL; 10.72 + free(ptr); 10.73 + return 0; 10.74 + } 10.75 + } 10.76 + /* haven't find the pointer, really bad */ 10.77 + return -1; 10.78 +} 10.79 + 10.80 +int libxl_free_all(struct libxl_ctx *ctx) 10.81 +{ 10.82 + void *ptr; 10.83 + int i; 10.84 + 10.85 + for (i = 0; i < ctx->alloc_maxsize; i++) { 10.86 + ptr = ctx->alloc_ptrs[i]; 10.87 + ctx->alloc_ptrs[i] = NULL; 10.88 + free(ptr); 10.89 + } 10.90 + return 0; 10.91 +} 10.92 + 10.93 +void *libxl_zalloc(struct libxl_ctx *ctx, int bytes) 10.94 +{ 10.95 + void *ptr = calloc(bytes, 1); 10.96 + if (!ptr) { 10.97 + libxl_error_set(ctx, ENOMEM); 10.98 + return NULL; 10.99 + } 10.100 + 10.101 + libxl_ptr_add(ctx, ptr); 10.102 + return ptr; 10.103 +} 10.104 + 10.105 +void *libxl_calloc(struct libxl_ctx *ctx, size_t nmemb, size_t size) 10.106 +{ 10.107 + void *ptr = calloc(nmemb, size); 10.108 + if (!ptr) { 10.109 + libxl_error_set(ctx, ENOMEM); 10.110 + return NULL; 10.111 + } 10.112 + 10.113 + libxl_ptr_add(ctx, ptr); 10.114 + return ptr; 10.115 +} 10.116 + 10.117 +char *libxl_sprintf(struct libxl_ctx *ctx, const char *fmt, ...) 10.118 +{ 10.119 + char *s; 10.120 + va_list ap; 10.121 + int ret; 10.122 + 10.123 + va_start(ap, fmt); 10.124 + ret = vsnprintf(NULL, 0, fmt, ap); 10.125 + va_end(ap); 10.126 + 10.127 + if (ret < 0) { 10.128 + return NULL; 10.129 + } 10.130 + 10.131 + s = libxl_zalloc(ctx, ret + 1); 10.132 + if (s) { 10.133 + va_start(ap, fmt); 10.134 + ret = vsnprintf(s, ret + 1, fmt, ap); 10.135 + va_end(ap); 10.136 + } 10.137 + return s; 10.138 +} 10.139 + 10.140 +char *libxl_dirname(struct libxl_ctx *ctx, const char *s) 10.141 +{ 10.142 + char *c; 10.143 + char *ptr = libxl_sprintf(ctx, "%s", s); 10.144 + 10.145 + c = strrchr(ptr, '/'); 10.146 + if (!c) 10.147 + return NULL; 10.148 + *c = '\0'; 10.149 + return ptr; 10.150 +} 10.151 + 10.152 +void xl_log(struct libxl_ctx *ctx, int loglevel, const char *file, int line, const char *func, char *fmt, ...) 10.153 +{ 10.154 + va_list ap; 10.155 + char *s; 10.156 + va_start(ap, fmt); 10.157 + vasprintf(&s, fmt, ap); 10.158 + va_end(ap); 10.159 + 10.160 + ctx->log_callback(ctx->log_userdata, loglevel, file, line, func, s); 10.161 + free(s); 10.162 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/tools/libxl/libxl_internal.h Mon Nov 09 19:54:28 2009 +0000 11.3 @@ -0,0 +1,135 @@ 11.4 +/* 11.5 + * Copyright (C) 2009 Citrix Ltd. 11.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 11.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 11.8 + * 11.9 + * This program is free software; you can redistribute it and/or modify 11.10 + * it under the terms of the GNU Lesser General Public License as published 11.11 + * by the Free Software Foundation; version 2.1 only. with the special 11.12 + * exception on linking described in file LICENSE. 11.13 + * 11.14 + * This program is distributed in the hope that it will be useful, 11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.17 + * GNU Lesser General Public License for more details. 11.18 + */ 11.19 + 11.20 +#ifndef LIBXL_INTERNAL_H 11.21 +# define LIBXL_INTERNAL_H 11.22 + 11.23 +#include <stdint.h> 11.24 +#include <stdarg.h> 11.25 +#include <stdlib.h> 11.26 + 11.27 +#include <xs.h> 11.28 +#include <xenctrl.h> 11.29 + 11.30 +#include "flexarray.h" 11.31 +#include "libxl_utils.h" 11.32 + 11.33 +#define LIBXL_DESTROY_TIMEOUT 10 11.34 + 11.35 +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 11.36 + 11.37 + 11.38 +#define XL_LOGGING_ENABLED 11.39 + 11.40 +#ifdef XL_LOGGING_ENABLED 11.41 +#define XL_LOG(ctx, loglevel, _f, _a...) xl_log(ctx, loglevel, __FILE__, __LINE__, __func__, _f, ##_a) 11.42 +#else 11.43 +#define XL_LOG(ctx, loglevel, _f, _a...) 11.44 +#endif 11.45 + 11.46 +#define XL_LOG_DEBUG 3 11.47 +#define XL_LOG_INFO 2 11.48 +#define XL_LOG_WARNING 1 11.49 +#define XL_LOG_ERROR 0 11.50 + 11.51 +void xl_log(struct libxl_ctx *ctx, int loglevel, const char *file, int line, const char *func, char *fmt, ...); 11.52 + 11.53 +typedef struct { 11.54 + uint32_t store_port; 11.55 + unsigned long store_mfn; 11.56 + uint32_t console_port; 11.57 + unsigned long console_mfn; 11.58 +} libxl_domain_build_state; 11.59 + 11.60 +typedef enum { 11.61 + DEVICE_VIF, 11.62 + DEVICE_VBD, 11.63 + DEVICE_TAP, 11.64 + DEVICE_PCI, 11.65 + DEVICE_VFB, 11.66 + DEVICE_VKBD, 11.67 +} libxl_device_kinds; 11.68 + 11.69 +typedef struct { 11.70 + uint32_t backend_devid; 11.71 + uint32_t backend_domid; 11.72 + uint32_t devid; 11.73 + uint32_t domid; 11.74 + libxl_device_kinds backend_kind; 11.75 + libxl_device_kinds kind; 11.76 +} libxl_device; 11.77 + 11.78 +#define PRINTF_ATTRIBUTE(x, y) __attribute__((format(printf, x, y))) 11.79 + 11.80 +/* memory allocation tracking/helpers */ 11.81 +int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr); 11.82 +int libxl_free(struct libxl_ctx *ctx, void *ptr); 11.83 +int libxl_free_all(struct libxl_ctx *ctx); 11.84 +void *libxl_zalloc(struct libxl_ctx *ctx, int bytes); 11.85 +void *libxl_calloc(struct libxl_ctx *ctx, size_t nmemb, size_t size); 11.86 +char *libxl_sprintf(struct libxl_ctx *ctx, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); 11.87 +char *libxl_dirname(struct libxl_ctx *ctx, const char *s); 11.88 +char *uuid_to_string(struct libxl_ctx *ctx, uint8_t *uuid); 11.89 + 11.90 +char **libxl_xs_kvs_of_flexarray(struct libxl_ctx *ctx, flexarray_t *array, int length); 11.91 +int libxl_xs_writev(struct libxl_ctx *ctx, xs_transaction_t t, 11.92 + char *dir, char **kvs); 11.93 +int libxl_xs_write(struct libxl_ctx *ctx, xs_transaction_t t, 11.94 + char *path, char *fmt, ...); 11.95 +char *libxl_xs_get_dompath(struct libxl_ctx *ctx, uint32_t domid); 11.96 +char *libxl_xs_read(struct libxl_ctx *ctx, xs_transaction_t t, char *path); 11.97 +char **libxl_xs_directory(struct libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb); 11.98 + 11.99 +/* from xd_dom */ 11.100 +int is_hvm(struct libxl_ctx *ctx, uint32_t domid); 11.101 +int build_pre(struct libxl_ctx *ctx, uint32_t domid, 11.102 + libxl_domain_build_info *info, libxl_domain_build_state *state); 11.103 +int build_post(struct libxl_ctx *ctx, uint32_t domid, 11.104 + libxl_domain_build_info *info, libxl_domain_build_state *state, 11.105 + char **vms_ents, char **local_ents); 11.106 + 11.107 +int build_pv(struct libxl_ctx *ctx, uint32_t domid, 11.108 + libxl_domain_build_info *info, libxl_domain_build_state *state); 11.109 +int build_hvm(struct libxl_ctx *ctx, uint32_t domid, 11.110 + libxl_domain_build_info *info, libxl_domain_build_state *state); 11.111 + 11.112 +int restore_common(struct libxl_ctx *ctx, uint32_t domid, 11.113 + libxl_domain_build_info *info, libxl_domain_build_state *state, int fd); 11.114 +int core_suspend(struct libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, int debug); 11.115 + 11.116 +/* from xd_device */ 11.117 +char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype); 11.118 +char *device_disk_string_of_phystype(libxl_disk_phystype phystype); 11.119 + 11.120 +int device_disk_major_minor(char *virtpath, int *major, int *minor); 11.121 +int device_disk_dev_number(char *virtpath); 11.122 + 11.123 +int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device, 11.124 + char **bents, char **fents); 11.125 +int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force); 11.126 +int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force); 11.127 + 11.128 +/* from xenguest (helper */ 11.129 +int hvm_build_set_params(int handle, uint32_t domid, 11.130 + int apic, int acpi, int pae, int nx, int viridian, 11.131 + int vcpus, int store_evtchn, unsigned long *store_mfn); 11.132 + 11.133 +/* xd_exec */ 11.134 +int libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int stderrfd, 11.135 + char *arg0, char **args); 11.136 + 11.137 +#endif 11.138 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/tools/libxl/libxl_utils.c Mon Nov 09 19:54:28 2009 +0000 12.3 @@ -0,0 +1,159 @@ 12.4 +/* 12.5 + * Copyright (C) 2009 Citrix Ltd. 12.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 12.7 + * 12.8 + * This program is free software; you can redistribute it and/or modify 12.9 + * it under the terms of the GNU Lesser General Public License as published 12.10 + * by the Free Software Foundation; version 2.1 only. with the special 12.11 + * exception on linking described in file LICENSE. 12.12 + * 12.13 + * This program is distributed in the hope that it will be useful, 12.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.16 + * GNU Lesser General Public License for more details. 12.17 + */ 12.18 + 12.19 +#include "libxl_utils.h" 12.20 +#include "libxl_internal.h" 12.21 +#include <stdio.h> 12.22 +#include <stdlib.h> 12.23 +#include <stdint.h> 12.24 +#include <string.h> 12.25 +#include <xs.h> 12.26 +#include <xenctrl.h> 12.27 +#include <ctype.h> 12.28 +#include <errno.h> 12.29 + 12.30 + 12.31 + 12.32 +unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus) 12.33 +{ 12.34 + /* 256 pages (1MB) per vcpu, 12.35 + plus 1 page per MiB of RAM for the P2M map, 12.36 + plus 1 page per MiB of RAM to shadow the resident processes. 12.37 + This is higher than the minimum that Xen would allocate if no value 12.38 + were given (but the Xen minimum is for safety, not performance). 12.39 + */ 12.40 + return 4 * (256 * smp_cpus + 2 * (maxmem_kb / 1024)); 12.41 +} 12.42 + 12.43 +char *libxl_domid_to_name(struct libxl_ctx *ctx, uint32_t domid) 12.44 +{ 12.45 + unsigned int len; 12.46 + char path[strlen("/local/domain") + 12]; 12.47 + char *s; 12.48 + 12.49 + snprintf(path, sizeof(path), "/local/domain/%d/name", domid); 12.50 + s = xs_read(ctx->xsh, XBT_NULL, path, &len); 12.51 + libxl_ptr_add(ctx, s); 12.52 + return s; 12.53 +} 12.54 + 12.55 +int libxl_name_to_domid(struct libxl_ctx *ctx, char *name, uint32_t *domid) 12.56 +{ 12.57 + unsigned int num, len; 12.58 + char path[strlen("/local/domain") + 12]; 12.59 + int i; 12.60 + char *domname, **l; 12.61 + 12.62 + l = xs_directory(ctx->xsh, XBT_NULL, "/local/domain", &num); 12.63 + for (i = 0; i < num; i++) { 12.64 + snprintf(path, sizeof(path), "/local/domain/%s/name", l[i]); 12.65 + domname = xs_read(ctx->xsh, XBT_NULL, path, &len); 12.66 + if (domname != NULL && !strncmp(domname, name, len)) { 12.67 + *domid = atoi(l[i]); 12.68 + free(l); 12.69 + free(domname); 12.70 + return 0; 12.71 + } 12.72 + free(domname); 12.73 + } 12.74 + free(l); 12.75 + return -1; 12.76 +} 12.77 + 12.78 +int libxl_uuid_to_domid(struct libxl_ctx *ctx, uint8_t *uuid, uint32_t *domid) 12.79 +{ 12.80 + int nb_domain, i; 12.81 + struct libxl_dominfo *info = libxl_domain_list(ctx, &nb_domain); 12.82 + for (i = 0; i < nb_domain; i++) { 12.83 + if (!memcmp(info[i].uuid, uuid, 16)) { 12.84 + *domid = info[i].domid; 12.85 + return 0; 12.86 + } 12.87 + } 12.88 + return -1; 12.89 +} 12.90 + 12.91 +int libxl_domid_to_uuid(struct libxl_ctx *ctx, uint8_t **uuid, uint32_t domid) 12.92 +{ 12.93 + int nb_domain, i; 12.94 + struct libxl_dominfo *info = libxl_domain_list(ctx, &nb_domain); 12.95 + for (i = 0; i < nb_domain; i++) { 12.96 + if (domid == info[i].domid) { 12.97 + *uuid = libxl_zalloc(ctx, 16); 12.98 + memcpy(*uuid, info[i].uuid, 16); 12.99 + return 0; 12.100 + } 12.101 + } 12.102 + return -1; 12.103 +} 12.104 + 12.105 +int libxl_is_uuid(char *s) 12.106 +{ 12.107 + int i; 12.108 + if (!s || strlen(s) != 36) 12.109 + return 0; 12.110 + for (i = 0; i < 36; i++) { 12.111 + if (i == 8 || i == 13 || i == 18 || i == 23) { 12.112 + if (s[i] != '-') 12.113 + return 0; 12.114 + } else { 12.115 + if (!isxdigit(s[i])) 12.116 + return 0; 12.117 + } 12.118 + } 12.119 + return 1; 12.120 +} 12.121 + 12.122 +uint8_t *string_to_uuid(struct libxl_ctx *ctx, char *s) 12.123 +{ 12.124 + uint8_t *buf; 12.125 + if (!s || !ctx) 12.126 + return NULL; 12.127 + 12.128 + buf = libxl_zalloc(ctx, 16); 12.129 + sscanf(s, UUID_FMT, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5], 12.130 + &buf[6], &buf[7], &buf[8], &buf[9], &buf[10], &buf[11], &buf[12], 12.131 + &buf[13], &buf[14], &buf[15]); 12.132 + return buf; 12.133 +} 12.134 + 12.135 +char *uuid_to_string(struct libxl_ctx *ctx, uint8_t *uuid) 12.136 +{ 12.137 + if (!uuid) 12.138 + return NULL; 12.139 + return libxl_sprintf(ctx, UUID_FMT, 12.140 + uuid[0], uuid[1], uuid[2], uuid[3], 12.141 + uuid[4], uuid[5], uuid[6], uuid[7], 12.142 + uuid[8], uuid[9], uuid[10], uuid[11], 12.143 + uuid[12], uuid[13], uuid[14], uuid[15]); 12.144 +} 12.145 + 12.146 +int libxl_param_to_domid(struct libxl_ctx *ctx, char *p, uint32_t *domid) 12.147 +{ 12.148 + uint8_t *uuid; 12.149 + uint32_t d; 12.150 + 12.151 + if (libxl_is_uuid(p)) { 12.152 + uuid = string_to_uuid(ctx, p); 12.153 + return libxl_uuid_to_domid(ctx, uuid, domid); 12.154 + } 12.155 + errno = 0; 12.156 + d = strtol(p, (char **) NULL, 10); 12.157 + if (!errno && d != 0 && d != LONG_MAX && d != LONG_MIN) { 12.158 + *domid = d; 12.159 + return 0; 12.160 + } 12.161 + return libxl_name_to_domid(ctx, p, domid); 12.162 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/tools/libxl/libxl_utils.h Mon Nov 09 19:54:28 2009 +0000 13.3 @@ -0,0 +1,34 @@ 13.4 +/* 13.5 + * Copyright (C) 2009 Citrix Ltd. 13.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 13.7 + * 13.8 + * This program is free software; you can redistribute it and/or modify 13.9 + * it under the terms of the GNU Lesser General Public License as published 13.10 + * by the Free Software Foundation; version 2.1 only. with the special 13.11 + * exception on linking described in file LICENSE. 13.12 + * 13.13 + * This program is distributed in the hope that it will be useful, 13.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.16 + * GNU Lesser General Public License for more details. 13.17 + */ 13.18 + 13.19 +#ifndef LIBXL_UTILS_H 13.20 +#define LIBXL_UTILS_H 13.21 + 13.22 +#include "libxl.h" 13.23 + 13.24 +#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" 13.25 + 13.26 +unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus); 13.27 +int libxl_name_to_domid(struct libxl_ctx *ctx, char *name, uint32_t *domid); 13.28 +char *libxl_domid_to_name(struct libxl_ctx *ctx, uint32_t domid); 13.29 +int libxl_uuid_to_domid(struct libxl_ctx *ctx, uint8_t *uuid, uint32_t *domid); 13.30 +int libxl_domid_to_uuid(struct libxl_ctx *ctx, uint8_t **uuid, uint32_t domid); 13.31 +int libxl_is_uuid(char *s); 13.32 +uint8_t *string_to_uuid(struct libxl_ctx *ctx, char *s); 13.33 +char *uuid_to_string(struct libxl_ctx *ctx, uint8_t *uuid); 13.34 +int libxl_param_to_domid(struct libxl_ctx *ctx, char *p, uint32_t *domid); 13.35 + 13.36 +#endif 13.37 +
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/tools/libxl/libxl_xshelp.c Mon Nov 09 19:54:28 2009 +0000 14.3 @@ -0,0 +1,108 @@ 14.4 +/* 14.5 + * Copyright (C) 2009 Citrix Ltd. 14.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 14.7 + * 14.8 + * This program is free software; you can redistribute it and/or modify 14.9 + * it under the terms of the GNU Lesser General Public License as published 14.10 + * by the Free Software Foundation; version 2.1 only. with the special 14.11 + * exception on linking described in file LICENSE. 14.12 + * 14.13 + * This program is distributed in the hope that it will be useful, 14.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.16 + * GNU Lesser General Public License for more details. 14.17 + */ 14.18 + 14.19 +#include <string.h> 14.20 +#include <stddef.h> 14.21 +#include "libxl.h" 14.22 +#include "libxl_internal.h" 14.23 +#include <stdio.h> 14.24 +#include <stdarg.h> 14.25 + 14.26 +char **libxl_xs_kvs_of_flexarray(struct libxl_ctx *ctx, flexarray_t *array, int length) 14.27 +{ 14.28 + char **kvs; 14.29 + int i; 14.30 + 14.31 + kvs = libxl_calloc(ctx, length + 2, sizeof(char *)); 14.32 + if (kvs) { 14.33 + for (i = 0; i < length; i += 2) { 14.34 + void *ptr; 14.35 + 14.36 + flexarray_get(array, i, &ptr); 14.37 + kvs[i] = (char *) ptr; 14.38 + flexarray_get(array, i + 1, &ptr); 14.39 + kvs[i + 1] = (char *) ptr; 14.40 + } 14.41 + kvs[i] = NULL; 14.42 + kvs[i + 1] = NULL; 14.43 + } 14.44 + return kvs; 14.45 +} 14.46 + 14.47 +int libxl_xs_writev(struct libxl_ctx *ctx, xs_transaction_t t, 14.48 + char *dir, char *kvs[]) 14.49 +{ 14.50 + char *path; 14.51 + int i; 14.52 + 14.53 + if (!kvs) 14.54 + return 0; 14.55 + 14.56 + for (i = 0; kvs[i] != NULL; i += 2) { 14.57 + path = libxl_sprintf(ctx, "%s/%s", dir, kvs[i]); 14.58 + if (path) { 14.59 + int length = strlen(kvs[i + 1]); 14.60 + xs_write(ctx->xsh, t, path, kvs[i + 1], length); 14.61 + } 14.62 + libxl_free(ctx, path); 14.63 + } 14.64 + return 0; 14.65 +} 14.66 + 14.67 +int libxl_xs_write(struct libxl_ctx *ctx, xs_transaction_t t, 14.68 + char *path, char *fmt, ...) 14.69 +{ 14.70 + char *s; 14.71 + va_list ap; 14.72 + int ret; 14.73 + va_start(ap, fmt); 14.74 + ret = vasprintf(&s, fmt, ap); 14.75 + va_end(ap); 14.76 + 14.77 + if (ret == -1) { 14.78 + return -1; 14.79 + } 14.80 + xs_write(ctx->xsh, t, path, s, ret); 14.81 + free(s); 14.82 + return 0; 14.83 +} 14.84 + 14.85 +char * libxl_xs_read(struct libxl_ctx *ctx, xs_transaction_t t, char *path) 14.86 +{ 14.87 + unsigned int len; 14.88 + char *ptr; 14.89 + 14.90 + ptr = xs_read(ctx->xsh, t, path, &len); 14.91 + if (ptr != NULL) { 14.92 + libxl_ptr_add(ctx, ptr); 14.93 + return ptr; 14.94 + } 14.95 + return 0; 14.96 +} 14.97 + 14.98 +char *libxl_xs_get_dompath(struct libxl_ctx *ctx, uint32_t domid) 14.99 +{ 14.100 + char *s = xs_get_domain_path(ctx->xsh, domid); 14.101 + libxl_ptr_add(ctx, s); 14.102 + return s; 14.103 +} 14.104 + 14.105 +char **libxl_xs_directory(struct libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb) 14.106 +{ 14.107 + char **ret = NULL; 14.108 + ret = xs_directory(ctx->xsh, XBT_NULL, path, nb); 14.109 + libxl_ptr_add(ctx, ret); 14.110 + return ret; 14.111 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/tools/libxl/osdeps.c Mon Nov 09 19:54:28 2009 +0000 15.3 @@ -0,0 +1,62 @@ 15.4 +/* 15.5 + * Copyright (C) 2009 Citrix Ltd. 15.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 15.7 + * 15.8 + * This program is free software; you can redistribute it and/or modify 15.9 + * it under the terms of the GNU Lesser General Public License as published 15.10 + * by the Free Software Foundation; version 2.1 only. with the special 15.11 + * exception on linking described in file LICENSE. 15.12 + * 15.13 + * This program is distributed in the hope that it will be useful, 15.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15.16 + * GNU Lesser General Public License for more details. 15.17 + */ 15.18 + 15.19 +#include <unistd.h> 15.20 +#include <stdarg.h> 15.21 +#include <stdio.h> 15.22 +#include <sys/time.h> 15.23 +#include <stdlib.h> 15.24 + 15.25 +int vasprintf(char **buffer, const char *fmt, va_list ap) 15.26 +{ 15.27 + int size = 0; 15.28 + int nchars; 15.29 + 15.30 + *buffer = 0; 15.31 + 15.32 + nchars = vsnprintf(*buffer, 0, fmt, ap); 15.33 + 15.34 + if (nchars >= size) 15.35 + { 15.36 + char *tmpbuff; 15.37 + /* Reallocate buffer now that we know how much space is needed. */ 15.38 + size = nchars+1; 15.39 + tmpbuff = (char*)realloc(*buffer, size); 15.40 + 15.41 + 15.42 + if (tmpbuff == NULL) { /* we need to free it*/ 15.43 + free(*buffer); 15.44 + return -1; 15.45 + } 15.46 + 15.47 + *buffer=tmpbuff; 15.48 + /* Try again. */ 15.49 + nchars = vsnprintf(*buffer, size, fmt, ap); 15.50 + } 15.51 + 15.52 + if (nchars < 0) return nchars; 15.53 + return size; 15.54 +} 15.55 + 15.56 +int asprintf(char **buffer, char *fmt, ...) 15.57 +{ 15.58 + int status; 15.59 + va_list ap; 15.60 + 15.61 + va_start (ap, fmt); 15.62 + status = vasprintf (buffer, fmt, ap); 15.63 + va_end (ap); 15.64 + return status; 15.65 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/tools/libxl/osdeps.h Mon Nov 09 19:54:28 2009 +0000 16.3 @@ -0,0 +1,24 @@ 16.4 +/* 16.5 + * Copyright (C) 2009 Citrix Ltd. 16.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 16.7 + * 16.8 + * This program is free software; you can redistribute it and/or modify 16.9 + * it under the terms of the GNU Lesser General Public License as published 16.10 + * by the Free Software Foundation; version 2.1 only. with the special 16.11 + * exception on linking described in file LICENSE. 16.12 + * 16.13 + * This program is distributed in the hope that it will be useful, 16.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16.16 + * GNU Lesser General Public License for more details. 16.17 + */ 16.18 + 16.19 +#ifndef LIBXL_OSDEP 16.20 +#define LIBXL_OSDEP 16.21 + 16.22 +#include <stdarg.h> 16.23 + 16.24 +int asprintf(char **buffer, char *fmt, ...); 16.25 +int vasprintf(char **buffer, const char *fmt, va_list ap); 16.26 + 16.27 +#endif
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/tools/libxl/xenguest.c Mon Nov 09 19:54:28 2009 +0000 17.3 @@ -0,0 +1,49 @@ 17.4 +/* 17.5 + * Copyright (C) 2009 Citrix Ltd. 17.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 17.7 + * 17.8 + * This program is free software; you can redistribute it and/or modify 17.9 + * it under the terms of the GNU Lesser General Public License as published 17.10 + * by the Free Software Foundation; version 2.1 only. with the special 17.11 + * exception on linking described in file LICENSE. 17.12 + * 17.13 + * This program is distributed in the hope that it will be useful, 17.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 17.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.16 + * GNU Lesser General Public License for more details. 17.17 + */ 17.18 + 17.19 +#include <xenctrl.h> 17.20 +#include <xenguest.h> 17.21 +#include <sys/mman.h> 17.22 +#include <xen/hvm/hvm_info_table.h> 17.23 + 17.24 +int hvm_build_set_params(int handle, uint32_t domid, 17.25 + int apic, int acpi, int pae, int nx, int viridian, 17.26 + int vcpus, int store_evtchn, unsigned long *store_mfn) 17.27 +{ 17.28 + struct hvm_info_table *va_hvm; 17.29 + uint8_t *va_map, sum; 17.30 + int i; 17.31 + 17.32 + va_map = xc_map_foreign_range(handle, domid, 17.33 + XC_PAGE_SIZE, PROT_READ | PROT_WRITE, 17.34 + HVM_INFO_PFN); 17.35 + if (va_map == NULL) 17.36 + return -1; 17.37 + 17.38 + va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET); 17.39 + va_hvm->acpi_enabled = acpi; 17.40 + va_hvm->apic_mode = apic; 17.41 + va_hvm->nr_vcpus = vcpus; 17.42 + for (i = 0, sum = 0; i < va_hvm->length; i++) 17.43 + sum += ((uint8_t *) va_hvm)[i]; 17.44 + va_hvm->checksum -= sum; 17.45 + munmap(va_map, XC_PAGE_SIZE); 17.46 + 17.47 + xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn); 17.48 + xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, pae); 17.49 + xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, viridian); 17.50 + xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn); 17.51 + return 0; 17.52 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/tools/libxl/xl.c Mon Nov 09 19:54:28 2009 +0000 18.3 @@ -0,0 +1,727 @@ 18.4 +/* 18.5 + * Copyright (C) 2009 Citrix Ltd. 18.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 18.7 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 18.8 + * 18.9 + * This program is free software; you can redistribute it and/or modify 18.10 + * it under the terms of the GNU Lesser General Public License as published 18.11 + * by the Free Software Foundation; version 2.1 only. with the special 18.12 + * exception on linking described in file LICENSE. 18.13 + * 18.14 + * This program is distributed in the hope that it will be useful, 18.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18.17 + * GNU Lesser General Public License for more details. 18.18 + */ 18.19 + 18.20 +#include "libxl.h" 18.21 +#include "libxl_utils.h" 18.22 +#include <stdio.h> 18.23 +#include <stdlib.h> 18.24 +#include <string.h> 18.25 +#include <uuid/uuid.h> 18.26 +#include <libconfig.h> 18.27 +#include <unistd.h> 18.28 +#include <getopt.h> 18.29 +#include <sys/types.h> 18.30 +#include <sys/socket.h> 18.31 +#include <arpa/inet.h> 18.32 +#include <xenctrl.h> 18.33 + 18.34 +void log_callback(void *userdata, int loglevel, const char *file, int line, const char *func, char *s) 18.35 +{ 18.36 + fprintf(stderr, "[%d] %s:%d:%s: %s\n", loglevel, file, line, func, s); 18.37 +} 18.38 + 18.39 +static void printf_info(libxl_domain_create_info *c_info, 18.40 + libxl_domain_build_info *b_info, 18.41 + libxl_device_disk *disks, 18.42 + int num_disks, 18.43 + libxl_device_nic *vifs, 18.44 + int num_vifs, 18.45 + libxl_device_model_info *dm_info) 18.46 +{ 18.47 + int i; 18.48 + printf("*** domain_create_info ***\n"); 18.49 + printf("hvm: %d\n", c_info->hvm); 18.50 + printf("hap: %d\n", c_info->hap); 18.51 + printf("ssidref: %d\n", c_info->ssidref); 18.52 + printf("name: %s\n", c_info->name); 18.53 + printf("uuid: " UUID_FMT "\n", c_info->uuid[0], c_info->uuid[1], c_info->uuid[2], c_info->uuid[3], 18.54 + c_info->uuid[4], c_info->uuid[5], c_info->uuid[6], c_info->uuid[7], 18.55 + c_info->uuid[8], c_info->uuid[9], c_info->uuid[10], c_info->uuid[11], 18.56 + c_info->uuid[12], c_info->uuid[13], c_info->uuid[14], c_info->uuid[15]); 18.57 + if (c_info->xsdata) 18.58 + printf("xsdata: contains data\n"); 18.59 + else 18.60 + printf("xsdata: (null)\n"); 18.61 + if (c_info->platformdata) 18.62 + printf("platformdata: contains data\n"); 18.63 + else 18.64 + printf("platformdata: (null)\n"); 18.65 + 18.66 + 18.67 + printf("\n\n\n*** domain_build_info ***\n"); 18.68 + printf("timer_mode: %d\n", b_info->timer_mode); 18.69 + printf("hpet: %d\n", b_info->hpet); 18.70 + printf("vpt_align: %d\n", b_info->vpt_align); 18.71 + printf("max_vcpus: %d\n", b_info->max_vcpus); 18.72 + printf("max_memkb: %d\n", b_info->max_memkb); 18.73 + printf("video_memkb: %d\n", b_info->video_memkb); 18.74 + printf("shadow_memkb: %d\n", b_info->shadow_memkb); 18.75 + printf("kernel: %s\n", b_info->kernel); 18.76 + printf("hvm: %d\n", b_info->hvm); 18.77 + 18.78 + if (b_info->hvm) { 18.79 + printf(" pae: %d\n", b_info->u.hvm.pae); 18.80 + printf(" apic: %d\n", b_info->u.hvm.apic); 18.81 + printf(" acpi: %d\n", b_info->u.hvm.acpi); 18.82 + printf(" nx: %d\n", b_info->u.hvm.nx); 18.83 + printf(" viridian: %d\n", b_info->u.hvm.viridian); 18.84 + } else { 18.85 + printf("cmdline: %s\n", b_info->u.pv.cmdline); 18.86 + printf("ramdisk: %s\n", b_info->u.pv.ramdisk); 18.87 + } 18.88 + 18.89 + for (i = 0; i < num_disks; i++) { 18.90 + printf("\n\n\n*** disks_info: %d ***\n", i); 18.91 + printf("backend_domid %d\n", disks[i].backend_domid); 18.92 + printf("domid %d\n", disks[i].domid); 18.93 + printf("physpath %s\n", disks[i].physpath); 18.94 + printf("phystype %d\n", disks[i].phystype); 18.95 + printf("virtpath %s\n", disks[i].virtpath); 18.96 + printf("unpluggable %d\n", disks[i].unpluggable); 18.97 + printf("readwrite %d\n", disks[i].readwrite); 18.98 + printf("is_cdrom %d\n", disks[i].is_cdrom); 18.99 + } 18.100 + 18.101 + for (i = 0; i < num_vifs; i++) { 18.102 + printf("\n\n\n*** vifs_info: %d ***\n", i); 18.103 + printf("backend_domid %d\n", vifs[i].backend_domid); 18.104 + printf("domid %d\n", vifs[i].domid); 18.105 + printf("devid %d\n", vifs[i].devid); 18.106 + printf("mtu %d\n", vifs[i].mtu); 18.107 + printf("model %s\n", vifs[i].model); 18.108 + printf("mac %02x:%02x:%02x:%02x:%02x:%02x\n", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); 18.109 + printf("smac %s\n", vifs[i].mac); 18.110 + } 18.111 + 18.112 + printf("\n\n\n*** device_model_info ***\n"); 18.113 + printf("domid: %d\n", dm_info->domid); 18.114 + printf("dom_name: %s\n", dm_info->dom_name); 18.115 + printf("device_model: %s\n", dm_info->device_model); 18.116 + printf("videoram: %d\n", dm_info->videoram); 18.117 + printf("stdvga: %d\n", dm_info->stdvga); 18.118 + printf("vnc: %d\n", dm_info->vnc); 18.119 + printf("vnclisten: %s\n", dm_info->vnclisten); 18.120 + printf("vncdisplay: %d\n", dm_info->vncdisplay); 18.121 + printf("vncunused: %d\n", dm_info->vncunused); 18.122 + printf("keymap: %s\n", dm_info->keymap); 18.123 + printf("sdl: %d\n", dm_info->sdl); 18.124 + printf("opengl: %d\n", dm_info->opengl); 18.125 + printf("nographic: %d\n", dm_info->nographic); 18.126 + printf("serial: %s\n", dm_info->serial); 18.127 + printf("boot: %s\n", dm_info->boot); 18.128 + printf("usb: %d\n", dm_info->usb); 18.129 + printf("usbdevice: %s\n", dm_info->usbdevice); 18.130 + printf("apic: %d\n", dm_info->apic); 18.131 +} 18.132 + 18.133 +static char* compat_config_file(const char *filename) 18.134 +{ 18.135 + char t; 18.136 + char *newfile = (char*) malloc(strlen(filename) + 4); 18.137 + char *buf = (char *) malloc(2048); 18.138 + int size = 2048, i; 18.139 + FILE *s; 18.140 + FILE *d; 18.141 + 18.142 + sprintf(newfile, "%s.xl", filename); 18.143 + 18.144 + s = fopen(filename, "r"); 18.145 + if (!s) { 18.146 + perror("cannot open file for reading"); 18.147 + return NULL; 18.148 + } 18.149 + d = fopen(newfile, "w"); 18.150 + if (!d) { 18.151 + fclose(s); 18.152 + perror("cannot open file for writting"); 18.153 + return NULL; 18.154 + } 18.155 + 18.156 + while (!feof(s)) { 18.157 + fgets(buf, size, s); 18.158 + while (buf[strlen(buf) - 1] != '\n' && !feof(s)) { 18.159 + size += 1024; 18.160 + buf = realloc(buf, size + 1024); 18.161 + fgets(buf + (size - 1025), 1025, s); 18.162 + } 18.163 + for (i = 0; i < strlen(buf); i++) 18.164 + if (buf[i] == '\'') 18.165 + buf[i] = '\"'; 18.166 + if (strchr(buf, '=') != NULL) { 18.167 + if ((buf[strlen(buf) - 1] == '\n' && buf[strlen(buf) - 2] == ';') || 18.168 + buf[strlen(buf) - 1] == ';') { 18.169 + fputs(buf, d); 18.170 + } else { 18.171 + t = buf[strlen(buf) - 1]; 18.172 + buf[strlen(buf) - 1] = ';'; 18.173 + fputs(buf, d); 18.174 + fputc(t, d); 18.175 + } 18.176 + } else if (buf[0] == '#' || buf[0] == ' ' || buf[0] == '\n') { 18.177 + fputs(buf, d); 18.178 + } 18.179 + } 18.180 + 18.181 + fclose(s); 18.182 + fclose(d); 18.183 + 18.184 + free(buf); 18.185 + 18.186 + return newfile; 18.187 +} 18.188 + 18.189 +void init_create_info(libxl_domain_create_info *c_info) 18.190 +{ 18.191 + memset(c_info, '\0', sizeof(*c_info)); 18.192 + c_info->xsdata = NULL; 18.193 + c_info->platformdata = NULL; 18.194 + c_info->hvm = 1; 18.195 + c_info->ssidref = 0; 18.196 +} 18.197 + 18.198 +void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info) 18.199 +{ 18.200 + memset(b_info, '\0', sizeof(*b_info)); 18.201 + b_info->timer_mode = -1; 18.202 + b_info->hpet = 1; 18.203 + b_info->vpt_align = -1; 18.204 + b_info->max_vcpus = 1; 18.205 + b_info->max_memkb = 32 * 1024; 18.206 + b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus); 18.207 + b_info->video_memkb = 8 * 1024; 18.208 + b_info->kernel = "/usr/lib/xen/boot/hvmloader"; 18.209 + if (c_info->hvm) { 18.210 + b_info->hvm = 1; 18.211 + b_info->u.hvm.pae = 1; 18.212 + b_info->u.hvm.apic = 1; 18.213 + b_info->u.hvm.acpi = 1; 18.214 + b_info->u.hvm.nx = 1; 18.215 + b_info->u.hvm.viridian = 0; 18.216 + } 18.217 +} 18.218 + 18.219 +void init_dm_info(libxl_device_model_info *dm_info, 18.220 + libxl_domain_create_info *c_info, libxl_domain_build_info *b_info) 18.221 +{ 18.222 + memset(dm_info, '\0', sizeof(*dm_info)); 18.223 + 18.224 + dm_info->dom_name = c_info->name; 18.225 + dm_info->device_model = "/usr/lib/xen/bin/qemu-dm"; 18.226 + dm_info->videoram = b_info->video_memkb / 1024; 18.227 + dm_info->apic = b_info->u.hvm.apic; 18.228 + 18.229 + dm_info->stdvga = 0; 18.230 + dm_info->vnc = 1; 18.231 + dm_info->vnclisten = "127.0.0.1"; 18.232 + dm_info->vncdisplay = 0; 18.233 + dm_info->vncunused = 0; 18.234 + dm_info->keymap = NULL; 18.235 + dm_info->sdl = 0; 18.236 + dm_info->opengl = 0; 18.237 + dm_info->nographic = 0; 18.238 + dm_info->serial = NULL; 18.239 + dm_info->boot = "cda"; 18.240 + dm_info->usb = 0; 18.241 + dm_info->usbdevice = NULL; 18.242 +} 18.243 + 18.244 +void init_nic_info(libxl_device_nic *nic_info, int devnum) 18.245 +{ 18.246 + memset(nic_info, '\0', sizeof(*nic_info)); 18.247 + 18.248 + 18.249 + nic_info->backend_domid = 0; 18.250 + nic_info->domid = 0; 18.251 + nic_info->devid = devnum; 18.252 + nic_info->mtu = 1492; 18.253 + nic_info->model = "e1000"; 18.254 + srand(time(0)); 18.255 + nic_info->mac[0] = 0x00; 18.256 + nic_info->mac[1] = 0x16; 18.257 + nic_info->mac[2] = 0x3e; 18.258 + nic_info->mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0))); 18.259 + nic_info->mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0))); 18.260 + nic_info->mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0))); 18.261 + asprintf(&(nic_info->smac), "%02x:%02x:%02x:%02x:%02x:%02x", nic_info->mac[0], nic_info->mac[1], nic_info->mac[2], nic_info->mac[3], nic_info->mac[4], nic_info->mac[5]); 18.262 + nic_info->ifname = NULL; 18.263 + nic_info->bridge = "xenbr0"; 18.264 + nic_info->script = "/etc/xen/scripts/vif-bridge"; 18.265 + nic_info->nictype = NICTYPE_IOEMU; 18.266 +} 18.267 + 18.268 +void nic_info_domid_fixup(libxl_device_nic *nic_info, int domid) 18.269 +{ 18.270 + nic_info->domid = domid; 18.271 + if (!nic_info->ifname) 18.272 + asprintf(&(nic_info->ifname), "tap%d.%d", domid, nic_info->devid - 1); 18.273 +} 18.274 + 18.275 +void disk_info_domid_fixup(libxl_device_disk *disk_info, int domid) 18.276 +{ 18.277 + disk_info->domid = domid; 18.278 +} 18.279 + 18.280 +void device_model_info_domid_fixup(libxl_device_model_info *dm_info, int domid) 18.281 +{ 18.282 + dm_info->domid = domid; 18.283 +} 18.284 + 18.285 +static void parse_config_file(const char *filename, 18.286 + libxl_domain_create_info *c_info, 18.287 + libxl_domain_build_info *b_info, 18.288 + libxl_device_disk **disks, 18.289 + int *num_disks, 18.290 + libxl_device_nic **vifs, 18.291 + int *num_vifs, 18.292 + libxl_device_model_info *dm_info) 18.293 +{ 18.294 + const char *buf; 18.295 + uint8_t uuid[16]; 18.296 + long l; 18.297 + struct config_t config; 18.298 + struct config_setting_t *vbds, *nics; 18.299 + 18.300 + config_init (&config); 18.301 + 18.302 + if (!config_read_file(&config, filename)) { 18.303 + char *newfilename; 18.304 + config_destroy(&config); 18.305 + newfilename = compat_config_file(filename); 18.306 + config_init (&config); 18.307 + if (!config_read_file(&config, newfilename)) { 18.308 + fprintf(stderr, "Failed to parse config file %s, try removing any embedded python code\n", config_error_text(&config)); 18.309 + exit(1); 18.310 + } 18.311 + free(newfilename); 18.312 + } 18.313 + 18.314 + init_create_info(c_info); 18.315 + 18.316 + if (config_lookup_string (&config, "builder", &buf) == CONFIG_TRUE) { 18.317 + if (!strncmp(buf, "hvm", strlen(buf))) 18.318 + c_info->hvm = 1; 18.319 + else 18.320 + c_info->hvm = 0; 18.321 + } 18.322 + 18.323 + /* hap is missing */ 18.324 + if (config_lookup_string (&config, "name", &buf) == CONFIG_TRUE) 18.325 + c_info->name = strdup(buf); 18.326 + else 18.327 + c_info->name = "test"; 18.328 + uuid_generate(uuid); 18.329 + c_info->uuid = uuid; 18.330 + 18.331 + init_build_info(b_info, c_info); 18.332 + 18.333 + /* the following is the actual config parsing with overriding values in the structures */ 18.334 + if (config_lookup_int (&config, "vcpus", &l) == CONFIG_TRUE) 18.335 + b_info->max_vcpus = l; 18.336 + 18.337 + if (config_lookup_int (&config, "memory", &l) == CONFIG_TRUE) 18.338 + b_info->max_memkb = l * 1024; 18.339 + 18.340 + if (config_lookup_int (&config, "shadow_memory", &l) == CONFIG_TRUE) 18.341 + b_info->shadow_memkb = l * 1024; 18.342 + 18.343 + if (config_lookup_int (&config, "videoram", &l) == CONFIG_TRUE) 18.344 + b_info->video_memkb = l * 1024; 18.345 + 18.346 + if (config_lookup_string (&config, "kernel", &buf) == CONFIG_TRUE) 18.347 + b_info->kernel = strdup(buf); 18.348 + 18.349 + if (c_info->hvm == 1) { 18.350 + if (config_lookup_int (&config, "pae", &l) == CONFIG_TRUE) 18.351 + b_info->u.hvm.pae = l; 18.352 + if (config_lookup_int (&config, "apic", &l) == CONFIG_TRUE) 18.353 + b_info->u.hvm.apic = l; 18.354 + if (config_lookup_int (&config, "acpi", &l) == CONFIG_TRUE) 18.355 + b_info->u.hvm.acpi = l; 18.356 + if (config_lookup_int (&config, "nx", &l) == CONFIG_TRUE) 18.357 + b_info->u.hvm.nx = l; 18.358 + if (config_lookup_int (&config, "viridian", &l) == CONFIG_TRUE) 18.359 + b_info->u.hvm.viridian = l; 18.360 + } else { 18.361 + if (config_lookup_string (&config, "cmdline", &buf) == CONFIG_TRUE) 18.362 + b_info->u.pv.cmdline = buf; 18.363 + if (config_lookup_string (&config, "ramdisk", &buf) == CONFIG_TRUE) 18.364 + b_info->u.pv.ramdisk = buf; 18.365 + } 18.366 + 18.367 + if ((vbds = config_lookup (&config, "disk")) != NULL) { 18.368 + *num_disks = 0; 18.369 + *disks = NULL; 18.370 + while ((buf = config_setting_get_string_elem (vbds, *num_disks)) != NULL) { 18.371 + char *buf2 = strdup(buf); 18.372 + char *p, *p2; 18.373 + *disks = (libxl_device_disk *) realloc(*disks, sizeof (libxl_device_disk) * ((*num_disks) + 1)); 18.374 + (*disks)[*num_disks].backend_domid = 0; 18.375 + (*disks)[*num_disks].domid = 0; 18.376 + (*disks)[*num_disks].unpluggable = 0; 18.377 + p = strtok(buf2, ",:"); 18.378 + while (*p == ' ') 18.379 + p++; 18.380 + if (!strcmp(p, "phy")) { 18.381 + (*disks)[*num_disks].phystype = PHYSTYPE_PHY; 18.382 + } else if (!strcmp(p, "file")) { 18.383 + (*disks)[*num_disks].phystype = PHYSTYPE_FILE; 18.384 + } else if (!strcmp(p, "tap")) { 18.385 + p = strtok(NULL, ":"); 18.386 + if (!strcmp(p, "aio")) { 18.387 + (*disks)[*num_disks].phystype = PHYSTYPE_AIO; 18.388 + } else if (!strcmp(p, "vhd")) { 18.389 + (*disks)[*num_disks].phystype = PHYSTYPE_VHD; 18.390 + } else if (!strcmp(p, "qcow")) { 18.391 + (*disks)[*num_disks].phystype = PHYSTYPE_QCOW; 18.392 + } else if (!strcmp(p, "qcow2")) { 18.393 + (*disks)[*num_disks].phystype = PHYSTYPE_QCOW2; 18.394 + } 18.395 + } 18.396 + p = strtok(NULL, ","); 18.397 + while (*p == ' ') 18.398 + p++; 18.399 + (*disks)[*num_disks].physpath= strdup(p); 18.400 + p = strtok(NULL, ","); 18.401 + while (*p == ' ') 18.402 + p++; 18.403 + p2 = strchr(p, ':'); 18.404 + if (p2 == NULL) { 18.405 + (*disks)[*num_disks].virtpath = strdup(p); 18.406 + (*disks)[*num_disks].is_cdrom = 0; 18.407 + } else { 18.408 + *p2 = '\0'; 18.409 + (*disks)[*num_disks].virtpath = strdup(p); 18.410 + if (!strcmp(p2 + 1, "cdrom")) 18.411 + (*disks)[*num_disks].is_cdrom = 1; 18.412 + else 18.413 + (*disks)[*num_disks].is_cdrom = 0; 18.414 + } 18.415 + p = strtok(NULL, ","); 18.416 + while (*p == ' ') 18.417 + p++; 18.418 + (*disks)[*num_disks].readwrite = (p[0] == 'w') ? 1 : 0; 18.419 + free(buf2); 18.420 + *num_disks = (*num_disks) + 1; 18.421 + } 18.422 + } 18.423 + 18.424 + if ((nics = config_lookup (&config, "vif")) != NULL) { 18.425 + *num_vifs = 0; 18.426 + *vifs = NULL; 18.427 + while ((buf = config_setting_get_string_elem (nics, *num_vifs)) != NULL) { 18.428 + char *buf2 = strdup(buf); 18.429 + char *p, *p2; 18.430 + *vifs = (libxl_device_nic *) realloc(*vifs, sizeof (libxl_device_nic) * ((*num_vifs) + 1)); 18.431 + init_nic_info((*vifs) + (*num_vifs), (*num_vifs) + 1); 18.432 + p = strtok(buf2, ","); 18.433 + if (!p) 18.434 + goto skip; 18.435 + do { 18.436 + while (*p == ' ') 18.437 + p++; 18.438 + if ((p2 = strchr(p, '=')) == NULL) 18.439 + break; 18.440 + *p2 = '\0'; 18.441 + if (!strcmp(p, "model")) { 18.442 + (*vifs)[*num_vifs].model = strdup(p2 + 1); 18.443 + } else if (!strcmp(p, "mac")) { 18.444 + char *p3 = p2 + 1; 18.445 + (*vifs)[*num_vifs].smac = strdup(p3); 18.446 + *(p3 + 2) = '\0'; 18.447 + (*vifs)[*num_vifs].mac[0] = strtol(p3, NULL, 16); 18.448 + p3 = p3 + 3; 18.449 + *(p3 + 2) = '\0'; 18.450 + (*vifs)[*num_vifs].mac[1] = strtol(p3, NULL, 16); 18.451 + p3 = p3 + 3; 18.452 + *(p3 + 2) = '\0'; 18.453 + (*vifs)[*num_vifs].mac[2] = strtol(p3, NULL, 16); 18.454 + p3 = p3 + 3; 18.455 + *(p3 + 2) = '\0'; 18.456 + (*vifs)[*num_vifs].mac[3] = strtol(p3, NULL, 16); 18.457 + p3 = p3 + 3; 18.458 + *(p3 + 2) = '\0'; 18.459 + (*vifs)[*num_vifs].mac[4] = strtol(p3, NULL, 16); 18.460 + p3 = p3 + 3; 18.461 + *(p3 + 2) = '\0'; 18.462 + (*vifs)[*num_vifs].mac[5] = strtol(p3, NULL, 16); 18.463 + } else if (!strcmp(p, "bridge")) { 18.464 + (*vifs)[*num_vifs].bridge = strdup(p2 + 1); 18.465 + } else if (!strcmp(p, "type")) { 18.466 + if (!strcmp(p2 + 1, "ioemu")) 18.467 + (*vifs)[*num_vifs].nictype = NICTYPE_IOEMU; 18.468 + else 18.469 + (*vifs)[*num_vifs].nictype = NICTYPE_VIF; 18.470 + } else if (!strcmp(p, "ip")) { 18.471 + inet_pton(AF_INET, p2 + 1, &((*vifs)[*num_vifs].ip)); 18.472 + } else if (!strcmp(p, "script")) { 18.473 + (*vifs)[*num_vifs].script = strdup(p2 + 1); 18.474 + } else if (!strcmp(p, "vifname")) { 18.475 + (*vifs)[*num_vifs].ifname = strdup(p2 + 1); 18.476 + } else if (!strcmp(p, "rate")) { 18.477 + fprintf(stderr, "the rate parameter for vifs is currently not supported\n"); 18.478 + } else if (!strcmp(p, "accel")) { 18.479 + fprintf(stderr, "the accel parameter for vifs is currently not supported\n"); 18.480 + } 18.481 + } while ((p = strtok(NULL, ",")) != NULL); 18.482 +skip: 18.483 + free(buf2); 18.484 + *num_vifs = (*num_vifs) + 1; 18.485 + } 18.486 + } 18.487 + 18.488 + /* init dm from c and b */ 18.489 + init_dm_info(dm_info, c_info, b_info); 18.490 + 18.491 + /* then process config related to dm */ 18.492 + if (config_lookup_string (&config, "device_model", &buf) == CONFIG_TRUE) 18.493 + dm_info->device_model = strdup(buf); 18.494 + if (config_lookup_int (&config, "stdvga", &l) == CONFIG_TRUE) 18.495 + dm_info->stdvga = l; 18.496 + if (config_lookup_int (&config, "vnc", &l) == CONFIG_TRUE) 18.497 + dm_info->vnc = l; 18.498 + if (config_lookup_string (&config, "vnclisten", &buf) == CONFIG_TRUE) 18.499 + dm_info->vnclisten = strdup(buf); 18.500 + if (config_lookup_int (&config, "vncdisplay", &l) == CONFIG_TRUE) 18.501 + dm_info->vncdisplay = l; 18.502 + if (config_lookup_int (&config, "vncunused", &l) == CONFIG_TRUE) 18.503 + dm_info->vncunused = l; 18.504 + if (config_lookup_string (&config, "keymap", &buf) == CONFIG_TRUE) 18.505 + dm_info->keymap = strdup(buf); 18.506 + if (config_lookup_int (&config, "sdl", &l) == CONFIG_TRUE) 18.507 + dm_info->sdl = l; 18.508 + if (config_lookup_int (&config, "opengl", &l) == CONFIG_TRUE) 18.509 + dm_info->opengl = l; 18.510 + if (config_lookup_int (&config, "nographic", &l) == CONFIG_TRUE) 18.511 + dm_info->nographic = l; 18.512 + if (config_lookup_string (&config, "serial", &buf) == CONFIG_TRUE) 18.513 + dm_info->serial = strdup(buf); 18.514 + if (config_lookup_string (&config, "boot", &buf) == CONFIG_TRUE) 18.515 + dm_info->boot = strdup(buf); 18.516 + if (config_lookup_int (&config, "usb", &l) == CONFIG_TRUE) 18.517 + dm_info->usb = l; 18.518 + if (config_lookup_string (&config, "usbdevice", &buf) == CONFIG_TRUE) 18.519 + dm_info->usbdevice = strdup(buf); 18.520 + 18.521 + config_destroy(&config); 18.522 +} 18.523 + 18.524 +static void create_domain(int debug, const char *filename) 18.525 +{ 18.526 + struct libxl_ctx ctx; 18.527 + uint32_t domid; 18.528 + libxl_domain_create_info info1; 18.529 + libxl_domain_build_info info2; 18.530 + libxl_device_model_info dm_info; 18.531 + libxl_device_disk *disks = NULL; 18.532 + libxl_device_nic *vifs = NULL; 18.533 + int num_disks = 0, num_vifs = 0; 18.534 + int i; 18.535 + 18.536 + printf("Parsing config file %s\n", filename); 18.537 + parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &dm_info); 18.538 + if (debug) 18.539 + printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, &dm_info); 18.540 + 18.541 + libxl_ctx_init(&ctx); 18.542 + libxl_ctx_set_log(&ctx, log_callback, NULL); 18.543 + libxl_domain_make(&ctx, &info1, &domid); 18.544 + libxl_domain_build(&ctx, &info2, domid); 18.545 + 18.546 + device_model_info_domid_fixup(&dm_info, domid); 18.547 + 18.548 + for (i = 0; i < num_disks; i++) { 18.549 + disk_info_domid_fixup(disks + i, domid); 18.550 + libxl_device_disk_add(&ctx, domid, &disks[i]); 18.551 + } 18.552 + for (i = 0; i < num_vifs; i++) { 18.553 + nic_info_domid_fixup(vifs + i, domid); 18.554 + libxl_device_nic_add(&ctx, domid, &vifs[i]); 18.555 + } 18.556 + libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs); 18.557 + libxl_domain_unpause(&ctx, domid); 18.558 + 18.559 +} 18.560 + 18.561 +static void help(char *command) 18.562 +{ 18.563 + if (!command || !strcmp(command, "help")) { 18.564 + printf("Usage xl <subcommand> [args]\n\n"); 18.565 + printf("xl full list of subcommands:\n\n"); 18.566 + printf(" create create a domain from config file <filename>\n\n"); 18.567 + printf(" list list information about all domains\n\n"); 18.568 + printf(" destroy terminate a domain immediately\n\n"); 18.569 + } else if(!strcmp(command, "create")) { 18.570 + printf("Usage: xl create <ConfigFile> [options] [vars]\n\n"); 18.571 + printf("Create a domain based on <ConfigFile>.\n\n"); 18.572 + printf("Options:\n\n"); 18.573 + printf("-h Print this help.\n"); 18.574 + printf("-d Enable debug messages.\n"); 18.575 + } else if(!strcmp(command, "list")) { 18.576 + printf("Usage: xl list [Domain]\n\n"); 18.577 + printf("List information about all/some domains.\n\n"); 18.578 + } else if(!strcmp(command, "destroy")) { 18.579 + printf("Usage: xl destroy <Domain>\n\n"); 18.580 + printf("Terminate a domain immediately.\n\n"); 18.581 + } 18.582 +} 18.583 + 18.584 +void destroy_domain(char *p) 18.585 +{ 18.586 + struct libxl_ctx ctx; 18.587 + uint32_t domid; 18.588 + 18.589 + libxl_ctx_init(&ctx); 18.590 + libxl_ctx_set_log(&ctx, log_callback, NULL); 18.591 + 18.592 + if (libxl_param_to_domid(&ctx, p, &domid) < 0) { 18.593 + fprintf(stderr, "%s is an invalid domain identifier\n", p); 18.594 + exit(2); 18.595 + } 18.596 + libxl_domain_destroy(&ctx, domid, 0); 18.597 +} 18.598 + 18.599 +void list_domains(void) 18.600 +{ 18.601 + struct libxl_ctx ctx; 18.602 + xc_dominfo_t *info; 18.603 + int nb_domain, i; 18.604 + 18.605 + libxl_ctx_init(&ctx); 18.606 + libxl_ctx_set_log(&ctx, log_callback, NULL); 18.607 + 18.608 + info = libxl_domain_infolist(&ctx, &nb_domain); 18.609 + 18.610 + if (info < 0) { 18.611 + fprintf(stderr, "libxl_domain_infolist failed.\n"); 18.612 + exit(1); 18.613 + } 18.614 + printf("Name ID Mem VCPUs\tState\tTime(s)\n"); 18.615 + for (i = 0; i < nb_domain; i++) { 18.616 + printf("%-40s %5d %5lu %5d %c%c%c%c%c%c %8.1f\n", 18.617 + libxl_domid_to_name(&ctx, info[i].domid), 18.618 + info[i].domid, 18.619 + info[i].nr_pages * XC_PAGE_SIZE/(1024*1024), 18.620 + info[i].nr_online_vcpus, 18.621 + info[i].running ? 'r' : '-', 18.622 + info[i].blocked ? 'b' : '-', 18.623 + info[i].paused ? 'p' : '-', 18.624 + info[i].shutdown ? 's' : '-', 18.625 + info[i].crashed ? 'c' : '-', 18.626 + info[i].dying ? 'd' : '-', 18.627 + ((float)info[i].cpu_time / 1e9)); 18.628 + } 18.629 +} 18.630 + 18.631 +int main_destroy(int argc, char **argv) 18.632 +{ 18.633 + int opt; 18.634 + char *p; 18.635 + 18.636 + while ((opt = getopt(argc, argv, "h")) != -1) { 18.637 + switch (opt) { 18.638 + case 'h': 18.639 + help("destroy"); 18.640 + exit(0); 18.641 + default: 18.642 + fprintf(stderr, "option not supported\n"); 18.643 + break; 18.644 + } 18.645 + } 18.646 + if (optind >= argc) { 18.647 + help("destroy"); 18.648 + exit(2); 18.649 + } 18.650 + 18.651 + p = argv[optind]; 18.652 + 18.653 + destroy_domain(p); 18.654 + exit(0); 18.655 +} 18.656 + 18.657 +int main_list(int argc, char **argv) 18.658 +{ 18.659 + int opt; 18.660 + 18.661 + while ((opt = getopt(argc, argv, "h")) != -1) { 18.662 + switch (opt) { 18.663 + case 'h': 18.664 + help("list"); 18.665 + exit(0); 18.666 + default: 18.667 + fprintf(stderr, "option not supported\n"); 18.668 + break; 18.669 + } 18.670 + } 18.671 + 18.672 + list_domains(); 18.673 + exit(0); 18.674 +} 18.675 + 18.676 +int main_create(int argc, char **argv) 18.677 +{ 18.678 + char *filename = NULL; 18.679 + int debug = 0; 18.680 + int opt; 18.681 + 18.682 + while ((opt = getopt(argc, argv, "hd")) != -1) { 18.683 + switch (opt) { 18.684 + case 'd': 18.685 + debug = 1; 18.686 + break; 18.687 + case 'h': 18.688 + help("create"); 18.689 + exit(0); 18.690 + default: 18.691 + fprintf(stderr, "option not supported\n"); 18.692 + break; 18.693 + } 18.694 + } 18.695 + 18.696 + if (optind >= argc) { 18.697 + help("create"); 18.698 + exit(2); 18.699 + } 18.700 + 18.701 + filename = argv[optind]; 18.702 + create_domain(debug, filename); 18.703 + exit(0); 18.704 +} 18.705 + 18.706 +int main(int argc, char **argv) 18.707 +{ 18.708 + if (argc < 2) { 18.709 + help(NULL); 18.710 + exit(1); 18.711 + } 18.712 + 18.713 + if (!strcmp(argv[1], "create")) { 18.714 + main_create(argc - 1, argv + 1); 18.715 + } else if (!strcmp(argv[1], "list")) { 18.716 + main_list(argc - 1, argv + 1); 18.717 + } else if (!strcmp(argv[1], "destroy")) { 18.718 + main_destroy(argc - 1, argv + 1); 18.719 + } else if (!strcmp(argv[1], "help")) { 18.720 + if (argc > 2) 18.721 + help(argv[2]); 18.722 + else 18.723 + help(NULL); 18.724 + exit(0); 18.725 + } else { 18.726 + fprintf(stderr, "command not implemented\n"); 18.727 + exit(1); 18.728 + } 18.729 +} 18.730 +