]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
CA-46079: Remove the blktap-1 control daemon.
authorDaniel Stodden <daniel.stodden@citrix.com>
Thu, 30 Sep 2010 21:01:33 +0000 (14:01 -0700)
committerDaniel Stodden <daniel.stodden@citrix.com>
Thu, 30 Sep 2010 21:01:33 +0000 (14:01 -0700)
Got in the way of shifting some definitions around.

Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
Makefile
daemon/Makefile [deleted file]
daemon/lib/Makefile [deleted file]
daemon/lib/xs_api.c [deleted file]
daemon/lib/xs_api.h [deleted file]
daemon/tapdisk-channel.c [deleted file]
daemon/tapdisk-daemon.c [deleted file]
daemon/tapdisk-dispatch-common.c [deleted file]
daemon/tapdisk-dispatch.h [deleted file]
mk/blktap.spec.in

index 32dc41a0371da89a3c4f8c0e212bee0ea0feebad..2923e40c7bf9513868b0bcb58cb856b08334d736 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,6 @@ SUBDIRS-y += lvm
 SUBDIRS-y += part
 SUBDIRS-y += vhd
 SUBDIRS-y += drivers
-SUBDIRS-y += daemon
 SUBDIRS-y += control
 
 .PHONY: all
diff --git a/daemon/Makefile b/daemon/Makefile
deleted file mode 100644 (file)
index 3bbf223..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-BLKTAP_ROOT := ..
-include $(BLKTAP_ROOT)/Rules.mk
-
-IBIN          = blktapctrl
-INST_DIR      = /usr/sbin
-
-LIBS         := -lxenstore
-LIBS         += -Llib
-LIBS         += -lblktap
-LIBS         += -lxenctrl
-
-ifneq ($(USE_SYSTEM_LIBRARIES),y)
-INCLUDES     += -I $(XEN_LIBXC) -I $(XEN_XENSTORE) -I $(XEN_ROOT)/tools/include
-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 $(INCLUDES)
-CFLAGS       += -D_GNU_SOURCE
-CFLAGS       += -g
-
-# Get gcc to generate the dependencies for us.
-CFLAGS       += -Wp,-MD,.$(@F).d
-DEPS          = .*.d
-
-all: libblktap $(IBIN)
-
-blktapctrl: tapdisk-daemon.c $(OBJS)
-       $(CC) $(CFLAGS) -o blktapctrl tapdisk-daemon.c $(LIBS) $(OBJS)
-
-libblktap:
-       @set -e
-       $(MAKE) -C lib all
-
-install: all
-       $(MAKE) -C lib install
-       $(INSTALL_DIR) -p $(DESTDIR)$(INST_DIR)
-       $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(INST_DIR)
-
-clean:
-       $(MAKE) -C lib clean
-       rm -rf *.o *~ $(IBIN) $(DEPS) xen TAGS
-
-.PHONY: all clean install libblktap
-
--include $(DEPS)
-
diff --git a/daemon/lib/Makefile b/daemon/lib/Makefile
deleted file mode 100644 (file)
index c3ec74e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-BLKTAP_ROOT := ../../
-include $(BLKTAP_ROOT)/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) -I $(XEN_ROOT)/tools/include
-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 $(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) \
-             -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 --git a/daemon/lib/xs_api.c b/daemon/lib/xs_api.c
deleted file mode 100644 (file)
index 54d3907..0000000
+++ /dev/null
@@ -1,321 +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>
-
-#define TAPDISK
-#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];
-
-       w = find_watch(token);
-       if (w) 
-               w->callback(h, w, node);
-
-       free(res);
-
-       return 1;
-}
diff --git a/daemon/lib/xs_api.h b/daemon/lib/xs_api.h
deleted file mode 100644 (file)
index e6f055a..0000000
+++ /dev/null
@@ -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 --git a/daemon/tapdisk-channel.c b/daemon/tapdisk-channel.c
deleted file mode 100644 (file)
index 14426c0..0000000
+++ /dev/null
@@ -1,1809 +0,0 @@
-/*
- * Copyright (c) 2008 Xensource Inc.
- *
- * 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 <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 "tapdisk-dispatch.h"
-
-static inline const char*
-tapdisk_channel_state_name(channel_state_t state)
-{
-       switch (state) {
-       case TAPDISK_CHANNEL_DEAD:
-               return "dead";
-       case TAPDISK_CHANNEL_LAUNCHED:
-               return "launched";
-       case TAPDISK_CHANNEL_WAIT_PID:
-               return "wait-pid";
-       case TAPDISK_CHANNEL_PID:
-               return "pid";
-       case TAPDISK_CHANNEL_WAIT_OPEN:
-               return "wait-open";
-       case TAPDISK_CHANNEL_RUNNING:
-               return "running";
-       case TAPDISK_CHANNEL_WAIT_PAUSE:
-               return "wait-pause";
-       case TAPDISK_CHANNEL_PAUSED:
-               return "paused";
-       case TAPDISK_CHANNEL_WAIT_RESUME:
-               return "wait-resume";
-       case TAPDISK_CHANNEL_WAIT_CLOSE:
-               return "wait-close";
-       case TAPDISK_CHANNEL_CLOSED:
-               return "closed";
-       }
-
-       return "unknown";
-}
-
-static inline const char*
-tapdisk_channel_vbd_state_name(vbd_state_t state)
-{
-       switch (state) {
-       case TAPDISK_VBD_UNPAUSED:
-               return "unpaused";
-       case TAPDISK_VBD_PAUSING:
-               return "pausing";
-       case TAPDISK_VBD_PAUSED:
-               return "paused";
-       case TAPDISK_VBD_BROKEN:
-               return "broken";
-       case TAPDISK_VBD_DEAD:
-               return "dead";
-       case TAPDISK_VBD_RECYCLED:
-               return "recycled";
-       }
-
-       return "unknown";
-}
-
-static inline int
-tapdisk_channel_vbd_fenced(tapdisk_channel_t *channel)
-{
-       return
-               channel->vbd_state == TAPDISK_VBD_BROKEN ||
-               channel->vbd_state == TAPDISK_VBD_DEAD ||
-               channel->vbd_state == TAPDISK_VBD_RECYCLED;
-}
-
-static inline int
-tapdisk_channel_enter_vbd_state(tapdisk_channel_t *channel, vbd_state_t state)
-{
-       int err = 0;
-
-       if (tapdisk_channel_vbd_fenced(channel))
-               err = -EINVAL;
-
-       DPRINTF("%s: vbd state %s -> %s: %d",
-               channel->path,
-               tapdisk_channel_vbd_state_name(channel->vbd_state),
-               tapdisk_channel_vbd_state_name(state),
-               err);
-
-       if (!err)
-               channel->vbd_state = state;
-
-       return err;
-}
-
-static inline const char*
-tapdisk_channel_shutdown_state_name(shutdown_state_t state)
-{
-       switch (state) {
-       case TAPDISK_VBD_UP:
-               return "up";
-       case TAPDISK_VBD_DOWN:
-               return "down";
-       }
-
-       return "unknown";
-}
-
-static int tapdisk_channel_write_atomic(tapdisk_channel_t *,
-                                       const char *, const void *,
-                                       unsigned int);
-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_refresh_params(tapdisk_channel_t *);
-static int tapdisk_channel_connect(tapdisk_channel_t *);
-static void tapdisk_channel_close_tapdisk(tapdisk_channel_t *);
-static void tapdisk_channel_destroy(tapdisk_channel_t *);
-
-static int
-__tapdisk_channel_check_uuid(tapdisk_channel_t *channel, xs_transaction_t xbt)
-{
-       uint32_t uuid;
-       char *uuid_str;
-
-       uuid_str = xs_read(channel->xsh, xbt, 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;
-}
-
-int
-tapdisk_channel_check_uuid(tapdisk_channel_t *channel)
-{
-       return __tapdisk_channel_check_uuid(channel, XBT_NULL);
-}
-
-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;
-
-       if (tapdisk_channel_vbd_fenced(channel))
-               return -ENOENT;
-
-       err = tapdisk_channel_check_uuid(channel);
-       if (err)
-               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;
-       }
-
-       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, state %s\n",
-               channel->path, tapdisk_message_name(message->type),
-               channel->channel_id, channel->cookie,
-               tapdisk_channel_state_name(channel->state));
-
-       if (!TAPDISK_CHANNEL_IPC_IDLE(channel))
-               EPRINTF("%s: writing message to non-idle channel, state %s (%d)\n",
-                       channel->path,
-                       tapdisk_channel_state_name(channel->state),
-                       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;
-
-       case TAPDISK_MESSAGE_FORCE_SHUTDOWN:
-               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;
-       }
-
-       tapdisk_channel_write_atomic(channel, 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;
-
-       tapdisk_channel_enter_vbd_state(channel, TAPDISK_VBD_BROKEN);
-
-       va_start(ap, fmt);
-       __tapdisk_channel_error(channel, fmt, ap);
-       va_end(ap);
-}
-
-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,
-                      "tapdisk-pid", "%d", channel->tapdisk_pid)) {
-               EPRINTF("ERROR: Failed writing tapdisk-pid");
-               return -errno;
-       }
-
-       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;
-
-       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;
-
-       if (!xs_rm(channel->xsh, XBT_NULL, path))
-               goto clean_out;
-
-       free(path);
-       if (asprintf(&path, "%s/tapdisk-pid", 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));
-
-       message.type              = TAPDISK_MESSAGE_OPEN;
-       message.cookie            = channel->cookie;
-       message.u.params.storage  = channel->storage;
-       message.u.params.devnum   = channel->minor;
-       message.u.params.domid    = channel->domid;
-       snprintf(message.u.params.path, sizeof(message.u.params.path),
-                "%s:%s", channel->vdi_type, channel->vdi_path);
-
-       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/vhd-index"))
-               message.u.params.flags |= TAPDISK_MESSAGE_FLAG_VHD_INDEX;
-       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->state = TAPDISK_CHANNEL_RUNNING;
-
-       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) {
-               tapdisk_channel_fatal(channel,
-                                     "failure completing connection: %d", err);
-               return err;
-       }
-
-       return 0;
-}
-
-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.cookie     = channel->cookie;
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_send_force_shutdown_request(tapdisk_channel_t *channel)
-{
-       tapdisk_message_t message;
-
-       memset(&message, 0, sizeof(tapdisk_message_t));
-
-       message.type       = TAPDISK_MESSAGE_FORCE_SHUTDOWN;
-       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->state = TAPDISK_CHANNEL_CLOSED;
-       tapdisk_channel_close_tapdisk(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.cookie     = channel->cookie;
-
-       err = tapdisk_channel_send_message(channel, &message, 2);
-
-       return err;
-}
-
-static int
-tapdisk_channel_receive_pid_response(tapdisk_channel_t *channel,
-                                    tapdisk_message_t *message)
-{
-       int err;
-
-       channel->state       = TAPDISK_CHANNEL_PID;
-       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;
-       }
-
-       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.cookie     = channel->cookie;
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_write_atomic(tapdisk_channel_t *channel,
-                            const char *_path, const void *_data,
-                            unsigned int _len)
-{
-       xs_transaction_t xbt;
-       int err, abort;
-       unsigned int len;
-       void *data;
-       bool ok;
-
-again:
-       err = 0;
-
-       xbt = xs_transaction_start(channel->xsh);
-       if (!xbt) {
-               err = -errno;
-               EPRINTF("error starting transaction: %d\n", err);
-               return err;
-       }
-
-       abort = 1;
-
-       err = __tapdisk_channel_check_uuid(channel, xbt);
-       if (err) {
-               if (err == -ENOENT)
-                       goto abort;
-               EPRINTF("error reading %s: %d\n", channel->path, err);
-               goto abort;
-       }
-
-       ok = xs_write(channel->xsh, xbt, _path, _data, _len);
-       if (!ok) {
-               err = -errno;
-               EPRINTF("error writing %s: %d\n", _path, err);
-               goto abort;
-       }
-
-       abort = 0;
-
-abort:
-       ok = xs_transaction_end(channel->xsh, xbt, abort);
-       if (!ok) {
-               err = -errno;
-               if (err == -EAGAIN && !abort)
-                       goto again;
-               EPRINTF("error ending transaction: %d\n", err);
-       }
-
-       return err;
-}
-
-static int
-tapdisk_channel_trigger_reprobe(tapdisk_channel_t *channel)
-{
-       int err;
-
-       /*
-        * NB. Kick the probe watch, paranoia-style. Performing an
-        * atomic test/set on the directory path. Abort if it's
-        * already gone again. Accidentally recreating the node would
-        * lead to a spurious start failure.
-        */
-
-       err = tapdisk_channel_write_atomic(channel, channel->path, "", 0);
-       if (err && err != -ENOENT)
-               EPRINTF("error writing %s: %d\n", channel->pause_done_str, err);
-
-       DPRINTF("write %s: %d\n", channel->path, err);
-       return err;
-}
-
-static int
-tapdisk_channel_signal_paused(tapdisk_channel_t *channel)
-{
-       bool ok;
-       int err;
-
-       err = tapdisk_channel_write_atomic(channel,
-                                          channel->pause_done_str, "", 0);
-       if (err && errno != -ENOENT)
-               EPRINTF("error writing %s: %d\n", channel->pause_done_str, err);
-
-       DPRINTF("write %s: %d\n", channel->pause_done_str, err);
-       return err;
-}
-
-static int
-tapdisk_channel_signal_unpaused(tapdisk_channel_t *channel)
-{
-       bool ok;
-       int err;
-
-       ok = xs_rm(channel->xsh, XBT_NULL, channel->pause_done_str);
-       err = ok ? 0 : -errno;
-       if (err && err != -ENOENT)
-               EPRINTF("error removing %s: %d\n", channel->pause_done_str, err);
-
-       DPRINTF("clear %s: %d\n", channel->pause_done_str, err);
-       return err;
-}
-
-static int
-tapdisk_channel_receive_pause_response(tapdisk_channel_t *channel,
-                                      tapdisk_message_t *message)
-{
-       channel->state = TAPDISK_CHANNEL_PAUSED;
-       return 0;
-}
-
-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.cookie            = channel->cookie;
-       snprintf(message.u.params.path, sizeof(message.u.params.path),
-                "%s:%s", channel->vdi_type, channel->vdi_path);
-
-       return tapdisk_channel_send_message(channel, &message, 2);
-}
-
-static int
-tapdisk_channel_receive_resume_response(tapdisk_channel_t *channel,
-                                       tapdisk_message_t *message)
-{
-       channel->state = TAPDISK_CHANNEL_RUNNING;
-       return 0;
-}
-
-static int
-tapdisk_channel_check_start_request(tapdisk_channel_t *channel)
-{
-       char *s;
-       int err;
-
-       err = 0;
-
-       s = xs_read(channel->xsh, XBT_NULL, channel->start_str, NULL);
-       if (!s) {
-               if (errno == ENOENT)
-                       goto down;
-
-               err = -errno;
-               EPRINTF("error reading %s: %d\n", channel->path, err);
-               goto out;
-       }
-
-       if (!strcmp(s, "start")) {
-               channel->shutdown_state = TAPDISK_VBD_UP;
-               channel->shutdown_force = 0;
-               goto out;
-
-       } else if (!strcmp(s, "shutdown-force")) {
-               channel->shutdown_state = TAPDISK_VBD_DOWN;
-               channel->shutdown_force = 1;
-               goto out;
-
-       } else if (strcmp(s, "shutdown-normal")) {
-               EPRINTF("%s: invalid request '%s'", channel->path, s);
-               err = -EINVAL;
-               goto out;
-       }
-
-down:
-       channel->shutdown_state = TAPDISK_VBD_DOWN;
-       channel->shutdown_force = 0;
-out:
-       DPRINTF("%s: got tapdisk-request '%s', shutdown state %s (%s): %d\n",
-               channel->path, s,
-               tapdisk_channel_shutdown_state_name(channel->shutdown_state),
-               channel->shutdown_force ? "force" : "normal", err);
-       free(s);
-       return err;
-}
-
-static void
-tapdisk_channel_shutdown_event(struct xs_handle *xsh,
-                              struct xenbus_watch *watch, const char *path)
-{
-       tapdisk_channel_t *channel;
-       int err;
-
-       channel = watch->data;
-
-       DPRINTF("%s: got start/shutdown watch on %s\n",
-               channel->path, path);
-
-       err = tapdisk_channel_validate_watch(channel, path);
-       if (err) {
-               if (err == -EINVAL)
-                       tapdisk_channel_fatal(channel,
-                                             "bad shutdown watch");
-               goto out;
-       }
-
-       err = tapdisk_channel_check_start_request(channel);
-       if (err)
-               tapdisk_channel_error(channel,
-                                     "shutdown event failed: %d", err);
-       else
-               tapdisk_channel_drive_vbd_state(channel);
-
-out:
-       DPRINTF("%s: handled start/shutdown watch on %s\n",
-               channel->path, path);
-}
-
-static int
-tapdisk_channel_drive_paused(tapdisk_channel_t *channel)
-{
-       int err;
-
-       switch (channel->state) {
-       case TAPDISK_CHANNEL_WAIT_PID:
-       case TAPDISK_CHANNEL_WAIT_OPEN:
-       case TAPDISK_CHANNEL_WAIT_PAUSE:
-       case TAPDISK_CHANNEL_WAIT_RESUME:
-       case TAPDISK_CHANNEL_WAIT_CLOSE:
-               return -EAGAIN;
-
-       case TAPDISK_CHANNEL_PID:
-       case TAPDISK_CHANNEL_PAUSED:
-       case TAPDISK_CHANNEL_CLOSED:
-       case TAPDISK_CHANNEL_DEAD:
-               return 0;
-
-       case TAPDISK_CHANNEL_RUNNING:
-               err = tapdisk_channel_send_pause_request(channel);
-               if (err)
-                       goto fail_msg;
-               return -EAGAIN;
-
-       default:
-               EPRINTF("%s: invalid channel state %d\n",
-                       __func__, channel->state);
-               return -EINVAL;
-       }
-
-fail_msg:
-       tapdisk_channel_fatal(channel, "sending message: %d", err);
-       return -EIO;
-}
-
-static int
-tapdisk_channel_drive_shutdown(tapdisk_channel_t *channel)
-{
-       int err;
-
-       switch (channel->state) {
-
-       case TAPDISK_CHANNEL_DEAD:
-               return 0;
-
-       case TAPDISK_CHANNEL_CLOSED:
-               if (channel->shared)
-                       return 0;
-               /* let's duely wait for a clean exit */
-               return -EAGAIN;
-
-       case TAPDISK_CHANNEL_LAUNCHED:
-       case TAPDISK_CHANNEL_WAIT_PID:
-       case TAPDISK_CHANNEL_WAIT_OPEN:
-       case TAPDISK_CHANNEL_WAIT_PAUSE:
-       case TAPDISK_CHANNEL_WAIT_RESUME:
-       case TAPDISK_CHANNEL_WAIT_CLOSE:
-               return -EAGAIN;
-
-       case TAPDISK_CHANNEL_PID:
-       case TAPDISK_CHANNEL_RUNNING:
-       case TAPDISK_CHANNEL_PAUSED:
-               if (channel->shutdown_force)
-                       err = tapdisk_channel_send_force_shutdown_request(channel);
-               else
-                       err = tapdisk_channel_send_shutdown_request(channel);
-               if (err)
-                       goto fail_msg;
-               return -EAGAIN;
-
-       default:
-               EPRINTF("%s: invalid channel state %d\n",
-                       __func__, channel->state);
-               return -EINVAL;
-       }
-
-fail_msg:
-       tapdisk_channel_fatal(channel, "sending message: %d", err);
-       return -EIO;
-}
-
-static int
-tapdisk_channel_drive_running(tapdisk_channel_t *channel)
-{
-       int err;
-
-       switch (channel->state) {
-       case TAPDISK_CHANNEL_DEAD:
-       case TAPDISK_CHANNEL_CLOSED:
-               err = tapdisk_channel_connect(channel);
-               if (err) {
-                       tapdisk_channel_fatal(channel, "failed connect: %d", err);
-                       return err;
-               }
-               return -EAGAIN;
-
-       case TAPDISK_CHANNEL_LAUNCHED:
-       case TAPDISK_CHANNEL_WAIT_PID:
-       case TAPDISK_CHANNEL_WAIT_OPEN:
-       case TAPDISK_CHANNEL_WAIT_PAUSE:
-       case TAPDISK_CHANNEL_WAIT_RESUME:
-       case TAPDISK_CHANNEL_WAIT_CLOSE:
-               return -EAGAIN;
-
-       case TAPDISK_CHANNEL_PID:
-               err = tapdisk_channel_send_open_request(channel);
-               if (err)
-                       goto fail_msg;
-               return -EAGAIN;
-
-       case TAPDISK_CHANNEL_RUNNING:
-               return 0;
-
-       case TAPDISK_CHANNEL_PAUSED:
-               err = tapdisk_channel_send_resume_request(channel);
-               if (err)
-                       goto fail_msg;
-               return -EAGAIN;
-
-       default:
-               EPRINTF("%s: invalid channel state %d\n",
-                       __func__, channel->state);
-               return -EINVAL;
-       }
-
-fail_msg:
-       tapdisk_channel_fatal(channel, "sending message: %d", err);
-       return -EIO;
-}
-
-static channel_state_t
-tapdisk_channel_map_vbd_state(tapdisk_channel_t *channel)
-{
-       channel_state_t next;
-
-       switch (channel->shutdown_state) {
-       case TAPDISK_VBD_DOWN:
-               return TAPDISK_CHANNEL_CLOSED;
-
-       case TAPDISK_VBD_UP:
-               switch (channel->vbd_state) {
-               case TAPDISK_VBD_UNPAUSED:
-                       return TAPDISK_CHANNEL_RUNNING;
-
-               case TAPDISK_VBD_PAUSING:
-               case TAPDISK_VBD_PAUSED:
-                       return TAPDISK_CHANNEL_PAUSED;
-
-               case TAPDISK_VBD_BROKEN:
-               case TAPDISK_VBD_DEAD:
-               case TAPDISK_VBD_RECYCLED:
-                       return TAPDISK_CHANNEL_CLOSED;
-
-               default:
-                       EPRINTF("%s: invalid vbd state %d\n",
-                               __func__, channel->vbd_state);
-                       return -EINVAL;
-               }
-               break;
-       default:
-               EPRINTF("%s: invalid shutdown state %d\n",
-                       __func__, channel->shutdown_state);
-               return -EINVAL;
-       }
-}
-
-void
-tapdisk_channel_drive_vbd_state(tapdisk_channel_t *channel)
-{
-       channel_state_t next;
-
-       next = tapdisk_channel_map_vbd_state(channel);
-       DPRINTF("driving channel state %s, vbd %s, %s to %s (%d)\n",
-               tapdisk_channel_state_name(channel->state),
-               tapdisk_channel_shutdown_state_name(channel->shutdown_state),
-               tapdisk_channel_vbd_state_name(channel->vbd_state),
-               tapdisk_channel_state_name(next), next);
-       if (next < 0)
-               return;
-
-       if (channel->state != next) {
-               int err = 0;
-
-               switch (next) {
-               case TAPDISK_CHANNEL_RUNNING:
-                       err = tapdisk_channel_drive_running(channel);
-                       break;
-               case TAPDISK_CHANNEL_PAUSED:
-                       err = tapdisk_channel_drive_paused(channel);
-                       break;
-               case TAPDISK_CHANNEL_CLOSED:
-                       err = tapdisk_channel_drive_shutdown(channel);
-                       break;
-               default:
-                       EPRINTF("%s: invalid target state %d\n", __func__, next);
-                       err = -EINVAL;
-                       break;
-               }
-               if (err)
-                       /* -EAGAIN: not there yet */
-                       return;
-       }
-
-       switch (channel->vbd_state) {
-       case TAPDISK_VBD_UNPAUSED:
-       case TAPDISK_VBD_PAUSED:
-       case TAPDISK_VBD_BROKEN:
-               break;
-
-       case TAPDISK_VBD_PAUSING:
-               tapdisk_channel_enter_vbd_state(channel, TAPDISK_VBD_PAUSED);
-               tapdisk_channel_signal_paused(channel);
-               break;
-
-       case TAPDISK_VBD_RECYCLED:
-               tapdisk_channel_trigger_reprobe(channel);
-               /* then destroy */
-       case TAPDISK_VBD_DEAD:
-               tapdisk_channel_destroy(channel);
-       }
-}
-
-static int
-tapdisk_channel_check_pause_request(tapdisk_channel_t *channel)
-{
-       int pause, err = 0;
-
-       pause = xs_exists(channel->xsh, channel->pause_str);
-       if (pause)
-               tapdisk_channel_enter_vbd_state(channel, TAPDISK_VBD_PAUSING);
-       else {
-               err = tapdisk_channel_refresh_params(channel);
-               if (!err)
-                       err = tapdisk_channel_enter_vbd_state(channel, TAPDISK_VBD_UNPAUSED);
-               if (!err)
-                       err = tapdisk_channel_signal_unpaused(channel);
-       }
-
-       return err;
-}
-
-static void
-tapdisk_channel_pause_event(struct xs_handle *xsh,
-                           struct xenbus_watch *watch, const char *path)
-{
-       int err, count;
-       tapdisk_channel_t *channel;
-
-       channel = watch->data;
-
-       DPRINTF("%s: got pause watch on %s\n",
-               channel->path, path);
-
-       err = tapdisk_channel_validate_watch(channel, path);
-       if (err) {
-               if (err == -EINVAL)
-                       tapdisk_channel_fatal(channel,
-                                             "bad pause watch");
-               goto out;
-       }
-
-       err = tapdisk_channel_check_pause_request(channel);
-       if (err)
-               tapdisk_channel_error(channel,
-                                     "pause event failed: %d", err);
-       else
-               tapdisk_channel_drive_vbd_state(channel);
-
-out:
-       DPRINTF("%s: handled pause watch on %s\n",
-               channel->path, path);
-}
-
-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) {
-               EPRINTF("invalid dev id: %d\n", minor);
-               return -EINVAL;
-       }
-
-       if (minor > MAX_TAP_DEV) {
-               EPRINTF("dev id %d exceeds maximum devices (%d)\n",
-                       minor, MAX_TAP_DEV);
-               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 opt_facility[32];
-       char *argv[] = { "tapdisk", opt_facility, write_dev, read_dev, NULL };
-       const char *tapdisk;
-       int i;
-
-       if ((child = fork()) == -1)
-               return -errno;
-
-       if (child)
-               return child;
-
-       for (i = 0; i < sysconf(_SC_OPEN_MAX) ; i++)
-               if (i != STDIN_FILENO &&
-                   i != STDOUT_FILENO &&
-                   i != STDERR_FILENO)
-                       close(i);
-
-       snprintf(opt_facility, sizeof(opt_facility),
-                "-l%d", tapdisk_daemon_log_facility);
-
-       tapdisk = getenv("TAPDISK");
-       if (!tapdisk)
-               tapdisk = argv[0];
-
-       execvp(tapdisk, argv);
-
-       PERROR("execvp");
-       _exit(1);
-}
-
-static void
-tapdisk_channel_close_tapdisk(tapdisk_channel_t *channel)
-{
-       if (channel->read_fd >= 0) {
-               close(channel->read_fd);
-               channel->read_fd = -1;
-       }
-
-       if (channel->write_fd >= 0) {
-               close(channel->write_fd);
-               channel->write_fd = -1;
-       }
-}
-
-static int
-tapdisk_channel_launch_tapdisk(tapdisk_channel_t *channel)
-{
-       int err;
-       char *read_dev, *write_dev;
-
-       read_dev          = NULL;
-       write_dev         = NULL;
-
-       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;
-       }
-
-       channel->tapdisk_pid = 
-               tapdisk_channel_start_process(channel, write_dev, read_dev);
-       if (channel->tapdisk_pid < 0) {
-               err = channel->tapdisk_pid;
-               channel->tapdisk_pid = -1;
-               goto fail;
-       }
-
-       channel->channel_id = channel->write_fd;
-
-       free(read_dev);
-       free(write_dev);
-
-       DPRINTF("process launched, channel = %d:%d\n",
-               channel->channel_id, channel->cookie);
-
-       channel->state = TAPDISK_CHANNEL_LAUNCHED;
-       return tapdisk_channel_send_pid_request(channel);
-
-fail:
-       free(read_dev);
-       free(write_dev);
-       tapdisk_channel_close_tapdisk(channel);
-       return err;
-}
-
-static int
-tapdisk_channel_connect(tapdisk_channel_t *channel)
-{
-       int err;
-
-       tapdisk_daemon_maybe_clone_channel(channel);
-       if (channel->tapdisk_pid)
-               channel->state = TAPDISK_CHANNEL_PID;
-       else
-               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 void
-tapdisk_channel_uninit(tapdisk_channel_t *channel)
-{
-       free(channel->uuid_str);
-       channel->uuid_str = NULL;
-
-       free(channel->start_str);
-       channel->start_str = NULL;
-
-       free(channel->pause_str);
-       channel->pause_str = NULL;
-
-       free(channel->pause_done_str);
-       channel->pause_done_str = NULL;
-
-       channel->share_tapdisk_str = NULL;
-}
-
-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->start_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->start_str,
-                      "%s/tapdisk-request", channel->path);
-       if (err == -1) {
-               channel->start_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;
-       }
-
-       channel->share_tapdisk_str = "/local/domain/0/tapdisk/share-tapdisks";
-
-       return 0;
-
-fail:
-       tapdisk_channel_uninit(channel);
-       return -ENOMEM;
-}
-
-static void
-tapdisk_channel_clear_watches(tapdisk_channel_t *channel)
-{
-       if (channel->start_watch.node) {
-               unregister_xenbus_watch(channel->xsh, &channel->start_watch);
-               channel->start_watch.node    = NULL;
-       }
-
-       if (channel->pause_watch.node) {
-               unregister_xenbus_watch(channel->xsh, &channel->pause_watch);
-               channel->pause_watch.node    = NULL;
-       }
-}
-
-static int
-tapdisk_channel_set_watches(tapdisk_channel_t *channel)
-{
-       int err;
-
-       /* watch for start/shutdown events */
-       channel->start_watch.node            = channel->start_str;
-       channel->start_watch.callback        = tapdisk_channel_shutdown_event;
-       channel->start_watch.data            = channel;
-       err = register_xenbus_watch(channel->xsh, &channel->start_watch);
-       if (err) {
-               channel->start_watch.node    = NULL;
-               goto fail;
-       }
-
-       /* 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;
-       }
-
-       return 0;
-
-fail:
-       tapdisk_channel_clear_watches(channel);
-       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_parse_params(tapdisk_channel_t *channel)
-{
-       char *vdi_type_path;
-       char *ptr, *path;
-       size_t len;
-       int err;
-
-       path = channel->params;
-
-       ptr = strchr(path, ':');
-       if (!ptr)
-               goto fail;
-
-       channel->vdi_path = ptr + 1;
-       channel->vdi_type = strndup(path, ptr - path);
-
-       err = asprintf(&vdi_type_path, "%s/sm-data/vdi-type", channel->path);
-       if (err == -1)
-               goto fail;
-
-       if (xs_exists(channel->xsh, vdi_type_path)) {
-               free(channel->vdi_type);
-
-               channel->vdi_type =
-                       xs_read(channel->xsh, XBT_NULL, vdi_type_path, &len);
-               free(vdi_type_path);
-
-               if (!channel->vdi_type)
-                       goto fail;
-       }
-
-       len  = strlen(channel->vdi_type);
-       len += strlen(":");
-       len += strlen(channel->vdi_path);
-
-       if (len + 1 >= TAPDISK_MESSAGE_MAX_PATH_LENGTH)
-               goto fail;
-
-       return 0;
-
-fail:
-       EPRINTF("%s: invalid blktap params: %s\n",
-               channel->path, channel->params);
-       channel->vdi_path = NULL;
-       channel->vdi_type = NULL;
-       return -EINVAL;
-}
-
-
-static void
-tapdisk_channel_release_info(tapdisk_channel_t *channel)
-{
-       free(channel->params);
-       channel->params = NULL;
-
-       free(channel->frontpath);
-       channel->frontpath = NULL;
-}
-
-static int
-tapdisk_channel_gather_info(tapdisk_channel_t *channel)
-{
-       int err;
-
-       err = xs_gather(channel->xsh, channel->path,
-                       "frontend", NULL, &channel->frontpath,
-                       "params", NULL, &channel->params,
-                       "mode", "%c", &channel->mode, NULL);
-       if (err) {
-               EPRINTF("could not find device info: %d\n", err);
-               goto fail;
-       }
-
-       err = tapdisk_channel_parse_params(channel);
-       if (err)
-               goto fail;
-
-       tapdisk_channel_get_storage_type(channel);
-
-       return 0;
-
-fail:
-       tapdisk_channel_release_info(channel);
-       return err;
-}
-
-static int
-tapdisk_channel_refresh_params(tapdisk_channel_t *channel)
-{
-       int err;
-
-       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;
-               return err;
-       }
-
-       return tapdisk_channel_parse_params(channel);
-}
-
-static void
-tapdisk_channel_destroy(tapdisk_channel_t *channel)
-{
-       DPRINTF("destroying channel %d:%d, state %s\n",
-               channel->channel_id, channel->cookie,
-               tapdisk_channel_state_name(channel->state));
-
-       tapdisk_channel_clear_watches(channel);
-       tapdisk_daemon_close_channel(channel);
-       tapdisk_channel_release_info(channel);
-       tapdisk_channel_uninit(channel);
-       free(channel->path);
-       free(channel);
-}
-
-int
-tapdisk_channel_open(tapdisk_channel_t **_channel,
-                    const char *path, struct xs_handle *xsh,
-                    int blktap_fd, uint16_t cookie,
-                    int domid, int busid)
-{
-       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->domid     = domid;
-       channel->busid     = busid;
-       channel->state     = TAPDISK_CHANNEL_DEAD;
-       channel->read_fd   = -1;
-       channel->write_fd  = -1;
-
-       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_set_watches(channel);
-       if (err) {
-               msg = "registering xenstore watches";
-               goto fail;
-       }
-
-       err = tapdisk_channel_check_start_request(channel);
-       if (err && err != -ENOENT) {
-               msg = "initializing shutdown state";
-               goto fail;
-       }
-
-       err = tapdisk_channel_check_pause_request(channel);
-       if (err) {
-               msg = "initializing pause state";
-               goto fail;
-       }
-
-       *_channel = channel;
-       return 0;
-
-fail:
-       tapdisk_channel_fatal(channel, "%s: %d", (msg ? : "failure"), err);
-       return err;
-}
-
-void
-tapdisk_channel_reap(tapdisk_channel_t *channel, int status)
-{
-       const char *chn_state, *vbd_state, *krn_state;
-
-       chn_state = tapdisk_channel_state_name(channel->state);
-       vbd_state = tapdisk_channel_vbd_state_name(channel->vbd_state);
-       krn_state = tapdisk_channel_shutdown_state_name(channel->shutdown_state);
-
-       DPRINTF("reaping tapdisk, status %x, channel state %s, vbd %s, %s\n",
-               status, chn_state, vbd_state, krn_state);
-
-       if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
-               tapdisk_channel_fatal(channel,
-                                     "tapdisk died with status %d",
-                                     WEXITSTATUS(status));
-       } else if (WIFSIGNALED(status)) {
-               tapdisk_channel_fatal(channel,
-                                     "tapdisk killed by signal %d",
-                                     WTERMSIG(status));
-       }
-
-       tapdisk_channel_close_tapdisk(channel);
-       channel->state = TAPDISK_CHANNEL_DEAD;
-
-       /* NB. we're in VBD_BROKEN state if we didn't exit properly,
-          implicitly avoiding an unwanted restart */
-       tapdisk_channel_drive_vbd_state(channel);
-}
-
-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:
-               err = tapdisk_channel_receive_pid_response(c, m);
-               break;
-
-       case TAPDISK_MESSAGE_OPEN_RSP:
-               err = tapdisk_channel_receive_open_response(c, m);
-               break;
-
-       case TAPDISK_MESSAGE_PAUSE_RSP:
-               err = tapdisk_channel_receive_pause_response(c, m);
-               break;
-
-       case TAPDISK_MESSAGE_RESUME_RSP:
-               err = tapdisk_channel_receive_resume_response(c, m);
-               break;
-
-       case TAPDISK_MESSAGE_CLOSE_RSP:
-               err = tapdisk_channel_receive_shutdown_response(c, m);
-               break;
-
-       case TAPDISK_MESSAGE_RUNTIME_ERROR:
-               err = tapdisk_channel_receive_runtime_error(c, m);
-               break;
-
-       default:
-       fail:
-               tapdisk_channel_fatal(c, "received unexpected message %s in state %d",
-                                     tapdisk_message_name(m->type), c->state);
-               return -EINVAL;
-       }
-
-       tapdisk_channel_drive_vbd_state(c);
-       return 0;
-}
diff --git a/daemon/tapdisk-daemon.c b/daemon/tapdisk-daemon.c
deleted file mode 100644 (file)
index f5a030f..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-/*
- * Copyright (c) 2008 Xensource Inc.
- *
- * 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 <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <getopt.h>
-#define SYSLOG_NAMES
-#include <syslog.h>
-
-#include <xs.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;
-       int                           n_channels;
-       struct xenbus_watch           watch;
-
-       sigset_t                      sigunmask;
-} tapdisk_daemon_t;
-
-static tapdisk_daemon_t tapdisk_daemon;
-int tapdisk_daemon_log_facility;
-
-#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");
-       DPRINTF("Syslog facility %d\n", tapdisk_daemon_log_facility);
-}
-
-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 void
-tapdisk_daemon_sa_none(int signo)
-{
-       /* only take a syscall restart */
-}
-
-static int
-tapdisk_daemon_init(void)
-{
-       char *devname;
-       int i, err, blktap_major;
-       sigset_t mask;
-
-       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;
-       }
-
-       /* 
-        * Spoil any opportunity for set/check races by forcing
-        * children to later serialize their demise into the event
-        * loop.
-        *
-        * NB. It's no coincidence we're blocking those signals right
-        * here. XS watches spawn threads [*shiver*]. The new mask is
-        * heritage.
-        */
-       sigemptyset(&mask);
-
-       sigaddset(&mask, SIGCHLD);
-       signal(SIGCHLD, tapdisk_daemon_sa_none);
-
-       sigprocmask(SIG_BLOCK, &mask, &tapdisk_daemon.sigunmask);
-
-       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;
-       }
-
-       fcntl(xs_fileno(tapdisk_daemon.xsh), F_SETFD, O_NONBLOCK);
-       
-       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 int
-tapdisk_daemon_write_uuid(const 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 tapdisk_channel_t*
-tapdisk_daemon_find_channel(int domid, int busid)
-{
-       tapdisk_channel_t *channel, *next;
-
-       tapdisk_daemon_for_each_channel(channel, next)
-               if (channel->domid == domid &&
-                   channel->busid == busid)
-                       return channel;
-
-       return NULL;
-}
-
-static void
-tapdisk_daemon_probe_vbd(int domid, int busid, const char *path)
-{
-       tapdisk_channel_t *channel;
-       uint32_t cookie;
-       int err;
-
-       channel = tapdisk_daemon_find_channel(domid, busid);
-       if (channel) {
-               err = tapdisk_channel_check_uuid(channel);
-               if (err == -ENOENT) {
-                       /* NB. Fast unplug/plug and we missed the path
-                          removal. Typically a dom0 phenonmenon */
-                       DPRINTF("%s: pending re-probe: uuid %d, state %d\n",
-                               path, channel->cookie, channel->vbd_state);
-                       channel->vbd_state = TAPDISK_VBD_RECYCLED;
-                       tapdisk_channel_drive_vbd_state(channel);
-                       return;
-               }
-
-               DPRINTF("%s: ignoring duplicate probe event:"
-                       " uuid %d, state %d\n",
-                       path, channel->cookie, channel->vbd_state);
-               return;
-       }
-
-       cookie = tapdisk_daemon.cookie++;
-       err    = tapdisk_daemon_write_uuid(path, cookie);
-       if (err)
-               return;
-
-       if (tapdisk_daemon.n_channels >= TAPDISK_DAEMON_MAX_CHANNELS) {
-               err = -EMFILE;
-               goto fail;
-       }
-
-       DPRINTF("%s: creating channel, uuid %u\n", path, cookie);
-
-       err = tapdisk_channel_open(&channel, path,
-                                  tapdisk_daemon.xsh,
-                                  tapdisk_daemon.blktap_fd,
-                                  cookie, domid, busid);
-       if (err)
-               goto fail;
-
-       list_add(&channel->list, &tapdisk_daemon.channels);
-       tapdisk_daemon.n_channels++;
-       return;
-
-fail:
-       EPRINTF("failed to open tapdisk channel for %s: %d\n", path, err);
-}
-
-static void
-tapdisk_daemon_remove_vbd(int domid, int busid, const char *path)
-{
-       tapdisk_channel_t *channel;
-
-       channel = tapdisk_daemon_find_channel(domid, busid);
-       if (!channel) {
-               DPRINTF("%s: ignoring remove event:"
-                       " no channel.\n",
-                       path);
-               return;
-       }
-
-       DPRINTF("%s: marking channel dead, uuid %u\n", path, channel->cookie);
-
-       channel->vbd_state = TAPDISK_VBD_DEAD;
-       tapdisk_channel_drive_vbd_state(channel);
-}
-
-static void
-tapdisk_daemon_node_event(struct xs_handle *xsh,
-                         struct xenbus_watch *watch, const char *path)
-{
-       int count, domid, busid, offset;
-       char slash;
-
-       count = sscanf(path, "/local/domain/%*d/backend/tap/%d/%d%c",
-                      &domid, &busid, &slash);
-
-       if (count == 2) {
-               const char *action;
-               int exists;
-
-               exists = xs_exists(xsh, path);
-               action = exists ? "probe" : "remove";
-
-               DPRINTF("got %s watch on %s\n", action, path);
-
-               if (exists)
-                       tapdisk_daemon_probe_vbd(domid, busid, path);
-               else
-                       tapdisk_daemon_remove_vbd(domid, busid, path);
-
-               DPRINTF("handled %s watch on %s\n", action, path);
-       }
-}
-
-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_node_event;
-
-       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 pid_t
-tapdisk_daemon_wait(int *_status)
-{
-       tapdisk_channel_t *channel;
-       pid_t pid;
-       int status;
-
-       pid = waitpid(-1, &status, WNOHANG);
-       if (pid == 0)
-               return -1; /* No state changes */
-
-       if (pid < 0) {
-               if (errno != ECHILD) /* No children */
-                       PERROR("waitpid");
-               return -1;
-       }
-
-       *_status = status;
-
-       if (WIFEXITED(status)) {
-               DPRINTF("child %d exited with status %d", pid, 
-                       WEXITSTATUS(status));
-               return pid;
-       }
-
-       if (WIFSIGNALED(status)) {
-               DPRINTF("child %d killed by signal %d", pid, WTERMSIG(status));
-               return pid;
-       }
-               
-       /* WIFSTOPPED? Oh well. */
-       DPRINTF("ignoring child %d transition to state 0x%x.", pid, status);
-
-       return 0;
-}
-
-static void
-tapdisk_daemon_reap_channels(void)
-{
-       do {
-               tapdisk_channel_t *channel, *next;
-               pid_t pid;
-               int status;
-
-               pid = tapdisk_daemon_wait(&status);
-               if (pid < 0)
-                       break;
-
-               if (!pid)
-                       /* ignorable child state. */
-                       continue;
-               
-               tapdisk_daemon_for_each_channel(channel, next)
-                       if (channel->tapdisk_pid == pid)
-                               tapdisk_channel_reap(channel, status);
-       } while (1);
-}
-
-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) {
-               if (!TAPDISK_CHANNEL_IPC_OPEN(channel))
-                       continue;
-               fd  = channel->read_fd;
-               max = MAX(fd, max);
-               FD_SET(fd, readfds);
-       }
-
-       return max;
-}
-
-static void
-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 (!TAPDISK_CHANNEL_IPC_OPEN(channel))
-                       continue;
-
-               if (FD_ISSET(channel->read_fd, readfds)) {
-                       tapdisk_daemon_receive_message(channel->read_fd);
-                       return;
-               }
-       }
-}
-
-static int
-tapdisk_daemon_run(void)
-{
-       int nfds, max;
-       fd_set readfds;
-
-       while (1) {
-               max = tapdisk_daemon_set_fds(&readfds);
-
-               nfds = pselect(max + 1, &readfds, NULL, NULL, NULL,
-                              &tapdisk_daemon.sigunmask);
-               if (nfds < 0) {
-                       if (errno != EINTR)
-                               PERROR("select");
-               }
-
-               if (nfds > 0)
-                       tapdisk_daemon_check_fds(&readfds);
-
-               tapdisk_daemon_reap_channels();
-       }
-
-       return 0;
-}
-
-void
-tapdisk_daemon_maybe_clone_channel(tapdisk_channel_t *channel)
-{
-       tapdisk_channel_t *c, *tmp;
-
-       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 (!strcmp(c->vdi_type, channel->vdi_type)) {
-                       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.n_channels--;
-
-       tapdisk_daemon_for_each_channel(c, tmp)
-               if (c->channel_id == channel->channel_id)
-                       return;
-
-       close(channel->read_fd);
-       close(channel->write_fd);
-}
-
-static void
-tapdisk_daemon_openlog(const char *ident, const char *facility_name)
-{
-       static char buf[128];
-       int facility;
-
-       facility = LOG_DAEMON;
-
-       if (facility_name) {
-               char *endptr;
-
-               facility = strtol(facility_name, &endptr, 0);
-               if (*endptr != 0) {
-                       CODE *c;
-
-                       facility = LOG_DAEMON;
-                       for (c = facilitynames; c->c_name != NULL; ++c)
-                               if (!strcmp(c->c_name, facility_name))
-                                       facility = c->c_val;
-               }
-       }
-
-       snprintf(buf, sizeof(buf), "%s[%d]", ident, getpid());
-       openlog(buf, LOG_CONS | LOG_ODELAY, facility);
-       tapdisk_daemon_log_facility = facility;
-}
-
-static const char *program;
-
-static void
-usage(FILE *stream)
-{
-       fprintf(stream, "Usage: %s [-h] [-l <syslog_facility>]\n", program);
-}
-
-int
-main(int argc, char *argv[])
-{
-       int err, gcc;
-       const char *facility;
-
-       program  = basename(argv[0]);
-       facility = "daemon";
-
-       do {
-               char c;
-
-               c = getopt(argc, argv, "hl:");
-               if (c < 0)
-                       break;
-
-               switch (c) {
-               case 'h':
-                       usage(stdout);
-                       return 0;
-               case 'l':
-                       facility = optarg;
-                       break;
-               default:
-                       goto usage;
-               }
-       } while (1);
-
-       gcc = daemon(0, 0);
-
-#define CORE_DUMP
-#if defined(CORE_DUMP)
-#include <sys/resource.h>
-       {
-               /* 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
-
-       tapdisk_daemon_openlog("BLKTAP-DAEMON", facility);
-
-       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) {
-               EPRINTF("failed to start %s: %d\n", argv[0], err);
-               goto out;
-       }
-
-       err = tapdisk_daemon_run();
-
-       tapdisk_daemon_stop();
-
-       tapdisk_daemon_free();
-
-
-out:
-       closelog();
-       return err ? 1 : 0;
-
-usage:
-       usage(stderr);
-       return EINVAL;
-
-}
diff --git a/daemon/tapdisk-dispatch-common.c b/daemon/tapdisk-dispatch-common.c
deleted file mode 100644 (file)
index 3d72b7d..0000000
+++ /dev/null
@@ -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 --git a/daemon/tapdisk-dispatch.h b/daemon/tapdisk-dispatch.h
deleted file mode 100644 (file)
index efe134e..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2008 Xensource Inc.
- *
- * 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 _TAPDISK_DISPATCH_H_
-#define _TAPDISK_DISPATCH_H_
-
-#include <sys/select.h>
-
-#include "xs_api.h"
-#define TAPDISK
-#include "blktaplib.h"
-#include "tapdisk-message.h"
-
-/*
- * This goes below MAX_TAP_DEV, bound by our ipc architecture and
- * fd_set size (typically 1024, minus room for misc). Named pipes are
- * simplex. Socketpairs might might have been a better choice.
- */
-#define TAPDISK_DAEMON_MAX_CHANNELS   ((FD_SETSIZE - 16) / 2)
-
-typedef enum {
-       TAPDISK_CHANNEL_DEAD          = 1,
-       TAPDISK_CHANNEL_LAUNCHED      = 2,
-       TAPDISK_CHANNEL_WAIT_PID      = 3,
-       TAPDISK_CHANNEL_PID           = 4,
-       TAPDISK_CHANNEL_WAIT_OPEN     = 5,
-       TAPDISK_CHANNEL_RUNNING       = 6,
-       TAPDISK_CHANNEL_WAIT_PAUSE    = 7,
-       TAPDISK_CHANNEL_PAUSED        = 8,
-       TAPDISK_CHANNEL_WAIT_RESUME   = 9,
-       TAPDISK_CHANNEL_WAIT_CLOSE    = 10,
-       TAPDISK_CHANNEL_CLOSED        = 11,
-} channel_state_t;
-
-#define TAPDISK_CHANNEL_IPC_OPEN(_c)               \
-       ((_c)->state != TAPDISK_CHANNEL_DEAD     && \
-        (_c)->state != TAPDISK_CHANNEL_CLOSED)
-
-#define TAPDISK_CHANNEL_IPC_IDLE(_c)              \
-       ((_c)->state == TAPDISK_CHANNEL_LAUNCHED || \
-        (_c)->state == TAPDISK_CHANNEL_PID      || \
-        (_c)->state == TAPDISK_CHANNEL_RUNNING  || \
-        (_c)->state == TAPDISK_CHANNEL_PAUSED)
-
-typedef enum {
-       TAPDISK_VBD_UNPAUSED        = 1,
-       TAPDISK_VBD_PAUSING         = 2,
-       TAPDISK_VBD_PAUSED          = 3,
-       TAPDISK_VBD_BROKEN          = 4,
-       TAPDISK_VBD_DEAD            = 5,
-       TAPDISK_VBD_RECYCLED        = 6,
-} vbd_state_t;
-
-typedef enum {
-       TAPDISK_VBD_UP              = 1,
-       TAPDISK_VBD_DOWN            = 2,
-} shutdown_state_t;
-
-struct tapdisk_channel {
-       channel_state_t           state;
-       vbd_state_t               vbd_state;
-       shutdown_state_t          shutdown_state;
-       int                       shutdown_force;
-
-       int                       read_fd;
-       int                       write_fd;
-       int                       blktap_fd;
-       int                       channel_id;
-
-       char                      mode;
-       char                      shared;
-       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;
-
-       char                     *path;
-       char                     *frontpath;
-       char                     *params;
-       char                     *vdi_type;
-       char                     *vdi_path;
-       char                     *uuid_str;
-       char                     *start_str;
-       char                     *pause_str;
-       char                     *pause_done_str;
-       char                     *share_tapdisk_str;
-
-       image_t                   image;
-
-       struct list_head          list;
-       struct xenbus_watch       start_watch;
-       struct xenbus_watch       pause_watch;
-
-       struct xs_handle         *xsh;
-};
-
-extern int tapdisk_daemon_log_facility;
-
-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 **,
-                        const char *node, struct xs_handle *,
-                        int blktap_fd, uint16_t cookie,
-                        int domid, int busid);
-
-void tapdisk_daemon_maybe_clone_channel(tapdisk_channel_t *);
-void tapdisk_daemon_close_channel(tapdisk_channel_t *);
-
-int tapdisk_channel_receive_message(tapdisk_channel_t *, tapdisk_message_t *);
-void tapdisk_channel_reap(tapdisk_channel_t *, int status);
-int tapdisk_channel_change_vbd_state(tapdisk_channel_t *, vbd_state_t);
-void tapdisk_channel_drive_vbd_state(tapdisk_channel_t *);
-int tapdisk_channel_check_uuid(tapdisk_channel_t *);
-
-#endif
index 2cca11c4c83bc97d96f45eb3a11710cd5ee3fafc..9e474d118ca1929ec7e40ffc6681687870a03647 100644 (file)
@@ -41,11 +41,9 @@ rm -rf $RPM_BUILD_ROOT
 %files
 %defattr(-,root,root,-)
 %doc
-%{_libdir}/libblktap.so*
 %{_libdir}/libvhd.so*
 %{_libdir}/libvhdio.so*
 %{_libdir}/libblktapctl.so*
-%{_sbindir}/blktapctrl
 %{_sbindir}/tapdisk
 %{_sbindir}/tapdisk2
 %{_sbindir}/tap-ctl
@@ -64,7 +62,6 @@ rm -rf $RPM_BUILD_ROOT
 %files devel
 %defattr(-,root,root,-)
 %doc
-%{_libdir}/libblktap.a
 %{_libdir}/libvhd.a
 %{_libdir}/libvhdio.a
 %{_libdir}/libblktapctl.a