[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Merge



# HG changeset patch
# User Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
# Date 1294774913 0
# Node ID 548c29920f682d30ac5f1d692e66f0f990e161c1
# Parent  cb94dbe20f97ae5ff242d4c7fe1a4dc57ee63c23
# Parent  ea6f92a479dae99857f8fdfd55833285042419f4
Merge
---
 extras/mini-os/fs-front.c           | 1297 ------------------------------------
 extras/mini-os/include/fs.h         |   56 -
 tools/fs-back/Makefile              |   35 
 tools/fs-back/fs-backend.c          |  500 -------------
 tools/fs-back/fs-backend.h          |  102 --
 tools/fs-back/fs-debug.h            |   12 
 tools/fs-back/fs-ops.c              |  794 ----------------------
 tools/fs-back/fs-xenbus.c           |  273 -------
 tools/fs-back/sys-queue.h           |  338 ---------
 Config.mk                           |    6 
 extras/mini-os/arch/x86/mm.c        |    2 
 extras/mini-os/include/fbfront.h    |    1 
 extras/mini-os/kernel.c             |    7 
 extras/mini-os/lib/math.c           |   44 -
 extras/mini-os/lib/sys.c            |  221 ------
 extras/mini-os/main.c               |    2 
 stubdom/stubdom-dm                  |    2 
 tools/Makefile                      |    2 
 tools/libxl/Makefile                |    6 
 tools/libxl/libxl.c                 |  322 ++------
 tools/libxl/libxl.h                 |   69 +
 tools/libxl/libxl.idl               |    1 
 tools/libxl/libxl_create.c          |  551 +++++++++++++++
 tools/libxl/libxl_dm.c              |   43 -
 tools/libxl/libxl_exec.c            |    2 
 tools/libxl/libxl_internal.h        |   29 
 tools/libxl/libxl_pci.c             |   74 +-
 tools/libxl/xl_cmdimpl.c            |  495 ++-----------
 tools/ocaml/libs/xl/xl_stubs.c      |   85 --
 tools/python/genwrap.py             |    7 
 tools/python/xen/lowlevel/xl/xl.c   |  187 ++++-
 tools/python/xen/xend/XendConfig.py |    4 
 tools/xenpaging/xc.c                |    2 
 33 files changed, 1074 insertions(+), 4497 deletions(-)

diff -r cb94dbe20f97 -r 548c29920f68 Config.mk
--- a/Config.mk Tue Jan 11 19:31:41 2011 +0000
+++ b/Config.mk Tue Jan 11 19:41:53 2011 +0000
@@ -185,9 +185,9 @@ endif
 # CONFIG_QEMU ?= ../qemu-xen.git
 CONFIG_QEMU ?= $(QEMU_REMOTE)
 
-QEMU_TAG ?= 99d53fbb69d3e03be61ae10506a304a3d08d792f
-# Wed Jan 5 23:48:36 2011 +0000
-# fix '|' key display problem in en-us with altgr processing
+QEMU_TAG ?= 1c304816043c0ffe14d20d6006d6165cb7fddb9b
+# Tue Jan 11 18:48:58 2011 +0000
+# qemu-xen: use dynticks instead of a static 10ms timeout
 
 # Optional components
 XENSTAT_XENTOP     ?= y
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c      Tue Jan 11 19:31:41 2011 +0000
+++ b/extras/mini-os/arch/x86/mm.c      Tue Jan 11 19:41:53 2011 +0000
@@ -281,7 +281,7 @@ static void build_pagetable(unsigned lon
 /*
  * Mark portion of the address space read only.
  */
-extern void shared_info;
+extern struct shared_info shared_info;
 static void set_readonly(void *text, void *etext)
 {
     unsigned long start_address =
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/fs-front.c
--- a/extras/mini-os/fs-front.c Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1297 +0,0 @@
-/******************************************************************************
- * fs-front.c
- * 
- * Frontend driver for FS split device driver.
- *
- * Copyright (c) 2007, Grzegorz Milos, <gm281@xxxxxxxxx>.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- * DEALINGS IN THE SOFTWARE.
- */
-
-#undef NDEBUG
-#include <stdint.h>
-#include <mini-os/os.h>
-#include <mini-os/list.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/events.h>
-#include <xen/io/fsif.h>
-#include <mini-os/fs.h>
-#include <mini-os/sched.h>
-
-#define preempt_disable()
-#define preempt_enable()
-#define cmpxchg(p,o,n) synch_cmpxchg(p,o,n)
-
-
-#ifdef FS_DEBUG
-#define DEBUG(_f, _a...) \
-    printk("MINI_OS(file=fs-front.c, line=%d) " _f "\n", __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...)    ((void)0)
-#endif
-
-
-struct fs_request;
-struct fs_import *fs_import;
-void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t 
*gref);
-void free_buffer_page(struct fs_request *req);
-
-/******************************************************************************/
-/*                      RING REQUEST/RESPONSES HANDLING                       
*/
-/******************************************************************************/
-
-struct fs_request
-{
-    void *private1;                        /* Specific to request type */
-    void *private2;
-    struct thread *thread;                 /* Thread blocked on this request */
-    struct fsif_response shadow_rsp;       /* Response copy writen by the 
-                                              interrupt handler */  
-};
-
-struct fs_rw_gnts
-{
-    /* TODO 16 bit? */
-    int count;
-    grant_ref_t grefs[FSIF_NR_READ_GNTS];  
-    void *pages[FSIF_NR_READ_GNTS];  
-};
-
-/* Ring operations:
- * FSIF ring is used differently to Linux-like split devices. This stems from 
- * the fact that no I/O request queue is present. The use of some of the macros
- * defined in ring.h is not allowed, in particular:
- * RING_PUSH_REQUESTS_AND_CHECK_NOTIFY cannot be used.
- *
- * The protocol used for FSIF ring is described below:
- *
- * In order to reserve a request the frontend:
- * a) saves current frontend_ring->req_prod_pvt into a local variable
- * b) checks that there are free request using the local req_prod_pvt
- * c) tries to reserve the request using cmpxchg on frontend_ring->req_prod_pvt
- *    if cmpxchg fails, it means that someone reserved the request, start from
- *    a)
- * 
- * In order to commit a request to the shared ring:
- * a) cmpxchg shared_ring->req_prod from local req_prod_pvt to req_prod_pvt+1 
- *    Loop if unsuccessful.
- * NOTE: Request should be commited to the shared ring as quickly as possible,
- *       because otherwise other threads might busy loop trying to commit next
- *       requests. It also follows that preemption should be disabled, if
- *       possible, for the duration of the request construction.
- */
-
-/* Number of free requests (for use on front side only). */
-#define FS_RING_FREE_REQUESTS(_r, _req_prod_pvt)                         \
-    (RING_SIZE(_r) - (_req_prod_pvt - (_r)->rsp_cons))
-
-
-
-static RING_IDX reserve_fsif_request(struct fs_import *import)
-{
-    RING_IDX idx; 
-
-    down(&import->reqs_sem);
-    preempt_disable();
-again:    
-    /* We will attempt to reserve slot idx */
-    idx = import->ring.req_prod_pvt;
-    ASSERT (FS_RING_FREE_REQUESTS(&import->ring, idx));
-    /* Attempt to reserve */
-    if(cmpxchg(&import->ring.req_prod_pvt, idx, idx+1) != idx)
-        goto again;
-
-    return idx; 
-}
-
-static void commit_fsif_request(struct fs_import *import, RING_IDX idx)
-{
-    while(cmpxchg(&import->ring.sring->req_prod, idx, idx+1) != idx)
-    {
-        printk("Failed to commit a request: req_prod=%d, idx=%d\n",
-                import->ring.sring->req_prod, idx);
-    }
-    preempt_enable();
-
-    /* NOTE: we cannot do anything clever about rsp_event, to hold off
-     * notifications, because we don't know if we are a single request (in 
which
-     * case we have to notify always), or a part of a larger request group
-     * (when, in some cases, notification isn't required) */
-    notify_remote_via_evtchn(import->local_port);
-}
-
-
-
-static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
-{
-    unsigned int old_id, new_id;
-
-again:    
-    old_id = freelist[0];
-    /* Note: temporal inconsistency, since freelist[0] can be changed by 
someone
-     * else, but we are a sole owner of freelist[id + 1], it's OK. */
-    freelist[id + 1] = old_id;
-    new_id = id;
-    if(cmpxchg(&freelist[0], old_id, new_id) != old_id)
-    {
-        printk("Cmpxchg on freelist add failed.\n");
-        goto again;
-    }
-}
-
-/* always call reserve_fsif_request(import) before this, to protect from
- * depletion. */
-static inline unsigned short get_id_from_freelist(unsigned short* freelist)
-{
-    unsigned int old_id, new_id;
-
-again:    
-    old_id = freelist[0];
-    new_id = freelist[old_id + 1];
-    if(cmpxchg(&freelist[0], old_id, new_id) != old_id)
-    {
-        printk("Cmpxchg on freelist remove failed.\n");
-        goto again;
-    }
-    
-    return old_id;
-}
-
-/******************************************************************************/
-/*                  END OF RING REQUEST/RESPONSES HANDLING                    
*/
-/******************************************************************************/
-
-
-
-/******************************************************************************/
-/*                         INDIVIDUAL FILE OPERATIONS                         
*/
-/******************************************************************************/
-int fs_open(struct fs_import *import, char *file)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int fd;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref id=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", file);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_OPEN;
-    req->id = priv_req_id;
-    req->u.fopen.gref = gref;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    fd = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following FD returned: %d\n", fd);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return fd;
-} 
-
-int fs_close(struct fs_import *import, int fd)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_close call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_CLOSE;
-    req->id = priv_req_id;
-    req->u.fclose.fd = fd;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Close returned: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-ssize_t fs_read(struct fs_import *import, int fd, void *buf, 
-                ssize_t len, ssize_t offset)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    struct fs_rw_gnts gnts;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    ssize_t ret;
-    int i;
-
-    if (!import)
-        return -1;
-
-    BUG_ON(len > PAGE_SIZE * FSIF_NR_READ_GNTS);
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_READ;
-    req->id = priv_req_id;
-    req->u.fread.fd = fd;
-    req->u.fread.len = len;
-    req->u.fread.offset = offset;
-
-
-    ASSERT(len > 0);
-    gnts.count = ((len - 1) / PAGE_SIZE) + 1; 
-    for(i=0; i<gnts.count; i++)
-    {
-        gnts.pages[i] = (void *)alloc_page(); 
-        gnts.grefs[i] = gnttab_grant_access(import->dom_id, 
-                                            virt_to_mfn(gnts.pages[i]), 
-                                            0); 
-        memset(gnts.pages[i], 0, PAGE_SIZE);
-        req->u.fread.grefs[i] = gnts.grefs[i];
-    }
-    fsr->thread = current;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (ssize_t)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret value returned %d\n", ret);
-    if(ret > 0)
-    {
-        ssize_t to_copy = ret, current_copy;
-        for(i=0; i<gnts.count; i++)
-        {
-            gnttab_end_access(gnts.grefs[i]);
-            current_copy = to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy;
-            if(current_copy > 0)
-                memcpy(buf, gnts.pages[i], current_copy); 
-            to_copy -= current_copy; 
-            buf = (char*) buf + current_copy;
-            free_page(gnts.pages[i]);
-        }
-    }
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-ssize_t fs_write(struct fs_import *import, int fd, void *buf, 
-                 ssize_t len, ssize_t offset)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    struct fs_rw_gnts gnts;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    ssize_t ret, to_copy;
-    int i;
-
-    if (!import)
-        return -1;
-
-    BUG_ON(len > PAGE_SIZE * FSIF_NR_WRITE_GNTS);
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_WRITE;
-    req->id = priv_req_id;
-    req->u.fwrite.fd = fd;
-    req->u.fwrite.len = len;
-    req->u.fwrite.offset = offset;
-
-    ASSERT(len > 0);
-    gnts.count = ((len - 1) / PAGE_SIZE) + 1; 
-    to_copy = len;
-    for(i=0; i<gnts.count; i++)
-    {
-        int current_copy = (to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy);
-        gnts.pages[i] = (void *)alloc_page(); 
-        gnts.grefs[i] = gnttab_grant_access(import->dom_id, 
-                                            virt_to_mfn(gnts.pages[i]), 
-                                            0); 
-        memcpy(gnts.pages[i], buf, current_copy);
-        if(current_copy < PAGE_SIZE)
-            memset((char *)gnts.pages[i] + current_copy, 
-                    0, 
-                    PAGE_SIZE - current_copy); 
-        req->u.fwrite.grefs[i] = gnts.grefs[i];
-        to_copy -= current_copy; 
-        buf = (char*) buf + current_copy;
-    }
-    fsr->thread = current;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (ssize_t)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret value returned %d\n", ret);
-    for(i=0; i<gnts.count; i++)
-    {
-        gnttab_end_access(gnts.grefs[i]);
-        free_page(gnts.pages[i]);
-    }
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_stat(struct fs_import *import, 
-            int fd, 
-            struct fsif_stat_response *stat)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_stat call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_STAT;
-    req->id = priv_req_id;
-    req->u.fstat.fd   = fd;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Following ret from fstat: %d\n", ret);
-    memcpy(stat, 
-           &fsr->shadow_rsp.u.fstat, 
-           sizeof(struct fsif_stat_response));
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_truncate(struct fs_import *import, 
-                int fd, 
-                int64_t length)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_truncate call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_TRUNCATE;
-    req->id = priv_req_id;
-    req->u.ftruncate.fd = fd;
-    req->u.ftruncate.length = length;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Following ret from ftruncate: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_remove(struct fs_import *import, char *file)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", file);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_REMOVE;
-    req->id = priv_req_id;
-    req->u.fremove.gref = gref;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret: %d\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-
-int fs_rename(struct fs_import *import, 
-              char *old_file_name, 
-              char *new_file_name)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-    char old_header[] = "old: ";
-    char new_header[] = "new: ";
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s%s%c%s%s", 
-            old_header, old_file_name, '\0', new_header, new_file_name);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_RENAME;
-    req->id = priv_req_id;
-    req->u.frename.gref = gref;
-    req->u.frename.old_name_offset = strlen(old_header);
-    req->u.frename.new_name_offset = strlen(old_header) +
-                                     strlen(old_file_name) +
-                                     strlen(new_header) +
-                                     1 /* Accouning for the additional 
-                                          end of string character */;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret: %d\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-int fs_create(struct fs_import *import, char *name, 
-              int8_t directory, int32_t mode)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_create call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", name);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_CREATE;
-    req->id = priv_req_id;
-    req->u.fcreate.gref = gref;
-    req->u.fcreate.directory = directory;
-    req->u.fcreate.mode = mode;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret: %d\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-char** fs_list(struct fs_import *import, char *name, 
-               int32_t offset, int32_t *nr_files, int *has_more)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    char **files, *current_file;
-    int i;
-
-    if (!import)
-        return NULL;
-
-    DEBUG("Different masks: NR_FILES=(%llx, %d), ERROR=(%llx, %d), 
HAS_MORE(%llx, %d)\n",
-            NR_FILES_MASK, NR_FILES_SHIFT, ERROR_MASK, ERROR_SHIFT, 
HAS_MORE_FLAG, HAS_MORE_SHIFT);
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_list call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", name);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_DIR_LIST;
-    req->id = priv_req_id;
-    req->u.flist.gref = gref;
-    req->u.flist.offset = offset;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    *nr_files = (fsr->shadow_rsp.u.ret_val & NR_FILES_MASK) >> NR_FILES_SHIFT;
-    files = NULL;
-    if(*nr_files <= 0) goto exit;
-    files = malloc(sizeof(char*) * (*nr_files));
-    current_file = buffer; 
-    for(i=0; i<*nr_files; i++)
-    {
-        files[i] = strdup(current_file); 
-        current_file += strlen(current_file) + 1;
-    }
-    if(has_more != NULL)
-        *has_more = fsr->shadow_rsp.u.ret_val & HAS_MORE_FLAG;
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-exit:
-    return files;
-} 
-
-int fs_chmod(struct fs_import *import, int fd, int32_t mode)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_chmod call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_CHMOD;
-    req->id = priv_req_id;
-    req->u.fchmod.fd = fd;
-    req->u.fchmod.mode = mode;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following returned: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int64_t fs_space(struct fs_import *import, char *location)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int64_t ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_space is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", location);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FS_SPACE;
-    req->id = priv_req_id;
-    req->u.fspace.gref = gref;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int64_t)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following returned: %lld\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_sync(struct fs_import *import, int fd)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_sync call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_SYNC;
-    req->id = priv_req_id;
-    req->u.fsync.fd = fd;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Close returned: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-
-/******************************************************************************/
-/*                       END OF INDIVIDUAL FILE OPERATIONS                    
*/
-/******************************************************************************/
-
-void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t 
*gref)
-{
-    void *page;
-
-    page = (void *)alloc_page(); 
-    *gref = gnttab_grant_access(domid, virt_to_mfn(page), 0); 
-    req->private1 = page;
-    req->private2 = (void *)(uintptr_t)(*gref);
-
-    return page;
-}
-
-void free_buffer_page(struct fs_request *req)
-{
-    gnttab_end_access((grant_ref_t)(uintptr_t)req->private2);
-    free_page(req->private1);
-}
-
-static void fsfront_handler(evtchn_port_t port, struct pt_regs *regs, void 
*data)
-{
-    struct fs_import *import = (struct fs_import*)data;
-    static int in_irq = 0;
-    RING_IDX cons, rp;
-    int more;
-
-    /* Check for non-reentrance */
-    BUG_ON(in_irq);
-    in_irq = 1;
-
-    DEBUG("Event from import [%d:%d].\n", import->dom_id, import->export_id);
-moretodo:   
-    rp = import->ring.sring->rsp_prod;
-    rmb(); /* Ensure we see queued responses up to 'rp'. */
-    cons = import->ring.rsp_cons;
-    while (cons != rp)
-    {
-        struct fsif_response *rsp;
-        struct fs_request *req;
-
-        rsp = RING_GET_RESPONSE(&import->ring, cons); 
-        DEBUG("Response at idx=%d to request id=%d, ret_val=%lx\n", 
-            cons, rsp->id, rsp->u.ret_val);
-        req = &import->requests[rsp->id];
-        memcpy(&req->shadow_rsp, rsp, sizeof(struct fsif_response));
-        DEBUG("Waking up: %s\n", req->thread->name);
-        wake(req->thread);
-
-        cons++;
-        up(&import->reqs_sem);
-    }
-
-    import->ring.rsp_cons = rp;
-    RING_FINAL_CHECK_FOR_RESPONSES(&import->ring, more);
-    if(more) goto moretodo;
-    
-    in_irq = 0;
-}
-
-static void alloc_request_table(struct fs_import *import)
-{
-    struct fs_request *requests;
-    int i;
-
-    BUG_ON(import->nr_entries <= 0);
-    printk("Allocating request array for import %d, nr_entries = %d.\n",
-            import->import_id, import->nr_entries);
-    requests = xmalloc_array(struct fs_request, import->nr_entries);
-    import->freelist = xmalloc_array(unsigned short, import->nr_entries + 1);
-    memset(import->freelist, 0, sizeof(unsigned short) * (import->nr_entries + 
1));
-    for(i=0; i<import->nr_entries; i++)
-        add_id_to_freelist(i, import->freelist);
-    import->requests = requests;
-}
-
-
-/******************************************************************************/
-/*                                FS TESTS                                    
*/
-/******************************************************************************/
-
-
-void test_fs_import(void *data)
-{
-    struct fs_import *import = (struct fs_import *)data; 
-    int ret, fd, i, repeat_count;
-    int32_t nr_files;
-    char buffer[1024];
-    ssize_t offset;
-    char **files;
-    long ret64;
-    struct fsif_stat_response stat;
-    
-    repeat_count = 10; 
-    /* Sleep for 1s and then try to open a file */
-    msleep(1000);
-again:
-    ret = fs_create(import, "mini-os-created-directory", 1, 0777);
-    printk("Directory create: %d\n", ret);
-
-    sprintf(buffer, "mini-os-created-directory/mini-os-created-file-%d", 
-            repeat_count);
-    ret = fs_create(import, buffer, 0, 0666);
-    printk("File create: %d\n", ret);
-
-    fd = fs_open(import, buffer);
-    printk("File descriptor: %d\n", fd);
-    if(fd < 0) return;
-
-    offset = 0;
-    for(i=0; i<10; i++)
-    {
-        sprintf(buffer, "Current time is: %lld\n", NOW());
-        ret = fs_write(import, fd, buffer, strlen(buffer), offset);
-        printk("Writen current time (%d)\n", ret);
-        if(ret < 0)
-            return;
-        offset += ret;
-    }
-    ret = fs_stat(import, fd, &stat);
-    printk("Ret after stat: %d\n", ret);
-    printk(" st_mode=%o\n", stat.stat_mode);
-    printk(" st_uid =%d\n", stat.stat_uid);
-    printk(" st_gid =%d\n", stat.stat_gid);
-    printk(" st_size=%ld\n", stat.stat_size);
-    printk(" st_atime=%ld\n", stat.stat_atime);
-    printk(" st_mtime=%ld\n", stat.stat_mtime);
-    printk(" st_ctime=%ld\n", stat.stat_ctime);
- 
-    ret = fs_close(import, fd);
-    printk("Closed fd: %d, ret=%d\n", fd, ret);
-   
-    printk("Listing files in /\n");
-    files = fs_list(import, "/", 0, &nr_files, NULL); 
-    for(i=0; i<nr_files; i++)
-        printk(" files[%d] = %s\n", i, files[i]);
-
-    ret64 = fs_space(import, "/");
-    printk("Free space: %lld (=%lld Mb)\n", ret64, (ret64 >> 20));
-    repeat_count--;
-    if(repeat_count > 0)
-        goto again;
-    
-}
-
-#if 0
-//    char *content = (char *)alloc_page();
-    int fd, ret;
-//    int read;
-    char write_string[] = "\"test data written from minios\"";
-    struct fsif_stat_response stat;
-    char **files;
-    int32_t nr_files, i;
-    int64_t ret64;
-
-
-    fd = fs_open(import, "test-export-file");
-//    read = fs_read(import, fd, content, PAGE_SIZE, 0);
-//    printk("Read: %d bytes\n", read); 
-//    content[read] = '\0';
-//    printk("Value: %s\n", content);
-    ret = fs_write(import, fd, write_string, strlen(write_string), 0);
-    printk("Ret after write: %d\n", ret);
-    ret = fs_stat(import, fd, &stat);
-    printk("Ret after stat: %d\n", ret);
-    printk(" st_mode=%o\n", stat.stat_mode);
-    printk(" st_uid =%d\n", stat.stat_uid);
-    printk(" st_gid =%d\n", stat.stat_gid);
-    printk(" st_size=%ld\n", stat.stat_size);
-    printk(" st_atime=%ld\n", stat.stat_atime);
-    printk(" st_mtime=%ld\n", stat.stat_mtime);
-    printk(" st_ctime=%ld\n", stat.stat_ctime);
-    ret = fs_truncate(import, fd, 30);
-    printk("Ret after truncate: %d\n", ret);
-    ret = fs_remove(import, "test-to-remove/test-file");
-    printk("Ret after remove: %d\n", ret);
-    ret = fs_remove(import, "test-to-remove");
-    printk("Ret after remove: %d\n", ret);
-    ret = fs_chmod(import, fd, 0700);
-    printk("Ret after chmod: %d\n", ret);
-    ret = fs_sync(import, fd);
-    printk("Ret after sync: %d\n", ret);
-    ret = fs_close(import, fd);
-    //ret = fs_rename(import, "test-export-file", "renamed-test-export-file");
-    //printk("Ret after rename: %d\n", ret);
-    ret = fs_create(import, "created-dir", 1, 0777);
-    printk("Ret after dir create: %d\n", ret);
-    ret = fs_create(import, "created-dir/created-file", 0, 0777);
-    printk("Ret after file create: %d\n", ret);
-    files = fs_list(import, "/", 15, &nr_files, NULL); 
-    for(i=0; i<nr_files; i++)
-        printk(" files[%d] = %s\n", i, files[i]);
-    ret64 = fs_space(import, "created-dir");
-    printk("Ret after space: %lld\n", ret64);
-
-#endif
-
-
-/******************************************************************************/
-/*                            END OF FS TESTS                                 
*/
-/******************************************************************************/
-
-static int init_fs_import(struct fs_import *import)
-{    
-    char *err;
-    xenbus_transaction_t xbt;
-    char nodename[1024], r_nodename[1024], token[128], *message = NULL;
-    struct fsif_sring *sring;
-    int i, retry = 0;
-    domid_t self_id;
-    xenbus_event_queue events = NULL;
-
-    printk("Initialising FS fortend to backend dom %d\n", import->dom_id);
-    /* Allocate page for the shared ring */
-    sring = (struct fsif_sring*) alloc_pages(FSIF_RING_SIZE_ORDER);
-    memset(sring, 0, PAGE_SIZE * FSIF_RING_SIZE_PAGES);
-
-    /* Init the shared ring */
-    SHARED_RING_INIT(sring);
-    ASSERT(FSIF_NR_READ_GNTS == FSIF_NR_WRITE_GNTS);
-
-    /* Init private frontend ring */
-    FRONT_RING_INIT(&import->ring, sring, PAGE_SIZE * FSIF_RING_SIZE_PAGES);
-    import->nr_entries = import->ring.nr_ents;
-
-    /* Allocate table of requests */
-    alloc_request_table(import);
-    init_SEMAPHORE(&import->reqs_sem, import->nr_entries);
-
-    /* Grant access to the shared ring */
-    for(i=0; i<FSIF_RING_SIZE_PAGES; i++) 
-        import->gnt_refs[i] = 
-            gnttab_grant_access(import->dom_id, 
-                                virt_to_mfn((char *)sring + i * PAGE_SIZE), 
-                                0);
-   
-    /* Allocate event channel */ 
-    BUG_ON(evtchn_alloc_unbound(import->dom_id, 
-                                fsfront_handler, 
-                                //ANY_CPU, 
-                                import, 
-                                &import->local_port));
-    unmask_evtchn(import->local_port);
-
-    
-    self_id = xenbus_get_self_id(); 
-    /* Write the frontend info to a node in our Xenbus */
-    sprintf(nodename, "/local/domain/%d/device/vfs/%d", 
-                        self_id, import->import_id);
-
-again:    
-    err = xenbus_transaction_start(&xbt);
-    if (err) {
-        printk("starting transaction\n");
-        free(err);
-    }
-    
-    err = xenbus_printf(xbt, 
-                        nodename, 
-                        "ring-size",
-                        "%u",
-                        FSIF_RING_SIZE_PAGES);
-    if (err) {
-        message = "writing ring-size";
-        goto abort_transaction;
-    }
-    
-    for(i=0; i<FSIF_RING_SIZE_PAGES; i++)
-    {
-        sprintf(r_nodename, "ring-ref-%d", i);
-        err = xenbus_printf(xbt, 
-                            nodename, 
-                            r_nodename,
-                            "%u",
-                            import->gnt_refs[i]);
-        if (err) {
-            message = "writing ring-refs";
-            goto abort_transaction;
-        }
-    }
-
-    err = xenbus_printf(xbt, 
-                        nodename,
-                        "event-channel", 
-                        "%u", 
-                        import->local_port);
-    if (err) {
-        message = "writing event-channel";
-        goto abort_transaction;
-    }
-
-    err = xenbus_printf(xbt, nodename, "state", STATE_READY, 0xdeadbeef);
-    if (err) free(err);
-
-    err = xenbus_transaction_end(xbt, 0, &retry);
-    if (err) free(err);
-    if (retry) {
-            goto again;
-        printk("completing transaction\n");
-    }
-
-    /* Now, when our node is prepared we write request in the exporting domain
-     * */
-    printk("Our own id is %d\n", self_id);
-    sprintf(r_nodename, 
-            "/local/domain/%d/backend/vfs/exports/requests/%d/%d/frontend", 
-            import->dom_id, self_id, import->export_id);
-    BUG_ON(xenbus_write(XBT_NIL, r_nodename, nodename));
-
-    goto done;
-
-abort_transaction:
-    free(err);
-    err = xenbus_transaction_end(xbt, 1, &retry);
-    if (err) free(err);
-
-done:
-
-#define WAIT_PERIOD 10   /* Wait period in ms */    
-#define MAX_WAIT    10   /* Max number of WAIT_PERIODs */
-    import->backend = NULL;
-    sprintf(r_nodename, "%s/backend", nodename);
-   
-    for(retry = MAX_WAIT; retry > 0; retry--)
-    { 
-        xenbus_read(XBT_NIL, r_nodename, &import->backend);
-        if(import->backend)
-        {
-            printk("Backend found at %s\n", import->backend);
-            break;
-        }
-       msleep(WAIT_PERIOD);
-    }        
-    
-    if(!import->backend)
-    {
-        printk("No backend available.\n");
-        /* TODO - cleanup datastructures/xenbus */
-        return 0;
-    }
-    sprintf(r_nodename, "%s/state", import->backend);
-    sprintf(token, "fs-front-%d", import->import_id);
-    /* The token will not be unique if multiple imports are inited */
-    xenbus_watch_path_token(XBT_NIL, r_nodename, r_nodename, &events);
-    err = xenbus_wait_for_value(r_nodename, STATE_READY, &events);
-    if (err) free(err);
-    xenbus_unwatch_path_token(XBT_NIL, r_nodename, r_nodename);
-    printk("Backend ready.\n");
-   
-    //create_thread("fs-tester", test_fs_import, import); 
-
-    return 1;
-}
-
-static void add_export(struct minios_list_head *exports, unsigned int domid)
-{
-    char node[1024], **exports_list = NULL, *ret_msg;
-    int j = 0;
-    static int import_id = 0;
-
-    sprintf(node, "/local/domain/%d/backend/vfs/exports", domid);
-    ret_msg = xenbus_ls(XBT_NIL, node, &exports_list);
-    if (ret_msg && strcmp(ret_msg, "ENOENT"))
-        printk("couldn't read %s: %s\n", node, ret_msg);
-    while(exports_list && exports_list[j])
-    {
-        struct fs_import *import; 
-        int export_id = -1;
-        
-        sscanf(exports_list[j], "%d", &export_id);
-        if(export_id >= 0)
-        {
-            import = xmalloc(struct fs_import);
-            import->dom_id = domid;
-            import->export_id = export_id;
-            import->import_id = import_id++;
-            MINIOS_INIT_LIST_HEAD(&import->list);
-            minios_list_add(&import->list, exports);
-        }
-        free(exports_list[j]);
-        j++;
-    }
-    if(exports_list)
-        free(exports_list);
-    if(ret_msg)
-        free(ret_msg);
-}
-
-#if 0
-static struct minios_list_head* probe_exports(void)
-{
-    struct minios_list_head *exports;
-    char **node_list = NULL, *msg = NULL;
-    int i = 0;
-
-    exports = xmalloc(struct minios_list_head);
-    MINIOS_INIT_LIST_HEAD(exports);
-    
-    msg = xenbus_ls(XBT_NIL, "/local/domain", &node_list);
-    if(msg)
-    {
-        printk("Could not list VFS exports (%s).\n", msg);
-        goto exit;
-    }
-
-    while(node_list[i])
-    {
-        add_export(exports, atoi(node_list[i]));
-        free(node_list[i]);
-        i++;
-    } 
-
-exit:    
-    if(msg)
-        free(msg);
-    if(node_list)
-        free(node_list);
-    return exports;
-}
-#endif
-
-MINIOS_LIST_HEAD(exports);
-
-void init_fs_frontend(void)
-{
-    struct minios_list_head *entry;
-    struct fs_import *import = NULL;
-    printk("Initing FS frontend(s).\n");
-
-    add_export(&exports, 0);
-    minios_list_for_each(entry, &exports)
-    {
-        import = minios_list_entry(entry, struct fs_import, list);
-        printk("FS export [dom=%d, id=%d] found\n", 
-                import->dom_id, import->export_id);
-        if (init_fs_import(import) != 0) {
-            fs_import = import;
-            break;
-        }
-    }
-
-    if (!fs_import)
-       printk("No FS import\n");
-}
-
-/* TODO: shutdown */
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/include/fbfront.h
--- a/extras/mini-os/include/fbfront.h  Tue Jan 11 19:31:41 2011 +0000
+++ b/extras/mini-os/include/fbfront.h  Tue Jan 11 19:41:53 2011 +0000
@@ -1,5 +1,6 @@
 #include <xen/io/kbdif.h>
 #include <xen/io/fbif.h>
