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-devel

[Xen-devel] [PATCH 0/1] backport libxl from xen-unstable to xen-4.0-test

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 0/1] backport libxl from xen-unstable to xen-4.0-testing
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Mon, 5 Jul 2010 12:39:37 +0100
Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Delivery-date: Mon, 05 Jul 2010 04:40:11 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Hi,

Following patch does what it says on the tin. It's a straightforward
backport of libxl to xen-4.0-testing. This buys harmony of functionality
between the two trees with the minimal of disruption to anything outside
tools/libxl.

The backport is therefore modulo features such as blktap2, vif2,
cpupools, numa, sched2, libxc logging API changes and so forth. To ease
review process I have attached a patch between the post-backport libxl.
DO NOT ATTEMPT TO APPLY THIS ONE :)

Makefile         |    4 
 libxl.c          |  320 +++++++++++++++++++++++++++++++++++++++++--------------
 libxl.h          |   57 ++++++++-
 libxl_device.c   |    6 -
 libxl_dom.c      |    6 -
 libxl_exec.c     |    3 
 libxl_internal.c |   44 +++----
 libxl_internal.h |   25 +++-
 libxl_utils.c    |   86 ++++++++++++++
 libxl_utils.h    |   11 -
 xenguest.c       |    2 
 xl.c             |   45 ++++---
 xl.h             |   12 +-
 xl_cmdimpl.c     |  300 +++++++++++++++++++++++++++++++++++++++++++++++++--
 xl_cmdtable.c    |   18 +++
 15 files changed, 777 insertions(+), 162 deletions(-)

diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl.c 
xen-unstable.hg/tools/libxl/libxl.c
--- xen-4.0-testing.hg/tools/libxl/libxl.c      2010-07-02 18:48:29.707283003 
+0100
+++ xen-unstable.hg/tools/libxl/libxl.c 2010-06-30 17:01:42.750781923 +0100
@@ -33,28 +33,34 @@
 #include "libxl_utils.h"
 #include "libxl_internal.h"
 #include "flexarray.h"
+#include "tap-ctl.h"
 
 #define PAGE_TO_MEMKB(pages) ((pages) * 4)
 
-int libxl_ctx_init(struct libxl_ctx *ctx, int version)
+int libxl_ctx_init(struct libxl_ctx *ctx, int version, xentoollog_logger *lg)
 {
     if (version != LIBXL_VERSION)
         return ERROR_VERSION;
     memset(ctx, 0, sizeof(struct libxl_ctx));
+    ctx->lg = lg;
     ctx->alloc_maxsize = 256;
     ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *));
     if (!ctx->alloc_ptrs)
         return ERROR_NOMEM;
     memset(&ctx->version_info, 0, sizeof(libxl_version_info));
 
-    ctx->xch = xc_interface_open();
-    if (ctx->xch == -1) {
+    ctx->xch = xc_interface_open(lg,lg,0);
+    if (!ctx->xch) {
+        XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, 
+                        "cannot open libxc handle");
         free(ctx->alloc_ptrs);
         return ERROR_FAIL;
     }
 
     ctx->xsh = xs_daemon_open();
     if (!ctx->xsh) {
+        XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, 
+                        "cannot connect to xenstore");
         xc_interface_close(ctx->xch);
         free(ctx->alloc_ptrs);
         return ERROR_FAIL;
@@ -71,13 +77,6 @@ int libxl_ctx_free(struct libxl_ctx *ctx
     return 0;
 }
 
-int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, 
void *log_data)
-{
-    ctx->log_callback = log_callback;
-    ctx->log_userdata = log_data;
-    return 0;
-}
-
 
/******************************************************************************/
 
 int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info,
@@ -111,6 +110,12 @@ int libxl_domain_make(struct libxl_ctx *
         return ERROR_FAIL;
     }
 
+    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
+    if (ret < 0) {
+        XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain move fail");
+        return ERROR_FAIL;
+    }
+
     dom_path = libxl_xs_get_dompath(ctx, *domid);
     if (!dom_path)
         return ERROR_FAIL;
@@ -163,6 +168,8 @@ retry_transaction:
 
     xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, 
strlen(uuid_string));
     xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, 
strlen(info->name));
+    if (info->poolname)
+        xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/pool_name", vm_path), 
info->poolname, strlen(info->poolname));
 
     libxl_xs_writev(ctx, t, dom_path, info->xsdata);
     libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), 
info->platformdata);
@@ -443,6 +450,26 @@ int libxl_domain_info(struct libxl_ctx *
     return 0;
 }
 
