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, &sectors)) {
  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)