+#include <mini-os/semaphore.h>
 #include <mini-os/wait.h>
 
 /* from <linux/input.h> */
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/include/fs.h
--- a/extras/mini-os/include/fs.h       Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#ifndef __FS_H__
-#define __FS_H__
-
-#include <xen/io/fsif.h>
-#include <mini-os/semaphore.h>
-#include <mini-os/types.h>
-
-#define FSIF_RING_SIZE_ORDER   1
-#define FSIF_RING_SIZE_PAGES   (1<<FSIF_RING_SIZE_ORDER)
-
-struct fs_import 
-{
-    domid_t dom_id;                 /* dom id of the exporting domain       */ 
-    uint16_t export_id;             /* export id (exporting dom specific)   */
-    uint16_t import_id;             /* import id (specific to this domain)  */ 
-    struct minios_list_head list;   /* list of all imports                  */
-    unsigned int nr_entries;        /* Number of entries in rings & request
-                                       array                                */
-    struct fsif_front_ring ring;    /* frontend ring (contains shared ring) */
-    uint32_t gnt_refs[FSIF_RING_SIZE_PAGES];  /* grant references to the 
shared ring  */
-    evtchn_port_t local_port;       /* local event channel port             */
-    char *backend;                  /* XenBus location of the backend       */
-    struct fs_request *requests;    /* Table of requests                    */
-    unsigned short *freelist;       /* List of free request ids             */
-    struct semaphore reqs_sem;      /* Accounts requests resource           */
-};
-
-extern struct fs_import *fs_import;
-
-void init_fs_frontend(void);
-
-int fs_open(struct fs_import *import, char *file);
-int fs_close(struct fs_import *import, int fd);
-ssize_t fs_read(struct fs_import *import, int fd, void *buf, 
-                ssize_t len, ssize_t offset);
-ssize_t fs_write(struct fs_import *import, int fd, void *buf, 
-                 ssize_t len, ssize_t offset);
-int fs_stat(struct fs_import *import, 
-            int fd, 
-            struct fsif_stat_response *stat);
-int fs_truncate(struct fs_import *import, 
-                int fd, 
-                int64_t length);
-int fs_remove(struct fs_import *import, char *file);
-int fs_rename(struct fs_import *import, 
-              char *old_file_name, 
-              char *new_file_name);
-int fs_create(struct fs_import *import, char *name, 
-              int8_t directory, int32_t mode);
-char** fs_list(struct fs_import *import, char *name, 
-               int32_t offset, int32_t *nr_files, int *has_more);
-int fs_chmod(struct fs_import *import, int fd, int32_t mode);
-int64_t fs_space(struct fs_import *import, char *location);
-int fs_sync(struct fs_import *import, int fd);
-
-#endif
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Tue Jan 11 19:31:41 2011 +0000
+++ b/extras/mini-os/kernel.c   Tue Jan 11 19:41:53 2011 +0000
@@ -41,7 +41,6 @@
 #include <mini-os/blkfront.h>
 #include <mini-os/fbfront.h>
 #include <mini-os/pcifront.h>
-#include <mini-os/fs.h>
 #include <mini-os/xmalloc.h>
 #include <fcntl.h>
 #include <xen/features.h>
@@ -456,11 +455,6 @@ static void pcifront_thread(void *p)
     pcifront_scan(pci_dev, print_pcidev);
 }
 
