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] blktap: re-enable blktap1 if blktap2 is d

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] blktap: re-enable blktap1 if blktap2 is disabled
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 19 Jun 2009 00:57:01 -0700
Delivery-date: Fri, 19 Jun 2009 01:10:34 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1245317398 -3600
# Node ID 4f779d41b0ba3cb835a901490fb6a52dda7f54c4
# Parent  94bf7d4854eba731e5fcb6418a550f160467cc89
blktap: re-enable blktap1 if blktap2 is disabled

This patch re-enables a useful blktap1 for users who disable blktap2.
Itremoves tapdisk and blktapctrl from blktap2, both of which cause
problems with blktap operation.  In addition, this patch modifies xend
to check for blktap2 installation.  If the blktap2 driver isn't
running (hopefully because the dom0 kernel option wasn't selected) we
fall back to blktap.

Signed-off-by: Dutch Meyer <dmeyer@xxxxxxxxx>
---
 tools/blktap2/daemon/Makefile                    |   53 
 tools/blktap2/daemon/lib/Makefile                |   68 -
 tools/blktap2/daemon/lib/xs_api.c                |  323 -----
 tools/blktap2/daemon/lib/xs_api.h                |   62 -
 tools/blktap2/daemon/tapdisk-channel.c           | 1367 -----------------------
 tools/blktap2/daemon/tapdisk-daemon.c            |  599 ----------
 tools/blktap2/daemon/tapdisk-dispatch-common.c   |   94 -
 tools/blktap2/daemon/tapdisk-dispatch.h          |   95 -
 tools/blktap2/drivers/tapdisk.c                  |   66 -
 tools/blktap2/Makefile                           |    1 
 tools/blktap2/drivers/Makefile                   |   10 
 tools/python/xen/xend/server/BlktapController.py |   12 
 12 files changed, 15 insertions(+), 2735 deletions(-)

diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/Makefile
--- a/tools/blktap2/Makefile    Thu Jun 18 10:27:21 2009 +0100
+++ b/tools/blktap2/Makefile    Thu Jun 18 10:29:58 2009 +0100
@@ -9,7 +9,6 @@ SUBDIRS-y += lvm
 SUBDIRS-y += lvm
 SUBDIRS-y += vhd
 SUBDIRS-y += drivers
-SUBDIRS-y += daemon
 
 clean:
        rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) TAGS
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/Makefile
--- a/tools/blktap2/daemon/Makefile     Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-XEN_ROOT=../../../
-BLKTAP_ROOT := ..
-include $(XEN_ROOT)/tools/Rules.mk
-
-SUBDIRS-y    :=
-SUBDIRS-y    += lib
-
-IBIN          = blktapctrl
-INST_DIR      = $(SBINDIR)
-
-LIBS         := -lxenstore
-LIBS         += -Llib
-LIBS         += -lblktap
-LIBS         += -lxenctrl
-
-ifneq ($(USE_SYSTEM_LIBRARIES),y)
-INCLUDES     += -I $(XEN_LIBXC) -I $(XEN_XENSTORE)
-LIBS         += -L $(XEN_LIBXC) -L $(XEN_XENSTORE)
-endif
-
-OBJS         := tapdisk-dispatch-common.o
-OBJS         += tapdisk-channel.o
-
-CFLAGS       += -Werror
-CFLAGS       += -Wno-unused
-CFLAGS       += -fno-strict-aliasing -fPIC
-CFLAGS       += -Ilib -I../include -I../drivers -I../../include $(INCLUDES)
-CFLAGS       += -D_GNU_SOURCE
-CFLAGS       += -g
-
-# Get gcc to generate the dependencies for us.
-CFLAGS       += -Wp,-MD,.$(@F).d
-DEPS          = .*.d
-
-all: subdirs-all $(IBIN)
-
-LIBS_DEPENDS := lib/libblktap.a lib/libblktap.so
-$(LIBS_DEPENDS):subdirs-all
-
-blktapctrl: tapdisk-daemon.c $(OBJS) $(LIBS_DEPENDS)
-       $(CC) $(CFLAGS) -o blktapctrl tapdisk-daemon.c $(LDFLAGS) $(LIBS) 
$(OBJS)
-
-install: all
-       $(MAKE) subdirs-install
-       $(INSTALL_DIR) -p $(DESTDIR)$(INST_DIR)
-       $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(INST_DIR)
-
-clean: subdirs-clean
-       rm -rf *.o *~ $(IBIN) $(DEPS) xen TAGS
-
-.PHONY: all clean install blktapctrl
-
--include $(DEPS)
-
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/lib/Makefile
--- a/tools/blktap2/daemon/lib/Makefile Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-XEN_ROOT=../../../../
-BLKTAP_ROOT := ../../
-include $(XEN_ROOT)/tools/Rules.mk
-
-MAJOR    = 3.1
-MINOR    = 0
-SONAME   = libblktap.so.$(MAJOR)
-
-BLKTAP_INSTALL_DIR = /usr/sbin
-
-LIBS     := -lxenstore
-
-ifneq ($(USE_SYSTEM_LIBRARIES),y)
-INCLUDES += -I $(XEN_LIBXC) -I $(XEN_XENSTORE)
-LIBS     += -L$(XEN_XENSTORE)
-endif
-
-SRCS     :=
-SRCS     += xs_api.c
-CFLAGS   += -Werror
-CFLAGS   += -Wno-unused
-CFLAGS   += -fno-strict-aliasing -fPIC
-# get asprintf():
-CFLAGS   += -D _GNU_SOURCE
-CFLAGS   += -g
-CFLAGS   += -I../../include -I../../../include/ $(INCLUDES) 
-
-
-# Get gcc to generate the dependencies for us.
-CFLAGS  += -Wp,-MD,.$(@F).d
-DEPS     = .*.d
-
-OBJS     = $(patsubst %.c,%.o,$(SRCS))
-IBINS   :=
-
-LIB      = libblktap.a libblktap.so.$(MAJOR).$(MINOR)
-
-.PHONY: all
-all: build
-
-.PHONY: build
-build: libblktap.a
-
-.PHONY: libblktap
-libblktap: libblktap.a
-
-install: all
-       $(INSTALL_DIR) -p $(DESTDIR)$(LIBDIR)
-       $(INSTALL_DATA) $(LIB) $(DESTDIR)$(LIBDIR)
-       ln -sf libblktap.so.$(MAJOR).$(MINOR) 
$(DESTDIR)$(LIBDIR)/libblktap.so.$(MAJOR)
-       ln -sf libblktap.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libblktap.so
-
-clean:
-       rm -rf *.a *.so* *.o *.rpm $(LIB) *~ $(DEPS) xen TAGS
-
-libblktap.a: $(OBJS) 
-       $(CC) $(CFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,$(SONAME) $(SHLIB_CFLAGS) \
-             $(LDFLAGS) -o libblktap.so.$(MAJOR).$(MINOR) $^ $(LIBS)
-       ln -sf libblktap.so.$(MAJOR).$(MINOR) libblktap.so.$(MAJOR)
-       ln -sf libblktap.so.$(MAJOR) libblktap.so
-       $(AR) rc $@ libblktap.so
-
-.PHONY: TAGS all build clean install libblktap
-
-TAGS:
-       etags -t $(SRCS) *.h
-
--include $(DEPS)
-
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/lib/xs_api.c
--- a/tools/blktap2/daemon/lib/xs_api.c Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-/*
- * xs_api.c
- * 
- * blocktap interface functions to xenstore
- *
- * (c) 2005 Andrew Warfield and Julian Chesterfield
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (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.
- *
- */
-
-#include <time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <xs.h>
-
-#include "xs_api.h"
-#include "blktaplib.h"
-
-#define DOMNAME "Domain-0"
-#define BASE_DEV_VAL 2048
-
-static LIST_HEAD(watches);
-
-int
-xs_gather(struct xs_handle *xs, const char *dir, ...)
-{
-       va_list ap;
-       const char *name;
-       char *path, **e;
-       int ret = 0, num,i;
-       unsigned int len;
-       xs_transaction_t xth;
-
-again:
-       if ((xth = xs_transaction_start(xs)) == XBT_NULL) {
-               DPRINTF("unable to start xs trasanction\n");
-               ret = ENOMEM;
-               return ret;
-       }
-
-       va_start(ap, dir);
-       while ((ret == 0) && (name = va_arg(ap, char *)) != NULL) {
-               char *p;
-               const char *fmt = va_arg(ap, char *);
-               void *result = va_arg(ap, void *);
-               
-               if (asprintf(&path, "%s/%s", dir, name) == -1) {
-                       EPRINTF("allocation error in xs_gather!\n");
-                       ret = ENOMEM;
-                       break;
-               }
-
-               p = xs_read(xs, xth, path, &len);
-               free(path);
-
-               if (!p) {
-                       ret = ENOENT;
-                       break;
-               }
-
-               if (fmt) {
-                       if (sscanf(p, fmt, result) == 0)
-                               ret = EINVAL;
-                       free(p);
-               } else
-                       *(char **)result = p;
-       }
-
-       va_end(ap);
-
-       if (!xs_transaction_end(xs, xth, ret)) {
-               if (ret == 0 && errno == EAGAIN)
-                       goto again;
-               else
-                       ret = errno;
-       }
-
-       return ret;
-}
-
-/* Single printf and write: returns -errno or 0. */
-int
-xs_printf(struct xs_handle *h, const char *dir,
-         const char *node, const char *fmt, ...)
-{
-       int ret;
-       va_list ap;
-       char *buf, *path;
-
-       va_start(ap, fmt);
-       ret = vasprintf(&buf, fmt, ap);
-       va_end(ap);
-
-       if (ret == -1)
-               return 0;
-
-       ret = asprintf(&path, "%s/%s", dir, node);
-       if (ret == -1) {
-               free(buf);
-               return 0;
-       }
-
-       ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1);
-
-       free(buf);
-       free(path);
-
-       return ret;
-}
-
-int
-xs_exists(struct xs_handle *h, const char *path)
-{
-       char **d;
-       unsigned int num;
-       xs_transaction_t xth;
-
-       if ((xth = xs_transaction_start(h)) == XBT_NULL) {
-               EPRINTF("unable to start xs trasanction\n");
-               return 0;
-       }
-
-       d = xs_directory(h, xth, path, &num);
-       xs_transaction_end(h, xth, 0);
-       if (!d)
-               return 0;
-
-       free(d);
-       return 1;
-}
-
-
-
-/**
- * This assumes that the domain name we are looking for is unique. 
- * Name parameter Domain-0 
- */
-char *
-get_dom_domid(struct xs_handle *h)
-{
-       int i;
-       xs_transaction_t xth;
-       unsigned int num, len;
-       char *val, *path, *domid, **e;
-
-       e     = NULL;
-       domid = NULL;
-
-       if ((xth = xs_transaction_start(h)) == XBT_NULL) {
-               EPRINTF("unable to start xs trasanction\n");
-               return NULL;
-       }
-
-       e = xs_directory(h, xth, "/local/domain", &num);
-       if (e == NULL)
-               goto done;
-
-       for (i = 0; (i < num) && (domid == NULL); i++) {
-               if (asprintf(&path, "/local/domain/%s/name", e[i]) == -1)
-                       break;
-
-               val = xs_read(h, xth, path, &len);
-               free(path);
-               if (val == NULL)
-                       continue;
-
-               if (strcmp(val, DOMNAME) == 0) {
-                       /* match! */
-                       if (asprintf(&path, 
-                                    "/local/domain/%s/domid", e[i]) == -1) {
-                               free(val);
-                               break;
-                       }
-                       domid = xs_read(h, xth, path, &len);
-                       free(path);
-               }
-               free(val);
-       }
-
- done:
-       xs_transaction_end(h, xth, 0);
-       free(e);
-       return domid;
-}
-
-/*
- * a little paranoia: we don't just trust token
- */
-static struct xenbus_watch *find_watch(const char *token)
-{
-       int ret;
-       long nonce;
-       unsigned long addr;
-       struct xenbus_watch *i, *cmp;
-
-       ret = sscanf(token, "%lX:%lX", &addr, &nonce);
-       if (ret != 2) {
-               EPRINTF("invalid watch token %s\n", token);
-               return NULL;
-       }
-
-       cmp = (struct xenbus_watch *)addr;
-       list_for_each_entry(i, &watches, list)
-               if (i == cmp && i->nonce == nonce)
-                       return i;
-
-       return NULL;
-}
-
-/*
- * Register callback to watch this node;
- * like xs_watch, return 0 on failure
- */
-int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch)
-{
-       /* Pointer in ascii is the token. */
-       char token[(sizeof(watch) + sizeof(long)) * 2 + 2];
-
-       /* 1-second granularity should suffice here */
-       watch->nonce = time(NULL);
-
-       sprintf(token, "%lX:%lX", (long)watch, watch->nonce);
-       if (find_watch(token)) {
-               EPRINTF("watch collision!\n");
-               return -EINVAL;
-       }
-
-       if (!xs_watch(h, watch->node, token)) {
-               EPRINTF("unable to set watch!\n");
-               return -EINVAL;
-       }
-
-       list_add(&watch->list, &watches);
-
-       return 0;
-}
-
-int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch)
-{
-       char token[(sizeof(watch) + sizeof(long)) * 2 + 2];
-
-       sprintf(token, "%lX:%lX", (long)watch, watch->nonce);
-       if (!find_watch(token)) {
-               EPRINTF("no such watch!\n");
-               return -EINVAL;
-       }
-
-       if (!xs_unwatch(h, watch->node, token))
-               EPRINTF("XENBUS Failed to release watch %s\n", watch->node);
-
-       list_del(&watch->list);
-
-       return 0;
-}
-
-/*
- * re-register callbacks to all watches
- */
-void reregister_xenbus_watches(struct xs_handle *h)
-{
-       struct xenbus_watch *watch;
-       char token[(sizeof(watch) + sizeof(long)) * 2 + 2];
-
-       list_for_each_entry(watch, &watches, list) {
-               sprintf(token, "%lX:%lX", (long)watch, watch->nonce);
-               xs_watch(h, watch->node, token);
-       }
-}
-
-/*
- * based on watch_thread() 
- */
-int xs_fire_next_watch(struct xs_handle *h)
-{
-       unsigned int num;
-       struct xenbus_watch *w;
-       char **res, *token, *node = NULL;
-
-       res = xs_read_watch(h, &num);
-       if (res == NULL) 
-               return -EAGAIN; /* in O_NONBLOCK, read_watch returns 0... */
-
-       node  = res[XS_WATCH_PATH];
-       token = res[XS_WATCH_TOKEN];
-       DPRINTF("got watch %s on %s\n", token, node);
-
-       w = find_watch(token);
-       if (w) 
-               w->callback(h, w, node);
-
-       DPRINTF("handled watch %s on %s\n", token, node);
-
-       free(res);
-
-       return 1;
-}
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/lib/xs_api.h
--- a/tools/blktap2/daemon/lib/xs_api.h Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * xs_api.h
- *
- * (c) 2005 Andrew Warfield and Julian Chesterfield
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (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.
- */
-
-#ifndef _XS_API_H_
-#define _XS_API_H_
-
-#include <xs.h>
-
-#include "list.h"
-
-struct xenbus_watch
-{
-        struct list_head  list;
-        char             *node;
-       void             *data;
-       long              nonce;
-        void (*callback) (struct xs_handle *h, 
-                         struct xenbus_watch *, 
-                         const  char *node);
-};
-
-int xs_gather(struct xs_handle *xs, const char *dir, ...);
-int xs_printf(struct xs_handle *h, const char *dir, const char *node, 
-             const char *fmt, ...) __attribute__((format(printf, 4, 5)));
-int xs_exists(struct xs_handle *h, const char *path);
-char *get_dom_domid(struct xs_handle *h);
-int convert_dev_name_to_num(char *name);
-
-int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
-int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
-void reregister_xenbus_watches(struct xs_handle *h);
-int xs_fire_next_watch(struct xs_handle *h);
-
-#endif
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/tapdisk-channel.c
--- a/tools/blktap2/daemon/tapdisk-channel.c    Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1367 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of XenSource Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
- * 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.
-*/
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdarg.h>
-#include <sys/wait.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-
-#include <xs.h>
-#include "disktypes.h"
-#include "tapdisk-dispatch.h"
-
-#define TAPDISK_CHANNEL_IDLE          1
-#define TAPDISK_CHANNEL_WAIT_PID      2
-#define TAPDISK_CHANNEL_WAIT_OPEN     3
-#define TAPDISK_CHANNEL_WAIT_PAUSE    4
-#define TAPDISK_CHANNEL_WAIT_RESUME   5
-#define TAPDISK_CHANNEL_WAIT_CLOSE    6
-#define TAPDISK_CHANNEL_CLOSED        7
-
-static void tapdisk_channel_error(tapdisk_channel_t *,
-                                 const char *fmt, ...)
-  __attribute__((format(printf, 2, 3)));
-static void tapdisk_channel_fatal(tapdisk_channel_t *,
-                                 const char *fmt, ...)
-  __attribute__((format(printf, 2, 3)));
-static int tapdisk_channel_parse_params(tapdisk_channel_t *);
-static void tapdisk_channel_pause_event(struct xs_handle *,
-                                       struct xenbus_watch *,
-                                       const char *);
-
-static int
-tapdisk_channel_check_uuid(tapdisk_channel_t *channel)
-{
-       uint32_t uuid;
-       char *uuid_str;
-
-       uuid_str = xs_read(channel->xsh, XBT_NULL, channel->uuid_str, NULL);
-       if (!uuid_str)
-               return -errno;
-
-       uuid = strtoul(uuid_str, NULL, 10);
-       free(uuid_str);
-
-       if (uuid != channel->cookie)
-               return -EINVAL;
-
-       return 0;
-}
-
-static inline int
-tapdisk_channel_validate_watch(tapdisk_channel_t *channel, const char *path)
-{
-       int err, len;
-
-       len = strsep_len(path, '/', 7);
-       if (len < 0)
-               return -EINVAL;
-
-       err = tapdisk_channel_check_uuid(channel);
-       if (err)
-               return err;
-
-       if (!xs_exists(channel->xsh, path))
-               return -ENOENT;
-
-       return 0;
-}
-
-static inline int
-tapdisk_channel_validate_message(tapdisk_channel_t *channel,
-                                tapdisk_message_t *message)
-{
-       switch (message->type) {
-       case TAPDISK_MESSAGE_PID_RSP:
-               if (channel->state != TAPDISK_CHANNEL_WAIT_PID)
-                       return -EINVAL;
-               break;
-
-       case TAPDISK_MESSAGE_OPEN_RSP:
-               if (channel->state != TAPDISK_CHANNEL_WAIT_OPEN)
-                       return -EINVAL;
-               break;
-
-       case TAPDISK_MESSAGE_PAUSE_RSP:
-               if (channel->state != TAPDISK_CHANNEL_WAIT_PAUSE)
-                       return -EINVAL;
-               break;
-
-       case TAPDISK_MESSAGE_RESUME_RSP:
-               if (channel->state != TAPDISK_CHANNEL_WAIT_RESUME)
-                       return -EINVAL;
-               break;
-
-       case TAPDISK_MESSAGE_CLOSE_RSP:
-               if (channel->state != TAPDISK_CHANNEL_WAIT_CLOSE)
-                       return -EINVAL;
-               break;
-
-       case TAPDISK_MESSAGE_RUNTIME_ERROR:
-               /*
-                * runtime errors can be received at any time
-                * and should not affect the state machine
-                */
-               return 0;
-       }
-
-       channel->state = TAPDISK_CHANNEL_IDLE;
-       return 0;
-}
-
-static int
-tapdisk_channel_send_message(tapdisk_channel_t *channel,
-                            tapdisk_message_t *message, int timeout)
-{
-       fd_set writefds;
-       struct timeval tv;
-       int ret, len, offset;
-
-       tv.tv_sec  = timeout;
-       tv.tv_usec = 0;
-       offset     = 0;
-       len        = sizeof(tapdisk_message_t);
-
-       DPRINTF("%s: sending '%s' message to %d:%d\n",
-               channel->path, tapdisk_message_name(message->type),
-               channel->channel_id, channel->cookie);
-
-       if (channel->state != TAPDISK_CHANNEL_IDLE &&
-           message->type  != TAPDISK_MESSAGE_CLOSE)
-               EPRINTF("%s: writing message to non-idle channel (%d)\n",
-                       channel->path, channel->state);
-
-       while (offset < len) {
-               FD_ZERO(&writefds);
-               FD_SET(channel->write_fd, &writefds);
-
-               /* we don't bother reinitializing tv. at worst, it will wait a
-                * bit more time than expected. */
-
-               ret = select(channel->write_fd + 1,
-                            NULL, &writefds, NULL, &tv);
-               if (ret == -1)
-                       break;
-               else if (FD_ISSET(channel->write_fd, &writefds)) {
-                       ret = write(channel->write_fd,
-                                   message + offset, len - offset);
-                       if (ret <= 0)
-                               break;
-                       offset += ret;
-               } else
-                       break;
-       }
-
-       if (offset != len) {
-               EPRINTF("%s: error writing '%s' message to %d:%d\n",
-                       channel->path, tapdisk_message_name(message->type),
-                       channel->channel_id, channel->cookie);
-               return -EIO;
-       }
-
-       switch (message->type) {
-       case TAPDISK_MESSAGE_PID:
-               channel->state = TAPDISK_CHANNEL_WAIT_PID;
-               break;
-
-       case TAPDISK_MESSAGE_OPEN:
-               channel->state = TAPDISK_CHANNEL_WAIT_OPEN;
-               break;
-
-       case TAPDISK_MESSAGE_PAUSE:
-               channel->state = TAPDISK_CHANNEL_WAIT_PAUSE;
-               break;
-
-       case TAPDISK_MESSAGE_RESUME:
-               channel->state = TAPDISK_CHANNEL_WAIT_RESUME;
-               break;
-
-       case TAPDISK_MESSAGE_CLOSE:
-               channel->state = TAPDISK_CHANNEL_WAIT_CLOSE;
-               break;
-
-       default:
-               EPRINTF("%s: unrecognized message type %d\n",
-                       channel->path, message->type);
-       }
-
-       return 0;
-}
-
-static void
-__tapdisk_channel_error(tapdisk_channel_t *channel,
-                       const char *fmt, va_list ap)
-{
-       int err;
-       char *dir, *buf, *message;
-
-       err = vasprintf(&buf, fmt, ap);
-       if (err == -1) {
-               EPRINTF("failed to allocate error message\n");
-               buf = NULL;
-       }
-
-       if (buf)
-               message = buf;
-       else
-               message = "tapdisk error";
-
-       EPRINTF("%s: %s\n", channel->path, message);
-
-       err = asprintf(&dir, "%s/tapdisk-error", channel->path);
-       if (err == -1) {
-               EPRINTF("%s: failed to write %s\n", __func__, message);
-               dir = NULL;
-               goto out;
-       }
-
-       xs_write(channel->xsh, XBT_NULL, dir, message, strlen(message));
-
-out:
-       free(dir);
-       free(buf);
-}
-
-static void
-tapdisk_channel_error(tapdisk_channel_t *channel, const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       __tapdisk_channel_error(channel, fmt, ap);
-       va_end(ap);
-}
-
-static void
-tapdisk_channel_fatal(tapdisk_channel_t *channel, const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       __tapdisk_channel_error(channel, fmt, ap);
-       va_end(ap);
-
-       tapdisk_channel_close(channel);
-}
-
-static int
-tapdisk_channel_connect_backdev(tapdisk_channel_t *channel)
-{
-       int err, major, minor;
-       char *s, *path, *devname;
-
-       s       = NULL;
-       path    = NULL;
-       devname = NULL;
-
-       err = ioctl(channel->blktap_fd,
-                   BLKTAP_IOCTL_BACKDEV_SETUP, channel->minor);
-       if (err) {
-               err = -errno;
-               goto fail;
-       }
-
-       err = asprintf(&path, "%s/backdev-node", channel->path);
-       if (err == -1) {
-               path = NULL;
-               err  = -ENOMEM;
-               goto fail;
-       }
-
-       s = xs_read(channel->xsh, XBT_NULL, path, NULL);
-       if (!s) {
-               err = -errno;
-               goto fail;
-       }
-
-       err = sscanf(s, "%d:%d", &major, &minor);
-       if (err != 2) {
-               err = -EINVAL;
-               goto fail;
-       }
-
-       err = asprintf(&devname,"%s/%s%d",
-                      BLKTAP_DEV_DIR, BACKDEV_NAME, minor);
-       if (err == -1) {
-               devname = NULL;
-               err = -ENOMEM;
-               goto fail;
-       }
-
-       err = make_blktap_device(devname, major, minor, S_IFBLK | 0600);
-       if (err)
-               goto fail;
-
-       free(path);
-       err = asprintf(&path, "%s/backdev-path", channel->path);
-       if (err == -1) {
-               path = NULL;
-               err  = -ENOMEM;
-               goto fail;
-       }
-
-       err = xs_write(channel->xsh, XBT_NULL, path, devname, strlen(devname));
-       if (err == 0) {
-               err = -errno;
-               goto fail;
-       }
-
-       err = 0;
- out:
-       free(devname);
-       free(path);
-       free(s);
-       return err;
-
- fail:
-       EPRINTF("backdev setup failed [%d]\n", err);
-       goto out;
-}
-
-static int
-tapdisk_channel_complete_connection(tapdisk_channel_t *channel)
-{
-       int err;
-       char *path;
-
-       if (!xs_printf(channel->xsh, channel->path,
-                      "sectors", "%llu", channel->image.size)) {
-               EPRINTF("ERROR: Failed writing sectors");
-               return -errno;
-       }
-
-       if (!xs_printf(channel->xsh, channel->path,
-                      "sector-size", "%lu", channel->image.secsize)) {
-               EPRINTF("ERROR: Failed writing sector-size");
-               return -errno;
-       }
-
-       if (!xs_printf(channel->xsh, channel->path,
-                      "info", "%u", channel->image.info)) {
-               EPRINTF("ERROR: Failed writing info");
-               return -errno;
-       }
-
-       err = tapdisk_channel_connect_backdev(channel);
-       if (err)
-               goto clean;
-
-       channel->connected = 1;
-       return 0;
-
- clean:
-       if (asprintf(&path, "%s/info", channel->path) == -1)
-               return err;
-
-       if (!xs_rm(channel->xsh, XBT_NULL, path))
-               goto clean_out;
-
-       free(path);
-       if (asprintf(&path, "%s/sector-size", channel->path) == -1)
-               return err;
-
-       if (!xs_rm(channel->xsh, XBT_NULL, path))
-               goto clean_out;
-
-       free(path);
-       if (asprintf(&path, "%s/sectors", channel->path) == -1)
-               return err;
-
-       xs_rm(channel->xsh, XBT_NULL, path);
-
- clean_out:
-       free(path);
-       return err;
-}
-
-static int
-tapdisk_channel_send_open_request(tapdisk_channel_t *channel)
-{
-       int len;
-       tapdisk_message_t message;
-
-       memset(&message, 0, sizeof(tapdisk_message_t));
-
-       len = strlen(channel->vdi_path);
-
-       message.type              = TAPDISK_MESSAGE_OPEN;
-       message.cookie            = channel->cookie;
-       message.drivertype        = channel->drivertype;
-       message.u.params.storage  = channel->storage;
-       message.u.params.devnum   = channel->minor;
-       message.u.params.domid    = channel->domid;
-       message.u.params.path_len = len;
-       strncpy(message.u.params.path, channel->vdi_path, len);
-
-       if (channel->mode == 'r')
-               message.u.params.flags |= TAPDISK_MESSAGE_FLAG_RDONLY;
-       if (channel->shared)
-               message.u.params.flags |= TAPDISK_MESSAGE_FLAG_SHARED;
-
-       /* TODO: clean this up */
-       if (xs_exists(channel->xsh, "/local/domain/0/tapdisk/add-cache"))
-               message.u.params.flags |= TAPDISK_MESSAGE_FLAG_ADD_CACHE;
-       if (xs_exists(channel->xsh, "/local/domain/0/tapdisk/log-dirty"))
-               message.u.params.flags |= TAPDISK_MESSAGE_FLAG_LOG_DIRTY;
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_receive_open_response(tapdisk_channel_t *channel,
-                                     tapdisk_message_t *message)
-{
-       int err;
-
-       channel->image.size    = message->u.image.sectors;
-       channel->image.secsize = message->u.image.sector_size;
-       channel->image.info    = message->u.image.info;
-
-       err = tapdisk_channel_complete_connection(channel);
-       if (err)
-               goto fail;
-
-       /* did we receive a pause request before the connection completed? */
-       if (channel->pause_needed) {
-               DPRINTF("%s: deferred pause request\n", channel->path);
-               tapdisk_channel_pause_event(channel->xsh,
-                                           &channel->pause_watch,
-                                           channel->pause_str);
-               channel->pause_needed = 0;
-       }
-
-       return 0;
-
-fail:
-       tapdisk_channel_fatal(channel,
-                             "failure completing connection: %d", err);
-       return err;
-}
-
-static int
-tapdisk_channel_send_shutdown_request(tapdisk_channel_t *channel)
-{
-       tapdisk_message_t message;
-
-       memset(&message, 0, sizeof(tapdisk_message_t));
-
-       message.type       = TAPDISK_MESSAGE_CLOSE;
-       message.drivertype = channel->drivertype;
-       message.cookie     = channel->cookie;
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_receive_shutdown_response(tapdisk_channel_t *channel,
-                                         tapdisk_message_t *message)
-{
-       channel->open  = 0;
-       channel->state = TAPDISK_CHANNEL_CLOSED;
-       tapdisk_channel_close(channel);
-       return 0;
-}
-
-static int
-tapdisk_channel_receive_runtime_error(tapdisk_channel_t *channel,
-                                     tapdisk_message_t *message)
-{
-       tapdisk_channel_error(channel,
-                             "runtime error: %s", message->u.string.text);
-       return 0;
-}
-
-static int
-tapdisk_channel_send_pid_request(tapdisk_channel_t *channel)
-{
-       int err;
-       tapdisk_message_t message;
-
-       memset(&message, 0, sizeof(tapdisk_message_t));
-
-       message.type       = TAPDISK_MESSAGE_PID;
-       message.drivertype = channel->drivertype;
-       message.cookie     = channel->cookie;
-
-       err = tapdisk_channel_send_message(channel, &message, 2);
-
-       if (!err)
-               channel->open = 1;
-
-       return err;
-}
-
-static int
-tapdisk_channel_receive_pid_response(tapdisk_channel_t *channel,
-                                    tapdisk_message_t *message)
-{
-       int err;
-
-       channel->tapdisk_pid = message->u.tapdisk_pid;
-
-       DPRINTF("%s: tapdisk pid: %d\n", channel->path, channel->tapdisk_pid);
-
-       err = setpriority(PRIO_PROCESS, channel->tapdisk_pid, PRIO_SPECIAL_IO);
-       if (err) {
-               tapdisk_channel_fatal(channel,
-                                     "setting tapdisk priority: %d", err);
-               return err;
-       }
-
-       err = tapdisk_channel_send_open_request(channel);
-       if (err) {
-               tapdisk_channel_fatal(channel,
-                                     "sending open request: %d", err);
-               return err;
-       }
-
-       return 0;
-}
-
-static int
-tapdisk_channel_send_pause_request(tapdisk_channel_t *channel)
-{
-       tapdisk_message_t message;
-
-       memset(&message, 0, sizeof(tapdisk_message_t));
-
-       DPRINTF("pausing %s\n", channel->path);
-
-       message.type       = TAPDISK_MESSAGE_PAUSE;
-       message.drivertype = channel->drivertype;
-       message.cookie     = channel->cookie;
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_receive_pause_response(tapdisk_channel_t *channel,
-                                      tapdisk_message_t *message)
-{
-       int err;
-
-       if (!xs_write(channel->xsh, XBT_NULL,
-                     channel->pause_done_str, "", strlen(""))) {
-               err = -errno;
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-       tapdisk_channel_fatal(channel,
-                             "failure receiving pause response: %d\n", err);
-       return err;
-}
-
-static int
-tapdisk_channel_send_resume_request(tapdisk_channel_t *channel)
-{
-       int len;
-       tapdisk_message_t message;
-
-       memset(&message, 0, sizeof(tapdisk_message_t));
-
-       len = strlen(channel->vdi_path);
-
-       DPRINTF("resuming %s\n", channel->path);
-
-       message.type              = TAPDISK_MESSAGE_RESUME;
-       message.drivertype        = channel->drivertype;
-       message.cookie            = channel->cookie;
-       message.u.params.path_len = len;
-       strncpy(message.u.params.path, channel->vdi_path, len);
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_receive_resume_response(tapdisk_channel_t *channel,
-                                       tapdisk_message_t *message)
-{
-       int err;
-
-       if (!xs_rm(channel->xsh, XBT_NULL, channel->pause_done_str)) {
-               err = -errno;
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-       tapdisk_channel_fatal(channel,
-                             "failure receiving pause response: %d", err);
-       return err;
-}
-
-static void
-tapdisk_channel_shutdown_event(struct xs_handle *xsh,
-                              struct xenbus_watch *watch, const char *path)
-{
-       int err;
-       tapdisk_channel_t *channel;
-
-       channel = watch->data;
-
-       DPRINTF("%s: got watch on %s\n", channel->path, path);
-
-       if (!xs_exists(channel->xsh, channel->path)) {
-               tapdisk_channel_close(channel);
-               return;
-       }
-
-       err = tapdisk_channel_validate_watch(channel, path);
-       if (err) {
-               if (err == -EINVAL)
-                       tapdisk_channel_fatal(channel, "bad shutdown watch");
-               return;
-       }
-
-       tapdisk_channel_send_shutdown_request(channel);
-}
-
-static void
-tapdisk_channel_pause_event(struct xs_handle *xsh,
-                           struct xenbus_watch *watch, const char *path)
-{
-       int err, paused;
-       tapdisk_channel_t *channel;
-
-       channel = watch->data;
-
-       DPRINTF("%s: got watch on %s\n", channel->path, path);
-
-       if (!xs_exists(channel->xsh, channel->path)) {
-               tapdisk_channel_close(channel);
-               return;
-       }
-
-       /* NB: The VBD is essentially considered ready since the
-        * backend hotplug event ocurred, which is just after
-        * start-tapdisk, not after watch registration. We start
-        * testing xenstore keys with the very first shot, but defer
-        * until after connection completion. */
-
-       err = tapdisk_channel_validate_watch(channel, path);
-       if (err) {
-               if (err == -EINVAL)
-                       tapdisk_channel_fatal(channel, "bad pause watch");
-
-               if (err != -ENOENT)
-                       return;
-
-               err = 0;
-       }
-
-       paused  = xs_exists(xsh, channel->pause_done_str);
-
-       if (xs_exists(xsh, channel->pause_str)) {
-               /*
-                * Duplicate requests are a protocol validation, but
-                * impossible to identify if watch registration and an
-                * actual pause request may fire separately in close
-                * succession. Warn, but do not signal an error.
-                */
-               int pausing = channel->state == TAPDISK_CHANNEL_WAIT_PAUSE;
-               if (pausing || paused) {
-                       DPRINTF("Ignoring pause event for %s vbd %s\n",
-                               pausing ? "pausing" : "paused", channel->path);
-                       goto out;
-               }
-
-               /* defer if tapdisk is not ready yet */
-               if (!channel->connected) {
-                       DPRINTF("%s: deferring pause request\n", path);
-                       channel->pause_needed = 1;
-                       goto out;
-               }
-
-               err = tapdisk_channel_send_pause_request(channel);
-
-       } else if (xs_exists(xsh, channel->pause_done_str)) {
-               free(channel->params);
-               channel->params   = NULL;
-               channel->vdi_path = NULL;
-
-               err = xs_gather(channel->xsh, channel->path,
-                               "params", NULL, &channel->params, NULL);
-               if (err) {
-                       EPRINTF("failure re-reading params: %d\n", err);
-                       channel->params = NULL;
-                       goto out;
-               }
-
-               err = tapdisk_channel_parse_params(channel);
-               if (err)
-                       goto out;
-
-               err = tapdisk_channel_send_resume_request(channel);
-               if (err)
-                       goto out;
-       }
-
-       err = 0;
-
-out:
-       if (err)
-               tapdisk_channel_error(channel, "pause event failed: %d", err);
-}
-
-static int
-tapdisk_channel_open_control_socket(char *devname)
-{
-       int err, fd;
-       fd_set socks;
-       struct timeval timeout;
-
-       err = mkdir(BLKTAP_CTRL_DIR, 0755);
-       if (err == -1 && errno != EEXIST) {
-               EPRINTF("Failure creating %s directory: %d\n",
-                       BLKTAP_CTRL_DIR, errno);
-               return -errno;
-       }
-
-       err = mkfifo(devname, S_IRWXU | S_IRWXG | S_IRWXO);
-       if (err) {
-               if (errno == EEXIST) {
-                       /*
-                        * Remove fifo since it may have data from
-                        * it's previous use --- earlier invocation
-                        * of tapdisk may not have read all messages.
-                        */
-                       err = unlink(devname);
-                       if (err) {
-                               EPRINTF("ERROR: unlink(%s) failed (%d)\n",
-                                       devname, errno);
-                               return -errno;
-                       }
-
-                       err = mkfifo(devname, S_IRWXU | S_IRWXG | S_IRWXO);
-               }
-
-               if (err) {
-                       EPRINTF("ERROR: pipe failed (%d)\n", errno);
-                       return -errno;
-               }
-       }
-
-       fd = open(devname, O_RDWR | O_NONBLOCK);
-       if (fd == -1) {
-               EPRINTF("Failed to open %s\n", devname);
-               return -errno;
-       }
-
-       return fd;
-}
-
-static int
-tapdisk_channel_get_device_number(tapdisk_channel_t *channel)
-{
-       char *devname;
-       domid_translate_t tr;
-       int major, minor, err;
-
-       tr.domid = channel->domid;
-        tr.busid = channel->busid;
-
-       minor = ioctl(channel->blktap_fd, BLKTAP_IOCTL_NEWINTF, tr);
-       if (minor <= 0 || minor > MAX_TAP_DEV) {
-               EPRINTF("invalid dev id: %d\n", minor);
-               return -EINVAL;
-       }
-
-       major = ioctl(channel->blktap_fd, BLKTAP_IOCTL_MAJOR, minor);
-       if (major < 0) {
-               EPRINTF("invalid major id: %d\n", major);
-               return -EINVAL;
-       }
-
-       err = asprintf(&devname, "%s/%s%d",
-                      BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, minor);
-       if (err == -1) {
-               EPRINTF("get_new_dev: malloc failed\n");
-               return -ENOMEM;
-       }
-
-       err = make_blktap_device(devname, major, minor, S_IFCHR | 0600);
-       free(devname);
-
-       if (err)
-               return err;
-
-       DPRINTF("Received device id %d and major %d, "
-               "sent domid %d and be_id %d\n",
-               minor, major, tr.domid, tr.busid);
-
-       channel->major = major;
-       channel->minor = minor;
-
-       return 0;
-}
-
-static int
-tapdisk_channel_start_process(tapdisk_channel_t *channel,
-                             char *write_dev, char *read_dev)
-{
-       pid_t child;
-       char *argv[] = { "tapdisk", write_dev, read_dev, NULL };
-
-       if ((child = fork()) == -1)
-               return -errno;
-
-       if (!child) {
-               int i;
-               for (i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++)
-                       if (i != STDIN_FILENO &&
-                           i != STDOUT_FILENO &&
-                           i != STDERR_FILENO)
-                               close(i);
-
-               execvp("tapdisk", argv);
-               _exit(1);
-       } else {
-               pid_t got;
-               do {
-                       got = waitpid(child, NULL, 0);
-               } while (got != child);
-       }
-       return 0;
-}
-
-static int
-tapdisk_channel_launch_tapdisk(tapdisk_channel_t *channel)
-{
-       int err;
-       char *read_dev, *write_dev;
-
-       read_dev          = NULL;
-       write_dev         = NULL;
-       channel->read_fd  = -1;
-       channel->write_fd = -1;
-
-       err = tapdisk_channel_get_device_number(channel);
-       if (err)
-               return err;
-
-       err = asprintf(&write_dev,
-                      "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, channel->minor);
-       if (err == -1) {
-               err = -ENOMEM;
-               write_dev = NULL;
-               goto fail;
-       }
-
-       err = asprintf(&read_dev,
-                      "%s/tapctrlread%d", BLKTAP_CTRL_DIR, channel->minor);
-       if (err == -1) {
-               err = -ENOMEM;
-               read_dev = NULL;
-               goto fail;
-       }
-
-       channel->write_fd = tapdisk_channel_open_control_socket(write_dev);
-       if (channel->write_fd < 0) {
-               err = channel->write_fd;
-               channel->write_fd = -1;
-               goto fail;
-       }
-
-       channel->read_fd = tapdisk_channel_open_control_socket(read_dev);
-       if (channel->read_fd < 0) {
-               err = channel->read_fd;
-               channel->read_fd = -1;
-               goto fail;
-       }
-
-       err = tapdisk_channel_start_process(channel, write_dev, read_dev);
-       if (err)
-               goto fail;
-
-       channel->open       = 1;
-       channel->channel_id = channel->write_fd;
-
-       free(read_dev);
-       free(write_dev);
-
-       DPRINTF("process launched, channel = %d:%d\n",
-               channel->channel_id, channel->cookie);
-
-       return tapdisk_channel_send_pid_request(channel);
-
-fail:
-       free(read_dev);
-       free(write_dev);
-       if (channel->read_fd != -1)
-               close(channel->read_fd);
-       if (channel->write_fd != -1)
-               close(channel->write_fd);
-       return err;
-}
-
-static int
-tapdisk_channel_connect(tapdisk_channel_t *channel)
-{
-       int err;
-
-       tapdisk_daemon_find_channel(channel);
-
-       if (!channel->tapdisk_pid)
-               return tapdisk_channel_launch_tapdisk(channel);
-
-       DPRINTF("%s: process exists: %d, channel = %d:%d\n",
-               channel->path, channel->tapdisk_pid,
-               channel->channel_id, channel->cookie);
-
-       err = tapdisk_channel_get_device_number(channel);
-       if (err)
-               return err;
-
-       return tapdisk_channel_send_pid_request(channel);
-}
-
-static int
-tapdisk_channel_init(tapdisk_channel_t *channel)
-{
-       int err;
-
-       channel->uuid_str          = NULL;
-       channel->pause_str         = NULL;
-       channel->pause_done_str    = NULL;
-       channel->shutdown_str      = NULL;
-       channel->share_tapdisk_str = NULL;
-
-       err = asprintf(&channel->uuid_str,
-                      "%s/tapdisk-uuid", channel->path);
-       if (err == -1) {
-               channel->uuid_str = NULL;
-               goto fail;
-       }
-
-       err = asprintf(&channel->pause_str, "%s/pause", channel->path);
-       if (err == -1) {
-               channel->pause_str = NULL;
-               goto fail;
-       }
-
-       err = asprintf(&channel->pause_done_str,
-                      "%s/pause-done", channel->path);
-       if (err == -1) {
-               channel->pause_done_str = NULL;
-               goto fail;
-       }
-
-       err = asprintf(&channel->shutdown_str,
-                      "%s/shutdown-tapdisk", channel->path);
-       if (err == -1) {
-               channel->shutdown_str = NULL;
-               goto fail;
-       }
-
-       channel->share_tapdisk_str = "/local/domain/0/tapdisk/share-tapdisks";
-
-       return 0;
-
-fail:
-       free(channel->uuid_str);
-       free(channel->pause_str);
-       free(channel->pause_done_str);
-       free(channel->shutdown_str);
-       channel->uuid_str          = NULL;
-       channel->pause_str         = NULL;
-       channel->pause_done_str    = NULL;
-       channel->shutdown_str      = NULL;
-       channel->share_tapdisk_str = NULL;
-       return -ENOMEM;
-}
-
-static int
-tapdisk_channel_set_watches(tapdisk_channel_t *channel)
-{
-       int err;
-
-       /* watch for pause events */
-       channel->pause_watch.node            = channel->pause_str;
-       channel->pause_watch.callback        = tapdisk_channel_pause_event;
-       channel->pause_watch.data            = channel;
-       err = register_xenbus_watch(channel->xsh, &channel->pause_watch);
-       if (err) {
-               channel->pause_watch.node    = NULL;
-               goto fail;
-       }
-
-       /* watch for shutdown events */
-       channel->shutdown_watch.node         = channel->shutdown_str;
-       channel->shutdown_watch.callback     = tapdisk_channel_shutdown_event;
-       channel->shutdown_watch.data         = channel;
-       err = register_xenbus_watch(channel->xsh, &channel->shutdown_watch);
-       if (err) {
-               channel->shutdown_watch.node = NULL;
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-       if (channel->pause_watch.node) {
-               unregister_xenbus_watch(channel->xsh, &channel->pause_watch);
-               channel->pause_watch.node    = NULL;
-       }
-       if (channel->shutdown_watch.node) {
-               unregister_xenbus_watch(channel->xsh, &channel->shutdown_watch);
-               channel->shutdown_watch.node = NULL;
-       }
-       return err;
-}
-
-static void
-tapdisk_channel_get_storage_type(tapdisk_channel_t *channel)
-{
-       int err, type;
-       unsigned int len;
-       char *path, *stype;
-
-       channel->storage = TAPDISK_STORAGE_TYPE_DEFAULT;
-
-       err = asprintf(&path, "%s/sm-data/storage-type", channel->path);
-       if (err == -1)
-               return;
-
-       stype = xs_read(channel->xsh, XBT_NULL, path, &len);
-       if (!stype)
-               goto out;
-       else if (!strcmp(stype, "nfs"))
-               channel->storage = TAPDISK_STORAGE_TYPE_NFS;
-       else if (!strcmp(stype, "ext"))
-               channel->storage = TAPDISK_STORAGE_TYPE_EXT;
-       else if (!strcmp(stype, "lvm"))
-               channel->storage = TAPDISK_STORAGE_TYPE_LVM;
-
-out:
-       free(path);
-       free(stype);
-}
-
-static int
-tapdisk_channel_get_busid(tapdisk_channel_t *channel)
-{
-       int len, end;
-       const char *ptr;
-       char *tptr, num[10];
-
-       len = strsep_len(channel->path, '/', 6);
-       end = strlen(channel->path);
-       if(len < 0 || end < 0) {
-               EPRINTF("invalid path: %s\n", channel->path);
-               return -EINVAL;
-       }
-       
-       ptr = channel->path + len + 1;
-       strncpy(num, ptr, end - len);
-       tptr = num + (end - (len + 1));
-       *tptr = '\0';
-
-       channel->busid = atoi(num);
-       return 0;
-}
-
-static int
-tapdisk_channel_parse_params(tapdisk_channel_t *channel)
-{
-       int i, size, err;
-       unsigned int len;
-       char *ptr, *path, handle[10];
-       char *vdi_type;
-       char *vtype;
-
-       path = channel->params;
-       size = sizeof(dtypes) / sizeof(disk_info_t *);
-
-       if (strlen(path) + 1 >= TAPDISK_MESSAGE_MAX_PATH_LENGTH)
-               goto fail;
-
-       ptr = strchr(path, ':');
-       if (!ptr)
-               goto fail;
-
-       channel->vdi_path = ptr + 1;
-       memcpy(handle, path, (ptr - path));
-       ptr  = handle + (ptr - path);
-       *ptr = '\0';
-
-       err = asprintf(&vdi_type, "%s/sm-data/vdi-type", channel->path);
-       if (err == -1)
-               goto fail;
-
-       if (xs_exists(channel->xsh, vdi_type)) {
-               vtype = xs_read(channel->xsh, XBT_NULL, vdi_type, &len);
-               free(vdi_type);
-               if (!vtype)
-                       goto fail;
-               if (len >= sizeof(handle) - 1) {
-                       free(vtype);
-                       goto fail;
-               }
-               sprintf(handle, "%s", vtype);
-               free(vtype);
-       }
-
-       for (i = 0; i < size; i++) {
-               if (strncmp(handle, dtypes[i]->handle, (ptr - path)))
-                       continue;
-
-               if (dtypes[i]->idnum == -1)
-                       goto fail;
-
-               channel->drivertype = dtypes[i]->idnum;
-               return 0;
-       }
-
-fail:
-       EPRINTF("%s: invalid blktap params: %s\n",
-               channel->path, channel->params);
-       channel->vdi_path = NULL;
-       return -EINVAL;
-}
-
-static int
-tapdisk_channel_gather_info(tapdisk_channel_t *channel)
-{
-       int err;
-
-       err = xs_gather(channel->xsh, channel->path,
-                       "frontend", NULL, &channel->frontpath,
-                       "frontend-id", "%li", &channel->domid,
-                       "params", NULL, &channel->params,
-                       "mode", "%c", &channel->mode, NULL);
-       if (err) {
-               EPRINTF("could not find device info: %d\n", err);
-               return err;
-       }
-
-       err = tapdisk_channel_parse_params(channel);
-       if (err)
-               return err;
-
-       err = tapdisk_channel_get_busid(channel);
-       if (err)
-               return err;
-
-       tapdisk_channel_get_storage_type(channel);
-
-       return 0;
-}
-
-static int
-tapdisk_channel_verify_start_request(tapdisk_channel_t *channel)
-{
-       char *path;
-       unsigned int err;
-
-       err = asprintf(&path, "%s/start-tapdisk", channel->path);
-       if (err == -1)
-               goto mem_fail;
-
-       if (!xs_exists(channel->xsh, path))
-               goto fail;
-
-       free(path);
-       err = asprintf(&path, "%s/shutdown-request", channel->path);
-       if (err == -1)
-               goto mem_fail;
-
-       if (xs_exists(channel->xsh, path))
-               goto fail;
-
-       if (xs_exists(channel->xsh, channel->shutdown_str))
-               goto fail;
-
-       free(path);
-       err = asprintf(&path, "%s/shutdown-done", channel->path);
-       if (err == -1)
-               goto mem_fail;
-
-       if (xs_exists(channel->xsh, path))
-               goto fail;
-
-       free(path);
-
-       return 0;
-
-fail:
-       free(path);
-       EPRINTF("%s:%s: invalid start request\n", __func__, channel->path);
-       return -EINVAL;
-
-mem_fail:
-       EPRINTF("%s:%s: out of memory\n", __func__, channel->path);
-       return -ENOMEM;
-}
-
-void
-tapdisk_channel_close(tapdisk_channel_t *channel)
-{
-       if (channel->channel_id)
-               DPRINTF("%s: closing channel %d:%d\n",
-                       channel->path, channel->channel_id, channel->cookie);
-
-       if (channel->open)
-               tapdisk_channel_send_shutdown_request(channel);
-
-       if (channel->pause_watch.node) {
-               unregister_xenbus_watch(channel->xsh, &channel->pause_watch);
-               channel->pause_watch.node = NULL;
-       }
-
-       if (channel->shutdown_watch.node) {
-               unregister_xenbus_watch(channel->xsh, &channel->shutdown_watch);
-               channel->shutdown_watch.node = NULL;
-       }
-
-       tapdisk_daemon_close_channel(channel);
-
-       free(channel->params);
-       free(channel->frontpath);
-       free(channel->shutdown_str);
-       free(channel->pause_done_str);
-       free(channel->pause_str);
-       free(channel->uuid_str);
-       free(channel->path);
-       free(channel);
-}
-
-int
-tapdisk_channel_open(tapdisk_channel_t **_channel,
-                    char *path, struct xs_handle *xsh,
-                    int blktap_fd, uint16_t cookie)
-{
-       int err;
-       char *msg;
-       tapdisk_channel_t *channel;
-
-       msg       = NULL;
-       *_channel = NULL;
-
-       channel = calloc(1, sizeof(tapdisk_channel_t));
-       if (!channel)
-               return -ENOMEM;
-
-       channel->xsh       = xsh;
-       channel->blktap_fd = blktap_fd;
-       channel->cookie    = cookie;
-       channel->state     = TAPDISK_CHANNEL_IDLE;
-
-       INIT_LIST_HEAD(&channel->list);
-
-       channel->path = strdup(path);
-       if (!channel->path) {
-               err = -ENOMEM;
-               goto fail;
-       }
-
-       err = tapdisk_channel_init(channel);
-       if (err) {
-               msg = "allocating device";
-               goto fail;
-       }
-
-       err = tapdisk_channel_check_uuid(channel);
-       if (err) {
-               msg = "checking uuid";
-               goto fail;
-       }
-
-       err = tapdisk_channel_gather_info(channel);
-       if (err) {
-               msg = "gathering parameters";
-               goto fail;
-       }
-
-       err = tapdisk_channel_verify_start_request(channel);
-       if (err) {
-               msg = "invalid start request";
-               goto fail;
-       }
-
-       err = tapdisk_channel_set_watches(channel);
-       if (err) {
-               msg = "registering xenstore watches";
-               goto fail;
-       }
-
-       err = tapdisk_channel_connect(channel);
-       if (err) {
-               msg = "connecting to tapdisk";
-               goto fail;
-       }
-
-       *_channel = channel;
-       return 0;
-
-fail:
-       tapdisk_channel_fatal(channel, "%s: %d", (msg ? : "failure"), err);
-       return err;
-}
-
-int
-tapdisk_channel_receive_message(tapdisk_channel_t *c, tapdisk_message_t *m)
-{
-       int err;
-
-       err = tapdisk_channel_validate_message(c, m);
-       if (err)
-               goto fail;
-
-       switch (m->type) {
-       case TAPDISK_MESSAGE_PID_RSP:
-               return tapdisk_channel_receive_pid_response(c, m);
-
-       case TAPDISK_MESSAGE_OPEN_RSP:
-               return tapdisk_channel_receive_open_response(c, m);
-
-       case TAPDISK_MESSAGE_PAUSE_RSP:
-               return tapdisk_channel_receive_pause_response(c, m);
-
-       case TAPDISK_MESSAGE_RESUME_RSP:
-               return tapdisk_channel_receive_resume_response(c, m);
-
-       case TAPDISK_MESSAGE_CLOSE_RSP:
-               return tapdisk_channel_receive_shutdown_response(c, m);
-
-       case TAPDISK_MESSAGE_RUNTIME_ERROR:
-               return tapdisk_channel_receive_runtime_error(c, m);
-       }
-
-fail:
-       tapdisk_channel_fatal(c, "received unexpected message %s in state %d",
-                             tapdisk_message_name(m->type), c->state);
-       return -EINVAL;
-}
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/tapdisk-daemon.c
--- a/tools/blktap2/daemon/tapdisk-daemon.c     Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,599 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of XenSource Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
- * 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.
-*/
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-
-#include <xs.h>
-#include "disktypes.h"
-#include "tapdisk-dispatch.h"
-
-#define TAPDISK_DAEMON_DOMID_WATCH   "domid-watch"
-#define TAPDISK_DAEMON_PIDFILE       "/var/run/blktapctrl.pid"
-
-typedef struct tapdisk_daemon {
-       char                         *node;
-       int                           blktap_fd;
-       uint16_t                      cookie;
-
-       struct xs_handle             *xsh;
-       struct list_head              channels;
-       struct xenbus_watch           watch;
-} tapdisk_daemon_t;
-
-static tapdisk_daemon_t tapdisk_daemon;
-
-#define tapdisk_daemon_for_each_channel(c, tmp) \
-       list_for_each_entry_safe(c, tmp, &tapdisk_daemon.channels, list)
-
-#define MAX(a, b) ((a) >= (b) ? (a) : (b))
-
-static void
-tapdisk_daemon_print_drivers(void)
-{
-       int i, size;
-
-       DPRINTF("blktap-daemon: v1.0.2\n");
-
-       size = sizeof(dtypes) / sizeof(disk_info_t *);
-       for (i = 0; i < size; i++)
-               DPRINTF("Found driver: [%s]\n", dtypes[i]->name);
-}
-
-static int
-tapdisk_daemon_write_pidfile(long pid)
-{
-       char buf[100];
-       int len, fd, flags, err;
-
-       fd = open(TAPDISK_DAEMON_PIDFILE, O_RDWR | O_CREAT, 0600);
-       if (fd == -1) {
-               EPRINTF("Opening pid file failed (%d)\n", errno);
-               return -errno;
-       }
-
-       /* We exit silently if daemon already running */
-       err = lockf(fd, F_TLOCK, 0);
-       if (err == -1)
-               exit(0);
-
-       /* Set FD_CLOEXEC, so that tapdisk doesn't get this file descriptor */
-       flags = fcntl(fd, F_GETFD);
-       if (flags == -1) {
-               EPRINTF("F_GETFD failed (%d)\n", errno);
-               return -errno;
-       }
-
-       flags |= FD_CLOEXEC;
-       err = fcntl(fd, F_SETFD, flags);
-       if (err == -1) {
-               EPRINTF("F_SETFD failed (%d)\n", errno);
-               return -errno;
-       }
-
-       len = sprintf(buf, "%ld\n", pid);
-       err = write(fd, buf, len);
-       if (err != len) {
-               EPRINTF("Writing pid file failed (%d)\n", errno);
-               return -errno;
-       }
-
-       return 0;
-}
-
-static int
-tapdisk_daemon_init(void)
-{
-       char *devname;
-       int i, err, blktap_major;
-
-       memset(&tapdisk_daemon, 0, sizeof(tapdisk_daemon_t));
-
-       err = asprintf(&devname, "%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME);
-       if (err == -1) {
-               devname = NULL;
-               err = -ENOMEM;
-               goto fail;
-       }
-
-       err = xc_find_device_number("blktap0");
-       if (err < 0)
-               goto fail;
-
-       blktap_major = major(err);
-       err = make_blktap_device(devname, blktap_major, 0, S_IFCHR | 0600);
-       if (err)
-               goto fail;
-
-       tapdisk_daemon.blktap_fd = open(devname, O_RDWR);
-       if (tapdisk_daemon.blktap_fd == -1) {
-               err = -errno;
-               EPRINTF("blktap0 open failed\n");
-               goto fail;
-       }
-
-       for (i = 0; i < 2; i++) {
-               tapdisk_daemon.xsh = xs_daemon_open();
-               if (!tapdisk_daemon.xsh) {
-                       EPRINTF("xs_daemon_open failed -- is xenstore 
running?\n");
-                       sleep(2);
-               } else
-                       break;
-       }
-
-       if (!tapdisk_daemon.xsh) {
-               err = -ENOSYS;
-               goto fail;
-       }
-
-       INIT_LIST_HEAD(&tapdisk_daemon.channels);
-
-       free(devname);
-       return 0;
-
-fail:
-       if (tapdisk_daemon.blktap_fd > 0)
-               close(tapdisk_daemon.blktap_fd);
-       free(devname);
-       memset(&tapdisk_daemon, 0, sizeof(tapdisk_daemon_t));
-       EPRINTF("%s: %d\n", __func__, err);
-
-       return err;
-}
-
-static int
-tapdisk_daemon_set_node(void)
-{
-       int err;
-       char *domid;
-
-       domid = get_dom_domid(tapdisk_daemon.xsh);
-       if (!domid)
-               return -EAGAIN;
-
-       err = asprintf(&tapdisk_daemon.node,
-                      "/local/domain/%s/backend/tap", domid);
-       if (err == -1) {
-               tapdisk_daemon.node = NULL;
-               err = -ENOMEM;
-               goto out;
-       }
-
-       err = 0;
-
-out:
-       free(domid);
-       return err;
-}
-
-static int
-tapdisk_daemon_get_domid(void)
-{
-       int err;
-       unsigned int num;
-       char **res, *node, *token, *domid;
-
-       res = xs_read_watch(tapdisk_daemon.xsh, &num);
-       if (!res)
-               return -EAGAIN;
-
-       err   = 0;
-       node  = res[XS_WATCH_PATH];
-       token = res[XS_WATCH_TOKEN];
-
-       if (strcmp(token, TAPDISK_DAEMON_DOMID_WATCH)) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       err = tapdisk_daemon_set_node();
-
-out:
-       free(res);
-       return err;
-}
-
-static int
-tapdisk_daemon_wait_for_domid(void)
-{
-       int err;
-       char *domid;
-       fd_set readfds;
-
-       err = tapdisk_daemon_set_node();
-       if (!err)
-               return 0;
-
-       if (!xs_watch(tapdisk_daemon.xsh, "/local/domain",
-                     TAPDISK_DAEMON_DOMID_WATCH)) {
-               EPRINTF("unable to set domain id watch\n");
-               return -EINVAL;
-       }
-
-       do {
-               FD_ZERO(&readfds);
-               FD_SET(xs_fileno(tapdisk_daemon.xsh), &readfds);
-
-               select(xs_fileno(tapdisk_daemon.xsh) + 1,
-                      &readfds, NULL, NULL, NULL);
-
-               if (FD_ISSET(xs_fileno(tapdisk_daemon.xsh), &readfds))
-                       err = tapdisk_daemon_get_domid();
-               else
-                       err = -EAGAIN;
-       } while (err == -EAGAIN);
-
-       xs_unwatch(tapdisk_daemon.xsh,
-                  "/local/domain", TAPDISK_DAEMON_DOMID_WATCH);
-       return err;
-}
-
-static inline int
-tapdisk_daemon_new_vbd_event(const char *node)
-{
-       return (!strcmp(node, "start-tapdisk"));
-}
-
-static int
-tapdisk_daemon_write_uuid(char *path, uint32_t uuid)
-{
-       int err;
-       char *cpath, uuid_str[12];
-
-       snprintf(uuid_str, sizeof(uuid_str), "%u", uuid);
-
-       err = asprintf(&cpath, "%s/tapdisk-uuid", path);
-       if (err == -1)
-               return -ENOMEM;
-
-       err = xs_write(tapdisk_daemon.xsh, XBT_NULL,
-                      cpath, uuid_str, strlen(uuid_str));
-       free(cpath);
-
-       return (err ? 0 : -errno);
-}
-
-static void
-tapdisk_daemon_probe(struct xs_handle *xsh,
-                    struct xenbus_watch *watch, const char *path)
-{
-       char *cpath;
-       int len, err;
-       uint32_t cookie;
-       const char *node;
-       tapdisk_channel_t *channel;
-
-       len = strsep_len(path, '/', 7);
-       if (len < 0)
-               return;
-
-       node = path + len + 1;
-
-       if (!tapdisk_daemon_new_vbd_event(node))
-               return;
-
-       if (!xs_exists(xsh, path))
-               return;
-
-       cpath = strdup(path);
-       if (!cpath) {
-               EPRINTF("failed to allocate control path for %s\n", path);
-               return;
-       }
-       cpath[len] = '\0';
-
-       cookie = tapdisk_daemon.cookie++;
-       err    = tapdisk_daemon_write_uuid(cpath, cookie);
-       if (err)
-               goto out;
-
-       DPRINTF("%s: got watch on %s, uuid = %u\n", __func__, path, cookie);
-
-       err = tapdisk_channel_open(&channel, cpath,
-                                  tapdisk_daemon.xsh,
-                                  tapdisk_daemon.blktap_fd,
-                                  cookie);
-       if (!err)
-               list_add(&channel->list, &tapdisk_daemon.channels);
-       else
-               EPRINTF("failed to open tapdisk channel for %s: %d\n",
-                       path, err);
-
-out:
-       free(cpath);
-}
-
-static int
-tapdisk_daemon_start(void)
-{
-       int err;
-
-       err = tapdisk_daemon_wait_for_domid();
-       if (err)
-               return err;
-
-       tapdisk_daemon.watch.node     = tapdisk_daemon.node;
-       tapdisk_daemon.watch.callback = tapdisk_daemon_probe;
-
-       err = register_xenbus_watch(tapdisk_daemon.xsh, &tapdisk_daemon.watch);
-       if (err)
-               goto fail;
-
-       ioctl(tapdisk_daemon.blktap_fd,
-             BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE);
-       ioctl(tapdisk_daemon.blktap_fd, BLKTAP_IOCTL_SENDPID, getpid());
-
-       return 0;
-
-fail:
-       free(tapdisk_daemon.node);
-       tapdisk_daemon.node       = NULL;
-       tapdisk_daemon.watch.node = NULL;
-       EPRINTF("%s: %d\n", __func__, err);
-       return err;
-}
-
-static int
-tapdisk_daemon_stop(void)
-{
-       unregister_xenbus_watch(tapdisk_daemon.xsh, &tapdisk_daemon.watch);
-
-       ioctl(tapdisk_daemon.blktap_fd,
-             BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH);
-       close(tapdisk_daemon.blktap_fd);
-
-       return 0;
-}
-
-static void
-tapdisk_daemon_free(void)
-{
-       free(tapdisk_daemon.node);
-       xs_daemon_close(tapdisk_daemon.xsh);
-       memset(&tapdisk_daemon, 0, sizeof(tapdisk_daemon_t));
-}
-
-static int
-tapdisk_daemon_read_message(int fd, tapdisk_message_t *message, int timeout)
-{
-       fd_set readfds;
-       struct timeval tv;
-       int ret, len, offset;
-
-       tv.tv_sec  = timeout;
-       tv.tv_usec = 0;
-       offset     = 0;
-       len        = sizeof(tapdisk_message_t);
-
-       memset(message, 0, sizeof(tapdisk_message_t));
-
-       while (offset < len) {
-               FD_ZERO(&readfds);
-               FD_SET(fd, &readfds);
-
-               /* we don't bother reinitializing tv. at worst, it will wait a
-                * bit more time than expected. */
-
-               ret = select(fd + 1, &readfds, NULL, NULL, &tv);
-               if (ret == -1)
-                       break;
-               else if (FD_ISSET(fd, &readfds)) {
-                       ret = read(fd, message + offset, len - offset);
-                       if (ret <= 0)
-                               break;
-                       offset += ret;
-               } else
-                       break;
-       }
-
-       return (offset == len ? 0 : -EIO);
-}
-
-static int
-tapdisk_daemon_receive_message(int fd)
-{
-       int err;
-       tapdisk_message_t m;
-       tapdisk_channel_t *c, *tmp;
-
-       err = tapdisk_daemon_read_message(fd, &m, 2);
-       if (err) {
-               EPRINTF("failed reading message on %d: %d\n", fd, err);
-               return err;
-       }
-
-       tapdisk_daemon_for_each_channel(c, tmp)
-               if (c->cookie == m.cookie && c->read_fd == fd) {
-                       DPRINTF("got '%s' message from %d:%d\n",
-                               tapdisk_message_name(m.type),
-                               c->channel_id, c->cookie);
-
-                       return tapdisk_channel_receive_message(c, &m);
-               }
-
-       EPRINTF("unrecognized message on %d: '%s' (uuid = %u)\n",
-               fd, tapdisk_message_name(m.type), m.cookie);
-
-       return -EINVAL;
-}
-
-static int
-tapdisk_daemon_set_fds(fd_set *readfds)
-{
-       int max, fd;
-       tapdisk_channel_t *channel, *tmp;
-
-       max = xs_fileno(tapdisk_daemon.xsh);
-
-       FD_ZERO(readfds);
-       FD_SET(max, readfds);
-
-       tapdisk_daemon_for_each_channel(channel, tmp) {
-               fd  = channel->read_fd;
-               max = MAX(fd, max);
-               FD_SET(fd, readfds);
-       }
-
-       return max;
-}
-
-static int
-tapdisk_daemon_check_fds(fd_set *readfds)
-{
-       int err;
-       tapdisk_channel_t *channel, *tmp;
-
-       if (FD_ISSET(xs_fileno(tapdisk_daemon.xsh), readfds))
-               xs_fire_next_watch(tapdisk_daemon.xsh);
-
-       tapdisk_daemon_for_each_channel(channel, tmp)
-               if (FD_ISSET(channel->read_fd, readfds))
-                       return tapdisk_daemon_receive_message(channel->read_fd);
-
-       return 0;
-}
-
-static int
-tapdisk_daemon_run(void)
-{
-       int err, max;
-       fd_set readfds;
-
-       while (1) {
-               max = tapdisk_daemon_set_fds(&readfds);
-
-               err = select(max + 1, &readfds, NULL, NULL, NULL);
-               if (err < 0)
-                       continue;
-
-               err = tapdisk_daemon_check_fds(&readfds);
-       }
-
-       return err;
-}
-
-void
-tapdisk_daemon_find_channel(tapdisk_channel_t *channel)
-{
-       tapdisk_channel_t *c, *tmp;
-
-       channel->read_fd     = 0;
-       channel->write_fd    = 0;
-       channel->tapdisk_pid = 0;
-
-       /* do we want multiple vbds per tapdisk? */
-       if (!xs_exists(tapdisk_daemon.xsh, channel->share_tapdisk_str)) {
-               channel->shared = 0;
-               return;
-       }
-
-       channel->shared = 1;
-
-       /* check if we already have a process started */
-       tapdisk_daemon_for_each_channel(c, tmp)
-               if (c->drivertype == channel->drivertype) {
-                       channel->write_fd    = c->write_fd;
-                       channel->read_fd     = c->read_fd;
-                       channel->channel_id  = c->channel_id;
-                       channel->tapdisk_pid = c->tapdisk_pid;
-                       return;
-               }
-}
-
-void
-tapdisk_daemon_close_channel(tapdisk_channel_t *channel)
-{
-       tapdisk_channel_t *c, *tmp;
-
-       list_del(&channel->list);
-
-       tapdisk_daemon_for_each_channel(c, tmp)
-               if (c->channel_id == channel->channel_id)
-                       return;
-
-       close(channel->read_fd);
-       close(channel->write_fd);
-}
-
-int
-main(int argc, char *argv[])
-{
-       int err;
-       char buf[128];
-
-       if (daemon(0, 0)) {
-         EPRINTF("daemon() failed (%d)\n", errno);
-         return -errno;
-       }
-
-#define CORE_DUMP
-#if defined(CORE_DUMP)
-       {
-               /* set up core-dumps*/
-               struct rlimit rlim;
-               rlim.rlim_cur = RLIM_INFINITY;
-               rlim.rlim_max = RLIM_INFINITY;
-               if (setrlimit(RLIMIT_CORE, &rlim) < 0)
-                       EPRINTF("setrlimit failed: %d\n", errno);
-       }
-#endif
-
-       snprintf(buf, sizeof(buf), "BLKTAP-DAEMON[%d]", getpid());
-       openlog(buf, LOG_CONS | LOG_ODELAY, LOG_DAEMON);
-
-       err = tapdisk_daemon_write_pidfile(getpid());
-       if (err)
-               goto out;
-
-       tapdisk_daemon_print_drivers();
-
-       err = tapdisk_daemon_init();
-       if (err)
-               goto out;
-
-       err = tapdisk_daemon_start();
-       if (err)
-               goto out;
-
-       tapdisk_daemon_run();
-
-       tapdisk_daemon_stop();
-       tapdisk_daemon_free();
-
-       err = 0;
-
-out:
-       if (err)
-               EPRINTF("failed to start %s: %d\n", argv[0], err);
-       closelog();
-       return err;
-}
diff -r 94bf7d4854eb -r 4f779d41b0ba 
tools/blktap2/daemon/tapdisk-dispatch-common.c
--- a/tools/blktap2/daemon/tapdisk-dispatch-common.c    Thu Jun 18 10:27:21 
2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * (c) 2005 Andrew Warfield and Julian Chesterfield
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (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.
- */
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "tapdisk-dispatch.h"
-
-int
-strsep_len(const char *str, char c, unsigned int len)
-{
-       unsigned int i;
-       
-       for (i = 0; str[i]; i++)
-               if (str[i] == c) {
-                       if (len == 0)
-                               return i;
-                       len--;
-               }
-
-       return (len == 0) ? i : -ERANGE;
-}
-
-int
-make_blktap_device(char *devname, int major, int minor, int perm)
-{
-       int err;
-
-       err = unlink(devname);
-       if (err && errno != ENOENT) {
-               EPRINTF("unlink %s failed: %d\n", devname, errno);
-               return -errno;
-       }
-
-       /* Need to create device */
-       err = mkdir(BLKTAP_DEV_DIR, 0755);
-       if (err && errno != EEXIST) {
-               EPRINTF("Failed to create %s directory\n", BLKTAP_DEV_DIR);
-               return -errno;
-       }
-
-       err = mknod(devname, perm, makedev(major, minor));
-       if (err) {
-               int ret = -errno;
-               struct stat st;
-
-               EPRINTF("mknod %s failed: %d\n", devname, -errno);
-
-               err = lstat(devname, &st);
-               if (err) {
-                       DPRINTF("lstat %s failed: %d\n", devname, -errno);
-                       err = access(devname, F_OK);
-                       if (err)
-                               DPRINTF("access %s failed: %d\n", devname, 
-errno);
-                       else
-                               DPRINTF("access %s succeeded\n", devname);
-               } else
-                       DPRINTF("lstat %s: %u:%u\n", devname,
-                               (unsigned int)st.st_rdev >> 8,
-                               (unsigned int)st.st_rdev & 0xff);
-
-               return ret;
-       }
-
-       DPRINTF("Created %s device\n", devname);
-       return 0;
-}
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/daemon/tapdisk-dispatch.h
--- a/tools/blktap2/daemon/tapdisk-dispatch.h   Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of XenSource Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
- * 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.
-*/
-#ifndef _TAPDISK_DISPATCH_H_
-#define _TAPDISK_DISPATCH_H_
-
-#include "xs_api.h"
-#include "blktaplib.h"
-#include "tapdisk-message.h"
-
-struct tapdisk_channel {
-       int                       state;
-
-       int                       read_fd;
-       int                       write_fd;
-       int                       blktap_fd;
-       int                       channel_id;
-
-       char                      mode;
-       char                      shared;
-       char                      open;
-       unsigned int              domid;
-       unsigned int              busid;
-       unsigned int              major;
-       unsigned int              minor;
-       unsigned int              storage;
-       unsigned int              drivertype;
-       uint16_t                  cookie;
-       pid_t                     tapdisk_pid;
-
-       /*
-        * special accounting needed to handle pause
-        * requests received before tapdisk process is ready
-        */
-       char                      connected;
-       char                      pause_needed;
-
-       char                     *path;
-       char                     *frontpath;
-       char                     *params;
-       char                     *vdi_path;
-       char                     *uuid_str;
-       char                     *pause_str;
-       char                     *pause_done_str;
-       char                     *shutdown_str;
-       char                     *share_tapdisk_str;
-
-       image_t                   image;
-
-       struct list_head          list;
-       struct xenbus_watch       pause_watch;
-       struct xenbus_watch       shutdown_watch;
-
-       struct xs_handle         *xsh;
-};
-
-typedef struct tapdisk_channel tapdisk_channel_t;
-
-int strsep_len(const char *str, char c, unsigned int len);
-int make_blktap_device(char *devname, int major, int minor, int perm);
-
-int tapdisk_channel_open(tapdisk_channel_t **,
-                        char *node, struct xs_handle *,
-                        int blktap_fd, uint16_t cookie);
-void tapdisk_channel_close(tapdisk_channel_t *);
-
-void tapdisk_daemon_find_channel(tapdisk_channel_t *);
-void tapdisk_daemon_close_channel(tapdisk_channel_t *);
-
-int tapdisk_channel_receive_message(tapdisk_channel_t *, tapdisk_message_t *);
-
-#endif
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/drivers/Makefile
--- a/tools/blktap2/drivers/Makefile    Thu Jun 18 10:27:21 2009 +0100
+++ b/tools/blktap2/drivers/Makefile    Thu Jun 18 10:29:58 2009 +0100
@@ -4,7 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 LIBVHDDIR  = $(BLKTAP_ROOT)/vhd/lib
 
-IBIN       = tapdisk tapdisk2 td-util tapdisk-client tapdisk-stream 
tapdisk-diff
+IBIN       = tapdisk2 td-util tapdisk-client tapdisk-stream tapdisk-diff
 QCOW_UTIL  = img2qcow qcow-create qcow2raw
 LOCK_UTIL  = lock-util
 INST_DIR   = $(SBINDIR)
@@ -34,11 +34,11 @@ endif
 
 LDFLAGS_img := $(CRYPT_LIB) -lpthread -lz
 
-tapdisk tapdisk2 td-util tapdisk-stream tapdisk-diff $(QCOW_UTIL): LIBS += 
-L$(LIBVHDDIR) -lvhd -luuid
+tapdisk2 td-util tapdisk-stream tapdisk-diff $(QCOW_UTIL): LIBS += 
-L$(LIBVHDDIR) -lvhd -luuid
 
 LIBAIO_DIR = $(XEN_ROOT)/tools/libaio/src
-tapdisk tapdisk2 tapdisk-stream tapdisk-diff $(QCOW_UTIL): AIOLIBS := 
$(LIBAIO_DIR)/libaio.a
-tapdisk tapdisk-client tapdisk-stream tapdisk-diff $(QCOW_UTIL): CFLAGS  += 
-I$(LIBAIO_DIR) -I$(XEN_LIBXC)
+tapdisk2 tapdisk-stream tapdisk-diff $(QCOW_UTIL): AIOLIBS := 
$(LIBAIO_DIR)/libaio.a
+tapdisk-client tapdisk-stream tapdisk-diff $(QCOW_UTIL): CFLAGS  += 
-I$(LIBAIO_DIR) -I$(XEN_LIBXC)
 
 ifeq ($(VHD_STATIC),y)
 td-util: CFLAGS += -static
@@ -71,8 +71,6 @@ BLK-OBJS-y  += aes.o
 
 all: $(IBIN) lock-util qcow-util
 
-tapdisk: $(TAP-OBJS-y) $(BLK-OBJS-y) $(MISC-OBJS-y) tapdisk.c
-       $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) $(AIOLIBS)  $(LDFLAGS_img)
 
 tapdisk2: $(TAP-OBJS-y) $(BLK-OBJS-y) $(MISC-OBJS-y) tapdisk2.c
        $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) $(AIOLIBS) $(LDFLAGS_img)
diff -r 94bf7d4854eb -r 4f779d41b0ba tools/blktap2/drivers/tapdisk.c
--- a/tools/blktap2/drivers/tapdisk.c   Thu Jun 18 10:27:21 2009 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of XenSource Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
- * 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.
- */
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "tapdisk-utils.h"
-#include "tapdisk-server.h"
-
-static void
-usage(void)
-{
-       fprintf(stderr, "blktap-utils: v2.0.0\n");
-       fprintf(stderr, "usage: tapdisk <READ fifo> <WRITE fifo>\n");
-       exit(EINVAL);
-}
-
-int
-main(int argc, char *argv[])
-{
-       int err;
-
-       if (argc != 3)
-               usage();
-
-       daemon(0, 0);
-       tapdisk_start_logging("TAPDISK");
-
-       err = tapdisk_server_initialize(argv[1], argv[2]);
-       if (err) {
-               EPRINTF("failed to initialize tapdisk server: %d\n", err);
-               goto out;
-       }
-
-       err = tapdisk_server_run();
-
-out:
-       tapdisk_stop_logging();
-       return err;
-}
diff -r 94bf7d4854eb -r 4f779d41b0ba 
tools/python/xen/xend/server/BlktapController.py
--- a/tools/python/xen/xend/server/BlktapController.py  Thu Jun 18 10:27:21 
2009 +0100
+++ b/tools/python/xen/xend/server/BlktapController.py  Thu Jun 18 10:29:58 
2009 +0100
@@ -126,9 +126,19 @@ class BlktapController(BlkifController):
         except:
             (typ, params, file) = string.split(uname, ':', 2)
             subtyp = 'tapdisk'
+
+        #check for blktap2 installation.
+        blktap2_installed=0;
+        (rc,stdout, stderr) = doexec("cat /proc/devices");
+        out = stdout.read();
+        stdout.close();
+        stderr.close();
+        if( out.find("blktap2") >= 0 ):
+            blktap2_installed=1;
+           
         if typ in ('tap'):
             if subtyp in ('tapdisk'):                                          
-                if params in ('ioemu', 'qcow2', 'vmdk', 'sync'):
+                if params in ('ioemu', 'qcow2', 'vmdk', 'sync') or not 
blktap2_installed:
                     log.warn('WARNING: using deprecated blktap module');
                     return BlkifController.createDevice(self, config);
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] blktap: re-enable blktap1 if blktap2 is disabled, Xen patchbot-unstable <=