+struct libxl_poolinfo * libxl_list_pool(struct libxl_ctx *ctx, int *nb_pool)
+{
+    struct libxl_poolinfo *ptr;
+    int i, ret;
+    xc_cpupoolinfo_t info[256];
+    int size = 256;
+
+    ptr = calloc(size, sizeof(struct libxl_poolinfo));
+    if (!ptr) return NULL;
+
+    ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info);
+    if (ret<0) return NULL;
+
+    for (i = 0; i < ret; i++) {
+        ptr[i].poolid = info[i].cpupool_id;
+    }
+    *nb_pool = ret;
+    return ptr;
+}
+
 /* this API call only list VM running on this host. a VM can be an aggregate 
of multiple domains. */
 struct libxl_vminfo * libxl_list_vm(struct libxl_ctx *ctx, int *nb_vm)
 {
@@ -1226,44 +1253,25 @@ int libxl_confirm_device_model_startup(s
 
 
/******************************************************************************/
 
-static int is_blktap2_supported(void)
+static char *get_blktap2_device(struct libxl_ctx *ctx,
+                               const char *name, const char *type)
 {
-    char buf[1024];
-    FILE *f = fopen("/proc/devices", "r");
-
-    
-    while (fgets(buf, sizeof(buf), f) != NULL) {
-        if (strstr(buf, "blktap2")) {
-            fclose(f);
-            return 1;
-        }
-    }
-    fclose(f);
-    return 0;
+    int minor = tap_ctl_find_minor(type, name);
+    if (minor < 0)
+        return NULL;
+    return libxl_sprintf(ctx, "/dev/xen/blktap-2/tapdev%d", minor);
 }
 
-static char *get_blktap2_device(struct libxl_ctx *ctx, char *name, char *type)
+static char *make_blktap2_device(struct libxl_ctx *ctx,
+                                const char *name, const char *type)
 {
-    char buf[1024];
-    char *p;
-    int devnum;
-    FILE *f = fopen("/sys/class/blktap2/devices", "r");
-
-    
-    while (!feof(f)) {
-        if (fscanf(f, "%d %s", &devnum, buf) != 2)
-            continue;
-        p = strchr(buf, ':');
-        if (p == NULL)
-            continue;
-        p++;
-        if (!strcmp(p, name) && !strncmp(buf, type, 3)) {
-            fclose(f);
-            return libxl_sprintf(ctx, "/dev/xen/blktap-2/tapdev%d", devnum);
-        }
-    }
-    fclose(f);
-    return NULL;
+    char *params, *devname = NULL;
+    int err;
+    params = libxl_sprintf(ctx, "%s:%s", type, name);
+    err = tap_ctl_create(params, &devname);
+    if (!err)
+        libxl_ptr_add(ctx, devname);
+    return err ? NULL : devname;
 }
 
 int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_disk *disk)
@@ -1314,38 +1322,16 @@ int libxl_device_disk_add(struct libxl_c
         case PHYSTYPE_FILE:
             /* let's pretend is tap:aio for the moment */
             disk->phystype = PHYSTYPE_AIO;
-        case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case 
PHYSTYPE_VHD:
-            if (is_blktap2_supported()) {
-                int rc, c, p[2], tot;
-                char buf[1024], *dev;
-                dev = get_blktap2_device(ctx, disk->physpath, 
device_disk_string_of_phystype(disk->phystype));
-                if (dev == NULL) {
-                    rc= libxl_pipe(ctx, p);  if (rc==-1) return -1;
-                    rc= libxl_fork(ctx);  if (rc==-1) return -1;
-                    if (!rc) { /* child */
-                        int null_r, null_w;
-                        char *args[4];
-                        args[0] = "tapdisk2";
-                        args[1] = "-n";
-                        args[2] = libxl_sprintf(ctx, "%s:%s", 
device_disk_string_of_phystype(disk->phystype), disk->physpath);
-                        args[3] = NULL;
-
-                        null_r = open("/dev/null", O_RDONLY);
-                        null_w = open("/dev/null", O_WRONLY);
-                        libxl_exec(null_r, p[1], null_w,
-                                   libxl_abs_path(ctx, "tapdisk2",
-                                                  libxl_sbindir_path()),
-                                   args);
-                        XL_LOG(ctx, XL_LOG_ERROR, "Error execing tapdisk2");
-                    }
-                    close(p[1]);
-                    tot = 0;
-                    while ((c = read(p[0], buf + tot, sizeof(buf) - tot)) > 0)
-                        tot = tot + c;
-                    close(p[0]);
-                    buf[tot - 1] = '\0';
-                    dev = buf;
-                }
+        case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case 
PHYSTYPE_VHD: {
+            const char *msg;
+            if (!tap_ctl_check(&msg)) {
+                const char *type = 
device_disk_string_of_phystype(disk->phystype);
+                char *dev;
+                dev = get_blktap2_device(ctx, disk->physpath, type);
+                if (!dev)
+                    dev = make_blktap2_device(ctx, disk->physpath, type);
+                if (!dev)
+                    return -1;
                 flexarray_set(back, boffset++, "tapdisk-params");
                 flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", 
device_disk_string_of_phystype(disk->phystype), disk->physpath));
                 flexarray_set(back, boffset++, "params");
@@ -1364,6 +1350,7 @@ int libxl_device_disk_add(struct libxl_c
 
             device.backend_kind = DEVICE_TAP;
             break;
+        }
         default:
             XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", 
disk->phystype);
             return ERROR_INVAL;
@@ -1579,6 +1566,186 @@ libxl_nicinfo *libxl_list_nics(struct li
     return res;
 }
 
+/******************************************************************************/
+int libxl_device_net2_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_net2 *net2)
+{
+    flexarray_t *front, *back;
+    unsigned int boffset = 0, foffset = 0;
+    libxl_device device;
+    char *dompath, *dom, **l;
+    unsigned int nb;
+
+    front = flexarray_make(16, 1);
+    if (!front)
+        return ERROR_NOMEM;
+    back = flexarray_make(16, 1);
+    if (!back)
+        return ERROR_NOMEM;
+
+    if (!(dompath = libxl_xs_get_dompath(ctx, domid))) {
+        return ERROR_FAIL;
+    }
+    dom = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/name", dompath));
+
+    if (net2->devid == -1) {
+        if (!(l = libxl_xs_directory(ctx, XBT_NULL,
+                                     libxl_sprintf(ctx, "%s/device/vif2", 
dompath), &nb))) {
+            net2->devid = 0;
+        } else {
+            net2->devid = strtoul(l[nb - 1], NULL, 10) + 1;
+            libxl_free(ctx, l);
+        }
+    }
+
+    device.backend_devid = net2->devid;
+    device.backend_domid = net2->backend_domid;
+    device.backend_kind = DEVICE_VIF2;
+    device.devid = net2->devid;
+    device.domid = net2->domid;
+    device.kind = DEVICE_VIF2;
+
+    flexarray_set(back, boffset++, "domain");
+    flexarray_set(back, boffset++, dom);
+    flexarray_set(back, boffset++, "frontend-id");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->domid));
+
+    flexarray_set(back, boffset++, "local-trusted");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
net2->back_trusted));
+    flexarray_set(back, boffset++, "mac");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                                                 net2->back_mac[0], 
net2->back_mac[1],
+                                                 net2->back_mac[2], 
net2->back_mac[3],
+                                                 net2->back_mac[4], 
net2->back_mac[5]));
+
+    flexarray_set(back, boffset++, "remote-trusted");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->trusted));
+    flexarray_set(back, boffset++, "remote-mac");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                                                 net2->front_mac[0], 
net2->front_mac[1],
+                                                 net2->front_mac[2], 
net2->front_mac[3],
+                                                 net2->front_mac[4], 
net2->front_mac[5]));
+
+    flexarray_set(back, boffset++, "max-bypasses");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
net2->max_bypasses));
+    flexarray_set(back, boffset++, "filter-mac");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
!!(net2->filter_mac)));
+    flexarray_set(back, boffset++, "handle");
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->devid));
+    flexarray_set(back, boffset++, "online");
+    flexarray_set(back, boffset++, "1");
+    flexarray_set(back, boffset++, "state");
+    flexarray_set(back, boffset++, "1");
+
+    flexarray_set(front, foffset++, "backend-id");
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
net2->backend_domid));
+
+    flexarray_set(front, foffset++, "local-trusted");
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->trusted));
+    flexarray_set(front, foffset++, "mac");
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                                                  net2->front_mac[0], 
net2->front_mac[1],
+                                                  net2->front_mac[2], 
net2->front_mac[3],
+                                                  net2->front_mac[4], 
net2->front_mac[5]));
+
+    flexarray_set(front, foffset++, "remote-trusted");
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
net2->back_trusted));
+    flexarray_set(front, foffset++, "remote-mac");
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                                                  net2->back_mac[0], 
net2->back_mac[1],
+                                                  net2->back_mac[2], 
net2->back_mac[3],
+                                                  net2->back_mac[4], 
net2->back_mac[5]));
+
+    flexarray_set(front, foffset++, "filter-mac");
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
!!(net2->filter_mac)));
+    flexarray_set(front, foffset++, "state");
+    flexarray_set(front, foffset++, "1");
+
+    libxl_device_generic_add(ctx, &device,
+                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
+                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+
+    /* FIXME: wait for plug */
+    flexarray_free(back);
+    flexarray_free(front);
+    return 0;
+}
+
+libxl_net2info *libxl_device_net2_list(struct libxl_ctx *ctx, uint32_t domid, 
unsigned int *nb)
+{
+    char *dompath, *net2_path_fe;
+    char **l;
+    char *val, *tok;
+    unsigned int nb_net2s, i;
+    libxl_net2info *res, *net2s;
+
+    dompath = libxl_xs_get_dompath(ctx, domid);
+    if (!dompath) {
+        return NULL;
+    }
+    l = libxl_xs_directory(ctx, XBT_NULL,
+                           libxl_sprintf(ctx, "%s/device/vif2", dompath), 
&nb_net2s);
+    if (!l) {
+        return NULL;
+    }
+    res = libxl_calloc(ctx, nb_net2s, sizeof (libxl_net2info));
+    if (!res) {
+        libxl_free(ctx, l);
+        return NULL;
+    }
+    net2s = res;
+    for (*nb = nb_net2s; nb_net2s > 0; --nb_net2s, ++l, ++net2s) {
+        net2_path_fe = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, *l);
+
+        net2s->backend = libxl_xs_read(ctx, XBT_NULL,
+                                       libxl_sprintf(ctx, "%s/backend", 
net2_path_fe));
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
net2_path_fe));
+        net2s->backend_id = val ? strtoul(val, NULL, 10) : -1;
+
+        net2s->devid = strtoul(*l, NULL, 10);
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", 
net2_path_fe));
+        net2s->state = val ? strtoul(val, NULL, 10) : -1;
+
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", 
net2_path_fe));
+        for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
+             ++i, tok = strtok(NULL, ":")) {
+            net2s->mac[i] = strtoul(tok, NULL, 16);
+        }
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/remote-trusted", net2_path_fe));
+        net2s->trusted = val ? strtoul(val, NULL, 10) : -1;
+
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", 
net2_path_fe));
+        for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
+             ++i, tok = strtok(NULL, ":")) {
+            net2s->back_mac[i] = strtoul(tok, NULL, 16);
+        }
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", 
net2_path_fe));
+        net2s->filter_mac = val ? strtoul(val, NULL, 10) : -1;
+
+        net2s->frontend = libxl_xs_read(ctx, XBT_NULL,
+                                        libxl_sprintf(ctx, "%s/frontend", 
net2s->backend));
+        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/frontend-id", net2s->backend));
+        net2s->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+        libxl_free(ctx, net2_path_fe);
+    }
+
+    libxl_free(ctx, l);
+    return res;
+}
+
+int libxl_device_net2_del(struct libxl_ctx *ctx, libxl_device_net2 *net2, int 
wait)
+{
+    libxl_device device;
+
+    device.backend_devid    = net2->devid;
+    device.backend_domid    = net2->backend_domid;
+    device.backend_kind     = DEVICE_VIF2;
+    device.devid            = net2->devid;
+    device.domid            = net2->domid;
+    device.kind             = DEVICE_VIF2;
+
+    return libxl_device_del(ctx, &device, wait);
+}
+
 
 
/******************************************************************************/
 int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_console *console)
@@ -2584,6 +2751,7 @@ int libxl_get_physinfo(struct libxl_ctx 
     physinfo->total_pages = xcphysinfo.total_pages;
     physinfo->free_pages = xcphysinfo.free_pages;
     physinfo->scrub_pages = xcphysinfo.scrub_pages;
+    physinfo->nr_nodes = xcphysinfo.nr_nodes;
     memcpy(physinfo->hw_cap,xcphysinfo.hw_cap, sizeof(physinfo->hw_cap));
     physinfo->phys_cap = xcphysinfo.capabilities;
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_device.c 
xen-unstable.hg/tools/libxl/libxl_device.c
--- xen-4.0-testing.hg/tools/libxl/libxl_device.c       2010-07-05 
11:48:35.875783996 +0100
+++ xen-unstable.hg/tools/libxl/libxl_device.c  2010-06-28 14:26:15.000932768 
+0100
@@ -24,11 +24,13 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+
 #include "libxl.h"
 #include "libxl_internal.h"
 
 static const char *string_of_kinds[] = {
     [DEVICE_VIF] = "vif",
+    [DEVICE_VIF2] = "vif2",
     [DEVICE_VBD] = "vbd",
     [DEVICE_TAP] = "tap",
     [DEVICE_PCI] = "pci",
@@ -292,7 +294,7 @@ int libxl_devices_destroy(struct libxl_c
     flexarray_t *toremove;
     struct libxl_ctx clone;
 
-    if (libxl_ctx_init(&clone, LIBXL_VERSION)) {
+    if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) {
         return -1;
     }
 
@@ -355,7 +357,7 @@ int libxl_device_del(struct libxl_ctx *c
     int rc;
     struct libxl_ctx clone;
 
-    if (libxl_ctx_init(&clone, LIBXL_VERSION)) {
+    if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) {
         return -1;
     }
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_dom.c 
xen-unstable.hg/tools/libxl/libxl_dom.c
--- xen-4.0-testing.hg/tools/libxl/libxl_dom.c  2010-07-05 11:49:52.895783116 
+0100
+++ xen-unstable.hg/tools/libxl/libxl_dom.c     2010-06-23 14:57:42.024133897 
+0100
@@ -148,7 +148,7 @@ int build_pv(struct libxl_ctx *ctx, uint
     int ret;
     int flags = 0;
 
-    dom = xc_dom_allocate(info->u.pv.cmdline, info->u.pv.features);
+    dom = xc_dom_allocate(ctx->xch, info->u.pv.cmdline, info->u.pv.features);
     if (!dom) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_allocate failed");
         return -1;
@@ -244,7 +244,7 @@ static int core_suspend_callback(void *d
             XL_LOG(si->ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", 
ret);
             return 0;
         }
-        ret = xc_await_suspend(si->xce, si->suspend_eventchn);
+        ret = xc_await_suspend(si->ctx->xch, si->xce, si->suspend_eventchn);
         if (ret < 0) {
             XL_LOG(si->ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", 
ret);
             return 0;
@@ -329,7 +329,7 @@ int core_suspend(struct libxl_ctx *ctx, 
                    &core_suspend_switch_qemu_logdirty);
 
     if (si.suspend_eventchn > 0)
-        xc_suspend_evtchn_release(si.xce, si.suspend_eventchn);
+        xc_suspend_evtchn_release(si.ctx->xch, si.xce, domid, 
si.suspend_eventchn);
     if (si.xce > 0)
         xc_evtchn_close(si.xce);
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_exec.c 
xen-unstable.hg/tools/libxl/libxl_exec.c
--- xen-4.0-testing.hg/tools/libxl/libxl_exec.c 2010-07-02 18:37:17.371283219 
+0100
+++ xen-unstable.hg/tools/libxl/libxl_exec.c    2010-06-23 14:57:42.024133897 
+0100
@@ -57,7 +57,8 @@ void libxl_exec(int stdinfd, int stdoutf
     _exit(-1);
 }
 
-void libxl_report_child_exitstatus(struct libxl_ctx *ctx, int level,
+void libxl_report_child_exitstatus(struct libxl_ctx *ctx,
+                                   xentoollog_level level,
                                    const char *what, pid_t pid, int status)
 {
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl.h 
xen-unstable.hg/tools/libxl/libxl.h
--- xen-4.0-testing.hg/tools/libxl/libxl.h      2010-07-05 11:45:08.871282040 
+0100
+++ xen-unstable.hg/tools/libxl/libxl.h 2010-06-23 14:57:42.024133897 +0100
@@ -22,8 +22,6 @@
 #include <xs.h>
 #include <sys/wait.h> /* for pid_t */
 
-typedef void (*libxl_log_callback)(void *userdata, int loglevel, const char 
*file,
-                                   int line, const char *func, char *s);
 struct libxl_dominfo {
     uint8_t uuid[16];
     uint32_t domid;
@@ -36,6 +34,10 @@ struct libxl_dominfo {
     uint32_t vcpu_online;
 };
 
+struct libxl_poolinfo {
+    uint32_t poolid;
+};
+
 struct libxl_vminfo {
     uint8_t uuid[16];
     uint32_t domid;
@@ -57,11 +59,9 @@ typedef struct {
 } libxl_version_info;
 
 struct libxl_ctx {
-    int xch;
+    xentoollog_logger *lg;
+    xc_interface *xch;
     struct xs_handle *xsh;
-    /* errors/debug buf */
-    void *log_userdata;
-    libxl_log_callback log_callback;
 
     /* mini-GC */
     int alloc_maxsize;
@@ -85,6 +85,8 @@ typedef struct {
     uint8_t uuid[16];
     char **xsdata;
     char **platformdata;
+    uint32_t poolid;
+    char *poolname;
 } libxl_domain_create_info;
 
 typedef struct {
@@ -241,6 +243,21 @@ typedef struct {
     libxl_nic_type nictype;
 } libxl_device_nic;
 
+typedef struct {
+    int devid;
+    uint8_t front_mac[6];
+    uint8_t back_mac[6];
+    uint32_t backend_domid;
+    uint32_t domid;
+    uint32_t trusted:1;
+    uint32_t back_trusted:1;
+    uint32_t filter_mac:1;
+    uint32_t front_filter_mac:1;
+    uint32_t pdev;
+    uint32_t max_bypasses;
+    char *bridge;
+} libxl_device_net2;
+
 typedef struct  {
     union {
         unsigned int value;
@@ -272,9 +289,9 @@ enum {
 #define LIBXL_VERSION 0
 
 /* context functions */
-int libxl_ctx_init(struct libxl_ctx *ctx, int version);
+int libxl_ctx_init(struct libxl_ctx *ctx, int version, xentoollog_logger*);
 int libxl_ctx_free(struct libxl_ctx *ctx);
-int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, 
void *log_data);
+int libxl_ctx_set_log(struct libxl_ctx *ctx, xentoollog_logger*);
 int libxl_ctx_postfork(struct libxl_ctx *ctx);
 
 /* domain related functions */
@@ -344,6 +361,7 @@ int libxl_console_attach(struct libxl_ct
 int libxl_domain_info(struct libxl_ctx*, struct libxl_dominfo *info_r,
                       uint32_t domid);
 struct libxl_dominfo * libxl_list_domain(struct libxl_ctx*, int *nb_domain);
+struct libxl_poolinfo * libxl_list_pool(struct libxl_ctx*, int *nb_pool);
 struct libxl_vminfo * libxl_list_vm(struct libxl_ctx *ctx, int *nb_vm);
 
 typedef struct libxl_device_model_starting libxl_device_model_starting;
@@ -480,6 +498,7 @@ struct libxl_physinfo {
     uint64_t free_pages;
     uint64_t scrub_pages;
 
+    uint32_t nr_nodes;
     uint32_t hw_cap[8];
     uint32_t phys_cap;
 };
@@ -536,7 +555,27 @@ int libxl_tmem_set(struct libxl_ctx *ctx
 int libxl_tmem_shared_auth(struct libxl_ctx *ctx, uint32_t domid, char* uuid,
                            int auth);
 
-/* libxl_paths.c */
+typedef struct {
+    char *backend;
+    uint32_t backend_id;
+    char *frontend;
+    uint32_t frontend_id;
+    int devid;
+    int state;
+    uint8_t mac[6];
+    int trusted;
+    uint8_t back_mac[6];
+    int filter_mac;
+} libxl_net2info;
+
+int libxl_device_net2_add(struct libxl_ctx *ctx, uint32_t domid,
+                          libxl_device_net2 *net2);
+libxl_net2info *libxl_device_net2_list(struct libxl_ctx *ctx, uint32_t domid,
+                                       unsigned int *nb);
+int libxl_device_net2_del(struct libxl_ctx *ctx, libxl_device_net2 *net2,
+                          int wait);
+
+/* common paths */
 const char *libxl_sbindir_path(void);
 const char *libxl_bindir_path(void);
 const char *libxl_libexec_path(void);
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_internal.c 
xen-unstable.hg/tools/libxl/libxl_internal.c
--- xen-4.0-testing.hg/tools/libxl/libxl_internal.c     2010-07-02 
18:37:17.371283219 +0100
+++ xen-unstable.hg/tools/libxl/libxl_internal.c        2010-06-23 
14:57:42.024133897 +0100
@@ -150,48 +150,40 @@ char *libxl_dirname(struct libxl_ctx *ct
     return ptr;
 }
 
-void xl_logv(struct libxl_ctx *ctx, int loglevel, int errnoval,
+void xl_logv(struct libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
              const char *file, int line, const char *func,
              char *fmt, va_list ap)
 {
     char *enomem = "[out of memory formatting log message]";
-    char *s;
+    char *base = NULL;
     int rc, esave;
-
-    if (!ctx->log_callback)
-        return;
+    char fileline[256];
 
     esave = errno;
-    
-    rc = vasprintf(&s, fmt, ap);
-    if (rc<0) { s = enomem; goto x; }
 
-    if (errnoval >= 0) {
-        char *errstr, *snew;
-        errstr = strerror(errnoval);
-        if (errstr)
-            rc = asprintf(&snew, "%s: %s", s, errstr);
-        else
-            rc = asprintf(&snew, "%s: unknown error number %d", s, errnoval);
-        free(s);
-        if (rc<0) { s = enomem; goto x; }
-        s = snew;
-    }
+    rc = vasprintf(&base, fmt, ap);
+    if (rc<0) { base = enomem; goto x; }
+
+    fileline[0] = 0;
+    if (file) snprintf(fileline, sizeof(fileline), "%s:%d",file,line);
+    fileline[sizeof(fileline)-1] = 0;
 
  x:
-    ctx->log_callback(ctx->log_userdata, loglevel, file, line, func, s);
-    if (s != enomem)
-        free(s);
+    xtl_log(ctx->lg, msglevel, errnoval, "libxl",
+            "%s%s%s%s" "%s",
+            fileline, func&&file?":":"", func?func:"", func||file?" ":"",
+            base);
+    if (base != enomem) free(base);
     errno = esave;
 }
 
-void xl_log(struct libxl_ctx *ctx, int loglevel, int errnoval,
-            const char *file, int line,
-            const char *func, char *fmt, ...)
+void xl_log(struct libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
+            const char *file, int line, const char *func,
+            char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
-    xl_logv(ctx, loglevel, errnoval, file, line, func, fmt, ap);
+    xl_logv(ctx, msglevel, errnoval, file, line, func, fmt, ap);
     va_end(ap);
 }
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_internal.h 
xen-unstable.hg/tools/libxl/libxl_internal.h
--- xen-4.0-testing.hg/tools/libxl/libxl_internal.h     2010-07-05 
11:44:50.631283386 +0100
+++ xen-unstable.hg/tools/libxl/libxl_internal.h        2010-06-28 
14:26:15.000932768 +0100
@@ -23,6 +23,7 @@
 
 #include <xs.h>
 #include <xenctrl.h>
+#include "xentoollog.h"
 
 #include "flexarray.h"
 #include "libxl_utils.h"
@@ -50,13 +51,24 @@
   /* all of these macros preserve errno (saving and restoring) */
 
 /* logging */
-void xl_logv(struct libxl_ctx *ctx, int errnoval, int loglevel, const char 
*file, int line, const char *func, char *fmt, va_list al);
-void xl_log(struct libxl_ctx *ctx, int errnoval, int loglevel, const char 
*file, int line, const char *func, char *fmt, ...);
-  /* these functions preserve errno (saving and restoring) */
+void xl_logv(struct libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
+             const char *file /* may be 0 */, int line /* ignored if !file */,
+             const char *func /* may be 0 */,
+             char *fmt, va_list al)
+     __attribute__((format(printf,7,0)));
+
+void xl_log(struct libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
+            const char *file /* may be 0 */, int line /* ignored if !file */,
+            const char *func /* may be 0 */,
+            char *fmt, ...)
+     __attribute__((format(printf,7,8)));
+
+     /* these functions preserve errno (saving and restoring) */
 

 typedef enum {
     DEVICE_VIF = 1,
+    DEVICE_VIF2,
     DEVICE_VBD,
     DEVICE_TAP,
     DEVICE_PCI,
@@ -154,7 +166,7 @@ int libxl_device_pci_reset(struct libxl_
                            unsigned int dev, unsigned int func);
 
 /* from xenguest (helper */
-int hvm_build_set_params(int handle, uint32_t domid,
+int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          libxl_domain_build_info *info,
                          int store_evtchn, unsigned long *store_mfn);
 
@@ -204,5 +216,10 @@ void libxl_log_child_exitstatus(struct l
 
 char *libxl_abs_path(struct libxl_ctx *ctx, char *s, const char *path);
 
+#define XL_LOG_DEBUG   XTL_DEBUG
+#define XL_LOG_INFO    XTL_INFO
+#define XL_LOG_WARNING XTL_WARN
+#define XL_LOG_ERROR   XTL_ERROR
+
 #endif
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_utils.c 
xen-unstable.hg/tools/libxl/libxl_utils.c
--- xen-4.0-testing.hg/tools/libxl/libxl_utils.c        2010-06-30 
14:21:43.603667868 +0100
+++ xen-unstable.hg/tools/libxl/libxl_utils.c   2010-06-23 14:57:42.024133897 
+0100
@@ -92,6 +92,29 @@ char *libxl_poolid_to_name(struct libxl_
     return s;
 }
 
+int libxl_name_to_poolid(struct libxl_ctx *ctx, const char *name,
+                        uint32_t *poolid)
+{
+    int i, nb_pools;
+    char *poolname;
+    struct libxl_poolinfo *poolinfo;
+
+    poolinfo = libxl_list_pool(ctx, &nb_pools);
+    if (!poolinfo)
+        return ERROR_NOMEM;
+
+    for (i = 0; i < nb_pools; i++) {
+        poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid);
+        if (!poolname)
+            continue;
+        if (strcmp(poolname, name) == 0) {
+            *poolid = poolinfo[i].poolid;
+            return 0;
+        }
+    }
+    return -1;
+}
+
 int libxl_get_stubdom_id(struct libxl_ctx *ctx, int guest_domid)
 {
     char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid)));
@@ -444,3 +467,66 @@ int libxl_devid_to_device_disk(struct li
 
     return 0;
 }
+
+int libxl_devid_to_device_net2(struct libxl_ctx *ctx, uint32_t domid,
+                               const char *devid, libxl_device_net2 *net2)
+{
+    char *tok, *endptr, *val;
+    char *dompath, *net2path, *be_path;
+    unsigned int devid_n, i;
+
+    devid_n = strtoul(devid, &endptr, 10);
+    if (devid == endptr) {
+        return ERROR_INVAL;
+    }
+    dompath = libxl_xs_get_dompath(ctx, domid);
+    net2path = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, devid);
+    if (!net2path) {
+        return ERROR_FAIL;
+    }
+    memset(net2, 0, sizeof (libxl_device_net2));
+    be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", 
net2path));
+
+    net2->devid = devid_n;
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", net2path));
+    for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
+         ++i, tok = strtok(NULL, ":")) {
+        net2->front_mac[i] = strtoul(tok, NULL, 16);
+    }
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", 
net2path));
+    for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
+         ++i, tok = strtok(NULL, ":")) {
+        net2->back_mac[i] = strtoul(tok, NULL, 16);
+    }
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
net2path));
+    net2->backend_domid = strtoul(val, NULL, 10);
+
+    net2->domid = domid;
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-trusted", 
be_path));
+    net2->trusted = strtoul(val, NULL, 10);
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/local-trusted", 
be_path));
+    net2->back_trusted = strtoul(val, NULL, 10);
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", 
be_path));
+    net2->filter_mac = strtoul(val, NULL, 10);
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", 
net2path));
+    net2->front_filter_mac = strtoul(val, NULL, 10);
+    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/max-bypasses", 
be_path));
+    net2->max_bypasses = strtoul(val, NULL, 10);
+
+    return 0;
+}
+
+int libxl_strtomac(const char *mac_s, uint8_t *mac)
+{
+    const char *end = mac_s + 17;
+    char val, *endptr;
+
+    for (; mac_s < end; mac_s += 3, ++mac) {
+        val = strtoul(mac_s, &endptr, 16);
+        if (endptr != (mac_s + 2)) {
+            return ERROR_INVAL;
+        }
+        *mac = val;
+    }
+    return 0;
+}
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/libxl_utils.h 
xen-unstable.hg/tools/libxl/libxl_utils.h
--- xen-4.0-testing.hg/tools/libxl/libxl_utils.h        2010-07-02 
18:48:29.707283003 +0100
+++ xen-unstable.hg/tools/libxl/libxl_utils.h   2010-06-23 14:57:42.034133693 
+0100
@@ -50,7 +50,7 @@ pid_t libxl_fork(struct libxl_ctx *ctx);
 int libxl_pipe(struct libxl_ctx *ctx, int pipes[2]);
   /* Just like fork(2), pipe(2), but log errors. */
 
-void libxl_report_child_exitstatus(struct libxl_ctx *ctx, int level,
+void libxl_report_child_exitstatus(struct libxl_ctx *ctx, xentoollog_level,
                                    const char *what, pid_t pid, int status);
     /* treats all exit statuses as errors; if that's not what you want,
      * check status yourself first */
@@ -63,11 +63,10 @@ int libxl_devid_to_device_nic(struct lib
 int libxl_devid_to_device_disk(struct libxl_ctx *ctx, uint32_t domid,
                                const char *devid, libxl_device_disk *disk);
 
-/* log levels: */
-#define XL_LOG_DEBUG 3
-#define XL_LOG_INFO 2
-#define XL_LOG_WARNING 1
-#define XL_LOG_ERROR 0
+int libxl_strtomac(const char *mac_s, uint8_t *mac);
+
+int libxl_devid_to_device_net2(struct libxl_ctx *ctx, uint32_t domid,
+                               const char *devid, libxl_device_net2 *net2);
 
 #endif
 
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/Makefile 
xen-unstable.hg/tools/libxl/Makefile
--- xen-4.0-testing.hg/tools/libxl/Makefile     2010-06-30 14:21:43.595667348 
+0100
+++ xen-unstable.hg/tools/libxl/Makefile        2010-06-23 14:57:42.024133897 
+0100
@@ -13,9 +13,9 @@ XLUMINOR = 0
 
 CFLAGS += -Werror
 CFLAGS += -I. -fPIC
-CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore)
+CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) 
$(CFLAGS_libblktapctl)
 
-LIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore)
+LIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore) 
$(LDFLAGS_libblktapctl)
 
 LIBXL_OBJS-y = osdeps.o libxl_paths.o
 LIBXL_OBJS = flexarray.o libxl.o libxl_dom.o libxl_exec.o libxl_xshelp.o 
libxl_device.o libxl_internal.o xenguest.o libxl_utils.o $(LIBXL_OBJS-y)
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/xenguest.c 
xen-unstable.hg/tools/libxl/xenguest.c
--- xen-4.0-testing.hg/tools/libxl/xenguest.c   2010-07-01 17:52:36.951783451 
+0100
+++ xen-unstable.hg/tools/libxl/xenguest.c      2010-06-23 14:57:42.034133693 
+0100
@@ -21,7 +21,7 @@
 
 #include "libxl.h"
 
-int hvm_build_set_params(int handle, uint32_t domid,
+int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          libxl_domain_build_info *info,
                          int store_evtchn, unsigned long *store_mfn)
 {
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/xl.c 
xen-unstable.hg/tools/libxl/xl.c
--- xen-4.0-testing.hg/tools/libxl/xl.c 2010-07-05 11:57:22.679783894 +0100
+++ xen-unstable.hg/tools/libxl/xl.c    2010-06-23 14:57:42.034133693 +0100
@@ -31,44 +31,49 @@
 #include "libxl_utils.h"
 #include "xl.h"
 
-extern struct libxl_ctx ctx;
-extern int logfile;
-
-void log_callback(
-    void *userdata, int loglevel, const char *file,
-    int line, const char *func, char *s)
-{
-    char str[1024];
+xentoollog_logger_stdiostream *logger;
 
-    snprintf(str, sizeof(str), "[%d] %s:%d:%s: %s\n",
-             loglevel, file, line, func, s);
-    libxl_write_exactly(NULL, logfile, str, strlen(str), NULL, NULL);
-}
+static xentoollog_level minmsglevel = XTL_PROGRESS;
 
 int main(int argc, char **argv)
 {
+    int opt = 0;
+    char *cmd = 0;
     struct cmd_spec *cspec;
 
-    if (argc < 2) {
+    while ((opt = getopt(argc, argv, "+v")) >= 0) {
+        switch (opt) {
+        case 'v':
+            if (minmsglevel > 0) minmsglevel--;
+            break;
+        default:
+            fprintf(stderr, "unknown global option\n");
+            exit(2);
+        }
+    }
+
+    cmd = argv[optind++];
+
+    if (!cmd) {
         help(NULL);
         exit(1);
     }
+    opterr = 0;
 
-    if (libxl_ctx_init(&ctx, LIBXL_VERSION)) {
+    logger = xtl_createlogger_stdiostream(stderr, minmsglevel,  0);
+    if (!logger) exit(1);
+
+    if (libxl_ctx_init(&ctx, LIBXL_VERSION, (xentoollog_logger*)logger)) {
         fprintf(stderr, "cannot init xl context\n");
         exit(1);
     }
-    if (libxl_ctx_set_log(&ctx, log_callback, NULL)) {
-        fprintf(stderr, "cannot set xl log callback\n");
-        exit(-ERROR_FAIL);
-    }
 
     srand(time(0));
 
-    cspec = cmdtable_lookup(argv[1]);
+    cspec = cmdtable_lookup(cmd);
     if (cspec)
         return cspec->cmd_impl(argc, argv);
-    else if (!strcmp(argv[1], "help")) {
+    else if (!strcmp(cmd, "help")) {
         help(argv[optind]);
         exit(0);
     } else {
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/xl_cmdimpl.c 
xen-unstable.hg/tools/libxl/xl_cmdimpl.c
--- xen-4.0-testing.hg/tools/libxl/xl_cmdimpl.c 2010-07-05 12:09:23.379782260 
+0100
+++ xen-unstable.hg/tools/libxl/xl_cmdimpl.c    2010-06-30 17:01:42.750781923 
+0100
@@ -137,6 +137,16 @@ static int domain_qualifier_to_domid(con
     return was_name ? libxl_name_to_domid(&ctx, p, domid_r) : 0;
 }
 
+static int pool_qualifier_to_poolid(const char *p, uint32_t *poolid_r,
+                                     int *was_name_r)
+{
+    int was_name;
+
+    was_name = qualifier_to_id(p, poolid_r);
+    if (was_name_r) *was_name_r = was_name;
+    return was_name ? libxl_name_to_poolid(&ctx, p, poolid_r) : 0;
+}
+
 static void find_domain(const char *p)
 {
     int rc, was_name;
@@ -173,6 +183,7 @@ static void init_create_info(libxl_domai
     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)
@@ -254,6 +265,29 @@ static void init_nic_info(libxl_device_n
     nic_info->nictype = NICTYPE_IOEMU;
 }
 
+static void init_net2_info(libxl_device_net2 *net2_info, int devnum)
+{
+    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] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
+    net2_info->front_mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+    net2_info->front_mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+    net2_info->back_mac[0] = 0x00;
+    net2_info->back_mac[1] = 0x16;
+    net2_info->back_mac[2] = 0x3e;
+    net2_info->back_mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
+    net2_info->back_mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+    net2_info->back_mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
+    net2_info->back_trusted = 1;
+    net2_info->filter_mac = 1;
+    net2_info->max_bypasses = 5;
+    net2_info->bridge = "xenbr0";
+}
+
 static void init_vfb_info(libxl_device_vfb *vfb, int dev_num)
 {
     memset(vfb, 0x00, sizeof(libxl_device_vfb));
@@ -310,6 +344,7 @@ static void printf_info(int domid,
            (c_info->uuid)[4], (c_info->uuid)[5], (c_info->uuid)[6], 
(c_info->uuid)[7],
            (c_info->uuid)[8], (c_info->uuid)[9], (c_info->uuid)[10], 
(c_info->uuid)[11],
            (c_info->uuid)[12], (c_info->uuid)[13], (c_info->uuid)[14], 
(c_info->uuid)[15]);
+    printf("\t(cpupool %s (%d))\n", c_info->poolname, c_info->poolid);
     if (c_info->xsdata)
         printf("\t(xsdata contains data)\n");
     else
@@ -434,6 +469,8 @@ static void parse_config_data(const char
                               int *num_disks,
                               libxl_device_nic **vifs,
                               int *num_vifs,
+                              libxl_device_net2 **vif2s,
+                              int *num_vif2s,
                               libxl_device_pci **pcidevs,
                               int *num_pcidevs,
                               libxl_device_vfb **vfbs,
@@ -445,7 +482,7 @@ static void parse_config_data(const char
     const char *buf;
     long l;
     XLU_Config *config;
-    XLU_ConfigList *vbds, *nics, *pcis, *cvfbs;
+    XLU_ConfigList *vbds, *nics, *pcis, *cvfbs, *net2s;
     int pci_power_mgmt = 0;
     int pci_msitranslate = 1;
     int i, e;
@@ -483,6 +520,16 @@ static void parse_config_data(const char
     if (!xlu_cfg_get_long(config, "oos", &l))
         c_info->oos = l;
 
+    if (!xlu_cfg_get_string (config, "pool", &buf)) {
+        c_info->poolid = -1;
+        pool_qualifier_to_poolid(buf, &c_info->poolid, NULL);
+    }
+    c_info->poolname = libxl_poolid_to_name(&ctx, c_info->poolid);
+    if (!c_info->poolname) {
+        fprintf(stderr, "Illegal pool specified\n");
+        exit(1);
+    }
+
     init_build_info(b_info, c_info);
 
     /* the following is the actual config parsing with overriding values in 
the structures */
@@ -670,6 +717,46 @@ skip:
         }
     }
 
+    if (!xlu_cfg_get_list(config, "vif2", &net2s, 0)) {
+        *num_vif2s = 0;
+        *vif2s = NULL;
+        while ((buf = xlu_cfg_get_listitem(net2s, *num_vif2s))) {
+            char *buf2 = strdup(buf);
+            char *p;
+
+            *vif2s = realloc(*vif2s, sizeof (libxl_device_net2) * (*num_vif2s 
+ 1));
+            init_net2_info(*vif2s + *num_vif2s, *num_vif2s);
+
+            for (p = strtok(buf2, ","); p; p = strtok(buf2, ",")) {
+                while (isblank(*p))
+                    p++;
+                if (!strncmp("front_mac=", p, 10)) {
+                    libxl_strtomac(p + 10, (*vif2s)[*num_vif2s].front_mac);
+                } else if (!strncmp("back_mac=", p, 9)) {
+                    libxl_strtomac(p + 9, (*vif2s)[*num_vif2s].back_mac);
+                } else if (!strncmp("backend=", p, 8)) {
+                    domain_qualifier_to_domid(p + 8, 
&((*vif2s)[*num_vif2s].backend_domid), 0);
+                } else if (!strncmp("trusted=", p, 8)) {
+                    (*vif2s)[*num_vif2s].trusted = (*(p + 8) == '1');
+                } else if (!strncmp("back_trusted=", p, 13)) {
+                    (*vif2s)[*num_vif2s].back_trusted = (*(p + 13) == '1');
+                } else if (!strncmp("bridge=", p, 7)) {
+                    (*vif2s)[*num_vif2s].bridge = strdup(p + 13);
+                } else if (!strncmp("filter_mac=", p, 11)) {
+                    (*vif2s)[*num_vif2s].filter_mac = (*(p + 11) == '1');
+                } else if (!strncmp("front_filter_mac=", p, 17)) {
+                    (*vif2s)[*num_vif2s].front_filter_mac = (*(p + 17) == '1');
+                } else if (!strncmp("pdev=", p, 5)) {
+                    (*vif2s)[*num_vif2s].pdev = strtoul(p + 5, NULL, 10);
+                } else if (!strncmp("max_bypasses=", p, 13)) {
+                    (*vif2s)[*num_vif2s].max_bypasses = strtoul(p + 13, NULL, 
10);
+                }
+            }
+            free(buf2);
+            ++(*num_vif2s);
+        }
+    }
+
     if (!xlu_cfg_get_list (config, "vfb", &cvfbs, 0)) {
         *num_vfbs = 0;
         *num_vkbs = 0;
@@ -849,6 +936,7 @@ static int create_domain(struct domain_c
     libxl_device_model_info dm_info;
     libxl_device_disk *disks = NULL;
     libxl_device_nic *vifs = NULL;
+    libxl_device_net2 *vif2s = NULL;
     libxl_device_pci *pcidevs = NULL;
     libxl_device_vfb *vfbs = NULL;
     libxl_device_vkb *vkbs = NULL;
@@ -863,7 +951,7 @@ static int create_domain(struct domain_c
     int migrate_fd = dom_info->migrate_fd;
     char **migration_domname_r = dom_info->migration_domname_r;
 
-    int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 
0;
+    int num_disks = 0, num_vifs = 0, num_vif2s = 0, num_pcidevs = 0, num_vfbs 
= 0, num_vkbs = 0;
     int i, fd;
     int need_daemon = 1;
     int ret, rc;
@@ -976,7 +1064,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, &info1, &info2, 
&disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, 
&vkbs, &num_vkbs, &dm_info);
+    parse_config_data(config_file, config_data, config_len, &info1, &info2, 
&disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs, 
&num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info);
 
     if (dom_info->dryrun)
         return 0;
@@ -1050,6 +1138,17 @@ start:
             goto error_out;
         }
     }
+    if (!info1.hvm) {
+        for (i = 0; i < num_vif2s; i++) {
+            vif2s[i].domid = domid;
+            ret = libxl_device_net2_add(&ctx, domid, &(vif2s[i]));
+            if (ret) {
+                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
+                ret = ERROR_FAIL;
+                goto error_out;
+            }
+        }
+    }
     if (info1.hvm) {
         dm_info.domid = domid;
         MUST( libxl_create_device_model(&ctx, &dm_info, disks, num_disks,
@@ -1100,7 +1199,7 @@ start:
                 }
             }
             if (status) {
-                libxl_report_child_exitstatus(&ctx, XL_LOG_ERROR,
+                libxl_report_child_exitstatus(&ctx, XTL_ERROR,
                            "daemonizing child", child1, status);
                 ret = ERROR_FAIL;
                 goto error_out;
@@ -1660,13 +1759,13 @@ void list_domains_details(void)
     char *config_file;
     uint8_t *data;
     int nb_domain, i, len, rc;
-    int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 
0;
+    int num_disks = 0, num_vifs = 0, num_vif2s = 0, num_pcidevs = 0, num_vfbs 
= 0, num_vkbs = 0;
     libxl_domain_create_info info1;
     libxl_domain_build_info info2;
     libxl_device_model_info dm_info;
     libxl_device_disk *disks = NULL;
     libxl_device_nic *vifs = NULL;
-
+    libxl_device_net2 *vif2s = NULL;
     libxl_device_pci *pcidevs = NULL;
     libxl_device_vfb *vfbs = NULL;
     libxl_device_vkb *vkbs = NULL;
@@ -1682,7 +1781,7 @@ void list_domains_details(void)
         if (rc)
             continue;
         CHK_ERRNO(asprintf(&config_file, "<domid %d data>", info[i].domid));
-        parse_config_data(config_file, (char *)data, len, &info1, &info2, 
&disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, 
&vkbs, &num_vkbs, &dm_info);
+        parse_config_data(config_file, (char *)data, len, &info1, &info2, 
&disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs, 
&num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info);
         printf_info(info[i].domid, &info1, &info2, disks, num_disks, vifs, 
num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info);
         free(data);
         free(config_file);
@@ -1877,7 +1976,7 @@ static void migration_child_report(pid_t
 
         if (child == migration_child) {
             if (status)
-                libxl_report_child_exitstatus(&ctx, XL_LOG_INFO,
+                libxl_report_child_exitstatus(&ctx, XTL_INFO,
                                               "migration target process",
                                               migration_child, status);
             break;
@@ -1985,6 +2084,8 @@ static void migrate_domain(char *domain_
     save_domain_core_writeconfig(send_fd, "migration stream",
                                  config_data, config_len);
 
+    xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0);
+
     memset(&suspinfo, 0, sizeof(suspinfo));
     suspinfo.flags |= XL_SUSPEND_LIVE;
     rc = libxl_domain_suspend(&ctx, &suspinfo, domid, send_fd);
@@ -2003,7 +2104,7 @@ static void migrate_domain(char *domain_
                                    "ready message", rune);
     if (rc) goto failed_resume;
 
-
+    xtl_stdiostream_adjust_flags(logger, 0, XTL_STDIOSTREAM_HIDE_PROGRESS);
 
     /* right, at this point we are about give the destination
      * permission to rename and resume, so we must first rename the
@@ -2984,7 +3085,9 @@ static void output_xeninfo(void)
     printf("xen_extra              : %s\n", info->xen_version_extra);
     printf("xen_caps               : %s\n", info->capabilities);
     printf("xen_scheduler          : %s\n",
-        sched_id == XEN_SCHEDULER_SEDF ? "sedf" : "credit");
+        sched_id == XEN_SCHEDULER_SEDF ? "sedf" :
+        sched_id == XEN_SCHEDULER_CREDIT ? "credit" :
+        sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown");
     printf("xen_pagesize           : %lu\n", info->pagesize);
     printf("platform_params        : virt_start=0x%lx\n", info->virt_start);
     printf("xen_changeset          : %s\n", info->changeset);
@@ -3022,6 +3125,7 @@ static void output_physinfo(void)
     }
 
     printf("nr_cpus                : %d\n", info.nr_cpus);
+    printf("nr_nodes               : %d\n", info.nr_nodes);
     printf("cores_per_socket       : %d\n", info.cores_per_socket);
     printf("threads_per_core       : %d\n", info.threads_per_core);
     printf("cpu_mhz                : %d\n", info.cpu_khz / 1000);
@@ -3780,6 +3884,182 @@ int main_blockdetach(int argc, char **ar
     exit(0);
 }
 
+int main_network2attach(int argc, char **argv)
+{
+    int opt;
+    char *tok, *endptr;
+    char *back_dom = NULL;
+    uint32_t domid, back_domid;
+    unsigned int val, i;
+    libxl_device_net2 net2;
+
+    if ((argc < 3) || (argc > 12)) {
+        help("network2-attach");
+        exit(0);
+    }
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("network2-attach");
+            exit(0);
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    if (domain_qualifier_to_domid(argv[2], &domid, 0) < 0) {
+        fprintf(stderr, "%s is an invalid domain identifier\n", argv[1]);
+        exit(1);
+    }
+    init_net2_info(&net2, -1);
+    for (argv += 3, argc -= 3; argc > 0; --argc, ++argv) {
+        if (!strncmp("front_mac=", *argv, 10)) {
+            tok = strtok((*argv) + 10, ":");
+            for (i = 0; tok && i < 6; tok = strtok(NULL, ":"), ++i) {
+                val = strtoul(tok, &endptr, 16);
+                if ((tok == endptr) || (val > 255)) {
+                    fprintf(stderr, "Invalid parameter `front_mac'.\n");
+                    exit(1);
+                }
+                net2.front_mac[i] = val;
+            }
+        } else if (!strncmp("back_mac=", *argv, 9)) {
+            tok = strtok((*argv) + 10, ":");
+            for (i = 0; tok && i < 6; tok = strtok(NULL, ":"), ++i) {
+                val = strtoul(tok, &endptr, 16);
+                if ((tok == endptr) || (val > 255)) {
+                    fprintf(stderr, "Invalid parameter back_mac=%s.\n", *argv 
+ 9);
+                    exit(1);
+                }
+                net2.back_mac[i] = val;
+            }
+        } else if (!strncmp("backend=", *argv, 8)) {
+            back_dom = *argv;
+        } else if (!strncmp("trusted=", *argv, 8)) {
+            net2.trusted = (*((*argv) + 8) == '1');
+        } else if (!strncmp("back_trusted=", *argv, 13)) {
+            net2.back_trusted = (*((*argv) + 13) == '1');
+        } else if (!strncmp("bridge=", *argv, 7)) {
+            net2.bridge = *argv + 13;
+        } else if (!strncmp("filter_mac=", *argv, 11)) {
+            net2.filter_mac = (*((*argv) + 11) == '1');
+        } else if (!strncmp("front_filter_mac=", *argv, 17)) {
+            net2.front_filter_mac = (*((*argv) + 17) == '1');
+        } else if (!strncmp("pdev=", *argv, 5)) {
+            val = strtoul(*argv + 5, &endptr, 10);
+            if (endptr == (*argv + 5)) {
+                fprintf(stderr, "Invalid parameter pdev=%s.\n", *argv + 5);
+                exit(1);
+            }
+            net2.pdev = val;
+        } else if (!strncmp("max_bypasses=", *argv, 13)) {
+            val = strtoul(*argv + 13, &endptr, 10);
+            if (endptr == (*argv + 13)) {
+                fprintf(stderr, "Invalid parameter max_bypasses=%s.\n", *argv 
+ 13);
+                exit(1);
+            }
+            net2.max_bypasses = val;
+        } else {
+            fprintf(stderr, "unrecognized argument `%s'\n", *argv);
+            exit(1);
+        }
+    }
+
+    if (back_dom) {
+        if (domain_qualifier_to_domid(back_dom, &back_domid, 0) < 0) {
+            fprintf(stderr, "%s is an invalid domain identifier\n", back_dom);
+            exit(1);
+        }
+    }
+    net2.domid = domid;
+    net2.backend_domid = back_domid;
+    if (libxl_device_net2_add(&ctx, domid, &net2)) {
+        fprintf(stderr, "libxl_device_net2_add failed.\n");
+    }
+    exit(0);
+}
+
+int main_network2list(int argc, char **argv)
+{
+    int opt;
+    unsigned int nb;
+    libxl_net2info *net2s;
+
+    if (argc < 3) {
+        help("network2-list");
+        exit(0);
+    }
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("network2-list");
+            exit(0);
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    printf("%-3s %-2s %-5s %-17s %-17s %-7s %-6s %-30s\n",
+           "Idx", "BE", "state", "Mac Addr.", "Remote Mac Addr.",
+           "trusted", "filter", "backend");
+    for (argv += 2, argc -=2; argc > 0; --argc, ++argv) {
+        if (domain_qualifier_to_domid(*argv, &domid, 0) < 0) {
+            fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
+            continue;
+        }
+        if ((net2s = libxl_device_net2_list(&ctx, domid, &nb))) {
+            for (; nb > 0; --nb, ++net2s) {
+                printf("%3d %2d %5d ", net2s->devid, net2s->backend_id, 
net2s->state);
+                printf("%02x:%02x:%02x:%02x:%02x:%02x ",
+                       net2s->mac[0], net2s->mac[1], net2s->mac[2],
+                       net2s->mac[3], net2s->mac[4], net2s->mac[5]);
+                printf("%02x:%02x:%02x:%02x:%02x:%02x ",
+                       net2s->back_mac[0], net2s->back_mac[1], 
net2s->back_mac[2],
+                       net2s->back_mac[3], net2s->back_mac[4], 
net2s->back_mac[5]);
+                printf("%-7d %-6d %-30s\n", net2s->trusted, net2s->filter_mac, 
net2s->backend);
+            }
+        }
+    }
+    exit(0);
+}
+
+int main_network2detach(int argc, char **argv)
+{
+    int opt;
+    libxl_device_net2 net2;
+
+    if (argc != 4) {
+        help("network2-detach");
+        exit(0);
+    }
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("network2-detach");
+            exit(0);
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    if (domain_qualifier_to_domid(argv[2], &domid, 0) < 0) {
+        fprintf(stderr, "%s is an invalid domain identifier\n", argv[2]);
+        exit(1);
+    }
+    if (libxl_devid_to_device_net2(&ctx, domid, argv[3], &net2)) {
+       fprintf(stderr, "Error: Device %s not connected.\n", argv[3]);
+        exit(1);
+    }
+    if (libxl_device_net2_del(&ctx, &net2, 1)) {
+        fprintf(stderr, "libxl_device_net2_del failed.\n");
+        exit(1);
+    }
+    exit(0);
+}
+
 static char *uptime_to_string(unsigned long time, int short_mode)
 {
     int sec, min, hour, day;
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/xl_cmdtable.c 
xen-unstable.hg/tools/libxl/xl_cmdtable.c
--- xen-4.0-testing.hg/tools/libxl/xl_cmdtable.c        2010-07-05 
11:57:53.144288270 +0100
+++ xen-unstable.hg/tools/libxl/xl_cmdtable.c   2010-06-28 14:26:15.004932848 
+0100
@@ -295,6 +295,24 @@ struct cmd_spec cmd_table[] = {
       "                                 
(abcdef01-2345-6789-1234-567890abcdef)\n"
       "  -A AUTH                        0=auth,1=deauth",
     },
+    { "network2-attach",
+      &main_network2attach,
+      "Create a new version 2 virtual network device",
+      "<Domain> [front_mac=<mac>] [back_mac=<mac>] [backend=<BackDomain>]"
+      " [trusted=<0|1>] [back_trusted=<0|1>] [bridge=<bridge>]"
+      " [filter_mac=<0|1>] [front_filter_mac=<0|1>] [pdev=<PDEV>]"
+      " [max_bypasses=n]",
+    },
+    { "network2-list",
+      &main_network2list,
+      "list version 2 virtual network interfaces for a domain",
+      "<Domain(s)>",
+    },
+    { "network2-detach",
+      &main_network2detach,
+      "destroy a domain's version 2 virtual network device",
+      "<Domain> <DevId>",
+    },
 };
 
 int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
diff -pud -x '*.d' xen-4.0-testing.hg/tools/libxl/xl.h 
xen-unstable.hg/tools/libxl/xl.h
--- xen-4.0-testing.hg/tools/libxl/xl.h 2010-07-05 11:46:39.719283147 +0100
+++ xen-unstable.hg/tools/libxl/xl.h    2010-06-23 14:57:42.034133693 +0100
@@ -15,6 +15,8 @@
 #ifndef XL_H
 #define XL_H
 
+#include "xentoollog.h"
+
 struct cmd_spec {
     char *cmd_name;
     int (*cmd_impl)(int argc, char **argv);
@@ -70,12 +72,18 @@ int main_tmem_destroy(int argc, char **a
 int main_tmem_thaw(int argc, char **argv);
 int main_tmem_set(int argc, char **argv);
 int main_tmem_shared_auth(int argc, char **argv);
+int main_network2attach(int argc, char **argv);
+int main_network2list(int argc, char **argv);
+int main_network2detach(int argc, char **argv);
 
 void help(char *command);
 
-/* Look up a command in the table, allowing unambiguous truncation */
-struct cmd_spec *cmdtable_lookup(const char *s);
 extern struct cmd_spec cmd_table[];
 extern int cmdtable_len;
+/* Look up a command in the table, allowing unambiguous truncation */
+struct cmd_spec *cmdtable_lookup(const char *s);
+
+extern struct libxl_ctx ctx;
+extern xentoollog_logger_stdiostream *logger;
 
 #endif /* XL_H */





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