-static void fs_thread(void *p)
-{
-    init_fs_frontend();
-}
-
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) int app_main(start_info_t *si)
 {
@@ -472,7 +466,6 @@ __attribute__((weak)) int app_main(start
     create_thread("fbfront", fbfront_thread, si);
     create_thread("kbdfront", kbdfront_thread, si);
     create_thread("pcifront", pcifront_thread, si);
-    create_thread("fs-frontend", fs_thread, si);
     return 0;
 }
 
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/lib/math.c
--- a/extras/mini-os/lib/math.c Tue Jan 11 19:31:41 2011 +0000
+++ b/extras/mini-os/lib/math.c Tue Jan 11 19:41:53 2011 +0000
@@ -70,8 +70,8 @@ union uu {
 union uu {
         int64_t           q;              /* as a (signed) quad */
         int64_t          uq;             /* as an unsigned quad */
-        long           sl[2];          /* as two signed longs */
-        unsigned long  ul[2];          /* as two unsigned longs */
+        int32_t        sl[2];          /* as two signed ints */
+        uint32_t       ul[2];          /* as two unsigned ints */
 };
 /* XXX RN: Yuck hardcoded endianess :) */
 #define _QUAD_HIGHWORD 1
@@ -91,17 +91,17 @@ union uu {
 #define CHAR_BIT        8               /* number of bits in a char */
 #endif
 #define QUAD_BITS       (sizeof(int64_t) * CHAR_BIT)
-#define LONG_BITS       (sizeof(long) * CHAR_BIT)
-#define HALF_BITS       (sizeof(long) * CHAR_BIT / 2)
-
-/*
- * Extract high and low shortwords from longword, and move low shortword of
- * longword to upper half of long, i.e., produce the upper longword of
- * ((quad_t)(x) << (number_of_bits_in_long/2)).  (`x' must actually be u_long.)
- *
- * These are used in the multiply code, to split a longword into upper
+#define LONG_BITS       (sizeof(int32_t) * CHAR_BIT)
+#define HALF_BITS       (sizeof(int32_t) * CHAR_BIT / 2)
+
+/*
+ * Extract high and low shortwords from intword, and move low shortword of
+ * intword to upper half of int32_t, i.e., produce the upper intword of
+ * ((quad_t)(x) << (number_of_bits_in_int/2)).  (`x' must actually be 
uint32_t.)
+ *
+ * These are used in the multiply code, to split a intword into upper
  * and lower halves, and to reassemble a product as a quad_t, shifted left
- * (sizeof(long)*CHAR_BIT/2).
+ * (sizeof(int32_t)*CHAR_BIT/2).
  */
 #define HHALF(x)        ((x) >> HALF_BITS)
 #define LHALF(x)        ((x) & ((1UL << HALF_BITS) - 1))
@@ -114,14 +114,10 @@ union uu {
 #define        B       (1UL << HALF_BITS)      /* digit base */
 
 /* Combine two `digits' to make a single two-digit number. */
-#define        COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
-
-/* select a type for digits in base B: use unsigned short if they fit */
-#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
-typedef unsigned short digit;
-#else
-typedef u_long digit;
-#endif
+#define        COMBINE(a, b) (((uint32_t)(a) << HALF_BITS) | (b))
+
+/* select a type for digits in base B: */
+typedef uint16_t digit;
 
 
 /*
@@ -143,7 +139,7 @@ shl(register digit *p, register int len,
  * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
  *
  * We do this in base 2-sup-HALF_BITS, so that all intermediate products
- * fit within u_long.  As a consequence, the maximum length dividend and
+ * fit within uint32_t.  As a consequence, the maximum length dividend and
  * divisor are 4 `digits' in this base (they are shorter if they have
  * leading zeros).
  */
@@ -153,7 +149,7 @@ __qdivrem(uint64_t uq, uint64_t vq, uint
        union uu tmp;
        digit *u, *v, *q;
        register digit v1, v2;
-       u_long qhat, rhat, t;
+       uint32_t qhat, rhat, t;
        int m, n, d, j, i;
        digit uspace[5], vspace[5], qspace[5];
 
@@ -204,7 +200,7 @@ __qdivrem(uint64_t uq, uint64_t vq, uint
        v[4] = LHALF(tmp.ul[L]);
        for (n = 4; v[1] == 0; v++) {
                if (--n == 1) {
-                       u_long rbj;     /* r*B+u[j] (not root boy jim) */
+                       uint32_t rbj;   /* r*B+u[j] (not root boy jim) */
                        digit q1, q2, q3, q4;
 
                        /*
@@ -280,7 +276,7 @@ __qdivrem(uint64_t uq, uint64_t vq, uint
                        rhat = uj1;
                        goto qhat_too_big;
                } else {
-                       u_long nn = COMBINE(uj0, uj1);
+                       uint32_t nn = COMBINE(uj0, uj1);
                        qhat = nn / v1;
                        rhat = nn % v1;
                }
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c  Tue Jan 11 19:31:41 2011 +0000
+++ b/extras/mini-os/lib/sys.c  Tue Jan 11 19:41:53 2011 +0000
@@ -47,7 +47,6 @@
 #ifdef HAVE_LWIP
 #include <lwip/sockets.h>
 #endif
-#include <fs.h>
 
 #define debug(fmt, ...) \
 
@@ -158,13 +157,8 @@ char *getcwd(char *buf, size_t size)
 
 int mkdir(const char *pathname, mode_t mode)
 {
-    int ret;
-    ret = fs_create(fs_import, (char *) pathname, 1, mode);
-    if (ret < 0) {
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    errno = EIO;
+    return -1;
 }
 
 int posix_openpt(int flags)
@@ -183,7 +177,7 @@ int posix_openpt(int flags)
 
 int open(const char *pathname, int flags, ...)
 {
-    int fs_fd, fd;
+    int fd;
     /* Ugly, but fine.  */
     if (!strncmp(pathname,LOG_PATH,strlen(LOG_PATH))) {
        fd = alloc_fd(FTYPE_CONSOLE);
@@ -197,34 +191,8 @@ int open(const char *pathname, int flags
     }
     if (!strncmp(pathname, "/dev/ptmx", strlen("/dev/ptmx")))
         return posix_openpt(flags);
-    printk("open(%s, %x)", pathname, flags);
-    switch (flags & ~O_ACCMODE) {
-        case 0:
-            fs_fd = fs_open(fs_import, (void *) pathname);
-            break;
-        case O_CREAT|O_TRUNC:
-        {
-            va_list ap;
-            mode_t mode;
-            va_start(ap, flags);
-            mode = va_arg(ap, mode_t);
-            va_end(ap);
-            fs_fd = fs_create(fs_import, (void *) pathname, 0, mode);
-            break;
-        }
-        default:
-            printk(" unsupported flags\n");
-            do_exit();
-    }
-    if (fs_fd < 0) {
-       errno = EIO;
-       return -1;
-    }
-    fd = alloc_fd(FTYPE_FILE);
-    printk("-> %d\n", fd);
-    files[fd].file.fd = fs_fd;
-    files[fd].file.offset = 0;
-    return fd;
+    errno = EIO;
+    return -1;
 }
 
 int isatty(int fd)
@@ -248,20 +216,6 @@ int read(int fd, void *buf, size_t nbyte
             remove_waiter(w);
             return ret;
         }
-       case FTYPE_FILE: {
-           ssize_t ret;
-           if (nbytes > PAGE_SIZE * FSIF_NR_READ_GNTS)
-               nbytes = PAGE_SIZE * FSIF_NR_READ_GNTS;
-           ret = fs_read(fs_import, files[fd].file.fd, buf, nbytes, 
files[fd].file.offset);
-           if (ret > 0) {
-               files[fd].file.offset += ret;
-               return ret;
-           } else if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
 #ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            return lwip_read(files[fd].socket.fd, buf, nbytes);
@@ -309,20 +263,6 @@ int write(int fd, const void *buf, size_
        case FTYPE_CONSOLE:
            console_print(files[fd].cons.dev, (char *)buf, nbytes);
            return nbytes;
-       case FTYPE_FILE: {
-           ssize_t ret;
-           if (nbytes > PAGE_SIZE * FSIF_NR_WRITE_GNTS)
-               nbytes = PAGE_SIZE * FSIF_NR_WRITE_GNTS;
-           ret = fs_write(fs_import, files[fd].file.fd, (void *) buf, nbytes, 
files[fd].file.offset);
-           if (ret > 0) {
-               files[fd].file.offset += ret;
-               return ret;
-           } else if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
 #ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
@@ -340,48 +280,11 @@ int write(int fd, const void *buf, size_
 
 off_t lseek(int fd, off_t offset, int whence)
 {
-    if (files[fd].type != FTYPE_FILE) {
-       errno = ESPIPE;
-       return (off_t) -1;
-    }
-    switch (whence) {
-       case SEEK_SET:
-           files[fd].file.offset = offset;
-           break;
-       case SEEK_CUR:
-           files[fd].file.offset += offset;
-           break;
-       case SEEK_END: {
-           struct stat st;
-           int ret;
-           ret = fstat(fd, &st);
-           if (ret)
-               return -1;
-           files[fd].file.offset = st.st_size + offset;
-           break;
-       }
-       default:
-           errno = EINVAL;
-           return -1;
-    }
-    return files[fd].file.offset;
+    errno = ESPIPE;
+    return (off_t) -1;
 }
 
 int fsync(int fd) {
-    switch (files[fd].type) {
-       case FTYPE_FILE: {
-           int ret;
-           ret = fs_sync(fs_import, files[fd].file.fd);
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
-       default:
-           break;
-    }
-    printk("fsync(%d): Bad descriptor\n", fd);
     errno = EBADF;
     return -1;
 }
@@ -393,15 +296,6 @@ int close(int fd)
         default:
            files[fd].type = FTYPE_NONE;
            return 0;
-       case FTYPE_FILE: {
-           int ret = fs_close(fs_import, files[fd].file.fd);
-           files[fd].type = FTYPE_NONE;
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
        case FTYPE_XENBUS:
             xs_daemon_close((void*)(intptr_t) fd);
             return 0;
@@ -460,43 +354,10 @@ static void init_stat(struct stat *buf)
     buf->st_blocks = 0;
 }
 
-static void stat_from_fs(struct stat *buf, struct fsif_stat_response *stat)
-{
-    buf->st_mode = stat->stat_mode;
-    buf->st_uid = stat->stat_uid;
-    buf->st_gid = stat->stat_gid;
-    buf->st_size = stat->stat_size;
-    buf->st_atime = stat->stat_atime;
-    buf->st_mtime = stat->stat_mtime;
-    buf->st_ctime = stat->stat_ctime;
-}
-
 int stat(const char *path, struct stat *buf)
 {
-    struct fsif_stat_response stat;
-    int ret;
-    int fs_fd;
-    printk("stat(%s)\n", path);
-    fs_fd = fs_open(fs_import, (char*) path);
-    if (fs_fd < 0) {
-       errno = EIO;
-       ret = -1;
-       goto out;
-    }
-    ret = fs_stat(fs_import, fs_fd, &stat);
-    if (ret < 0) {
-       errno = EIO;
-       ret = -1;
-       goto outfd;
-    }
-    init_stat(buf);
-    stat_from_fs(buf, &stat);
-    ret = 0;
-
-outfd:
-    fs_close(fs_import, fs_fd);
-out:
-    return ret;
+    errno = EIO;
+    return -1;
 }
 
 int fstat(int fd, struct stat *buf)
@@ -514,18 +375,6 @@ int fstat(int fd, struct stat *buf)
            buf->st_ctime = time(NULL);
            return 0;
        }
-       case FTYPE_FILE: {
-           struct fsif_stat_response stat;
-           int ret;
-           ret = fs_stat(fs_import, files[fd].file.fd, &stat);
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           /* The protocol is a bit evasive about this value */
-           stat_from_fs(buf, &stat);
-           return 0;
-       }
        default:
            break;
     }
@@ -537,35 +386,14 @@ int fstat(int fd, struct stat *buf)
 
 int ftruncate(int fd, off_t length)
 {
-    switch (files[fd].type) {
-       case FTYPE_FILE: {
-            int ret;
-            ret = fs_truncate(fs_import, files[fd].file.fd, length);
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
-       default:
-           break;
-    }
-
-    printk("ftruncate(%d): Bad descriptor\n", fd);
     errno = EBADF;
     return -1;
 }
 
 int remove(const char *pathname)
 {
-    int ret;
-    printk("remove(%s)", pathname);
-    ret = fs_remove(fs_import, (char*) pathname);
-    if (ret < 0) {
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    errno = EIO;
+    return -1;
 }
 
 int unlink(const char *pathname)
@@ -618,26 +446,9 @@ DIR *opendir(const char *name)
 
 struct dirent *readdir(DIR *dir)
 {
-    if (dir->curentry >= 0) {
-        free(dir->entries[dir->curentry]);
-        dir->entries[dir->curentry] = NULL;
-    }
-    dir->curentry++;
-    if (dir->curentry >= dir->nbentries) {
-        dir->offset += dir->nbentries;
-        free(dir->entries);
-        dir->curentry = -1;
-        dir->nbentries = 0;
-        if (!dir->has_more)
-            return NULL;
-        dir->entries = fs_list(fs_import, dir->name, dir->offset, 
&dir->nbentries, &dir->has_more);
-        if (!dir->entries || !dir->nbentries)
-            return NULL;
-        dir->curentry = 0;
-    }
-    dir->dirent.d_name = dir->entries[dir->curentry];
-    return &dir->dirent;
+    return NULL;
 } 
+
 int closedir(DIR *dir)
 {
     int i;
@@ -654,7 +465,6 @@ static const char file_types[] = {
 static const char file_types[] = {
     [FTYPE_NONE]       = 'N',
     [FTYPE_CONSOLE]    = 'C',
-    [FTYPE_FILE]       = 'F',
     [FTYPE_XENBUS]     = 'S',
     [FTYPE_XC]         = 'X',
     [FTYPE_EVTCHN]     = 'E',
@@ -753,11 +563,6 @@ static int select_poll(int nfds, fd_set 
            if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, 
exceptfds))
                printk("bogus fd %d in select\n", i);
            /* Fallthrough.  */
-       case FTYPE_FILE:
-           FD_CLR(i, readfds);
-           FD_CLR(i, writefds);
-           FD_CLR(i, exceptfds);
-           break;
        case FTYPE_CONSOLE:
            if (FD_ISSET(i, readfds)) {
                 if (xencons_ring_avail(files[i].cons.dev))
diff -r cb94dbe20f97 -r 548c29920f68 extras/mini-os/main.c
--- a/extras/mini-os/main.c     Tue Jan 11 19:31:41 2011 +0000
+++ b/extras/mini-os/main.c     Tue Jan 11 19:41:53 2011 +0000
@@ -13,7 +13,6 @@
 #include <time.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <fs.h>
 #include <xenbus.h>
 #include <events.h>
 
@@ -66,7 +65,6 @@ static void call_main(void *p)
 #if defined(HAVE_LWIP) && !defined(CONFIG_QEMU)
     start_networking();
 #endif
-    init_fs_frontend();
 #endif
     create_thread("pcifront", pcifront_watches, NULL);
 
diff -r cb94dbe20f97 -r 548c29920f68 stubdom/stubdom-dm
--- a/stubdom/stubdom-dm        Tue Jan 11 19:31:41 2011 +0000
+++ b/stubdom/stubdom-dm        Tue Jan 11 19:41:53 2011 +0000
@@ -91,7 +91,7 @@ trap term SIGHUP
 ############
 # stubdomain
 # Wait for any previous stubdom to terminate
-while xm list | grep $domname-dm
+while xm list | grep -w $domname-dm
 do
        sleep 1
 done
diff -r cb94dbe20f97 -r 548c29920f68 tools/Makefile
--- a/tools/Makefile    Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/Makefile    Tue Jan 11 19:41:53 2011 +0000
@@ -28,8 +28,6 @@ SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
 SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
 SUBDIRS-y += libfsimage
 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
-SUBDIRS-$(CONFIG_Linux) += fs-back
-SUBDIRS-$(CONFIG_NetBSD) += fs-back
 
 # do not recurse in to a dir we are about to delete
 ifneq "$(MAKECMDGOALS)" "distclean"
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/Makefile
--- a/tools/fs-back/Makefile    Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-XEN_ROOT = ../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-INCLUDES += -I.. -I../lib
-
-IBIN         = fs-backend 
-
-CFLAGS   += -Werror
-CFLAGS   += -Wno-unused
-CFLAGS   += -fno-strict-aliasing
-CFLAGS   += $(CFLAGS_libxenctrl)
-CFLAGS   += $(CFLAGS_libxenstore)
-CFLAGS   += $(INCLUDES) -I.
-CFLAGS   += -D_GNU_SOURCE
-
-LIBS      := -L. -L.. -L../lib
-LIBS      += $(LDLIBS_libxenctrl)
-LIBS      += $(LDLIBS_libxenstore)
-LIBS      += -lrt -lpthread
-
-OBJS     := fs-xenbus.o fs-ops.o
-
-all: $(IBIN)
-
-fs-backend: $(OBJS) fs-backend.c
-       $(CC) $(CFLAGS) -o fs-backend $(OBJS) $(LIBS) fs-backend.c
-
-install: all
-       $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(SBINDIR)
-
-clean:
-       rm -rf *.o *~ $(DEPS) xen $(IBIN) $(LIB)
-
-.PHONY: clean install
-
--include $(DEPS)
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/fs-backend.c
--- a/tools/fs-back/fs-backend.c        Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,500 +0,0 @@
-#undef NDEBUG
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <malloc.h>
-#include <xenctrl.h>
-#include <aio.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <xen/io/ring.h>
-#include <xc_private.h>
-#include <err.h>
-#include "sys-queue.h"
-#include "fs-backend.h"
-#include "fs-debug.h"
-
-struct xs_handle *xsh = NULL;
-static struct fs_export *fs_exports = NULL;
-static int export_id = 0;
-static int mount_id = 0;
-static int pipefds[2];
-static LIST_HEAD(mount_requests_head, fs_mount) mount_requests_head;
-
-static void free_mount_request(struct fs_mount *mount);
-
-static void dispatch_response(struct fs_request *request)
-{
-    int i;
-    struct fs_op *op;
-
-    for(i=0;;i++)
-    {
-        op = fsops[i];
-        /* We should dispatch a response before reaching the end of the array 
*/
-        assert(op != NULL);
-        if(op->type == request->req_shadow.type)
-        {
-            FS_DEBUG("Found op for type=%d\n", op->type);
-            /* There needs to be a response handler */
-            assert(op->response_handler != NULL);
-            op->response_handler(request->mount, request);
-            break;
-        }
-    }
-
-    request->active = 0;
-    add_id_to_freelist(request->id, request->mount->freelist);
-}
-
-static void handle_aio_event(struct fs_request *request)
-{
-    int ret, notify;
-
-    FS_DEBUG("handle_aio_event: mount %s request %d\n", 
request->mount->frontend, request->id);
-    if (request->active < 0) {
-        request->mount->nr_entries++;
-        if (!request->mount->nr_entries)
-            free_mount_request(request->mount);
-        return;
-    }
-
-    ret = aio_error(&request->aiocb);
-    if(ret != EINPROGRESS && ret != ECANCELED)
-        dispatch_response(request);
-
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&request->mount->ring, notify);
-    FS_DEBUG("Pushed responces and notify=%d\n", notify);
-    if(notify)
-        xc_evtchn_notify(request->mount->evth, request->mount->local_evtchn);
-}
-
-static void allocate_request_array(struct fs_mount *mount)
-{
-    int i, nr_entries = mount->nr_entries;
-    struct fs_request *requests;
-    unsigned short *freelist;
-    
-    requests = malloc(sizeof(struct fs_request) *nr_entries);
-    freelist = malloc(sizeof(unsigned short) * (nr_entries + 1)); 
-    memset(requests, 0, sizeof(struct fs_request) * nr_entries);
-    memset(freelist, 0, sizeof(unsigned short) * (nr_entries + 1));
-    for(i=0; i< nr_entries; i++)
-    {
-        requests[i].active = 0; 
-        requests[i].mount = mount; 
-        add_id_to_freelist(i, freelist);
-    }
-    mount->requests = requests;
-    mount->freelist = freelist;
-}
-
-
-static void handle_mount(struct fs_mount *mount)
-{
-    int more, notify;
-    int nr_consumed=0;
-    RING_IDX cons, rp;
-    struct fsif_request *req;
-
-moretodo:
-    rp = mount->ring.sring->req_prod;
-    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
-
-    while ((cons = mount->ring.req_cons) != rp)
-    {
-        int i;
-        struct fs_op *op;
-
-        FS_DEBUG("Got a request at %d (of %d)\n", 
-                cons, RING_SIZE(&mount->ring));
-        req = RING_GET_REQUEST(&mount->ring, cons);
-        FS_DEBUG("Request type=%d\n", req->type); 
-        for(i=0;;i++)
-        {
-            op = fsops[i];
-            if(op == NULL)
-            {
-                /* We've reached the end of the array, no appropirate
-                 * handler found. Warn, ignore and continue. */
-                FS_DEBUG("WARN: Unknown request type: %d\n", req->type);
-                mount->ring.req_cons++; 
-                break;
-            }
-            if(op->type == req->type)
-            {
-                /* There needs to be a dispatch handler */
-                assert(op->dispatch_handler != NULL);
-                op->dispatch_handler(mount, req);
-                break;
-            }
-        }
-
-        nr_consumed++;
-    }
-    FS_DEBUG("Backend consumed: %d requests\n", nr_consumed);
-    RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more);
-    if(more) goto moretodo;
-
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify);
-    FS_DEBUG("Pushed responces and notify=%d\n", notify);
-    if(notify)
-        xc_evtchn_notify(mount->evth, mount->local_evtchn);
-}
-
-void terminate_mount_request(struct fs_mount *mount)
-{
-    int count = 0, i;
-
-    FS_DEBUG("terminate_mount_request %s\n", mount->frontend);
-    xenbus_write_backend_state(mount, STATE_CLOSING);
-
-    for(i=0; i<mount->nr_entries; i++)
-        if(mount->requests[i].active) {
-            mount->requests[i].active = -1;
-            aio_cancel(mount->requests[i].aiocb.aio_fildes, 
&mount->requests[i].aiocb);
-            count--;
-        }
-    mount->nr_entries = count;
-
-    /* wait for the frontend to shut down but don't wait more than 3
-     * seconds */
-    i = 0;
-    while (!xenbus_frontend_state_changed(mount, STATE_CLOSING) && i < 3) {
-        sleep(1);
-        i++;
-    }
-    xenbus_write_backend_state(mount, STATE_CLOSED);
-
-    xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size);
-    xc_gnttab_close(mount->gnth);
-    xc_evtchn_unbind(mount->evth, mount->local_evtchn);
-    xc_evtchn_close(mount->evth);
-
-    if (!count)
-        free_mount_request(mount);
-}
-
-static void free_mount_request(struct fs_mount *mount) {
-    FS_DEBUG("free_mount_request %s\n", mount->frontend);
-    xenbus_free_backend_node(mount);
-    free(mount->frontend);
-    free(mount->requests);
-    free(mount->freelist);
-    LIST_REMOVE (mount, entries);
-    free(mount);
-}
-
-static void handle_connection(int frontend_dom_id, int export_id, char 
*frontend)
-{
-    struct fs_mount *mount;
-    struct fs_export *export;
-    struct fsif_sring *sring = NULL;
-    uint32_t dom_ids[MAX_RING_SIZE];
-    int i;
-
-    FS_DEBUG("Handling connection from dom=%d, for export=%d\n", 
-            frontend_dom_id, export_id);
-    /* Try to find the export on the list */
-    export = fs_exports;
-    while(export)
-    {
-        if(export->export_id == export_id)
-            break;
-        export = export->next;
-    }
-    if(!export)
-    {
-        FS_DEBUG("Could not find the export (the id is unknown).\n");
-        return;
-    }
-
-    mount = (struct fs_mount*)malloc(sizeof(struct fs_mount));
-    memset(mount, 0, sizeof(struct fs_mount));
-    mount->xch = xc_interface_open(0,0,XC_OPENFLAG_DUMMY);
-    if (!mount->xch) goto error;
-
-    mount->dom_id = frontend_dom_id;
-    mount->export = export;
-    mount->mount_id = mount_id++;
-    if (xenbus_read_mount_request(mount, frontend) < 0)
-        goto error;
-    FS_DEBUG("Frontend found at: %s (gref=%d, evtchn=%d)\n", 
-            mount->frontend, mount->grefs[0], mount->remote_evtchn);
-    if (!xenbus_write_backend_node(mount)) {
-        FS_DEBUG("ERROR: failed to write backend node on xenbus\n");
-        goto error;
-    }
-    mount->evth = NULL;
-    mount->evth = xc_evtchn_open(NULL, 0);
-    if (mount->evth == NULL) {
-        FS_DEBUG("ERROR: Couldn't open evtchn!\n");
-        goto error;
-    }
-    mount->local_evtchn = -1;
-    mount->local_evtchn = xc_evtchn_bind_interdomain(mount->evth, 
-                                                     mount->dom_id, 
-                                                     mount->remote_evtchn);
-    if (mount->local_evtchn < 0) {
-        FS_DEBUG("ERROR: Couldn't bind evtchn!\n");
-        goto error;
-    }
-    mount->gnth = NULL;
-    mount->gnth = xc_gnttab_open(NULL, 0);
-    if (mount->gnth == NULL) {
-        FS_DEBUG("ERROR: Couldn't open gnttab!\n");
-        goto error;
-    }
-    for(i=0; i<mount->shared_ring_size; i++)
-        dom_ids[i] = mount->dom_id;
-    sring = xc_gnttab_map_grant_refs(mount->gnth,
-                                     mount->shared_ring_size,
-                                     dom_ids,
-                                     mount->grefs,
-                                     PROT_READ | PROT_WRITE);
-
-    if (!sring) {
-        FS_DEBUG("ERROR: Couldn't amp grant refs!\n");
-        goto error;
-    }
-
-    BACK_RING_INIT(&mount->ring, sring, mount->shared_ring_size * 
XC_PAGE_SIZE);
-    mount->nr_entries = mount->ring.nr_ents; 
-    for (i = 0; i < MAX_FDS; i++)
-        mount->fds[i] = -1;
-
-    LIST_INSERT_HEAD(&mount_requests_head, mount, entries);
-    if (!xenbus_watch_frontend_state(mount)) {
-        FS_DEBUG("ERROR: failed to watch frontend state on xenbus\n");
-        goto error;
-    }
-    if (!xenbus_write_backend_state(mount, STATE_READY)) {
-        FS_DEBUG("ERROR: failed to write backend state to xenbus\n");
-        goto error;
-    }
-
-    allocate_request_array(mount);
-
-    return;
-
-error:
-    xenbus_write_backend_state(mount, STATE_CLOSED);
-    if (sring)
-        xc_gnttab_munmap(mount->gnth, mount->ring.sring, 
mount->shared_ring_size);
-    if (mount->gnth != NULL)
-        xc_gnttab_close(mount->gnth);
-    if (mount->local_evtchn > 0)
-        xc_evtchn_unbind(mount->evth, mount->local_evtchn);
-    if (mount->evth != NULL)
-        xc_evtchn_close(mount->evth);
-    if (mount->xch)
-        xc_interface_close(mount->xch);
-}
-
-static void await_connections(void)
-{
-    int fd, max_fd, ret, dom_id, export_id; 
-    fd_set fds;
-    char **watch_paths;
-    unsigned int len;
-    char d;
-    struct fs_mount *pointer;
-
-    LIST_INIT (&mount_requests_head);
-
-    assert(xsh != NULL);
-    if ((fd = xenbus_get_watch_fd()) == -1)
-           err(1, "xenbus_get_watch_fd: could not setup watch");
-    /* Infinite watch loop */
-    do {
-       FD_ZERO(&fds);
-       FD_SET(fd, &fds);
-       FD_SET(pipefds[0], &fds);
-        max_fd = fd > pipefds[0] ? fd : pipefds[0];
-        LIST_FOREACH(pointer, &mount_requests_head, entries) {
-            int tfd = xc_evtchn_fd(pointer->evth);
-            FD_SET(tfd, &fds);
-            if (tfd > max_fd) max_fd = tfd;
-        }
-        ret = select(max_fd+1, &fds, NULL, NULL, NULL);
-        if (ret < 0) {
-            if (errno == EINTR) continue;
-            /* try to recover */
-            else if (errno == EBADF) {
-                struct timeval timeout;
-                memset(&timeout, 0x00, sizeof(timeout));
-                FD_ZERO(&fds);
-                FD_SET(fd, &fds);
-                FD_SET(pipefds[0], &fds);
-                max_fd = fd > pipefds[0] ? fd : pipefds[0];
-                ret = select(max_fd + 1, &fds, NULL, NULL, &timeout);
-                if (ret < 0)
-                    err(1, "select: unrecoverable error occurred: %d\n", 
errno);
-
-                /* trying to find the bogus fd among the open event channels */
-                LIST_FOREACH(pointer, &mount_requests_head, entries) {
-                    int tfd = xc_evtchn_fd(pointer->evth);
-                    memset(&timeout, 0x00, sizeof(timeout));
-                    FD_ZERO(&fds);
-                    FD_SET(tfd, &fds);
-                    ret = select(tfd + 1, &fds, NULL, NULL, &timeout);
-                    if (ret < 0) {
-                        FS_DEBUG("fd %d is bogus, closing the related 
connection %p\n", tfd, pointer->evth);
-                        /*pointer->evth = fd;*/
-                        terminate_mount_request(pointer);
-                        continue;
-                    }
-                }
-                continue;
-            } else
-                err(1, "select: unrecoverable error occurred: %d\n", errno);
-        }
-        if (FD_ISSET(fd, &fds)) {
-            watch_paths = xs_read_watch(xsh, &len);
-            if (!strcmp(watch_paths[XS_WATCH_TOKEN], "conn-watch")) {
-                dom_id = -1;
-                export_id = -1;
-                d = 0;
-                FS_DEBUG("Path changed %s\n", watch_paths[0]);
-                sscanf(watch_paths[XS_WATCH_PATH], 
WATCH_NODE"/%d/%d/fronten%c", 
-                        &dom_id, &export_id, &d);
-                if((dom_id >= 0) && (export_id >= 0) && d == 'd') {
-                    char *frontend = xs_read(xsh, XBT_NULL, 
watch_paths[XS_WATCH_PATH], NULL);
-                    if (frontend) {
-                        char *p, *wp = strdup(watch_paths[XS_WATCH_PATH]);
-                        handle_connection(dom_id, export_id, frontend);
-                        xs_rm(xsh, XBT_NULL, wp);
-                        p = strrchr(wp, '/');
-                        if (p) {
-                            *p = '\0';
-                            p = strrchr(wp, '/');
-                            if (p) {
-                                *p = '\0';
-                                xs_rm(xsh, XBT_NULL, wp);
-                            }
-                        }
-                        free(wp);
-                    }
-                }
-            } else if (!strcmp(watch_paths[XS_WATCH_TOKEN], "frontend-state")) 
{
-                LIST_FOREACH(pointer, &mount_requests_head, entries) {
-                    if (!strncmp(pointer->frontend, 
watch_paths[XS_WATCH_PATH], strlen(pointer->frontend))) {
-                        char *state = xenbus_read_frontend_state(pointer);
-                        if (!state || strcmp(state, STATE_READY)) {
-                            xenbus_unwatch_frontend_state(pointer);
-                            terminate_mount_request(pointer);
-                        }
-                        free(state);
-                        break;
-                    }
-                }
-            } else {
-                FS_DEBUG("xenstore watch event unrecognized\n");
-            }
-            FS_DEBUG("Awaiting next connection.\n");
-            /* TODO - we need to figure out what to free */
-            free(watch_paths);
-        }
-        if (FD_ISSET(pipefds[0], &fds)) {
-            struct fs_request *request;
-            if (read_exact(pipefds[0], &request, sizeof(struct fs_request *)) 
< 0)
-                err(1, "read request failed\n");
-            handle_aio_event(request); 
-        }
-        LIST_FOREACH(pointer, &mount_requests_head, entries) {
-            if (FD_ISSET(xc_evtchn_fd(pointer->evth), &fds)) {
-                evtchn_port_t port;
-                port = xc_evtchn_pending(pointer->evth);
-                if (port != -1) {
-                    handle_mount(pointer);
-                    xc_evtchn_unmask(pointer->evth, port);
-                }
-            }
-        }
-    } while (1);
-}
-
-static struct fs_export* create_export(char *name, char *export_path)
-{
-    struct fs_export *curr_export, **last_export;
-
-    /* Create export structure */
-    curr_export = (struct fs_export *)malloc(sizeof(struct fs_export));
-    curr_export->name = name;
-    curr_export->export_path = export_path;
-    curr_export->export_id = export_id++;
-    /* Thread it onto the list */
-    curr_export->next = NULL;
-    last_export = &fs_exports;
-    while(*last_export)
-        last_export = &((*last_export)->next);
-    *last_export = curr_export;
-
-    return curr_export;
-}
-
-static void aio_signal_handler(int signo, siginfo_t *info, void *context)
-{
-    struct fs_request *request = (struct fs_request*) info->si_value.sival_ptr;
-    int saved_errno = errno;
-    if (write_exact(pipefds[1], &request, sizeof(struct fs_request *)) < 0)
-        err(1, "write request filed\n");
-    errno = saved_errno;
-}
-
-int main(void)
-{
-    struct fs_export *export;
-    struct sigaction act;
-    sigset_t enable;
-
-    sigemptyset(&enable);
-    sigaddset(&enable, SIGUSR2);
-    pthread_sigmask(SIG_UNBLOCK, &enable, NULL);
-
-    sigfillset(&act.sa_mask);
-    act.sa_flags = SA_SIGINFO; /* do not restart syscalls to interrupt 
select(); use sa_sigaction */
-    act.sa_sigaction = aio_signal_handler;
-    sigaction(SIGUSR2, &act, NULL);
-
-    /* Open the connection to XenStore first */
-    xsh = xs_domain_open();
-    assert(xsh != NULL);
-    xs_rm(xsh, XBT_NULL, ROOT_NODE);
-    /* Create watch node */
-    xenbus_create_request_node();
-    
-    /* Create & register the default export */
-    export = create_export("default", "/var/lib/xen");
-    xenbus_register_export(export);
-
-    if (socketpair(PF_UNIX,SOCK_STREAM, 0, pipefds) == -1)
-        err(1, "failed to create pipe\n");
-
-    await_connections();
-    /* Close the connection to XenStore when we are finished with everything */
-    xs_daemon_close(xsh);
-#if 0
-    xc_interface *xc_handle;
-    char *shared_page;
-    int prot = PROT_READ | PROT_WRITE;
-  
-    xc_handle = xc_gnttab_open();
-    printf("Main fn.\n");
-
-    shared_page = xc_gnttab_map_grant_ref(xc_handle,
-                                           7,
-                                           2047,
-                                           prot);
-    
-    shared_page[20] = '\0';
-    printf("Current content of the page = %s\n", shared_page);
-    sprintf(shared_page, "%s", "Haha dirty page now! Very bad page.");
-    xc_gnttab_munmap(xc_handle, shared_page, 1);
-    xc_gnttab_close(xc_handle);
-    unrelated next line, saved for later convinience    
-    xc_evtchn_notify(mount->evth, mount->local_evtchn);
-#endif
-}
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/fs-backend.h
--- a/tools/fs-back/fs-backend.h        Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-#ifndef __LIB_FS_BACKEND__
-#define __LIB_FS_BACKEND__
-
-#include <aio.h>
-#include <xs.h>
-#include <xen/grant_table.h>
-#include <xen/event_channel.h>
-#include <xen/io/ring.h>
-#include <xen/io/fsif.h>
-#include "sys-queue.h"
-
-#define ROOT_NODE           "backend/vfs"
-#define EXPORTS_SUBNODE     "exports"
-#define EXPORTS_NODE        ROOT_NODE"/"EXPORTS_SUBNODE
-#define WATCH_NODE          EXPORTS_NODE"/requests"
-#define MAX_FDS             16
-#define MAX_RING_SIZE       16
-
-struct fs_export
-{
-    int export_id;
-    char *export_path;
-    char *name;
-    struct fs_export *next; 
-};
-
-struct fs_request
-{
-    struct fs_mount *mount;
-    int id;
-    int active;
-    void *page;                         /* Pointer to mapped grant */
-    int count;
-    struct fsif_request req_shadow;
-    struct aiocb aiocb; 
-};
-
-
-struct fs_mount
-{
-    struct fs_export *export;
-    int dom_id;
-    char *frontend;
-    int mount_id;                     /* = backend id */
-    grant_ref_t grefs[MAX_RING_SIZE];
-    evtchn_port_t remote_evtchn;
-    xc_interface *xch; /* just for error logging, so a dummy */
-    xc_evtchn *evth;               /* Handle to the event channel */
-    evtchn_port_t local_evtchn;
-    xc_gnttab *gnth;
-    int shared_ring_size;             /* in pages */
-    struct fsif_back_ring ring;
-    int nr_entries;
-    struct fs_request *requests;
-    unsigned short *freelist;
-    int fds[MAX_FDS];
-    LIST_ENTRY(fs_mount) entries;
-};
-
-void terminate_mount_request(struct fs_mount *mount);
-
-/* Handle to XenStore driver */
-extern struct xs_handle *xsh;
-
-bool xenbus_create_request_node(void);
-int xenbus_register_export(struct fs_export *export);
-int xenbus_get_watch_fd(void);
-int xenbus_read_mount_request(struct fs_mount *mount, char *frontend);
-bool xenbus_write_backend_node(struct fs_mount *mount);
-bool xenbus_write_backend_state(struct fs_mount *mount, const char *state);
-void xenbus_free_backend_node(struct fs_mount *mount);
-int xenbus_frontend_state_changed(struct fs_mount *mount, const char 
*oldstate);
-bool xenbus_watch_frontend_state(struct fs_mount *mount);
-bool xenbus_unwatch_frontend_state(struct fs_mount *mount);
-char* xenbus_read_frontend_state(struct fs_mount *mount);
-
-/* File operations, implemented in fs-ops.c */
-struct fs_op
-{
-    int type;       /* Type of request (from fsif.h) this handlers 
-                       are responsible for */
-    void (*dispatch_handler)(struct fs_mount *mount, struct fsif_request *req);
-    void (*response_handler)(struct fs_mount *mount, struct fs_request *req);
-};
-
-/* This NULL terminated array of all file requests handlers */
-extern struct fs_op *fsops[];
-
-static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
-{
-    freelist[id + 1] = freelist[0];
-    freelist[0]  = id;
-}
-
-static inline unsigned short get_id_from_freelist(unsigned short* freelist)
-{
-    unsigned int id = freelist[0];
-    freelist[0] = freelist[id + 1];
-    return id;
-}
-
-#endif /* __LIB_FS_BACKEND__ */
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/fs-debug.h
--- a/tools/fs-back/fs-debug.h  Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#ifndef __FS_DEBUG__
-#define __FS_DEBUG__
-
-// #define DEBUG 1
-
-#ifdef DEBUG
-#define FS_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while 
(0)
-#else
-#define FS_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-#endif /*__FS_DEBUG__*/
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/fs-ops.c
--- a/tools/fs-back/fs-ops.c    Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,794 +0,0 @@
-#undef NDEBUG
-#include <stdio.h>
-#include <aio.h>
-#include <string.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <xenctrl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <ctype.h>
-#include "fs-backend.h"
-#include "fs-debug.h"
-
-/* For debugging only */
-#include <sys/time.h>
-#include <time.h>
-
-
-#define BUFFER_SIZE 1024
-
-static int check_export_path(const char *export_path, const char *path)
-{
-    int i;
-    if (!export_path || !path)
-        return -1;
-    if (strlen(path) < strlen(export_path))
-        return -1;
-    if (strstr(path, "..") != NULL)
-        return -1;
-    for (i = 0; i < strlen(path); i++) {
-        if (!isascii(path[i]))
-            return -1;
-    }
-    if (strncmp(export_path, path, strlen(export_path)))
-        return -1;
-    else
-        return 0;
-}
-
-static unsigned short get_request(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    unsigned short id = get_id_from_freelist(mount->freelist); 
-
-    FS_DEBUG("Private Request id: %d\n", id);
-    memcpy(&mount->requests[id].req_shadow, req, sizeof(struct fsif_request));
-    mount->requests[id].active = 1;
-
-    return id;
-}
-
-static int get_fd(struct fs_mount *mount)
-{
-    int i;
-
-    for (i = 0; i < MAX_FDS; i++)
-        if (mount->fds[i] == -1)
-            return i;
-    return -1;
-}
-
-
-static void dispatch_file_open(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    char *file_name;
-    int fd;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching file open operation (gref=%d).\n", 
req->u.fopen.gref);
-    /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fopen.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("File open issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        fd = -1;
-        goto out;
-    }
-    fd = get_fd(mount);
-    if (fd >= 0) {
-        int real_fd = open(file_name, O_RDWR);
-        if (real_fd < 0)
-            fd = -1;
-        else
-        {
-            mount->fds[fd] = real_fd;
-            FS_DEBUG("Got FD: %d for real %d\n", fd, real_fd);
-        }
-    }
-out:
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)fd;
-}
-
-static void dispatch_file_close(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    int ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd);
-   
-    req_id = req->id;
-    if (req->u.fclose.fd < MAX_FDS) {
-        int fd = mount->fds[req->u.fclose.fd];
-        ret = close(fd);
-        mount->fds[req->u.fclose.fd] = -1;
-    } else
-        ret = -1;
-    FS_DEBUG("Got ret: %d\n", ret);
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-#define MAX_GNTS 16
-static void dispatch_file_read(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    void *buf;
-    int fd, count;
-    uint16_t req_id;
-    unsigned short priv_id;
-    struct fs_request *priv_req;
-
-    /* Read the request */
-    assert(req->u.fread.len > 0); 
-    count = (req->u.fread.len - 1) / XC_PAGE_SIZE + 1;
-    assert(count <= FSIF_NR_READ_GNTS);
-    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
-                                          count,
-                                          mount->dom_id,
-                                          req->u.fread.grefs,
-                                          PROT_WRITE);
-   
-    req_id = req->id;
-    FS_DEBUG("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
-            req->u.fread.fd, req->u.fread.len, req->u.fread.offset); 
-
-    if (req->u.fread.fd < MAX_FDS)
-        fd = mount->fds[req->u.fread.fd];
-    else
-        fd = -1;
-
-    priv_id = get_request(mount, req);
-    FS_DEBUG("Private id is: %d\n", priv_id);
-    priv_req = &mount->requests[priv_id];
-    priv_req->page = buf;
-    priv_req->count = count;
-    priv_req->id = priv_id;
-
-    /* Dispatch AIO read request */
-    bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = fd;
-    priv_req->aiocb.aio_nbytes = req->u.fread.len;
-    priv_req->aiocb.aio_offset = req->u.fread.offset;
-    priv_req->aiocb.aio_buf = buf;
-    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
-    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
-    if (aio_read(&priv_req->aiocb) < 0) {
-        FS_DEBUG("ERROR: aio_read failed errno=%d\n", errno);
-        xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count);
-        terminate_mount_request(mount);
-    }
-
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-}
-
-static void end_file_read(struct fs_mount *mount, struct fs_request *priv_req)
-{
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    /* Release the grant */
-    if (xc_gnttab_munmap(mount->gnth,
-                         priv_req->page, priv_req->count) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    req_id = priv_req->req_shadow.id; 
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb);
-}
-
-static void dispatch_file_write(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    void *buf;
-    int fd, count;
-    uint16_t req_id;
-    unsigned short priv_id;
-    struct fs_request *priv_req;
-
-    /* Read the request */
-    assert(req->u.fwrite.len > 0); 
-    count = (req->u.fwrite.len - 1) / XC_PAGE_SIZE + 1;
-    assert(count <= FSIF_NR_WRITE_GNTS);
-    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
-                                          count,
-                                          mount->dom_id,
-                                          req->u.fwrite.grefs,
-                                          PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("File write issued for FD=%d (len=%"PRIu64", 
offest=%"PRIu64")\n", 
-            req->u.fwrite.fd, req->u.fwrite.len, req->u.fwrite.offset); 
-   
-    if (req->u.fwrite.fd < MAX_FDS)
-        fd = mount->fds[req->u.fwrite.fd];
-    else
-        fd = -1;
-
-    priv_id = get_request(mount, req);
-    FS_DEBUG("Private id is: %d\n", priv_id);
-    priv_req = &mount->requests[priv_id];
-    priv_req->page = buf;
-    priv_req->count = count;
-    priv_req->id = priv_id;
-
-    /* Dispatch AIO write request */
-    bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = fd;
-    priv_req->aiocb.aio_nbytes = req->u.fwrite.len;
-    priv_req->aiocb.aio_offset = req->u.fwrite.offset;
-    priv_req->aiocb.aio_buf = buf;
-    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
-    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
-    if (aio_write(&priv_req->aiocb) < 0) {
-        FS_DEBUG("ERROR: aio_write failed errno=%d\n", errno);
-        xc_gnttab_munmap(mount->gnth,
-                         priv_req->page, priv_req->count);
-        terminate_mount_request(mount);
-    }
-
-     
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-}
-
-static void end_file_write(struct fs_mount *mount, struct fs_request *priv_req)
-{
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    /* Release the grant */
-    if (xc_gnttab_munmap(mount->gnth,
-                         priv_req->page, priv_req->count) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    req_id = priv_req->req_shadow.id; 
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb);
-}
-
-static void dispatch_stat(struct fs_mount *mount, struct fsif_request *req)
-{
-    struct stat stat;
-    int fd, ret;
-    uint16_t req_id;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-
-    req_id = req->id;
-    if (req->u.fstat.fd < MAX_FDS)
-        fd = mount->fds[req->u.fstat.fd];
-    else
-        fd = -1;
-
-    FS_DEBUG("File stat issued for FD=%d\n", req->u.fstat.fd); 
-   
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-   
-    /* Stat, and create the response */ 
-    ret = fstat(fd, &stat);
-    FS_DEBUG("Mode=%o, uid=%d, a_time=%ld\n",
-            stat.st_mode, stat.st_uid, (long)stat.st_atime);
-    
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.fstat.stat_ret = (uint32_t)ret;
-    rsp->u.fstat.stat_mode  = stat.st_mode;
-    rsp->u.fstat.stat_uid   = stat.st_uid;
-    rsp->u.fstat.stat_gid   = stat.st_gid;
-#ifdef BLKGETSIZE
-    if (S_ISBLK(stat.st_mode)) {
-       unsigned long sectors;
-       if (ioctl(fd, BLKGETSIZE, &sectors)) {
-           perror("getting device size\n");
-           rsp->u.fstat.stat_size = 0;
-       } else
-           rsp->u.fstat.stat_size = sectors << 9;
-    } else
-#endif
-       rsp->u.fstat.stat_size  = stat.st_size;
-    rsp->u.fstat.stat_atime = stat.st_atime;
-    rsp->u.fstat.stat_mtime = stat.st_mtime;
-    rsp->u.fstat.stat_ctime = stat.st_ctime;
-}
-
-
-static void dispatch_truncate(struct fs_mount *mount, struct fsif_request *req)
-{
-    int fd, ret;
-    uint16_t req_id;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    int64_t length;
-
-    req_id = req->id;
-    length = req->u.ftruncate.length;
-    FS_DEBUG("File truncate issued for FD=%d, length=%"PRId64"\n", 
req->u.ftruncate.fd, length); 
-   
-    if (req->u.ftruncate.fd < MAX_FDS)
-        fd = mount->fds[req->u.ftruncate.fd];
-    else
-        fd = -1;
-
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-   
-    /* Stat, and create the response */ 
-    ret = ftruncate(fd, length);
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_remove(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name;
-    int ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref);
-    /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fremove.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("File remove issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-    } else {
-        ret = remove(file_name);
-    }
-    FS_DEBUG("Got ret: %d\n", ret);
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-
-static void dispatch_rename(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *buf, *old_file_name, *new_file_name;
-    int ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref);
-    /* Read the request, and open file */
-    buf = xc_gnttab_map_grant_ref(mount->gnth,
-                                  mount->dom_id,
-                                  req->u.frename.gref,
-                                  PROT_READ);
-   
-    req_id = req->id;
-    old_file_name = buf + req->u.frename.old_name_offset;
-    new_file_name = buf + req->u.frename.new_name_offset;
-    FS_DEBUG("File rename issued for %s -> %s (buf=%s)\n", 
-            old_file_name, new_file_name, buf); 
-    if (check_export_path(mount->export->export_path, old_file_name) < 0 ||
-        check_export_path(mount->export->export_path, new_file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-    } else {
-        ret = rename(old_file_name, new_file_name);
-    }
-    FS_DEBUG("Got ret: %d\n", ret);
-    if (xc_gnttab_munmap(mount->gnth, buf, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-
-static void dispatch_create(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name;
-    int ret;
-    int8_t directory;
-    int32_t mode;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching file create operation (gref=%d).\n", 
req->u.fcreate.gref);
-    /* Read the request, and create file/directory */
-    mode = req->u.fcreate.mode;
-    directory = req->u.fcreate.directory;
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fcreate.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-        goto out;
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-    if(directory)
-    {
-        FS_DEBUG("Issuing create for directory: %s\n", file_name);
-        ret = mkdir(file_name, mode);
-    }
-    else
-    {
-        FS_DEBUG("Issuing create for file: %s\n", file_name);
-        ret = get_fd(mount);
-        if (ret >= 0) {
-            int real_fd = creat(file_name, mode);
-            if (real_fd < 0)
-                ret = -1;
-            else
-            {
-                mount->fds[ret] = real_fd;
-                FS_DEBUG("Got FD: %d for real %d\n", ret, real_fd);
-            }
-        }
-    }
-out:
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    FS_DEBUG("Got ret %d (errno=%d)\n", ret, errno);
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_list(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name, *buf;
-    uint32_t offset = 0, nr_files = 0, error_code = 0;
-    uint64_t ret_val;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-    DIR *dir;
-    struct dirent *dirent = NULL;
-
-    FS_DEBUG("Dispatching list operation (gref=%d).\n", req->u.flist.gref);
-    /* Read the request, and list directory */
-    offset = req->u.flist.offset;
-    buf = file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.flist.gref,
-                                        PROT_READ | PROT_WRITE);
-   
-    req_id = req->id;
-    FS_DEBUG("Dir list issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        error_code = 1;
-        goto error_out;
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-    ret_val = 0;
-    nr_files = 0;
-    dir = opendir(file_name);
-    if(dir == NULL)
-    {
-        error_code = errno;
-        goto error_out;
-    }
-    /* Skip offset dirs */
-    dirent = readdir(dir);
-    while(offset-- > 0 && dirent != NULL)
-        dirent = readdir(dir);
-    /* If there was any error with reading the directory, errno will be set */
-    error_code = errno;
-    /* Copy file names of the remaining non-NULL dirents into buf */
-    if (NAME_MAX >= XC_PAGE_SIZE >> 1)
-        goto error_out;
-    while(dirent != NULL && 
-            (XC_PAGE_SIZE - ((unsigned long)buf & XC_PAGE_MASK) > NAME_MAX))
-    {
-        int curr_length = strlen(dirent->d_name) + 1;
-        
-        memcpy(buf, dirent->d_name, curr_length);
-        buf += curr_length;
-        dirent = readdir(dir);
-        error_code = errno;
-        nr_files++;
-    }
-error_out:    
-    ret_val = ((nr_files << NR_FILES_SHIFT) & NR_FILES_MASK) | 
-              ((error_code << ERROR_SHIFT) & ERROR_MASK) | 
-              (dirent != NULL ? HAS_MORE_FLAG : 0);
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = ret_val;
-}
-
-static void dispatch_chmod(struct fs_mount *mount, struct fsif_request *req)
-{
-    int fd, ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-    int32_t mode;
-
-    FS_DEBUG("Dispatching file chmod operation (fd=%d, mode=%o).\n", 
-            req->u.fchmod.fd, req->u.fchmod.mode);
-    req_id = req->id;
-    if (req->u.fchmod.fd < MAX_FDS)
-        fd = mount->fds[req->u.fchmod.fd];
-    else
-        fd = -1;
-
-    mode = req->u.fchmod.mode;
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-    ret = fchmod(fd, mode); 
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_fs_space(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-    struct statvfs stat;
-    int64_t ret;
-
-    FS_DEBUG("Dispatching fs space operation (gref=%d).\n", 
req->u.fspace.gref);
-    /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fspace.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("Fs space issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-    } else {
-        ret = statvfs(file_name, &stat);
-    }
-    if(ret >= 0)
-        ret = stat.f_bsize * stat.f_bfree;
-
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_file_sync(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    int fd;
-    uint16_t req_id;
-    unsigned short priv_id;
-    struct fs_request *priv_req;
-
-    req_id = req->id;
-    if (req->u.fsync.fd < MAX_FDS)
-        fd = mount->fds[req->u.fsync.fd];
-    else
-        fd = -1;
-
-    FS_DEBUG("File sync issued for FD=%d\n", req->u.fsync.fd); 
-   
-    priv_id = get_request(mount, req);
-    FS_DEBUG("Private id is: %d\n", priv_id);
-    priv_req = &mount->requests[priv_id];
-    priv_req->id = priv_id;
-
-    /* Dispatch AIO read request */
-    bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = fd;
-    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
-    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
-    if (aio_fsync(O_SYNC, &priv_req->aiocb) < 0) {
-        FS_DEBUG("ERROR: aio_fsync failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-}
-
-static void end_file_sync(struct fs_mount *mount, struct fs_request *priv_req)
-{
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    req_id = priv_req->req_shadow.id; 
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb);
-}
-
-struct fs_op fopen_op     = {.type             = REQ_FILE_OPEN,
-                             .dispatch_handler = dispatch_file_open,
-                             .response_handler = NULL};
-struct fs_op fclose_op    = {.type             = REQ_FILE_CLOSE,
-                             .dispatch_handler = dispatch_file_close,
-                             .response_handler = NULL};
-struct fs_op fread_op     = {.type             = REQ_FILE_READ,
-                             .dispatch_handler = dispatch_file_read,
-                             .response_handler = end_file_read};
-struct fs_op fwrite_op    = {.type             = REQ_FILE_WRITE,
-                             .dispatch_handler = dispatch_file_write,
-                             .response_handler = end_file_write};
-struct fs_op fstat_op     = {.type             = REQ_STAT,
-                             .dispatch_handler = dispatch_stat,
-                             .response_handler = NULL};
-struct fs_op ftruncate_op = {.type             = REQ_FILE_TRUNCATE,
-                             .dispatch_handler = dispatch_truncate,
-                             .response_handler = NULL};
-struct fs_op fremove_op   = {.type             = REQ_REMOVE,
-                             .dispatch_handler = dispatch_remove,
-                             .response_handler = NULL};
-struct fs_op frename_op   = {.type             = REQ_RENAME,
-                             .dispatch_handler = dispatch_rename,
-                             .response_handler = NULL};
-struct fs_op fcreate_op   = {.type             = REQ_CREATE,
-                             .dispatch_handler = dispatch_create,
-                             .response_handler = NULL};
-struct fs_op flist_op     = {.type             = REQ_DIR_LIST,
-                             .dispatch_handler = dispatch_list,
-                             .response_handler = NULL};
-struct fs_op fchmod_op    = {.type             = REQ_CHMOD,
-                             .dispatch_handler = dispatch_chmod,
-                             .response_handler = NULL};
-struct fs_op fspace_op    = {.type             = REQ_FS_SPACE,
-                             .dispatch_handler = dispatch_fs_space,
-                             .response_handler = NULL};
-struct fs_op fsync_op     = {.type             = REQ_FILE_SYNC,
-                             .dispatch_handler = dispatch_file_sync,
-                             .response_handler = end_file_sync};
-
-
-struct fs_op *fsops[] = {&fopen_op, 
-                         &fclose_op, 
-                         &fread_op, 
-                         &fwrite_op, 
-                         &fstat_op, 
-                         &ftruncate_op, 
-                         &fremove_op, 
-                         &frename_op, 
-                         &fcreate_op, 
-                         &flist_op, 
-                         &fchmod_op, 
-                         &fspace_op, 
-                         &fsync_op, 
-                         NULL};
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/fs-xenbus.c
--- a/tools/fs-back/fs-xenbus.c Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-#undef NDEBUG
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/select.h>
-#include <xenctrl.h>
-#include <xs.h>
-#include <xen/io/fsif.h>
-#include "fs-backend.h"
-#include "fs-debug.h"
-
-
-static bool xenbus_printf(struct xs_handle *xsh,
-                          xs_transaction_t xbt,
-                          char* node,
-                          char* path,
-                          char* fmt,
-                          ...)
-{
-    char fullpath[1024];
-    char val[1024];
-    va_list args;
-    
-    va_start(args, fmt);
-    snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path);
-    vsnprintf(val, sizeof(val), fmt, args);
-    va_end(args);
-    FS_DEBUG("xenbus_printf (%s) <= %s.\n", fullpath, val);    
-
-    return xs_write(xsh, xbt, fullpath, val, strlen(val));
-}
-
-bool xenbus_create_request_node(void)
-{
-    bool ret;
-    struct xs_permissions perms;
-    
-    assert(xsh != NULL);
-    xs_rm(xsh, XBT_NULL, WATCH_NODE);
-    ret = xs_mkdir(xsh, XBT_NULL, WATCH_NODE); 
-    if (!ret)
-        return false;
-
-    perms.id = 0;
-    perms.perms = XS_PERM_WRITE;
-    ret = xs_set_permissions(xsh, XBT_NULL, WATCH_NODE, &perms, 1);
-
-    return ret;
-}
-
-int xenbus_register_export(struct fs_export *export)
-{
-    xs_transaction_t xst = 0;
-    char node[1024];
-    struct xs_permissions perms;
-
-    assert(xsh != NULL);
-    if(xsh == NULL)
-    {
-        FS_DEBUG("Could not open connection to xenbus deamon.\n");
-        goto error_exit;
-    }
-    FS_DEBUG("Connection to the xenbus deamon opened successfully.\n");
-
-    /* Start transaction */
-    xst = xs_transaction_start(xsh);
-    if(xst == 0)
-    {
-        FS_DEBUG("Could not start a transaction.\n");
-        goto error_exit;
-    }
-    FS_DEBUG("XS transaction is %d\n", xst); 
- 
-    /* Create node string */
-    snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 
-    /* Remove old export (if exists) */ 
-    xs_rm(xsh, xst, node);
-
-    if(!xenbus_printf(xsh, xst, node, "name", "%s", export->name))
-    {
-        FS_DEBUG("Could not write the export node.\n");
-        goto error_exit;
-    }
-
-    /* People need to be able to read our export */
-    perms.id = 0;
-    perms.perms = XS_PERM_READ;
-    if(!xs_set_permissions(xsh, xst, EXPORTS_NODE, &perms, 1))
-    {
-        FS_DEBUG("Could not set permissions on the export node.\n");
-        goto error_exit;
-    }
-
-    xs_transaction_end(xsh, xst, 0);
-    return 0; 
-
-error_exit:    
-    if(xst != 0)
-        xs_transaction_end(xsh, xst, 1);
-    return -1;
-}
-
-int xenbus_get_watch_fd(void)
-{
-    int res;
-#if DEBUG
-    int errno_orig;
-#endif
-    assert(xsh != NULL);
-    res = xs_watch(xsh, WATCH_NODE, "conn-watch");
-    if (!res) {
-#if DEBUG
-       errno_orig = errno;
-        FS_DEBUG("ERROR: xs_watch %s failed ret=%d errno=%d\n",
-                 WATCH_NODE, res, errno);
-       errno = errno_orig;
-#endif
-        return -1;
-    }
-    return xs_fileno(xsh); 
-}
-
-int xenbus_read_mount_request(struct fs_mount *mount, char *frontend)
-{
-    char node[1024];
-    char *s;
-    int i;
-
-    assert(xsh != NULL);
-#if 0
-    snprintf(node, sizeof(node), WATCH_NODE"/%d/%d/frontend", 
-                           mount->dom_id, mount->export->export_id);
-    frontend = xs_read(xsh, XBT_NULL, node, NULL);
-#endif
-    mount->frontend = frontend;
-    snprintf(node, sizeof(node), "%s/state", frontend);
-    s = xs_read(xsh, XBT_NULL, node, NULL);
-    if (strcmp(s, STATE_READY) != 0) {
-        FS_DEBUG("ERROR: frontend not read\n");
-        goto error;
-    }
-    free(s);
-    snprintf(node, sizeof(node), "%s/ring-size", frontend);
-    s = xs_read(xsh, XBT_NULL, node, NULL);
-    mount->shared_ring_size = atoi(s);
-    if (mount->shared_ring_size > MAX_RING_SIZE) {
-        FS_DEBUG("ERROR: shared_ring_size (%d) > MAX_RING_SIZE\n", 
mount->shared_ring_size);
-        goto error;
-    }
-    free(s);
-    for(i=0; i<mount->shared_ring_size; i++)
-    {
-        snprintf(node, sizeof(node), "%s/ring-ref-%d", frontend, i);
-        s = xs_read(xsh, XBT_NULL, node, NULL);
-        mount->grefs[i] = atoi(s);
-        free(s);
-    }
-    snprintf(node, sizeof(node), "%s/event-channel", frontend);
-    s = xs_read(xsh, XBT_NULL, node, NULL);
-    mount->remote_evtchn = atoi(s);
-    free(s);
-    return 0;
-
-error:
-    free(s);
-    return -1;
-}
-
-/* Small utility function to figure out our domain id */
-static int get_self_id(void)
-{
-    char *dom_id;
-    int ret; 
-                
-    assert(xsh != NULL);
-    dom_id = xs_read(xsh, XBT_NULL, "domid", NULL);
-    sscanf(dom_id, "%d", &ret); 
-    free(dom_id);
-                        
-    return ret;                                  
-} 
-
-
-bool xenbus_write_backend_node(struct fs_mount *mount)
-{
-    char node[1024], backend_node[1024];
-    int self_id;
-
-    assert(xsh != NULL);
-    self_id = get_self_id();
-    FS_DEBUG("Our own dom_id=%d\n", self_id);
-    snprintf(node, sizeof(node), "%s/backend", mount->frontend);
-    snprintf(backend_node, sizeof(backend_node), 
"/local/domain/%d/"ROOT_NODE"/%d",
-                                self_id, mount->mount_id);
-    xs_write(xsh, XBT_NULL, node, backend_node, strlen(backend_node));
-
-    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
-    return xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, 
strlen(STATE_INITIALISED));
-}
-
-bool xenbus_write_backend_state(struct fs_mount *mount, const char *state)
-{
-    char node[1024];
-    int self_id;
-
-    assert(xsh != NULL);
-    self_id = get_self_id();
-    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
-    return xs_write(xsh, XBT_NULL, node, state, strlen(state));
-}
-
-void xenbus_free_backend_node(struct fs_mount *mount)
-{
-    char node[1024];
-    int self_id;
-
-    assert(xsh != NULL);
-    self_id = get_self_id();
-    snprintf(node, sizeof(node), ROOT_NODE"/%d", mount->mount_id);
-    xs_rm(xsh, XBT_NULL, node);
-}
-
-bool xenbus_watch_frontend_state(struct fs_mount *mount)
-{
-    char statepath[1024];
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    return xs_watch(xsh, statepath, "frontend-state");
-}
-
-bool xenbus_unwatch_frontend_state(struct fs_mount *mount)
-{
-    char statepath[1024];
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    return xs_unwatch(xsh, statepath, "frontend-state");
-}
-
-int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate)
-{
-    unsigned int len;
-    char statepath[1024];
-    char *state = NULL;
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    state = xs_read(xsh, XBT_NULL, statepath, &len);
-    if (state && len > 0) {
-        if (strcmp(state, oldstate)) {
-            free(state);
-            return 1;
-        } else {
-            free(state);
-            return 0;
-        }
-    } else
-        return 1;
-}
-
-char* xenbus_read_frontend_state(struct fs_mount *mount)
-{
-    unsigned int len;
-    char statepath[1024];
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    return xs_read(xsh, XBT_NULL, statepath, &len);
-}
-
diff -r cb94dbe20f97 -r 548c29920f68 tools/fs-back/sys-queue.h
--- a/tools/fs-back/sys-queue.h Tue Jan 11 19:31:41 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/*      $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */
-
-/*
- * Qemu version: Copy from netbsd, removed debug code, removed some of
- * the implementations.  Left in lists, tail queues and circular queues.
- */
-
-/*
- * Copyright (c) 1991, 1993
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)queue.h     8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines three types of data structures:
- * lists, tail queues, and circular queues.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type)                                           \
-struct name {                                                           \
-        struct type *lh_first;  /* first element */                     \
-}
-
-#define LIST_HEAD_INITIALIZER(head)                                     \
-        { NULL }
-
-#define LIST_ENTRY(type)                                                \
-struct {                                                                \
-        struct type *le_next;   /* next element */                      \
-        struct type **le_prev;  /* address of previous next element */  \
-}
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) do {                                            \
-        (head)->lh_first = NULL;                                        \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
-        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
-                (listelm)->field.le_next->field.le_prev =               \
-                    &(elm)->field.le_next;                              \
-        (listelm)->field.le_next = (elm);                               \
-        (elm)->field.le_prev = &(listelm)->field.le_next;               \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
-        (elm)->field.le_prev = (listelm)->field.le_prev;                \
-        (elm)->field.le_next = (listelm);                               \
-        *(listelm)->field.le_prev = (elm);                              \
-        (listelm)->field.le_prev = &(elm)->field.le_next;               \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do {                         \
-        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
-                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-        (head)->lh_first = (elm);                                       \
-        (elm)->field.le_prev = &(head)->lh_first;                       \
-} while (/*CONSTCOND*/0)
-
-#define LIST_REMOVE(elm, field) do {                                    \
-        if ((elm)->field.le_next != NULL)                               \
-                (elm)->field.le_next->field.le_prev =                   \
-                    (elm)->field.le_prev;                               \
-        *(elm)->field.le_prev = (elm)->field.le_next;                   \
-} while (/*CONSTCOND*/0)
-
-#define LIST_FOREACH(var, head, field)                                  \
-        for ((var) = ((head)->lh_first);                                \
-                (var);                                                  \
-                (var) = ((var)->field.le_next))
-
-/*
- * List access methods.
- */
-#define LIST_EMPTY(head)                ((head)->lh_first == NULL)
-#define LIST_FIRST(head)                ((head)->lh_first)
-#define LIST_NEXT(elm, field)           ((elm)->field.le_next)
-
-
-/*
- * Tail queue definitions.
- */
-#define _TAILQ_HEAD(name, type, qual)                                   \
-struct name {                                                           \
-        qual type *tqh_first;           /* first element */             \
-        qual type *qual *tqh_last;      /* addr of last next element */ \
-}
-#define TAILQ_HEAD(name, type)  _TAILQ_HEAD(name, struct type,)
-
-#define TAILQ_HEAD_INITIALIZER(head)                                    \
-        { NULL, &(head).tqh_first }
-
-#define _TAILQ_ENTRY(type, qual)                                        \
-struct {                                                                \
-        qual type *tqe_next;            /* next element */              \
-        qual type *qual *tqe_prev;      /* address of previous next element */\
-}
-#define TAILQ_ENTRY(type)       _TAILQ_ENTRY(struct type,)
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do {                                           \
-        (head)->tqh_first = NULL;                                       \
-        (head)->tqh_last = &(head)->tqh_first;                          \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
-        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
-                (head)->tqh_first->field.tqe_prev =                     \
-                    &(elm)->field.tqe_next;                             \
-        else                                                            \
-                (head)->tqh_last = &(elm)->field.tqe_next;              \
-        (head)->tqh_first = (elm);                                      \
-        (elm)->field.tqe_prev = &(head)->tqh_first;                     \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
-        (elm)->field.tqe_next = NULL;                                   \
-        (elm)->field.tqe_prev = (head)->tqh_last;                       \
-        *(head)->tqh_last = (elm);                                      \
-        (head)->tqh_last = &(elm)->field.tqe_next;                      \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
-        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-                (elm)->field.tqe_next->field.tqe_prev =                 \
-                    &(elm)->field.tqe_next;                             \
-        else                                                            \
-                (head)->tqh_last = &(elm)->field.tqe_next;              \
-        (listelm)->field.tqe_next = (elm);                              \
-        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
-        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
-        (elm)->field.tqe_next = (listelm);                              \
-        *(listelm)->field.tqe_prev = (elm);                             \
-        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_REMOVE(head, elm, field) do {                             \
-        if (((elm)->field.tqe_next) != NULL)                            \
-                (elm)->field.tqe_next->field.tqe_prev =                 \
-                    (elm)->field.tqe_prev;                              \
-        else                                                            \
-                (head)->tqh_last = (elm)->field.tqe_prev;               \
-        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_FOREACH(var, head, field)                                 \
-        for ((var) = ((head)->tqh_first);                               \
-                (var);                                                  \
-                (var) = ((var)->field.tqe_next))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
-        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));   
 \
-                (var);                                                  \
-                (var) = (*(((struct headname 
*)((var)->field.tqe_prev))->tqh_last)))
-
-/*
- * Tail queue access methods.
- */
-#define TAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
-#define TAILQ_FIRST(head)               ((head)->tqh_first)
-#define TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
-
-#define TAILQ_LAST(head, headname) \
-        (*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define TAILQ_PREV(elm, headname, field) \
-        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type)                                        \
-struct name {                                                           \
-        struct type *cqh_first;         /* first element */             \
-        struct type *cqh_last;          /* last element */              \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head)                                  \
-        { (void *)&head, (void *)&head }
-
-#define CIRCLEQ_ENTRY(type)                                             \
-struct {                                                                \
-        struct type *cqe_next;          /* next element */              \
-        struct type *cqe_prev;          /* previous element */          \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do {                                         \
-        (head)->cqh_first = (void *)(head);                             \
-        (head)->cqh_last = (void *)(head);                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {            \
-        (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
-        (elm)->field.cqe_prev = (listelm);                              \
-        if ((listelm)->field.cqe_next == (void *)(head))                \
-                (head)->cqh_last = (elm);                               \
-        else                                                            \
-                (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
-        (listelm)->field.cqe_next = (elm);                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {           \
-        (elm)->field.cqe_next = (listelm);                              \
-        (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
-        if ((listelm)->field.cqe_prev == (void *)(head))                \
-                (head)->cqh_first = (elm);                              \
-        else                                                            \
-                (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
-        (listelm)->field.cqe_prev = (elm);                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {                      \
-        (elm)->field.cqe_next = (head)->cqh_first;                      \
-        (elm)->field.cqe_prev = (void *)(head);                         \
-        if ((head)->cqh_last == (void *)(head))                         \
-                (head)->cqh_last = (elm);                               \
-        else                                                            \
-                (head)->cqh_first->field.cqe_prev = (elm);              \
-        (head)->cqh_first = (elm);                                      \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {                      \
-        (elm)->field.cqe_next = (void *)(head);                         \
-        (elm)->field.cqe_prev = (head)->cqh_last;                       \
-        if ((head)->cqh_first == (void *)(head))                        \
-                (head)->cqh_first = (elm);                              \
-        else                                                            \
-                (head)->cqh_last->field.cqe_next = (elm);               \
-        (head)->cqh_last = (elm);                                       \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do {                           \
-        if ((elm)->field.cqe_next == (void *)(head))                    \
-                (head)->cqh_last = (elm)->field.cqe_prev;               \
-        else                                                            \
-                (elm)->field.cqe_next->field.cqe_prev =                 \
-                    (elm)->field.cqe_prev;                              \
-        if ((elm)->field.cqe_prev == (void *)(head))                    \
-                (head)->cqh_first = (elm)->field.cqe_next;              \
-        else                                                            \
-                (elm)->field.cqe_prev->field.cqe_next =                 \
-                    (elm)->field.cqe_next;                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_FOREACH(var, head, field)                               \
-        for ((var) = ((head)->cqh_first);                               \
-                (var) != (const void *)(head);                          \
-                (var) = ((var)->field.cqe_next))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                       \
-        for ((var) = ((head)->cqh_last);                                \
-                (var) != (const void *)(head);                          \
-                (var) = ((var)->field.cqe_prev))
-
-/*
- * Circular queue access methods.
- */
-#define CIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
-#define CIRCLEQ_FIRST(head)             ((head)->cqh_first)
-#define CIRCLEQ_LAST(head)              ((head)->cqh_last)
-#define CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_LOOP_NEXT(head, elm, field)                             \
-        (((elm)->field.cqe_next == (void *)(head))                      \
-            ? ((head)->cqh_first)                                       \
-            : (elm->field.cqe_next))
-#define CIRCLEQ_LOOP_PREV(head, elm, field)                             \
-        (((elm)->field.cqe_prev == (void *)(head))                      \
-            ? ((head)->cqh_last)                                        \
-            : (elm->field.cqe_prev))
-
-#endif  /* !_SYS_QUEUE_H_ */
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/Makefile
--- a/tools/libxl/Makefile      Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/Makefile      Tue Jan 11 19:41:53 2011 +0000
@@ -20,7 +20,7 @@ LIBS += -luuid
 LIBS += -luuid
 endif
 
-LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
+LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o
 ifeq ($(LIBXL_BLKTAP),y)
 LIBXL_OBJS-y += libxl_blktap2.o
 else
@@ -29,7 +29,9 @@ LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.
 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 
-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)
+LIBXL_OBJS = flexarray.o libxl.o libxl_create.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)
 LIBXL_OBJS += _libxl_types.o
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl.c       Tue Jan 11 19:41:53 2011 +0000
@@ -104,114 +104,6 @@ void libxl_key_value_list_destroy(libxl_
 
 
/******************************************************************************/
 
-int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
-                       uint32_t *domid)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    int flags, ret, i, rc;
-    char *uuid_string;
-    char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
-    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
-                         "control", "attr", "messages" };
-    char *dom_path, *vm_path;
-    struct xs_permissions roperm[2];
-    struct xs_permissions rwperm[1];
-    xs_transaction_t t;
-    xen_domain_handle_t handle;
-
-    uuid_string = libxl__uuid2string(&gc, info->uuid);
-    if (!uuid_string) {
-        libxl__free_all(&gc);
-        return ERROR_NOMEM;
-    }
-
-    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
-    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
-    flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off;
-    *domid = -1;
-
-    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
-    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
-
-    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
-    if (ret < 0) {
-        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation 
fail");
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
-    if (ret < 0) {
-        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    dom_path = libxl__xs_get_dompath(&gc, *domid);
-    if (!dom_path) {
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string);
-    if (!vm_path) {
-        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    roperm[0].id = 0;
-    roperm[0].perms = XS_PERM_NONE;
-    roperm[1].id = *domid;
-    roperm[1].perms = XS_PERM_READ;
-    rwperm[0].id = *domid;
-    rwperm[0].perms = XS_PERM_NONE;
-
-retry_transaction:
-    t = xs_transaction_start(ctx->xsh);
-    xs_rm(ctx->xsh, t, dom_path);
-    xs_mkdir(ctx->xsh, t, dom_path);
-    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
-
-    xs_rm(ctx->xsh, t, vm_path);
-    xs_mkdir(ctx->xsh, t, vm_path);
-    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
-
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
-    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
-    if (rc) {
-        libxl__free_all(&gc);
-        return rc;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
-        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
-        xs_mkdir(ctx->xsh, t, path);
-        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
-    }
-    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
-        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
-        xs_mkdir(ctx->xsh, t, path);
-        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
-    }
-
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), 
uuid_string, strlen(uuid_string));
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, 
strlen(info->name));
-    if (info->poolname)
-        xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), 
info->poolname, strlen(info->poolname));
-
-    libxl__xs_writev(&gc, t, dom_path, info->xsdata);
-    libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), 
info->platformdata);
-
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, 
"%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
-
-    if (!xs_transaction_end(ctx->xsh, t, 0))
-        if (errno == EAGAIN)
-            goto retry_transaction;
-
-    libxl__free_all(&gc);
-    return 0;
-}
 
 int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid,
                         const char *old_name, const char *new_name,
@@ -291,141 +183,6 @@ int libxl_domain_rename(libxl_ctx *ctx, 
 
  x_fail:  rc = ERROR_FAIL;  goto x_rc;
  x_nomem: rc = ERROR_NOMEM; goto x_rc;
-}
-
-int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t 
domid, libxl_domain_build_state *state)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char **vments = NULL, **localents = NULL;
-    struct timeval start_time;
-    int i, ret;
-
-    ret = libxl__build_pre(ctx, domid, info, state);
-    if (ret)
-        goto out;
-
-    gettimeofday(&start_time, NULL);
-
-    if (info->hvm) {
-        ret = libxl__build_hvm(ctx, domid, info, state);
-        if (ret)
-            goto out;
-
-        vments = libxl__calloc(&gc, 7, sizeof(char *));
-        vments[0] = "rtc/timeoffset";
-        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
-        vments[2] = "image/ostype";
-        vments[3] = "hvm";
-        vments[4] = "start_time";
-        vments[5] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
-    } else {
-        ret = libxl__build_pv(ctx, domid, info, state);
-        if (ret)
-            goto out;
-
-        vments = libxl__calloc(&gc, 11, sizeof(char *));
-        i = 0;
-        vments[i++] = "image/ostype";
-        vments[i++] = "linux";
-        vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel.path;
-        vments[i++] = "start_time";
-        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->u.pv.ramdisk.path) {
-            vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->u.pv.ramdisk.path;
-        }
-        if (info->u.pv.cmdline) {
-            vments[i++] = "image/cmdline";
-            vments[i++] = (char*) info->u.pv.cmdline;
-        }
-    }
-    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
-out:
-    libxl__file_reference_unmap(&info->kernel);
-    if (!info->hvm)
-           libxl__file_reference_unmap(&info->u.pv.ramdisk);
-
-    libxl__free_all(&gc);
-    return ret;
-}
-
-int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
-                         uint32_t domid, int fd, libxl_domain_build_state 
*state,
-                         libxl_device_model_info *dm_info)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char **vments = NULL, **localents = NULL;
-    struct timeval start_time;
-    int i, ret, esave, flags;
-
-    ret = libxl__build_pre(ctx, domid, info, state);
-    if (ret)
-        goto out;
-
-    ret = libxl__domain_restore_common(ctx, domid, info, state, fd);
-    if (ret)
-        goto out;
-
-    gettimeofday(&start_time, NULL);
-
-    if (info->hvm) {
-        vments = libxl__calloc(&gc, 7, sizeof(char *));
-        vments[0] = "rtc/timeoffset";
-        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
-        vments[2] = "image/ostype";
-        vments[3] = "hvm";
-        vments[4] = "start_time";
-        vments[5] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
-    } else {
-        vments = libxl__calloc(&gc, 11, sizeof(char *));
-        i = 0;
-        vments[i++] = "image/ostype";
-        vments[i++] = "linux";
-        vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel.path;
-        vments[i++] = "start_time";
-        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->u.pv.ramdisk.path) {
-            vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->u.pv.ramdisk.path;
-        }
-        if (info->u.pv.cmdline) {
-            vments[i++] = "image/cmdline";
-            vments[i++] = (char*) info->u.pv.cmdline;
-        }
-    }
-    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
-    if (ret)
-        goto out;
-
-    dm_info->saved_state = NULL;
-    if (info->hvm) {
-        ret = asprintf(&dm_info->saved_state,
-                       "/var/lib/xen/qemu-save.%d", domid);
-        ret = (ret < 0) ? ERROR_FAIL : 0;
-    }
-
-out:
-    libxl__file_reference_unmap(&info->kernel);
-    if (!info->hvm)
-           libxl__file_reference_unmap(&info->u.pv.ramdisk);
-
-    esave = errno;
-
-    flags = fcntl(fd, F_GETFL);
-    if (flags == -1) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on 
restore fd");
-    } else {
-        flags &= ~O_NONBLOCK;
-        if (fcntl(fd, F_SETFL, flags) == -1)
-            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd"
-                         " back to blocking mode");
-    }
-
-    errno = esave;
-    libxl__free_all(&gc);
-    return ret;
 }
 
 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid)
@@ -1267,6 +1024,35 @@ int libxl_device_disk_local_detach(libxl
 }
 
 
/******************************************************************************/
+int libxl_device_nic_init(libxl_device_nic *nic_info, int devnum)
+{
+    const uint8_t *r;
+    libxl_uuid uuid;
+
+    libxl_uuid_generate(&uuid);
+    r = libxl_uuid_bytearray(&uuid);
+    memset(nic_info, '\0', sizeof(*nic_info));
+
+    nic_info->backend_domid = 0;
+    nic_info->domid = 0;
+    nic_info->devid = devnum;
+    nic_info->mtu = 1492;
+    nic_info->model = strdup("e1000");
+    nic_info->mac[0] = 0x00;
+    nic_info->mac[1] = 0x16;
+    nic_info->mac[2] = 0x3e;
+    nic_info->mac[3] = r[0] & 0x7f;
+    nic_info->mac[4] = r[1];
+    nic_info->mac[5] = r[2];
+    nic_info->ifname = NULL;
+    nic_info->bridge = strdup("xenbr0");
+    if ( asprintf(&nic_info->script, "%s/vif-bridge",
+               libxl_xen_script_dir_path()) < 0 )
+        return ERROR_FAIL;
+    nic_info->nictype = NICTYPE_IOEMU;
+    return 0;
+}
+
 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
@@ -1425,6 +1211,34 @@ err:
 }
 
 
/******************************************************************************/
+void libxl_device_net2_init(libxl_device_net2 *net2_info, int devnum)
+{
+    const uint8_t *r;
+    libxl_uuid uuid;
+
+    libxl_uuid_generate(&uuid);
+    r = libxl_uuid_bytearray(&uuid);
+    memset(net2_info, '\0', sizeof(*net2_info));
+
+    net2_info->devid = devnum;
+    net2_info->front_mac[0] = 0x00;
+    net2_info->front_mac[1] = 0x16;
+    net2_info->front_mac[2] = 0x3e;;
+    net2_info->front_mac[3] = 0x7f & r[0];
+    net2_info->front_mac[4] = r[1];
+    net2_info->front_mac[5] = r[2];
+    net2_info->back_mac[0] = 0x00;
+    net2_info->back_mac[1] = 0x16;
+    net2_info->back_mac[2] = 0x3e;
+    net2_info->back_mac[3] = 0x7f & r[3];
+    net2_info->back_mac[4] = r[4];
+    net2_info->back_mac[5] = r[5];
+    net2_info->back_trusted = 1;
+    net2_info->filter_mac = 1;
+    net2_info->max_bypasses = 5;
+    net2_info->bridge = strdup("xenbr0");
+}
+
 int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 
*net2)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
@@ -1692,6 +1506,12 @@ out:
 }
 
 
/******************************************************************************/
+void libxl_device_vkb_init(libxl_device_vkb *vkb, int dev_num)
+{
+    memset(vkb, 0x00, sizeof(libxl_device_vkb));
+    vkb->devid = dev_num;
+}
+
 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
@@ -1890,6 +1710,22 @@ out:
 }
 
 
/******************************************************************************/
+void libxl_device_vfb_init(libxl_device_vfb *vfb, int dev_num)
+{
+    memset(vfb, 0x00, sizeof(libxl_device_vfb));
+    vfb->devid = dev_num;
+    vfb->display = NULL;
+    vfb->xauthority = NULL;
+    vfb->vnc = 1;
+    vfb->vncpasswd = NULL;
+    vfb->vnclisten = strdup("127.0.0.1");
+    vfb->vncdisplay = 0;
+    vfb->vncunused = 1;
+    vfb->keymap = NULL;
+    vfb->sdl = 0;
+    vfb->opengl = 0;
+}
+
 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl.h       Tue Jan 11 19:41:53 2011 +0000
@@ -241,6 +241,38 @@ enum {
 
 #define LIBXL_VERSION 0
 
+enum libxl_action_on_shutdown {
+    LIBXL_ACTION_DESTROY,
+
+    LIBXL_ACTION_RESTART,
+    LIBXL_ACTION_RESTART_RENAME,
+
+    LIBXL_ACTION_PRESERVE,
+
+    LIBXL_ACTION_COREDUMP_DESTROY,
+    LIBXL_ACTION_COREDUMP_RESTART,
+};
+
+typedef struct {
+    libxl_domain_create_info c_info;
+    libxl_domain_build_info b_info;
+    libxl_device_model_info dm_info;
+
+    int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
+
+    libxl_device_disk *disks;
+    libxl_device_nic *vifs;
+    libxl_device_net2 *vif2s;
+    libxl_device_pci *pcidevs;
+    libxl_device_vfb *vfbs;
+    libxl_device_vkb *vkbs;
+
+    enum libxl_action_on_shutdown on_poweroff;
+    enum libxl_action_on_shutdown on_reboot;
+    enum libxl_action_on_shutdown on_watchdog;
+    enum libxl_action_on_shutdown on_crash;
+} libxl_domain_config;
+
 /* context functions */
 int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*);
 int libxl_ctx_free(libxl_ctx *ctx);
