debuggers.hg
changeset 22782:548c29920f68
Merge
author | Ian Jackson <Ian.Jackson@eu.citrix.com> |
---|---|
date | Tue Jan 11 19:41:53 2011 +0000 (2011-01-11) |
parents | cb94dbe20f97 ea6f92a479da |
children | c3e478eafabc |
files | extras/mini-os/fs-front.c extras/mini-os/include/fs.h tools/fs-back/Makefile tools/fs-back/fs-backend.c tools/fs-back/fs-backend.h tools/fs-back/fs-debug.h tools/fs-back/fs-ops.c tools/fs-back/fs-xenbus.c tools/fs-back/sys-queue.h |
line diff
1.1 --- a/Config.mk Tue Jan 11 19:31:41 2011 +0000 1.2 +++ b/Config.mk Tue Jan 11 19:41:53 2011 +0000 1.3 @@ -185,9 +185,9 @@ endif 1.4 # CONFIG_QEMU ?= ../qemu-xen.git 1.5 CONFIG_QEMU ?= $(QEMU_REMOTE) 1.6 1.7 -QEMU_TAG ?= 99d53fbb69d3e03be61ae10506a304a3d08d792f 1.8 -# Wed Jan 5 23:48:36 2011 +0000 1.9 -# fix '|' key display problem in en-us with altgr processing 1.10 +QEMU_TAG ?= 1c304816043c0ffe14d20d6006d6165cb7fddb9b 1.11 +# Tue Jan 11 18:48:58 2011 +0000 1.12 +# qemu-xen: use dynticks instead of a static 10ms timeout 1.13 1.14 # Optional components 1.15 XENSTAT_XENTOP ?= y
2.1 --- a/extras/mini-os/arch/x86/mm.c Tue Jan 11 19:31:41 2011 +0000 2.2 +++ b/extras/mini-os/arch/x86/mm.c Tue Jan 11 19:41:53 2011 +0000 2.3 @@ -281,7 +281,7 @@ static void build_pagetable(unsigned lon 2.4 /* 2.5 * Mark portion of the address space read only. 2.6 */ 2.7 -extern void shared_info; 2.8 +extern struct shared_info shared_info; 2.9 static void set_readonly(void *text, void *etext) 2.10 { 2.11 unsigned long start_address =
3.1 --- a/extras/mini-os/fs-front.c Tue Jan 11 19:31:41 2011 +0000 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,1297 +0,0 @@ 3.4 -/****************************************************************************** 3.5 - * fs-front.c 3.6 - * 3.7 - * Frontend driver for FS split device driver. 3.8 - * 3.9 - * Copyright (c) 2007, Grzegorz Milos, <gm281@cam.ac.uk>. 3.10 - * 3.11 - * Permission is hereby granted, free of charge, to any person obtaining a copy 3.12 - * of this software and associated documentation files (the "Software"), to 3.13 - * deal in the Software without restriction, including without limitation the 3.14 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 3.15 - * sell copies of the Software, and to permit persons to whom the Software is 3.16 - * furnished to do so, subject to the following conditions: 3.17 - * 3.18 - * The above copyright notice and this permission notice shall be included in 3.19 - * all copies or substantial portions of the Software. 3.20 - * 3.21 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 3.22 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 3.23 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 3.24 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 3.25 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 3.26 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 3.27 - * DEALINGS IN THE SOFTWARE. 3.28 - */ 3.29 - 3.30 -#undef NDEBUG 3.31 -#include <stdint.h> 3.32 -#include <mini-os/os.h> 3.33 -#include <mini-os/list.h> 3.34 -#include <mini-os/xmalloc.h> 3.35 -#include <mini-os/xenbus.h> 3.36 -#include <mini-os/gnttab.h> 3.37 -#include <mini-os/events.h> 3.38 -#include <xen/io/fsif.h> 3.39 -#include <mini-os/fs.h> 3.40 -#include <mini-os/sched.h> 3.41 - 3.42 -#define preempt_disable() 3.43 -#define preempt_enable() 3.44 -#define cmpxchg(p,o,n) synch_cmpxchg(p,o,n) 3.45 - 3.46 - 3.47 -#ifdef FS_DEBUG 3.48 -#define DEBUG(_f, _a...) \ 3.49 - printk("MINI_OS(file=fs-front.c, line=%d) " _f "\n", __LINE__, ## _a) 3.50 -#else 3.51 -#define DEBUG(_f, _a...) ((void)0) 3.52 -#endif 3.53 - 3.54 - 3.55 -struct fs_request; 3.56 -struct fs_import *fs_import; 3.57 -void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t *gref); 3.58 -void free_buffer_page(struct fs_request *req); 3.59 - 3.60 -/******************************************************************************/ 3.61 -/* RING REQUEST/RESPONSES HANDLING */ 3.62 -/******************************************************************************/ 3.63 - 3.64 -struct fs_request 3.65 -{ 3.66 - void *private1; /* Specific to request type */ 3.67 - void *private2; 3.68 - struct thread *thread; /* Thread blocked on this request */ 3.69 - struct fsif_response shadow_rsp; /* Response copy writen by the 3.70 - interrupt handler */ 3.71 -}; 3.72 - 3.73 -struct fs_rw_gnts 3.74 -{ 3.75 - /* TODO 16 bit? */ 3.76 - int count; 3.77 - grant_ref_t grefs[FSIF_NR_READ_GNTS]; 3.78 - void *pages[FSIF_NR_READ_GNTS]; 3.79 -}; 3.80 - 3.81 -/* Ring operations: 3.82 - * FSIF ring is used differently to Linux-like split devices. This stems from 3.83 - * the fact that no I/O request queue is present. The use of some of the macros 3.84 - * defined in ring.h is not allowed, in particular: 3.85 - * RING_PUSH_REQUESTS_AND_CHECK_NOTIFY cannot be used. 3.86 - * 3.87 - * The protocol used for FSIF ring is described below: 3.88 - * 3.89 - * In order to reserve a request the frontend: 3.90 - * a) saves current frontend_ring->req_prod_pvt into a local variable 3.91 - * b) checks that there are free request using the local req_prod_pvt 3.92 - * c) tries to reserve the request using cmpxchg on frontend_ring->req_prod_pvt 3.93 - * if cmpxchg fails, it means that someone reserved the request, start from 3.94 - * a) 3.95 - * 3.96 - * In order to commit a request to the shared ring: 3.97 - * a) cmpxchg shared_ring->req_prod from local req_prod_pvt to req_prod_pvt+1 3.98 - * Loop if unsuccessful. 3.99 - * NOTE: Request should be commited to the shared ring as quickly as possible, 3.100 - * because otherwise other threads might busy loop trying to commit next 3.101 - * requests. It also follows that preemption should be disabled, if 3.102 - * possible, for the duration of the request construction. 3.103 - */ 3.104 - 3.105 -/* Number of free requests (for use on front side only). */ 3.106 -#define FS_RING_FREE_REQUESTS(_r, _req_prod_pvt) \ 3.107 - (RING_SIZE(_r) - (_req_prod_pvt - (_r)->rsp_cons)) 3.108 - 3.109 - 3.110 - 3.111 -static RING_IDX reserve_fsif_request(struct fs_import *import) 3.112 -{ 3.113 - RING_IDX idx; 3.114 - 3.115 - down(&import->reqs_sem); 3.116 - preempt_disable(); 3.117 -again: 3.118 - /* We will attempt to reserve slot idx */ 3.119 - idx = import->ring.req_prod_pvt; 3.120 - ASSERT (FS_RING_FREE_REQUESTS(&import->ring, idx)); 3.121 - /* Attempt to reserve */ 3.122 - if(cmpxchg(&import->ring.req_prod_pvt, idx, idx+1) != idx) 3.123 - goto again; 3.124 - 3.125 - return idx; 3.126 -} 3.127 - 3.128 -static void commit_fsif_request(struct fs_import *import, RING_IDX idx) 3.129 -{ 3.130 - while(cmpxchg(&import->ring.sring->req_prod, idx, idx+1) != idx) 3.131 - { 3.132 - printk("Failed to commit a request: req_prod=%d, idx=%d\n", 3.133 - import->ring.sring->req_prod, idx); 3.134 - } 3.135 - preempt_enable(); 3.136 - 3.137 - /* NOTE: we cannot do anything clever about rsp_event, to hold off 3.138 - * notifications, because we don't know if we are a single request (in which 3.139 - * case we have to notify always), or a part of a larger request group 3.140 - * (when, in some cases, notification isn't required) */ 3.141 - notify_remote_via_evtchn(import->local_port); 3.142 -} 3.143 - 3.144 - 3.145 - 3.146 -static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist) 3.147 -{ 3.148 - unsigned int old_id, new_id; 3.149 - 3.150 -again: 3.151 - old_id = freelist[0]; 3.152 - /* Note: temporal inconsistency, since freelist[0] can be changed by someone 3.153 - * else, but we are a sole owner of freelist[id + 1], it's OK. */ 3.154 - freelist[id + 1] = old_id; 3.155 - new_id = id; 3.156 - if(cmpxchg(&freelist[0], old_id, new_id) != old_id) 3.157 - { 3.158 - printk("Cmpxchg on freelist add failed.\n"); 3.159 - goto again; 3.160 - } 3.161 -} 3.162 - 3.163 -/* always call reserve_fsif_request(import) before this, to protect from 3.164 - * depletion. */ 3.165 -static inline unsigned short get_id_from_freelist(unsigned short* freelist) 3.166 -{ 3.167 - unsigned int old_id, new_id; 3.168 - 3.169 -again: 3.170 - old_id = freelist[0]; 3.171 - new_id = freelist[old_id + 1]; 3.172 - if(cmpxchg(&freelist[0], old_id, new_id) != old_id) 3.173 - { 3.174 - printk("Cmpxchg on freelist remove failed.\n"); 3.175 - goto again; 3.176 - } 3.177 - 3.178 - return old_id; 3.179 -} 3.180 - 3.181 -/******************************************************************************/ 3.182 -/* END OF RING REQUEST/RESPONSES HANDLING */ 3.183 -/******************************************************************************/ 3.184 - 3.185 - 3.186 - 3.187 -/******************************************************************************/ 3.188 -/* INDIVIDUAL FILE OPERATIONS */ 3.189 -/******************************************************************************/ 3.190 -int fs_open(struct fs_import *import, char *file) 3.191 -{ 3.192 - struct fs_request *fsr; 3.193 - unsigned short priv_req_id; 3.194 - grant_ref_t gref; 3.195 - void *buffer; 3.196 - RING_IDX back_req_id; 3.197 - struct fsif_request *req; 3.198 - int fd; 3.199 - 3.200 - if (!import) 3.201 - return -1; 3.202 - 3.203 - /* Prepare request for the backend */ 3.204 - back_req_id = reserve_fsif_request(import); 3.205 - DEBUG("Backend request id=%d\n", back_req_id); 3.206 - 3.207 - /* Prepare our private request structure */ 3.208 - priv_req_id = get_id_from_freelist(import->freelist); 3.209 - DEBUG("Request id for fs_open call is: %d\n", priv_req_id); 3.210 - fsr = &import->requests[priv_req_id]; 3.211 - buffer = alloc_buffer_page(fsr, import->dom_id, &gref); 3.212 - DEBUG("gref id=%d\n", gref); 3.213 - fsr->thread = current; 3.214 - sprintf(buffer, "%s", file); 3.215 - 3.216 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.217 - req->type = REQ_FILE_OPEN; 3.218 - req->id = priv_req_id; 3.219 - req->u.fopen.gref = gref; 3.220 - 3.221 - /* Set blocked flag before commiting the request, thus avoiding missed 3.222 - * response race */ 3.223 - block(current); 3.224 - commit_fsif_request(import, back_req_id); 3.225 - schedule(); 3.226 - 3.227 - /* Read the response */ 3.228 - fd = (int)fsr->shadow_rsp.u.ret_val; 3.229 - DEBUG("The following FD returned: %d\n", fd); 3.230 - free_buffer_page(fsr); 3.231 - add_id_to_freelist(priv_req_id, import->freelist); 3.232 - 3.233 - return fd; 3.234 -} 3.235 - 3.236 -int fs_close(struct fs_import *import, int fd) 3.237 -{ 3.238 - struct fs_request *fsr; 3.239 - unsigned short priv_req_id; 3.240 - RING_IDX back_req_id; 3.241 - struct fsif_request *req; 3.242 - int ret; 3.243 - 3.244 - if (!import) 3.245 - return -1; 3.246 - 3.247 - /* Prepare request for the backend */ 3.248 - back_req_id = reserve_fsif_request(import); 3.249 - DEBUG("Backend request id=%d\n", back_req_id); 3.250 - 3.251 - /* Prepare our private request structure */ 3.252 - priv_req_id = get_id_from_freelist(import->freelist); 3.253 - DEBUG("Request id for fs_close call is: %d\n", priv_req_id); 3.254 - fsr = &import->requests[priv_req_id]; 3.255 - fsr->thread = current; 3.256 - 3.257 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.258 - req->type = REQ_FILE_CLOSE; 3.259 - req->id = priv_req_id; 3.260 - req->u.fclose.fd = fd; 3.261 - 3.262 - /* Set blocked flag before commiting the request, thus avoiding missed 3.263 - * response race */ 3.264 - block(current); 3.265 - commit_fsif_request(import, back_req_id); 3.266 - schedule(); 3.267 - 3.268 - /* Read the response */ 3.269 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.270 - DEBUG("Close returned: %d\n", ret); 3.271 - add_id_to_freelist(priv_req_id, import->freelist); 3.272 - 3.273 - return ret; 3.274 -} 3.275 - 3.276 -ssize_t fs_read(struct fs_import *import, int fd, void *buf, 3.277 - ssize_t len, ssize_t offset) 3.278 -{ 3.279 - struct fs_request *fsr; 3.280 - unsigned short priv_req_id; 3.281 - struct fs_rw_gnts gnts; 3.282 - RING_IDX back_req_id; 3.283 - struct fsif_request *req; 3.284 - ssize_t ret; 3.285 - int i; 3.286 - 3.287 - if (!import) 3.288 - return -1; 3.289 - 3.290 - BUG_ON(len > PAGE_SIZE * FSIF_NR_READ_GNTS); 3.291 - 3.292 - /* Prepare request for the backend */ 3.293 - back_req_id = reserve_fsif_request(import); 3.294 - DEBUG("Backend request id=%d\n", back_req_id); 3.295 - 3.296 - /* Prepare our private request structure */ 3.297 - priv_req_id = get_id_from_freelist(import->freelist); 3.298 - DEBUG("Request id for fs_read call is: %d\n", priv_req_id); 3.299 - fsr = &import->requests[priv_req_id]; 3.300 - 3.301 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.302 - req->type = REQ_FILE_READ; 3.303 - req->id = priv_req_id; 3.304 - req->u.fread.fd = fd; 3.305 - req->u.fread.len = len; 3.306 - req->u.fread.offset = offset; 3.307 - 3.308 - 3.309 - ASSERT(len > 0); 3.310 - gnts.count = ((len - 1) / PAGE_SIZE) + 1; 3.311 - for(i=0; i<gnts.count; i++) 3.312 - { 3.313 - gnts.pages[i] = (void *)alloc_page(); 3.314 - gnts.grefs[i] = gnttab_grant_access(import->dom_id, 3.315 - virt_to_mfn(gnts.pages[i]), 3.316 - 0); 3.317 - memset(gnts.pages[i], 0, PAGE_SIZE); 3.318 - req->u.fread.grefs[i] = gnts.grefs[i]; 3.319 - } 3.320 - fsr->thread = current; 3.321 - 3.322 - /* Set blocked flag before commiting the request, thus avoiding missed 3.323 - * response race */ 3.324 - block(current); 3.325 - commit_fsif_request(import, back_req_id); 3.326 - schedule(); 3.327 - 3.328 - /* Read the response */ 3.329 - ret = (ssize_t)fsr->shadow_rsp.u.ret_val; 3.330 - DEBUG("The following ret value returned %d\n", ret); 3.331 - if(ret > 0) 3.332 - { 3.333 - ssize_t to_copy = ret, current_copy; 3.334 - for(i=0; i<gnts.count; i++) 3.335 - { 3.336 - gnttab_end_access(gnts.grefs[i]); 3.337 - current_copy = to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy; 3.338 - if(current_copy > 0) 3.339 - memcpy(buf, gnts.pages[i], current_copy); 3.340 - to_copy -= current_copy; 3.341 - buf = (char*) buf + current_copy; 3.342 - free_page(gnts.pages[i]); 3.343 - } 3.344 - } 3.345 - add_id_to_freelist(priv_req_id, import->freelist); 3.346 - 3.347 - return ret; 3.348 -} 3.349 - 3.350 -ssize_t fs_write(struct fs_import *import, int fd, void *buf, 3.351 - ssize_t len, ssize_t offset) 3.352 -{ 3.353 - struct fs_request *fsr; 3.354 - unsigned short priv_req_id; 3.355 - struct fs_rw_gnts gnts; 3.356 - RING_IDX back_req_id; 3.357 - struct fsif_request *req; 3.358 - ssize_t ret, to_copy; 3.359 - int i; 3.360 - 3.361 - if (!import) 3.362 - return -1; 3.363 - 3.364 - BUG_ON(len > PAGE_SIZE * FSIF_NR_WRITE_GNTS); 3.365 - 3.366 - /* Prepare request for the backend */ 3.367 - back_req_id = reserve_fsif_request(import); 3.368 - DEBUG("Backend request id=%d\n", back_req_id); 3.369 - 3.370 - /* Prepare our private request structure */ 3.371 - priv_req_id = get_id_from_freelist(import->freelist); 3.372 - DEBUG("Request id for fs_read call is: %d\n", priv_req_id); 3.373 - fsr = &import->requests[priv_req_id]; 3.374 - 3.375 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.376 - req->type = REQ_FILE_WRITE; 3.377 - req->id = priv_req_id; 3.378 - req->u.fwrite.fd = fd; 3.379 - req->u.fwrite.len = len; 3.380 - req->u.fwrite.offset = offset; 3.381 - 3.382 - ASSERT(len > 0); 3.383 - gnts.count = ((len - 1) / PAGE_SIZE) + 1; 3.384 - to_copy = len; 3.385 - for(i=0; i<gnts.count; i++) 3.386 - { 3.387 - int current_copy = (to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy); 3.388 - gnts.pages[i] = (void *)alloc_page(); 3.389 - gnts.grefs[i] = gnttab_grant_access(import->dom_id, 3.390 - virt_to_mfn(gnts.pages[i]), 3.391 - 0); 3.392 - memcpy(gnts.pages[i], buf, current_copy); 3.393 - if(current_copy < PAGE_SIZE) 3.394 - memset((char *)gnts.pages[i] + current_copy, 3.395 - 0, 3.396 - PAGE_SIZE - current_copy); 3.397 - req->u.fwrite.grefs[i] = gnts.grefs[i]; 3.398 - to_copy -= current_copy; 3.399 - buf = (char*) buf + current_copy; 3.400 - } 3.401 - fsr->thread = current; 3.402 - 3.403 - /* Set blocked flag before commiting the request, thus avoiding missed 3.404 - * response race */ 3.405 - block(current); 3.406 - commit_fsif_request(import, back_req_id); 3.407 - schedule(); 3.408 - 3.409 - /* Read the response */ 3.410 - ret = (ssize_t)fsr->shadow_rsp.u.ret_val; 3.411 - DEBUG("The following ret value returned %d\n", ret); 3.412 - for(i=0; i<gnts.count; i++) 3.413 - { 3.414 - gnttab_end_access(gnts.grefs[i]); 3.415 - free_page(gnts.pages[i]); 3.416 - } 3.417 - add_id_to_freelist(priv_req_id, import->freelist); 3.418 - 3.419 - return ret; 3.420 -} 3.421 - 3.422 -int fs_stat(struct fs_import *import, 3.423 - int fd, 3.424 - struct fsif_stat_response *stat) 3.425 -{ 3.426 - struct fs_request *fsr; 3.427 - unsigned short priv_req_id; 3.428 - RING_IDX back_req_id; 3.429 - struct fsif_request *req; 3.430 - int ret; 3.431 - 3.432 - if (!import) 3.433 - return -1; 3.434 - 3.435 - /* Prepare request for the backend */ 3.436 - back_req_id = reserve_fsif_request(import); 3.437 - DEBUG("Backend request id=%d\n", back_req_id); 3.438 - 3.439 - /* Prepare our private request structure */ 3.440 - priv_req_id = get_id_from_freelist(import->freelist); 3.441 - DEBUG("Request id for fs_stat call is: %d\n", priv_req_id); 3.442 - fsr = &import->requests[priv_req_id]; 3.443 - fsr->thread = current; 3.444 - 3.445 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.446 - req->type = REQ_STAT; 3.447 - req->id = priv_req_id; 3.448 - req->u.fstat.fd = fd; 3.449 - 3.450 - /* Set blocked flag before commiting the request, thus avoiding missed 3.451 - * response race */ 3.452 - block(current); 3.453 - commit_fsif_request(import, back_req_id); 3.454 - schedule(); 3.455 - 3.456 - /* Read the response */ 3.457 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.458 - DEBUG("Following ret from fstat: %d\n", ret); 3.459 - memcpy(stat, 3.460 - &fsr->shadow_rsp.u.fstat, 3.461 - sizeof(struct fsif_stat_response)); 3.462 - add_id_to_freelist(priv_req_id, import->freelist); 3.463 - 3.464 - return ret; 3.465 -} 3.466 - 3.467 -int fs_truncate(struct fs_import *import, 3.468 - int fd, 3.469 - int64_t length) 3.470 -{ 3.471 - struct fs_request *fsr; 3.472 - unsigned short priv_req_id; 3.473 - RING_IDX back_req_id; 3.474 - struct fsif_request *req; 3.475 - int ret; 3.476 - 3.477 - if (!import) 3.478 - return -1; 3.479 - 3.480 - /* Prepare request for the backend */ 3.481 - back_req_id = reserve_fsif_request(import); 3.482 - DEBUG("Backend request id=%d\n", back_req_id); 3.483 - 3.484 - /* Prepare our private request structure */ 3.485 - priv_req_id = get_id_from_freelist(import->freelist); 3.486 - DEBUG("Request id for fs_truncate call is: %d\n", priv_req_id); 3.487 - fsr = &import->requests[priv_req_id]; 3.488 - fsr->thread = current; 3.489 - 3.490 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.491 - req->type = REQ_FILE_TRUNCATE; 3.492 - req->id = priv_req_id; 3.493 - req->u.ftruncate.fd = fd; 3.494 - req->u.ftruncate.length = length; 3.495 - 3.496 - /* Set blocked flag before commiting the request, thus avoiding missed 3.497 - * response race */ 3.498 - block(current); 3.499 - commit_fsif_request(import, back_req_id); 3.500 - schedule(); 3.501 - 3.502 - /* Read the response */ 3.503 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.504 - DEBUG("Following ret from ftruncate: %d\n", ret); 3.505 - add_id_to_freelist(priv_req_id, import->freelist); 3.506 - 3.507 - return ret; 3.508 -} 3.509 - 3.510 -int fs_remove(struct fs_import *import, char *file) 3.511 -{ 3.512 - struct fs_request *fsr; 3.513 - unsigned short priv_req_id; 3.514 - grant_ref_t gref; 3.515 - void *buffer; 3.516 - RING_IDX back_req_id; 3.517 - struct fsif_request *req; 3.518 - int ret; 3.519 - 3.520 - if (!import) 3.521 - return -1; 3.522 - 3.523 - /* Prepare request for the backend */ 3.524 - back_req_id = reserve_fsif_request(import); 3.525 - DEBUG("Backend request id=%d\n", back_req_id); 3.526 - 3.527 - /* Prepare our private request structure */ 3.528 - priv_req_id = get_id_from_freelist(import->freelist); 3.529 - DEBUG("Request id for fs_open call is: %d\n", priv_req_id); 3.530 - fsr = &import->requests[priv_req_id]; 3.531 - buffer = alloc_buffer_page(fsr, import->dom_id, &gref); 3.532 - DEBUG("gref=%d\n", gref); 3.533 - fsr->thread = current; 3.534 - sprintf(buffer, "%s", file); 3.535 - 3.536 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.537 - req->type = REQ_REMOVE; 3.538 - req->id = priv_req_id; 3.539 - req->u.fremove.gref = gref; 3.540 - 3.541 - /* Set blocked flag before commiting the request, thus avoiding missed 3.542 - * response race */ 3.543 - block(current); 3.544 - commit_fsif_request(import, back_req_id); 3.545 - schedule(); 3.546 - 3.547 - /* Read the response */ 3.548 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.549 - DEBUG("The following ret: %d\n", ret); 3.550 - free_buffer_page(fsr); 3.551 - add_id_to_freelist(priv_req_id, import->freelist); 3.552 - 3.553 - return ret; 3.554 -} 3.555 - 3.556 - 3.557 -int fs_rename(struct fs_import *import, 3.558 - char *old_file_name, 3.559 - char *new_file_name) 3.560 -{ 3.561 - struct fs_request *fsr; 3.562 - unsigned short priv_req_id; 3.563 - grant_ref_t gref; 3.564 - void *buffer; 3.565 - RING_IDX back_req_id; 3.566 - struct fsif_request *req; 3.567 - int ret; 3.568 - char old_header[] = "old: "; 3.569 - char new_header[] = "new: "; 3.570 - 3.571 - if (!import) 3.572 - return -1; 3.573 - 3.574 - /* Prepare request for the backend */ 3.575 - back_req_id = reserve_fsif_request(import); 3.576 - DEBUG("Backend request id=%d\n", back_req_id); 3.577 - 3.578 - /* Prepare our private request structure */ 3.579 - priv_req_id = get_id_from_freelist(import->freelist); 3.580 - DEBUG("Request id for fs_open call is: %d\n", priv_req_id); 3.581 - fsr = &import->requests[priv_req_id]; 3.582 - buffer = alloc_buffer_page(fsr, import->dom_id, &gref); 3.583 - DEBUG("gref=%d\n", gref); 3.584 - fsr->thread = current; 3.585 - sprintf(buffer, "%s%s%c%s%s", 3.586 - old_header, old_file_name, '\0', new_header, new_file_name); 3.587 - 3.588 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.589 - req->type = REQ_RENAME; 3.590 - req->id = priv_req_id; 3.591 - req->u.frename.gref = gref; 3.592 - req->u.frename.old_name_offset = strlen(old_header); 3.593 - req->u.frename.new_name_offset = strlen(old_header) + 3.594 - strlen(old_file_name) + 3.595 - strlen(new_header) + 3.596 - 1 /* Accouning for the additional 3.597 - end of string character */; 3.598 - 3.599 - /* Set blocked flag before commiting the request, thus avoiding missed 3.600 - * response race */ 3.601 - block(current); 3.602 - commit_fsif_request(import, back_req_id); 3.603 - schedule(); 3.604 - 3.605 - /* Read the response */ 3.606 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.607 - DEBUG("The following ret: %d\n", ret); 3.608 - free_buffer_page(fsr); 3.609 - add_id_to_freelist(priv_req_id, import->freelist); 3.610 - 3.611 - return ret; 3.612 -} 3.613 - 3.614 -int fs_create(struct fs_import *import, char *name, 3.615 - int8_t directory, int32_t mode) 3.616 -{ 3.617 - struct fs_request *fsr; 3.618 - unsigned short priv_req_id; 3.619 - grant_ref_t gref; 3.620 - void *buffer; 3.621 - RING_IDX back_req_id; 3.622 - struct fsif_request *req; 3.623 - int ret; 3.624 - 3.625 - if (!import) 3.626 - return -1; 3.627 - 3.628 - /* Prepare request for the backend */ 3.629 - back_req_id = reserve_fsif_request(import); 3.630 - DEBUG("Backend request id=%d\n", back_req_id); 3.631 - 3.632 - /* Prepare our private request structure */ 3.633 - priv_req_id = get_id_from_freelist(import->freelist); 3.634 - DEBUG("Request id for fs_create call is: %d\n", priv_req_id); 3.635 - fsr = &import->requests[priv_req_id]; 3.636 - buffer = alloc_buffer_page(fsr, import->dom_id, &gref); 3.637 - DEBUG("gref=%d\n", gref); 3.638 - fsr->thread = current; 3.639 - sprintf(buffer, "%s", name); 3.640 - 3.641 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.642 - req->type = REQ_CREATE; 3.643 - req->id = priv_req_id; 3.644 - req->u.fcreate.gref = gref; 3.645 - req->u.fcreate.directory = directory; 3.646 - req->u.fcreate.mode = mode; 3.647 - 3.648 - /* Set blocked flag before commiting the request, thus avoiding missed 3.649 - * response race */ 3.650 - block(current); 3.651 - commit_fsif_request(import, back_req_id); 3.652 - schedule(); 3.653 - 3.654 - /* Read the response */ 3.655 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.656 - DEBUG("The following ret: %d\n", ret); 3.657 - free_buffer_page(fsr); 3.658 - add_id_to_freelist(priv_req_id, import->freelist); 3.659 - 3.660 - return ret; 3.661 -} 3.662 - 3.663 -char** fs_list(struct fs_import *import, char *name, 3.664 - int32_t offset, int32_t *nr_files, int *has_more) 3.665 -{ 3.666 - struct fs_request *fsr; 3.667 - unsigned short priv_req_id; 3.668 - grant_ref_t gref; 3.669 - void *buffer; 3.670 - RING_IDX back_req_id; 3.671 - struct fsif_request *req; 3.672 - char **files, *current_file; 3.673 - int i; 3.674 - 3.675 - if (!import) 3.676 - return NULL; 3.677 - 3.678 - DEBUG("Different masks: NR_FILES=(%llx, %d), ERROR=(%llx, %d), HAS_MORE(%llx, %d)\n", 3.679 - NR_FILES_MASK, NR_FILES_SHIFT, ERROR_MASK, ERROR_SHIFT, HAS_MORE_FLAG, HAS_MORE_SHIFT); 3.680 - 3.681 - /* Prepare request for the backend */ 3.682 - back_req_id = reserve_fsif_request(import); 3.683 - DEBUG("Backend request id=%d\n", back_req_id); 3.684 - 3.685 - /* Prepare our private request structure */ 3.686 - priv_req_id = get_id_from_freelist(import->freelist); 3.687 - DEBUG("Request id for fs_list call is: %d\n", priv_req_id); 3.688 - fsr = &import->requests[priv_req_id]; 3.689 - buffer = alloc_buffer_page(fsr, import->dom_id, &gref); 3.690 - DEBUG("gref=%d\n", gref); 3.691 - fsr->thread = current; 3.692 - sprintf(buffer, "%s", name); 3.693 - 3.694 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.695 - req->type = REQ_DIR_LIST; 3.696 - req->id = priv_req_id; 3.697 - req->u.flist.gref = gref; 3.698 - req->u.flist.offset = offset; 3.699 - 3.700 - /* Set blocked flag before commiting the request, thus avoiding missed 3.701 - * response race */ 3.702 - block(current); 3.703 - commit_fsif_request(import, back_req_id); 3.704 - schedule(); 3.705 - 3.706 - /* Read the response */ 3.707 - *nr_files = (fsr->shadow_rsp.u.ret_val & NR_FILES_MASK) >> NR_FILES_SHIFT; 3.708 - files = NULL; 3.709 - if(*nr_files <= 0) goto exit; 3.710 - files = malloc(sizeof(char*) * (*nr_files)); 3.711 - current_file = buffer; 3.712 - for(i=0; i<*nr_files; i++) 3.713 - { 3.714 - files[i] = strdup(current_file); 3.715 - current_file += strlen(current_file) + 1; 3.716 - } 3.717 - if(has_more != NULL) 3.718 - *has_more = fsr->shadow_rsp.u.ret_val & HAS_MORE_FLAG; 3.719 - free_buffer_page(fsr); 3.720 - add_id_to_freelist(priv_req_id, import->freelist); 3.721 -exit: 3.722 - return files; 3.723 -} 3.724 - 3.725 -int fs_chmod(struct fs_import *import, int fd, int32_t mode) 3.726 -{ 3.727 - struct fs_request *fsr; 3.728 - unsigned short priv_req_id; 3.729 - RING_IDX back_req_id; 3.730 - struct fsif_request *req; 3.731 - int ret; 3.732 - 3.733 - if (!import) 3.734 - return -1; 3.735 - 3.736 - /* Prepare request for the backend */ 3.737 - back_req_id = reserve_fsif_request(import); 3.738 - DEBUG("Backend request id=%d\n", back_req_id); 3.739 - 3.740 - /* Prepare our private request structure */ 3.741 - priv_req_id = get_id_from_freelist(import->freelist); 3.742 - DEBUG("Request id for fs_chmod call is: %d\n", priv_req_id); 3.743 - fsr = &import->requests[priv_req_id]; 3.744 - fsr->thread = current; 3.745 - 3.746 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.747 - req->type = REQ_CHMOD; 3.748 - req->id = priv_req_id; 3.749 - req->u.fchmod.fd = fd; 3.750 - req->u.fchmod.mode = mode; 3.751 - 3.752 - /* Set blocked flag before commiting the request, thus avoiding missed 3.753 - * response race */ 3.754 - block(current); 3.755 - commit_fsif_request(import, back_req_id); 3.756 - schedule(); 3.757 - 3.758 - /* Read the response */ 3.759 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.760 - DEBUG("The following returned: %d\n", ret); 3.761 - add_id_to_freelist(priv_req_id, import->freelist); 3.762 - 3.763 - return ret; 3.764 -} 3.765 - 3.766 -int64_t fs_space(struct fs_import *import, char *location) 3.767 -{ 3.768 - struct fs_request *fsr; 3.769 - unsigned short priv_req_id; 3.770 - grant_ref_t gref; 3.771 - void *buffer; 3.772 - RING_IDX back_req_id; 3.773 - struct fsif_request *req; 3.774 - int64_t ret; 3.775 - 3.776 - if (!import) 3.777 - return -1; 3.778 - 3.779 - /* Prepare request for the backend */ 3.780 - back_req_id = reserve_fsif_request(import); 3.781 - DEBUG("Backend request id=%d\n", back_req_id); 3.782 - 3.783 - /* Prepare our private request structure */ 3.784 - priv_req_id = get_id_from_freelist(import->freelist); 3.785 - DEBUG("Request id for fs_space is: %d\n", priv_req_id); 3.786 - fsr = &import->requests[priv_req_id]; 3.787 - buffer = alloc_buffer_page(fsr, import->dom_id, &gref); 3.788 - DEBUG("gref=%d\n", gref); 3.789 - fsr->thread = current; 3.790 - sprintf(buffer, "%s", location); 3.791 - 3.792 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.793 - req->type = REQ_FS_SPACE; 3.794 - req->id = priv_req_id; 3.795 - req->u.fspace.gref = gref; 3.796 - 3.797 - /* Set blocked flag before commiting the request, thus avoiding missed 3.798 - * response race */ 3.799 - block(current); 3.800 - commit_fsif_request(import, back_req_id); 3.801 - schedule(); 3.802 - 3.803 - /* Read the response */ 3.804 - ret = (int64_t)fsr->shadow_rsp.u.ret_val; 3.805 - DEBUG("The following returned: %lld\n", ret); 3.806 - free_buffer_page(fsr); 3.807 - add_id_to_freelist(priv_req_id, import->freelist); 3.808 - 3.809 - return ret; 3.810 -} 3.811 - 3.812 -int fs_sync(struct fs_import *import, int fd) 3.813 -{ 3.814 - struct fs_request *fsr; 3.815 - unsigned short priv_req_id; 3.816 - RING_IDX back_req_id; 3.817 - struct fsif_request *req; 3.818 - int ret; 3.819 - 3.820 - if (!import) 3.821 - return -1; 3.822 - 3.823 - /* Prepare request for the backend */ 3.824 - back_req_id = reserve_fsif_request(import); 3.825 - DEBUG("Backend request id=%d\n", back_req_id); 3.826 - 3.827 - /* Prepare our private request structure */ 3.828 - priv_req_id = get_id_from_freelist(import->freelist); 3.829 - DEBUG("Request id for fs_sync call is: %d\n", priv_req_id); 3.830 - fsr = &import->requests[priv_req_id]; 3.831 - fsr->thread = current; 3.832 - 3.833 - req = RING_GET_REQUEST(&import->ring, back_req_id); 3.834 - req->type = REQ_FILE_SYNC; 3.835 - req->id = priv_req_id; 3.836 - req->u.fsync.fd = fd; 3.837 - 3.838 - /* Set blocked flag before commiting the request, thus avoiding missed 3.839 - * response race */ 3.840 - block(current); 3.841 - commit_fsif_request(import, back_req_id); 3.842 - schedule(); 3.843 - 3.844 - /* Read the response */ 3.845 - ret = (int)fsr->shadow_rsp.u.ret_val; 3.846 - DEBUG("Close returned: %d\n", ret); 3.847 - add_id_to_freelist(priv_req_id, import->freelist); 3.848 - 3.849 - return ret; 3.850 -} 3.851 - 3.852 - 3.853 -/******************************************************************************/ 3.854 -/* END OF INDIVIDUAL FILE OPERATIONS */ 3.855 -/******************************************************************************/ 3.856 - 3.857 -void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t *gref) 3.858 -{ 3.859 - void *page; 3.860 - 3.861 - page = (void *)alloc_page(); 3.862 - *gref = gnttab_grant_access(domid, virt_to_mfn(page), 0); 3.863 - req->private1 = page; 3.864 - req->private2 = (void *)(uintptr_t)(*gref); 3.865 - 3.866 - return page; 3.867 -} 3.868 - 3.869 -void free_buffer_page(struct fs_request *req) 3.870 -{ 3.871 - gnttab_end_access((grant_ref_t)(uintptr_t)req->private2); 3.872 - free_page(req->private1); 3.873 -} 3.874 - 3.875 -static void fsfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) 3.876 -{ 3.877 - struct fs_import *import = (struct fs_import*)data; 3.878 - static int in_irq = 0; 3.879 - RING_IDX cons, rp; 3.880 - int more; 3.881 - 3.882 - /* Check for non-reentrance */ 3.883 - BUG_ON(in_irq); 3.884 - in_irq = 1; 3.885 - 3.886 - DEBUG("Event from import [%d:%d].\n", import->dom_id, import->export_id); 3.887 -moretodo: 3.888 - rp = import->ring.sring->rsp_prod; 3.889 - rmb(); /* Ensure we see queued responses up to 'rp'. */ 3.890 - cons = import->ring.rsp_cons; 3.891 - while (cons != rp) 3.892 - { 3.893 - struct fsif_response *rsp; 3.894 - struct fs_request *req; 3.895 - 3.896 - rsp = RING_GET_RESPONSE(&import->ring, cons); 3.897 - DEBUG("Response at idx=%d to request id=%d, ret_val=%lx\n", 3.898 - cons, rsp->id, rsp->u.ret_val); 3.899 - req = &import->requests[rsp->id]; 3.900 - memcpy(&req->shadow_rsp, rsp, sizeof(struct fsif_response)); 3.901 - DEBUG("Waking up: %s\n", req->thread->name); 3.902 - wake(req->thread); 3.903 - 3.904 - cons++; 3.905 - up(&import->reqs_sem); 3.906 - } 3.907 - 3.908 - import->ring.rsp_cons = rp; 3.909 - RING_FINAL_CHECK_FOR_RESPONSES(&import->ring, more); 3.910 - if(more) goto moretodo; 3.911 - 3.912 - in_irq = 0; 3.913 -} 3.914 - 3.915 -static void alloc_request_table(struct fs_import *import) 3.916 -{ 3.917 - struct fs_request *requests; 3.918 - int i; 3.919 - 3.920 - BUG_ON(import->nr_entries <= 0); 3.921 - printk("Allocating request array for import %d, nr_entries = %d.\n", 3.922 - import->import_id, import->nr_entries); 3.923 - requests = xmalloc_array(struct fs_request, import->nr_entries); 3.924 - import->freelist = xmalloc_array(unsigned short, import->nr_entries + 1); 3.925 - memset(import->freelist, 0, sizeof(unsigned short) * (import->nr_entries + 1)); 3.926 - for(i=0; i<import->nr_entries; i++) 3.927 - add_id_to_freelist(i, import->freelist); 3.928 - import->requests = requests; 3.929 -} 3.930 - 3.931 - 3.932 -/******************************************************************************/ 3.933 -/* FS TESTS */ 3.934 -/******************************************************************************/ 3.935 - 3.936 - 3.937 -void test_fs_import(void *data) 3.938 -{ 3.939 - struct fs_import *import = (struct fs_import *)data; 3.940 - int ret, fd, i, repeat_count; 3.941 - int32_t nr_files; 3.942 - char buffer[1024]; 3.943 - ssize_t offset; 3.944 - char **files; 3.945 - long ret64; 3.946 - struct fsif_stat_response stat; 3.947 - 3.948 - repeat_count = 10; 3.949 - /* Sleep for 1s and then try to open a file */ 3.950 - msleep(1000); 3.951 -again: 3.952 - ret = fs_create(import, "mini-os-created-directory", 1, 0777); 3.953 - printk("Directory create: %d\n", ret); 3.954 - 3.955 - sprintf(buffer, "mini-os-created-directory/mini-os-created-file-%d", 3.956 - repeat_count); 3.957 - ret = fs_create(import, buffer, 0, 0666); 3.958 - printk("File create: %d\n", ret); 3.959 - 3.960 - fd = fs_open(import, buffer); 3.961 - printk("File descriptor: %d\n", fd); 3.962 - if(fd < 0) return; 3.963 - 3.964 - offset = 0; 3.965 - for(i=0; i<10; i++) 3.966 - { 3.967 - sprintf(buffer, "Current time is: %lld\n", NOW()); 3.968 - ret = fs_write(import, fd, buffer, strlen(buffer), offset); 3.969 - printk("Writen current time (%d)\n", ret); 3.970 - if(ret < 0) 3.971 - return; 3.972 - offset += ret; 3.973 - } 3.974 - ret = fs_stat(import, fd, &stat); 3.975 - printk("Ret after stat: %d\n", ret); 3.976 - printk(" st_mode=%o\n", stat.stat_mode); 3.977 - printk(" st_uid =%d\n", stat.stat_uid); 3.978 - printk(" st_gid =%d\n", stat.stat_gid); 3.979 - printk(" st_size=%ld\n", stat.stat_size); 3.980 - printk(" st_atime=%ld\n", stat.stat_atime); 3.981 - printk(" st_mtime=%ld\n", stat.stat_mtime); 3.982 - printk(" st_ctime=%ld\n", stat.stat_ctime); 3.983 - 3.984 - ret = fs_close(import, fd); 3.985 - printk("Closed fd: %d, ret=%d\n", fd, ret); 3.986 - 3.987 - printk("Listing files in /\n"); 3.988 - files = fs_list(import, "/", 0, &nr_files, NULL); 3.989 - for(i=0; i<nr_files; i++) 3.990 - printk(" files[%d] = %s\n", i, files[i]); 3.991 - 3.992 - ret64 = fs_space(import, "/"); 3.993 - printk("Free space: %lld (=%lld Mb)\n", ret64, (ret64 >> 20)); 3.994 - repeat_count--; 3.995 - if(repeat_count > 0) 3.996 - goto again; 3.997 - 3.998 -} 3.999 - 3.1000 -#if 0 3.1001 -// char *content = (char *)alloc_page(); 3.1002 - int fd, ret; 3.1003 -// int read; 3.1004 - char write_string[] = "\"test data written from minios\""; 3.1005 - struct fsif_stat_response stat; 3.1006 - char **files; 3.1007 - int32_t nr_files, i; 3.1008 - int64_t ret64; 3.1009 - 3.1010 - 3.1011 - fd = fs_open(import, "test-export-file"); 3.1012 -// read = fs_read(import, fd, content, PAGE_SIZE, 0); 3.1013 -// printk("Read: %d bytes\n", read); 3.1014 -// content[read] = '\0'; 3.1015 -// printk("Value: %s\n", content); 3.1016 - ret = fs_write(import, fd, write_string, strlen(write_string), 0); 3.1017 - printk("Ret after write: %d\n", ret); 3.1018 - ret = fs_stat(import, fd, &stat); 3.1019 - printk("Ret after stat: %d\n", ret); 3.1020 - printk(" st_mode=%o\n", stat.stat_mode); 3.1021 - printk(" st_uid =%d\n", stat.stat_uid); 3.1022 - printk(" st_gid =%d\n", stat.stat_gid); 3.1023 - printk(" st_size=%ld\n", stat.stat_size); 3.1024 - printk(" st_atime=%ld\n", stat.stat_atime); 3.1025 - printk(" st_mtime=%ld\n", stat.stat_mtime); 3.1026 - printk(" st_ctime=%ld\n", stat.stat_ctime); 3.1027 - ret = fs_truncate(import, fd, 30); 3.1028 - printk("Ret after truncate: %d\n", ret); 3.1029 - ret = fs_remove(import, "test-to-remove/test-file"); 3.1030 - printk("Ret after remove: %d\n", ret); 3.1031 - ret = fs_remove(import, "test-to-remove"); 3.1032 - printk("Ret after remove: %d\n", ret); 3.1033 - ret = fs_chmod(import, fd, 0700); 3.1034 - printk("Ret after chmod: %d\n", ret); 3.1035 - ret = fs_sync(import, fd); 3.1036 - printk("Ret after sync: %d\n", ret); 3.1037 - ret = fs_close(import, fd); 3.1038 - //ret = fs_rename(import, "test-export-file", "renamed-test-export-file"); 3.1039 - //printk("Ret after rename: %d\n", ret); 3.1040 - ret = fs_create(import, "created-dir", 1, 0777); 3.1041 - printk("Ret after dir create: %d\n", ret); 3.1042 - ret = fs_create(import, "created-dir/created-file", 0, 0777); 3.1043 - printk("Ret after file create: %d\n", ret); 3.1044 - files = fs_list(import, "/", 15, &nr_files, NULL); 3.1045 - for(i=0; i<nr_files; i++) 3.1046 - printk(" files[%d] = %s\n", i, files[i]); 3.1047 - ret64 = fs_space(import, "created-dir"); 3.1048 - printk("Ret after space: %lld\n", ret64); 3.1049 - 3.1050 -#endif 3.1051 - 3.1052 - 3.1053 -/******************************************************************************/ 3.1054 -/* END OF FS TESTS */ 3.1055 -/******************************************************************************/ 3.1056 - 3.1057 -static int init_fs_import(struct fs_import *import) 3.1058 -{ 3.1059 - char *err; 3.1060 - xenbus_transaction_t xbt; 3.1061 - char nodename[1024], r_nodename[1024], token[128], *message = NULL; 3.1062 - struct fsif_sring *sring; 3.1063 - int i, retry = 0; 3.1064 - domid_t self_id; 3.1065 - xenbus_event_queue events = NULL; 3.1066 - 3.1067 - printk("Initialising FS fortend to backend dom %d\n", import->dom_id); 3.1068 - /* Allocate page for the shared ring */ 3.1069 - sring = (struct fsif_sring*) alloc_pages(FSIF_RING_SIZE_ORDER); 3.1070 - memset(sring, 0, PAGE_SIZE * FSIF_RING_SIZE_PAGES); 3.1071 - 3.1072 - /* Init the shared ring */ 3.1073 - SHARED_RING_INIT(sring); 3.1074 - ASSERT(FSIF_NR_READ_GNTS == FSIF_NR_WRITE_GNTS); 3.1075 - 3.1076 - /* Init private frontend ring */ 3.1077 - FRONT_RING_INIT(&import->ring, sring, PAGE_SIZE * FSIF_RING_SIZE_PAGES); 3.1078 - import->nr_entries = import->ring.nr_ents; 3.1079 - 3.1080 - /* Allocate table of requests */ 3.1081 - alloc_request_table(import); 3.1082 - init_SEMAPHORE(&import->reqs_sem, import->nr_entries); 3.1083 - 3.1084 - /* Grant access to the shared ring */ 3.1085 - for(i=0; i<FSIF_RING_SIZE_PAGES; i++) 3.1086 - import->gnt_refs[i] = 3.1087 - gnttab_grant_access(import->dom_id, 3.1088 - virt_to_mfn((char *)sring + i * PAGE_SIZE), 3.1089 - 0); 3.1090 - 3.1091 - /* Allocate event channel */ 3.1092 - BUG_ON(evtchn_alloc_unbound(import->dom_id, 3.1093 - fsfront_handler, 3.1094 - //ANY_CPU, 3.1095 - import, 3.1096 - &import->local_port)); 3.1097 - unmask_evtchn(import->local_port); 3.1098 - 3.1099 - 3.1100 - self_id = xenbus_get_self_id(); 3.1101 - /* Write the frontend info to a node in our Xenbus */ 3.1102 - sprintf(nodename, "/local/domain/%d/device/vfs/%d", 3.1103 - self_id, import->import_id); 3.1104 - 3.1105 -again: 3.1106 - err = xenbus_transaction_start(&xbt); 3.1107 - if (err) { 3.1108 - printk("starting transaction\n"); 3.1109 - free(err); 3.1110 - } 3.1111 - 3.1112 - err = xenbus_printf(xbt, 3.1113 - nodename, 3.1114 - "ring-size", 3.1115 - "%u", 3.1116 - FSIF_RING_SIZE_PAGES); 3.1117 - if (err) { 3.1118 - message = "writing ring-size"; 3.1119 - goto abort_transaction; 3.1120 - } 3.1121 - 3.1122 - for(i=0; i<FSIF_RING_SIZE_PAGES; i++) 3.1123 - { 3.1124 - sprintf(r_nodename, "ring-ref-%d", i); 3.1125 - err = xenbus_printf(xbt, 3.1126 - nodename, 3.1127 - r_nodename, 3.1128 - "%u", 3.1129 - import->gnt_refs[i]); 3.1130 - if (err) { 3.1131 - message = "writing ring-refs"; 3.1132 - goto abort_transaction; 3.1133 - } 3.1134 - } 3.1135 - 3.1136 - err = xenbus_printf(xbt, 3.1137 - nodename, 3.1138 - "event-channel", 3.1139 - "%u", 3.1140 - import->local_port); 3.1141 - if (err) { 3.1142 - message = "writing event-channel"; 3.1143 - goto abort_transaction; 3.1144 - } 3.1145 - 3.1146 - err = xenbus_printf(xbt, nodename, "state", STATE_READY, 0xdeadbeef); 3.1147 - if (err) free(err); 3.1148 - 3.1149 - err = xenbus_transaction_end(xbt, 0, &retry); 3.1150 - if (err) free(err); 3.1151 - if (retry) { 3.1152 - goto again; 3.1153 - printk("completing transaction\n"); 3.1154 - } 3.1155 - 3.1156 - /* Now, when our node is prepared we write request in the exporting domain 3.1157 - * */ 3.1158 - printk("Our own id is %d\n", self_id); 3.1159 - sprintf(r_nodename, 3.1160 - "/local/domain/%d/backend/vfs/exports/requests/%d/%d/frontend", 3.1161 - import->dom_id, self_id, import->export_id); 3.1162 - BUG_ON(xenbus_write(XBT_NIL, r_nodename, nodename)); 3.1163 - 3.1164 - goto done; 3.1165 - 3.1166 -abort_transaction: 3.1167 - free(err); 3.1168 - err = xenbus_transaction_end(xbt, 1, &retry); 3.1169 - if (err) free(err); 3.1170 - 3.1171 -done: 3.1172 - 3.1173 -#define WAIT_PERIOD 10 /* Wait period in ms */ 3.1174 -#define MAX_WAIT 10 /* Max number of WAIT_PERIODs */ 3.1175 - import->backend = NULL; 3.1176 - sprintf(r_nodename, "%s/backend", nodename); 3.1177 - 3.1178 - for(retry = MAX_WAIT; retry > 0; retry--) 3.1179 - { 3.1180 - xenbus_read(XBT_NIL, r_nodename, &import->backend); 3.1181 - if(import->backend) 3.1182 - { 3.1183 - printk("Backend found at %s\n", import->backend); 3.1184 - break; 3.1185 - } 3.1186 - msleep(WAIT_PERIOD); 3.1187 - } 3.1188 - 3.1189 - if(!import->backend) 3.1190 - { 3.1191 - printk("No backend available.\n"); 3.1192 - /* TODO - cleanup datastructures/xenbus */ 3.1193 - return 0; 3.1194 - } 3.1195 - sprintf(r_nodename, "%s/state", import->backend); 3.1196 - sprintf(token, "fs-front-%d", import->import_id); 3.1197 - /* The token will not be unique if multiple imports are inited */ 3.1198 - xenbus_watch_path_token(XBT_NIL, r_nodename, r_nodename, &events); 3.1199 - err = xenbus_wait_for_value(r_nodename, STATE_READY, &events); 3.1200 - if (err) free(err); 3.1201 - xenbus_unwatch_path_token(XBT_NIL, r_nodename, r_nodename); 3.1202 - printk("Backend ready.\n"); 3.1203 - 3.1204 - //create_thread("fs-tester", test_fs_import, import); 3.1205 - 3.1206 - return 1; 3.1207 -} 3.1208 - 3.1209 -static void add_export(struct minios_list_head *exports, unsigned int domid) 3.1210 -{ 3.1211 - char node[1024], **exports_list = NULL, *ret_msg; 3.1212 - int j = 0; 3.1213 - static int import_id = 0; 3.1214 - 3.1215 - sprintf(node, "/local/domain/%d/backend/vfs/exports", domid); 3.1216 - ret_msg = xenbus_ls(XBT_NIL, node, &exports_list); 3.1217 - if (ret_msg && strcmp(ret_msg, "ENOENT")) 3.1218 - printk("couldn't read %s: %s\n", node, ret_msg); 3.1219 - while(exports_list && exports_list[j]) 3.1220 - { 3.1221 - struct fs_import *import; 3.1222 - int export_id = -1; 3.1223 - 3.1224 - sscanf(exports_list[j], "%d", &export_id); 3.1225 - if(export_id >= 0) 3.1226 - { 3.1227 - import = xmalloc(struct fs_import); 3.1228 - import->dom_id = domid; 3.1229 - import->export_id = export_id; 3.1230 - import->import_id = import_id++; 3.1231 - MINIOS_INIT_LIST_HEAD(&import->list); 3.1232 - minios_list_add(&import->list, exports); 3.1233 - } 3.1234 - free(exports_list[j]); 3.1235 - j++; 3.1236 - } 3.1237 - if(exports_list) 3.1238 - free(exports_list); 3.1239 - if(ret_msg) 3.1240 - free(ret_msg); 3.1241 -} 3.1242 - 3.1243 -#if 0 3.1244 -static struct minios_list_head* probe_exports(void) 3.1245 -{ 3.1246 - struct minios_list_head *exports; 3.1247 - char **node_list = NULL, *msg = NULL; 3.1248 - int i = 0; 3.1249 - 3.1250 - exports = xmalloc(struct minios_list_head); 3.1251 - MINIOS_INIT_LIST_HEAD(exports); 3.1252 - 3.1253 - msg = xenbus_ls(XBT_NIL, "/local/domain", &node_list); 3.1254 - if(msg) 3.1255 - { 3.1256 - printk("Could not list VFS exports (%s).\n", msg); 3.1257 - goto exit; 3.1258 - } 3.1259 - 3.1260 - while(node_list[i]) 3.1261 - { 3.1262 - add_export(exports, atoi(node_list[i])); 3.1263 - free(node_list[i]); 3.1264 - i++; 3.1265 - } 3.1266 - 3.1267 -exit: 3.1268 - if(msg) 3.1269 - free(msg); 3.1270 - if(node_list) 3.1271 - free(node_list); 3.1272 - return exports; 3.1273 -} 3.1274 -#endif 3.1275 - 3.1276 -MINIOS_LIST_HEAD(exports); 3.1277 - 3.1278 -void init_fs_frontend(void) 3.1279 -{ 3.1280 - struct minios_list_head *entry; 3.1281 - struct fs_import *import = NULL; 3.1282 - printk("Initing FS frontend(s).\n"); 3.1283 - 3.1284 - add_export(&exports, 0); 3.1285 - minios_list_for_each(entry, &exports) 3.1286 - { 3.1287 - import = minios_list_entry(entry, struct fs_import, list); 3.1288 - printk("FS export [dom=%d, id=%d] found\n", 3.1289 - import->dom_id, import->export_id); 3.1290 - if (init_fs_import(import) != 0) { 3.1291 - fs_import = import; 3.1292 - break; 3.1293 - } 3.1294 - } 3.1295 - 3.1296 - if (!fs_import) 3.1297 - printk("No FS import\n"); 3.1298 -} 3.1299 - 3.1300 -/* TODO: shutdown */
4.1 --- a/extras/mini-os/include/fbfront.h Tue Jan 11 19:31:41 2011 +0000 4.2 +++ b/extras/mini-os/include/fbfront.h Tue Jan 11 19:41:53 2011 +0000 4.3 @@ -1,5 +1,6 @@ 4.4 #include <xen/io/kbdif.h> 4.5 #include <xen/io/fbif.h> 4.6 +#include <mini-os/semaphore.h> 4.7 #include <mini-os/wait.h> 4.8 4.9 /* from <linux/input.h> */
5.1 --- a/extras/mini-os/include/fs.h Tue Jan 11 19:31:41 2011 +0000 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,56 +0,0 @@ 5.4 -#ifndef __FS_H__ 5.5 -#define __FS_H__ 5.6 - 5.7 -#include <xen/io/fsif.h> 5.8 -#include <mini-os/semaphore.h> 5.9 -#include <mini-os/types.h> 5.10 - 5.11 -#define FSIF_RING_SIZE_ORDER 1 5.12 -#define FSIF_RING_SIZE_PAGES (1<<FSIF_RING_SIZE_ORDER) 5.13 - 5.14 -struct fs_import 5.15 -{ 5.16 - domid_t dom_id; /* dom id of the exporting domain */ 5.17 - uint16_t export_id; /* export id (exporting dom specific) */ 5.18 - uint16_t import_id; /* import id (specific to this domain) */ 5.19 - struct minios_list_head list; /* list of all imports */ 5.20 - unsigned int nr_entries; /* Number of entries in rings & request 5.21 - array */ 5.22 - struct fsif_front_ring ring; /* frontend ring (contains shared ring) */ 5.23 - uint32_t gnt_refs[FSIF_RING_SIZE_PAGES]; /* grant references to the shared ring */ 5.24 - evtchn_port_t local_port; /* local event channel port */ 5.25 - char *backend; /* XenBus location of the backend */ 5.26 - struct fs_request *requests; /* Table of requests */ 5.27 - unsigned short *freelist; /* List of free request ids */ 5.28 - struct semaphore reqs_sem; /* Accounts requests resource */ 5.29 -}; 5.30 - 5.31 -extern struct fs_import *fs_import; 5.32 - 5.33 -void init_fs_frontend(void); 5.34 - 5.35 -int fs_open(struct fs_import *import, char *file); 5.36 -int fs_close(struct fs_import *import, int fd); 5.37 -ssize_t fs_read(struct fs_import *import, int fd, void *buf, 5.38 - ssize_t len, ssize_t offset); 5.39 -ssize_t fs_write(struct fs_import *import, int fd, void *buf, 5.40 - ssize_t len, ssize_t offset); 5.41 -int fs_stat(struct fs_import *import, 5.42 - int fd, 5.43 - struct fsif_stat_response *stat); 5.44 -int fs_truncate(struct fs_import *import, 5.45 - int fd, 5.46 - int64_t length); 5.47 -int fs_remove(struct fs_import *import, char *file); 5.48 -int fs_rename(struct fs_import *import, 5.49 - char *old_file_name, 5.50 - char *new_file_name); 5.51 -int fs_create(struct fs_import *import, char *name, 5.52 - int8_t directory, int32_t mode); 5.53 -char** fs_list(struct fs_import *import, char *name, 5.54 - int32_t offset, int32_t *nr_files, int *has_more); 5.55 -int fs_chmod(struct fs_import *import, int fd, int32_t mode); 5.56 -int64_t fs_space(struct fs_import *import, char *location); 5.57 -int fs_sync(struct fs_import *import, int fd); 5.58 - 5.59 -#endif
6.1 --- a/extras/mini-os/kernel.c Tue Jan 11 19:31:41 2011 +0000 6.2 +++ b/extras/mini-os/kernel.c Tue Jan 11 19:41:53 2011 +0000 6.3 @@ -41,7 +41,6 @@ 6.4 #include <mini-os/blkfront.h> 6.5 #include <mini-os/fbfront.h> 6.6 #include <mini-os/pcifront.h> 6.7 -#include <mini-os/fs.h> 6.8 #include <mini-os/xmalloc.h> 6.9 #include <fcntl.h> 6.10 #include <xen/features.h> 6.11 @@ -456,11 +455,6 @@ static void pcifront_thread(void *p) 6.12 pcifront_scan(pci_dev, print_pcidev); 6.13 } 6.14 6.15 -static void fs_thread(void *p) 6.16 -{ 6.17 - init_fs_frontend(); 6.18 -} 6.19 - 6.20 /* This should be overridden by the application we are linked against. */ 6.21 __attribute__((weak)) int app_main(start_info_t *si) 6.22 { 6.23 @@ -472,7 +466,6 @@ static void fs_thread(void *p) 6.24 create_thread("fbfront", fbfront_thread, si); 6.25 create_thread("kbdfront", kbdfront_thread, si); 6.26 create_thread("pcifront", pcifront_thread, si); 6.27 - create_thread("fs-frontend", fs_thread, si); 6.28 return 0; 6.29 } 6.30
7.1 --- a/extras/mini-os/lib/math.c Tue Jan 11 19:31:41 2011 +0000 7.2 +++ b/extras/mini-os/lib/math.c Tue Jan 11 19:41:53 2011 +0000 7.3 @@ -70,8 +70,8 @@ 7.4 union uu { 7.5 int64_t q; /* as a (signed) quad */ 7.6 int64_t uq; /* as an unsigned quad */ 7.7 - long sl[2]; /* as two signed longs */ 7.8 - unsigned long ul[2]; /* as two unsigned longs */ 7.9 + int32_t sl[2]; /* as two signed ints */ 7.10 + uint32_t ul[2]; /* as two unsigned ints */ 7.11 }; 7.12 /* XXX RN: Yuck hardcoded endianess :) */ 7.13 #define _QUAD_HIGHWORD 1 7.14 @@ -91,17 +91,17 @@ union uu { 7.15 #define CHAR_BIT 8 /* number of bits in a char */ 7.16 #endif 7.17 #define QUAD_BITS (sizeof(int64_t) * CHAR_BIT) 7.18 -#define LONG_BITS (sizeof(long) * CHAR_BIT) 7.19 -#define HALF_BITS (sizeof(long) * CHAR_BIT / 2) 7.20 +#define LONG_BITS (sizeof(int32_t) * CHAR_BIT) 7.21 +#define HALF_BITS (sizeof(int32_t) * CHAR_BIT / 2) 7.22 7.23 /* 7.24 - * Extract high and low shortwords from longword, and move low shortword of 7.25 - * longword to upper half of long, i.e., produce the upper longword of 7.26 - * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.) 7.27 + * Extract high and low shortwords from intword, and move low shortword of 7.28 + * intword to upper half of int32_t, i.e., produce the upper intword of 7.29 + * ((quad_t)(x) << (number_of_bits_in_int/2)). (`x' must actually be uint32_t.) 7.30 * 7.31 - * These are used in the multiply code, to split a longword into upper 7.32 + * These are used in the multiply code, to split a intword into upper 7.33 * and lower halves, and to reassemble a product as a quad_t, shifted left 7.34 - * (sizeof(long)*CHAR_BIT/2). 7.35 + * (sizeof(int32_t)*CHAR_BIT/2). 7.36 */ 7.37 #define HHALF(x) ((x) >> HALF_BITS) 7.38 #define LHALF(x) ((x) & ((1UL << HALF_BITS) - 1)) 7.39 @@ -114,14 +114,10 @@ union uu { 7.40 #define B (1UL << HALF_BITS) /* digit base */ 7.41 7.42 /* Combine two `digits' to make a single two-digit number. */ 7.43 -#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b)) 7.44 +#define COMBINE(a, b) (((uint32_t)(a) << HALF_BITS) | (b)) 7.45 7.46 -/* select a type for digits in base B: use unsigned short if they fit */ 7.47 -#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff 7.48 -typedef unsigned short digit; 7.49 -#else 7.50 -typedef u_long digit; 7.51 -#endif 7.52 +/* select a type for digits in base B: */ 7.53 +typedef uint16_t digit; 7.54 7.55 7.56 /* 7.57 @@ -143,7 +139,7 @@ shl(register digit *p, register int len, 7.58 * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v. 7.59 * 7.60 * We do this in base 2-sup-HALF_BITS, so that all intermediate products 7.61 - * fit within u_long. As a consequence, the maximum length dividend and 7.62 + * fit within uint32_t. As a consequence, the maximum length dividend and 7.63 * divisor are 4 `digits' in this base (they are shorter if they have 7.64 * leading zeros). 7.65 */ 7.66 @@ -153,7 +149,7 @@ uint64_t 7.67 union uu tmp; 7.68 digit *u, *v, *q; 7.69 register digit v1, v2; 7.70 - u_long qhat, rhat, t; 7.71 + uint32_t qhat, rhat, t; 7.72 int m, n, d, j, i; 7.73 digit uspace[5], vspace[5], qspace[5]; 7.74 7.75 @@ -204,7 +200,7 @@ uint64_t 7.76 v[4] = LHALF(tmp.ul[L]); 7.77 for (n = 4; v[1] == 0; v++) { 7.78 if (--n == 1) { 7.79 - u_long rbj; /* r*B+u[j] (not root boy jim) */ 7.80 + uint32_t rbj; /* r*B+u[j] (not root boy jim) */ 7.81 digit q1, q2, q3, q4; 7.82 7.83 /* 7.84 @@ -280,7 +276,7 @@ uint64_t 7.85 rhat = uj1; 7.86 goto qhat_too_big; 7.87 } else { 7.88 - u_long nn = COMBINE(uj0, uj1); 7.89 + uint32_t nn = COMBINE(uj0, uj1); 7.90 qhat = nn / v1; 7.91 rhat = nn % v1; 7.92 }
8.1 --- a/extras/mini-os/lib/sys.c Tue Jan 11 19:31:41 2011 +0000 8.2 +++ b/extras/mini-os/lib/sys.c Tue Jan 11 19:41:53 2011 +0000 8.3 @@ -47,7 +47,6 @@ 8.4 #ifdef HAVE_LWIP 8.5 #include <lwip/sockets.h> 8.6 #endif 8.7 -#include <fs.h> 8.8 8.9 #define debug(fmt, ...) \ 8.10 8.11 @@ -158,13 +157,8 @@ char *getcwd(char *buf, size_t size) 8.12 8.13 int mkdir(const char *pathname, mode_t mode) 8.14 { 8.15 - int ret; 8.16 - ret = fs_create(fs_import, (char *) pathname, 1, mode); 8.17 - if (ret < 0) { 8.18 - errno = EIO; 8.19 - return -1; 8.20 - } 8.21 - return 0; 8.22 + errno = EIO; 8.23 + return -1; 8.24 } 8.25 8.26 int posix_openpt(int flags) 8.27 @@ -183,7 +177,7 @@ int posix_openpt(int flags) 8.28 8.29 int open(const char *pathname, int flags, ...) 8.30 { 8.31 - int fs_fd, fd; 8.32 + int fd; 8.33 /* Ugly, but fine. */ 8.34 if (!strncmp(pathname,LOG_PATH,strlen(LOG_PATH))) { 8.35 fd = alloc_fd(FTYPE_CONSOLE); 8.36 @@ -197,34 +191,8 @@ int open(const char *pathname, int flags 8.37 } 8.38 if (!strncmp(pathname, "/dev/ptmx", strlen("/dev/ptmx"))) 8.39 return posix_openpt(flags); 8.40 - printk("open(%s, %x)", pathname, flags); 8.41 - switch (flags & ~O_ACCMODE) { 8.42 - case 0: 8.43 - fs_fd = fs_open(fs_import, (void *) pathname); 8.44 - break; 8.45 - case O_CREAT|O_TRUNC: 8.46 - { 8.47 - va_list ap; 8.48 - mode_t mode; 8.49 - va_start(ap, flags); 8.50 - mode = va_arg(ap, mode_t); 8.51 - va_end(ap); 8.52 - fs_fd = fs_create(fs_import, (void *) pathname, 0, mode); 8.53 - break; 8.54 - } 8.55 - default: 8.56 - printk(" unsupported flags\n"); 8.57 - do_exit(); 8.58 - } 8.59 - if (fs_fd < 0) { 8.60 - errno = EIO; 8.61 - return -1; 8.62 - } 8.63 - fd = alloc_fd(FTYPE_FILE); 8.64 - printk("-> %d\n", fd); 8.65 - files[fd].file.fd = fs_fd; 8.66 - files[fd].file.offset = 0; 8.67 - return fd; 8.68 + errno = EIO; 8.69 + return -1; 8.70 } 8.71 8.72 int isatty(int fd) 8.73 @@ -248,20 +216,6 @@ int read(int fd, void *buf, size_t nbyte 8.74 remove_waiter(w); 8.75 return ret; 8.76 } 8.77 - case FTYPE_FILE: { 8.78 - ssize_t ret; 8.79 - if (nbytes > PAGE_SIZE * FSIF_NR_READ_GNTS) 8.80 - nbytes = PAGE_SIZE * FSIF_NR_READ_GNTS; 8.81 - ret = fs_read(fs_import, files[fd].file.fd, buf, nbytes, files[fd].file.offset); 8.82 - if (ret > 0) { 8.83 - files[fd].file.offset += ret; 8.84 - return ret; 8.85 - } else if (ret < 0) { 8.86 - errno = EIO; 8.87 - return -1; 8.88 - } 8.89 - return 0; 8.90 - } 8.91 #ifdef HAVE_LWIP 8.92 case FTYPE_SOCKET: 8.93 return lwip_read(files[fd].socket.fd, buf, nbytes); 8.94 @@ -309,20 +263,6 @@ int write(int fd, const void *buf, size_ 8.95 case FTYPE_CONSOLE: 8.96 console_print(files[fd].cons.dev, (char *)buf, nbytes); 8.97 return nbytes; 8.98 - case FTYPE_FILE: { 8.99 - ssize_t ret; 8.100 - if (nbytes > PAGE_SIZE * FSIF_NR_WRITE_GNTS) 8.101 - nbytes = PAGE_SIZE * FSIF_NR_WRITE_GNTS; 8.102 - ret = fs_write(fs_import, files[fd].file.fd, (void *) buf, nbytes, files[fd].file.offset); 8.103 - if (ret > 0) { 8.104 - files[fd].file.offset += ret; 8.105 - return ret; 8.106 - } else if (ret < 0) { 8.107 - errno = EIO; 8.108 - return -1; 8.109 - } 8.110 - return 0; 8.111 - } 8.112 #ifdef HAVE_LWIP 8.113 case FTYPE_SOCKET: 8.114 return lwip_write(files[fd].socket.fd, (void*) buf, nbytes); 8.115 @@ -340,48 +280,11 @@ int write(int fd, const void *buf, size_ 8.116 8.117 off_t lseek(int fd, off_t offset, int whence) 8.118 { 8.119 - if (files[fd].type != FTYPE_FILE) { 8.120 - errno = ESPIPE; 8.121 - return (off_t) -1; 8.122 - } 8.123 - switch (whence) { 8.124 - case SEEK_SET: 8.125 - files[fd].file.offset = offset; 8.126 - break; 8.127 - case SEEK_CUR: 8.128 - files[fd].file.offset += offset; 8.129 - break; 8.130 - case SEEK_END: { 8.131 - struct stat st; 8.132 - int ret; 8.133 - ret = fstat(fd, &st); 8.134 - if (ret) 8.135 - return -1; 8.136 - files[fd].file.offset = st.st_size + offset; 8.137 - break; 8.138 - } 8.139 - default: 8.140 - errno = EINVAL; 8.141 - return -1; 8.142 - } 8.143 - return files[fd].file.offset; 8.144 + errno = ESPIPE; 8.145 + return (off_t) -1; 8.146 } 8.147 8.148 int fsync(int fd) { 8.149 - switch (files[fd].type) { 8.150 - case FTYPE_FILE: { 8.151 - int ret; 8.152 - ret = fs_sync(fs_import, files[fd].file.fd); 8.153 - if (ret < 0) { 8.154 - errno = EIO; 8.155 - return -1; 8.156 - } 8.157 - return 0; 8.158 - } 8.159 - default: 8.160 - break; 8.161 - } 8.162 - printk("fsync(%d): Bad descriptor\n", fd); 8.163 errno = EBADF; 8.164 return -1; 8.165 } 8.166 @@ -393,15 +296,6 @@ int close(int fd) 8.167 default: 8.168 files[fd].type = FTYPE_NONE; 8.169 return 0; 8.170 - case FTYPE_FILE: { 8.171 - int ret = fs_close(fs_import, files[fd].file.fd); 8.172 - files[fd].type = FTYPE_NONE; 8.173 - if (ret < 0) { 8.174 - errno = EIO; 8.175 - return -1; 8.176 - } 8.177 - return 0; 8.178 - } 8.179 case FTYPE_XENBUS: 8.180 xs_daemon_close((void*)(intptr_t) fd); 8.181 return 0; 8.182 @@ -460,43 +354,10 @@ static void init_stat(struct stat *buf) 8.183 buf->st_blocks = 0; 8.184 } 8.185 8.186 -static void stat_from_fs(struct stat *buf, struct fsif_stat_response *stat) 8.187 -{ 8.188 - buf->st_mode = stat->stat_mode; 8.189 - buf->st_uid = stat->stat_uid; 8.190 - buf->st_gid = stat->stat_gid; 8.191 - buf->st_size = stat->stat_size; 8.192 - buf->st_atime = stat->stat_atime; 8.193 - buf->st_mtime = stat->stat_mtime; 8.194 - buf->st_ctime = stat->stat_ctime; 8.195 -} 8.196 - 8.197 int stat(const char *path, struct stat *buf) 8.198 { 8.199 - struct fsif_stat_response stat; 8.200 - int ret; 8.201 - int fs_fd; 8.202 - printk("stat(%s)\n", path); 8.203 - fs_fd = fs_open(fs_import, (char*) path); 8.204 - if (fs_fd < 0) { 8.205 - errno = EIO; 8.206 - ret = -1; 8.207 - goto out; 8.208 - } 8.209 - ret = fs_stat(fs_import, fs_fd, &stat); 8.210 - if (ret < 0) { 8.211 - errno = EIO; 8.212 - ret = -1; 8.213 - goto outfd; 8.214 - } 8.215 - init_stat(buf); 8.216 - stat_from_fs(buf, &stat); 8.217 - ret = 0; 8.218 - 8.219 -outfd: 8.220 - fs_close(fs_import, fs_fd); 8.221 -out: 8.222 - return ret; 8.223 + errno = EIO; 8.224 + return -1; 8.225 } 8.226 8.227 int fstat(int fd, struct stat *buf) 8.228 @@ -514,18 +375,6 @@ int fstat(int fd, struct stat *buf) 8.229 buf->st_ctime = time(NULL); 8.230 return 0; 8.231 } 8.232 - case FTYPE_FILE: { 8.233 - struct fsif_stat_response stat; 8.234 - int ret; 8.235 - ret = fs_stat(fs_import, files[fd].file.fd, &stat); 8.236 - if (ret < 0) { 8.237 - errno = EIO; 8.238 - return -1; 8.239 - } 8.240 - /* The protocol is a bit evasive about this value */ 8.241 - stat_from_fs(buf, &stat); 8.242 - return 0; 8.243 - } 8.244 default: 8.245 break; 8.246 } 8.247 @@ -537,35 +386,14 @@ int fstat(int fd, struct stat *buf) 8.248 8.249 int ftruncate(int fd, off_t length) 8.250 { 8.251 - switch (files[fd].type) { 8.252 - case FTYPE_FILE: { 8.253 - int ret; 8.254 - ret = fs_truncate(fs_import, files[fd].file.fd, length); 8.255 - if (ret < 0) { 8.256 - errno = EIO; 8.257 - return -1; 8.258 - } 8.259 - return 0; 8.260 - } 8.261 - default: 8.262 - break; 8.263 - } 8.264 - 8.265 - printk("ftruncate(%d): Bad descriptor\n", fd); 8.266 errno = EBADF; 8.267 return -1; 8.268 } 8.269 8.270 int remove(const char *pathname) 8.271 { 8.272 - int ret; 8.273 - printk("remove(%s)", pathname); 8.274 - ret = fs_remove(fs_import, (char*) pathname); 8.275 - if (ret < 0) { 8.276 - errno = EIO; 8.277 - return -1; 8.278 - } 8.279 - return 0; 8.280 + errno = EIO; 8.281 + return -1; 8.282 } 8.283 8.284 int unlink(const char *pathname) 8.285 @@ -618,26 +446,9 @@ DIR *opendir(const char *name) 8.286 8.287 struct dirent *readdir(DIR *dir) 8.288 { 8.289 - if (dir->curentry >= 0) { 8.290 - free(dir->entries[dir->curentry]); 8.291 - dir->entries[dir->curentry] = NULL; 8.292 - } 8.293 - dir->curentry++; 8.294 - if (dir->curentry >= dir->nbentries) { 8.295 - dir->offset += dir->nbentries; 8.296 - free(dir->entries); 8.297 - dir->curentry = -1; 8.298 - dir->nbentries = 0; 8.299 - if (!dir->has_more) 8.300 - return NULL; 8.301 - dir->entries = fs_list(fs_import, dir->name, dir->offset, &dir->nbentries, &dir->has_more); 8.302 - if (!dir->entries || !dir->nbentries) 8.303 - return NULL; 8.304 - dir->curentry = 0; 8.305 - } 8.306 - dir->dirent.d_name = dir->entries[dir->curentry]; 8.307 - return &dir->dirent; 8.308 + return NULL; 8.309 } 8.310 + 8.311 int closedir(DIR *dir) 8.312 { 8.313 int i; 8.314 @@ -654,7 +465,6 @@ int closedir(DIR *dir) 8.315 static const char file_types[] = { 8.316 [FTYPE_NONE] = 'N', 8.317 [FTYPE_CONSOLE] = 'C', 8.318 - [FTYPE_FILE] = 'F', 8.319 [FTYPE_XENBUS] = 'S', 8.320 [FTYPE_XC] = 'X', 8.321 [FTYPE_EVTCHN] = 'E', 8.322 @@ -753,11 +563,6 @@ static int select_poll(int nfds, fd_set 8.323 if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds)) 8.324 printk("bogus fd %d in select\n", i); 8.325 /* Fallthrough. */ 8.326 - case FTYPE_FILE: 8.327 - FD_CLR(i, readfds); 8.328 - FD_CLR(i, writefds); 8.329 - FD_CLR(i, exceptfds); 8.330 - break; 8.331 case FTYPE_CONSOLE: 8.332 if (FD_ISSET(i, readfds)) { 8.333 if (xencons_ring_avail(files[i].cons.dev))
9.1 --- a/extras/mini-os/main.c Tue Jan 11 19:31:41 2011 +0000 9.2 +++ b/extras/mini-os/main.c Tue Jan 11 19:41:53 2011 +0000 9.3 @@ -13,7 +13,6 @@ 9.4 #include <time.h> 9.5 #include <stdlib.h> 9.6 #include <unistd.h> 9.7 -#include <fs.h> 9.8 #include <xenbus.h> 9.9 #include <events.h> 9.10 9.11 @@ -66,7 +65,6 @@ static void call_main(void *p) 9.12 #if defined(HAVE_LWIP) && !defined(CONFIG_QEMU) 9.13 start_networking(); 9.14 #endif 9.15 - init_fs_frontend(); 9.16 #endif 9.17 create_thread("pcifront", pcifront_watches, NULL); 9.18
10.1 --- a/stubdom/stubdom-dm Tue Jan 11 19:31:41 2011 +0000 10.2 +++ b/stubdom/stubdom-dm Tue Jan 11 19:41:53 2011 +0000 10.3 @@ -91,7 +91,7 @@ trap term SIGHUP 10.4 ############ 10.5 # stubdomain 10.6 # Wait for any previous stubdom to terminate 10.7 -while xm list | grep $domname-dm 10.8 +while xm list | grep -w $domname-dm 10.9 do 10.10 sleep 1 10.11 done
11.1 --- a/tools/Makefile Tue Jan 11 19:31:41 2011 +0000 11.2 +++ b/tools/Makefile Tue Jan 11 19:41:53 2011 +0000 11.3 @@ -28,8 +28,6 @@ SUBDIRS-$(CONFIG_NetBSD) += blktap2 11.4 SUBDIRS-$(CONFIG_NetBSD) += xenbackendd 11.5 SUBDIRS-y += libfsimage 11.6 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen 11.7 -SUBDIRS-$(CONFIG_Linux) += fs-back 11.8 -SUBDIRS-$(CONFIG_NetBSD) += fs-back 11.9 11.10 # do not recurse in to a dir we are about to delete 11.11 ifneq "$(MAKECMDGOALS)" "distclean"
12.1 --- a/tools/fs-back/Makefile Tue Jan 11 19:31:41 2011 +0000 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,36 +0,0 @@ 12.4 -XEN_ROOT = ../.. 12.5 -include $(XEN_ROOT)/tools/Rules.mk 12.6 - 12.7 -INCLUDES += -I.. -I../lib 12.8 - 12.9 -IBIN = fs-backend 12.10 - 12.11 -CFLAGS += -Werror 12.12 -CFLAGS += -Wno-unused 12.13 -CFLAGS += -fno-strict-aliasing 12.14 -CFLAGS += $(CFLAGS_libxenctrl) 12.15 -CFLAGS += $(CFLAGS_libxenstore) 12.16 -CFLAGS += $(INCLUDES) -I. 12.17 -CFLAGS += -D_GNU_SOURCE 12.18 - 12.19 -LIBS := -L. -L.. -L../lib 12.20 -LIBS += $(LDLIBS_libxenctrl) 12.21 -LIBS += $(LDLIBS_libxenstore) 12.22 -LIBS += -lrt -lpthread 12.23 - 12.24 -OBJS := fs-xenbus.o fs-ops.o 12.25 - 12.26 -all: $(IBIN) 12.27 - 12.28 -fs-backend: $(OBJS) fs-backend.c 12.29 - $(CC) $(CFLAGS) -o fs-backend $(OBJS) $(LIBS) fs-backend.c 12.30 - 12.31 -install: all 12.32 - $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(SBINDIR) 12.33 - 12.34 -clean: 12.35 - rm -rf *.o *~ $(DEPS) xen $(IBIN) $(LIB) 12.36 - 12.37 -.PHONY: clean install 12.38 - 12.39 --include $(DEPS)
13.1 --- a/tools/fs-back/fs-backend.c Tue Jan 11 19:31:41 2011 +0000 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,500 +0,0 @@ 13.4 -#undef NDEBUG 13.5 -#include <unistd.h> 13.6 -#include <stdio.h> 13.7 -#include <string.h> 13.8 -#include <assert.h> 13.9 -#include <malloc.h> 13.10 -#include <xenctrl.h> 13.11 -#include <aio.h> 13.12 -#include <sys/mman.h> 13.13 -#include <sys/select.h> 13.14 -#include <sys/socket.h> 13.15 -#include <xen/io/ring.h> 13.16 -#include <xc_private.h> 13.17 -#include <err.h> 13.18 -#include "sys-queue.h" 13.19 -#include "fs-backend.h" 13.20 -#include "fs-debug.h" 13.21 - 13.22 -struct xs_handle *xsh = NULL; 13.23 -static struct fs_export *fs_exports = NULL; 13.24 -static int export_id = 0; 13.25 -static int mount_id = 0; 13.26 -static int pipefds[2]; 13.27 -static LIST_HEAD(mount_requests_head, fs_mount) mount_requests_head; 13.28 - 13.29 -static void free_mount_request(struct fs_mount *mount); 13.30 - 13.31 -static void dispatch_response(struct fs_request *request) 13.32 -{ 13.33 - int i; 13.34 - struct fs_op *op; 13.35 - 13.36 - for(i=0;;i++) 13.37 - { 13.38 - op = fsops[i]; 13.39 - /* We should dispatch a response before reaching the end of the array */ 13.40 - assert(op != NULL); 13.41 - if(op->type == request->req_shadow.type) 13.42 - { 13.43 - FS_DEBUG("Found op for type=%d\n", op->type); 13.44 - /* There needs to be a response handler */ 13.45 - assert(op->response_handler != NULL); 13.46 - op->response_handler(request->mount, request); 13.47 - break; 13.48 - } 13.49 - } 13.50 - 13.51 - request->active = 0; 13.52 - add_id_to_freelist(request->id, request->mount->freelist); 13.53 -} 13.54 - 13.55 -static void handle_aio_event(struct fs_request *request) 13.56 -{ 13.57 - int ret, notify; 13.58 - 13.59 - FS_DEBUG("handle_aio_event: mount %s request %d\n", request->mount->frontend, request->id); 13.60 - if (request->active < 0) { 13.61 - request->mount->nr_entries++; 13.62 - if (!request->mount->nr_entries) 13.63 - free_mount_request(request->mount); 13.64 - return; 13.65 - } 13.66 - 13.67 - ret = aio_error(&request->aiocb); 13.68 - if(ret != EINPROGRESS && ret != ECANCELED) 13.69 - dispatch_response(request); 13.70 - 13.71 - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&request->mount->ring, notify); 13.72 - FS_DEBUG("Pushed responces and notify=%d\n", notify); 13.73 - if(notify) 13.74 - xc_evtchn_notify(request->mount->evth, request->mount->local_evtchn); 13.75 -} 13.76 - 13.77 -static void allocate_request_array(struct fs_mount *mount) 13.78 -{ 13.79 - int i, nr_entries = mount->nr_entries; 13.80 - struct fs_request *requests; 13.81 - unsigned short *freelist; 13.82 - 13.83 - requests = malloc(sizeof(struct fs_request) *nr_entries); 13.84 - freelist = malloc(sizeof(unsigned short) * (nr_entries + 1)); 13.85 - memset(requests, 0, sizeof(struct fs_request) * nr_entries); 13.86 - memset(freelist, 0, sizeof(unsigned short) * (nr_entries + 1)); 13.87 - for(i=0; i< nr_entries; i++) 13.88 - { 13.89 - requests[i].active = 0; 13.90 - requests[i].mount = mount; 13.91 - add_id_to_freelist(i, freelist); 13.92 - } 13.93 - mount->requests = requests; 13.94 - mount->freelist = freelist; 13.95 -} 13.96 - 13.97 - 13.98 -static void handle_mount(struct fs_mount *mount) 13.99 -{ 13.100 - int more, notify; 13.101 - int nr_consumed=0; 13.102 - RING_IDX cons, rp; 13.103 - struct fsif_request *req; 13.104 - 13.105 -moretodo: 13.106 - rp = mount->ring.sring->req_prod; 13.107 - xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ 13.108 - 13.109 - while ((cons = mount->ring.req_cons) != rp) 13.110 - { 13.111 - int i; 13.112 - struct fs_op *op; 13.113 - 13.114 - FS_DEBUG("Got a request at %d (of %d)\n", 13.115 - cons, RING_SIZE(&mount->ring)); 13.116 - req = RING_GET_REQUEST(&mount->ring, cons); 13.117 - FS_DEBUG("Request type=%d\n", req->type); 13.118 - for(i=0;;i++) 13.119 - { 13.120 - op = fsops[i]; 13.121 - if(op == NULL) 13.122 - { 13.123 - /* We've reached the end of the array, no appropirate 13.124 - * handler found. Warn, ignore and continue. */ 13.125 - FS_DEBUG("WARN: Unknown request type: %d\n", req->type); 13.126 - mount->ring.req_cons++; 13.127 - break; 13.128 - } 13.129 - if(op->type == req->type) 13.130 - { 13.131 - /* There needs to be a dispatch handler */ 13.132 - assert(op->dispatch_handler != NULL); 13.133 - op->dispatch_handler(mount, req); 13.134 - break; 13.135 - } 13.136 - } 13.137 - 13.138 - nr_consumed++; 13.139 - } 13.140 - FS_DEBUG("Backend consumed: %d requests\n", nr_consumed); 13.141 - RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more); 13.142 - if(more) goto moretodo; 13.143 - 13.144 - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify); 13.145 - FS_DEBUG("Pushed responces and notify=%d\n", notify); 13.146 - if(notify) 13.147 - xc_evtchn_notify(mount->evth, mount->local_evtchn); 13.148 -} 13.149 - 13.150 -void terminate_mount_request(struct fs_mount *mount) 13.151 -{ 13.152 - int count = 0, i; 13.153 - 13.154 - FS_DEBUG("terminate_mount_request %s\n", mount->frontend); 13.155 - xenbus_write_backend_state(mount, STATE_CLOSING); 13.156 - 13.157 - for(i=0; i<mount->nr_entries; i++) 13.158 - if(mount->requests[i].active) { 13.159 - mount->requests[i].active = -1; 13.160 - aio_cancel(mount->requests[i].aiocb.aio_fildes, &mount->requests[i].aiocb); 13.161 - count--; 13.162 - } 13.163 - mount->nr_entries = count; 13.164 - 13.165 - /* wait for the frontend to shut down but don't wait more than 3 13.166 - * seconds */ 13.167 - i = 0; 13.168 - while (!xenbus_frontend_state_changed(mount, STATE_CLOSING) && i < 3) { 13.169 - sleep(1); 13.170 - i++; 13.171 - } 13.172 - xenbus_write_backend_state(mount, STATE_CLOSED); 13.173 - 13.174 - xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size); 13.175 - xc_gnttab_close(mount->gnth); 13.176 - xc_evtchn_unbind(mount->evth, mount->local_evtchn); 13.177 - xc_evtchn_close(mount->evth); 13.178 - 13.179 - if (!count) 13.180 - free_mount_request(mount); 13.181 -} 13.182 - 13.183 -static void free_mount_request(struct fs_mount *mount) { 13.184 - FS_DEBUG("free_mount_request %s\n", mount->frontend); 13.185 - xenbus_free_backend_node(mount); 13.186 - free(mount->frontend); 13.187 - free(mount->requests); 13.188 - free(mount->freelist); 13.189 - LIST_REMOVE (mount, entries); 13.190 - free(mount); 13.191 -} 13.192 - 13.193 -static void handle_connection(int frontend_dom_id, int export_id, char *frontend) 13.194 -{ 13.195 - struct fs_mount *mount; 13.196 - struct fs_export *export; 13.197 - struct fsif_sring *sring = NULL; 13.198 - uint32_t dom_ids[MAX_RING_SIZE]; 13.199 - int i; 13.200 - 13.201 - FS_DEBUG("Handling connection from dom=%d, for export=%d\n", 13.202 - frontend_dom_id, export_id); 13.203 - /* Try to find the export on the list */ 13.204 - export = fs_exports; 13.205 - while(export) 13.206 - { 13.207 - if(export->export_id == export_id) 13.208 - break; 13.209 - export = export->next; 13.210 - } 13.211 - if(!export) 13.212 - { 13.213 - FS_DEBUG("Could not find the export (the id is unknown).\n"); 13.214 - return; 13.215 - } 13.216 - 13.217 - mount = (struct fs_mount*)malloc(sizeof(struct fs_mount)); 13.218 - memset(mount, 0, sizeof(struct fs_mount)); 13.219 - mount->xch = xc_interface_open(0,0,XC_OPENFLAG_DUMMY); 13.220 - if (!mount->xch) goto error; 13.221 - 13.222 - mount->dom_id = frontend_dom_id; 13.223 - mount->export = export; 13.224 - mount->mount_id = mount_id++; 13.225 - if (xenbus_read_mount_request(mount, frontend) < 0) 13.226 - goto error; 13.227 - FS_DEBUG("Frontend found at: %s (gref=%d, evtchn=%d)\n", 13.228 - mount->frontend, mount->grefs[0], mount->remote_evtchn); 13.229 - if (!xenbus_write_backend_node(mount)) { 13.230 - FS_DEBUG("ERROR: failed to write backend node on xenbus\n"); 13.231 - goto error; 13.232 - } 13.233 - mount->evth = NULL; 13.234 - mount->evth = xc_evtchn_open(NULL, 0); 13.235 - if (mount->evth == NULL) { 13.236 - FS_DEBUG("ERROR: Couldn't open evtchn!\n"); 13.237 - goto error; 13.238 - } 13.239 - mount->local_evtchn = -1; 13.240 - mount->local_evtchn = xc_evtchn_bind_interdomain(mount->evth, 13.241 - mount->dom_id, 13.242 - mount->remote_evtchn); 13.243 - if (mount->local_evtchn < 0) { 13.244 - FS_DEBUG("ERROR: Couldn't bind evtchn!\n"); 13.245 - goto error; 13.246 - } 13.247 - mount->gnth = NULL; 13.248 - mount->gnth = xc_gnttab_open(NULL, 0); 13.249 - if (mount->gnth == NULL) { 13.250 - FS_DEBUG("ERROR: Couldn't open gnttab!\n"); 13.251 - goto error; 13.252 - } 13.253 - for(i=0; i<mount->shared_ring_size; i++) 13.254 - dom_ids[i] = mount->dom_id; 13.255 - sring = xc_gnttab_map_grant_refs(mount->gnth, 13.256 - mount->shared_ring_size, 13.257 - dom_ids, 13.258 - mount->grefs, 13.259 - PROT_READ | PROT_WRITE); 13.260 - 13.261 - if (!sring) { 13.262 - FS_DEBUG("ERROR: Couldn't amp grant refs!\n"); 13.263 - goto error; 13.264 - } 13.265 - 13.266 - BACK_RING_INIT(&mount->ring, sring, mount->shared_ring_size * XC_PAGE_SIZE); 13.267 - mount->nr_entries = mount->ring.nr_ents; 13.268 - for (i = 0; i < MAX_FDS; i++) 13.269 - mount->fds[i] = -1; 13.270 - 13.271 - LIST_INSERT_HEAD(&mount_requests_head, mount, entries); 13.272 - if (!xenbus_watch_frontend_state(mount)) { 13.273 - FS_DEBUG("ERROR: failed to watch frontend state on xenbus\n"); 13.274 - goto error; 13.275 - } 13.276 - if (!xenbus_write_backend_state(mount, STATE_READY)) { 13.277 - FS_DEBUG("ERROR: failed to write backend state to xenbus\n"); 13.278 - goto error; 13.279 - } 13.280 - 13.281 - allocate_request_array(mount); 13.282 - 13.283 - return; 13.284 - 13.285 -error: 13.286 - xenbus_write_backend_state(mount, STATE_CLOSED); 13.287 - if (sring) 13.288 - xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size); 13.289 - if (mount->gnth != NULL) 13.290 - xc_gnttab_close(mount->gnth); 13.291 - if (mount->local_evtchn > 0) 13.292 - xc_evtchn_unbind(mount->evth, mount->local_evtchn); 13.293 - if (mount->evth != NULL) 13.294 - xc_evtchn_close(mount->evth); 13.295 - if (mount->xch) 13.296 - xc_interface_close(mount->xch); 13.297 -} 13.298 - 13.299 -static void await_connections(void) 13.300 -{ 13.301 - int fd, max_fd, ret, dom_id, export_id; 13.302 - fd_set fds; 13.303 - char **watch_paths; 13.304 - unsigned int len; 13.305 - char d; 13.306 - struct fs_mount *pointer; 13.307 - 13.308 - LIST_INIT (&mount_requests_head); 13.309 - 13.310 - assert(xsh != NULL); 13.311 - if ((fd = xenbus_get_watch_fd()) == -1) 13.312 - err(1, "xenbus_get_watch_fd: could not setup watch"); 13.313 - /* Infinite watch loop */ 13.314 - do { 13.315 - FD_ZERO(&fds); 13.316 - FD_SET(fd, &fds); 13.317 - FD_SET(pipefds[0], &fds); 13.318 - max_fd = fd > pipefds[0] ? fd : pipefds[0]; 13.319 - LIST_FOREACH(pointer, &mount_requests_head, entries) { 13.320 - int tfd = xc_evtchn_fd(pointer->evth); 13.321 - FD_SET(tfd, &fds); 13.322 - if (tfd > max_fd) max_fd = tfd; 13.323 - } 13.324 - ret = select(max_fd+1, &fds, NULL, NULL, NULL); 13.325 - if (ret < 0) { 13.326 - if (errno == EINTR) continue; 13.327 - /* try to recover */ 13.328 - else if (errno == EBADF) { 13.329 - struct timeval timeout; 13.330 - memset(&timeout, 0x00, sizeof(timeout)); 13.331 - FD_ZERO(&fds); 13.332 - FD_SET(fd, &fds); 13.333 - FD_SET(pipefds[0], &fds); 13.334 - max_fd = fd > pipefds[0] ? fd : pipefds[0]; 13.335 - ret = select(max_fd + 1, &fds, NULL, NULL, &timeout); 13.336 - if (ret < 0) 13.337 - err(1, "select: unrecoverable error occurred: %d\n", errno); 13.338 - 13.339 - /* trying to find the bogus fd among the open event channels */ 13.340 - LIST_FOREACH(pointer, &mount_requests_head, entries) { 13.341 - int tfd = xc_evtchn_fd(pointer->evth); 13.342 - memset(&timeout, 0x00, sizeof(timeout)); 13.343 - FD_ZERO(&fds); 13.344 - FD_SET(tfd, &fds); 13.345 - ret = select(tfd + 1, &fds, NULL, NULL, &timeout); 13.346 - if (ret < 0) { 13.347 - FS_DEBUG("fd %d is bogus, closing the related connection %p\n", tfd, pointer->evth); 13.348 - /*pointer->evth = fd;*/ 13.349 - terminate_mount_request(pointer); 13.350 - continue; 13.351 - } 13.352 - } 13.353 - continue; 13.354 - } else 13.355 - err(1, "select: unrecoverable error occurred: %d\n", errno); 13.356 - } 13.357 - if (FD_ISSET(fd, &fds)) { 13.358 - watch_paths = xs_read_watch(xsh, &len); 13.359 - if (!strcmp(watch_paths[XS_WATCH_TOKEN], "conn-watch")) { 13.360 - dom_id = -1; 13.361 - export_id = -1; 13.362 - d = 0; 13.363 - FS_DEBUG("Path changed %s\n", watch_paths[0]); 13.364 - sscanf(watch_paths[XS_WATCH_PATH], WATCH_NODE"/%d/%d/fronten%c", 13.365 - &dom_id, &export_id, &d); 13.366 - if((dom_id >= 0) && (export_id >= 0) && d == 'd') { 13.367 - char *frontend = xs_read(xsh, XBT_NULL, watch_paths[XS_WATCH_PATH], NULL); 13.368 - if (frontend) { 13.369 - char *p, *wp = strdup(watch_paths[XS_WATCH_PATH]); 13.370 - handle_connection(dom_id, export_id, frontend); 13.371 - xs_rm(xsh, XBT_NULL, wp); 13.372 - p = strrchr(wp, '/'); 13.373 - if (p) { 13.374 - *p = '\0'; 13.375 - p = strrchr(wp, '/'); 13.376 - if (p) { 13.377 - *p = '\0'; 13.378 - xs_rm(xsh, XBT_NULL, wp); 13.379 - } 13.380 - } 13.381 - free(wp); 13.382 - } 13.383 - } 13.384 - } else if (!strcmp(watch_paths[XS_WATCH_TOKEN], "frontend-state")) { 13.385 - LIST_FOREACH(pointer, &mount_requests_head, entries) { 13.386 - if (!strncmp(pointer->frontend, watch_paths[XS_WATCH_PATH], strlen(pointer->frontend))) { 13.387 - char *state = xenbus_read_frontend_state(pointer); 13.388 - if (!state || strcmp(state, STATE_READY)) { 13.389 - xenbus_unwatch_frontend_state(pointer); 13.390 - terminate_mount_request(pointer); 13.391 - } 13.392 - free(state); 13.393 - break; 13.394 - } 13.395 - } 13.396 - } else { 13.397 - FS_DEBUG("xenstore watch event unrecognized\n"); 13.398 - } 13.399 - FS_DEBUG("Awaiting next connection.\n"); 13.400 - /* TODO - we need to figure out what to free */ 13.401 - free(watch_paths); 13.402 - } 13.403 - if (FD_ISSET(pipefds[0], &fds)) { 13.404 - struct fs_request *request; 13.405 - if (read_exact(pipefds[0], &request, sizeof(struct fs_request *)) < 0) 13.406 - err(1, "read request failed\n"); 13.407 - handle_aio_event(request); 13.408 - } 13.409 - LIST_FOREACH(pointer, &mount_requests_head, entries) { 13.410 - if (FD_ISSET(xc_evtchn_fd(pointer->evth), &fds)) { 13.411 - evtchn_port_t port; 13.412 - port = xc_evtchn_pending(pointer->evth); 13.413 - if (port != -1) { 13.414 - handle_mount(pointer); 13.415 - xc_evtchn_unmask(pointer->evth, port); 13.416 - } 13.417 - } 13.418 - } 13.419 - } while (1); 13.420 -} 13.421 - 13.422 -static struct fs_export* create_export(char *name, char *export_path) 13.423 -{ 13.424 - struct fs_export *curr_export, **last_export; 13.425 - 13.426 - /* Create export structure */ 13.427 - curr_export = (struct fs_export *)malloc(sizeof(struct fs_export)); 13.428 - curr_export->name = name; 13.429 - curr_export->export_path = export_path; 13.430 - curr_export->export_id = export_id++; 13.431 - /* Thread it onto the list */ 13.432 - curr_export->next = NULL; 13.433 - last_export = &fs_exports; 13.434 - while(*last_export) 13.435 - last_export = &((*last_export)->next); 13.436 - *last_export = curr_export; 13.437 - 13.438 - return curr_export; 13.439 -} 13.440 - 13.441 -static void aio_signal_handler(int signo, siginfo_t *info, void *context) 13.442 -{ 13.443 - struct fs_request *request = (struct fs_request*) info->si_value.sival_ptr; 13.444 - int saved_errno = errno; 13.445 - if (write_exact(pipefds[1], &request, sizeof(struct fs_request *)) < 0) 13.446 - err(1, "write request filed\n"); 13.447 - errno = saved_errno; 13.448 -} 13.449 - 13.450 -int main(void) 13.451 -{ 13.452 - struct fs_export *export; 13.453 - struct sigaction act; 13.454 - sigset_t enable; 13.455 - 13.456 - sigemptyset(&enable); 13.457 - sigaddset(&enable, SIGUSR2); 13.458 - pthread_sigmask(SIG_UNBLOCK, &enable, NULL); 13.459 - 13.460 - sigfillset(&act.sa_mask); 13.461 - act.sa_flags = SA_SIGINFO; /* do not restart syscalls to interrupt select(); use sa_sigaction */ 13.462 - act.sa_sigaction = aio_signal_handler; 13.463 - sigaction(SIGUSR2, &act, NULL); 13.464 - 13.465 - /* Open the connection to XenStore first */ 13.466 - xsh = xs_domain_open(); 13.467 - assert(xsh != NULL); 13.468 - xs_rm(xsh, XBT_NULL, ROOT_NODE); 13.469 - /* Create watch node */ 13.470 - xenbus_create_request_node(); 13.471 - 13.472 - /* Create & register the default export */ 13.473 - export = create_export("default", "/var/lib/xen"); 13.474 - xenbus_register_export(export); 13.475 - 13.476 - if (socketpair(PF_UNIX,SOCK_STREAM, 0, pipefds) == -1) 13.477 - err(1, "failed to create pipe\n"); 13.478 - 13.479 - await_connections(); 13.480 - /* Close the connection to XenStore when we are finished with everything */ 13.481 - xs_daemon_close(xsh); 13.482 -#if 0 13.483 - xc_interface *xc_handle; 13.484 - char *shared_page; 13.485 - int prot = PROT_READ | PROT_WRITE; 13.486 - 13.487 - xc_handle = xc_gnttab_open(); 13.488 - printf("Main fn.\n"); 13.489 - 13.490 - shared_page = xc_gnttab_map_grant_ref(xc_handle, 13.491 - 7, 13.492 - 2047, 13.493 - prot); 13.494 - 13.495 - shared_page[20] = '\0'; 13.496 - printf("Current content of the page = %s\n", shared_page); 13.497 - sprintf(shared_page, "%s", "Haha dirty page now! Very bad page."); 13.498 - xc_gnttab_munmap(xc_handle, shared_page, 1); 13.499 - xc_gnttab_close(xc_handle); 13.500 - unrelated next line, saved for later convinience 13.501 - xc_evtchn_notify(mount->evth, mount->local_evtchn); 13.502 -#endif 13.503 -}
14.1 --- a/tools/fs-back/fs-backend.h Tue Jan 11 19:31:41 2011 +0000 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,102 +0,0 @@ 14.4 -#ifndef __LIB_FS_BACKEND__ 14.5 -#define __LIB_FS_BACKEND__ 14.6 - 14.7 -#include <aio.h> 14.8 -#include <xs.h> 14.9 -#include <xen/grant_table.h> 14.10 -#include <xen/event_channel.h> 14.11 -#include <xen/io/ring.h> 14.12 -#include <xen/io/fsif.h> 14.13 -#include "sys-queue.h" 14.14 - 14.15 -#define ROOT_NODE "backend/vfs" 14.16 -#define EXPORTS_SUBNODE "exports" 14.17 -#define EXPORTS_NODE ROOT_NODE"/"EXPORTS_SUBNODE 14.18 -#define WATCH_NODE EXPORTS_NODE"/requests" 14.19 -#define MAX_FDS 16 14.20 -#define MAX_RING_SIZE 16 14.21 - 14.22 -struct fs_export 14.23 -{ 14.24 - int export_id; 14.25 - char *export_path; 14.26 - char *name; 14.27 - struct fs_export *next; 14.28 -}; 14.29 - 14.30 -struct fs_request 14.31 -{ 14.32 - struct fs_mount *mount; 14.33 - int id; 14.34 - int active; 14.35 - void *page; /* Pointer to mapped grant */ 14.36 - int count; 14.37 - struct fsif_request req_shadow; 14.38 - struct aiocb aiocb; 14.39 -}; 14.40 - 14.41 - 14.42 -struct fs_mount 14.43 -{ 14.44 - struct fs_export *export; 14.45 - int dom_id; 14.46 - char *frontend; 14.47 - int mount_id; /* = backend id */ 14.48 - grant_ref_t grefs[MAX_RING_SIZE]; 14.49 - evtchn_port_t remote_evtchn; 14.50 - xc_interface *xch; /* just for error logging, so a dummy */ 14.51 - xc_evtchn *evth; /* Handle to the event channel */ 14.52 - evtchn_port_t local_evtchn; 14.53 - xc_gnttab *gnth; 14.54 - int shared_ring_size; /* in pages */ 14.55 - struct fsif_back_ring ring; 14.56 - int nr_entries; 14.57 - struct fs_request *requests; 14.58 - unsigned short *freelist; 14.59 - int fds[MAX_FDS]; 14.60 - LIST_ENTRY(fs_mount) entries; 14.61 -}; 14.62 - 14.63 -void terminate_mount_request(struct fs_mount *mount); 14.64 - 14.65 -/* Handle to XenStore driver */ 14.66 -extern struct xs_handle *xsh; 14.67 - 14.68 -bool xenbus_create_request_node(void); 14.69 -int xenbus_register_export(struct fs_export *export); 14.70 -int xenbus_get_watch_fd(void); 14.71 -int xenbus_read_mount_request(struct fs_mount *mount, char *frontend); 14.72 -bool xenbus_write_backend_node(struct fs_mount *mount); 14.73 -bool xenbus_write_backend_state(struct fs_mount *mount, const char *state); 14.74 -void xenbus_free_backend_node(struct fs_mount *mount); 14.75 -int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate); 14.76 -bool xenbus_watch_frontend_state(struct fs_mount *mount); 14.77 -bool xenbus_unwatch_frontend_state(struct fs_mount *mount); 14.78 -char* xenbus_read_frontend_state(struct fs_mount *mount); 14.79 - 14.80 -/* File operations, implemented in fs-ops.c */ 14.81 -struct fs_op 14.82 -{ 14.83 - int type; /* Type of request (from fsif.h) this handlers 14.84 - are responsible for */ 14.85 - void (*dispatch_handler)(struct fs_mount *mount, struct fsif_request *req); 14.86 - void (*response_handler)(struct fs_mount *mount, struct fs_request *req); 14.87 -}; 14.88 - 14.89 -/* This NULL terminated array of all file requests handlers */ 14.90 -extern struct fs_op *fsops[]; 14.91 - 14.92 -static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist) 14.93 -{ 14.94 - freelist[id + 1] = freelist[0]; 14.95 - freelist[0] = id; 14.96 -} 14.97 - 14.98 -static inline unsigned short get_id_from_freelist(unsigned short* freelist) 14.99 -{ 14.100 - unsigned int id = freelist[0]; 14.101 - freelist[0] = freelist[id + 1]; 14.102 - return id; 14.103 -} 14.104 - 14.105 -#endif /* __LIB_FS_BACKEND__ */
15.1 --- a/tools/fs-back/fs-debug.h Tue Jan 11 19:31:41 2011 +0000 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,12 +0,0 @@ 15.4 -#ifndef __FS_DEBUG__ 15.5 -#define __FS_DEBUG__ 15.6 - 15.7 -// #define DEBUG 1 15.8 - 15.9 -#ifdef DEBUG 15.10 -#define FS_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) 15.11 -#else 15.12 -#define FS_DEBUG(fmt, ...) do { } while (0) 15.13 -#endif 15.14 - 15.15 -#endif /*__FS_DEBUG__*/
16.1 --- a/tools/fs-back/fs-ops.c Tue Jan 11 19:31:41 2011 +0000 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,794 +0,0 @@ 16.4 -#undef NDEBUG 16.5 -#include <stdio.h> 16.6 -#include <aio.h> 16.7 -#include <string.h> 16.8 -#include <assert.h> 16.9 -#include <fcntl.h> 16.10 -#include <dirent.h> 16.11 -#include <inttypes.h> 16.12 -#include <xenctrl.h> 16.13 -#include <sys/mman.h> 16.14 -#include <sys/types.h> 16.15 -#include <sys/stat.h> 16.16 -#include <sys/statvfs.h> 16.17 -#include <sys/mount.h> 16.18 -#include <unistd.h> 16.19 -#include <ctype.h> 16.20 -#include "fs-backend.h" 16.21 -#include "fs-debug.h" 16.22 - 16.23 -/* For debugging only */ 16.24 -#include <sys/time.h> 16.25 -#include <time.h> 16.26 - 16.27 - 16.28 -#define BUFFER_SIZE 1024 16.29 - 16.30 -static int check_export_path(const char *export_path, const char *path) 16.31 -{ 16.32 - int i; 16.33 - if (!export_path || !path) 16.34 - return -1; 16.35 - if (strlen(path) < strlen(export_path)) 16.36 - return -1; 16.37 - if (strstr(path, "..") != NULL) 16.38 - return -1; 16.39 - for (i = 0; i < strlen(path); i++) { 16.40 - if (!isascii(path[i])) 16.41 - return -1; 16.42 - } 16.43 - if (strncmp(export_path, path, strlen(export_path))) 16.44 - return -1; 16.45 - else 16.46 - return 0; 16.47 -} 16.48 - 16.49 -static unsigned short get_request(struct fs_mount *mount, struct fsif_request *req) 16.50 -{ 16.51 - unsigned short id = get_id_from_freelist(mount->freelist); 16.52 - 16.53 - FS_DEBUG("Private Request id: %d\n", id); 16.54 - memcpy(&mount->requests[id].req_shadow, req, sizeof(struct fsif_request)); 16.55 - mount->requests[id].active = 1; 16.56 - 16.57 - return id; 16.58 -} 16.59 - 16.60 -static int get_fd(struct fs_mount *mount) 16.61 -{ 16.62 - int i; 16.63 - 16.64 - for (i = 0; i < MAX_FDS; i++) 16.65 - if (mount->fds[i] == -1) 16.66 - return i; 16.67 - return -1; 16.68 -} 16.69 - 16.70 - 16.71 -static void dispatch_file_open(struct fs_mount *mount, struct fsif_request *req) 16.72 -{ 16.73 - char *file_name; 16.74 - int fd; 16.75 - RING_IDX rsp_idx; 16.76 - fsif_response_t *rsp; 16.77 - uint16_t req_id; 16.78 - 16.79 - FS_DEBUG("Dispatching file open operation (gref=%d).\n", req->u.fopen.gref); 16.80 - /* Read the request, and open file */ 16.81 - file_name = xc_gnttab_map_grant_ref(mount->gnth, 16.82 - mount->dom_id, 16.83 - req->u.fopen.gref, 16.84 - PROT_READ); 16.85 - 16.86 - req_id = req->id; 16.87 - FS_DEBUG("File open issued for %s\n", file_name); 16.88 - if (check_export_path(mount->export->export_path, file_name) < 0) { 16.89 - FS_DEBUG("Filename check failed\n"); 16.90 - fd = -1; 16.91 - goto out; 16.92 - } 16.93 - fd = get_fd(mount); 16.94 - if (fd >= 0) { 16.95 - int real_fd = open(file_name, O_RDWR); 16.96 - if (real_fd < 0) 16.97 - fd = -1; 16.98 - else 16.99 - { 16.100 - mount->fds[fd] = real_fd; 16.101 - FS_DEBUG("Got FD: %d for real %d\n", fd, real_fd); 16.102 - } 16.103 - } 16.104 -out: 16.105 - if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) { 16.106 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.107 - terminate_mount_request(mount); 16.108 - } 16.109 - /* We can advance the request consumer index, from here on, the request 16.110 - * should not be used (it may be overrinden by a response) */ 16.111 - mount->ring.req_cons++; 16.112 - 16.113 - 16.114 - /* Get a response from the ring */ 16.115 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.116 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.117 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.118 - rsp->id = req_id; 16.119 - rsp->u.ret_val = (uint64_t)fd; 16.120 -} 16.121 - 16.122 -static void dispatch_file_close(struct fs_mount *mount, struct fsif_request *req) 16.123 -{ 16.124 - int ret; 16.125 - RING_IDX rsp_idx; 16.126 - fsif_response_t *rsp; 16.127 - uint16_t req_id; 16.128 - 16.129 - FS_DEBUG("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd); 16.130 - 16.131 - req_id = req->id; 16.132 - if (req->u.fclose.fd < MAX_FDS) { 16.133 - int fd = mount->fds[req->u.fclose.fd]; 16.134 - ret = close(fd); 16.135 - mount->fds[req->u.fclose.fd] = -1; 16.136 - } else 16.137 - ret = -1; 16.138 - FS_DEBUG("Got ret: %d\n", ret); 16.139 - /* We can advance the request consumer index, from here on, the request 16.140 - * should not be used (it may be overrinden by a response) */ 16.141 - mount->ring.req_cons++; 16.142 - 16.143 - 16.144 - /* Get a response from the ring */ 16.145 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.146 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.147 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.148 - rsp->id = req_id; 16.149 - rsp->u.ret_val = (uint64_t)ret; 16.150 -} 16.151 - 16.152 -#define MAX_GNTS 16 16.153 -static void dispatch_file_read(struct fs_mount *mount, struct fsif_request *req) 16.154 -{ 16.155 - void *buf; 16.156 - int fd, count; 16.157 - uint16_t req_id; 16.158 - unsigned short priv_id; 16.159 - struct fs_request *priv_req; 16.160 - 16.161 - /* Read the request */ 16.162 - assert(req->u.fread.len > 0); 16.163 - count = (req->u.fread.len - 1) / XC_PAGE_SIZE + 1; 16.164 - assert(count <= FSIF_NR_READ_GNTS); 16.165 - buf = xc_gnttab_map_domain_grant_refs(mount->gnth, 16.166 - count, 16.167 - mount->dom_id, 16.168 - req->u.fread.grefs, 16.169 - PROT_WRITE); 16.170 - 16.171 - req_id = req->id; 16.172 - FS_DEBUG("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 16.173 - req->u.fread.fd, req->u.fread.len, req->u.fread.offset); 16.174 - 16.175 - if (req->u.fread.fd < MAX_FDS) 16.176 - fd = mount->fds[req->u.fread.fd]; 16.177 - else 16.178 - fd = -1; 16.179 - 16.180 - priv_id = get_request(mount, req); 16.181 - FS_DEBUG("Private id is: %d\n", priv_id); 16.182 - priv_req = &mount->requests[priv_id]; 16.183 - priv_req->page = buf; 16.184 - priv_req->count = count; 16.185 - priv_req->id = priv_id; 16.186 - 16.187 - /* Dispatch AIO read request */ 16.188 - bzero(&priv_req->aiocb, sizeof(struct aiocb)); 16.189 - priv_req->aiocb.aio_fildes = fd; 16.190 - priv_req->aiocb.aio_nbytes = req->u.fread.len; 16.191 - priv_req->aiocb.aio_offset = req->u.fread.offset; 16.192 - priv_req->aiocb.aio_buf = buf; 16.193 - priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 16.194 - priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2; 16.195 - priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req; 16.196 - if (aio_read(&priv_req->aiocb) < 0) { 16.197 - FS_DEBUG("ERROR: aio_read failed errno=%d\n", errno); 16.198 - xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count); 16.199 - terminate_mount_request(mount); 16.200 - } 16.201 - 16.202 - /* We can advance the request consumer index, from here on, the request 16.203 - * should not be used (it may be overrinden by a response) */ 16.204 - mount->ring.req_cons++; 16.205 -} 16.206 - 16.207 -static void end_file_read(struct fs_mount *mount, struct fs_request *priv_req) 16.208 -{ 16.209 - RING_IDX rsp_idx; 16.210 - fsif_response_t *rsp; 16.211 - uint16_t req_id; 16.212 - 16.213 - /* Release the grant */ 16.214 - if (xc_gnttab_munmap(mount->gnth, 16.215 - priv_req->page, priv_req->count) != 0) { 16.216 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.217 - terminate_mount_request(mount); 16.218 - } 16.219 - 16.220 - /* Get a response from the ring */ 16.221 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.222 - req_id = priv_req->req_shadow.id; 16.223 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.224 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.225 - rsp->id = req_id; 16.226 - rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb); 16.227 -} 16.228 - 16.229 -static void dispatch_file_write(struct fs_mount *mount, struct fsif_request *req) 16.230 -{ 16.231 - void *buf; 16.232 - int fd, count; 16.233 - uint16_t req_id; 16.234 - unsigned short priv_id; 16.235 - struct fs_request *priv_req; 16.236 - 16.237 - /* Read the request */ 16.238 - assert(req->u.fwrite.len > 0); 16.239 - count = (req->u.fwrite.len - 1) / XC_PAGE_SIZE + 1; 16.240 - assert(count <= FSIF_NR_WRITE_GNTS); 16.241 - buf = xc_gnttab_map_domain_grant_refs(mount->gnth, 16.242 - count, 16.243 - mount->dom_id, 16.244 - req->u.fwrite.grefs, 16.245 - PROT_READ); 16.246 - 16.247 - req_id = req->id; 16.248 - FS_DEBUG("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 16.249 - req->u.fwrite.fd, req->u.fwrite.len, req->u.fwrite.offset); 16.250 - 16.251 - if (req->u.fwrite.fd < MAX_FDS) 16.252 - fd = mount->fds[req->u.fwrite.fd]; 16.253 - else 16.254 - fd = -1; 16.255 - 16.256 - priv_id = get_request(mount, req); 16.257 - FS_DEBUG("Private id is: %d\n", priv_id); 16.258 - priv_req = &mount->requests[priv_id]; 16.259 - priv_req->page = buf; 16.260 - priv_req->count = count; 16.261 - priv_req->id = priv_id; 16.262 - 16.263 - /* Dispatch AIO write request */ 16.264 - bzero(&priv_req->aiocb, sizeof(struct aiocb)); 16.265 - priv_req->aiocb.aio_fildes = fd; 16.266 - priv_req->aiocb.aio_nbytes = req->u.fwrite.len; 16.267 - priv_req->aiocb.aio_offset = req->u.fwrite.offset; 16.268 - priv_req->aiocb.aio_buf = buf; 16.269 - priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 16.270 - priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2; 16.271 - priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req; 16.272 - if (aio_write(&priv_req->aiocb) < 0) { 16.273 - FS_DEBUG("ERROR: aio_write failed errno=%d\n", errno); 16.274 - xc_gnttab_munmap(mount->gnth, 16.275 - priv_req->page, priv_req->count); 16.276 - terminate_mount_request(mount); 16.277 - } 16.278 - 16.279 - 16.280 - /* We can advance the request consumer index, from here on, the request 16.281 - * should not be used (it may be overrinden by a response) */ 16.282 - mount->ring.req_cons++; 16.283 -} 16.284 - 16.285 -static void end_file_write(struct fs_mount *mount, struct fs_request *priv_req) 16.286 -{ 16.287 - RING_IDX rsp_idx; 16.288 - fsif_response_t *rsp; 16.289 - uint16_t req_id; 16.290 - 16.291 - /* Release the grant */ 16.292 - if (xc_gnttab_munmap(mount->gnth, 16.293 - priv_req->page, priv_req->count) != 0) { 16.294 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.295 - terminate_mount_request(mount); 16.296 - } 16.297 - 16.298 - /* Get a response from the ring */ 16.299 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.300 - req_id = priv_req->req_shadow.id; 16.301 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.302 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.303 - rsp->id = req_id; 16.304 - rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb); 16.305 -} 16.306 - 16.307 -static void dispatch_stat(struct fs_mount *mount, struct fsif_request *req) 16.308 -{ 16.309 - struct stat stat; 16.310 - int fd, ret; 16.311 - uint16_t req_id; 16.312 - RING_IDX rsp_idx; 16.313 - fsif_response_t *rsp; 16.314 - 16.315 - req_id = req->id; 16.316 - if (req->u.fstat.fd < MAX_FDS) 16.317 - fd = mount->fds[req->u.fstat.fd]; 16.318 - else 16.319 - fd = -1; 16.320 - 16.321 - FS_DEBUG("File stat issued for FD=%d\n", req->u.fstat.fd); 16.322 - 16.323 - /* We can advance the request consumer index, from here on, the request 16.324 - * should not be used (it may be overrinden by a response) */ 16.325 - mount->ring.req_cons++; 16.326 - 16.327 - /* Stat, and create the response */ 16.328 - ret = fstat(fd, &stat); 16.329 - FS_DEBUG("Mode=%o, uid=%d, a_time=%ld\n", 16.330 - stat.st_mode, stat.st_uid, (long)stat.st_atime); 16.331 - 16.332 - /* Get a response from the ring */ 16.333 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.334 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.335 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.336 - rsp->id = req_id; 16.337 - rsp->u.fstat.stat_ret = (uint32_t)ret; 16.338 - rsp->u.fstat.stat_mode = stat.st_mode; 16.339 - rsp->u.fstat.stat_uid = stat.st_uid; 16.340 - rsp->u.fstat.stat_gid = stat.st_gid; 16.341 -#ifdef BLKGETSIZE 16.342 - if (S_ISBLK(stat.st_mode)) { 16.343 - unsigned long sectors; 16.344 - if (ioctl(fd, BLKGETSIZE, §ors)) { 16.345 - perror("getting device size\n"); 16.346 - rsp->u.fstat.stat_size = 0; 16.347 - } else 16.348 - rsp->u.fstat.stat_size = sectors << 9; 16.349 - } else 16.350 -#endif 16.351 - rsp->u.fstat.stat_size = stat.st_size; 16.352 - rsp->u.fstat.stat_atime = stat.st_atime; 16.353 - rsp->u.fstat.stat_mtime = stat.st_mtime; 16.354 - rsp->u.fstat.stat_ctime = stat.st_ctime; 16.355 -} 16.356 - 16.357 - 16.358 -static void dispatch_truncate(struct fs_mount *mount, struct fsif_request *req) 16.359 -{ 16.360 - int fd, ret; 16.361 - uint16_t req_id; 16.362 - RING_IDX rsp_idx; 16.363 - fsif_response_t *rsp; 16.364 - int64_t length; 16.365 - 16.366 - req_id = req->id; 16.367 - length = req->u.ftruncate.length; 16.368 - FS_DEBUG("File truncate issued for FD=%d, length=%"PRId64"\n", req->u.ftruncate.fd, length); 16.369 - 16.370 - if (req->u.ftruncate.fd < MAX_FDS) 16.371 - fd = mount->fds[req->u.ftruncate.fd]; 16.372 - else 16.373 - fd = -1; 16.374 - 16.375 - /* We can advance the request consumer index, from here on, the request 16.376 - * should not be used (it may be overrinden by a response) */ 16.377 - mount->ring.req_cons++; 16.378 - 16.379 - /* Stat, and create the response */ 16.380 - ret = ftruncate(fd, length); 16.381 - 16.382 - /* Get a response from the ring */ 16.383 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.384 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.385 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.386 - rsp->id = req_id; 16.387 - rsp->u.ret_val = (uint64_t)ret; 16.388 -} 16.389 - 16.390 -static void dispatch_remove(struct fs_mount *mount, struct fsif_request *req) 16.391 -{ 16.392 - char *file_name; 16.393 - int ret; 16.394 - RING_IDX rsp_idx; 16.395 - fsif_response_t *rsp; 16.396 - uint16_t req_id; 16.397 - 16.398 - FS_DEBUG("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref); 16.399 - /* Read the request, and open file */ 16.400 - file_name = xc_gnttab_map_grant_ref(mount->gnth, 16.401 - mount->dom_id, 16.402 - req->u.fremove.gref, 16.403 - PROT_READ); 16.404 - 16.405 - req_id = req->id; 16.406 - FS_DEBUG("File remove issued for %s\n", file_name); 16.407 - if (check_export_path(mount->export->export_path, file_name) < 0) { 16.408 - FS_DEBUG("Filename check failed\n"); 16.409 - ret = -1; 16.410 - } else { 16.411 - ret = remove(file_name); 16.412 - } 16.413 - FS_DEBUG("Got ret: %d\n", ret); 16.414 - if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) { 16.415 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.416 - terminate_mount_request(mount); 16.417 - } 16.418 - /* We can advance the request consumer index, from here on, the request 16.419 - * should not be used (it may be overrinden by a response) */ 16.420 - mount->ring.req_cons++; 16.421 - 16.422 - 16.423 - /* Get a response from the ring */ 16.424 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.425 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.426 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.427 - rsp->id = req_id; 16.428 - rsp->u.ret_val = (uint64_t)ret; 16.429 -} 16.430 - 16.431 - 16.432 -static void dispatch_rename(struct fs_mount *mount, struct fsif_request *req) 16.433 -{ 16.434 - char *buf, *old_file_name, *new_file_name; 16.435 - int ret; 16.436 - RING_IDX rsp_idx; 16.437 - fsif_response_t *rsp; 16.438 - uint16_t req_id; 16.439 - 16.440 - FS_DEBUG("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref); 16.441 - /* Read the request, and open file */ 16.442 - buf = xc_gnttab_map_grant_ref(mount->gnth, 16.443 - mount->dom_id, 16.444 - req->u.frename.gref, 16.445 - PROT_READ); 16.446 - 16.447 - req_id = req->id; 16.448 - old_file_name = buf + req->u.frename.old_name_offset; 16.449 - new_file_name = buf + req->u.frename.new_name_offset; 16.450 - FS_DEBUG("File rename issued for %s -> %s (buf=%s)\n", 16.451 - old_file_name, new_file_name, buf); 16.452 - if (check_export_path(mount->export->export_path, old_file_name) < 0 || 16.453 - check_export_path(mount->export->export_path, new_file_name) < 0) { 16.454 - FS_DEBUG("Filename check failed\n"); 16.455 - ret = -1; 16.456 - } else { 16.457 - ret = rename(old_file_name, new_file_name); 16.458 - } 16.459 - FS_DEBUG("Got ret: %d\n", ret); 16.460 - if (xc_gnttab_munmap(mount->gnth, buf, 1) != 0) { 16.461 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.462 - terminate_mount_request(mount); 16.463 - } 16.464 - /* We can advance the request consumer index, from here on, the request 16.465 - * should not be used (it may be overrinden by a response) */ 16.466 - mount->ring.req_cons++; 16.467 - 16.468 - 16.469 - /* Get a response from the ring */ 16.470 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.471 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.472 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.473 - rsp->id = req_id; 16.474 - rsp->u.ret_val = (uint64_t)ret; 16.475 -} 16.476 - 16.477 - 16.478 -static void dispatch_create(struct fs_mount *mount, struct fsif_request *req) 16.479 -{ 16.480 - char *file_name; 16.481 - int ret; 16.482 - int8_t directory; 16.483 - int32_t mode; 16.484 - RING_IDX rsp_idx; 16.485 - fsif_response_t *rsp; 16.486 - uint16_t req_id; 16.487 - 16.488 - FS_DEBUG("Dispatching file create operation (gref=%d).\n", req->u.fcreate.gref); 16.489 - /* Read the request, and create file/directory */ 16.490 - mode = req->u.fcreate.mode; 16.491 - directory = req->u.fcreate.directory; 16.492 - file_name = xc_gnttab_map_grant_ref(mount->gnth, 16.493 - mount->dom_id, 16.494 - req->u.fcreate.gref, 16.495 - PROT_READ); 16.496 - 16.497 - req_id = req->id; 16.498 - if (check_export_path(mount->export->export_path, file_name) < 0) { 16.499 - FS_DEBUG("Filename check failed\n"); 16.500 - ret = -1; 16.501 - goto out; 16.502 - } 16.503 - /* We can advance the request consumer index, from here on, the request 16.504 - * should not be used (it may be overrinden by a response) */ 16.505 - mount->ring.req_cons++; 16.506 - 16.507 - if(directory) 16.508 - { 16.509 - FS_DEBUG("Issuing create for directory: %s\n", file_name); 16.510 - ret = mkdir(file_name, mode); 16.511 - } 16.512 - else 16.513 - { 16.514 - FS_DEBUG("Issuing create for file: %s\n", file_name); 16.515 - ret = get_fd(mount); 16.516 - if (ret >= 0) { 16.517 - int real_fd = creat(file_name, mode); 16.518 - if (real_fd < 0) 16.519 - ret = -1; 16.520 - else 16.521 - { 16.522 - mount->fds[ret] = real_fd; 16.523 - FS_DEBUG("Got FD: %d for real %d\n", ret, real_fd); 16.524 - } 16.525 - } 16.526 - } 16.527 -out: 16.528 - if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) { 16.529 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.530 - terminate_mount_request(mount); 16.531 - } 16.532 - FS_DEBUG("Got ret %d (errno=%d)\n", ret, errno); 16.533 - 16.534 - /* Get a response from the ring */ 16.535 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.536 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.537 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.538 - rsp->id = req_id; 16.539 - rsp->u.ret_val = (uint64_t)ret; 16.540 -} 16.541 - 16.542 -static void dispatch_list(struct fs_mount *mount, struct fsif_request *req) 16.543 -{ 16.544 - char *file_name, *buf; 16.545 - uint32_t offset = 0, nr_files = 0, error_code = 0; 16.546 - uint64_t ret_val; 16.547 - RING_IDX rsp_idx; 16.548 - fsif_response_t *rsp; 16.549 - uint16_t req_id; 16.550 - DIR *dir; 16.551 - struct dirent *dirent = NULL; 16.552 - 16.553 - FS_DEBUG("Dispatching list operation (gref=%d).\n", req->u.flist.gref); 16.554 - /* Read the request, and list directory */ 16.555 - offset = req->u.flist.offset; 16.556 - buf = file_name = xc_gnttab_map_grant_ref(mount->gnth, 16.557 - mount->dom_id, 16.558 - req->u.flist.gref, 16.559 - PROT_READ | PROT_WRITE); 16.560 - 16.561 - req_id = req->id; 16.562 - FS_DEBUG("Dir list issued for %s\n", file_name); 16.563 - if (check_export_path(mount->export->export_path, file_name) < 0) { 16.564 - FS_DEBUG("Filename check failed\n"); 16.565 - error_code = 1; 16.566 - goto error_out; 16.567 - } 16.568 - /* We can advance the request consumer index, from here on, the request 16.569 - * should not be used (it may be overrinden by a response) */ 16.570 - mount->ring.req_cons++; 16.571 - 16.572 - ret_val = 0; 16.573 - nr_files = 0; 16.574 - dir = opendir(file_name); 16.575 - if(dir == NULL) 16.576 - { 16.577 - error_code = errno; 16.578 - goto error_out; 16.579 - } 16.580 - /* Skip offset dirs */ 16.581 - dirent = readdir(dir); 16.582 - while(offset-- > 0 && dirent != NULL) 16.583 - dirent = readdir(dir); 16.584 - /* If there was any error with reading the directory, errno will be set */ 16.585 - error_code = errno; 16.586 - /* Copy file names of the remaining non-NULL dirents into buf */ 16.587 - if (NAME_MAX >= XC_PAGE_SIZE >> 1) 16.588 - goto error_out; 16.589 - while(dirent != NULL && 16.590 - (XC_PAGE_SIZE - ((unsigned long)buf & XC_PAGE_MASK) > NAME_MAX)) 16.591 - { 16.592 - int curr_length = strlen(dirent->d_name) + 1; 16.593 - 16.594 - memcpy(buf, dirent->d_name, curr_length); 16.595 - buf += curr_length; 16.596 - dirent = readdir(dir); 16.597 - error_code = errno; 16.598 - nr_files++; 16.599 - } 16.600 -error_out: 16.601 - ret_val = ((nr_files << NR_FILES_SHIFT) & NR_FILES_MASK) | 16.602 - ((error_code << ERROR_SHIFT) & ERROR_MASK) | 16.603 - (dirent != NULL ? HAS_MORE_FLAG : 0); 16.604 - if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) { 16.605 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.606 - terminate_mount_request(mount); 16.607 - } 16.608 - 16.609 - /* Get a response from the ring */ 16.610 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.611 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.612 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.613 - rsp->id = req_id; 16.614 - rsp->u.ret_val = ret_val; 16.615 -} 16.616 - 16.617 -static void dispatch_chmod(struct fs_mount *mount, struct fsif_request *req) 16.618 -{ 16.619 - int fd, ret; 16.620 - RING_IDX rsp_idx; 16.621 - fsif_response_t *rsp; 16.622 - uint16_t req_id; 16.623 - int32_t mode; 16.624 - 16.625 - FS_DEBUG("Dispatching file chmod operation (fd=%d, mode=%o).\n", 16.626 - req->u.fchmod.fd, req->u.fchmod.mode); 16.627 - req_id = req->id; 16.628 - if (req->u.fchmod.fd < MAX_FDS) 16.629 - fd = mount->fds[req->u.fchmod.fd]; 16.630 - else 16.631 - fd = -1; 16.632 - 16.633 - mode = req->u.fchmod.mode; 16.634 - /* We can advance the request consumer index, from here on, the request 16.635 - * should not be used (it may be overrinden by a response) */ 16.636 - mount->ring.req_cons++; 16.637 - 16.638 - ret = fchmod(fd, mode); 16.639 - 16.640 - /* Get a response from the ring */ 16.641 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.642 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.643 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.644 - rsp->id = req_id; 16.645 - rsp->u.ret_val = (uint64_t)ret; 16.646 -} 16.647 - 16.648 -static void dispatch_fs_space(struct fs_mount *mount, struct fsif_request *req) 16.649 -{ 16.650 - char *file_name; 16.651 - RING_IDX rsp_idx; 16.652 - fsif_response_t *rsp; 16.653 - uint16_t req_id; 16.654 - struct statvfs stat; 16.655 - int64_t ret; 16.656 - 16.657 - FS_DEBUG("Dispatching fs space operation (gref=%d).\n", req->u.fspace.gref); 16.658 - /* Read the request, and open file */ 16.659 - file_name = xc_gnttab_map_grant_ref(mount->gnth, 16.660 - mount->dom_id, 16.661 - req->u.fspace.gref, 16.662 - PROT_READ); 16.663 - 16.664 - req_id = req->id; 16.665 - FS_DEBUG("Fs space issued for %s\n", file_name); 16.666 - if (check_export_path(mount->export->export_path, file_name) < 0) { 16.667 - FS_DEBUG("Filename check failed\n"); 16.668 - ret = -1; 16.669 - } else { 16.670 - ret = statvfs(file_name, &stat); 16.671 - } 16.672 - if(ret >= 0) 16.673 - ret = stat.f_bsize * stat.f_bfree; 16.674 - 16.675 - if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) { 16.676 - FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno); 16.677 - terminate_mount_request(mount); 16.678 - } 16.679 - /* We can advance the request consumer index, from here on, the request 16.680 - * should not be used (it may be overrinden by a response) */ 16.681 - mount->ring.req_cons++; 16.682 - 16.683 - 16.684 - /* Get a response from the ring */ 16.685 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.686 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.687 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.688 - rsp->id = req_id; 16.689 - rsp->u.ret_val = (uint64_t)ret; 16.690 -} 16.691 - 16.692 -static void dispatch_file_sync(struct fs_mount *mount, struct fsif_request *req) 16.693 -{ 16.694 - int fd; 16.695 - uint16_t req_id; 16.696 - unsigned short priv_id; 16.697 - struct fs_request *priv_req; 16.698 - 16.699 - req_id = req->id; 16.700 - if (req->u.fsync.fd < MAX_FDS) 16.701 - fd = mount->fds[req->u.fsync.fd]; 16.702 - else 16.703 - fd = -1; 16.704 - 16.705 - FS_DEBUG("File sync issued for FD=%d\n", req->u.fsync.fd); 16.706 - 16.707 - priv_id = get_request(mount, req); 16.708 - FS_DEBUG("Private id is: %d\n", priv_id); 16.709 - priv_req = &mount->requests[priv_id]; 16.710 - priv_req->id = priv_id; 16.711 - 16.712 - /* Dispatch AIO read request */ 16.713 - bzero(&priv_req->aiocb, sizeof(struct aiocb)); 16.714 - priv_req->aiocb.aio_fildes = fd; 16.715 - priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 16.716 - priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2; 16.717 - priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req; 16.718 - if (aio_fsync(O_SYNC, &priv_req->aiocb) < 0) { 16.719 - FS_DEBUG("ERROR: aio_fsync failed errno=%d\n", errno); 16.720 - terminate_mount_request(mount); 16.721 - } 16.722 - 16.723 - /* We can advance the request consumer index, from here on, the request 16.724 - * should not be used (it may be overrinden by a response) */ 16.725 - mount->ring.req_cons++; 16.726 -} 16.727 - 16.728 -static void end_file_sync(struct fs_mount *mount, struct fs_request *priv_req) 16.729 -{ 16.730 - RING_IDX rsp_idx; 16.731 - fsif_response_t *rsp; 16.732 - uint16_t req_id; 16.733 - 16.734 - /* Get a response from the ring */ 16.735 - rsp_idx = mount->ring.rsp_prod_pvt++; 16.736 - req_id = priv_req->req_shadow.id; 16.737 - FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 16.738 - rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 16.739 - rsp->id = req_id; 16.740 - rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb); 16.741 -} 16.742 - 16.743 -struct fs_op fopen_op = {.type = REQ_FILE_OPEN, 16.744 - .dispatch_handler = dispatch_file_open, 16.745 - .response_handler = NULL}; 16.746 -struct fs_op fclose_op = {.type = REQ_FILE_CLOSE, 16.747 - .dispatch_handler = dispatch_file_close, 16.748 - .response_handler = NULL}; 16.749 -struct fs_op fread_op = {.type = REQ_FILE_READ, 16.750 - .dispatch_handler = dispatch_file_read, 16.751 - .response_handler = end_file_read}; 16.752 -struct fs_op fwrite_op = {.type = REQ_FILE_WRITE, 16.753 - .dispatch_handler = dispatch_file_write, 16.754 - .response_handler = end_file_write}; 16.755 -struct fs_op fstat_op = {.type = REQ_STAT, 16.756 - .dispatch_handler = dispatch_stat, 16.757 - .response_handler = NULL}; 16.758 -struct fs_op ftruncate_op = {.type = REQ_FILE_TRUNCATE, 16.759 - .dispatch_handler = dispatch_truncate, 16.760 - .response_handler = NULL}; 16.761 -struct fs_op fremove_op = {.type = REQ_REMOVE, 16.762 - .dispatch_handler = dispatch_remove, 16.763 - .response_handler = NULL}; 16.764 -struct fs_op frename_op = {.type = REQ_RENAME, 16.765 - .dispatch_handler = dispatch_rename, 16.766 - .response_handler = NULL}; 16.767 -struct fs_op fcreate_op = {.type = REQ_CREATE, 16.768 - .dispatch_handler = dispatch_create, 16.769 - .response_handler = NULL}; 16.770 -struct fs_op flist_op = {.type = REQ_DIR_LIST, 16.771 - .dispatch_handler = dispatch_list, 16.772 - .response_handler = NULL}; 16.773 -struct fs_op fchmod_op = {.type = REQ_CHMOD, 16.774 - .dispatch_handler = dispatch_chmod, 16.775 - .response_handler = NULL}; 16.776 -struct fs_op fspace_op = {.type = REQ_FS_SPACE, 16.777 - .dispatch_handler = dispatch_fs_space, 16.778 - .response_handler = NULL}; 16.779 -struct fs_op fsync_op = {.type = REQ_FILE_SYNC, 16.780 - .dispatch_handler = dispatch_file_sync, 16.781 - .response_handler = end_file_sync}; 16.782 - 16.783 - 16.784 -struct fs_op *fsops[] = {&fopen_op, 16.785 - &fclose_op, 16.786 - &fread_op, 16.787 - &fwrite_op, 16.788 - &fstat_op, 16.789 - &ftruncate_op, 16.790 - &fremove_op, 16.791 - &frename_op, 16.792 - &fcreate_op, 16.793 - &flist_op, 16.794 - &fchmod_op, 16.795 - &fspace_op, 16.796 - &fsync_op, 16.797 - NULL};
17.1 --- a/tools/fs-back/fs-xenbus.c Tue Jan 11 19:31:41 2011 +0000 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,273 +0,0 @@ 17.4 -#undef NDEBUG 17.5 -#include <stdio.h> 17.6 -#include <stdlib.h> 17.7 -#include <stdarg.h> 17.8 -#include <string.h> 17.9 -#include <assert.h> 17.10 -#include <sys/select.h> 17.11 -#include <xenctrl.h> 17.12 -#include <xs.h> 17.13 -#include <xen/io/fsif.h> 17.14 -#include "fs-backend.h" 17.15 -#include "fs-debug.h" 17.16 - 17.17 - 17.18 -static bool xenbus_printf(struct xs_handle *xsh, 17.19 - xs_transaction_t xbt, 17.20 - char* node, 17.21 - char* path, 17.22 - char* fmt, 17.23 - ...) 17.24 -{ 17.25 - char fullpath[1024]; 17.26 - char val[1024]; 17.27 - va_list args; 17.28 - 17.29 - va_start(args, fmt); 17.30 - snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path); 17.31 - vsnprintf(val, sizeof(val), fmt, args); 17.32 - va_end(args); 17.33 - FS_DEBUG("xenbus_printf (%s) <= %s.\n", fullpath, val); 17.34 - 17.35 - return xs_write(xsh, xbt, fullpath, val, strlen(val)); 17.36 -} 17.37 - 17.38 -bool xenbus_create_request_node(void) 17.39 -{ 17.40 - bool ret; 17.41 - struct xs_permissions perms; 17.42 - 17.43 - assert(xsh != NULL); 17.44 - xs_rm(xsh, XBT_NULL, WATCH_NODE); 17.45 - ret = xs_mkdir(xsh, XBT_NULL, WATCH_NODE); 17.46 - if (!ret) 17.47 - return false; 17.48 - 17.49 - perms.id = 0; 17.50 - perms.perms = XS_PERM_WRITE; 17.51 - ret = xs_set_permissions(xsh, XBT_NULL, WATCH_NODE, &perms, 1); 17.52 - 17.53 - return ret; 17.54 -} 17.55 - 17.56 -int xenbus_register_export(struct fs_export *export) 17.57 -{ 17.58 - xs_transaction_t xst = 0; 17.59 - char node[1024]; 17.60 - struct xs_permissions perms; 17.61 - 17.62 - assert(xsh != NULL); 17.63 - if(xsh == NULL) 17.64 - { 17.65 - FS_DEBUG("Could not open connection to xenbus deamon.\n"); 17.66 - goto error_exit; 17.67 - } 17.68 - FS_DEBUG("Connection to the xenbus deamon opened successfully.\n"); 17.69 - 17.70 - /* Start transaction */ 17.71 - xst = xs_transaction_start(xsh); 17.72 - if(xst == 0) 17.73 - { 17.74 - FS_DEBUG("Could not start a transaction.\n"); 17.75 - goto error_exit; 17.76 - } 17.77 - FS_DEBUG("XS transaction is %d\n", xst); 17.78 - 17.79 - /* Create node string */ 17.80 - snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 17.81 - /* Remove old export (if exists) */ 17.82 - xs_rm(xsh, xst, node); 17.83 - 17.84 - if(!xenbus_printf(xsh, xst, node, "name", "%s", export->name)) 17.85 - { 17.86 - FS_DEBUG("Could not write the export node.\n"); 17.87 - goto error_exit; 17.88 - } 17.89 - 17.90 - /* People need to be able to read our export */ 17.91 - perms.id = 0; 17.92 - perms.perms = XS_PERM_READ; 17.93 - if(!xs_set_permissions(xsh, xst, EXPORTS_NODE, &perms, 1)) 17.94 - { 17.95 - FS_DEBUG("Could not set permissions on the export node.\n"); 17.96 - goto error_exit; 17.97 - } 17.98 - 17.99 - xs_transaction_end(xsh, xst, 0); 17.100 - return 0; 17.101 - 17.102 -error_exit: 17.103 - if(xst != 0) 17.104 - xs_transaction_end(xsh, xst, 1); 17.105 - return -1; 17.106 -} 17.107 - 17.108 -int xenbus_get_watch_fd(void) 17.109 -{ 17.110 - int res; 17.111 -#if DEBUG 17.112 - int errno_orig; 17.113 -#endif 17.114 - assert(xsh != NULL); 17.115 - res = xs_watch(xsh, WATCH_NODE, "conn-watch"); 17.116 - if (!res) { 17.117 -#if DEBUG 17.118 - errno_orig = errno; 17.119 - FS_DEBUG("ERROR: xs_watch %s failed ret=%d errno=%d\n", 17.120 - WATCH_NODE, res, errno); 17.121 - errno = errno_orig; 17.122 -#endif 17.123 - return -1; 17.124 - } 17.125 - return xs_fileno(xsh); 17.126 -} 17.127 - 17.128 -int xenbus_read_mount_request(struct fs_mount *mount, char *frontend) 17.129 -{ 17.130 - char node[1024]; 17.131 - char *s; 17.132 - int i; 17.133 - 17.134 - assert(xsh != NULL); 17.135 -#if 0 17.136 - snprintf(node, sizeof(node), WATCH_NODE"/%d/%d/frontend", 17.137 - mount->dom_id, mount->export->export_id); 17.138 - frontend = xs_read(xsh, XBT_NULL, node, NULL); 17.139 -#endif 17.140 - mount->frontend = frontend; 17.141 - snprintf(node, sizeof(node), "%s/state", frontend); 17.142 - s = xs_read(xsh, XBT_NULL, node, NULL); 17.143 - if (strcmp(s, STATE_READY) != 0) { 17.144 - FS_DEBUG("ERROR: frontend not read\n"); 17.145 - goto error; 17.146 - } 17.147 - free(s); 17.148 - snprintf(node, sizeof(node), "%s/ring-size", frontend); 17.149 - s = xs_read(xsh, XBT_NULL, node, NULL); 17.150 - mount->shared_ring_size = atoi(s); 17.151 - if (mount->shared_ring_size > MAX_RING_SIZE) { 17.152 - FS_DEBUG("ERROR: shared_ring_size (%d) > MAX_RING_SIZE\n", mount->shared_ring_size); 17.153 - goto error; 17.154 - } 17.155 - free(s); 17.156 - for(i=0; i<mount->shared_ring_size; i++) 17.157 - { 17.158 - snprintf(node, sizeof(node), "%s/ring-ref-%d", frontend, i); 17.159 - s = xs_read(xsh, XBT_NULL, node, NULL); 17.160 - mount->grefs[i] = atoi(s); 17.161 - free(s); 17.162 - } 17.163 - snprintf(node, sizeof(node), "%s/event-channel", frontend); 17.164 - s = xs_read(xsh, XBT_NULL, node, NULL); 17.165 - mount->remote_evtchn = atoi(s); 17.166 - free(s); 17.167 - return 0; 17.168 - 17.169 -error: 17.170 - free(s); 17.171 - return -1; 17.172 -} 17.173 - 17.174 -/* Small utility function to figure out our domain id */ 17.175 -static int get_self_id(void) 17.176 -{ 17.177 - char *dom_id; 17.178 - int ret; 17.179 - 17.180 - assert(xsh != NULL); 17.181 - dom_id = xs_read(xsh, XBT_NULL, "domid", NULL); 17.182 - sscanf(dom_id, "%d", &ret); 17.183 - free(dom_id); 17.184 - 17.185 - return ret; 17.186 -} 17.187 - 17.188 - 17.189 -bool xenbus_write_backend_node(struct fs_mount *mount) 17.190 -{ 17.191 - char node[1024], backend_node[1024]; 17.192 - int self_id; 17.193 - 17.194 - assert(xsh != NULL); 17.195 - self_id = get_self_id(); 17.196 - FS_DEBUG("Our own dom_id=%d\n", self_id); 17.197 - snprintf(node, sizeof(node), "%s/backend", mount->frontend); 17.198 - snprintf(backend_node, sizeof(backend_node), "/local/domain/%d/"ROOT_NODE"/%d", 17.199 - self_id, mount->mount_id); 17.200 - xs_write(xsh, XBT_NULL, node, backend_node, strlen(backend_node)); 17.201 - 17.202 - snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id); 17.203 - return xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, strlen(STATE_INITIALISED)); 17.204 -} 17.205 - 17.206 -bool xenbus_write_backend_state(struct fs_mount *mount, const char *state) 17.207 -{ 17.208 - char node[1024]; 17.209 - int self_id; 17.210 - 17.211 - assert(xsh != NULL); 17.212 - self_id = get_self_id(); 17.213 - snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id); 17.214 - return xs_write(xsh, XBT_NULL, node, state, strlen(state)); 17.215 -} 17.216 - 17.217 -void xenbus_free_backend_node(struct fs_mount *mount) 17.218 -{ 17.219 - char node[1024]; 17.220 - int self_id; 17.221 - 17.222 - assert(xsh != NULL); 17.223 - self_id = get_self_id(); 17.224 - snprintf(node, sizeof(node), ROOT_NODE"/%d", mount->mount_id); 17.225 - xs_rm(xsh, XBT_NULL, node); 17.226 -} 17.227 - 17.228 -bool xenbus_watch_frontend_state(struct fs_mount *mount) 17.229 -{ 17.230 - char statepath[1024]; 17.231 - 17.232 - assert(xsh != NULL); 17.233 - snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 17.234 - return xs_watch(xsh, statepath, "frontend-state"); 17.235 -} 17.236 - 17.237 -bool xenbus_unwatch_frontend_state(struct fs_mount *mount) 17.238 -{ 17.239 - char statepath[1024]; 17.240 - 17.241 - assert(xsh != NULL); 17.242 - snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 17.243 - return xs_unwatch(xsh, statepath, "frontend-state"); 17.244 -} 17.245 - 17.246 -int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate) 17.247 -{ 17.248 - unsigned int len; 17.249 - char statepath[1024]; 17.250 - char *state = NULL; 17.251 - 17.252 - assert(xsh != NULL); 17.253 - snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 17.254 - state = xs_read(xsh, XBT_NULL, statepath, &len); 17.255 - if (state && len > 0) { 17.256 - if (strcmp(state, oldstate)) { 17.257 - free(state); 17.258 - return 1; 17.259 - } else { 17.260 - free(state); 17.261 - return 0; 17.262 - } 17.263 - } else 17.264 - return 1; 17.265 -} 17.266 - 17.267 -char* xenbus_read_frontend_state(struct fs_mount *mount) 17.268 -{ 17.269 - unsigned int len; 17.270 - char statepath[1024]; 17.271 - 17.272 - assert(xsh != NULL); 17.273 - snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 17.274 - return xs_read(xsh, XBT_NULL, statepath, &len); 17.275 -} 17.276 -
18.1 --- a/tools/fs-back/sys-queue.h Tue Jan 11 19:31:41 2011 +0000 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,338 +0,0 @@ 18.4 -/* $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */ 18.5 - 18.6 -/* 18.7 - * Qemu version: Copy from netbsd, removed debug code, removed some of 18.8 - * the implementations. Left in lists, tail queues and circular queues. 18.9 - */ 18.10 - 18.11 -/* 18.12 - * Copyright (c) 1991, 1993 18.13 - * The Regents of the University of California. All rights reserved. 18.14 - * 18.15 - * Redistribution and use in source and binary forms, with or without 18.16 - * modification, are permitted provided that the following conditions 18.17 - * are met: 18.18 - * 1. Redistributions of source code must retain the above copyright 18.19 - * notice, this list of conditions and the following disclaimer. 18.20 - * 2. Redistributions in binary form must reproduce the above copyright 18.21 - * notice, this list of conditions and the following disclaimer in the 18.22 - * documentation and/or other materials provided with the distribution. 18.23 - * 3. Neither the name of the University nor the names of its contributors 18.24 - * may be used to endorse or promote products derived from this software 18.25 - * without specific prior written permission. 18.26 - * 18.27 - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18.28 - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.29 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18.30 - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 18.31 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.32 - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18.33 - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18.34 - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18.35 - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 18.36 - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 18.37 - * SUCH DAMAGE. 18.38 - * 18.39 - * @(#)queue.h 8.5 (Berkeley) 8/20/94 18.40 - */ 18.41 - 18.42 -#ifndef _SYS_QUEUE_H_ 18.43 -#define _SYS_QUEUE_H_ 18.44 - 18.45 -/* 18.46 - * This file defines three types of data structures: 18.47 - * lists, tail queues, and circular queues. 18.48 - * 18.49 - * A list is headed by a single forward pointer (or an array of forward 18.50 - * pointers for a hash table header). The elements are doubly linked 18.51 - * so that an arbitrary element can be removed without a need to 18.52 - * traverse the list. New elements can be added to the list before 18.53 - * or after an existing element or at the head of the list. A list 18.54 - * may only be traversed in the forward direction. 18.55 - * 18.56 - * A tail queue is headed by a pair of pointers, one to the head of the 18.57 - * list and the other to the tail of the list. The elements are doubly 18.58 - * linked so that an arbitrary element can be removed without a need to 18.59 - * traverse the list. New elements can be added to the list before or 18.60 - * after an existing element, at the head of the list, or at the end of 18.61 - * the list. A tail queue may be traversed in either direction. 18.62 - * 18.63 - * A circle queue is headed by a pair of pointers, one to the head of the 18.64 - * list and the other to the tail of the list. The elements are doubly 18.65 - * linked so that an arbitrary element can be removed without a need to 18.66 - * traverse the list. New elements can be added to the list before or after 18.67 - * an existing element, at the head of the list, or at the end of the list. 18.68 - * A circle queue may be traversed in either direction, but has a more 18.69 - * complex end of list detection. 18.70 - * 18.71 - * For details on the use of these macros, see the queue(3) manual page. 18.72 - */ 18.73 - 18.74 -/* 18.75 - * List definitions. 18.76 - */ 18.77 -#define LIST_HEAD(name, type) \ 18.78 -struct name { \ 18.79 - struct type *lh_first; /* first element */ \ 18.80 -} 18.81 - 18.82 -#define LIST_HEAD_INITIALIZER(head) \ 18.83 - { NULL } 18.84 - 18.85 -#define LIST_ENTRY(type) \ 18.86 -struct { \ 18.87 - struct type *le_next; /* next element */ \ 18.88 - struct type **le_prev; /* address of previous next element */ \ 18.89 -} 18.90 - 18.91 -/* 18.92 - * List functions. 18.93 - */ 18.94 -#define LIST_INIT(head) do { \ 18.95 - (head)->lh_first = NULL; \ 18.96 -} while (/*CONSTCOND*/0) 18.97 - 18.98 -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ 18.99 - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ 18.100 - (listelm)->field.le_next->field.le_prev = \ 18.101 - &(elm)->field.le_next; \ 18.102 - (listelm)->field.le_next = (elm); \ 18.103 - (elm)->field.le_prev = &(listelm)->field.le_next; \ 18.104 -} while (/*CONSTCOND*/0) 18.105 - 18.106 -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 18.107 - (elm)->field.le_prev = (listelm)->field.le_prev; \ 18.108 - (elm)->field.le_next = (listelm); \ 18.109 - *(listelm)->field.le_prev = (elm); \ 18.110 - (listelm)->field.le_prev = &(elm)->field.le_next; \ 18.111 -} while (/*CONSTCOND*/0) 18.112 - 18.113 -#define LIST_INSERT_HEAD(head, elm, field) do { \ 18.114 - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ 18.115 - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ 18.116 - (head)->lh_first = (elm); \ 18.117 - (elm)->field.le_prev = &(head)->lh_first; \ 18.118 -} while (/*CONSTCOND*/0) 18.119 - 18.120 -#define LIST_REMOVE(elm, field) do { \ 18.121 - if ((elm)->field.le_next != NULL) \ 18.122 - (elm)->field.le_next->field.le_prev = \ 18.123 - (elm)->field.le_prev; \ 18.124 - *(elm)->field.le_prev = (elm)->field.le_next; \ 18.125 -} while (/*CONSTCOND*/0) 18.126 - 18.127 -#define LIST_FOREACH(var, head, field) \ 18.128 - for ((var) = ((head)->lh_first); \ 18.129 - (var); \ 18.130 - (var) = ((var)->field.le_next)) 18.131 - 18.132 -/* 18.133 - * List access methods. 18.134 - */ 18.135 -#define LIST_EMPTY(head) ((head)->lh_first == NULL) 18.136 -#define LIST_FIRST(head) ((head)->lh_first) 18.137 -#define LIST_NEXT(elm, field) ((elm)->field.le_next) 18.138 - 18.139 - 18.140 -/* 18.141 - * Tail queue definitions. 18.142 - */ 18.143 -#define _TAILQ_HEAD(name, type, qual) \ 18.144 -struct name { \ 18.145 - qual type *tqh_first; /* first element */ \ 18.146 - qual type *qual *tqh_last; /* addr of last next element */ \ 18.147 -} 18.148 -#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,) 18.149 - 18.150 -#define TAILQ_HEAD_INITIALIZER(head) \ 18.151 - { NULL, &(head).tqh_first } 18.152 - 18.153 -#define _TAILQ_ENTRY(type, qual) \ 18.154 -struct { \ 18.155 - qual type *tqe_next; /* next element */ \ 18.156 - qual type *qual *tqe_prev; /* address of previous next element */\ 18.157 -} 18.158 -#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,) 18.159 - 18.160 -/* 18.161 - * Tail queue functions. 18.162 - */ 18.163 -#define TAILQ_INIT(head) do { \ 18.164 - (head)->tqh_first = NULL; \ 18.165 - (head)->tqh_last = &(head)->tqh_first; \ 18.166 -} while (/*CONSTCOND*/0) 18.167 - 18.168 -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ 18.169 - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ 18.170 - (head)->tqh_first->field.tqe_prev = \ 18.171 - &(elm)->field.tqe_next; \ 18.172 - else \ 18.173 - (head)->tqh_last = &(elm)->field.tqe_next; \ 18.174 - (head)->tqh_first = (elm); \ 18.175 - (elm)->field.tqe_prev = &(head)->tqh_first; \ 18.176 -} while (/*CONSTCOND*/0) 18.177 - 18.178 -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ 18.179 - (elm)->field.tqe_next = NULL; \ 18.180 - (elm)->field.tqe_prev = (head)->tqh_last; \ 18.181 - *(head)->tqh_last = (elm); \ 18.182 - (head)->tqh_last = &(elm)->field.tqe_next; \ 18.183 -} while (/*CONSTCOND*/0) 18.184 - 18.185 -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 18.186 - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ 18.187 - (elm)->field.tqe_next->field.tqe_prev = \ 18.188 - &(elm)->field.tqe_next; \ 18.189 - else \ 18.190 - (head)->tqh_last = &(elm)->field.tqe_next; \ 18.191 - (listelm)->field.tqe_next = (elm); \ 18.192 - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ 18.193 -} while (/*CONSTCOND*/0) 18.194 - 18.195 -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 18.196 - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 18.197 - (elm)->field.tqe_next = (listelm); \ 18.198 - *(listelm)->field.tqe_prev = (elm); \ 18.199 - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ 18.200 -} while (/*CONSTCOND*/0) 18.201 - 18.202 -#define TAILQ_REMOVE(head, elm, field) do { \ 18.203 - if (((elm)->field.tqe_next) != NULL) \ 18.204 - (elm)->field.tqe_next->field.tqe_prev = \ 18.205 - (elm)->field.tqe_prev; \ 18.206 - else \ 18.207 - (head)->tqh_last = (elm)->field.tqe_prev; \ 18.208 - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ 18.209 -} while (/*CONSTCOND*/0) 18.210 - 18.211 -#define TAILQ_FOREACH(var, head, field) \ 18.212 - for ((var) = ((head)->tqh_first); \ 18.213 - (var); \ 18.214 - (var) = ((var)->field.tqe_next)) 18.215 - 18.216 -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 18.217 - for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ 18.218 - (var); \ 18.219 - (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) 18.220 - 18.221 -/* 18.222 - * Tail queue access methods. 18.223 - */ 18.224 -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 18.225 -#define TAILQ_FIRST(head) ((head)->tqh_first) 18.226 -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 18.227 - 18.228 -#define TAILQ_LAST(head, headname) \ 18.229 - (*(((struct headname *)((head)->tqh_last))->tqh_last)) 18.230 -#define TAILQ_PREV(elm, headname, field) \ 18.231 - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 18.232 - 18.233 - 18.234 -/* 18.235 - * Circular queue definitions. 18.236 - */ 18.237 -#define CIRCLEQ_HEAD(name, type) \ 18.238 -struct name { \ 18.239 - struct type *cqh_first; /* first element */ \ 18.240 - struct type *cqh_last; /* last element */ \ 18.241 -} 18.242 - 18.243 -#define CIRCLEQ_HEAD_INITIALIZER(head) \ 18.244 - { (void *)&head, (void *)&head } 18.245 - 18.246 -#define CIRCLEQ_ENTRY(type) \ 18.247 -struct { \ 18.248 - struct type *cqe_next; /* next element */ \ 18.249 - struct type *cqe_prev; /* previous element */ \ 18.250 -} 18.251 - 18.252 -/* 18.253 - * Circular queue functions. 18.254 - */ 18.255 -#define CIRCLEQ_INIT(head) do { \ 18.256 - (head)->cqh_first = (void *)(head); \ 18.257 - (head)->cqh_last = (void *)(head); \ 18.258 -} while (/*CONSTCOND*/0) 18.259 - 18.260 -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 18.261 - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ 18.262 - (elm)->field.cqe_prev = (listelm); \ 18.263 - if ((listelm)->field.cqe_next == (void *)(head)) \ 18.264 - (head)->cqh_last = (elm); \ 18.265 - else \ 18.266 - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ 18.267 - (listelm)->field.cqe_next = (elm); \ 18.268 -} while (/*CONSTCOND*/0) 18.269 - 18.270 -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ 18.271 - (elm)->field.cqe_next = (listelm); \ 18.272 - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ 18.273 - if ((listelm)->field.cqe_prev == (void *)(head)) \ 18.274 - (head)->cqh_first = (elm); \ 18.275 - else \ 18.276 - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ 18.277 - (listelm)->field.cqe_prev = (elm); \ 18.278 -} while (/*CONSTCOND*/0) 18.279 - 18.280 -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ 18.281 - (elm)->field.cqe_next = (head)->cqh_first; \ 18.282 - (elm)->field.cqe_prev = (void *)(head); \ 18.283 - if ((head)->cqh_last == (void *)(head)) \ 18.284 - (head)->cqh_last = (elm); \ 18.285 - else \ 18.286 - (head)->cqh_first->field.cqe_prev = (elm); \ 18.287 - (head)->cqh_first = (elm); \ 18.288 -} while (/*CONSTCOND*/0) 18.289 - 18.290 -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ 18.291 - (elm)->field.cqe_next = (void *)(head); \ 18.292 - (elm)->field.cqe_prev = (head)->cqh_last; \ 18.293 - if ((head)->cqh_first == (void *)(head)) \ 18.294 - (head)->cqh_first = (elm); \ 18.295 - else \ 18.296 - (head)->cqh_last->field.cqe_next = (elm); \ 18.297 - (head)->cqh_last = (elm); \ 18.298 -} while (/*CONSTCOND*/0) 18.299 - 18.300 -#define CIRCLEQ_REMOVE(head, elm, field) do { \ 18.301 - if ((elm)->field.cqe_next == (void *)(head)) \ 18.302 - (head)->cqh_last = (elm)->field.cqe_prev; \ 18.303 - else \ 18.304 - (elm)->field.cqe_next->field.cqe_prev = \ 18.305 - (elm)->field.cqe_prev; \ 18.306 - if ((elm)->field.cqe_prev == (void *)(head)) \ 18.307 - (head)->cqh_first = (elm)->field.cqe_next; \ 18.308 - else \ 18.309 - (elm)->field.cqe_prev->field.cqe_next = \ 18.310 - (elm)->field.cqe_next; \ 18.311 -} while (/*CONSTCOND*/0) 18.312 - 18.313 -#define CIRCLEQ_FOREACH(var, head, field) \ 18.314 - for ((var) = ((head)->cqh_first); \ 18.315 - (var) != (const void *)(head); \ 18.316 - (var) = ((var)->field.cqe_next)) 18.317 - 18.318 -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ 18.319 - for ((var) = ((head)->cqh_last); \ 18.320 - (var) != (const void *)(head); \ 18.321 - (var) = ((var)->field.cqe_prev)) 18.322 - 18.323 -/* 18.324 - * Circular queue access methods. 18.325 - */ 18.326 -#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) 18.327 -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) 18.328 -#define CIRCLEQ_LAST(head) ((head)->cqh_last) 18.329 -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) 18.330 -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) 18.331 - 18.332 -#define CIRCLEQ_LOOP_NEXT(head, elm, field) \ 18.333 - (((elm)->field.cqe_next == (void *)(head)) \ 18.334 - ? ((head)->cqh_first) \ 18.335 - : (elm->field.cqe_next)) 18.336 -#define CIRCLEQ_LOOP_PREV(head, elm, field) \ 18.337 - (((elm)->field.cqe_prev == (void *)(head)) \ 18.338 - ? ((head)->cqh_last) \ 18.339 - : (elm->field.cqe_prev)) 18.340 - 18.341 -#endif /* !_SYS_QUEUE_H_ */
19.1 --- a/tools/libxl/Makefile Tue Jan 11 19:31:41 2011 +0000 19.2 +++ b/tools/libxl/Makefile Tue Jan 11 19:41:53 2011 +0000 19.3 @@ -20,7 +20,7 @@ ifeq ($(CONFIG_Linux),y) 19.4 LIBS += -luuid 19.5 endif 19.6 19.7 -LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o 19.8 +LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o 19.9 ifeq ($(LIBXL_BLKTAP),y) 19.10 LIBXL_OBJS-y += libxl_blktap2.o 19.11 else 19.12 @@ -29,7 +29,9 @@ endif 19.13 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o 19.14 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o 19.15 19.16 -LIBXL_OBJS = flexarray.o libxl.o libxl_dm.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y) 19.17 +LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \ 19.18 + libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \ 19.19 + libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y) 19.20 LIBXL_OBJS += _libxl_types.o 19.21 19.22 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
20.1 --- a/tools/libxl/libxl.c Tue Jan 11 19:31:41 2011 +0000 20.2 +++ b/tools/libxl/libxl.c Tue Jan 11 19:41:53 2011 +0000 20.3 @@ -104,114 +104,6 @@ void libxl_key_value_list_destroy(libxl_ 20.4 20.5 /******************************************************************************/ 20.6 20.7 -int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, 20.8 - uint32_t *domid) 20.9 -{ 20.10 - libxl__gc gc = LIBXL_INIT_GC(ctx); 20.11 - int flags, ret, i, rc; 20.12 - char *uuid_string; 20.13 - char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; 20.14 - char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", 20.15 - "control", "attr", "messages" }; 20.16 - char *dom_path, *vm_path; 20.17 - struct xs_permissions roperm[2]; 20.18 - struct xs_permissions rwperm[1]; 20.19 - xs_transaction_t t; 20.20 - xen_domain_handle_t handle; 20.21 - 20.22 - uuid_string = libxl__uuid2string(&gc, info->uuid); 20.23 - if (!uuid_string) { 20.24 - libxl__free_all(&gc); 20.25 - return ERROR_NOMEM; 20.26 - } 20.27 - 20.28 - flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; 20.29 - flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; 20.30 - flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off; 20.31 - *domid = -1; 20.32 - 20.33 - /* Ultimately, handle is an array of 16 uint8_t, same as uuid */ 20.34 - libxl_uuid_copy((libxl_uuid *)handle, &info->uuid); 20.35 - 20.36 - ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); 20.37 - if (ret < 0) { 20.38 - LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail"); 20.39 - libxl__free_all(&gc); 20.40 - return ERROR_FAIL; 20.41 - } 20.42 - 20.43 - ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); 20.44 - if (ret < 0) { 20.45 - LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail"); 20.46 - libxl__free_all(&gc); 20.47 - return ERROR_FAIL; 20.48 - } 20.49 - 20.50 - dom_path = libxl__xs_get_dompath(&gc, *domid); 20.51 - if (!dom_path) { 20.52 - libxl__free_all(&gc); 20.53 - return ERROR_FAIL; 20.54 - } 20.55 - 20.56 - vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string); 20.57 - if (!vm_path) { 20.58 - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths"); 20.59 - libxl__free_all(&gc); 20.60 - return ERROR_FAIL; 20.61 - } 20.62 - 20.63 - roperm[0].id = 0; 20.64 - roperm[0].perms = XS_PERM_NONE; 20.65 - roperm[1].id = *domid; 20.66 - roperm[1].perms = XS_PERM_READ; 20.67 - rwperm[0].id = *domid; 20.68 - rwperm[0].perms = XS_PERM_NONE; 20.69 - 20.70 -retry_transaction: 20.71 - t = xs_transaction_start(ctx->xsh); 20.72 - xs_rm(ctx->xsh, t, dom_path); 20.73 - xs_mkdir(ctx->xsh, t, dom_path); 20.74 - xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); 20.75 - 20.76 - xs_rm(ctx->xsh, t, vm_path); 20.77 - xs_mkdir(ctx->xsh, t, vm_path); 20.78 - xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); 20.79 - 20.80 - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); 20.81 - rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); 20.82 - if (rc) { 20.83 - libxl__free_all(&gc); 20.84 - return rc; 20.85 - } 20.86 - 20.87 - for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { 20.88 - char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); 20.89 - xs_mkdir(ctx->xsh, t, path); 20.90 - xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); 20.91 - } 20.92 - for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { 20.93 - char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); 20.94 - xs_mkdir(ctx->xsh, t, path); 20.95 - xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); 20.96 - } 20.97 - 20.98 - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); 20.99 - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); 20.100 - if (info->poolname) 20.101 - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); 20.102 - 20.103 - libxl__xs_writev(&gc, t, dom_path, info->xsdata); 20.104 - libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata); 20.105 - 20.106 - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); 20.107 - 20.108 - if (!xs_transaction_end(ctx->xsh, t, 0)) 20.109 - if (errno == EAGAIN) 20.110 - goto retry_transaction; 20.111 - 20.112 - libxl__free_all(&gc); 20.113 - return 0; 20.114 -} 20.115 20.116 int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, 20.117 const char *old_name, const char *new_name, 20.118 @@ -293,141 +185,6 @@ int libxl_domain_rename(libxl_ctx *ctx, 20.119 x_nomem: rc = ERROR_NOMEM; goto x_rc; 20.120 } 20.121 20.122 -int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) 20.123 -{ 20.124 - libxl__gc gc = LIBXL_INIT_GC(ctx); 20.125 - char **vments = NULL, **localents = NULL; 20.126 - struct timeval start_time; 20.127 - int i, ret; 20.128 - 20.129 - ret = libxl__build_pre(ctx, domid, info, state); 20.130 - if (ret) 20.131 - goto out; 20.132 - 20.133 - gettimeofday(&start_time, NULL); 20.134 - 20.135 - if (info->hvm) { 20.136 - ret = libxl__build_hvm(ctx, domid, info, state); 20.137 - if (ret) 20.138 - goto out; 20.139 - 20.140 - vments = libxl__calloc(&gc, 7, sizeof(char *)); 20.141 - vments[0] = "rtc/timeoffset"; 20.142 - vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; 20.143 - vments[2] = "image/ostype"; 20.144 - vments[3] = "hvm"; 20.145 - vments[4] = "start_time"; 20.146 - vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 20.147 - } else { 20.148 - ret = libxl__build_pv(ctx, domid, info, state); 20.149 - if (ret) 20.150 - goto out; 20.151 - 20.152 - vments = libxl__calloc(&gc, 11, sizeof(char *)); 20.153 - i = 0; 20.154 - vments[i++] = "image/ostype"; 20.155 - vments[i++] = "linux"; 20.156 - vments[i++] = "image/kernel"; 20.157 - vments[i++] = (char*) info->kernel.path; 20.158 - vments[i++] = "start_time"; 20.159 - vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 20.160 - if (info->u.pv.ramdisk.path) { 20.161 - vments[i++] = "image/ramdisk"; 20.162 - vments[i++] = (char*) info->u.pv.ramdisk.path; 20.163 - } 20.164 - if (info->u.pv.cmdline) { 20.165 - vments[i++] = "image/cmdline"; 20.166 - vments[i++] = (char*) info->u.pv.cmdline; 20.167 - } 20.168 - } 20.169 - ret = libxl__build_post(ctx, domid, info, state, vments, localents); 20.170 -out: 20.171 - libxl__file_reference_unmap(&info->kernel); 20.172 - if (!info->hvm) 20.173 - libxl__file_reference_unmap(&info->u.pv.ramdisk); 20.174 - 20.175 - libxl__free_all(&gc); 20.176 - return ret; 20.177 -} 20.178 - 20.179 -int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, 20.180 - uint32_t domid, int fd, libxl_domain_build_state *state, 20.181 - libxl_device_model_info *dm_info) 20.182 -{ 20.183 - libxl__gc gc = LIBXL_INIT_GC(ctx); 20.184 - char **vments = NULL, **localents = NULL; 20.185 - struct timeval start_time; 20.186 - int i, ret, esave, flags; 20.187 - 20.188 - ret = libxl__build_pre(ctx, domid, info, state); 20.189 - if (ret) 20.190 - goto out; 20.191 - 20.192 - ret = libxl__domain_restore_common(ctx, domid, info, state, fd); 20.193 - if (ret) 20.194 - goto out; 20.195 - 20.196 - gettimeofday(&start_time, NULL); 20.197 - 20.198 - if (info->hvm) { 20.199 - vments = libxl__calloc(&gc, 7, sizeof(char *)); 20.200 - vments[0] = "rtc/timeoffset"; 20.201 - vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; 20.202 - vments[2] = "image/ostype"; 20.203 - vments[3] = "hvm"; 20.204 - vments[4] = "start_time"; 20.205 - vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 20.206 - } else { 20.207 - vments = libxl__calloc(&gc, 11, sizeof(char *)); 20.208 - i = 0; 20.209 - vments[i++] = "image/ostype"; 20.210 - vments[i++] = "linux"; 20.211 - vments[i++] = "image/kernel"; 20.212 - vments[i++] = (char*) info->kernel.path; 20.213 - vments[i++] = "start_time"; 20.214 - vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 20.215 - if (info->u.pv.ramdisk.path) { 20.216 - vments[i++] = "image/ramdisk"; 20.217 - vments[i++] = (char*) info->u.pv.ramdisk.path; 20.218 - } 20.219 - if (info->u.pv.cmdline) { 20.220 - vments[i++] = "image/cmdline"; 20.221 - vments[i++] = (char*) info->u.pv.cmdline; 20.222 - } 20.223 - } 20.224 - ret = libxl__build_post(ctx, domid, info, state, vments, localents); 20.225 - if (ret) 20.226 - goto out; 20.227 - 20.228 - dm_info->saved_state = NULL; 20.229 - if (info->hvm) { 20.230 - ret = asprintf(&dm_info->saved_state, 20.231 - "/var/lib/xen/qemu-save.%d", domid); 20.232 - ret = (ret < 0) ? ERROR_FAIL : 0; 20.233 - } 20.234 - 20.235 -out: 20.236 - libxl__file_reference_unmap(&info->kernel); 20.237 - if (!info->hvm) 20.238 - libxl__file_reference_unmap(&info->u.pv.ramdisk); 20.239 - 20.240 - esave = errno; 20.241 - 20.242 - flags = fcntl(fd, F_GETFL); 20.243 - if (flags == -1) { 20.244 - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd"); 20.245 - } else { 20.246 - flags &= ~O_NONBLOCK; 20.247 - if (fcntl(fd, F_SETFL, flags) == -1) 20.248 - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd" 20.249 - " back to blocking mode"); 20.250 - } 20.251 - 20.252 - errno = esave; 20.253 - libxl__free_all(&gc); 20.254 - return ret; 20.255 -} 20.256 - 20.257 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) 20.258 { 20.259 libxl__gc gc = LIBXL_INIT_GC(ctx); 20.260 @@ -1267,6 +1024,35 @@ int libxl_device_disk_local_detach(libxl 20.261 } 20.262 20.263 /******************************************************************************/ 20.264 +int libxl_device_nic_init(libxl_device_nic *nic_info, int devnum) 20.265 +{ 20.266 + const uint8_t *r; 20.267 + libxl_uuid uuid; 20.268 + 20.269 + libxl_uuid_generate(&uuid); 20.270 + r = libxl_uuid_bytearray(&uuid); 20.271 + memset(nic_info, '\0', sizeof(*nic_info)); 20.272 + 20.273 + nic_info->backend_domid = 0; 20.274 + nic_info->domid = 0; 20.275 + nic_info->devid = devnum; 20.276 + nic_info->mtu = 1492; 20.277 + nic_info->model = strdup("e1000"); 20.278 + nic_info->mac[0] = 0x00; 20.279 + nic_info->mac[1] = 0x16; 20.280 + nic_info->mac[2] = 0x3e; 20.281 + nic_info->mac[3] = r[0] & 0x7f; 20.282 + nic_info->mac[4] = r[1]; 20.283 + nic_info->mac[5] = r[2]; 20.284 + nic_info->ifname = NULL; 20.285 + nic_info->bridge = strdup("xenbr0"); 20.286 + if ( asprintf(&nic_info->script, "%s/vif-bridge", 20.287 + libxl_xen_script_dir_path()) < 0 ) 20.288 + return ERROR_FAIL; 20.289 + nic_info->nictype = NICTYPE_IOEMU; 20.290 + return 0; 20.291 +} 20.292 + 20.293 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) 20.294 { 20.295 libxl__gc gc = LIBXL_INIT_GC(ctx); 20.296 @@ -1425,6 +1211,34 @@ err: 20.297 } 20.298 20.299 /******************************************************************************/ 20.300 +void libxl_device_net2_init(libxl_device_net2 *net2_info, int devnum) 20.301 +{ 20.302 + const uint8_t *r; 20.303 + libxl_uuid uuid; 20.304 + 20.305 + libxl_uuid_generate(&uuid); 20.306 + r = libxl_uuid_bytearray(&uuid); 20.307 + memset(net2_info, '\0', sizeof(*net2_info)); 20.308 + 20.309 + net2_info->devid = devnum; 20.310 + net2_info->front_mac[0] = 0x00; 20.311 + net2_info->front_mac[1] = 0x16; 20.312 + net2_info->front_mac[2] = 0x3e;; 20.313 + net2_info->front_mac[3] = 0x7f & r[0]; 20.314 + net2_info->front_mac[4] = r[1]; 20.315 + net2_info->front_mac[5] = r[2]; 20.316 + net2_info->back_mac[0] = 0x00; 20.317 + net2_info->back_mac[1] = 0x16; 20.318 + net2_info->back_mac[2] = 0x3e; 20.319 + net2_info->back_mac[3] = 0x7f & r[3]; 20.320 + net2_info->back_mac[4] = r[4]; 20.321 + net2_info->back_mac[5] = r[5]; 20.322 + net2_info->back_trusted = 1; 20.323 + net2_info->filter_mac = 1; 20.324 + net2_info->max_bypasses = 5; 20.325 + net2_info->bridge = strdup("xenbr0"); 20.326 +} 20.327 + 20.328 int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 *net2) 20.329 { 20.330 libxl__gc gc = LIBXL_INIT_GC(ctx); 20.331 @@ -1692,6 +1506,12 @@ out: 20.332 } 20.333 20.334 /******************************************************************************/ 20.335 +void libxl_device_vkb_init(libxl_device_vkb *vkb, int dev_num) 20.336 +{ 20.337 + memset(vkb, 0x00, sizeof(libxl_device_vkb)); 20.338 + vkb->devid = dev_num; 20.339 +} 20.340 + 20.341 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) 20.342 { 20.343 libxl__gc gc = LIBXL_INIT_GC(ctx); 20.344 @@ -1890,6 +1710,22 @@ out: 20.345 } 20.346 20.347 /******************************************************************************/ 20.348 +void libxl_device_vfb_init(libxl_device_vfb *vfb, int dev_num) 20.349 +{ 20.350 + memset(vfb, 0x00, sizeof(libxl_device_vfb)); 20.351 + vfb->devid = dev_num; 20.352 + vfb->display = NULL; 20.353 + vfb->xauthority = NULL; 20.354 + vfb->vnc = 1; 20.355 + vfb->vncpasswd = NULL; 20.356 + vfb->vnclisten = strdup("127.0.0.1"); 20.357 + vfb->vncdisplay = 0; 20.358 + vfb->vncunused = 1; 20.359 + vfb->keymap = NULL; 20.360 + vfb->sdl = 0; 20.361 + vfb->opengl = 0; 20.362 +} 20.363 + 20.364 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) 20.365 { 20.366 libxl__gc gc = LIBXL_INIT_GC(ctx);
21.1 --- a/tools/libxl/libxl.h Tue Jan 11 19:31:41 2011 +0000 21.2 +++ b/tools/libxl/libxl.h Tue Jan 11 19:41:53 2011 +0000 21.3 @@ -241,6 +241,38 @@ enum { 21.4 21.5 #define LIBXL_VERSION 0 21.6 21.7 +enum libxl_action_on_shutdown { 21.8 + LIBXL_ACTION_DESTROY, 21.9 + 21.10 + LIBXL_ACTION_RESTART, 21.11 + LIBXL_ACTION_RESTART_RENAME, 21.12 + 21.13 + LIBXL_ACTION_PRESERVE, 21.14 + 21.15 + LIBXL_ACTION_COREDUMP_DESTROY, 21.16 + LIBXL_ACTION_COREDUMP_RESTART, 21.17 +}; 21.18 + 21.19 +typedef struct { 21.20 + libxl_domain_create_info c_info; 21.21 + libxl_domain_build_info b_info; 21.22 + libxl_device_model_info dm_info; 21.23 + 21.24 + int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs; 21.25 + 21.26 + libxl_device_disk *disks; 21.27 + libxl_device_nic *vifs; 21.28 + libxl_device_net2 *vif2s; 21.29 + libxl_device_pci *pcidevs; 21.30 + libxl_device_vfb *vfbs; 21.31 + libxl_device_vkb *vkbs; 21.32 + 21.33 + enum libxl_action_on_shutdown on_poweroff; 21.34 + enum libxl_action_on_shutdown on_reboot; 21.35 + enum libxl_action_on_shutdown on_watchdog; 21.36 + enum libxl_action_on_shutdown on_crash; 21.37 +} libxl_domain_config; 21.38 + 21.39 /* context functions */ 21.40 int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*); 21.41 int libxl_ctx_free(libxl_ctx *ctx); 21.42 @@ -248,11 +280,13 @@ int libxl_ctx_set_log(libxl_ctx *ctx, xe 21.43 int libxl_ctx_postfork(libxl_ctx *ctx); 21.44 21.45 /* domain related functions */ 21.46 -int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid); 21.47 -int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state); 21.48 -int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, 21.49 - uint32_t domid, int fd, libxl_domain_build_state *state, 21.50 - libxl_device_model_info *dm_info); 21.51 +void libxl_init_create_info(libxl_domain_create_info *c_info); 21.52 +void libxl_init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info); 21.53 +void libxl_init_dm_info(libxl_device_model_info *dm_info, libxl_domain_create_info *c_info, libxl_domain_build_info *b_info); 21.54 +typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv); 21.55 +int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid); 21.56 +int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd); 21.57 +void libxl_domain_config_destroy(libxl_domain_config *d_config); 21.58 int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, 21.59 uint32_t domid, int fd); 21.60 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid); 21.61 @@ -375,27 +409,6 @@ libxl_dominfo * libxl_list_domain(libxl_ 21.62 libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool); 21.63 libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm); 21.64 21.65 -typedef struct libxl__device_model_starting libxl_device_model_starting; 21.66 -int libxl_create_device_model(libxl_ctx *ctx, 21.67 - libxl_device_model_info *info, 21.68 - libxl_device_disk *disk, int num_disks, 21.69 - libxl_device_nic *vifs, int num_vifs, 21.70 - libxl_device_model_starting **starting_r); 21.71 -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, 21.72 - libxl_device_model_starting **starting_r); 21.73 -int libxl_need_xenpv_qemu(libxl_ctx *ctx, 21.74 - int nr_consoles, libxl_device_console *consoles, 21.75 - int nr_vfbs, libxl_device_vfb *vfbs, 21.76 - int nr_disks, libxl_device_disk *disks); 21.77 - /* Caller must either: pass starting_r==0, or on successful 21.78 - * return pass *starting_r (which will be non-0) to 21.79 - * libxl_confirm_device_model or libxl_detach_device_model. */ 21.80 -int libxl_confirm_device_model_startup(libxl_ctx *ctx, 21.81 - libxl_device_model_starting *starting); 21.82 -int libxl_detach_device_model(libxl_ctx *ctx, 21.83 - libxl_device_model_starting *starting); 21.84 - /* DM is detached even if error is returned */ 21.85 - 21.86 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk); 21.87 int libxl_device_disk_del(libxl_ctx *ctx, libxl_device_disk *disk, int wait); 21.88 libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num); 21.89 @@ -409,16 +422,19 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u 21.90 char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); 21.91 int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk); 21.92 21.93 +int libxl_device_nic_init(libxl_device_nic *nic, int dev_num); 21.94 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic); 21.95 int libxl_device_nic_del(libxl_ctx *ctx, libxl_device_nic *nic, int wait); 21.96 libxl_nicinfo *libxl_list_nics(libxl_ctx *ctx, uint32_t domid, unsigned int *nb); 21.97 21.98 int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, libxl_device_console *console); 21.99 21.100 +void libxl_device_vkb_init(libxl_device_vkb *vkb, int dev_num); 21.101 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb); 21.102 int libxl_device_vkb_clean_shutdown(libxl_ctx *ctx, uint32_t domid); 21.103 int libxl_device_vkb_hard_shutdown(libxl_ctx *ctx, uint32_t domid); 21.104 21.105 +void libxl_device_vfb_init(libxl_device_vfb *vfb, int dev_num); 21.106 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb); 21.107 int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid); 21.108 int libxl_device_vfb_hard_shutdown(libxl_ctx *ctx, uint32_t domid); 21.109 @@ -516,6 +532,7 @@ int libxl_tmem_shared_auth(libxl_ctx *ct 21.110 int auth); 21.111 int libxl_tmem_freeable(libxl_ctx *ctx); 21.112 21.113 +void libxl_device_net2_init(libxl_device_net2 *net2, int dev_num); 21.114 int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, 21.115 libxl_device_net2 *net2); 21.116 libxl_net2info *libxl_device_net2_list(libxl_ctx *ctx, uint32_t domid,
22.1 --- a/tools/libxl/libxl.idl Tue Jan 11 19:31:41 2011 +0000 22.2 +++ b/tools/libxl/libxl.idl Tue Jan 11 19:41:53 2011 +0000 22.3 @@ -152,6 +152,7 @@ libxl_device_model_info = Struct("device 22.4 ("sdl", bool, False, "sdl enabled or disabled"), 22.5 ("opengl", bool, False, "opengl enabled or disabled (if enabled requires sdl enabled)"), 22.6 ("nographic", bool, False, "no graphics, use serial port"), 22.7 + ("gfx_passthru", bool, False, "disable qemu graphics for PCI passthru of GPU from host"), 22.8 ("serial", string, False, "serial port re-direct to pty deivce"), 22.9 ("boot", string, False, "boot order, for example dca"), 22.10 ("usb", bool, False, "usb support enabled or disabled"),
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/tools/libxl/libxl_create.c Tue Jan 11 19:41:53 2011 +0000 23.3 @@ -0,0 +1,551 @@ 23.4 +/* 23.5 + * Copyright (C) 2010 Citrix Ltd. 23.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> 23.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> 23.8 + * Author Gianni Tedesco <gianni.tedesco@citrix.com> 23.9 + * 23.10 + * This program is free software; you can redistribute it and/or modify 23.11 + * it under the terms of the GNU Lesser General Public License as published 23.12 + * by the Free Software Foundation; version 2.1 only. with the special 23.13 + * exception on linking described in file LICENSE. 23.14 + * 23.15 + * This program is distributed in the hope that it will be useful, 23.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 23.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.18 + * GNU Lesser General Public License for more details. 23.19 + */ 23.20 + 23.21 +#include "libxl_osdeps.h" 23.22 + 23.23 +#include <stdio.h> 23.24 +#include <string.h> 23.25 +#include <stdlib.h> 23.26 +#include <unistd.h> 23.27 +#include <fcntl.h> 23.28 +#include "libxl.h" 23.29 +#include "libxl_utils.h" 23.30 +#include "libxl_internal.h" 23.31 +#include "flexarray.h" 23.32 + 23.33 +void libxl_domain_config_destroy(libxl_domain_config *d_config) 23.34 +{ 23.35 + int i; 23.36 + 23.37 + for (i=0; i<d_config->num_disks; i++) 23.38 + libxl_device_disk_destroy(&d_config->disks[i]); 23.39 + free(d_config->disks); 23.40 + 23.41 + for (i=0; i<d_config->num_vifs; i++) 23.42 + libxl_device_nic_destroy(&d_config->vifs[i]); 23.43 + free(d_config->vifs); 23.44 + 23.45 + for (i=0; i<d_config->num_vif2s; i++) 23.46 + libxl_device_net2_destroy(&d_config->vif2s[i]); 23.47 + free(d_config->vif2s); 23.48 + 23.49 + for (i=0; i<d_config->num_pcidevs; i++) 23.50 + libxl_device_pci_destroy(&d_config->pcidevs[i]); 23.51 + free(d_config->pcidevs); 23.52 + 23.53 + for (i=0; i<d_config->num_vfbs; i++) 23.54 + libxl_device_vfb_destroy(&d_config->vfbs[i]); 23.55 + free(d_config->vfbs); 23.56 + 23.57 + for (i=0; i<d_config->num_vkbs; i++) 23.58 + libxl_device_vkb_destroy(&d_config->vkbs[i]); 23.59 + free(d_config->vkbs); 23.60 + 23.61 + libxl_domain_create_info_destroy(&d_config->c_info); 23.62 + libxl_domain_build_info_destroy(&d_config->b_info); 23.63 + libxl_device_model_info_destroy(&d_config->dm_info); 23.64 +} 23.65 + 23.66 +void libxl_init_create_info(libxl_domain_create_info *c_info) 23.67 +{ 23.68 + memset(c_info, '\0', sizeof(*c_info)); 23.69 + c_info->xsdata = NULL; 23.70 + c_info->platformdata = NULL; 23.71 + c_info->hap = 1; 23.72 + c_info->hvm = 1; 23.73 + c_info->oos = 1; 23.74 + c_info->ssidref = 0; 23.75 + c_info->poolid = 0; 23.76 +} 23.77 + 23.78 +void libxl_init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info) 23.79 +{ 23.80 + memset(b_info, '\0', sizeof(*b_info)); 23.81 + b_info->max_vcpus = 1; 23.82 + b_info->max_memkb = 32 * 1024; 23.83 + b_info->target_memkb = b_info->max_memkb; 23.84 + b_info->disable_migrate = 0; 23.85 + b_info->cpuid = NULL; 23.86 + b_info->shadow_memkb = 0; 23.87 + if (c_info->hvm) { 23.88 + b_info->video_memkb = 8 * 1024; 23.89 + b_info->kernel.path = strdup("hvmloader"); 23.90 + b_info->hvm = 1; 23.91 + b_info->u.hvm.pae = 1; 23.92 + b_info->u.hvm.apic = 1; 23.93 + b_info->u.hvm.acpi = 1; 23.94 + b_info->u.hvm.nx = 1; 23.95 + b_info->u.hvm.viridian = 0; 23.96 + b_info->u.hvm.hpet = 1; 23.97 + b_info->u.hvm.vpt_align = 1; 23.98 + b_info->u.hvm.timer_mode = 1; 23.99 + } else { 23.100 + b_info->u.pv.slack_memkb = 8 * 1024; 23.101 + } 23.102 +} 23.103 + 23.104 +void libxl_init_dm_info(libxl_device_model_info *dm_info, 23.105 + libxl_domain_create_info *c_info, libxl_domain_build_info *b_info) 23.106 +{ 23.107 + memset(dm_info, '\0', sizeof(*dm_info)); 23.108 + 23.109 + libxl_uuid_generate(&dm_info->uuid); 23.110 + 23.111 + dm_info->dom_name = strdup(c_info->name); 23.112 + dm_info->device_model = strdup("qemu-dm"); 23.113 + dm_info->target_ram = libxl__sizekb_to_mb(b_info->target_memkb); 23.114 + dm_info->videoram = libxl__sizekb_to_mb(b_info->video_memkb); 23.115 + dm_info->apic = b_info->u.hvm.apic; 23.116 + dm_info->vcpus = b_info->max_vcpus; 23.117 + dm_info->vcpu_avail = b_info->cur_vcpus; 23.118 + 23.119 + dm_info->stdvga = 0; 23.120 + dm_info->vnc = 1; 23.121 + dm_info->vnclisten = strdup("127.0.0.1"); 23.122 + dm_info->vncdisplay = 0; 23.123 + dm_info->vncunused = 1; 23.124 + dm_info->keymap = NULL; 23.125 + dm_info->sdl = 0; 23.126 + dm_info->opengl = 0; 23.127 + dm_info->nographic = 0; 23.128 + dm_info->serial = NULL; 23.129 + dm_info->boot = strdup("cda"); 23.130 + dm_info->usb = 0; 23.131 + dm_info->usbdevice = NULL; 23.132 + dm_info->xen_platform_pci = 1; 23.133 +} 23.134 + 23.135 +static int init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state) 23.136 +{ 23.137 + memset(console, 0x00, sizeof(libxl_device_console)); 23.138 + console->devid = dev_num; 23.139 + console->consback = LIBXL_CONSBACK_XENCONSOLED; 23.140 + console->output = strdup("pty"); 23.141 + if ( NULL == console->output ) 23.142 + return ERROR_NOMEM; 23.143 + if (state) 23.144 + console->build_state = state; 23.145 + return 0; 23.146 +} 23.147 + 23.148 +int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) 23.149 +{ 23.150 + libxl__gc gc = LIBXL_INIT_GC(ctx); 23.151 + char **vments = NULL, **localents = NULL; 23.152 + struct timeval start_time; 23.153 + int i, ret; 23.154 + 23.155 + ret = libxl__build_pre(ctx, domid, info, state); 23.156 + if (ret) 23.157 + goto out; 23.158 + 23.159 + gettimeofday(&start_time, NULL); 23.160 + 23.161 + if (info->hvm) { 23.162 + ret = libxl__build_hvm(ctx, domid, info, state); 23.163 + if (ret) 23.164 + goto out; 23.165 + 23.166 + vments = libxl__calloc(&gc, 7, sizeof(char *)); 23.167 + vments[0] = "rtc/timeoffset"; 23.168 + vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; 23.169 + vments[2] = "image/ostype"; 23.170 + vments[3] = "hvm"; 23.171 + vments[4] = "start_time"; 23.172 + vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 23.173 + } else { 23.174 + ret = libxl__build_pv(ctx, domid, info, state); 23.175 + if (ret) 23.176 + goto out; 23.177 + 23.178 + vments = libxl__calloc(&gc, 11, sizeof(char *)); 23.179 + i = 0; 23.180 + vments[i++] = "image/ostype"; 23.181 + vments[i++] = "linux"; 23.182 + vments[i++] = "image/kernel"; 23.183 + vments[i++] = (char*) info->kernel.path; 23.184 + vments[i++] = "start_time"; 23.185 + vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 23.186 + if (info->u.pv.ramdisk.path) { 23.187 + vments[i++] = "image/ramdisk"; 23.188 + vments[i++] = (char*) info->u.pv.ramdisk.path; 23.189 + } 23.190 + if (info->u.pv.cmdline) { 23.191 + vments[i++] = "image/cmdline"; 23.192 + vments[i++] = (char*) info->u.pv.cmdline; 23.193 + } 23.194 + } 23.195 + ret = libxl__build_post(ctx, domid, info, state, vments, localents); 23.196 +out: 23.197 + libxl__file_reference_unmap(&info->kernel); 23.198 + if (!info->hvm) 23.199 + libxl__file_reference_unmap(&info->u.pv.ramdisk); 23.200 + 23.201 + libxl__free_all(&gc); 23.202 + return ret; 23.203 +} 23.204 + 23.205 +static int domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, 23.206 + uint32_t domid, int fd, libxl_domain_build_state *state, 23.207 + libxl_device_model_info *dm_info) 23.208 +{ 23.209 + libxl__gc gc = LIBXL_INIT_GC(ctx); 23.210 + char **vments = NULL, **localents = NULL; 23.211 + struct timeval start_time; 23.212 + int i, ret, esave, flags; 23.213 + 23.214 + ret = libxl__build_pre(ctx, domid, info, state); 23.215 + if (ret) 23.216 + goto out; 23.217 + 23.218 + ret = libxl__domain_restore_common(ctx, domid, info, state, fd); 23.219 + if (ret) 23.220 + goto out; 23.221 + 23.222 + gettimeofday(&start_time, NULL); 23.223 + 23.224 + if (info->hvm) { 23.225 + vments = libxl__calloc(&gc, 7, sizeof(char *)); 23.226 + vments[0] = "rtc/timeoffset"; 23.227 + vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; 23.228 + vments[2] = "image/ostype"; 23.229 + vments[3] = "hvm"; 23.230 + vments[4] = "start_time"; 23.231 + vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 23.232 + } else { 23.233 + vments = libxl__calloc(&gc, 11, sizeof(char *)); 23.234 + i = 0; 23.235 + vments[i++] = "image/ostype"; 23.236 + vments[i++] = "linux"; 23.237 + vments[i++] = "image/kernel"; 23.238 + vments[i++] = (char*) info->kernel.path; 23.239 + vments[i++] = "start_time"; 23.240 + vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); 23.241 + if (info->u.pv.ramdisk.path) { 23.242 + vments[i++] = "image/ramdisk"; 23.243 + vments[i++] = (char*) info->u.pv.ramdisk.path; 23.244 + } 23.245 + if (info->u.pv.cmdline) { 23.246 + vments[i++] = "image/cmdline"; 23.247 + vments[i++] = (char*) info->u.pv.cmdline; 23.248 + } 23.249 + } 23.250 + ret = libxl__build_post(ctx, domid, info, state, vments, localents); 23.251 + if (ret) 23.252 + goto out; 23.253 + 23.254 + dm_info->saved_state = NULL; 23.255 + if (info->hvm) { 23.256 + ret = asprintf(&dm_info->saved_state, 23.257 + "/var/lib/xen/qemu-save.%d", domid); 23.258 + ret = (ret < 0) ? ERROR_FAIL : 0; 23.259 + } 23.260 + 23.261 +out: 23.262 + libxl__file_reference_unmap(&info->kernel); 23.263 + if (!info->hvm) 23.264 + libxl__file_reference_unmap(&info->u.pv.ramdisk); 23.265 + 23.266 + esave = errno; 23.267 + 23.268 + flags = fcntl(fd, F_GETFL); 23.269 + if (flags == -1) { 23.270 + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd"); 23.271 + } else { 23.272 + flags &= ~O_NONBLOCK; 23.273 + if (fcntl(fd, F_SETFL, flags) == -1) 23.274 + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd" 23.275 + " back to blocking mode"); 23.276 + } 23.277 + 23.278 + errno = esave; 23.279 + libxl__free_all(&gc); 23.280 + return ret; 23.281 +} 23.282 + 23.283 +int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, 23.284 + uint32_t *domid) 23.285 +{ 23.286 + libxl__gc gc = LIBXL_INIT_GC(ctx); 23.287 + int flags, ret, i, rc; 23.288 + char *uuid_string; 23.289 + char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; 23.290 + char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", 23.291 + "control", "attr", "messages" }; 23.292 + char *dom_path, *vm_path; 23.293 + struct xs_permissions roperm[2]; 23.294 + struct xs_permissions rwperm[1]; 23.295 + xs_transaction_t t; 23.296 + xen_domain_handle_t handle; 23.297 + 23.298 + uuid_string = libxl__uuid2string(&gc, info->uuid); 23.299 + if (!uuid_string) { 23.300 + libxl__free_all(&gc); 23.301 + return ERROR_NOMEM; 23.302 + } 23.303 + 23.304 + flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; 23.305 + flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; 23.306 + flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off; 23.307 + *domid = -1; 23.308 + 23.309 + /* Ultimately, handle is an array of 16 uint8_t, same as uuid */ 23.310 + libxl_uuid_copy((libxl_uuid *)handle, &info->uuid); 23.311 + 23.312 + ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); 23.313 + if (ret < 0) { 23.314 + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail"); 23.315 + libxl__free_all(&gc); 23.316 + return ERROR_FAIL; 23.317 + } 23.318 + 23.319 + ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); 23.320 + if (ret < 0) { 23.321 + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail"); 23.322 + libxl__free_all(&gc); 23.323 + return ERROR_FAIL; 23.324 + } 23.325 + 23.326 + dom_path = libxl__xs_get_dompath(&gc, *domid); 23.327 + if (!dom_path) { 23.328 + libxl__free_all(&gc); 23.329 + return ERROR_FAIL; 23.330 + } 23.331 + 23.332 + vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string); 23.333 + if (!vm_path) { 23.334 + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths"); 23.335 + libxl__free_all(&gc); 23.336 + return ERROR_FAIL; 23.337 + } 23.338 + 23.339 + roperm[0].id = 0; 23.340 + roperm[0].perms = XS_PERM_NONE; 23.341 + roperm[1].id = *domid; 23.342 + roperm[1].perms = XS_PERM_READ; 23.343 + rwperm[0].id = *domid; 23.344 + rwperm[0].perms = XS_PERM_NONE; 23.345 + 23.346 +retry_transaction: 23.347 + t = xs_transaction_start(ctx->xsh); 23.348 + xs_rm(ctx->xsh, t, dom_path); 23.349 + xs_mkdir(ctx->xsh, t, dom_path); 23.350 + xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); 23.351 + 23.352 + xs_rm(ctx->xsh, t, vm_path); 23.353 + xs_mkdir(ctx->xsh, t, vm_path); 23.354 + xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); 23.355 + 23.356 + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); 23.357 + rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); 23.358 + if (rc) { 23.359 + libxl__free_all(&gc); 23.360 + return rc; 23.361 + } 23.362 + 23.363 + for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { 23.364 + char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); 23.365 + xs_mkdir(ctx->xsh, t, path); 23.366 + xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); 23.367 + } 23.368 + for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { 23.369 + char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); 23.370 + xs_mkdir(ctx->xsh, t, path); 23.371 + xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); 23.372 + } 23.373 + 23.374 + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); 23.375 + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); 23.376 + if (info->poolname) 23.377 + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); 23.378 + 23.379 + libxl__xs_writev(&gc, t, dom_path, info->xsdata); 23.380 + libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata); 23.381 + 23.382 + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); 23.383 + if (!xs_transaction_end(ctx->xsh, t, 0)) 23.384 + if (errno == EAGAIN) 23.385 + goto retry_transaction; 23.386 + 23.387 + libxl__free_all(&gc); 23.388 + return 0; 23.389 +} 23.390 + 23.391 +static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config, 23.392 + libxl_console_ready cb, void *priv, 23.393 + uint32_t *domid_out, int restore_fd) 23.394 +{ 23.395 + libxl__device_model_starting *dm_starting = 0; 23.396 + libxl_device_model_info *dm_info = &d_config->dm_info; 23.397 + libxl_domain_build_state state; 23.398 + uint32_t domid; 23.399 + int i, ret; 23.400 + 23.401 + domid = 0; 23.402 + 23.403 + ret = libxl__domain_make(ctx, &d_config->c_info, &domid); 23.404 + if (ret) { 23.405 + fprintf(stderr, "cannot make domain: %d\n", ret); 23.406 + ret = ERROR_FAIL; 23.407 + goto error_out; 23.408 + } 23.409 + 23.410 + if ( !d_config->c_info.hvm && cb ) { 23.411 + if ( (*cb)(ctx, domid, priv) ) 23.412 + goto error_out; 23.413 + } 23.414 + 23.415 + if ( restore_fd < 0 ) { 23.416 + ret = libxl_run_bootloader(ctx, &d_config->b_info, d_config->num_disks > 0 ? &d_config->disks[0] : NULL, domid); 23.417 + if (ret) { 23.418 + fprintf(stderr, "failed to run bootloader: %d\n", ret); 23.419 + goto error_out; 23.420 + } 23.421 + } 23.422 + 23.423 + if ( restore_fd >= 0 ) { 23.424 + ret = domain_restore(ctx, &d_config->b_info, domid, restore_fd, &state, dm_info); 23.425 + } else { 23.426 + if (dm_info->saved_state) { 23.427 + free(dm_info->saved_state); 23.428 + dm_info->saved_state = NULL; 23.429 + } 23.430 + ret = libxl__domain_build(ctx, &d_config->b_info, domid, &state); 23.431 + } 23.432 + 23.433 + if (ret) { 23.434 + fprintf(stderr, "cannot (re-)build domain: %d\n", ret); 23.435 + ret = ERROR_FAIL; 23.436 + goto error_out; 23.437 + } 23.438 + 23.439 + for (i = 0; i < d_config->num_disks; i++) { 23.440 + d_config->disks[i].domid = domid; 23.441 + ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]); 23.442 + if (ret) { 23.443 + fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret); 23.444 + ret = ERROR_FAIL; 23.445 + goto error_out; 23.446 + } 23.447 + } 23.448 + for (i = 0; i < d_config->num_vifs; i++) { 23.449 + d_config->vifs[i].domid = domid; 23.450 + ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]); 23.451 + if (ret) { 23.452 + fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret); 23.453 + ret = ERROR_FAIL; 23.454 + goto error_out; 23.455 + } 23.456 + } 23.457 + if (!d_config->c_info.hvm) { 23.458 + for (i = 0; i < d_config->num_vif2s; i++) { 23.459 + d_config->vif2s[i].domid = domid; 23.460 + ret = libxl_device_net2_add(ctx, domid, &d_config->vif2s[i]); 23.461 + if (ret) { 23.462 + fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret); 23.463 + ret = ERROR_FAIL; 23.464 + goto error_out; 23.465 + } 23.466 + } 23.467 + } 23.468 + if (d_config->c_info.hvm) { 23.469 + libxl_device_console console; 23.470 + 23.471 + ret = init_console_info(&console, 0, &state); 23.472 + if ( ret ) 23.473 + goto error_out; 23.474 + console.domid = domid; 23.475 + libxl_device_console_add(ctx, domid, &console); 23.476 + libxl_device_console_destroy(&console); 23.477 + 23.478 + dm_info->domid = domid; 23.479 + ret = libxl__create_device_model(ctx, dm_info, 23.480 + d_config->disks, d_config->num_disks, 23.481 + d_config->vifs, d_config->num_vifs, 23.482 + &dm_starting); 23.483 + if (ret < 0) { 23.484 + fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__create_device_model\n", 23.485 + __FILE__,__LINE__, ret); 23.486 + goto error_out; 23.487 + } 23.488 + } else { 23.489 + int need_qemu = 0; 23.490 + libxl_device_console console; 23.491 + 23.492 + for (i = 0; i < d_config->num_vfbs; i++) { 23.493 + d_config->vfbs[i].domid = domid; 23.494 + libxl_device_vfb_add(ctx, domid, &d_config->vfbs[i]); 23.495 + d_config->vkbs[i].domid = domid; 23.496 + libxl_device_vkb_add(ctx, domid, &d_config->vkbs[i]); 23.497 + } 23.498 + 23.499 + ret = init_console_info(&console, 0, &state); 23.500 + if ( ret ) 23.501 + goto error_out; 23.502 + console.domid = domid; 23.503 + 23.504 + need_qemu = libxl__need_xenpv_qemu(ctx, 1, &console, 23.505 + d_config->num_vfbs, d_config->vfbs, 23.506 + d_config->num_disks, &d_config->disks[0]); 23.507 + 23.508 + if (need_qemu) 23.509 + console.consback = LIBXL_CONSBACK_IOEMU; 23.510 + 23.511 + libxl_device_console_add(ctx, domid, &console); 23.512 + libxl_device_console_destroy(&console); 23.513 + 23.514 + if (need_qemu) 23.515 + libxl__create_xenpv_qemu(ctx, domid, d_config->vfbs, &dm_starting); 23.516 + } 23.517 + 23.518 + if (dm_starting) { 23.519 + ret = libxl__confirm_device_model_startup(ctx, dm_starting); 23.520 + if (ret < 0) { 23.521 + fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__confirm_device_model_startup\n", 23.522 + __FILE__,__LINE__, ret); 23.523 + goto error_out; 23.524 + } 23.525 + } 23.526 + 23.527 + for (i = 0; i < d_config->num_pcidevs; i++) 23.528 + libxl_device_pci_add(ctx, domid, &d_config->pcidevs[i]); 23.529 + 23.530 + if ( d_config->c_info.hvm && cb ) { 23.531 + if ( (*cb)(ctx, domid, priv) ) 23.532 + goto error_out; 23.533 + } 23.534 + 23.535 + *domid_out = domid; 23.536 + return 0; 23.537 + 23.538 +error_out: 23.539 + if (domid) 23.540 + libxl_domain_destroy(ctx, domid, 0); 23.541 + 23.542 + return ret; 23.543 +} 23.544 +int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, 23.545 + libxl_console_ready cb, void *priv, uint32_t *domid) 23.546 +{ 23.547 + return do_domain_create(ctx, d_config, cb, priv, domid, -1); 23.548 +} 23.549 + 23.550 +int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, 23.551 + libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd) 23.552 +{ 23.553 + return do_domain_create(ctx, d_config, cb, priv, domid, restore_fd); 23.554 +}
24.1 --- a/tools/libxl/libxl_dm.c Tue Jan 11 19:31:41 2011 +0000 24.2 +++ b/tools/libxl/libxl_dm.c Tue Jan 11 19:41:53 2011 +0000 24.3 @@ -20,6 +20,7 @@ 24.4 #include <stdio.h> 24.5 #include <string.h> 24.6 #include <stdlib.h> 24.7 +#include <signal.h> 24.8 #include <unistd.h> 24.9 #include <fcntl.h> 24.10 #include "libxl_utils.h" 24.11 @@ -324,7 +325,7 @@ static char ** libxl_build_device_model_ 24.12 24.13 static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild) 24.14 { 24.15 - libxl_device_model_starting *starting = for_spawn; 24.16 + libxl__device_model_starting *starting = for_spawn; 24.17 struct xs_handle *xsh; 24.18 char *path = NULL, *pid = NULL; 24.19 int len; 24.20 @@ -426,7 +427,7 @@ static int libxl_create_stubdom(libxl_ct 24.21 libxl_device_nic *vifs, int num_vifs, 24.22 libxl_device_vfb *vfb, 24.23 libxl_device_vkb *vkb, 24.24 - libxl_device_model_starting **starting_r) 24.25 + libxl__device_model_starting **starting_r) 24.26 { 24.27 libxl__gc gc = LIBXL_INIT_GC(ctx); 24.28 int i, num_console = 1, ret; 24.29 @@ -438,7 +439,7 @@ static int libxl_create_stubdom(libxl_ct 24.30 char **args; 24.31 struct xs_permissions perm[2]; 24.32 xs_transaction_t t; 24.33 - libxl_device_model_starting *dm_starting = 0; 24.34 + libxl__device_model_starting *dm_starting = 0; 24.35 24.36 args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); 24.37 if (!args) { 24.38 @@ -462,10 +463,10 @@ static int libxl_create_stubdom(libxl_ct 24.39 b_info.u.pv.features = ""; 24.40 b_info.hvm = 0; 24.41 24.42 - ret = libxl_domain_make(ctx, &c_info, &domid); 24.43 + ret = libxl__domain_make(ctx, &c_info, &domid); 24.44 if (ret) 24.45 goto out_free; 24.46 - ret = libxl_domain_build(ctx, &b_info, domid, &state); 24.47 + ret = libxl__domain_build(ctx, &b_info, domid, &state); 24.48 if (ret) 24.49 goto out_free; 24.50 24.51 @@ -545,11 +546,11 @@ retry_transaction: 24.52 if (ret) 24.53 goto out_free; 24.54 } 24.55 - if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) { 24.56 + if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) { 24.57 ret = ERROR_FAIL; 24.58 goto out_free; 24.59 } 24.60 - if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { 24.61 + if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) { 24.62 ret = ERROR_FAIL; 24.63 goto out_free; 24.64 } 24.65 @@ -557,7 +558,7 @@ retry_transaction: 24.66 libxl_domain_unpause(ctx, domid); 24.67 24.68 if (starting_r) { 24.69 - *starting_r = calloc(sizeof(libxl_device_model_starting), 1); 24.70 + *starting_r = calloc(sizeof(libxl__device_model_starting), 1); 24.71 (*starting_r)->domid = info->domid; 24.72 (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid); 24.73 (*starting_r)->for_spawn = NULL; 24.74 @@ -572,18 +573,18 @@ out: 24.75 return ret; 24.76 } 24.77 24.78 -int libxl_create_device_model(libxl_ctx *ctx, 24.79 +int libxl__create_device_model(libxl_ctx *ctx, 24.80 libxl_device_model_info *info, 24.81 libxl_device_disk *disks, int num_disks, 24.82 libxl_device_nic *vifs, int num_vifs, 24.83 - libxl_device_model_starting **starting_r) 24.84 + libxl__device_model_starting **starting_r) 24.85 { 24.86 libxl__gc gc = LIBXL_INIT_GC(ctx); 24.87 char *path, *logfile; 24.88 int logfile_w, null; 24.89 int rc; 24.90 char **args; 24.91 - libxl_device_model_starting buf_starting, *p; 24.92 + libxl__device_model_starting buf_starting, *p; 24.93 xs_transaction_t t; 24.94 char *vm_path; 24.95 char **pass_stuff; 24.96 @@ -614,7 +615,7 @@ int libxl_create_device_model(libxl_ctx 24.97 24.98 if (starting_r) { 24.99 rc = ERROR_NOMEM; 24.100 - *starting_r = calloc(sizeof(libxl_device_model_starting), 1); 24.101 + *starting_r = calloc(sizeof(libxl__device_model_starting), 1); 24.102 if (!*starting_r) 24.103 goto out_close; 24.104 p = *starting_r; 24.105 @@ -668,8 +669,8 @@ out: 24.106 return rc; 24.107 } 24.108 24.109 -int libxl_detach_device_model(libxl_ctx *ctx, 24.110 - libxl_device_model_starting *starting) 24.111 +static int detach_device_model(libxl_ctx *ctx, 24.112 + libxl__device_model_starting *starting) 24.113 { 24.114 int rc; 24.115 rc = libxl__spawn_detach(ctx, starting->for_spawn); 24.116 @@ -680,14 +681,14 @@ int libxl_detach_device_model(libxl_ctx 24.117 } 24.118 24.119 24.120 -int libxl_confirm_device_model_startup(libxl_ctx *ctx, 24.121 - libxl_device_model_starting *starting) 24.122 +int libxl__confirm_device_model_startup(libxl_ctx *ctx, 24.123 + libxl__device_model_starting *starting) 24.124 { 24.125 int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL); 24.126 int detach; 24.127 if ( !problem ) 24.128 problem = libxl__spawn_check(ctx, starting->for_spawn); 24.129 - detach = libxl_detach_device_model(ctx, starting); 24.130 + detach = detach_device_model(ctx, starting); 24.131 return problem ? problem : detach; 24.132 } 24.133 24.134 @@ -760,7 +761,7 @@ static int libxl_build_xenpv_qemu_args(l 24.135 return 0; 24.136 } 24.137 24.138 -int libxl_need_xenpv_qemu(libxl_ctx *ctx, 24.139 +int libxl__need_xenpv_qemu(libxl_ctx *ctx, 24.140 int nr_consoles, libxl_device_console *consoles, 24.141 int nr_vfbs, libxl_device_vfb *vfbs, 24.142 int nr_disks, libxl_device_disk *disks) 24.143 @@ -793,14 +794,14 @@ out: 24.144 return ret; 24.145 } 24.146 24.147 -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, 24.148 - libxl_device_model_starting **starting_r) 24.149 +int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, 24.150 + libxl__device_model_starting **starting_r) 24.151 { 24.152 libxl__gc gc = LIBXL_INIT_GC(ctx); 24.153 libxl_device_model_info info; 24.154 24.155 libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info); 24.156 - libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); 24.157 + libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); 24.158 libxl__free_all(&gc); 24.159 return 0; 24.160 }
25.1 --- a/tools/libxl/libxl_exec.c Tue Jan 11 19:31:41 2011 +0000 25.2 +++ b/tools/libxl/libxl_exec.c Tue Jan 11 19:41:53 2011 +0000 25.3 @@ -90,7 +90,7 @@ void libxl_report_child_exitstatus(libxl 25.4 } 25.5 25.6 int libxl__spawn_spawn(libxl_ctx *ctx, 25.7 - libxl_device_model_starting *starting, 25.8 + libxl__device_model_starting *starting, 25.9 const char *what, 25.10 void (*intermediate_hook)(void *for_spawn, 25.11 pid_t innerchild))
26.1 --- a/tools/libxl/libxl_internal.h Tue Jan 11 19:31:41 2011 +0000 26.2 +++ b/tools/libxl/libxl_internal.h Tue Jan 11 19:41:53 2011 +0000 26.3 @@ -194,14 +194,37 @@ typedef struct { 26.4 char *what; /* malloc'd in spawn_spawn */ 26.5 } libxl__spawn_starting; 26.6 26.7 -struct libxl__device_model_starting { 26.8 +typedef struct { 26.9 libxl__spawn_starting *for_spawn; /* first! */ 26.10 char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */ 26.11 int domid; 26.12 -}; 26.13 +} libxl__device_model_starting; 26.14 + 26.15 +/* from xl_create */ 26.16 +_hidden int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid); 26.17 +_hidden int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state); 26.18 + 26.19 +/* for device model creation */ 26.20 +_hidden int libxl__create_device_model(libxl_ctx *ctx, 26.21 + libxl_device_model_info *info, 26.22 + libxl_device_disk *disk, int num_disks, 26.23 + libxl_device_nic *vifs, int num_vifs, 26.24 + libxl__device_model_starting **starting_r); 26.25 +_hidden int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, 26.26 + libxl__device_model_starting **starting_r); 26.27 +_hidden int libxl__need_xenpv_qemu(libxl_ctx *ctx, 26.28 + int nr_consoles, libxl_device_console *consoles, 26.29 + int nr_vfbs, libxl_device_vfb *vfbs, 26.30 + int nr_disks, libxl_device_disk *disks); 26.31 + 26.32 + /* Caller must either: pass starting_r==0, or on successful 26.33 + * return pass *starting_r (which will be non-0) to 26.34 + * libxl_confirm_device_model or libxl_detach_device_model. */ 26.35 +_hidden int libxl__confirm_device_model_startup(libxl_ctx *ctx, 26.36 + libxl__device_model_starting *starting); 26.37 26.38 _hidden int libxl__spawn_spawn(libxl_ctx *ctx, 26.39 - libxl_device_model_starting *starting, 26.40 + libxl__device_model_starting *starting, 26.41 const char *what, 26.42 void (*intermediate_hook)(void *for_spawn, pid_t innerchild)); 26.43 _hidden int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid);
27.1 --- a/tools/libxl/libxl_pci.c Tue Jan 11 19:31:41 2011 +0000 27.2 +++ b/tools/libxl/libxl_pci.c Tue Jan 11 19:41:53 2011 +0000 27.3 @@ -221,20 +221,35 @@ parse_error: 27.4 return ERROR_INVAL; 27.5 } 27.6 27.7 +static void libxl_create_pci_backend_device(libxl__gc *gc, flexarray_t *back, int num, libxl_device_pci *pcidev) 27.8 +{ 27.9 + flexarray_append(back, libxl__sprintf(gc, "key-%d", num)); 27.10 + flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); 27.11 + flexarray_append(back, libxl__sprintf(gc, "dev-%d", num)); 27.12 + flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); 27.13 + if (pcidev->vdevfn) 27.14 + flexarray_vappend(back, libxl__sprintf(gc, "vdevfn-%d", num), libxl__sprintf(gc, "%x", pcidev->vdevfn), NULL); 27.15 + flexarray_append(back, libxl__sprintf(gc, "opts-%d", num)); 27.16 + flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); 27.17 + flexarray_vappend(back, libxl__sprintf(gc, "state-%d", num), libxl__sprintf(gc, "%d", 1), NULL); 27.18 +} 27.19 + 27.20 static int libxl_create_pci_backend(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int num) 27.21 { 27.22 libxl_ctx *ctx = libxl__gc_owner(gc); 27.23 - flexarray_t *front; 27.24 - flexarray_t *back; 27.25 + flexarray_t *front = NULL; 27.26 + flexarray_t *back = NULL; 27.27 libxl__device device; 27.28 - int i; 27.29 + int ret = ERROR_NOMEM, i; 27.30 27.31 front = flexarray_make(16, 1); 27.32 if (!front) 27.33 - return ERROR_NOMEM; 27.34 + goto out; 27.35 back = flexarray_make(16, 1); 27.36 if (!back) 27.37 - return ERROR_NOMEM; 27.38 + goto out; 27.39 + 27.40 + ret = 0; 27.41 27.42 LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Creating pci backend"); 27.43 27.44 @@ -247,30 +262,27 @@ static int libxl_create_pci_backend(libx 27.45 device.kind = DEVICE_PCI; 27.46 27.47 flexarray_vappend(back, "frontend-id", libxl__sprintf(gc, "%d", domid), 27.48 - "online", "1", "state", libxl__sprintf(gc, "%d", 1), 27.49 - "domain", libxl__domid_to_name(gc, domid), NULL); 27.50 - for (i = 0; i < num; i++) { 27.51 - flexarray_append(back, libxl__sprintf(gc, "key-%d", i)); 27.52 - flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); 27.53 - flexarray_append(back, libxl__sprintf(gc, "dev-%d", i)); 27.54 - flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); 27.55 - if (pcidev->vdevfn) { 27.56 - flexarray_vappend(back, libxl__sprintf(gc, "vdevfn-%d", i), libxl__sprintf(gc, "%x", pcidev->vdevfn), NULL); 27.57 - } 27.58 - flexarray_append(back, libxl__sprintf(gc, "opts-%d", i)); 27.59 - flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); 27.60 - flexarray_vappend(back, libxl__sprintf(gc, "state-%d", i), libxl__sprintf(gc, "%d", 1), NULL); 27.61 - } 27.62 - flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num), 27.63 - "backend-id", libxl__sprintf(gc, "%d", 0), 27.64 - "state", libxl__sprintf(gc, "%d", 1), NULL); 27.65 + "online", "1", "state", libxl__sprintf(gc, "%d", 1), 27.66 + "domain", libxl__domid_to_name(gc, domid), NULL); 27.67 + 27.68 + for (i = 0; i < num; i++, pcidev++) 27.69 + libxl_create_pci_backend_device(gc, back, i, pcidev); 27.70 + 27.71 + flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num)); 27.72 + 27.73 + flexarray_vappend(front, 27.74 + "backend-id", libxl__sprintf(gc, "%d", 0), 27.75 + "state", libxl__sprintf(gc, "%d", 1), NULL); 27.76 27.77 libxl__device_generic_add(ctx, &device, 27.78 libxl__xs_kvs_of_flexarray(gc, back, back->count), 27.79 libxl__xs_kvs_of_flexarray(gc, front, front->count)); 27.80 27.81 - flexarray_free(back); 27.82 - flexarray_free(front); 27.83 +out: 27.84 + if (back) 27.85 + flexarray_free(back); 27.86 + if (front) 27.87 + flexarray_free(front); 27.88 return 0; 27.89 } 27.90 27.91 @@ -298,17 +310,7 @@ static int libxl_device_pci_add_xenstore 27.92 27.93 LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Adding new pci device to xenstore"); 27.94 num = atoi(num_devs); 27.95 - flexarray_append(back, libxl__sprintf(gc, "key-%d", num)); 27.96 - flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); 27.97 - flexarray_append(back, libxl__sprintf(gc, "dev-%d", num)); 27.98 - flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); 27.99 - if (pcidev->vdevfn) { 27.100 - flexarray_append(back, libxl__sprintf(gc, "vdevfn-%d", num)); 27.101 - flexarray_append(back, libxl__sprintf(gc, "%x", pcidev->vdevfn)); 27.102 - } 27.103 - flexarray_append(back, libxl__sprintf(gc, "opts-%d", num)); 27.104 - flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); 27.105 - flexarray_vappend(back, libxl__sprintf(gc, "state-%d", num), libxl__sprintf(gc, "%d", 1), NULL); 27.106 + libxl_create_pci_backend_device(gc, back, num, pcidev); 27.107 flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num + 1), NULL); 27.108 flexarray_vappend(back, "state", libxl__sprintf(gc, "%d", 7), NULL); 27.109 27.110 @@ -749,7 +751,7 @@ static int libxl_device_pci_reset(libxl_ 27.111 return rc < 0 ? rc : 0; 27.112 } 27.113 if (errno == ENOENT) { 27.114 - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "The kernel doesn't support PCI device reset from sysfs"); 27.115 + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "The kernel doesn't support reset from sysfs for PCI device "PCI_BDF, domain, bus, dev, func); 27.116 } else { 27.117 LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Failed to access reset path %s", reset); 27.118 }
28.1 --- a/tools/libxl/xl_cmdimpl.c Tue Jan 11 19:31:41 2011 +0000 28.2 +++ b/tools/libxl/xl_cmdimpl.c Tue Jan 11 19:41:53 2011 +0000 28.3 @@ -100,81 +100,18 @@ struct save_file_header { 28.4 }; 28.5 28.6 28.7 -enum action_on_shutdown { 28.8 - ACTION_DESTROY, 28.9 - 28.10 - ACTION_RESTART, 28.11 - ACTION_RESTART_RENAME, 28.12 - 28.13 - ACTION_PRESERVE, 28.14 - 28.15 - ACTION_COREDUMP_DESTROY, 28.16 - ACTION_COREDUMP_RESTART, 28.17 -}; 28.18 - 28.19 static const char *action_on_shutdown_names[] = { 28.20 - [ACTION_DESTROY] = "destroy", 28.21 - 28.22 - [ACTION_RESTART] = "restart", 28.23 - [ACTION_RESTART_RENAME] = "rename-restart", 28.24 - 28.25 - [ACTION_PRESERVE] = "preserve", 28.26 - 28.27 - [ACTION_COREDUMP_DESTROY] = "coredump-destroy", 28.28 - [ACTION_COREDUMP_RESTART] = "coredump-restart", 28.29 + [LIBXL_ACTION_DESTROY] = "destroy", 28.30 + 28.31 + [LIBXL_ACTION_RESTART] = "restart", 28.32 + [LIBXL_ACTION_RESTART_RENAME] = "rename-restart", 28.33 + 28.34 + [LIBXL_ACTION_PRESERVE] = "preserve", 28.35 + 28.36 + [LIBXL_ACTION_COREDUMP_DESTROY] = "coredump-destroy", 28.37 + [LIBXL_ACTION_COREDUMP_RESTART] = "coredump-restart", 28.38 }; 28.39 28.40 -struct domain_config { 28.41 - libxl_domain_create_info c_info; 28.42 - libxl_domain_build_info b_info; 28.43 - 28.44 - int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs; 28.45 - 28.46 - libxl_device_disk *disks; 28.47 - libxl_device_nic *vifs; 28.48 - libxl_device_net2 *vif2s; 28.49 - libxl_device_pci *pcidevs; 28.50 - libxl_device_vfb *vfbs; 28.51 - libxl_device_vkb *vkbs; 28.52 - 28.53 - enum action_on_shutdown on_poweroff; 28.54 - enum action_on_shutdown on_reboot; 28.55 - enum action_on_shutdown on_watchdog; 28.56 - enum action_on_shutdown on_crash; 28.57 -}; 28.58 - 28.59 -static void free_domain_config(struct domain_config *d_config) 28.60 -{ 28.61 - int i; 28.62 - 28.63 - for (i=0; i<d_config->num_disks; i++) 28.64 - libxl_device_disk_destroy(&d_config->disks[i]); 28.65 - free(d_config->disks); 28.66 - 28.67 - for (i=0; i<d_config->num_vifs; i++) 28.68 - libxl_device_nic_destroy(&d_config->vifs[i]); 28.69 - free(d_config->vifs); 28.70 - 28.71 - for (i=0; i<d_config->num_vif2s; i++) 28.72 - libxl_device_net2_destroy(&d_config->vif2s[i]); 28.73 - free(d_config->vif2s); 28.74 - 28.75 - for (i=0; i<d_config->num_pcidevs; i++) 28.76 - libxl_device_pci_destroy(&d_config->pcidevs[i]); 28.77 - free(d_config->pcidevs); 28.78 - 28.79 - for (i=0; i<d_config->num_vfbs; i++) 28.80 - libxl_device_vfb_destroy(&d_config->vfbs[i]); 28.81 - free(d_config->vfbs); 28.82 - 28.83 - for (i=0; i<d_config->num_vkbs; i++) 28.84 - libxl_device_vkb_destroy(&d_config->vkbs[i]); 28.85 - free(d_config->vkbs); 28.86 - 28.87 - libxl_domain_create_info_destroy(&d_config->c_info); 28.88 - libxl_domain_build_info_destroy(&d_config->b_info); 28.89 -} 28.90 - 28.91 /* Optional data, in order: 28.92 * 4 bytes uint32_t config file size 28.93 * n bytes config file in Unix text file format 28.94 @@ -312,164 +249,8 @@ static void dolog(const char *file, int 28.95 libxl_write_exactly(NULL, logfile, s, rc, NULL, NULL); 28.96 } 28.97 28.98 -static void init_create_info(libxl_domain_create_info *c_info) 28.99 -{ 28.100 - memset(c_info, '\0', sizeof(*c_info)); 28.101 - c_info->xsdata = NULL; 28.102 - c_info->platformdata = NULL; 28.103 - c_info->hap = 1; 28.104 - c_info->hvm = 1; 28.105 - c_info->oos = 1; 28.106 - c_info->ssidref = 0; 28.107 - c_info->poolid = 0; 28.108 -} 28.109 - 28.110 -static void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info) 28.111 -{ 28.112 - memset(b_info, '\0', sizeof(*b_info)); 28.113 - b_info->max_vcpus = 1; 28.114 - b_info->max_memkb = 32 * 1024; 28.115 - b_info->target_memkb = b_info->max_memkb; 28.116 - b_info->disable_migrate = 0; 28.117 - b_info->cpuid = NULL; 28.118 - b_info->shadow_memkb = 0; 28.119 - if (c_info->hvm) { 28.120 - b_info->video_memkb = 8 * 1024; 28.121 - b_info->kernel.path = strdup("hvmloader"); 28.122 - b_info->hvm = 1; 28.123 - b_info->u.hvm.pae = 1; 28.124 - b_info->u.hvm.apic = 1; 28.125 - b_info->u.hvm.acpi = 1; 28.126 - b_info->u.hvm.nx = 1; 28.127 - b_info->u.hvm.viridian = 0; 28.128 - b_info->u.hvm.hpet = 1; 28.129 - b_info->u.hvm.vpt_align = 1; 28.130 - b_info->u.hvm.timer_mode = 1; 28.131 - } else { 28.132 - b_info->u.pv.slack_memkb = 8 * 1024; 28.133 - } 28.134 -} 28.135 - 28.136 -static void init_dm_info(libxl_device_model_info *dm_info, 28.137 - libxl_domain_create_info *c_info, libxl_domain_build_info *b_info) 28.138 -{ 28.139 - memset(dm_info, '\0', sizeof(*dm_info)); 28.140 - 28.141 - libxl_uuid_generate(&dm_info->uuid); 28.142 - 28.143 - dm_info->dom_name = strdup(c_info->name); 28.144 - dm_info->device_model = strdup("qemu-dm"); 28.145 - dm_info->target_ram = libxl__sizekb_to_mb(b_info->target_memkb); 28.146 - dm_info->videoram = libxl__sizekb_to_mb(b_info->video_memkb); 28.147 - dm_info->apic = b_info->u.hvm.apic; 28.148 - dm_info->vcpus = b_info->max_vcpus; 28.149 - dm_info->vcpu_avail = b_info->cur_vcpus; 28.150 - 28.151 - dm_info->stdvga = 0; 28.152 - dm_info->vnc = 1; 28.153 - dm_info->vnclisten = strdup("127.0.0.1"); 28.154 - dm_info->vncdisplay = 0; 28.155 - dm_info->vncunused = 1; 28.156 - dm_info->keymap = NULL; 28.157 - dm_info->sdl = 0; 28.158 - dm_info->opengl = 0; 28.159 - dm_info->nographic = 0; 28.160 - dm_info->serial = NULL; 28.161 - dm_info->boot = strdup("cda"); 28.162 - dm_info->usb = 0; 28.163 - dm_info->usbdevice = NULL; 28.164 - dm_info->xen_platform_pci = 1; 28.165 -} 28.166 - 28.167 -static void init_nic_info(libxl_device_nic *nic_info, int devnum) 28.168 -{ 28.169 - const uint8_t *r; 28.170 - libxl_uuid uuid; 28.171 - 28.172 - libxl_uuid_generate(&uuid); 28.173 - r = libxl_uuid_bytearray(&uuid); 28.174 - memset(nic_info, '\0', sizeof(*nic_info)); 28.175 - 28.176 - nic_info->backend_domid = 0; 28.177 - nic_info->domid = 0; 28.178 - nic_info->devid = devnum; 28.179 - nic_info->mtu = 1492; 28.180 - nic_info->model = strdup("e1000"); 28.181 - nic_info->mac[0] = 0x00; 28.182 - nic_info->mac[1] = 0x16; 28.183 - nic_info->mac[2] = 0x3e; 28.184 - nic_info->mac[3] = r[0] & 0x7f; 28.185 - nic_info->mac[4] = r[1]; 28.186 - nic_info->mac[5] = r[2]; 28.187 - nic_info->ifname = NULL; 28.188 - nic_info->bridge = strdup("xenbr0"); 28.189 - CHK_ERRNO( asprintf(&nic_info->script, "%s/vif-bridge", 28.190 - libxl_xen_script_dir_path()) ); 28.191 - nic_info->nictype = NICTYPE_IOEMU; 28.192 -} 28.193 - 28.194 -static void init_net2_info(libxl_device_net2 *net2_info, int devnum) 28.195 -{ 28.196 - const uint8_t *r; 28.197 - libxl_uuid uuid; 28.198 - 28.199 - libxl_uuid_generate(&uuid); 28.200 - r = libxl_uuid_bytearray(&uuid); 28.201 - memset(net2_info, '\0', sizeof(*net2_info)); 28.202 - 28.203 - net2_info->devid = devnum; 28.204 - net2_info->front_mac[0] = 0x00; 28.205 - net2_info->front_mac[1] = 0x16; 28.206 - net2_info->front_mac[2] = 0x3e;; 28.207 - net2_info->front_mac[3] = 0x7f & r[0]; 28.208 - net2_info->front_mac[4] = r[1]; 28.209 - net2_info->front_mac[5] = r[2]; 28.210 - net2_info->back_mac[0] = 0x00; 28.211 - net2_info->back_mac[1] = 0x16; 28.212 - net2_info->back_mac[2] = 0x3e; 28.213 - net2_info->back_mac[3] = 0x7f & r[3]; 28.214 - net2_info->back_mac[4] = r[4]; 28.215 - net2_info->back_mac[5] = r[5]; 28.216 - net2_info->back_trusted = 1; 28.217 - net2_info->filter_mac = 1; 28.218 - net2_info->max_bypasses = 5; 28.219 - net2_info->bridge = strdup("xenbr0"); 28.220 -} 28.221 - 28.222 -static void init_vfb_info(libxl_device_vfb *vfb, int dev_num) 28.223 -{ 28.224 - memset(vfb, 0x00, sizeof(libxl_device_vfb)); 28.225 - vfb->devid = dev_num; 28.226 - vfb->display = NULL; 28.227 - vfb->xauthority = NULL; 28.228 - vfb->vnc = 1; 28.229 - vfb->vncpasswd = NULL; 28.230 - vfb->vnclisten = strdup("127.0.0.1"); 28.231 - vfb->vncdisplay = 0; 28.232 - vfb->vncunused = 1; 28.233 - vfb->keymap = NULL; 28.234 - vfb->sdl = 0; 28.235 - vfb->opengl = 0; 28.236 -} 28.237 - 28.238 -static void init_vkb_info(libxl_device_vkb *vkb, int dev_num) 28.239 -{ 28.240 - memset(vkb, 0x00, sizeof(libxl_device_vkb)); 28.241 - vkb->devid = dev_num; 28.242 -} 28.243 - 28.244 -static void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state) 28.245 -{ 28.246 - memset(console, 0x00, sizeof(libxl_device_console)); 28.247 - console->devid = dev_num; 28.248 - console->consback = LIBXL_CONSBACK_XENCONSOLED; 28.249 - console->output = strdup("pty"); 28.250 - if (state) 28.251 - console->build_state = state; 28.252 -} 28.253 - 28.254 static void printf_info(int domid, 28.255 - struct domain_config *d_config, 28.256 + libxl_domain_config *d_config, 28.257 libxl_device_model_info *dm_info) 28.258 { 28.259 int i; 28.260 @@ -543,6 +324,7 @@ static void printf_info(int domid, 28.261 printf("\t\t\t(vncunused %d)\n", dm_info->vncunused); 28.262 printf("\t\t\t(keymap %s)\n", dm_info->keymap); 28.263 printf("\t\t\t(sdl %d)\n", dm_info->sdl); 28.264 + printf("\t\t\t(gfx_passthru %d)\n", dm_info->gfx_passthru); 28.265 printf("\t\t\t(opengl %d)\n", dm_info->opengl); 28.266 printf("\t\t\t(nographic %d)\n", dm_info->nographic); 28.267 printf("\t\t\t(serial %s)\n", dm_info->serial); 28.268 @@ -626,7 +408,7 @@ static void printf_info(int domid, 28.269 printf(")\n"); 28.270 } 28.271 28.272 -static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a) 28.273 +static int parse_action_on_shutdown(const char *buf, enum libxl_action_on_shutdown *a) 28.274 { 28.275 int i; 28.276 const char *n; 28.277 @@ -773,7 +555,7 @@ out: 28.278 static void parse_config_data(const char *configfile_filename_report, 28.279 const char *configfile_data, 28.280 int configfile_len, 28.281 - struct domain_config *d_config, 28.282 + libxl_domain_config *d_config, 28.283 libxl_device_model_info *dm_info) 28.284 { 28.285 const char *buf; 28.286 @@ -799,7 +581,7 @@ static void parse_config_data(const char 28.287 exit(1); 28.288 } 28.289 28.290 - init_create_info(c_info); 28.291 + libxl_init_create_info(c_info); 28.292 28.293 c_info->hvm = 0; 28.294 if (!xlu_cfg_get_string (config, "builder", &buf) && 28.295 @@ -834,7 +616,7 @@ static void parse_config_data(const char 28.296 exit(1); 28.297 } 28.298 28.299 - init_build_info(b_info, c_info); 28.300 + libxl_init_build_info(b_info, c_info); 28.301 28.302 /* the following is the actual config parsing with overriding values in the structures */ 28.303 if (!xlu_cfg_get_long (config, "vcpus", &l)) { 28.304 @@ -977,7 +759,7 @@ static void parse_config_data(const char 28.305 28.306 d_config->vifs = (libxl_device_nic *) realloc(d_config->vifs, sizeof (libxl_device_nic) * (d_config->num_vifs+1)); 28.307 nic = d_config->vifs + d_config->num_vifs; 28.308 - init_nic_info(nic, d_config->num_vifs); 28.309 + CHK_ERRNO( libxl_device_nic_init(nic, d_config->num_vifs) ); 28.310 28.311 p = strtok(buf2, ","); 28.312 if (!p) 28.313 @@ -1054,7 +836,7 @@ skip: 28.314 d_config->vif2s = realloc(d_config->vif2s, sizeof (libxl_device_net2) * (d_config->num_vif2s + 1)); 28.315 net2 = d_config->vif2s + d_config->num_vif2s; 28.316 28.317 - init_net2_info(net2, d_config->num_vif2s); 28.318 + libxl_device_net2_init(net2, d_config->num_vif2s); 28.319 28.320 for (p = strtok(buf2, ","); p; p = strtok(NULL, ",")) { 28.321 char* val; 28.322 @@ -1106,11 +888,11 @@ skip: 28.323 28.324 d_config->vfbs = (libxl_device_vfb *) realloc(d_config->vfbs, sizeof(libxl_device_vfb) * (d_config->num_vfbs + 1)); 28.325 vfb = d_config->vfbs + d_config->num_vfbs; 28.326 - init_vfb_info(vfb, d_config->num_vfbs); 28.327 + libxl_device_vfb_init(vfb, d_config->num_vfbs); 28.328 28.329 d_config->vkbs = (libxl_device_vkb *) realloc(d_config->vkbs, sizeof(libxl_device_vkb) * (d_config->num_vkbs + 1)); 28.330 vkb = d_config->vkbs + d_config->num_vkbs; 28.331 - init_vkb_info(vkb, d_config->num_vkbs); 28.332 + libxl_device_vkb_init(vkb, d_config->num_vkbs); 28.333 28.334 p = strtok(buf2, ","); 28.335 if (!p) 28.336 @@ -1260,7 +1042,7 @@ skip_vfb: 28.337 28.338 if (c_info->hvm == 1) { 28.339 /* init dm from c and b */ 28.340 - init_dm_info(dm_info, c_info, b_info); 28.341 + libxl_init_dm_info(dm_info, c_info, b_info); 28.342 28.343 /* then process config related to dm */ 28.344 xlu_cfg_replace_string (config, "device_model", &dm_info->device_model); 28.345 @@ -1281,6 +1063,8 @@ skip_vfb: 28.346 dm_info->opengl = l; 28.347 if (!xlu_cfg_get_long (config, "nographic", &l)) 28.348 dm_info->nographic = l; 28.349 + if (!xlu_cfg_get_long (config, "gfx_passthru", &l)) 28.350 + dm_info->gfx_passthru = l; 28.351 xlu_cfg_replace_string (config, "serial", &dm_info->serial); 28.352 xlu_cfg_replace_string (config, "boot", &dm_info->boot); 28.353 if (!xlu_cfg_get_long (config, "usb", &l)) 28.354 @@ -1316,32 +1100,12 @@ static void *xrealloc(void *ptr, size_t 28.355 return r; 28.356 } 28.357 28.358 -static pid_t autoconnect_console(void) 28.359 -{ 28.360 - pid_t pid; 28.361 - 28.362 - pid = fork(); 28.363 - if (pid < 0) { 28.364 - perror("unable to fork xenconsole"); 28.365 - return ERROR_FAIL; 28.366 - } else if (pid > 0) 28.367 - return pid; 28.368 - 28.369 - libxl_ctx_postfork(&ctx); 28.370 - 28.371 - sleep(1); 28.372 - libxl_primary_console_exec(&ctx, domid); 28.373 - /* Do not return. xl continued in child process */ 28.374 - fprintf(stderr, "Unable to attach console\n"); 28.375 - _exit(1); 28.376 -} 28.377 - 28.378 /* Returns 1 if domain should be restarted, 2 if domain should be renamed then restarted */ 28.379 static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *event, 28.380 - struct domain_config *d_config, libxl_dominfo *info) 28.381 + libxl_domain_config *d_config, libxl_dominfo *info) 28.382 { 28.383 int restart = 0; 28.384 - enum action_on_shutdown action; 28.385 + enum libxl_action_on_shutdown action; 28.386 28.387 switch (info->shutdown_reason) { 28.388 case SHUTDOWN_poweroff: 28.389 @@ -1360,12 +1124,12 @@ static int handle_domain_death(libxl_ctx 28.390 break; 28.391 default: 28.392 LOG("Unknown shutdown reason code %d. Destroying domain.", info->shutdown_reason); 28.393 - action = ACTION_DESTROY; 28.394 + action = LIBXL_ACTION_DESTROY; 28.395 } 28.396 28.397 LOG("Action for shutdown reason code %d is %s", info->shutdown_reason, action_on_shutdown_names[action]); 28.398 28.399 - if (action == ACTION_COREDUMP_DESTROY || action == ACTION_COREDUMP_RESTART) { 28.400 + if (action == LIBXL_ACTION_COREDUMP_DESTROY || action == LIBXL_ACTION_COREDUMP_RESTART) { 28.401 char *corefile; 28.402 int rc; 28.403 28.404 @@ -1378,30 +1142,30 @@ static int handle_domain_death(libxl_ctx 28.405 } 28.406 /* No point crying over spilled milk, continue on failure. */ 28.407 28.408 - if (action == ACTION_COREDUMP_DESTROY) 28.409 - action = ACTION_DESTROY; 28.410 + if (action == LIBXL_ACTION_COREDUMP_DESTROY) 28.411 + action = LIBXL_ACTION_DESTROY; 28.412 else 28.413 - action = ACTION_RESTART; 28.414 + action = LIBXL_ACTION_RESTART; 28.415 } 28.416 28.417 switch (action) { 28.418 - case ACTION_PRESERVE: 28.419 + case LIBXL_ACTION_PRESERVE: 28.420 break; 28.421 28.422 - case ACTION_RESTART_RENAME: 28.423 + case LIBXL_ACTION_RESTART_RENAME: 28.424 restart = 2; 28.425 break; 28.426 28.427 - case ACTION_RESTART: 28.428 + case LIBXL_ACTION_RESTART: 28.429 restart = 1; 28.430 /* fall-through */ 28.431 - case ACTION_DESTROY: 28.432 + case LIBXL_ACTION_DESTROY: 28.433 LOG("Domain %d needs to be cleaned up: destroying the domain", domid); 28.434 libxl_domain_destroy(ctx, domid, 0); 28.435 break; 28.436 28.437 - case ACTION_COREDUMP_DESTROY: 28.438 - case ACTION_COREDUMP_RESTART: 28.439 + case LIBXL_ACTION_COREDUMP_DESTROY: 28.440 + case LIBXL_ACTION_COREDUMP_RESTART: 28.441 /* Already handled these above. */ 28.442 abort(); 28.443 } 28.444 @@ -1410,7 +1174,7 @@ static int handle_domain_death(libxl_ctx 28.445 } 28.446 28.447 static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event, 28.448 - struct domain_config *d_config, libxl_dominfo *info) 28.449 + libxl_domain_config *d_config, libxl_dominfo *info) 28.450 { 28.451 time_t now; 28.452 struct tm tm; 28.453 @@ -1501,12 +1265,29 @@ static int freemem(libxl_domain_build_in 28.454 return ERROR_NOMEM; 28.455 } 28.456 28.457 +static int autoconnect_console(libxl_ctx *ctx, uint32_t domid, void *priv) 28.458 +{ 28.459 + pid_t *pid = priv; 28.460 + 28.461 + *pid = fork(); 28.462 + if (*pid < 0) { 28.463 + perror("unable to fork xenconsole"); 28.464 + return ERROR_FAIL; 28.465 + } else if (*pid > 0) 28.466 + return 0; 28.467 + 28.468 + libxl_ctx_postfork(ctx); 28.469 + 28.470 + sleep(1); 28.471 + libxl_primary_console_exec(ctx, domid); 28.472 + /* Do not return. xl continued in child process */ 28.473 + fprintf(stderr, "Unable to attach console\n"); 28.474 + _exit(1); 28.475 +} 28.476 + 28.477 static int create_domain(struct domain_create *dom_info) 28.478 { 28.479 - struct domain_config d_config; 28.480 - 28.481 - libxl_domain_build_state state; 28.482 - libxl_device_model_info dm_info; 28.483 + libxl_domain_config d_config; 28.484 28.485 int debug = dom_info->debug; 28.486 int daemonize = dom_info->daemonize; 28.487 @@ -1516,20 +1297,19 @@ static int create_domain(struct domain_c 28.488 const char *restore_file = dom_info->restore_file; 28.489 int migrate_fd = dom_info->migrate_fd; 28.490 28.491 - int i, fd; 28.492 + int fd; 28.493 int need_daemon = 1; 28.494 int ret, rc; 28.495 - libxl_device_model_starting *dm_starting = 0; 28.496 libxl_waiter *w1 = NULL, *w2 = NULL; 28.497 void *config_data = 0; 28.498 int config_len = 0; 28.499 int restore_fd = -1; 28.500 - struct save_file_header hdr; 28.501 + int status = 0; 28.502 + libxl_console_ready cb; 28.503 pid_t child_console_pid = -1; 28.504 - int status = 0; 28.505 + struct save_file_header hdr; 28.506 28.507 memset(&d_config, 0x00, sizeof(d_config)); 28.508 - memset(&dm_info, 0x00, sizeof(dm_info)); 28.509 28.510 if (restore_file) { 28.511 uint8_t *optdata_begin = 0; 28.512 @@ -1629,7 +1409,7 @@ static int create_domain(struct domain_c 28.513 if (!dom_info->quiet) 28.514 printf("Parsing config file %s\n", config_file); 28.515 28.516 - parse_config_data(config_file, config_data, config_len, &d_config, &dm_info); 28.517 + parse_config_data(config_file, config_data, config_len, &d_config, &d_config.dm_info); 28.518 28.519 ret = 0; 28.520 if (dom_info->dryrun) 28.521 @@ -1654,7 +1434,7 @@ static int create_domain(struct domain_c 28.522 } 28.523 28.524 if (debug) 28.525 - printf_info(-1, &d_config, &dm_info); 28.526 + printf_info(-1, &d_config, &d_config.dm_info); 28.527 28.528 start: 28.529 domid = 0; 28.530 @@ -1663,20 +1443,13 @@ start: 28.531 if (rc < 0) 28.532 goto error_out; 28.533 28.534 - ret = freemem(&d_config.b_info, &dm_info); 28.535 + ret = freemem(&d_config.b_info, &d_config.dm_info); 28.536 if (ret < 0) { 28.537 fprintf(stderr, "failed to free memory for the domain\n"); 28.538 ret = ERROR_FAIL; 28.539 goto error_out; 28.540 } 28.541 28.542 - ret = libxl_domain_make(&ctx, &d_config.c_info, &domid); 28.543 - if (ret) { 28.544 - fprintf(stderr, "cannot make domain: %d\n", ret); 28.545 - ret = ERROR_FAIL; 28.546 - goto error_out; 28.547 - } 28.548 - 28.549 ret = libxl_userdata_store(&ctx, domid, "xl", 28.550 config_data, config_len); 28.551 if (ret) { 28.552 @@ -1685,116 +1458,22 @@ start: 28.553 goto error_out; 28.554 } 28.555 28.556 - if (dom_info->console_autoconnect && !d_config.c_info.hvm) { 28.557 - child_console_pid = autoconnect_console(); 28.558 - if (child_console_pid < 0) 28.559 - goto error_out; 28.560 - } 28.561 - 28.562 - if (!restore_file) { 28.563 - ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks > 0 ? &d_config.disks[0] : NULL, domid); 28.564 - if (ret) { 28.565 - fprintf(stderr, "failed to run bootloader: %d\n", ret); 28.566 - goto error_out; 28.567 - } 28.568 - } 28.569 - 28.570 - if (!restore_file || !need_daemon) { 28.571 - if (dm_info.saved_state) { 28.572 - free(dm_info.saved_state); 28.573 - dm_info.saved_state = NULL; 28.574 - } 28.575 - ret = libxl_domain_build(&ctx, &d_config.b_info, domid, &state); 28.576 - } else { 28.577 - ret = libxl_domain_restore(&ctx, &d_config.b_info, domid, restore_fd, &state, &dm_info); 28.578 - } 28.579 - 28.580 - if (ret) { 28.581 - fprintf(stderr, "cannot (re-)build domain: %d\n", ret); 28.582 - ret = ERROR_FAIL; 28.583 + if ( dom_info->console_autoconnect ) { 28.584 + cb = autoconnect_console; 28.585 + }else{ 28.586 + cb = NULL; 28.587 + } 28.588 + 28.589 + if ( restore_file ) { 28.590 + ret = libxl_domain_create_restore(&ctx, &d_config, 28.591 + cb, &child_console_pid, 28.592 + &domid, restore_fd); 28.593 + }else{ 28.594 + ret = libxl_domain_create_new(&ctx, &d_config, 28.595 + cb, &child_console_pid, &domid); 28.596 + } 28.597 + if ( ret ) 28.598 goto error_out; 28.599 - } 28.600 - 28.601 - for (i = 0; i < d_config.num_disks; i++) { 28.602 - d_config.disks[i].domid = domid; 28.603 - ret = libxl_device_disk_add(&ctx, domid, &d_config.disks[i]); 28.604 - if (ret) { 28.605 - fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret); 28.606 - ret = ERROR_FAIL; 28.607 - goto error_out; 28.608 - } 28.609 - } 28.610 - for (i = 0; i < d_config.num_vifs; i++) { 28.611 - d_config.vifs[i].domid = domid; 28.612 - ret = libxl_device_nic_add(&ctx, domid, &d_config.vifs[i]); 28.613 - if (ret) { 28.614 - fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret); 28.615 - ret = ERROR_FAIL; 28.616 - goto error_out; 28.617 - } 28.618 - } 28.619 - if (!d_config.c_info.hvm) { 28.620 - for (i = 0; i < d_config.num_vif2s; i++) { 28.621 - d_config.vif2s[i].domid = domid; 28.622 - ret = libxl_device_net2_add(&ctx, domid, &d_config.vif2s[i]); 28.623 - if (ret) { 28.624 - fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret); 28.625 - ret = ERROR_FAIL; 28.626 - goto error_out; 28.627 - } 28.628 - } 28.629 - } 28.630 - if (d_config.c_info.hvm) { 28.631 - libxl_device_console console; 28.632 - 28.633 - init_console_info(&console, 0, &state); 28.634 - console.domid = domid; 28.635 - libxl_device_console_add(&ctx, domid, &console); 28.636 - libxl_device_console_destroy(&console); 28.637 - 28.638 - dm_info.domid = domid; 28.639 - MUST( libxl_create_device_model(&ctx, &dm_info, 28.640 - d_config.disks, d_config.num_disks, 28.641 - d_config.vifs, d_config.num_vifs, 28.642 - &dm_starting) ); 28.643 - } else { 28.644 - int need_qemu = 0; 28.645 - libxl_device_console console; 28.646 - 28.647 - for (i = 0; i < d_config.num_vfbs; i++) { 28.648 - d_config.vfbs[i].domid = domid; 28.649 - libxl_device_vfb_add(&ctx, domid, &d_config.vfbs[i]); 28.650 - d_config.vkbs[i].domid = domid; 28.651 - libxl_device_vkb_add(&ctx, domid, &d_config.vkbs[i]); 28.652 - } 28.653 - 28.654 - init_console_info(&console, 0, &state); 28.655 - console.domid = domid; 28.656 - 28.657 - need_qemu = libxl_need_xenpv_qemu(&ctx, 1, &console, 28.658 - d_config.num_vfbs, d_config.vfbs, 28.659 - d_config.num_disks, &d_config.disks[0]); 28.660 - 28.661 - if (need_qemu) 28.662 - console.consback = LIBXL_CONSBACK_IOEMU; 28.663 - 28.664 - libxl_device_console_add(&ctx, domid, &console); 28.665 - libxl_device_console_destroy(&console); 28.666 - 28.667 - if (need_qemu) 28.668 - libxl_create_xenpv_qemu(&ctx, domid, d_config.vfbs, &dm_starting); 28.669 - } 28.670 - 28.671 - if (dm_starting) 28.672 - MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) ); 28.673 - for (i = 0; i < d_config.num_pcidevs; i++) 28.674 - libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]); 28.675 - 28.676 - if (dom_info->console_autoconnect && d_config.c_info.hvm) { 28.677 - child_console_pid = autoconnect_console(); 28.678 - if (child_console_pid < 0) 28.679 - goto error_out; 28.680 - } 28.681 28.682 release_lock(); 28.683 28.684 @@ -1812,6 +1491,8 @@ start: 28.685 28.686 child1 = libxl_fork(&ctx); 28.687 if (child1) { 28.688 + printf("Daemon running with PID %d\n", child1); 28.689 + 28.690 for (;;) { 28.691 got_child = waitpid(child1, &status, 0); 28.692 if (got_child == child1) break; 28.693 @@ -1953,9 +1634,7 @@ out: 28.694 if (logfile != 2) 28.695 close(logfile); 28.696 28.697 - libxl_device_model_info_destroy(&dm_info); 28.698 - 28.699 - free_domain_config(&d_config); 28.700 + libxl_domain_config_destroy(&d_config); 28.701 28.702 free(config_data); 28.703 28.704 @@ -2550,7 +2229,7 @@ static void reboot_domain(const char *p) 28.705 28.706 static void list_domains_details(const libxl_dominfo *info, int nb_domain) 28.707 { 28.708 - struct domain_config d_config; 28.709 + libxl_domain_config d_config; 28.710 28.711 char *config_file; 28.712 uint8_t *data; 28.713 @@ -2568,7 +2247,7 @@ static void list_domains_details(const l 28.714 memset(&d_config, 0x00, sizeof(d_config)); 28.715 parse_config_data(config_file, (char *)data, len, &d_config, &dm_info); 28.716 printf_info(info[i].domid, &d_config, &dm_info); 28.717 - free_domain_config(&d_config); 28.718 + libxl_domain_config_destroy(&d_config); 28.719 free(data); 28.720 free(config_file); 28.721 } 28.722 @@ -4500,7 +4179,7 @@ int main_networkattach(int argc, char ** 28.723 fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]); 28.724 return 1; 28.725 } 28.726 - init_nic_info(&nic, -1); 28.727 + libxl_device_nic_init(&nic, -1); 28.728 for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) { 28.729 if (!strncmp("type=", *argv, 5)) { 28.730 if (!strncmp("vif", (*argv) + 5, 4)) { 28.731 @@ -4834,7 +4513,7 @@ int main_network2attach(int argc, char * 28.732 fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]); 28.733 return 1; 28.734 } 28.735 - init_net2_info(&net2, -1); 28.736 + libxl_device_net2_init(&net2, -1); 28.737 for (argv += optind+1, argc -= optind+1; argc > 0; --argc, ++argv) { 28.738 if (!strncmp("front_mac=", *argv, 10)) { 28.739 tok = strtok((*argv) + 10, ":");
29.1 --- a/tools/ocaml/libs/xl/xl_stubs.c Tue Jan 11 19:31:41 2011 +0000 29.2 +++ b/tools/ocaml/libs/xl/xl_stubs.c Tue Jan 11 19:41:53 2011 +0000 29.3 @@ -68,16 +68,6 @@ void log_destroy(struct xentoollog_logge 29.4 caml_leave_blocking_section(); \ 29.5 libxl_ctx_free(&ctx) 29.6 29.7 -static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size) 29.8 -{ 29.9 - void *ptr; 29.10 - ptr = calloc(nmemb, size); 29.11 - if (!ptr) 29.12 - caml_raise_out_of_memory(); 29.13 - gc->ptrs[gc->offset++] = ptr; 29.14 - return ptr; 29.15 -} 29.16 - 29.17 static char * dup_String_val(caml_gc *gc, value s) 29.18 { 29.19 int len; 29.20 @@ -106,6 +96,17 @@ void failwith_xl(char *fname, struct cam 29.21 caml_raise_with_string(*caml_named_value("xl.error"), s); 29.22 } 29.23 29.24 +#if 0 /* TODO: wrap libxl_domain_create(), these functions will be needed then */ 29.25 +static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size) 29.26 +{ 29.27 + void *ptr; 29.28 + ptr = calloc(nmemb, size); 29.29 + if (!ptr) 29.30 + caml_raise_out_of_memory(); 29.31 + gc->ptrs[gc->offset++] = ptr; 29.32 + return ptr; 29.33 +} 29.34 + 29.35 static int string_string_tuple_array_val (caml_gc *gc, char ***c_val, value v) 29.36 { 29.37 CAMLparam1(v); 29.38 @@ -163,7 +164,7 @@ static int domain_build_info_val (caml_g 29.39 c_val->video_memkb = Int64_val(Field(v, 4)); 29.40 c_val->shadow_memkb = Int64_val(Field(v, 5)); 29.41 c_val->kernel.path = dup_String_val(gc, Field(v, 6)); 29.42 - c_val->hvm = Tag_val(Field(v, 7)) == 0; 29.43 + c_val->is_hvm = Tag_val(Field(v, 7)) == 0; 29.44 infopriv = Field(Field(v, 7), 0); 29.45 if (c_val->hvm) { 29.46 c_val->u.hvm.pae = Bool_val(Field(infopriv, 0)); 29.47 @@ -184,6 +185,7 @@ static int domain_build_info_val (caml_g 29.48 29.49 CAMLreturn(0); 29.50 } 29.51 +#endif 29.52 29.53 static int device_disk_val(caml_gc *gc, libxl_device_disk *c_val, value v) 29.54 { 29.55 @@ -332,21 +334,6 @@ static value Val_sched_credit(libxl_sche 29.56 CAMLreturn(v); 29.57 } 29.58 29.59 -static value Val_domain_build_state(libxl_domain_build_state *c_val) 29.60 -{ 29.61 - CAMLparam0(); 29.62 - CAMLlocal1(v); 29.63 - 29.64 - v = caml_alloc_tuple(4); 29.65 - 29.66 - Store_field(v, 0, Val_int(c_val->store_port)); 29.67 - Store_field(v, 1, caml_copy_int64(c_val->store_mfn)); 29.68 - Store_field(v, 2, Val_int(c_val->console_port)); 29.69 - Store_field(v, 3, caml_copy_int64(c_val->console_mfn)); 29.70 - 29.71 - CAMLreturn(v); 29.72 -} 29.73 - 29.74 static value Val_physinfo(libxl_physinfo *c_val) 29.75 { 29.76 CAMLparam0(); 29.77 @@ -373,52 +360,6 @@ static value Val_physinfo(libxl_physinfo 29.78 CAMLreturn(v); 29.79 } 29.80 29.81 -value stub_xl_domain_make(value info) 29.82 -{ 29.83 - CAMLparam1(info); 29.84 - uint32_t domid; 29.85 - libxl_domain_create_info c_info; 29.86 - int ret; 29.87 - INIT_STRUCT(); 29.88 - 29.89 - domain_create_info_val (&gc, &c_info, info); 29.90 - 29.91 - INIT_CTX(); 29.92 - 29.93 - ret = libxl_domain_make(&ctx, &c_info, &domid); 29.94 - if (ret != 0) 29.95 - failwith_xl("domain make", &lg); 29.96 - 29.97 - FREE_CTX(); 29.98 - 29.99 - CAMLreturn(Val_int(domid)); 29.100 -} 29.101 - 29.102 -value stub_xl_domain_build(value info, value domid) 29.103 -{ 29.104 - CAMLparam2(info, domid); 29.105 - CAMLlocal1(result); 29.106 - libxl_domain_build_info c_info; 29.107 - libxl_domain_build_state c_state; 29.108 - int ret; 29.109 - int c_domid; 29.110 - INIT_STRUCT(); 29.111 - 29.112 - domain_build_info_val (&gc, &c_info, info); 29.113 - c_domid = Int_val(domid); 29.114 - 29.115 - INIT_CTX(); 29.116 - 29.117 - ret = libxl_domain_build(&ctx, &c_info, c_domid, &c_state); 29.118 - if (ret != 0) 29.119 - failwith_xl("domain_build", &lg); 29.120 - 29.121 - result = Val_domain_build_state(&c_state); 29.122 - FREE_CTX(); 29.123 - 29.124 - CAMLreturn(result); 29.125 -} 29.126 - 29.127 value stub_xl_disk_add(value info, value domid) 29.128 { 29.129 CAMLparam2(info, domid);
30.1 --- a/tools/python/genwrap.py Tue Jan 11 19:31:41 2011 +0000 30.2 +++ b/tools/python/genwrap.py Tue Jan 11 19:41:53 2011 +0000 30.3 @@ -51,7 +51,10 @@ def py_attrib_get(ty, f): 30.4 l.append('static PyObject *py_%s_%s_get(Py_%s *self, void *priv)'%(ty.rawname, f.name, ty.rawname)) 30.5 l.append('{') 30.6 if t == TYPE_BOOL: 30.7 - l.append(' return (self->obj.%s) ? Py_True : Py_False;'%f.name) 30.8 + l.append(' PyObject *ret;') 30.9 + l.append(' ret = (self->obj.%s) ? Py_True : Py_False;'%f.name) 30.10 + l.append(' Py_INCREF(ret);') 30.11 + l.append(' return ret;') 30.12 elif t == TYPE_INT: 30.13 l.append(' return genwrap__ll_get(self->obj.%s);'%f.name) 30.14 elif t == TYPE_UINT: 30.15 @@ -148,7 +151,7 @@ static PyTypeObject Py%s_Type= { 30.16 NULL, /* tp_getattro */ 30.17 NULL, /* tp_setattro */ 30.18 NULL, /* tp_as_buffer */ 30.19 - Py_TPFLAGS_DEFAULT, /* tp_flags */ 30.20 + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ 30.21 "%s", /* tp_doc */ 30.22 NULL, /* tp_traverse */ 30.23 NULL, /* tp_clear */
31.1 --- a/tools/python/xen/lowlevel/xl/xl.c Tue Jan 11 19:31:41 2011 +0000 31.2 +++ b/tools/python/xen/lowlevel/xl/xl.c Tue Jan 11 19:41:53 2011 +0000 31.3 @@ -76,7 +76,7 @@ int genwrap__obj_init(PyObject *self, Py 31.4 int genwrap__string_set(PyObject *v, char **str) 31.5 { 31.6 char *tmp; 31.7 - if ( NULL == v ) { 31.8 + if ( NULL == v || Py_None == v ) { 31.9 free(*str); 31.10 *str = NULL; 31.11 return 0; 31.12 @@ -97,8 +97,10 @@ int genwrap__string_set(PyObject *v, cha 31.13 31.14 PyObject *genwrap__string_get(char **str) 31.15 { 31.16 - if ( NULL == *str ) 31.17 + if ( NULL == *str ) { 31.18 + Py_INCREF(Py_None); 31.19 return Py_None; 31.20 + } 31.21 return PyString_FromString(*str); 31.22 } 31.23 31.24 @@ -209,6 +211,7 @@ static PyObject *fixed_bytearray_get(con 31.25 31.26 int attrib__libxl_cpuid_policy_list_set(PyObject *v, libxl_cpuid_policy_list *pptr) 31.27 { 31.28 + PyErr_SetString(PyExc_NotImplementedError, "Setting cpuid_policy_list"); 31.29 return -1; 31.30 } 31.31 31.32 @@ -231,21 +234,29 @@ int attrib__libxl_cpuarray_set(PyObject 31.33 31.34 int attrib__libxl_domain_build_state_ptr_set(PyObject *v, libxl_domain_build_state **pptr) 31.35 { 31.36 + PyErr_SetString(PyExc_NotImplementedError, "Setting domain_build_state_ptr"); 31.37 return -1; 31.38 } 31.39 31.40 int attrib__libxl_file_reference_set(PyObject *v, libxl_file_reference *pptr) 31.41 { 31.42 - return -1; 31.43 + return genwrap__string_set(v, &pptr->path); 31.44 } 31.45 31.46 int attrib__libxl_hwcap_set(PyObject *v, libxl_hwcap *pptr) 31.47 { 31.48 + PyErr_SetString(PyExc_NotImplementedError, "Setting hwcap"); 31.49 return -1; 31.50 } 31.51 31.52 int attrib__libxl_key_value_list_set(PyObject *v, libxl_key_value_list *pptr) 31.53 { 31.54 + if ( *pptr ) { 31.55 + libxl_key_value_list_destroy(pptr); 31.56 + *pptr = NULL; 31.57 + } 31.58 + if ( v == Py_None ) 31.59 + return 0; 31.60 return -1; 31.61 } 31.62 31.63 @@ -256,6 +267,7 @@ int attrib__libxl_mac_set(PyObject *v, l 31.64 31.65 int attrib__libxl_string_list_set(PyObject *v, libxl_string_list *pptr) 31.66 { 31.67 + PyErr_SetString(PyExc_NotImplementedError, "Setting string_list"); 31.68 return -1; 31.69 } 31.70 31.71 @@ -266,11 +278,13 @@ int attrib__libxl_uuid_set(PyObject *v, 31.72 31.73 int attrib__struct_in_addr_set(PyObject *v, struct in_addr *pptr) 31.74 { 31.75 + PyErr_SetString(PyExc_NotImplementedError, "Setting in_addr"); 31.76 return -1; 31.77 } 31.78 31.79 PyObject *attrib__libxl_cpuid_policy_list_get(libxl_cpuid_policy_list *pptr) 31.80 { 31.81 + PyErr_SetString(PyExc_NotImplementedError, "Getting cpuid_policy_list"); 31.82 return NULL; 31.83 } 31.84 31.85 @@ -312,21 +326,24 @@ PyObject *attrib__libxl_cpuarray_get(lib 31.86 31.87 PyObject *attrib__libxl_domain_build_state_ptr_get(libxl_domain_build_state **pptr) 31.88 { 31.89 + PyErr_SetString(PyExc_NotImplementedError, "Getting domain_build_state_ptr"); 31.90 return NULL; 31.91 } 31.92 31.93 PyObject *attrib__libxl_file_reference_get(libxl_file_reference *pptr) 31.94 { 31.95 - return NULL; 31.96 + return genwrap__string_get(&pptr->path); 31.97 } 31.98 31.99 PyObject *attrib__libxl_hwcap_get(libxl_hwcap *pptr) 31.100 { 31.101 + PyErr_SetString(PyExc_NotImplementedError, "Getting hwcap"); 31.102 return NULL; 31.103 } 31.104 31.105 PyObject *attrib__libxl_key_value_list_get(libxl_key_value_list *pptr) 31.106 { 31.107 + PyErr_SetString(PyExc_NotImplementedError, "Getting key_value_list"); 31.108 return NULL; 31.109 } 31.110 31.111 @@ -337,6 +354,7 @@ PyObject *attrib__libxl_mac_get(libxl_ma 31.112 31.113 PyObject *attrib__libxl_string_list_get(libxl_string_list *pptr) 31.114 { 31.115 + PyErr_SetString(PyExc_NotImplementedError, "Getting string_list"); 31.116 return NULL; 31.117 } 31.118 31.119 @@ -347,6 +365,7 @@ PyObject *attrib__libxl_uuid_get(libxl_u 31.120 31.121 PyObject *attrib__struct_in_addr_get(struct in_addr *pptr) 31.122 { 31.123 + PyErr_SetString(PyExc_NotImplementedError, "Getting in_addr"); 31.124 return NULL; 31.125 } 31.126 31.127 @@ -377,6 +396,7 @@ static PyObject *pyxl_list_domains(XlObj 31.128 if ( NULL == di ) 31.129 goto err_mem; 31.130 memcpy(&di->obj, cur, sizeof(di->obj)); 31.131 + /* SetItem steals a reference */ 31.132 PyList_SetItem(list, i, (PyObject *)di); 31.133 } 31.134 31.135 @@ -413,6 +433,7 @@ static PyObject *pyxl_domain_shutdown(Xl 31.136 PyErr_SetString(xl_error_obj, "cannot shutdown domain"); 31.137 return NULL; 31.138 } 31.139 + Py_INCREF(Py_None); 31.140 return Py_None; 31.141 } 31.142 31.143 @@ -425,6 +446,7 @@ static PyObject *pyxl_domain_destroy(XlO 31.144 PyErr_SetString(xl_error_obj, "cannot destroy domain"); 31.145 return NULL; 31.146 } 31.147 + Py_INCREF(Py_None); 31.148 return Py_None; 31.149 } 31.150 31.151 @@ -437,6 +459,7 @@ static PyObject *pyxl_domain_pause(XlObj 31.152 PyErr_SetString(xl_error_obj, "cannot pause domain"); 31.153 return NULL; 31.154 } 31.155 + Py_INCREF(Py_None); 31.156 return Py_None; 31.157 } 31.158 31.159 @@ -449,6 +472,7 @@ static PyObject *pyxl_domain_unpause(XlO 31.160 PyErr_SetString(xl_error_obj, "cannot unpause domain"); 31.161 return NULL; 31.162 } 31.163 + Py_INCREF(Py_None); 31.164 return Py_None; 31.165 } 31.166 31.167 @@ -462,6 +486,7 @@ static PyObject *pyxl_domain_rename(XlOb 31.168 PyErr_SetString(xl_error_obj, "cannot rename domain"); 31.169 return NULL; 31.170 } 31.171 + Py_INCREF(Py_None); 31.172 return Py_None; 31.173 } 31.174 31.175 @@ -481,6 +506,7 @@ static PyObject *pyxl_pci_add(XlObject * 31.176 PyErr_SetString(xl_error_obj, "cannot add pci device"); 31.177 return NULL; 31.178 } 31.179 + Py_INCREF(Py_None); 31.180 return Py_None; 31.181 } 31.182 31.183 @@ -501,6 +527,7 @@ static PyObject *pyxl_pci_del(XlObject * 31.184 PyErr_SetString(xl_error_obj, "cannot remove pci device"); 31.185 return NULL; 31.186 } 31.187 + Py_INCREF(Py_None); 31.188 return Py_None; 31.189 } 31.190 31.191 @@ -527,6 +554,75 @@ static PyObject *pyxl_pci_parse(XlObject 31.192 return (PyObject *)pci; 31.193 } 31.194 31.195 +static PyObject *pyxl_pci_list_assignable(XlObject *self, PyObject *args) 31.196 +{ 31.197 + libxl_device_pci *dev; 31.198 + PyObject *list; 31.199 + int nr_dev, i; 31.200 + 31.201 + if ( libxl_device_pci_list_assignable(&self->ctx, &dev, &nr_dev) ) { 31.202 + PyErr_SetString(xl_error_obj, "Cannot list assignable devices"); 31.203 + return NULL; 31.204 + } 31.205 + 31.206 + list = PyList_New(nr_dev); 31.207 + if ( NULL == list ) 31.208 + return NULL; 31.209 + 31.210 + for(i = 0; i < nr_dev; i++) { 31.211 + Py_device_pci *pd; 31.212 + pd = Pydevice_pci_New(); 31.213 + if ( NULL == pd ) 31.214 + goto err_mem; 31.215 + memcpy(&pd->obj, &dev[i], sizeof(pd->obj)); 31.216 + /* SetItem steals a reference */ 31.217 + PyList_SetItem(list, i, (PyObject *)pd); 31.218 + } 31.219 + 31.220 + free(dev); 31.221 + return list; 31.222 +err_mem: 31.223 + Py_DECREF(list); 31.224 + PyErr_SetString(PyExc_MemoryError, "Allocating PCI device list"); 31.225 + return NULL; 31.226 +} 31.227 + 31.228 +static PyObject *pyxl_pci_list(XlObject *self, PyObject *args) 31.229 +{ 31.230 + libxl_device_pci *dev; 31.231 + PyObject *list; 31.232 + int nr_dev, i, domid; 31.233 + 31.234 + if ( !PyArg_ParseTuple(args, "i", &domid) ) 31.235 + return NULL; 31.236 + 31.237 + if ( libxl_device_pci_list_assigned(&self->ctx, &dev, domid, &nr_dev) ) { 31.238 + PyErr_SetString(xl_error_obj, "Cannot list assignable devices"); 31.239 + return NULL; 31.240 + } 31.241 + 31.242 + list = PyList_New(nr_dev); 31.243 + if ( NULL == list ) 31.244 + return NULL; 31.245 + 31.246 + for(i = 0; i < nr_dev; i++) { 31.247 + Py_device_pci *pd; 31.248 + pd = Pydevice_pci_New(); 31.249 + if ( NULL == pd ) 31.250 + goto err_mem; 31.251 + memcpy(&pd->obj, &dev[i], sizeof(pd->obj)); 31.252 + /* SetItem steals a reference */ 31.253 + PyList_SetItem(list, i, (PyObject *)pd); 31.254 + } 31.255 + 31.256 + free(dev); 31.257 + return list; 31.258 +err_mem: 31.259 + Py_DECREF(list); 31.260 + PyErr_SetString(PyExc_MemoryError, "Allocating PCI device list"); 31.261 + return NULL; 31.262 +} 31.263 + 31.264 static PyMethodDef pyxl_methods[] = { 31.265 {"list_domains", (PyCFunction)pyxl_list_domains, METH_NOARGS, 31.266 "List domains"}, 31.267 @@ -536,9 +632,9 @@ static PyMethodDef pyxl_methods[] = { 31.268 "Shutdown a domain"}, 31.269 {"domain_destroy", (PyCFunction)pyxl_domain_destroy, METH_VARARGS, 31.270 "Destroy a domain"}, 31.271 - {"domain_pause", (PyCFunction)pyxl_domain_unpause, METH_VARARGS, 31.272 + {"domain_pause", (PyCFunction)pyxl_domain_pause, METH_VARARGS, 31.273 "Pause a domain"}, 31.274 - {"domain_unpause", (PyCFunction)pyxl_domain_pause, METH_VARARGS, 31.275 + {"domain_unpause", (PyCFunction)pyxl_domain_unpause, METH_VARARGS, 31.276 "Unpause a domain"}, 31.277 {"domain_rename", (PyCFunction)pyxl_domain_rename, METH_VARARGS, 31.278 "Rename a domain"}, 31.279 @@ -548,6 +644,11 @@ static PyMethodDef pyxl_methods[] = { 31.280 "Remove a pass-through PCI device"}, 31.281 {"device_pci_parse_bdf", (PyCFunction)pyxl_pci_parse, METH_VARARGS, 31.282 "Parse pass-through PCI device spec (BDF)"}, 31.283 + {"device_pci_list", (PyCFunction)pyxl_pci_list, METH_VARARGS, 31.284 + "List PCI devices assigned to a domain"}, 31.285 + {"device_pci_list_assignable", 31.286 + (PyCFunction)pyxl_pci_list_assignable, METH_NOARGS, 31.287 + "List assignable PCI devices"}, 31.288 { NULL, NULL, 0, NULL } 31.289 }; 31.290 31.291 @@ -618,7 +719,7 @@ static PyTypeObject PyXlType = { 31.292 NULL, /* tp_getattro */ 31.293 NULL, /* tp_setattro */ 31.294 NULL, /* tp_as_buffer */ 31.295 - Py_TPFLAGS_DEFAULT, /* tp_flags */ 31.296 + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ 31.297 "libxenlight connection", /* tp_doc */ 31.298 NULL, /* tp_traverse */ 31.299 NULL, /* tp_clear */ 31.300 @@ -641,6 +742,8 @@ static PyTypeObject PyXlType = { 31.301 31.302 static PyMethodDef xl_methods[] = { { NULL } }; 31.303 31.304 +#define _INT_CONST(m, c) PyModule_AddIntConstant(m, #c, c) 31.305 +#define _INT_CONST_LIBXL(m, c) PyModule_AddIntConstant(m, #c, LIBXL_ ## c) 31.306 PyMODINIT_FUNC initxl(void) 31.307 { 31.308 PyObject *m; 31.309 @@ -661,6 +764,36 @@ PyMODINIT_FUNC initxl(void) 31.310 Py_INCREF(xl_error_obj); 31.311 PyModule_AddObject(m, "Error", xl_error_obj); 31.312 31.313 + _INT_CONST(m, SHUTDOWN_poweroff); 31.314 + _INT_CONST(m, SHUTDOWN_reboot); 31.315 + _INT_CONST(m, SHUTDOWN_suspend); 31.316 + _INT_CONST(m, SHUTDOWN_crash); 31.317 + _INT_CONST(m, SHUTDOWN_watchdog); 31.318 + 31.319 + _INT_CONST(m, XENFV); 31.320 + _INT_CONST(m, XENPV); 31.321 + 31.322 + _INT_CONST_LIBXL(m, CONSTYPE_SERIAL); 31.323 + _INT_CONST_LIBXL(m, CONSTYPE_PV); 31.324 + 31.325 + _INT_CONST_LIBXL(m, CONSBACK_XENCONSOLED); 31.326 + _INT_CONST_LIBXL(m, CONSBACK_IOEMU); 31.327 + 31.328 + _INT_CONST(m, PHYSTYPE_QCOW); 31.329 + _INT_CONST(m, PHYSTYPE_QCOW2); 31.330 + _INT_CONST(m, PHYSTYPE_VHD); 31.331 + _INT_CONST(m, PHYSTYPE_AIO); 31.332 + _INT_CONST(m, PHYSTYPE_FILE); 31.333 + _INT_CONST(m, PHYSTYPE_PHY); 31.334 + 31.335 + _INT_CONST(m, NICTYPE_IOEMU); 31.336 + _INT_CONST(m, NICTYPE_VIF); 31.337 + 31.338 + _INT_CONST_LIBXL(m, EVENT_DOMAIN_DEATH); 31.339 + _INT_CONST_LIBXL(m, EVENT_DISK_EJECT); 31.340 + 31.341 + _INT_CONST(m, POWER_BUTTON); 31.342 + _INT_CONST(m, SLEEP_BUTTON); 31.343 genwrap__init(m); 31.344 } 31.345
32.1 --- a/tools/python/xen/xend/XendConfig.py Tue Jan 11 19:31:41 2011 +0000 32.2 +++ b/tools/python/xen/xend/XendConfig.py Tue Jan 11 19:41:53 2011 +0000 32.3 @@ -498,6 +498,10 @@ class XendConfig(dict): 32.4 if os.path.dirname(self['platform']['device_model']) == "": 32.5 self['platform']['device_model'] = \ 32.6 auxbin.pathTo(self['platform']['device_model']) 32.7 + # If the device_model is not set the os.path.exists() would raise 32.8 + # an exception so we return our error message instead if applicable 32.9 + if not self['platform']['device_model']: 32.10 + raise VmError("No valid device model specified") 32.11 if not os.path.exists(self['platform']['device_model']): 32.12 raise VmError("device model '%s' not found" % str(self['platform']['device_model'])) 32.13
33.1 --- a/tools/xenpaging/xc.c Tue Jan 11 19:31:41 2011 +0000 33.2 +++ b/tools/xenpaging/xc.c Tue Jan 11 19:41:53 2011 +0000 33.3 @@ -62,7 +62,7 @@ int xc_mem_paging_flush_ioemu_cache(domi 33.4 33.5 xs_daemon_close(xsh); 33.6 33.7 - return rc; 33.8 + return rc ? 0 : -1; 33.9 } 33.10 33.11 int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms)