WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[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

<Prev in Thread] Current Thread [Next in Thread>