@@ -248,11 +280,13 @@ int libxl_ctx_postfork(libxl_ctx *ctx);
 int libxl_ctx_postfork(libxl_ctx *ctx);
 
 /* domain related functions */
-int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t 
*domid);
-int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t 
domid, /* out */ libxl_domain_build_state *state);
-int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
-                         uint32_t domid, int fd, libxl_domain_build_state 
*state,
-                         libxl_device_model_info *dm_info);
+void libxl_init_create_info(libxl_domain_create_info *c_info);
+void libxl_init_build_info(libxl_domain_build_info *b_info, 
libxl_domain_create_info *c_info);
+void libxl_init_dm_info(libxl_device_model_info *dm_info, 
libxl_domain_create_info *c_info, libxl_domain_build_info *b_info);
+typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
+int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, 
libxl_console_ready cb, void *priv, uint32_t *domid);
+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);
+void libxl_domain_config_destroy(libxl_domain_config *d_config);
 int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
                           uint32_t domid, int fd);
 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid);
@@ -375,27 +409,6 @@ libxl_cpupoolinfo * libxl_list_cpupool(l
 libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool);
 libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm);
 
-typedef struct libxl__device_model_starting libxl_device_model_starting;
-int libxl_create_device_model(libxl_ctx *ctx,
-                              libxl_device_model_info *info,
-                              libxl_device_disk *disk, int num_disks,
-                              libxl_device_nic *vifs, int num_vifs,
-                              libxl_device_model_starting **starting_r);
-int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb,
-                            libxl_device_model_starting **starting_r);
-int libxl_need_xenpv_qemu(libxl_ctx *ctx,
-        int nr_consoles, libxl_device_console *consoles,
-        int nr_vfbs, libxl_device_vfb *vfbs,
-        int nr_disks, libxl_device_disk *disks);
-  /* Caller must either: pass starting_r==0, or on successful
-   * return pass *starting_r (which will be non-0) to
-   * libxl_confirm_device_model or libxl_detach_device_model. */
-int libxl_confirm_device_model_startup(libxl_ctx *ctx,
-                              libxl_device_model_starting *starting);
-int libxl_detach_device_model(libxl_ctx *ctx,
-                              libxl_device_model_starting *starting);
-  /* DM is detached even if error is returned */
-
 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk 
*disk);
 int libxl_device_disk_del(libxl_ctx *ctx, libxl_device_disk *disk, int wait);
 libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int 
*num);
@@ -409,16 +422,19 @@ char * libxl_device_disk_local_attach(li
 char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk);
 int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk);
 
+int libxl_device_nic_init(libxl_device_nic *nic, int dev_num);
 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic 
*nic);
 int libxl_device_nic_del(libxl_ctx *ctx, libxl_device_nic *nic, int wait);
 libxl_nicinfo *libxl_list_nics(libxl_ctx *ctx, uint32_t domid, unsigned int 
*nb);
 
 int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, 
libxl_device_console *console);
 
+void libxl_device_vkb_init(libxl_device_vkb *vkb, int dev_num);
 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb 
*vkb);
 int libxl_device_vkb_clean_shutdown(libxl_ctx *ctx, uint32_t domid);
 int libxl_device_vkb_hard_shutdown(libxl_ctx *ctx, uint32_t domid);
 
+void libxl_device_vfb_init(libxl_device_vfb *vfb, int dev_num);
 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb);
 int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid);
 int libxl_device_vfb_hard_shutdown(libxl_ctx *ctx, uint32_t domid);
@@ -516,6 +532,7 @@ int libxl_tmem_shared_auth(libxl_ctx *ct
                            int auth);
 int libxl_tmem_freeable(libxl_ctx *ctx);
 
+void libxl_device_net2_init(libxl_device_net2 *net2, int dev_num);
 int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid,
                           libxl_device_net2 *net2);
 libxl_net2info *libxl_device_net2_list(libxl_ctx *ctx, uint32_t domid,
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl     Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl.idl     Tue Jan 11 19:41:53 2011 +0000
@@ -152,6 +152,7 @@ libxl_device_model_info = Struct("device
     ("sdl",              bool,              False, "sdl enabled or disabled"),
     ("opengl",           bool,              False, "opengl enabled or disabled 
(if enabled requires sdl enabled)"),
     ("nographic",        bool,              False, "no graphics, use serial 
port"),
+    ("gfx_passthru",     bool,              False, "disable qemu graphics for 
PCI passthru of GPU from host"),
     ("serial",           string,            False, "serial port re-direct to 
pty deivce"),
     ("boot",             string,            False, "boot order, for example 
dca"),
     ("usb",              bool,              False, "usb support enabled or 
disabled"),
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl_create.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_create.c        Tue Jan 11 19:41:53 2011 +0000
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ * Author Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
+ * Author Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "libxl.h"
+#include "libxl_utils.h"
+#include "libxl_internal.h"
+#include "flexarray.h"
+
+void libxl_domain_config_destroy(libxl_domain_config *d_config)
+{
+    int i;
+
+    for (i=0; i<d_config->num_disks; i++)
+        libxl_device_disk_destroy(&d_config->disks[i]);
+    free(d_config->disks);
+
+    for (i=0; i<d_config->num_vifs; i++)
+        libxl_device_nic_destroy(&d_config->vifs[i]);
+    free(d_config->vifs);
+
+    for (i=0; i<d_config->num_vif2s; i++)
+        libxl_device_net2_destroy(&d_config->vif2s[i]);
+    free(d_config->vif2s);
+
+    for (i=0; i<d_config->num_pcidevs; i++)
+        libxl_device_pci_destroy(&d_config->pcidevs[i]);
+    free(d_config->pcidevs);
+
+    for (i=0; i<d_config->num_vfbs; i++)
+        libxl_device_vfb_destroy(&d_config->vfbs[i]);
+    free(d_config->vfbs);
+
+    for (i=0; i<d_config->num_vkbs; i++)
+        libxl_device_vkb_destroy(&d_config->vkbs[i]);
+    free(d_config->vkbs);
+
+    libxl_domain_create_info_destroy(&d_config->c_info);
+    libxl_domain_build_info_destroy(&d_config->b_info);
+    libxl_device_model_info_destroy(&d_config->dm_info);
+}
+
+void libxl_init_create_info(libxl_domain_create_info *c_info)
+{
+    memset(c_info, '\0', sizeof(*c_info));
+    c_info->xsdata = NULL;
+    c_info->platformdata = NULL;
+    c_info->hap = 1;
+    c_info->hvm = 1;
+    c_info->oos = 1;
+    c_info->ssidref = 0;
+    c_info->poolid = 0;
+}
+
+void libxl_init_build_info(libxl_domain_build_info *b_info, 
libxl_domain_create_info *c_info)
+{
+    memset(b_info, '\0', sizeof(*b_info));
+    b_info->max_vcpus = 1;
+    b_info->max_memkb = 32 * 1024;
+    b_info->target_memkb = b_info->max_memkb;
+    b_info->disable_migrate = 0;
+    b_info->cpuid = NULL;
+    b_info->shadow_memkb = 0;
+    if (c_info->hvm) {
+        b_info->video_memkb = 8 * 1024;
+        b_info->kernel.path = strdup("hvmloader");
+        b_info->hvm = 1;
+        b_info->u.hvm.pae = 1;
+        b_info->u.hvm.apic = 1;
+        b_info->u.hvm.acpi = 1;
+        b_info->u.hvm.nx = 1;
+        b_info->u.hvm.viridian = 0;
+        b_info->u.hvm.hpet = 1;
+        b_info->u.hvm.vpt_align = 1;
+        b_info->u.hvm.timer_mode = 1;
+    } else {
+        b_info->u.pv.slack_memkb = 8 * 1024;
+    }
+}
+
+void libxl_init_dm_info(libxl_device_model_info *dm_info,
+        libxl_domain_create_info *c_info, libxl_domain_build_info *b_info)
+{
+    memset(dm_info, '\0', sizeof(*dm_info));
+
+    libxl_uuid_generate(&dm_info->uuid);
+
+    dm_info->dom_name = strdup(c_info->name);
+    dm_info->device_model = strdup("qemu-dm");
+    dm_info->target_ram = libxl__sizekb_to_mb(b_info->target_memkb);
+    dm_info->videoram = libxl__sizekb_to_mb(b_info->video_memkb);
+    dm_info->apic = b_info->u.hvm.apic;
+    dm_info->vcpus = b_info->max_vcpus;
+    dm_info->vcpu_avail = b_info->cur_vcpus;
+
+    dm_info->stdvga = 0;
+    dm_info->vnc = 1;
+    dm_info->vnclisten = strdup("127.0.0.1");
+    dm_info->vncdisplay = 0;
+    dm_info->vncunused = 1;
+    dm_info->keymap = NULL;
+    dm_info->sdl = 0;
+    dm_info->opengl = 0;
+    dm_info->nographic = 0;
+    dm_info->serial = NULL;
+    dm_info->boot = strdup("cda");
+    dm_info->usb = 0;
+    dm_info->usbdevice = NULL;
+    dm_info->xen_platform_pci = 1;
+}
+
+static int init_console_info(libxl_device_console *console, int dev_num, 
libxl_domain_build_state *state)
+{
+    memset(console, 0x00, sizeof(libxl_device_console));
+    console->devid = dev_num;
+    console->consback = LIBXL_CONSBACK_XENCONSOLED;
+    console->output = strdup("pty");
+    if ( NULL == console->output )
+        return ERROR_NOMEM;
+    if (state)
+        console->build_state = state;
+    return 0;
+}
+
+int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, 
uint32_t domid, libxl_domain_build_state *state)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char **vments = NULL, **localents = NULL;
+    struct timeval start_time;
+    int i, ret;
+
+    ret = libxl__build_pre(ctx, domid, info, state);
+    if (ret)
+        goto out;
+
+    gettimeofday(&start_time, NULL);
+
+    if (info->hvm) {
+        ret = libxl__build_hvm(ctx, domid, info, state);
+        if (ret)
+            goto out;
+
+        vments = libxl__calloc(&gc, 7, sizeof(char *));
+        vments[0] = "rtc/timeoffset";
+        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
+        vments[2] = "image/ostype";
+        vments[3] = "hvm";
+        vments[4] = "start_time";
+        vments[5] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+    } else {
+        ret = libxl__build_pv(ctx, domid, info, state);
+        if (ret)
+            goto out;
+
+        vments = libxl__calloc(&gc, 11, sizeof(char *));
+        i = 0;
+        vments[i++] = "image/ostype";
+        vments[i++] = "linux";
+        vments[i++] = "image/kernel";
+        vments[i++] = (char*) info->kernel.path;
+        vments[i++] = "start_time";
+        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+        if (info->u.pv.ramdisk.path) {
+            vments[i++] = "image/ramdisk";
+            vments[i++] = (char*) info->u.pv.ramdisk.path;
+        }
+        if (info->u.pv.cmdline) {
+            vments[i++] = "image/cmdline";
+            vments[i++] = (char*) info->u.pv.cmdline;
+        }
+    }
+    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
+out:
+    libxl__file_reference_unmap(&info->kernel);
+    if (!info->hvm)
+           libxl__file_reference_unmap(&info->u.pv.ramdisk);
+
+    libxl__free_all(&gc);
+    return ret;
+}
+
+static int domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
+                         uint32_t domid, int fd, libxl_domain_build_state 
*state,
+                         libxl_device_model_info *dm_info)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char **vments = NULL, **localents = NULL;
+    struct timeval start_time;
+    int i, ret, esave, flags;
+
+    ret = libxl__build_pre(ctx, domid, info, state);
+    if (ret)
+        goto out;
+
+    ret = libxl__domain_restore_common(ctx, domid, info, state, fd);
+    if (ret)
+        goto out;
+
+    gettimeofday(&start_time, NULL);
+
+    if (info->hvm) {
+        vments = libxl__calloc(&gc, 7, sizeof(char *));
+        vments[0] = "rtc/timeoffset";
+        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
+        vments[2] = "image/ostype";
+        vments[3] = "hvm";
+        vments[4] = "start_time";
+        vments[5] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+    } else {
+        vments = libxl__calloc(&gc, 11, sizeof(char *));
+        i = 0;
+        vments[i++] = "image/ostype";
+        vments[i++] = "linux";
+        vments[i++] = "image/kernel";
+        vments[i++] = (char*) info->kernel.path;
+        vments[i++] = "start_time";
+        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+        if (info->u.pv.ramdisk.path) {
+            vments[i++] = "image/ramdisk";
+            vments[i++] = (char*) info->u.pv.ramdisk.path;
+        }
+        if (info->u.pv.cmdline) {
+            vments[i++] = "image/cmdline";
+            vments[i++] = (char*) info->u.pv.cmdline;
+        }
+    }
+    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
+    if (ret)
+        goto out;
+
+    dm_info->saved_state = NULL;
+    if (info->hvm) {
+        ret = asprintf(&dm_info->saved_state,
+                       "/var/lib/xen/qemu-save.%d", domid);
+        ret = (ret < 0) ? ERROR_FAIL : 0;
+    }
+
+out:
+    libxl__file_reference_unmap(&info->kernel);
+    if (!info->hvm)
+           libxl__file_reference_unmap(&info->u.pv.ramdisk);
+
+    esave = errno;
+
+    flags = fcntl(fd, F_GETFL);
+    if (flags == -1) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on 
restore fd");
+    } else {
+        flags &= ~O_NONBLOCK;
+        if (fcntl(fd, F_SETFL, flags) == -1)
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd"
+                         " back to blocking mode");
+    }
+
+    errno = esave;
+    libxl__free_all(&gc);
+    return ret;
+}
+
+int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
+                       uint32_t *domid)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    int flags, ret, i, rc;
+    char *uuid_string;
+    char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
+    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
+                         "control", "attr", "messages" };
+    char *dom_path, *vm_path;
+    struct xs_permissions roperm[2];
+    struct xs_permissions rwperm[1];
+    xs_transaction_t t;
+    xen_domain_handle_t handle;
+
+    uuid_string = libxl__uuid2string(&gc, info->uuid);
+    if (!uuid_string) {
+        libxl__free_all(&gc);
+        return ERROR_NOMEM;
+    }
+
+    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
+    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
+    flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off;
+    *domid = -1;
+
+    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
+    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
+
+    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
+    if (ret < 0) {
+        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation 
fail");
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
+    if (ret < 0) {
+        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    dom_path = libxl__xs_get_dompath(&gc, *domid);
+    if (!dom_path) {
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string);
+    if (!vm_path) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    roperm[0].id = 0;
+    roperm[0].perms = XS_PERM_NONE;
+    roperm[1].id = *domid;
+    roperm[1].perms = XS_PERM_READ;
+    rwperm[0].id = *domid;
+    rwperm[0].perms = XS_PERM_NONE;
+
+retry_transaction:
+    t = xs_transaction_start(ctx->xsh);
+    xs_rm(ctx->xsh, t, dom_path);
+    xs_mkdir(ctx->xsh, t, dom_path);
+    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
+
+    xs_rm(ctx->xsh, t, vm_path);
+    xs_mkdir(ctx->xsh, t, vm_path);
+    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
+
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
+    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
+    if (rc) {
+        libxl__free_all(&gc);
+        return rc;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
+        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
+        xs_mkdir(ctx->xsh, t, path);
+        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
+    }
+    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
+        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
+        xs_mkdir(ctx->xsh, t, path);
+        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
+    }
+
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), 
uuid_string, strlen(uuid_string));
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, 
strlen(info->name));
+    if (info->poolname)
+        xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), 
info->poolname, strlen(info->poolname));
+
+    libxl__xs_writev(&gc, t, dom_path, info->xsdata);
+    libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), 
info->platformdata);
+
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, 
"%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
+    if (!xs_transaction_end(ctx->xsh, t, 0))
+        if (errno == EAGAIN)
+            goto retry_transaction;
+
+    libxl__free_all(&gc);
+    return 0;
+}
+
+static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config,
+                            libxl_console_ready cb, void *priv,
+                            uint32_t *domid_out, int restore_fd)
+{
+    libxl__device_model_starting *dm_starting = 0;
+    libxl_device_model_info *dm_info = &d_config->dm_info;
+    libxl_domain_build_state state;
+    uint32_t domid;
+    int i, ret;
+
+    domid = 0;
+
+    ret = libxl__domain_make(ctx, &d_config->c_info, &domid);
+    if (ret) {
+        fprintf(stderr, "cannot make domain: %d\n", ret);
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
+    if ( !d_config->c_info.hvm && cb ) {
+        if ( (*cb)(ctx, domid, priv) )
+            goto error_out;
+    }
+
+    if ( restore_fd < 0 ) {
+        ret = libxl_run_bootloader(ctx, &d_config->b_info, d_config->num_disks 
> 0 ? &d_config->disks[0] : NULL, domid);
+        if (ret) {
+            fprintf(stderr, "failed to run bootloader: %d\n", ret);
+            goto error_out;
+        }
+    }
+
+    if ( restore_fd >= 0 ) {
+        ret = domain_restore(ctx, &d_config->b_info, domid, restore_fd, 
&state, dm_info);
+    } else {
+        if (dm_info->saved_state) {
+            free(dm_info->saved_state);
+            dm_info->saved_state = NULL;
+        }
+        ret = libxl__domain_build(ctx, &d_config->b_info, domid, &state);
+    }
+
+    if (ret) {
+        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
+    for (i = 0; i < d_config->num_disks; i++) {
+        d_config->disks[i].domid = domid;
+        ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]);
+        if (ret) {
+            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
+            ret = ERROR_FAIL;
+            goto error_out;
+        }
+    }
+    for (i = 0; i < d_config->num_vifs; i++) {
+        d_config->vifs[i].domid = domid;
+        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]);
+        if (ret) {
+            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
+            ret = ERROR_FAIL;
+            goto error_out;
+        }
+    }
+    if (!d_config->c_info.hvm) {
+        for (i = 0; i < d_config->num_vif2s; i++) {
+            d_config->vif2s[i].domid = domid;
+            ret = libxl_device_net2_add(ctx, domid, &d_config->vif2s[i]);
+            if (ret) {
+                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
+                ret = ERROR_FAIL;
+                goto error_out;
+            }
+        }
+    }
+    if (d_config->c_info.hvm) {
+        libxl_device_console console;
+
+        ret = init_console_info(&console, 0, &state);
+        if ( ret )
+            goto error_out;
+        console.domid = domid;
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        dm_info->domid = domid;
+        ret = libxl__create_device_model(ctx, dm_info,
+                                        d_config->disks, d_config->num_disks,
+                                        d_config->vifs, d_config->num_vifs,
+                                        &dm_starting);
+        if (ret < 0) {
+            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: 
libxl__create_device_model\n",
+                    __FILE__,__LINE__, ret);
+            goto error_out;
+        }
+    } else {
+        int need_qemu = 0;
+        libxl_device_console console;
+
+        for (i = 0; i < d_config->num_vfbs; i++) {
+            d_config->vfbs[i].domid = domid;
+            libxl_device_vfb_add(ctx, domid, &d_config->vfbs[i]);
+            d_config->vkbs[i].domid = domid;
+            libxl_device_vkb_add(ctx, domid, &d_config->vkbs[i]);
+        }
+
+        ret = init_console_info(&console, 0, &state);
+        if ( ret )
+            goto error_out;
+        console.domid = domid;
+
+        need_qemu = libxl__need_xenpv_qemu(ctx, 1, &console,
+                d_config->num_vfbs, d_config->vfbs,
+                d_config->num_disks, &d_config->disks[0]);
+
+        if (need_qemu)
+             console.consback = LIBXL_CONSBACK_IOEMU;
+
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        if (need_qemu)
+            libxl__create_xenpv_qemu(ctx, domid, d_config->vfbs, &dm_starting);
+    }
+
+    if (dm_starting) {
+        ret = libxl__confirm_device_model_startup(ctx, dm_starting);
+        if (ret < 0) {
+            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: 
libxl__confirm_device_model_startup\n",
+                    __FILE__,__LINE__, ret);
+            goto error_out;
+        }
+    }
+
+    for (i = 0; i < d_config->num_pcidevs; i++)
+        libxl_device_pci_add(ctx, domid, &d_config->pcidevs[i]);
+
+    if ( d_config->c_info.hvm && cb ) {
+        if ( (*cb)(ctx, domid, priv) )
+            goto error_out;
+    }
+
+    *domid_out = domid;
+    return 0;
+
+error_out:
+    if (domid)
+        libxl_domain_destroy(ctx, domid, 0);
+
+    return ret;
+}
+int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config,
+                            libxl_console_ready cb, void *priv, uint32_t 
*domid)
+{
+    return do_domain_create(ctx, d_config, cb, priv, domid, -1);
+}
+
+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)
+{
+    return do_domain_create(ctx, d_config, cb, priv, domid, restore_fd);
+}
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c    Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl_dm.c    Tue Jan 11 19:41:53 2011 +0000
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <signal.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include "libxl_utils.h"
@@ -324,7 +325,7 @@ static char ** libxl_build_device_model_
 
 static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
 {
-    libxl_device_model_starting *starting = for_spawn;
+    libxl__device_model_starting *starting = for_spawn;
     struct xs_handle *xsh;
     char *path = NULL, *pid = NULL;
     int len;
@@ -426,7 +427,7 @@ static int libxl_create_stubdom(libxl_ct
                                 libxl_device_nic *vifs, int num_vifs,
                                 libxl_device_vfb *vfb,
                                 libxl_device_vkb *vkb,
-                                libxl_device_model_starting **starting_r)
+                                libxl__device_model_starting **starting_r)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     int i, num_console = 1, ret;
@@ -438,7 +439,7 @@ static int libxl_create_stubdom(libxl_ct
     char **args;
     struct xs_permissions perm[2];
     xs_transaction_t t;
-    libxl_device_model_starting *dm_starting = 0;
+    libxl__device_model_starting *dm_starting = 0;
 
     args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
     if (!args) {
@@ -462,10 +463,10 @@ static int libxl_create_stubdom(libxl_ct
     b_info.u.pv.features = "";
     b_info.hvm = 0;
 
-    ret = libxl_domain_make(ctx, &c_info, &domid);
+    ret = libxl__domain_make(ctx, &c_info, &domid);
     if (ret)
         goto out_free;
-    ret = libxl_domain_build(ctx, &b_info, domid, &state);
+    ret = libxl__domain_build(ctx, &b_info, domid, &state);
     if (ret)
         goto out_free;
 
@@ -545,11 +546,11 @@ retry_transaction:
         if (ret)
             goto out_free;
     }
-    if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
+    if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
         ret = ERROR_FAIL;
         goto out_free;
     }
-    if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) {
+    if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) {
         ret = ERROR_FAIL;
         goto out_free;
     }
@@ -557,7 +558,7 @@ retry_transaction:
     libxl_domain_unpause(ctx, domid);
 
     if (starting_r) {
-        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
+        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
         (*starting_r)->domid = info->domid;
         (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
         (*starting_r)->for_spawn = NULL;
@@ -572,18 +573,18 @@ out:
     return ret;
 }
 
-int libxl_create_device_model(libxl_ctx *ctx,
+int libxl__create_device_model(libxl_ctx *ctx,
                               libxl_device_model_info *info,
                               libxl_device_disk *disks, int num_disks,
                               libxl_device_nic *vifs, int num_vifs,
-                              libxl_device_model_starting **starting_r)
+                              libxl__device_model_starting **starting_r)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     char *path, *logfile;
     int logfile_w, null;
     int rc;
     char **args;
-    libxl_device_model_starting buf_starting, *p;
+    libxl__device_model_starting buf_starting, *p;
     xs_transaction_t t; 
     char *vm_path;
     char **pass_stuff;
@@ -614,7 +615,7 @@ int libxl_create_device_model(libxl_ctx 
 
     if (starting_r) {
         rc = ERROR_NOMEM;
-        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
+        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
         if (!*starting_r)
             goto out_close;
         p = *starting_r;
@@ -668,8 +669,8 @@ out:
     return rc;
 }
 
-int libxl_detach_device_model(libxl_ctx *ctx,
-                              libxl_device_model_starting *starting)
+static int detach_device_model(libxl_ctx *ctx,
+                              libxl__device_model_starting *starting)
 {
     int rc;
     rc = libxl__spawn_detach(ctx, starting->for_spawn);
@@ -680,14 +681,14 @@ int libxl_detach_device_model(libxl_ctx 
 }
 
 
-int libxl_confirm_device_model_startup(libxl_ctx *ctx,
-                                       libxl_device_model_starting *starting)
+int libxl__confirm_device_model_startup(libxl_ctx *ctx,
+                                       libxl__device_model_starting *starting)
 {
     int problem = libxl__wait_for_device_model(ctx, starting->domid, 
"running", NULL, NULL);
     int detach;
     if ( !problem )
         problem = libxl__spawn_check(ctx, starting->for_spawn);
-    detach = libxl_detach_device_model(ctx, starting);
+    detach = detach_device_model(ctx, starting);
     return problem ? problem : detach;
 }
 
@@ -760,7 +761,7 @@ static int libxl_build_xenpv_qemu_args(l
     return 0;
 }
 
-int libxl_need_xenpv_qemu(libxl_ctx *ctx,
+int libxl__need_xenpv_qemu(libxl_ctx *ctx,
         int nr_consoles, libxl_device_console *consoles,
         int nr_vfbs, libxl_device_vfb *vfbs,
         int nr_disks, libxl_device_disk *disks)
@@ -793,14 +794,14 @@ out:
     return ret;
 }
 
-int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb,
-                            libxl_device_model_starting **starting_r)
+int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb,
+                            libxl__device_model_starting **starting_r)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     libxl_device_model_info info;
 
     libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
-    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
+    libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
     libxl__free_all(&gc);
     return 0;
 }
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c  Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl_exec.c  Tue Jan 11 19:41:53 2011 +0000
@@ -90,7 +90,7 @@ void libxl_report_child_exitstatus(libxl
 }
 
 int libxl__spawn_spawn(libxl_ctx *ctx,
-                      libxl_device_model_starting *starting,
+                      libxl__device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn,
                                                 pid_t innerchild))
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl_internal.h      Tue Jan 11 19:41:53 2011 +0000
@@ -194,14 +194,37 @@ typedef struct {
     char *what; /* malloc'd in spawn_spawn */
 } libxl__spawn_starting;
 
-struct libxl__device_model_starting {
+typedef struct {
     libxl__spawn_starting *for_spawn; /* first! */
     char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */
     int domid;
-};
+} libxl__device_model_starting;
+
+/* from xl_create */
+_hidden int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, 
uint32_t *domid);
+_hidden int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, 
uint32_t domid, /* out */ libxl_domain_build_state *state);
+
+/* for device model creation */
+_hidden int libxl__create_device_model(libxl_ctx *ctx,
+                              libxl_device_model_info *info,
+                              libxl_device_disk *disk, int num_disks,
+                              libxl_device_nic *vifs, int num_vifs,
+                              libxl__device_model_starting **starting_r);
+_hidden int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, 
libxl_device_vfb *vfb,
+                            libxl__device_model_starting **starting_r);
+_hidden int libxl__need_xenpv_qemu(libxl_ctx *ctx,
+        int nr_consoles, libxl_device_console *consoles,
+        int nr_vfbs, libxl_device_vfb *vfbs,
+        int nr_disks, libxl_device_disk *disks);
+
+  /* Caller must either: pass starting_r==0, or on successful
+   * return pass *starting_r (which will be non-0) to
+   * libxl_confirm_device_model or libxl_detach_device_model. */
+_hidden int libxl__confirm_device_model_startup(libxl_ctx *ctx,
+                              libxl__device_model_starting *starting);
 
 _hidden int libxl__spawn_spawn(libxl_ctx *ctx,
-                      libxl_device_model_starting *starting,
+                      libxl__device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn, pid_t 
innerchild));
 _hidden int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid);
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c   Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/libxl_pci.c   Tue Jan 11 19:41:53 2011 +0000
@@ -221,20 +221,35 @@ parse_error:
     return ERROR_INVAL;
 }
 
+static void libxl_create_pci_backend_device(libxl__gc *gc, flexarray_t *back, 
int num, libxl_device_pci *pcidev)
+{
+    flexarray_append(back, libxl__sprintf(gc, "key-%d", num));
+    flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_append(back, libxl__sprintf(gc, "dev-%d", num));
+    flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
+    if (pcidev->vdevfn)
+        flexarray_vappend(back, libxl__sprintf(gc, "vdevfn-%d", num), 
libxl__sprintf(gc, "%x", pcidev->vdevfn), NULL);
+    flexarray_append(back, libxl__sprintf(gc, "opts-%d", num));
+    flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", 
pcidev->msitranslate, pcidev->power_mgmt));
+    flexarray_vappend(back, libxl__sprintf(gc, "state-%d", num), 
libxl__sprintf(gc, "%d", 1), NULL);
+}
+
 static int libxl_create_pci_backend(libxl__gc *gc, uint32_t domid, 
libxl_device_pci *pcidev, int num)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    flexarray_t *front;
-    flexarray_t *back;
+    flexarray_t *front = NULL;
+    flexarray_t *back = NULL;
     libxl__device device;
-    int i;
+    int ret = ERROR_NOMEM, i;
 
     front = flexarray_make(16, 1);
     if (!front)
-        return ERROR_NOMEM;
+        goto out;
     back = flexarray_make(16, 1);
     if (!back)
-        return ERROR_NOMEM;
+        goto out;
+
+    ret = 0;
 
     LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Creating pci backend");
 
@@ -247,30 +262,27 @@ static int libxl_create_pci_backend(libx
     device.kind = DEVICE_PCI;
 
     flexarray_vappend(back, "frontend-id", libxl__sprintf(gc, "%d", domid),
-                     "online", "1", "state", libxl__sprintf(gc, "%d", 1),
-                    "domain", libxl__domid_to_name(gc, domid), NULL);
-    for (i = 0; i < num; i++) {
-        flexarray_append(back, libxl__sprintf(gc, "key-%d", i));
-        flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
-        flexarray_append(back, libxl__sprintf(gc, "dev-%d", i));
-        flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
-        if (pcidev->vdevfn) {
-            flexarray_vappend(back, libxl__sprintf(gc, "vdevfn-%d", i), 
libxl__sprintf(gc, "%x", pcidev->vdevfn), NULL);
-        }
-        flexarray_append(back, libxl__sprintf(gc, "opts-%d", i));
-        flexarray_append(back, libxl__sprintf(gc, 
"msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
-        flexarray_vappend(back, libxl__sprintf(gc, "state-%d", i), 
libxl__sprintf(gc, "%d", 1), NULL);
-    }
-    flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num),
-                    "backend-id", libxl__sprintf(gc, "%d", 0),
-                    "state", libxl__sprintf(gc, "%d", 1), NULL);
+                      "online", "1", "state", libxl__sprintf(gc, "%d", 1),
+                      "domain", libxl__domid_to_name(gc, domid), NULL);
+
+    for (i = 0; i < num; i++, pcidev++)
+        libxl_create_pci_backend_device(gc, back, i, pcidev);
+
+    flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num));
+
+    flexarray_vappend(front,
+                      "backend-id", libxl__sprintf(gc, "%d", 0),
+                      "state", libxl__sprintf(gc, "%d", 1), NULL);
 
     libxl__device_generic_add(ctx, &device,
                              libxl__xs_kvs_of_flexarray(gc, back, back->count),
                              libxl__xs_kvs_of_flexarray(gc, front, 
front->count));
 
-    flexarray_free(back);
-    flexarray_free(front);
+out:
+    if (back)
+        flexarray_free(back);
+    if (front)
+        flexarray_free(front);
     return 0;
 }
 
@@ -298,17 +310,7 @@ static int libxl_device_pci_add_xenstore
 
     LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Adding new pci device to xenstore");
     num = atoi(num_devs);
-    flexarray_append(back, libxl__sprintf(gc, "key-%d", num));
-    flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
-    flexarray_append(back, libxl__sprintf(gc, "dev-%d", num));
-    flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
-    if (pcidev->vdevfn) {
-        flexarray_append(back, libxl__sprintf(gc, "vdevfn-%d", num));
-        flexarray_append(back, libxl__sprintf(gc, "%x", pcidev->vdevfn));
-    }
-    flexarray_append(back, libxl__sprintf(gc, "opts-%d", num));
-    flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", 
pcidev->msitranslate, pcidev->power_mgmt));
-    flexarray_vappend(back, libxl__sprintf(gc, "state-%d", num), 
libxl__sprintf(gc, "%d", 1), NULL);
+    libxl_create_pci_backend_device(gc, back, num, pcidev);
     flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num + 1), 
NULL);
     flexarray_vappend(back, "state", libxl__sprintf(gc, "%d", 7), NULL);
 
@@ -749,7 +751,7 @@ static int libxl_device_pci_reset(libxl_
         return rc < 0 ? rc : 0;
     }
     if (errno == ENOENT) {
-        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "The kernel doesn't support PCI 
device reset from sysfs");
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "The kernel doesn't support reset 
from sysfs for PCI device "PCI_BDF, domain, bus, dev, func);
     } else {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Failed to access reset path 
%s", reset);
     }
diff -r cb94dbe20f97 -r 548c29920f68 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/libxl/xl_cmdimpl.c  Tue Jan 11 19:41:53 2011 +0000
@@ -100,80 +100,17 @@ struct save_file_header {
 };
 
 
-enum action_on_shutdown {
-    ACTION_DESTROY,
-
-    ACTION_RESTART,
-    ACTION_RESTART_RENAME,
-
-    ACTION_PRESERVE,
-
-    ACTION_COREDUMP_DESTROY,
-    ACTION_COREDUMP_RESTART,
+static const char *action_on_shutdown_names[] = {
+    [LIBXL_ACTION_DESTROY] = "destroy",
+
+    [LIBXL_ACTION_RESTART] = "restart",
+    [LIBXL_ACTION_RESTART_RENAME] = "rename-restart",
+
+    [LIBXL_ACTION_PRESERVE] = "preserve",
+
+    [LIBXL_ACTION_COREDUMP_DESTROY] = "coredump-destroy",
+    [LIBXL_ACTION_COREDUMP_RESTART] = "coredump-restart",
 };
-
-static const char *action_on_shutdown_names[] = {
-    [ACTION_DESTROY] = "destroy",
-
-    [ACTION_RESTART] = "restart",
-    [ACTION_RESTART_RENAME] = "rename-restart",
-
-    [ACTION_PRESERVE] = "preserve",
-
-    [ACTION_COREDUMP_DESTROY] = "coredump-destroy",
-    [ACTION_COREDUMP_RESTART] = "coredump-restart",
-};
-
-struct domain_config {
-    libxl_domain_create_info c_info;
-    libxl_domain_build_info b_info;
-
-    int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
-
-    libxl_device_disk *disks;
-    libxl_device_nic *vifs;
-    libxl_device_net2 *vif2s;
-    libxl_device_pci *pcidevs;
-    libxl_device_vfb *vfbs;
-    libxl_device_vkb *vkbs;
-
-    enum action_on_shutdown on_poweroff;
-    enum action_on_shutdown on_reboot;
-    enum action_on_shutdown on_watchdog;
-    enum action_on_shutdown on_crash;
-};
-
-static void free_domain_config(struct domain_config *d_config)
-{
-    int i;
-
-    for (i=0; i<d_config->num_disks; i++)
-        libxl_device_disk_destroy(&d_config->disks[i]);
-    free(d_config->disks);
-
-    for (i=0; i<d_config->num_vifs; i++)
-        libxl_device_nic_destroy(&d_config->vifs[i]);
-    free(d_config->vifs);
-
-    for (i=0; i<d_config->num_vif2s; i++)
-        libxl_device_net2_destroy(&d_config->vif2s[i]);
-    free(d_config->vif2s);
-
-    for (i=0; i<d_config->num_pcidevs; i++)
-        libxl_device_pci_destroy(&d_config->pcidevs[i]);
-    free(d_config->pcidevs);
-
-    for (i=0; i<d_config->num_vfbs; i++)
-        libxl_device_vfb_destroy(&d_config->vfbs[i]);
-    free(d_config->vfbs);
-
-    for (i=0; i<d_config->num_vkbs; i++)
-        libxl_device_vkb_destroy(&d_config->vkbs[i]);
-    free(d_config->vkbs);
-
-    libxl_domain_create_info_destroy(&d_config->c_info);
-    libxl_domain_build_info_destroy(&d_config->b_info);
-}
 
 /* Optional data, in order:
  *   4 bytes uint32_t  config file size
@@ -312,164 +249,8 @@ static void dolog(const char *file, int 
         libxl_write_exactly(NULL, logfile, s, rc, NULL, NULL);
 }
 
-static void init_create_info(libxl_domain_create_info *c_info)
-{
-    memset(c_info, '\0', sizeof(*c_info));
-    c_info->xsdata = NULL;
-    c_info->platformdata = NULL;
-    c_info->hap = 1;
-    c_info->hvm = 1;
-    c_info->oos = 1;
-    c_info->ssidref = 0;
-    c_info->poolid = 0;
-}
-
-static void init_build_info(libxl_domain_build_info *b_info, 
libxl_domain_create_info *c_info)
-{
-    memset(b_info, '\0', sizeof(*b_info));
-    b_info->max_vcpus = 1;
-    b_info->max_memkb = 32 * 1024;
-    b_info->target_memkb = b_info->max_memkb;
-    b_info->disable_migrate = 0;
-    b_info->cpuid = NULL;
-    b_info->shadow_memkb = 0;
-    if (c_info->hvm) {
-        b_info->video_memkb = 8 * 1024;
-        b_info->kernel.path = strdup("hvmloader");
-        b_info->hvm = 1;
-        b_info->u.hvm.pae = 1;
-        b_info->u.hvm.apic = 1;
-        b_info->u.hvm.acpi = 1;
-        b_info->u.hvm.nx = 1;
-        b_info->u.hvm.viridian = 0;
-        b_info->u.hvm.hpet = 1;
-        b_info->u.hvm.vpt_align = 1;
-        b_info->u.hvm.timer_mode = 1;
-    } else {
-        b_info->u.pv.slack_memkb = 8 * 1024;
-    }
-}
-
-static void init_dm_info(libxl_device_model_info *dm_info,
-        libxl_domain_create_info *c_info, libxl_domain_build_info *b_info)
-{
-    memset(dm_info, '\0', sizeof(*dm_info));
-
-    libxl_uuid_generate(&dm_info->uuid);
-
-    dm_info->dom_name = strdup(c_info->name);
-    dm_info->device_model = strdup("qemu-dm");
-    dm_info->target_ram = libxl__sizekb_to_mb(b_info->target_memkb);
-    dm_info->videoram = libxl__sizekb_to_mb(b_info->video_memkb);
-    dm_info->apic = b_info->u.hvm.apic;
-    dm_info->vcpus = b_info->max_vcpus;
-    dm_info->vcpu_avail = b_info->cur_vcpus;
-
-    dm_info->stdvga = 0;
-    dm_info->vnc = 1;
-    dm_info->vnclisten = strdup("127.0.0.1");
-    dm_info->vncdisplay = 0;
-    dm_info->vncunused = 1;
-    dm_info->keymap = NULL;
-    dm_info->sdl = 0;
-    dm_info->opengl = 0;
-    dm_info->nographic = 0;
-    dm_info->serial = NULL;
-    dm_info->boot = strdup("cda");
-    dm_info->usb = 0;
-    dm_info->usbdevice = NULL;
-    dm_info->xen_platform_pci = 1;
-}
-
-static void init_nic_info(libxl_device_nic *nic_info, int devnum)
-{
-    const uint8_t *r;
-    libxl_uuid uuid;
-
-    libxl_uuid_generate(&uuid);
-    r = libxl_uuid_bytearray(&uuid);
-    memset(nic_info, '\0', sizeof(*nic_info));
-
-    nic_info->backend_domid = 0;
-    nic_info->domid = 0;
-    nic_info->devid = devnum;
-    nic_info->mtu = 1492;
-    nic_info->model = strdup("e1000");
-    nic_info->mac[0] = 0x00;
-    nic_info->mac[1] = 0x16;
-    nic_info->mac[2] = 0x3e;
-    nic_info->mac[3] = r[0] & 0x7f;
-    nic_info->mac[4] = r[1];
-    nic_info->mac[5] = r[2];
-    nic_info->ifname = NULL;
-    nic_info->bridge = strdup("xenbr0");
-    CHK_ERRNO( asprintf(&nic_info->script, "%s/vif-bridge",
-               libxl_xen_script_dir_path()) );
-    nic_info->nictype = NICTYPE_IOEMU;
-}
-
-static void init_net2_info(libxl_device_net2 *net2_info, int devnum)
-{
-    const uint8_t *r;
-    libxl_uuid uuid;
-
-    libxl_uuid_generate(&uuid);
-    r = libxl_uuid_bytearray(&uuid);
-    memset(net2_info, '\0', sizeof(*net2_info));
-
-    net2_info->devid = devnum;
-    net2_info->front_mac[0] = 0x00;
-    net2_info->front_mac[1] = 0x16;
-    net2_info->front_mac[2] = 0x3e;;
-    net2_info->front_mac[3] = 0x7f & r[0];
-    net2_info->front_mac[4] = r[1];
-    net2_info->front_mac[5] = r[2];
-    net2_info->back_mac[0] = 0x00;
-    net2_info->back_mac[1] = 0x16;
-    net2_info->back_mac[2] = 0x3e;
-    net2_info->back_mac[3] = 0x7f & r[3];
-    net2_info->back_mac[4] = r[4];
-    net2_info->back_mac[5] = r[5];
-    net2_info->back_trusted = 1;
-    net2_info->filter_mac = 1;
-    net2_info->max_bypasses = 5;
-    net2_info->bridge = strdup("xenbr0");
-}
-
-static void init_vfb_info(libxl_device_vfb *vfb, int dev_num)
-{
-    memset(vfb, 0x00, sizeof(libxl_device_vfb));
-    vfb->devid = dev_num;
-    vfb->display = NULL;
-    vfb->xauthority = NULL;
-    vfb->vnc = 1;
-    vfb->vncpasswd = NULL;
-    vfb->vnclisten = strdup("127.0.0.1");
-    vfb->vncdisplay = 0;
-    vfb->vncunused = 1;
-    vfb->keymap = NULL;
-    vfb->sdl = 0;
-    vfb->opengl = 0;
-}
-
-static void init_vkb_info(libxl_device_vkb *vkb, int dev_num)
-{
-    memset(vkb, 0x00, sizeof(libxl_device_vkb));
-    vkb->devid = dev_num;
-}
-
-static void init_console_info(libxl_device_console *console, int dev_num, 
libxl_domain_build_state *state)
-{
-    memset(console, 0x00, sizeof(libxl_device_console));
-    console->devid = dev_num;
-    console->consback = LIBXL_CONSBACK_XENCONSOLED;
-    console->output = strdup("pty");
-    if (state)
-        console->build_state = state;
-}
-
 static void printf_info(int domid,
-                        struct domain_config *d_config,
+                        libxl_domain_config *d_config,
                         libxl_device_model_info *dm_info)
 {
     int i;
@@ -543,6 +324,7 @@ static void printf_info(int domid,
         printf("\t\t\t(vncunused %d)\n", dm_info->vncunused);
         printf("\t\t\t(keymap %s)\n", dm_info->keymap);
         printf("\t\t\t(sdl %d)\n", dm_info->sdl);
+        printf("\t\t\t(gfx_passthru %d)\n", dm_info->gfx_passthru);
         printf("\t\t\t(opengl %d)\n", dm_info->opengl);
         printf("\t\t\t(nographic %d)\n", dm_info->nographic);
         printf("\t\t\t(serial %s)\n", dm_info->serial);
@@ -626,7 +408,7 @@ static void printf_info(int domid,
        printf(")\n");
 }
 
-static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown 
*a)
+static int parse_action_on_shutdown(const char *buf, enum 
libxl_action_on_shutdown *a)
 {
     int i;
     const char *n;
@@ -773,7 +555,7 @@ static void parse_config_data(const char
 static void parse_config_data(const char *configfile_filename_report,
                               const char *configfile_data,
                               int configfile_len,
-                              struct domain_config *d_config,
+                              libxl_domain_config *d_config,
                               libxl_device_model_info *dm_info)
 {
     const char *buf;
@@ -799,7 +581,7 @@ static void parse_config_data(const char
         exit(1);
     }
 
-    init_create_info(c_info);
+    libxl_init_create_info(c_info);
 
     c_info->hvm = 0;
     if (!xlu_cfg_get_string (config, "builder", &buf) &&
@@ -834,7 +616,7 @@ static void parse_config_data(const char
         exit(1);
     }
 
-    init_build_info(b_info, c_info);
+    libxl_init_build_info(b_info, c_info);
 
     /* the following is the actual config parsing with overriding values in 
the structures */
     if (!xlu_cfg_get_long (config, "vcpus", &l)) {
@@ -977,7 +759,7 @@ static void parse_config_data(const char
 
             d_config->vifs = (libxl_device_nic *) realloc(d_config->vifs, 
sizeof (libxl_device_nic) * (d_config->num_vifs+1));
             nic = d_config->vifs + d_config->num_vifs;
-            init_nic_info(nic, d_config->num_vifs);
+            CHK_ERRNO( libxl_device_nic_init(nic, d_config->num_vifs) );
 
             p = strtok(buf2, ",");
             if (!p)
@@ -1054,7 +836,7 @@ skip:
             d_config->vif2s = realloc(d_config->vif2s, sizeof 
(libxl_device_net2) * (d_config->num_vif2s + 1));
             net2 = d_config->vif2s + d_config->num_vif2s;
 
-            init_net2_info(net2, d_config->num_vif2s);
+            libxl_device_net2_init(net2, d_config->num_vif2s);
 
             for (p = strtok(buf2, ","); p; p = strtok(NULL, ",")) {
                 char* val;
@@ -1106,11 +888,11 @@ skip:
 
             d_config->vfbs = (libxl_device_vfb *) realloc(d_config->vfbs, 
sizeof(libxl_device_vfb) * (d_config->num_vfbs + 1));
             vfb = d_config->vfbs + d_config->num_vfbs;
-            init_vfb_info(vfb, d_config->num_vfbs);
+            libxl_device_vfb_init(vfb, d_config->num_vfbs);
 
             d_config->vkbs = (libxl_device_vkb *) realloc(d_config->vkbs, 
sizeof(libxl_device_vkb) * (d_config->num_vkbs + 1));
             vkb = d_config->vkbs + d_config->num_vkbs;
-            init_vkb_info(vkb, d_config->num_vkbs);
+            libxl_device_vkb_init(vkb, d_config->num_vkbs);
 
             p = strtok(buf2, ",");
             if (!p)
@@ -1260,7 +1042,7 @@ skip_vfb:
 
     if (c_info->hvm == 1) {
         /* init dm from c and b */
-        init_dm_info(dm_info, c_info, b_info);
+        libxl_init_dm_info(dm_info, c_info, b_info);
 
         /* then process config related to dm */
         xlu_cfg_replace_string (config, "device_model", 
&dm_info->device_model);
@@ -1281,6 +1063,8 @@ skip_vfb:
             dm_info->opengl = l;
         if (!xlu_cfg_get_long (config, "nographic", &l))
             dm_info->nographic = l;
+        if (!xlu_cfg_get_long (config, "gfx_passthru", &l))
+            dm_info->gfx_passthru = l;
         xlu_cfg_replace_string (config, "serial", &dm_info->serial);
         xlu_cfg_replace_string (config, "boot", &dm_info->boot);
         if (!xlu_cfg_get_long (config, "usb", &l))
@@ -1316,32 +1100,12 @@ static void *xrealloc(void *ptr, size_t 
     return r;
 }
 
-static pid_t autoconnect_console(void)
-{
-    pid_t pid;
-
-    pid = fork();
-    if (pid < 0) {
-        perror("unable to fork xenconsole");
-        return ERROR_FAIL;
-    } else if (pid > 0)
-        return pid;
-
-    libxl_ctx_postfork(&ctx);
-
-    sleep(1);
-    libxl_primary_console_exec(&ctx, domid);
-    /* Do not return. xl continued in child process */
-    fprintf(stderr, "Unable to attach console\n");
-    _exit(1);
-}
-
 /* Returns 1 if domain should be restarted, 2 if domain should be renamed then 
restarted  */
 static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event 
*event,
-                               struct domain_config *d_config, libxl_dominfo 
*info)
+                               libxl_domain_config *d_config, libxl_dominfo 
*info)
 {
     int restart = 0;
-    enum action_on_shutdown action;
+    enum libxl_action_on_shutdown action;
 
     switch (info->shutdown_reason) {
     case SHUTDOWN_poweroff:
@@ -1360,12 +1124,12 @@ static int handle_domain_death(libxl_ctx
         break;
     default:
         LOG("Unknown shutdown reason code %d. Destroying domain.", 
info->shutdown_reason);
-        action = ACTION_DESTROY;
+        action = LIBXL_ACTION_DESTROY;
     }
 
     LOG("Action for shutdown reason code %d is %s", info->shutdown_reason, 
action_on_shutdown_names[action]);
 
-    if (action == ACTION_COREDUMP_DESTROY || action == 
ACTION_COREDUMP_RESTART) {
+    if (action == LIBXL_ACTION_COREDUMP_DESTROY || action == 
LIBXL_ACTION_COREDUMP_RESTART) {
         char *corefile;
         int rc;
 
@@ -1378,30 +1142,30 @@ static int handle_domain_death(libxl_ctx
         }
         /* No point crying over spilled milk, continue on failure. */
 
-        if (action == ACTION_COREDUMP_DESTROY)
-            action = ACTION_DESTROY;
+        if (action == LIBXL_ACTION_COREDUMP_DESTROY)
+            action = LIBXL_ACTION_DESTROY;
         else
-            action = ACTION_RESTART;
+            action = LIBXL_ACTION_RESTART;
     }
 
     switch (action) {
-    case ACTION_PRESERVE:
+    case LIBXL_ACTION_PRESERVE:
         break;
 
-    case ACTION_RESTART_RENAME:
+    case LIBXL_ACTION_RESTART_RENAME:
         restart = 2;
         break;
 
-    case ACTION_RESTART:
+    case LIBXL_ACTION_RESTART:
         restart = 1;
         /* fall-through */
-    case ACTION_DESTROY:
+    case LIBXL_ACTION_DESTROY:
         LOG("Domain %d needs to be cleaned up: destroying the domain", domid);
         libxl_domain_destroy(ctx, domid, 0);
         break;
 
-    case ACTION_COREDUMP_DESTROY:
-    case ACTION_COREDUMP_RESTART:
+    case LIBXL_ACTION_COREDUMP_DESTROY:
+    case LIBXL_ACTION_COREDUMP_RESTART:
         /* Already handled these above. */
         abort();
     }
@@ -1410,7 +1174,7 @@ static int handle_domain_death(libxl_ctx
 }
 
 static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
-                           struct domain_config *d_config, libxl_dominfo *info)
+                           libxl_domain_config *d_config, libxl_dominfo *info)
 {
     time_t now;
     struct tm tm;
@@ -1501,12 +1265,29 @@ static int freemem(libxl_domain_build_in
     return ERROR_NOMEM;
 }
 
+static int autoconnect_console(libxl_ctx *ctx, uint32_t domid, void *priv)
+{
+    pid_t *pid = priv;
+
+    *pid = fork();
+    if (*pid < 0) {
+        perror("unable to fork xenconsole");
+        return ERROR_FAIL;
+    } else if (*pid > 0)
+        return 0;
+
+    libxl_ctx_postfork(ctx);
+
+    sleep(1);
+    libxl_primary_console_exec(ctx, domid);
+    /* Do not return. xl continued in child process */
+    fprintf(stderr, "Unable to attach console\n");
+    _exit(1);
+}
+
 static int create_domain(struct domain_create *dom_info)
 {
-    struct domain_config d_config;
-
-    libxl_domain_build_state state;
-    libxl_device_model_info dm_info;
+    libxl_domain_config d_config;
 
     int debug = dom_info->debug;
     int daemonize = dom_info->daemonize;
@@ -1516,20 +1297,19 @@ static int create_domain(struct domain_c
     const char *restore_file = dom_info->restore_file;
     int migrate_fd = dom_info->migrate_fd;
 
-    int i, fd;
+    int fd;
     int need_daemon = 1;
     int ret, rc;
-    libxl_device_model_starting *dm_starting = 0;
     libxl_waiter *w1 = NULL, *w2 = NULL;
     void *config_data = 0;
     int config_len = 0;
     int restore_fd = -1;
+    int status = 0;
+    libxl_console_ready cb;
+    pid_t child_console_pid = -1;
     struct save_file_header hdr;
-    pid_t child_console_pid = -1;
-    int status = 0;
 
     memset(&d_config, 0x00, sizeof(d_config));
-    memset(&dm_info, 0x00, sizeof(dm_info));
 
     if (restore_file) {
         uint8_t *optdata_begin = 0;
@@ -1629,7 +1409,7 @@ static int create_domain(struct domain_c
     if (!dom_info->quiet)
         printf("Parsing config file %s\n", config_file);
 
-    parse_config_data(config_file, config_data, config_len, &d_config, 
&dm_info);
+    parse_config_data(config_file, config_data, config_len, &d_config, 
&d_config.dm_info);
 
     ret = 0;
     if (dom_info->dryrun)
@@ -1654,7 +1434,7 @@ static int create_domain(struct domain_c
     }
 
     if (debug)
-        printf_info(-1, &d_config, &dm_info);
+        printf_info(-1, &d_config, &d_config.dm_info);
 
 start:
     domid = 0;
@@ -1663,16 +1443,9 @@ start:
     if (rc < 0)
         goto error_out;
 
-    ret = freemem(&d_config.b_info, &dm_info);
+    ret = freemem(&d_config.b_info, &d_config.dm_info);
     if (ret < 0) {
         fprintf(stderr, "failed to free memory for the domain\n");
-        ret = ERROR_FAIL;
-        goto error_out;
-    }
-
-    ret = libxl_domain_make(&ctx, &d_config.c_info, &domid);
-    if (ret) {
-        fprintf(stderr, "cannot make domain: %d\n", ret);
         ret = ERROR_FAIL;
         goto error_out;
     }
@@ -1685,116 +1458,22 @@ start:
         goto error_out;
     }
 
-    if (dom_info->console_autoconnect && !d_config.c_info.hvm) {
-        child_console_pid = autoconnect_console();
-        if (child_console_pid < 0)
-            goto error_out;
-    }
-
-    if (!restore_file) {
-        ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks 
> 0 ? &d_config.disks[0] : NULL, domid);
-        if (ret) {
-            fprintf(stderr, "failed to run bootloader: %d\n", ret);
-            goto error_out;
-        }
-    }
-
-    if (!restore_file || !need_daemon) {
-        if (dm_info.saved_state) {
-            free(dm_info.saved_state);
-            dm_info.saved_state = NULL;
-        }
-        ret = libxl_domain_build(&ctx, &d_config.b_info, domid, &state);
-    } else {
-        ret = libxl_domain_restore(&ctx, &d_config.b_info, domid, restore_fd, 
&state, &dm_info);
-    }
-
-    if (ret) {
-        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
-        ret = ERROR_FAIL;
+    if ( dom_info->console_autoconnect ) {
+        cb = autoconnect_console;
+    }else{
+        cb = NULL;
+    }
+
+    if ( restore_file ) {
+        ret = libxl_domain_create_restore(&ctx, &d_config,
+                                            cb, &child_console_pid,
+                                            &domid, restore_fd);
+    }else{
+        ret = libxl_domain_create_new(&ctx, &d_config,
+                                        cb, &child_console_pid, &domid);
+    }
+    if ( ret )
         goto error_out;
-    }
-
-    for (i = 0; i < d_config.num_disks; i++) {
-        d_config.disks[i].domid = domid;
-        ret = libxl_device_disk_add(&ctx, domid, &d_config.disks[i]);
-        if (ret) {
-            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
-    }
-    for (i = 0; i < d_config.num_vifs; i++) {
-        d_config.vifs[i].domid = domid;
-        ret = libxl_device_nic_add(&ctx, domid, &d_config.vifs[i]);
-        if (ret) {
-            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
-    }
-    if (!d_config.c_info.hvm) {
-        for (i = 0; i < d_config.num_vif2s; i++) {
-            d_config.vif2s[i].domid = domid;
-            ret = libxl_device_net2_add(&ctx, domid, &d_config.vif2s[i]);
-            if (ret) {
-                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
-                ret = ERROR_FAIL;
-                goto error_out;
-            }
-        }
-    }
-    if (d_config.c_info.hvm) {
-        libxl_device_console console;
-
-        init_console_info(&console, 0, &state);
-        console.domid = domid;
-        libxl_device_console_add(&ctx, domid, &console);
-        libxl_device_console_destroy(&console);
-
-        dm_info.domid = domid;
-        MUST( libxl_create_device_model(&ctx, &dm_info,
-                                        d_config.disks, d_config.num_disks,
-                                        d_config.vifs, d_config.num_vifs,
-                                        &dm_starting) );
-    } else {
-        int need_qemu = 0;
-        libxl_device_console console;
-
-        for (i = 0; i < d_config.num_vfbs; i++) {
-            d_config.vfbs[i].domid = domid;
-            libxl_device_vfb_add(&ctx, domid, &d_config.vfbs[i]);
-            d_config.vkbs[i].domid = domid;
-            libxl_device_vkb_add(&ctx, domid, &d_config.vkbs[i]);
-        }
-
-        init_console_info(&console, 0, &state);
-        console.domid = domid;
-
-        need_qemu = libxl_need_xenpv_qemu(&ctx, 1, &console,
-                d_config.num_vfbs, d_config.vfbs,
-                d_config.num_disks, &d_config.disks[0]);
-
-        if (need_qemu)
-             console.consback = LIBXL_CONSBACK_IOEMU;
-
-        libxl_device_console_add(&ctx, domid, &console);
-        libxl_device_console_destroy(&console);
-
-        if (need_qemu)
-            libxl_create_xenpv_qemu(&ctx, domid, d_config.vfbs, &dm_starting);
-    }
-
-    if (dm_starting)
-        MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) );
-    for (i = 0; i < d_config.num_pcidevs; i++)
-        libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]);
-
-    if (dom_info->console_autoconnect && d_config.c_info.hvm) {
-        child_console_pid = autoconnect_console();
-        if (child_console_pid < 0)
-            goto error_out;
-    }
 
     release_lock();
 
@@ -1812,6 +1491,8 @@ start:
 
         child1 = libxl_fork(&ctx);
         if (child1) {
+            printf("Daemon running with PID %d\n", child1);
+
             for (;;) {
                 got_child = waitpid(child1, &status, 0);
                 if (got_child == child1) break;
@@ -1953,9 +1634,7 @@ out:
     if (logfile != 2)
         close(logfile);
 
-    libxl_device_model_info_destroy(&dm_info);
-
-    free_domain_config(&d_config);
+    libxl_domain_config_destroy(&d_config);
 
     free(config_data);
 
@@ -2550,7 +2229,7 @@ static void reboot_domain(const char *p)
 
 static void list_domains_details(const libxl_dominfo *info, int nb_domain)
 {
-    struct domain_config d_config;
+    libxl_domain_config d_config;
 
     char *config_file;
     uint8_t *data;
@@ -2568,7 +2247,7 @@ static void list_domains_details(const l
         memset(&d_config, 0x00, sizeof(d_config));
         parse_config_data(config_file, (char *)data, len, &d_config, &dm_info);
         printf_info(info[i].domid, &d_config, &dm_info);
-        free_domain_config(&d_config);
+        libxl_domain_config_destroy(&d_config);
         free(data);
         free(config_file);
     }
@@ -4500,7 +4179,7 @@ int main_networkattach(int argc, char **
         fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
         return 1;
     }
-    init_nic_info(&nic, -1);
+    libxl_device_nic_init(&nic, -1);
     for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) {
         if (!strncmp("type=", *argv, 5)) {
             if (!strncmp("vif", (*argv) + 5, 4)) {
@@ -4834,7 +4513,7 @@ int main_network2attach(int argc, char *
         fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
         return 1;
     }
-    init_net2_info(&net2, -1);
+    libxl_device_net2_init(&net2, -1);
     for (argv += optind+1, argc -= optind+1; argc > 0; --argc, ++argv) {
         if (!strncmp("front_mac=", *argv, 10)) {
             tok = strtok((*argv) + 10, ":");
diff -r cb94dbe20f97 -r 548c29920f68 tools/ocaml/libs/xl/xl_stubs.c
--- a/tools/ocaml/libs/xl/xl_stubs.c    Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/ocaml/libs/xl/xl_stubs.c    Tue Jan 11 19:41:53 2011 +0000
@@ -68,16 +68,6 @@ void log_destroy(struct xentoollog_logge
        caml_leave_blocking_section(); \
        libxl_ctx_free(&ctx)
 
-static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size)
-{
-       void *ptr;
-       ptr = calloc(nmemb, size);
-       if (!ptr)
-               caml_raise_out_of_memory();
-       gc->ptrs[gc->offset++] = ptr;
-       return ptr;
-}
-
 static char * dup_String_val(caml_gc *gc, value s)
 {
        int len;
@@ -104,6 +94,17 @@ void failwith_xl(char *fname, struct cam
        char *s;
        s = (lg) ? lg->log_buf : fname;
        caml_raise_with_string(*caml_named_value("xl.error"), s);
+}
+
+#if 0 /* TODO: wrap libxl_domain_create(), these functions will be needed then 
*/
+static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size)
+{
+       void *ptr;
+       ptr = calloc(nmemb, size);
+       if (!ptr)
+               caml_raise_out_of_memory();
+       gc->ptrs[gc->offset++] = ptr;
+       return ptr;
 }
 
 static int string_string_tuple_array_val (caml_gc *gc, char ***c_val, value v)
@@ -163,7 +164,7 @@ static int domain_build_info_val (caml_g
        c_val->video_memkb = Int64_val(Field(v, 4));
        c_val->shadow_memkb = Int64_val(Field(v, 5));
        c_val->kernel.path = dup_String_val(gc, Field(v, 6));
-       c_val->hvm = Tag_val(Field(v, 7)) == 0;
+       c_val->is_hvm = Tag_val(Field(v, 7)) == 0;
        infopriv = Field(Field(v, 7), 0);
        if (c_val->hvm) {
                c_val->u.hvm.pae = Bool_val(Field(infopriv, 0));
@@ -184,6 +185,7 @@ static int domain_build_info_val (caml_g
 
        CAMLreturn(0);
 }
+#endif
 
 static int device_disk_val(caml_gc *gc, libxl_device_disk *c_val, value v)
 {
@@ -332,21 +334,6 @@ static value Val_sched_credit(libxl_sche
        CAMLreturn(v);
 }
 
-static value Val_domain_build_state(libxl_domain_build_state *c_val)
-{
-       CAMLparam0();
-       CAMLlocal1(v);
-
-       v = caml_alloc_tuple(4);
-
-       Store_field(v, 0, Val_int(c_val->store_port));
-       Store_field(v, 1, caml_copy_int64(c_val->store_mfn));
-       Store_field(v, 2, Val_int(c_val->console_port));
-       Store_field(v, 3, caml_copy_int64(c_val->console_mfn));
-
-       CAMLreturn(v);
-}
-
 static value Val_physinfo(libxl_physinfo *c_val)
 {
        CAMLparam0();
@@ -373,52 +360,6 @@ static value Val_physinfo(libxl_physinfo
        CAMLreturn(v);
 }
 
-value stub_xl_domain_make(value info)
-{
-       CAMLparam1(info);
-       uint32_t domid;
-       libxl_domain_create_info c_info;
-       int ret;
-       INIT_STRUCT();
-
-       domain_create_info_val (&gc, &c_info, info);
-
-       INIT_CTX();
-
-       ret = libxl_domain_make(&ctx, &c_info, &domid);
-       if (ret != 0)
-               failwith_xl("domain make", &lg);
-
-       FREE_CTX();
-
-       CAMLreturn(Val_int(domid));
-}
-
-value stub_xl_domain_build(value info, value domid)
-{
-       CAMLparam2(info, domid);
-       CAMLlocal1(result);
-       libxl_domain_build_info c_info;
-       libxl_domain_build_state c_state;
-       int ret;
-       int c_domid;
-       INIT_STRUCT();
-
-       domain_build_info_val (&gc, &c_info, info);
-       c_domid = Int_val(domid);
-
-       INIT_CTX();
-
-       ret = libxl_domain_build(&ctx, &c_info, c_domid, &c_state);
-       if (ret != 0)
-               failwith_xl("domain_build", &lg);
-
-       result = Val_domain_build_state(&c_state);
-       FREE_CTX();
-
-       CAMLreturn(result);
-}
-
 value stub_xl_disk_add(value info, value domid)
 {
        CAMLparam2(info, domid);
diff -r cb94dbe20f97 -r 548c29920f68 tools/python/genwrap.py
--- a/tools/python/genwrap.py   Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/python/genwrap.py   Tue Jan 11 19:41:53 2011 +0000
@@ -51,7 +51,10 @@ def py_attrib_get(ty, f):
     l.append('static PyObject *py_%s_%s_get(Py_%s *self, void 
*priv)'%(ty.rawname, f.name, ty.rawname))
     l.append('{')
     if t == TYPE_BOOL:
-        l.append('    return (self->obj.%s) ? Py_True : Py_False;'%f.name)
+        l.append('    PyObject *ret;')
+        l.append('    ret = (self->obj.%s) ? Py_True : Py_False;'%f.name)
+        l.append('    Py_INCREF(ret);')
+        l.append('    return ret;')
     elif t == TYPE_INT:
         l.append('    return genwrap__ll_get(self->obj.%s);'%f.name)
     elif t == TYPE_UINT:
@@ -148,7 +151,7 @@ static PyTypeObject Py%s_Type= {
     NULL,                         /* tp_getattro       */
     NULL,                         /* tp_setattro       */
     NULL,                         /* tp_as_buffer      */
-    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
+    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags          */
     "%s",                         /* tp_doc            */
     NULL,                         /* tp_traverse       */
     NULL,                         /* tp_clear          */
diff -r cb94dbe20f97 -r 548c29920f68 tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/python/xen/lowlevel/xl/xl.c Tue Jan 11 19:41:53 2011 +0000
@@ -76,7 +76,7 @@ int genwrap__string_set(PyObject *v, cha
 int genwrap__string_set(PyObject *v, char **str)
 {
     char *tmp;
-    if ( NULL == v ) {
+    if ( NULL == v || Py_None == v ) {
         free(*str);
         *str = NULL;
         return 0;
@@ -97,8 +97,10 @@ int genwrap__string_set(PyObject *v, cha
 
 PyObject *genwrap__string_get(char **str)
 {
-    if ( NULL == *str )
+    if ( NULL == *str ) {
+        Py_INCREF(Py_None);
         return Py_None;
+    }
     return PyString_FromString(*str);
 }
 
@@ -209,6 +211,7 @@ static PyObject *fixed_bytearray_get(con
 
 int attrib__libxl_cpuid_policy_list_set(PyObject *v, libxl_cpuid_policy_list 
*pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Setting cpuid_policy_list");
     return -1;
 }
 
@@ -231,46 +234,57 @@ int attrib__libxl_cpuarray_set(PyObject 
 
 int attrib__libxl_domain_build_state_ptr_set(PyObject *v, 
libxl_domain_build_state **pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Setting 
domain_build_state_ptr");
     return -1;
 }
 
 int attrib__libxl_file_reference_set(PyObject *v, libxl_file_reference *pptr)
 {
+    return genwrap__string_set(v, &pptr->path);
+}
+
+int attrib__libxl_hwcap_set(PyObject *v, libxl_hwcap *pptr)
+{
+    PyErr_SetString(PyExc_NotImplementedError, "Setting hwcap");
     return -1;
 }
 
-int attrib__libxl_hwcap_set(PyObject *v, libxl_hwcap *pptr)
-{
+int attrib__libxl_key_value_list_set(PyObject *v, libxl_key_value_list *pptr)
+{
+    if ( *pptr ) {
+        libxl_key_value_list_destroy(pptr);
+        *pptr = NULL;
+    }
+    if ( v == Py_None )
+        return 0;
     return -1;
 }
 
-int attrib__libxl_key_value_list_set(PyObject *v, libxl_key_value_list *pptr)
-{
+int attrib__libxl_mac_set(PyObject *v, libxl_mac *pptr)
+{
+    return fixed_bytearray_set(v, *pptr, 6);
+}
+
+int attrib__libxl_string_list_set(PyObject *v, libxl_string_list *pptr)
+{
+    PyErr_SetString(PyExc_NotImplementedError, "Setting string_list");
     return -1;
 }
 
-int attrib__libxl_mac_set(PyObject *v, libxl_mac *pptr)
-{
-    return fixed_bytearray_set(v, *pptr, 6);
-}
-
-int attrib__libxl_string_list_set(PyObject *v, libxl_string_list *pptr)
-{
+int attrib__libxl_uuid_set(PyObject *v, libxl_uuid *pptr)
+{
+    return fixed_bytearray_set(v, libxl_uuid_bytearray(pptr), 16);
+}
+
+int attrib__struct_in_addr_set(PyObject *v, struct in_addr *pptr)
+{
+    PyErr_SetString(PyExc_NotImplementedError, "Setting in_addr");
     return -1;
 }
 
-int attrib__libxl_uuid_set(PyObject *v, libxl_uuid *pptr)
-{
-    return fixed_bytearray_set(v, libxl_uuid_bytearray(pptr), 16);
-}
-
-int attrib__struct_in_addr_set(PyObject *v, struct in_addr *pptr)
-{
-    return -1;
-}
-
 PyObject *attrib__libxl_cpuid_policy_list_get(libxl_cpuid_policy_list *pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Getting cpuid_policy_list");
     return NULL;
 }
 
@@ -312,21 +326,24 @@ PyObject *attrib__libxl_cpuarray_get(lib
 
 PyObject *attrib__libxl_domain_build_state_ptr_get(libxl_domain_build_state 
**pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Getting 
domain_build_state_ptr");
     return NULL;
 }
 
 PyObject *attrib__libxl_file_reference_get(libxl_file_reference *pptr)
 {
-    return NULL;
+    return genwrap__string_get(&pptr->path);
 }
 
 PyObject *attrib__libxl_hwcap_get(libxl_hwcap *pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Getting hwcap");
     return NULL;
 }
 
 PyObject *attrib__libxl_key_value_list_get(libxl_key_value_list *pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Getting key_value_list");
     return NULL;
 }
 
@@ -337,6 +354,7 @@ PyObject *attrib__libxl_mac_get(libxl_ma
 
 PyObject *attrib__libxl_string_list_get(libxl_string_list *pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Getting string_list");
     return NULL;
 }
 
@@ -347,6 +365,7 @@ PyObject *attrib__libxl_uuid_get(libxl_u
 
 PyObject *attrib__struct_in_addr_get(struct in_addr *pptr)
 {
+    PyErr_SetString(PyExc_NotImplementedError, "Getting in_addr");
     return NULL;
 }
 
@@ -377,6 +396,7 @@ static PyObject *pyxl_list_domains(XlObj
         if ( NULL == di )
             goto err_mem;
         memcpy(&di->obj, cur, sizeof(di->obj));
+        /* SetItem steals a reference */
         PyList_SetItem(list, i, (PyObject *)di);
     }
 
@@ -413,6 +433,7 @@ static PyObject *pyxl_domain_shutdown(Xl
         PyErr_SetString(xl_error_obj, "cannot shutdown domain");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -425,6 +446,7 @@ static PyObject *pyxl_domain_destroy(XlO
         PyErr_SetString(xl_error_obj, "cannot destroy domain");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -437,6 +459,7 @@ static PyObject *pyxl_domain_pause(XlObj
         PyErr_SetString(xl_error_obj, "cannot pause domain");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -449,6 +472,7 @@ static PyObject *pyxl_domain_unpause(XlO
         PyErr_SetString(xl_error_obj, "cannot unpause domain");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -462,6 +486,7 @@ static PyObject *pyxl_domain_rename(XlOb
         PyErr_SetString(xl_error_obj, "cannot rename domain");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -481,6 +506,7 @@ static PyObject *pyxl_pci_add(XlObject *
         PyErr_SetString(xl_error_obj, "cannot add pci device");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -501,6 +527,7 @@ static PyObject *pyxl_pci_del(XlObject *
         PyErr_SetString(xl_error_obj, "cannot remove pci device");
         return NULL;
     }
+    Py_INCREF(Py_None);
     return Py_None;
 }
 
@@ -525,6 +552,75 @@ static PyObject *pyxl_pci_parse(XlObject
     }
 
     return (PyObject *)pci;
+}
+
+static PyObject *pyxl_pci_list_assignable(XlObject *self, PyObject *args)
+{
+    libxl_device_pci *dev;
+    PyObject *list;
+    int nr_dev, i;
+
+    if ( libxl_device_pci_list_assignable(&self->ctx, &dev, &nr_dev) ) {
+        PyErr_SetString(xl_error_obj, "Cannot list assignable devices");
+        return NULL;
+    }
+
+    list = PyList_New(nr_dev);
+    if ( NULL == list )
+        return NULL;
+
+    for(i = 0; i < nr_dev; i++) {
+        Py_device_pci *pd;
+        pd = Pydevice_pci_New();
+        if ( NULL == pd )
+            goto err_mem;
+        memcpy(&pd->obj, &dev[i], sizeof(pd->obj));
+        /* SetItem steals a reference */
+        PyList_SetItem(list, i, (PyObject *)pd);
+    }
+
+    free(dev);
+    return list;
+err_mem:
+    Py_DECREF(list);
+    PyErr_SetString(PyExc_MemoryError, "Allocating PCI device list");
+    return NULL;
+}
+
+static PyObject *pyxl_pci_list(XlObject *self, PyObject *args)
+{
+    libxl_device_pci *dev;
+    PyObject *list;
+    int nr_dev, i, domid;
+
+    if ( !PyArg_ParseTuple(args, "i", &domid) )
+        return NULL;
+
+    if ( libxl_device_pci_list_assigned(&self->ctx, &dev, domid, &nr_dev) ) {
+        PyErr_SetString(xl_error_obj, "Cannot list assignable devices");
+        return NULL;
+    }
+
+    list = PyList_New(nr_dev);
+    if ( NULL == list )
+        return NULL;
+
+    for(i = 0; i < nr_dev; i++) {
+        Py_device_pci *pd;
+        pd = Pydevice_pci_New();
+        if ( NULL == pd )
+            goto err_mem;
+        memcpy(&pd->obj, &dev[i], sizeof(pd->obj));
+        /* SetItem steals a reference */
+        PyList_SetItem(list, i, (PyObject *)pd);
+    }
+
+    free(dev);
+    return list;
+err_mem:
+    Py_DECREF(list);
+    PyErr_SetString(PyExc_MemoryError, "Allocating PCI device list");
+    return NULL;
 }
 
 static PyMethodDef pyxl_methods[] = {
@@ -536,9 +632,9 @@ static PyMethodDef pyxl_methods[] = {
          "Shutdown a domain"},
     {"domain_destroy", (PyCFunction)pyxl_domain_destroy, METH_VARARGS,
          "Destroy a domain"},
-    {"domain_pause", (PyCFunction)pyxl_domain_unpause, METH_VARARGS,
+    {"domain_pause", (PyCFunction)pyxl_domain_pause, METH_VARARGS,
          "Pause a domain"},
-    {"domain_unpause", (PyCFunction)pyxl_domain_pause, METH_VARARGS,
+    {"domain_unpause", (PyCFunction)pyxl_domain_unpause, METH_VARARGS,
          "Unpause a domain"},
     {"domain_rename", (PyCFunction)pyxl_domain_rename, METH_VARARGS,
          "Rename a domain"},
@@ -548,6 +644,11 @@ static PyMethodDef pyxl_methods[] = {
          "Remove a pass-through PCI device"},
     {"device_pci_parse_bdf", (PyCFunction)pyxl_pci_parse, METH_VARARGS,
          "Parse pass-through PCI device spec (BDF)"},
+    {"device_pci_list", (PyCFunction)pyxl_pci_list, METH_VARARGS,
+        "List PCI devices assigned to a domain"},
+    {"device_pci_list_assignable",
+        (PyCFunction)pyxl_pci_list_assignable, METH_NOARGS,
+        "List assignable PCI devices"},
     { NULL, NULL, 0, NULL }
 };
 
@@ -618,7 +719,7 @@ static PyTypeObject PyXlType = {
     NULL,                         /* tp_getattro       */
     NULL,                         /* tp_setattro       */
     NULL,                         /* tp_as_buffer      */
-    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
+    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags          */
     "libxenlight connection",     /* tp_doc            */
     NULL,                         /* tp_traverse       */
     NULL,                         /* tp_clear          */
@@ -641,6 +742,8 @@ static PyTypeObject PyXlType = {
 
 static PyMethodDef xl_methods[] = { { NULL } };
 
+#define  _INT_CONST(m, c) PyModule_AddIntConstant(m, #c, c)
+#define  _INT_CONST_LIBXL(m, c) PyModule_AddIntConstant(m, #c, LIBXL_ ## c)
 PyMODINIT_FUNC initxl(void)
 {
     PyObject *m;
@@ -661,6 +764,36 @@ PyMODINIT_FUNC initxl(void)
     Py_INCREF(xl_error_obj);
     PyModule_AddObject(m, "Error", xl_error_obj);
 
+    _INT_CONST(m, SHUTDOWN_poweroff);
+    _INT_CONST(m, SHUTDOWN_reboot);
+    _INT_CONST(m, SHUTDOWN_suspend);
+    _INT_CONST(m, SHUTDOWN_crash);
+    _INT_CONST(m, SHUTDOWN_watchdog);
+
+    _INT_CONST(m, XENFV);
+    _INT_CONST(m, XENPV);
+
+    _INT_CONST_LIBXL(m, CONSTYPE_SERIAL);
+    _INT_CONST_LIBXL(m, CONSTYPE_PV);
+
+    _INT_CONST_LIBXL(m, CONSBACK_XENCONSOLED);
+    _INT_CONST_LIBXL(m, CONSBACK_IOEMU);
+
+    _INT_CONST(m, PHYSTYPE_QCOW);
+    _INT_CONST(m, PHYSTYPE_QCOW2);
+    _INT_CONST(m, PHYSTYPE_VHD);
+    _INT_CONST(m, PHYSTYPE_AIO);
+    _INT_CONST(m, PHYSTYPE_FILE);
+    _INT_CONST(m, PHYSTYPE_PHY);
+
+    _INT_CONST(m, NICTYPE_IOEMU);
+    _INT_CONST(m, NICTYPE_VIF);
+
+    _INT_CONST_LIBXL(m, EVENT_DOMAIN_DEATH);
+    _INT_CONST_LIBXL(m, EVENT_DISK_EJECT);
+
+    _INT_CONST(m, POWER_BUTTON);
+    _INT_CONST(m, SLEEP_BUTTON);
     genwrap__init(m);
 }
 
diff -r cb94dbe20f97 -r 548c29920f68 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Tue Jan 11 19:41:53 2011 +0000
@@ -498,6 +498,10 @@ class XendConfig(dict):
             if os.path.dirname(self['platform']['device_model']) == "":
                 self['platform']['device_model'] = \
                     auxbin.pathTo(self['platform']['device_model'])
+            # If the device_model is not set the os.path.exists() would raise
+            # an exception so we return our error message instead if applicable
+            if not self['platform']['device_model']:
+                raise VmError("No valid device model specified")
             if not os.path.exists(self['platform']['device_model']):
                 raise VmError("device model '%s' not found" % 
str(self['platform']['device_model']))
 
diff -r cb94dbe20f97 -r 548c29920f68 tools/xenpaging/xc.c
--- a/tools/xenpaging/xc.c      Tue Jan 11 19:31:41 2011 +0000
+++ b/tools/xenpaging/xc.c      Tue Jan 11 19:41:53 2011 +0000
@@ -62,7 +62,7 @@ int xc_mem_paging_flush_ioemu_cache(domi
 
     xs_daemon_close(xsh);
 
-    return rc;
+    return rc ? 0 : -1;
 }
 
 int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned 
long ms)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.