]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
blktap2: Sync with latest OSS.
authorDaniel Stodden <daniel.stodden@citrix.com>
Tue, 29 Jun 2010 20:03:09 +0000 (13:03 -0700)
committerDaniel Stodden <daniel.stodden@citrix.com>
Tue, 29 Jun 2010 20:03:09 +0000 (13:03 -0700)
27 files changed:
control/Makefile
control/tap-ctl-allocate.c
control/tap-ctl-attach.c
control/tap-ctl-check.c [new file with mode: 0644]
control/tap-ctl-close.c
control/tap-ctl-create.c
control/tap-ctl-destroy.c
control/tap-ctl-detach.c
control/tap-ctl-free.c
control/tap-ctl-ipc.c
control/tap-ctl-list.c
control/tap-ctl-open.c
control/tap-ctl-pause.c
control/tap-ctl-spawn.c
control/tap-ctl-unpause.c
control/tap-ctl.c
control/tap-ctl.h
daemon/lib/xs_api.c
drivers/Makefile
drivers/tapdisk-control.c
drivers/tapdisk-control.h
drivers/tapdisk-interface.c
drivers/tapdisk-interface.h
drivers/tapdisk-server.c
drivers/tapdisk2.c
include/blktaplib.h
include/tapdisk-message.h

index 8c23b364c045572223d4d863535a1abb3d62c0e8..2ac3ecc6f02c1d38d3ab9a7b2e1c0137d14ae441 100644 (file)
@@ -8,6 +8,7 @@ CFLAGS            += -Werror
 CFLAGS            += -Wno-unused
 CFLAGS            += -I../include -I../drivers
 CFLAGS            += -D_GNU_SOURCE
+CFLAGS            += -DTAPCTL
 
 # Get gcc to generate the dependencies for us.
 CFLAGS            += -Wp,-MD,.$(@F).d
@@ -27,6 +28,7 @@ CTL_OBJS  += tap-ctl-close.o
 CTL_OBJS  += tap-ctl-pause.o
 CTL_OBJS  += tap-ctl-unpause.o
 CTL_OBJS  += tap-ctl-major.o
+CTL_OBJS  += tap-ctl-check.o
 
 OBJS = $(CTL_OBJS)
 LIBS = libblktapctl.a
index 4c74e959ca201205c514f5729caec4e6490029e7..8a6471e987a4e655b7ee7f110b4bff5600be7805 100644 (file)
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <linux/major.h>
 
 #include "tap-ctl.h"
 #include "blktap2.h"
 
-static void
-usage(void)
-{
-       printf("usage: allocate [-d device name]>\n");
-}
-
 static int
 tap_ctl_prepare_directory(const char *dir)
 {
@@ -69,9 +64,8 @@ tap_ctl_prepare_directory(const char *dir)
 
                err = mkdir(name, 0755);
                if (err && errno != EEXIST) {
+                       PERROR("mkdir %s", name);
                        err = errno;
-                       fprintf(stderr, "failed to create directory %s: %d\n",
-                               name, err);
                        break;
                }
 
@@ -108,14 +102,13 @@ tap_ctl_make_device(const char *devname, const int major,
 
        if (!access(devname, F_OK))
                if (unlink(devname)) {
-                       fprintf(stderr, "error unlinking %s: %d\n",
-                               devname, errno);
+                       PERROR("unlink %s", devname);
                        return errno;
                }
 
        err = mknod(devname, perm, makedev(major, minor));
        if (err) {
-               fprintf(stderr, "mknod %s failed: %d\n", devname, errno);
+               PERROR("mknod %s", devname);
                return errno;
        }
 
@@ -140,20 +133,20 @@ tap_ctl_check_environment(void)
 
        f = fopen("/proc/misc", "r");
        if (!f) {
-               fprintf(stderr, "failed to open /proc/misc: %d\n", errno);
+               EPRINTF("failed to open /proc/misc: %d\n", errno);
                return errno;
        }
 
        while (fscanf(f, "%d %256s", &minor, name) == 2)
                if (!strcmp(name, BLKTAP2_CONTROL_NAME)) {
                        err = tap_ctl_make_device(BLKTAP2_CONTROL_DEVICE,
-                                                 MISC_MAJOR_NUMBER,
+                                                 MISC_MAJOR,
                                                  minor, S_IFCHR | 0600);
                        goto out;
                }
 
        err = ENOSYS;
-       fprintf(stderr, "didn't find %s in /proc/misc\n", BLKTAP2_CONTROL_NAME);
+       EPRINTF("didn't find %s in /proc/misc\n", BLKTAP2_CONTROL_NAME);
 
 out:
        fclose(f);
@@ -173,48 +166,48 @@ tap_ctl_allocate_device(int *minor, char **devname)
 
        fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
        if (fd == -1) {
-               fprintf(stderr, "failed to open control device: %d\n", errno);
+               EPRINTF("failed to open control device: %d\n", errno);
                return errno;
        }
 
        err = ioctl(fd, BLKTAP2_IOCTL_ALLOC_TAP, &handle);
        close(fd);
        if (err == -1) {
-               fprintf(stderr, "failed to allocate new device: %d\n", errno);
+               EPRINTF("failed to allocate new device: %d\n", errno);
                return errno;
        }
 
-       if (*devname)
-               name = *devname;
-       else {
-               err = asprintf(&name, "%s%d",
-                              BLKTAP2_RING_DEVICE, handle.minor);
-               if (err == -1) {
-                       err = ENOMEM;
-                       goto fail;
-               }
-               *devname = name;
+       err = asprintf(&name, "%s%d", BLKTAP2_RING_DEVICE, handle.minor);
+       if (err == -1) {
+               err = ENOMEM;
+               goto fail;
        }
 
        err = tap_ctl_make_device(name, handle.ring,
                                  handle.minor, S_IFCHR | 0600);
+       free(name);
        if (err) {
-               fprintf(stderr, "creating ring device for %d failed: %d\n",
+               EPRINTF("creating ring device for %d failed: %d\n",
                        handle.minor, err);
                goto fail;
        }
 
-       err = asprintf(&name, "%s%d", BLKTAP2_IO_DEVICE, handle.minor);
-       if (err == -1) {
-               err = ENOMEM;
-               goto fail;
+       if (*devname)
+               name = *devname;
+       else {
+               err = asprintf(&name, "%s%d",
+                              BLKTAP2_IO_DEVICE, handle.minor);
+               if (err == -1) {
+                       err = ENOMEM;
+                       goto fail;
+               }
+               *devname = name;
        }
 
        err = tap_ctl_make_device(name, handle.device,
                                  handle.minor, S_IFBLK | 0600);
-       free(name);
        if (err) {
-               fprintf(stderr, "creating IO device for %d failed: %d\n",
+               EPRINTF("creating IO device for %d failed: %d\n",
                        handle.minor, err);
                goto fail;
        }
@@ -226,12 +219,12 @@ tap_ctl_allocate_device(int *minor, char **devname)
        return 0;
 
 fail:
-       _tap_ctl_free(handle.minor);
+       tap_ctl_free(handle.minor);
        return err;
 }
 
 int
-_tap_ctl_allocate(int *minor, char **devname)
+tap_ctl_allocate(int *minor, char **devname)
 {
        int err;
 
@@ -247,30 +240,3 @@ _tap_ctl_allocate(int *minor, char **devname)
 
        return 0;
 }
-
-int
-tap_ctl_allocate(int argc, char **argv)
-{
-       char *devname;
-       int c, id, err;
-
-       devname = NULL;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "d:h")) != -1) {
-               switch (c) {
-               case 'd':
-                       devname = optarg;
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       err = _tap_ctl_allocate(&id, &devname);
-       if (!err)
-               printf("%s\n", devname);
-
-       return err;
-}
index 7b9859e751035689b19960eb1c154594fda1ee73..3cb933cec84f14dcfa50381734ef67c2e8f8970b 100644 (file)
 
 #include "tap-ctl.h"
 
-static void
-usage(void)
-{
-       printf("usage: attach <-i id> <-m minor>\n");
-}
-
 int
-_tap_ctl_attach(const int id, const int minor)
+tap_ctl_attach(const int id, const int minor)
 {
        int err;
        tapdisk_message_t message;
@@ -56,43 +50,12 @@ _tap_ctl_attach(const int id, const int minor)
        if (message.type == TAPDISK_MESSAGE_ATTACH_RSP) {
                err = message.u.response.error;
                if (err)
-                       printf("attach failed: %d\n", err);
+                       EPRINTF("attach failed: %d\n", err);
        } else {
-               printf("got unexpected result '%s' from %d\n",
-                      tapdisk_message_name(message.type), id);
+               EPRINTF("got unexpected result '%s' from %d\n",
+                       tapdisk_message_name(message.type), id);
                err = EINVAL;
        }
 
        return err;
 }
-
-int
-tap_ctl_attach(int argc, char **argv)
-{
-       int c, id, minor;
-
-       id    = -1;
-       minor = -1;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "i:m:h")) != -1) {
-               switch (c) {
-               case 'i':
-                       id = atoi(optarg);
-                       break;
-               case 'm':
-                       minor = atoi(optarg);
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       if (id == -1 || minor == -1) {
-               usage();
-               return EINVAL;
-       }
-
-       return _tap_ctl_attach(id, minor);
-}
diff --git a/control/tap-ctl-check.c b/control/tap-ctl-check.c
new file mode 100644 (file)
index 0000000..e98583a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+int
+tap_ctl_check_blktap(const char **msg)
+{
+       FILE *f;
+       int err = 0, minor;
+       char name[32];
+
+       memset(name, 0, sizeof(name));
+
+       f = fopen("/proc/misc", "r");
+       if (!f) {
+               *msg = "failed to open /proc/misc";
+               return -errno;
+       }
+
+       while (fscanf(f, "%d %32s", &minor, name) == 2) {
+               if (!strcmp(name, BLKTAP2_CONTROL_NAME))
+                       goto out;
+       }
+
+       err = -ENOSYS;
+       *msg = "blktap kernel module not installed";
+
+out:
+       fclose(f);
+       return err;
+}
+
+int
+tap_ctl_check(const char **msg)
+{
+       int err;
+       uid_t uid;
+
+       err = tap_ctl_check_blktap(msg);
+       if (err)
+               goto out;
+
+       err  = 0;
+       *msg = "ok";
+
+out:
+       return err;
+}
index 0e4076391041f5f7b434c36363788b2d80f93c39..2e5f80b29de460776a76de3c3a5ae8f69a952fd2 100644 (file)
 
 #include "tap-ctl.h"
 
-static void
-usage(void)
-{
-       printf("usage: close <-i id> <-m minor> [-f force]\n");
-}
-
 static int
 __tap_ctl_close(const int id, const int minor, const int force)
 {
@@ -59,10 +53,10 @@ __tap_ctl_close(const int id, const int minor, const int force)
        if (message.type == TAPDISK_MESSAGE_CLOSE_RSP) {
                err = message.u.response.error;
                if (err)
-                       printf("close failed: %d\n", err);
+                       EPRINTF("close failed: %d\n", err);
        } else {
-               printf("got unexpected result '%s' from %d\n",
-                      tapdisk_message_name(message.type), id);
+               EPRINTF("got unexpected result '%s' from %d\n",
+                       tapdisk_message_name(message.type), id);
                err = EINVAL;
        }
 
@@ -70,7 +64,7 @@ __tap_ctl_close(const int id, const int minor, const int force)
 }
 
 int
-_tap_ctl_close(const int id, const int minor, const int force)
+tap_ctl_close(const int id, const int minor, const int force)
 {
        int i, err;
 
@@ -81,48 +75,13 @@ _tap_ctl_close(const int id, const int minor, const int force)
 
                err = (err < 0 ? -err : err);
                if (err != EAGAIN) {
-                       printf("close failed: %d\n", err);
+                       EPRINTF("close failed: %d\n", err);
                        return err;
                }
 
                usleep(1000);
        }
 
-       printf("close timed out\n");
+       EPRINTF("close timed out\n");
        return EIO;
 }
-
-int
-tap_ctl_close(int argc, char **argv)
-{
-       int c, id, minor, force;
-
-       id    = -1;
-       minor = -1;
-       force = 0;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "i:m:fh")) != -1) {
-               switch (c) {
-               case 'i':
-                       id = atoi(optarg);
-                       break;
-               case 'm':
-                       minor = atoi(optarg);
-                       break;
-               case 'f':
-                       force = -1;
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       if (id == -1 || minor == -1) {
-               usage();
-               return EINVAL;
-       }
-
-       return _tap_ctl_close(id, minor, force);
-}
index 9d2e5d7414807d75278f895bfb1e52f9a00c7213..46d135e93cb925f9b49cd8bd3ac4b61d62c893eb 100644 (file)
 #include "tap-ctl.h"
 #include "blktap2.h"
 
-static void
-usage(void)
-{
-       printf("usage: create <-a args> [-d device name]\n");
-}
-
 int
-_tap_ctl_create(const char *params, char **devname)
+tap_ctl_create(const char *params, char **devname)
 {
-       int err, id;
+       int err, id, minor;
 
-       err = _tap_ctl_allocate(&id, devname);
+       err = tap_ctl_allocate(&minor, devname);
        if (err)
                return err;
 
-       err = _tap_ctl_spawn(id);
-       if (err < 0)
+       id = tap_ctl_spawn();
+       if (id < 0)
                goto destroy;
 
-       err = _tap_ctl_attach(id, id);
+       err = tap_ctl_attach(id, minor);
        if (err)
                goto destroy;
 
-       err = tap_ctl_open(id, id, params);
+       err = tap_ctl_open(id, minor, params);
        if (err)
                goto detach;
 
        return 0;
 
 detach:
-       _tap_ctl_detach(id, id);
+       tap_ctl_detach(id, minor);
 destroy:
-       _tap_ctl_free(id);
-       return err;
-}
-
-int
-tap_ctl_create(int argc, char **argv)
-{
-       int c, err, type;
-       char *args, *devname;
-
-       args    = NULL;
-       devname = NULL;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "a:d:h")) != -1) {
-               switch (c) {
-               case 'a':
-                       args = optarg;
-                       break;
-               case 'd':
-                       devname = optarg;
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       if (!args) {
-               usage();
-               return EINVAL;
-       }
-
-       err = _tap_ctl_create(args, &devname);
-       if (!err)
-               printf("%s\n", devname);
-
+       tap_ctl_free(minor);
        return err;
 }
index 5e5f3aeb4974c963fa954defaaba37ce5dcb556c..dc5dbaa1a2d1b2ee5e7218c3e26936ab38177959 100644 (file)
 #include "tap-ctl.h"
 #include "blktap2.h"
 
-static void
-usage(void)
-{
-       printf("usage: destroy <-i id> <-m minor>\n");
-}
-
 int
-_tap_ctl_destroy(const int id, const int minor)
+tap_ctl_destroy(const int id, const int minor)
 {
        int err;
 
-       err = _tap_ctl_close(id, minor, 0);
+       err = tap_ctl_close(id, minor, 0);
        if (err)
                return err;
 
-       err = _tap_ctl_detach(id, minor);
+       err = tap_ctl_detach(id, minor);
        if (err)
                return err;
 
-       err = _tap_ctl_free(minor);
+       err = tap_ctl_free(minor);
        if (err)
                return err;
 
        return 0;
 }
-
-int
-tap_ctl_destroy(int argc, char **argv)
-{
-       int c, id, minor;
-
-       id    = -1;
-       minor = -1;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "i:m:h")) != -1) {
-               switch (c) {
-               case 'i':
-                       id = atoi(optarg);
-                       break;
-               case 'm':
-                       minor = atoi(optarg);
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       if (id == -1 || minor == -1) {
-               usage();
-               return EINVAL;
-       }
-
-       return _tap_ctl_destroy(id, minor);
-}
index 344a0f1f6dc37c02bf60d9ab645b342347515708..7d7bbf30d31b5421d7f8a40951f04367341033c9 100644 (file)
 
 #include "tap-ctl.h"
 
-static void
-usage(void)
-{
-       printf("usage: detach <-i id> <-m minor>\n");
-}
-
 int
-_tap_ctl_detach(const int id, const int minor)
+tap_ctl_detach(const int id, const int minor)
 {
        int err;
        tapdisk_message_t message;
@@ -65,34 +59,3 @@ _tap_ctl_detach(const int id, const int minor)
 
        return err;
 }
-
-int
-tap_ctl_detach(int argc, char **argv)
-{
-       int c, id, minor;
-
-       id    = -1;
-       minor = -1;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "i:m:h")) != -1) {
-               switch (c) {
-               case 'i':
-                       id = atoi(optarg);
-                       break;
-               case 'm':
-                       minor = atoi(optarg);
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       if (id == -1 || minor == -1) {
-               usage();
-               return EINVAL;
-       }
-
-       return _tap_ctl_detach(id, minor);
-}
index efc470fd6194a7c37c518b95eeb02b5a46a7b0ae..9ae729574748709b196397daf80d38c0ccc685db 100644 (file)
 #include "tap-ctl.h"
 #include "blktap2.h"
 
-static void
-usage(void)
-{
-       printf("usage: free <-m minor>\n");
-}
-
 int
-_tap_ctl_free(const int minor)
+tap_ctl_free(const int minor)
 {
        int fd, err;
 
        fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
        if (fd == -1) {
-               printf("failed to open control device: %d\n", errno);
+               EPRINTF("failed to open control device: %d\n", errno);
                return errno;
        }
 
@@ -58,30 +52,3 @@ _tap_ctl_free(const int minor)
 
        return err;
 }
-
-int
-tap_ctl_free(int argc, char **argv)
-{
-       int c, minor;
-
-       minor = -1;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "m:h")) != -1) {
-               switch (c) {
-               case 'm':
-                       minor = atoi(optarg);
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
-
-       if (minor == -1) {
-               usage();
-               return EINVAL;
-       }
-
-       return _tap_ctl_free(minor);
-}
index af3763a2daf400f021382ad038d36885c10b9df5..cc6160e9da3ce11ec93ee80d8f0f46a9133bdceb 100644 (file)
@@ -76,7 +76,7 @@ tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout)
        }
 
        if (offset != len) {
-               printf("failure reading message\n");
+               EPRINTF("failure reading message\n");
                return -EIO;
        }
 
@@ -126,7 +126,7 @@ tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout)
        }
 
        if (offset != len) {
-               printf("failure writing message\n");
+               EPRINTF("failure writing message\n");
                return -EIO;
        }
 
@@ -140,15 +140,15 @@ tap_ctl_send_and_receive(int sfd, tapdisk_message_t *message, int timeout)
 
        err = tap_ctl_write_message(sfd, message, timeout);
        if (err) {
-               printf("failed to send '%s' message\n",
-                      tapdisk_message_name(message->type));
+               EPRINTF("failed to send '%s' message\n",
+                       tapdisk_message_name(message->type));
                return err;
        }
 
        err = tap_ctl_read_message(sfd, message, timeout);
        if (err) {
-               printf("failed to receive '%s' message\n",
-                      tapdisk_message_name(message->type));
+               EPRINTF("failed to receive '%s' message\n",
+                       tapdisk_message_name(message->type));
                return err;
        }
 
@@ -177,7 +177,7 @@ tap_ctl_connect(const char *name, int *sfd)
 
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd == -1) {
-               fprintf(stderr, "couldn't create socket for %s: %d\n", name, errno);
+               EPRINTF("couldn't create socket for %s: %d\n", name, errno);
                return -errno;
        }
 
@@ -187,8 +187,7 @@ tap_ctl_connect(const char *name, int *sfd)
 
        err = connect(fd, (const struct sockaddr *)&saddr, sizeof(saddr));
        if (err) {
-               //if (errno != ECONNREFUSED)
-                       fprintf(stderr, "couldn't connect to %s: %d\n", name, errno);
+               EPRINTF("couldn't connect to %s: %d\n", name, errno);
                close(fd);
                return -errno;
        }
@@ -206,13 +205,13 @@ tap_ctl_connect_id(int id, int *sfd)
        *sfd = -1;
 
        if (id < 0) {
-               printf("invalid id %d\n", id);
+               EPRINTF("invalid id %d\n", id);
                return -EINVAL;
        }
 
        name = tap_ctl_socket_name(id);
        if (!name) {
-               printf("couldn't name socket for %d\n", id);
+               EPRINTF("couldn't name socket for %d\n", id);
                return -ENOMEM;
        }
 
index 6f65b680833615bfad2ab99e826e2b0b114cee76..af5922772c2ef7f10527a9d13af8e0c0e32c1240 100644 (file)
@@ -36,7 +36,6 @@
 #include "tap-ctl.h"
 #include "blktap2.h"
 #include "list.h"
-#include "tapdisk-disktype.h"
 
 static void
 free_list(tap_list_t *entry)
@@ -187,7 +186,7 @@ _tap_ctl_find_minors(int **_minorv)
        case GLOB_ABORTED:
        case GLOB_NOSPACE:
                err = -errno;
-               fprintf(stderr, "%s: glob failed, err %d", pattern, err);
+               EPRINTF("%s: glob failed, err %d", pattern, err);
                goto fail;
        }
 
@@ -260,7 +259,7 @@ _tap_ctl_find_tapdisks(struct tapdisk **_tapv)
        case GLOB_ABORTED:
        case GLOB_NOSPACE:
                err = -errno;
-               fprintf(stderr, "%s: glob failed, err %d", pattern, err);
+               EPRINTF("%s: glob failed, err %d", pattern, err);
                goto fail;
        }
 
@@ -280,17 +279,18 @@ _tap_ctl_find_tapdisks(struct tapdisk **_tapv)
                if (err != 1)
                        continue;
 
-               tap->pid = _tap_ctl_get_pid(tap->id);
+               tap->pid = tap_ctl_get_pid(tap->id);
                if (tap->pid < 0)
                        continue;
 
-               INIT_LIST_HEAD(&tap->list);
-
                n_taps++;
        }
 
        qsort(tapv, n_taps, sizeof(struct tapdisk), _tap_tapdisk_cmp);
 
+       for (i = 0; i < n_taps; ++i)
+               INIT_LIST_HEAD(&tapv[i].list);
+
 done:
        *_tapv = tapv;
        err = 0;
index e54e02b7faf31fd136d78cbaa58120a2c8106a89..5961c99183efd03240f853bd1fb6c806699d8f15 100644 (file)
@@ -36,7 +36,7 @@
 #include "blktaplib.h"
 
 int
-tap_ctl_open(const int id, const int minor, const char *args)
+tap_ctl_open(const int id, const int minor, const char *params)
 {
        int err;
        tapdisk_message_t message;
@@ -48,9 +48,9 @@ tap_ctl_open(const int id, const int minor, const char *args)
        message.u.params.devnum = minor;
 
        err = snprintf(message.u.params.path,
-                      sizeof(message.u.params.path) - 1, "%s", args);
+                      sizeof(message.u.params.path) - 1, "%s", params);
        if (err >= sizeof(message.u.params.path)) {
-               printf("name too long\n");
+               EPRINTF("name too long\n");
                return ENAMETOOLONG;
        }
 
@@ -63,11 +63,11 @@ tap_ctl_open(const int id, const int minor, const char *args)
                break;
        case TAPDISK_MESSAGE_ERROR:
                err = -message.u.response.error;
-               fprintf(stderr, "open failed, err %d\n", err);
+               EPRINTF("open failed, err %d\n", err);
                break;
        default:
-               printf("got unexpected result '%s' from %d\n",
-                      tapdisk_message_name(message.type), id);
+               EPRINTF("got unexpected result '%s' from %d\n",
+                       tapdisk_message_name(message.type), id);
                err = EINVAL;
        }
 
index 85b871cd88e531b31cc3256d55de1a8d98f22b09..5e31a5866d21abfe434fbee20087ae07564986d5 100644 (file)
 
 #include "tap-ctl.h"
 
-static void
-usage(void)
-{
-       printf("usage: pause <-i id> <-m minor>\n");
-}
-
 int
 tap_ctl_pause(const int id, const int minor)
 {
@@ -57,8 +51,8 @@ tap_ctl_pause(const int id, const int minor)
                err = message.u.response.error;
        else {
                err = EINVAL;
-               printf("got unexpected result '%s' from %d\n",
-                      tapdisk_message_name(message.type), id);
+               EPRINTF("got unexpected result '%s' from %d\n",
+                       tapdisk_message_name(message.type), id);
        }
 
        return err;
index 1c4a34efdc80b1dfe9d43005299e0db97024f5c1..31a651ec389672961376cb2ccc27304141e7a268 100644 (file)
 #include "tap-ctl.h"
 #include "blktap2.h"
 
-static void
-usage(void)
-{
-       printf("usage: spawn <-i id>\n");
-}
-
 static pid_t
-__tap_ctl_spawn(const int id)
+__tap_ctl_spawn(int *readfd)
 {
-       int err, child;
-       char uuid[12], *control, *tapdisk;
+       int err, child, channel[2];
+       char *tapdisk;
+
+       if (pipe(channel)) {
+               EPRINTF("pipe failed: %d\n", errno);
+               return -errno;
+       }
 
        if ((child = fork()) == -1) {
-               printf("fork failed: %d\n", errno);
+               EPRINTF("fork failed: %d\n", errno);
                return -errno;
        }
 
-       if (child)
+       if (child) {
+               close(channel[1]);
+               *readfd = channel[0];
                return child;
+       }
 
-       err = asprintf(&control, "%s/%s%d",
-                      BLKTAP2_CONTROL_DIR,
-                      BLKTAP2_CONTROL_SOCKET, id);
-       if (err == -1) {
-               printf("fork failed: %d\n", ENOMEM);
-               exit(ENOMEM);
+       if (dup2(channel[1], STDOUT_FILENO) == -1) {
+               EPRINTF("dup2 failed: %d\n", errno);
+               exit(errno);
        }
 
+       if (dup2(channel[1], STDERR_FILENO) == -1) {
+               EPRINTF("dup2 failed: %d\n", errno);
+               exit(errno);
+       }
+
+       close(channel[0]);
+       close(channel[1]);
+
        tapdisk = getenv("TAPDISK2");
        if (!tapdisk)
                tapdisk = "tapdisk2";
 
-       snprintf(uuid, sizeof(uuid) - 1, "%d", id);
+       execlp(tapdisk, tapdisk, NULL);
 
-       execlp(tapdisk, tapdisk, "-u", uuid, "-c", control, NULL);
-
-       printf("exec failed\n");
+       EPRINTF("exec failed\n");
        exit(1);
 }
 
 pid_t
-_tap_ctl_get_pid(const int id)
+tap_ctl_get_pid(const int id)
 {
        int err;
        tapdisk_message_t message;
@@ -93,82 +98,77 @@ _tap_ctl_get_pid(const int id)
 }
 
 static int
-_tap_ctl_wait(pid_t child)
+tap_ctl_wait(pid_t child)
 {
        pid_t pid;
        int status;
 
        pid = waitpid(child, &status, 0);
        if (pid < 0) {
-               fprintf(stderr, "wait(%d) failed, err %d\n", child, errno);
+               EPRINTF("wait(%d) failed, err %d\n", child, errno);
                return -errno;
        }
 
        if (WIFEXITED(status)) {
                int code = WEXITSTATUS(status);
                if (code)
-                       fprintf(stderr, "tapdisk2[%d] failed, status %d\n", child, code);
+                       EPRINTF("tapdisk2[%d] failed, status %d\n", child, code);
                return -code;
        }
 
        if (WIFSIGNALED(status)) {
                int signo = WTERMSIG(status);
-               fprintf(stderr, "tapdisk2[%d] killed by signal %d\n", child, signo);
+               EPRINTF("tapdisk2[%d] killed by signal %d\n", child, signo);
                return -EINTR;
        }
 
-       fprintf(stderr, "tapdisk2[%d]: unexpected status %#x\n", child, status);
+       EPRINTF("tapdisk2[%d]: unexpected status %#x\n", child, status);
        return -EAGAIN;
 }
 
-
-int
-_tap_ctl_spawn(const int id)
+static int
+tap_ctl_get_child_id(int readfd)
 {
-       pid_t child, task;
-       int err;
+       int id;
+       FILE *f;
 
-       child = __tap_ctl_spawn(id);
-       if (child < 0)
-               return child;
-
-       err = _tap_ctl_wait(child);
-       if (err)
-               return err;
+       f = fdopen(readfd, "r");
+       if (!f) {
+               EPRINTF("fdopen failed: %d\n", errno);
+               return -1;
+       }
 
-       task = _tap_ctl_get_pid(id);
-       if (task < 0)
-               fprintf(stderr, "get_pid(%d) failed, err %d\n", child, errno);
+       errno = 0;
+       if (fscanf(f, BLKTAP2_CONTROL_DIR"/"
+                  BLKTAP2_CONTROL_SOCKET"%d", &id) != 1) {
+               errno = (errno ? : EINVAL);
+               EPRINTF("parsing id failed: %d\n", errno);
+               id = -1;
+       }
 
-       return task;
+       fclose(f);
+       return id;
 }
 
 int
-tap_ctl_spawn(int argc, char **argv)
+tap_ctl_spawn(void)
 {
-       int c, id;
-       pid_t task;
-
-       id = -1;
-
-       optind = 0;
-       while ((c = getopt(argc, argv, "i:h")) != -1) {
-               switch (c) {
-               case 'i':
-                       id = atoi(optarg);
-                       break;
-               case 'h':
-                       usage();
-                       return 0;
-               }
-       }
+       pid_t child;
+       int err, id, readfd;
 
-       if (id == -1) {
-               usage();
-               return EINVAL;
-       }
+       readfd = -1;
+
+       child = __tap_ctl_spawn(&readfd);
+       if (child < 0)
+               return child;
+
+       err = tap_ctl_wait(child);
+       if (err)
+               return err;
 
-       task = _tap_ctl_spawn(id);
+       id = tap_ctl_get_child_id(readfd);
+       if (id < 0)
+               EPRINTF("get_id failed, child %d err %d\n", child, errno);
 
-       return task < 0 ? task : 0;
+       return id;
 }
index 4a922f271e45eb8f5195d78d6c3ce8998bfa4939..dfb7450226e737a26e35f534cd4671894b2c09ad 100644 (file)
@@ -56,8 +56,8 @@ tap_ctl_unpause(const int id, const int minor, const char *params)
                err = message.u.response.error;
        else {
                err = EINVAL;
-               printf("got unexpected result '%s' from %d\n",
-                      tapdisk_message_name(message.type), id);
+               EPRINTF("got unexpected result '%s' from %d\n",
+                       tapdisk_message_name(message.type), id);
        }
 
        return err;
index a4a734028e0062afe774b8ffc0182d0158214f56..80fc933a895ae4be15987017c56c5cdce0de888d 100644 (file)
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include <stdio.h>
-#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <getopt.h>
 
 #include "tap-ctl.h"
@@ -44,14 +45,63 @@ static void
 tap_cli_list_usage(FILE *stream)
 {
        fprintf(stream,
-               "usage: list [-h] [-m minor] [-i id] [-p pid] [-t type] [-f file]\n");
+               "usage: list [-h] [-p pid] [-m minor] [-t type] [-f file]\n");
+}
+
+static void
+tap_ctl_list_row(tap_list_t *entry)
+{
+       char minor_str[10] = "-";
+       char state_str[10] = "-";
+       char pid_str[10]   = "-";
+
+       if (entry->pid != -1)
+               sprintf(pid_str, "%d", entry->pid);
+
+       if (entry->minor != -1)
+               sprintf(minor_str, "%d", entry->minor);
+
+       if (entry->state != -1)
+               sprintf(state_str, "%x", entry->state);
+
+       printf("%8s %2s %4s %10s %s\n",
+              pid_str, minor_str, state_str,
+              entry->type ? : "-", entry->path ? : "-");
+}
+
+static void
+tap_ctl_list_dict(tap_list_t *entry)
+{
+       int d = 0;
+
+       if (entry->pid != -1) {
+               if (d) putc(' ', stdout);
+               d = printf("pid=%d", entry->pid);
+       }
+
+       if (entry->minor != -1) {
+               if (d) putc(' ', stdout);
+               d = printf("minor=%d", entry->minor);
+       }
+
+       if (entry->state != -1) {
+               if (d) putc(' ', stdout);
+               d = printf("state=%d", entry->state);
+       }
+
+       if (entry->type && entry->path) {
+               if (d) putc(' ', stdout);
+               d = printf("args=%s:%s", entry->type, entry->path);
+       }
+
+       putc('\n', stdout);
 }
 
 int
 tap_cli_list(int argc, char **argv)
 {
        tap_list_t **list, **_entry;
-       int c, id, minor, err;
+       int c, minor, tty, err;
        const char *type, *file;
        pid_t pid;
 
@@ -59,17 +109,13 @@ tap_cli_list(int argc, char **argv)
        if (err)
                return -err;
 
-       id     = -1;
-       minor  = -1;
-       pid    = -1;
-       type   = NULL;
-       file   = NULL;
+       pid   = -1;
+       minor = -1;
+       type  = NULL;
+       file  = NULL;
 
-       while ((c = getopt(argc, argv, "m:i:p:t:f:h")) != -1) {
+       while ((c = getopt(argc, argv, "m:p:t:f:h")) != -1) {
                switch (c) {
-               case 'i':
-                       id = atoi(optarg);
-                       break;
                case 'm':
                        minor = atoi(optarg);
                        break;
@@ -82,21 +128,18 @@ tap_cli_list(int argc, char **argv)
                case 'f':
                        file = optarg;
                        break;
+               case '?':
+                       goto usage;
                case 'h':
                        tap_cli_list_usage(stdout);
                        return 0;
                }
        }
 
+       tty = isatty(STDOUT_FILENO);
+
        for (_entry = list; *_entry != NULL; ++_entry) {
                tap_list_t *entry  = *_entry;
-               char id_str[10]    = "-";
-               char minor_str[10] = "-";
-               char state_str[10] = "-";
-               char pid_str[10]   = "-";
-
-               if (id >= 0 && entry->id != id)
-                       continue;
 
                if (minor >= 0 && entry->minor != minor)
                        continue;
@@ -110,67 +153,387 @@ tap_cli_list(int argc, char **argv)
                if (file && entry->path && strcmp(entry->path, file))
                        continue;
 
-               if (entry->id != -1)
-                       sprintf(id_str, "%d", entry->id);
+               if (tty)
+                       tap_ctl_list_row(entry);
+               else
+                       tap_ctl_list_dict(entry);
+       }
 
-               if (entry->pid != -1)
-                       sprintf(pid_str, "%d", entry->pid);
+       tap_ctl_free_list(list);
 
-               if (entry->minor != -1)
-                       sprintf(minor_str, "%d", entry->minor);
+       return 0;
 
-               if (entry->state != -1)
-                       sprintf(state_str, "%x", entry->state);
+usage:
+       tap_cli_list_usage(stderr);
+       return EINVAL;
+}
 
-               printf("%-3s %2s %8s %4s %10s %s\n",
-                      minor_str, id_str, pid_str, state_str,
-                      entry->type ? : "-", entry->path ? : "-");
+static void
+tap_cli_allocate_usage(FILE *stream)
+{
+       fprintf(stream, "usage: allocate [-d device name]>\n");
+}
+
+static int
+tap_cli_allocate(int argc, char **argv)
+{
+       char *devname;
+       int c, minor, err;
+
+       devname = NULL;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "d:h")) != -1) {
+               switch (c) {
+               case 'd':
+                       devname = optarg;
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_allocate_usage(stdout);
+                       return 0;
+               }
        }
 
-       tap_ctl_free_list(list);
+       err = tap_ctl_allocate(&minor, &devname);
+       if (!err)
+               printf("%s\n", devname);
+
+       return err;
+
+usage:
+       tap_cli_allocate_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_free_usage(FILE *stream)
+{
+       fprintf(stream, "usage: free <-m minor>\n");
+}
+
+static int
+tap_cli_free(int argc, char **argv)
+{
+       int c, minor;
+
+       minor = -1;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "m:h")) != -1) {
+               switch (c) {
+               case 'm':
+                       minor = atoi(optarg);
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_free_usage(stdout);
+                       return 0;
+               }
+       }
+
+       if (minor == -1)
+               goto usage;
+
+       return tap_ctl_free(minor);
+
+usage:
+       tap_cli_free_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_create_usage(FILE *stream)
+{
+       fprintf(stream, "usage: create <-a args> [-d device name]\n");
+}
+
+static int
+tap_cli_create(int argc, char **argv)
+{
+       int c, err;
+       char *args, *devname;
+
+       args    = NULL;
+       devname = NULL;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "a:d:h")) != -1) {
+               switch (c) {
+               case 'a':
+                       args = optarg;
+                       break;
+               case 'd':
+                       devname = optarg;
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_create_usage(stdout);
+                       return 0;
+               }
+       }
+
+       if (!args)
+               goto usage;
+
+       err = tap_ctl_create(args, &devname);
+       if (!err)
+               printf("%s\n", devname);
+
+       return err;
+
+usage:
+       tap_cli_create_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_destroy_usage(FILE *stream)
+{
+       fprintf(stream, "usage: destroy <-p pid> <-m minor>\n");
+}
+
+static int
+tap_cli_destroy(int argc, char **argv)
+{
+       int c, pid, minor;
+
+       pid   = -1;
+       minor = -1;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "p:m:h")) != -1) {
+               switch (c) {
+               case 'p':
+                       pid = atoi(optarg);
+                       break;
+               case 'm':
+                       minor = atoi(optarg);
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_destroy_usage(stdout);
+                       return 0;
+               }
+       }
+
+       if (pid == -1 || minor == -1)
+               goto usage;
+
+       return tap_ctl_destroy(pid, minor);
+
+usage:
+       tap_cli_destroy_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_spawn_usage(FILE *stream)
+{
+       fprintf(stream, "usage: spawn\n");
+}
+
+static int
+tap_cli_spawn(int argc, char **argv)
+{
+       int c;
+       pid_t task;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "h")) != -1) {
+               switch (c) {
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_spawn_usage(stdout);
+                       return 0;
+               }
+       }
 
+       task = tap_ctl_spawn();
+       if (task < 0) {
+               printf("spawn failed: %d\n", errno);
+               return task;
+       }
+
+       printf("tapdisk spawned with pid %d\n", task);
        return 0;
 
 usage:
-       tap_cli_list_usage(stderr);
+       tap_cli_spawn_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_attach_usage(FILE *stream)
+{
+       fprintf(stream, "usage: attach <-p pid> <-m minor>\n");
+}
+
+static int
+tap_cli_attach(int argc, char **argv)
+{
+       int c, pid, minor;
+
+       pid   = -1;
+       minor = -1;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "p:m:h")) != -1) {
+               switch (c) {
+               case 'p':
+                       pid = atoi(optarg);
+                       break;
+               case 'm':
+                       minor = atoi(optarg);
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_attach_usage(stderr);
+                       return 0;
+               }
+       }
+
+       if (pid == -1 || minor == -1)
+               goto usage;
+
+       return tap_ctl_attach(pid, minor);
+
+usage:
+       tap_cli_attach_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_detach_usage(FILE *stream)
+{
+       fprintf(stream, "usage: detach <-p pid> <-m minor>\n");
+}
+
+static int
+tap_cli_detach(int argc, char **argv)
+{
+       int c, pid, minor;
+
+       pid   = -1;
+       minor = -1;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "p:m:h")) != -1) {
+               switch (c) {
+               case 'p':
+                       pid = atoi(optarg);
+                       break;
+               case 'm':
+                       minor = atoi(optarg);
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_detach_usage(stdout);
+                       return 0;
+               }
+       }
+
+       if (pid == -1 || minor == -1)
+               goto usage;
+
+       return tap_ctl_detach(pid, minor);
+
+usage:
+       tap_cli_detach_usage(stderr);
+       return EINVAL;
+}
+
+static void
+tap_cli_close_usage(FILE *stream)
+{
+       fprintf(stream, "usage: close <-p pid> <-m minor> [-f force]\n");
+}
+
+static int
+tap_cli_close(int argc, char **argv)
+{
+       int c, pid, minor, force;
+
+       pid   = -1;
+       minor = -1;
+       force = 0;
+
+       optind = 0;
+       while ((c = getopt(argc, argv, "p:m:fh")) != -1) {
+               switch (c) {
+               case 'p':
+                       pid = atoi(optarg);
+                       break;
+               case 'm':
+                       minor = atoi(optarg);
+                       break;
+               case 'f':
+                       force = -1;
+                       break;
+               case '?':
+                       goto usage;
+               case 'h':
+                       tap_cli_close_usage(stdout);
+                       return 0;
+               }
+       }
+
+       if (pid == -1 || minor == -1)
+               goto usage;
+
+       return tap_ctl_close(pid, minor, force);
+
+usage:
+       tap_cli_close_usage(stderr);
        return EINVAL;
 }
 
 static void
 tap_cli_pause_usage(FILE *stream)
 {
-       fprintf(stream, "usage: pause <-id> <-m minor>\n");
+       fprintf(stream, "usage: pause <-p pid> <-m minor>\n");
 }
 
 static int
 tap_cli_pause(int argc, char **argv)
 {
-       int c, id, minor;
+       int c, pid, minor;
 
-       id    = -1;
+       pid   = -1;
        minor = -1;
 
        optind = 0;
-       while ((c = getopt(argc, argv, "i:m:h")) != -1) {
+       while ((c = getopt(argc, argv, "p:m:h")) != -1) {
                switch (c) {
-               case 'i':
-                       id = atoi(optarg);
+               case 'p':
+                       pid = atoi(optarg);
                        break;
                case 'm':
                        minor = atoi(optarg);
                        break;
+               case '?':
+                       goto usage;
                case 'h':
                        tap_cli_pause_usage(stdout);
                        return 0;
                }
        }
 
-       if (id == -1 || minor == -1) {
-               tap_cli_pause_usage(stderr);
-               return EINVAL;
-       }
+       if (pid == -1 || minor == -1)
+               goto usage;
 
-       return tap_ctl_pause(id, minor);
+       return tap_ctl_pause(pid, minor);
+
+usage:
+       tap_cli_pause_usage(stderr);
+       return EINVAL;
 }
 
 static void
@@ -182,18 +545,18 @@ tap_cli_unpause_usage(FILE *stream)
 int
 tap_cli_unpause(int argc, char **argv)
 {
-       char *args;
-       int c, id, minor, type;
+       const char *args;
+       int c, pid, minor;
 
-       id    = -1;
+       pid   = -1;
        minor = -1;
        args  = NULL;
 
        optind = 0;
-       while ((c = getopt(argc, argv, "i:m:a:h")) != -1) {
+       while ((c = getopt(argc, argv, "p:m:a:h")) != -1) {
                switch (c) {
-               case 'i':
-                       id = atoi(optarg);
+               case 'p':
+                       pid = atoi(optarg);
                        break;
                case 'm':
                        minor = atoi(optarg);
@@ -201,16 +564,18 @@ tap_cli_unpause(int argc, char **argv)
                case 'a':
                        args = optarg;
                        break;
+               case '?':
+                       goto usage;
                case 'h':
                        tap_cli_unpause_usage(stdout);
                        return 0;
                }
        }
 
-       if (id == -1 || minor == -1)
+       if (pid == -1 || minor == -1)
                goto usage;
 
-       return tap_ctl_unpause(id, minor, args);
+       return tap_ctl_unpause(pid, minor, args);
 
 usage:
        tap_cli_unpause_usage(stderr);
@@ -220,7 +585,7 @@ usage:
 static void
 tap_cli_major_usage(FILE *stream)
 {
-       fprintf(stream, "usage: unpause <-i id> <-m minor> <-t type> <-f file>\n");
+       fprintf(stream, "usage: major [-h]\n");
 }
 
 static int
@@ -238,6 +603,8 @@ tap_cli_major(int argc, char **argv)
                case 'c':
                        chr = 1;
                        break;
+               case '?':
+                       goto usage;
                case 'h':
                        tap_cli_major_usage(stdout);
                        return 0;
@@ -266,24 +633,24 @@ usage:
 static void
 tap_cli_open_usage(FILE *stream)
 {
-       fprintf(stream, "usage: open <-id> <-m minor> <-a args>\n");
+       fprintf(stream, "usage: open <-p pid> <-m minor> <-a args>\n");
 }
 
 static int
 tap_cli_open(int argc, char **argv)
 {
        const char *args;
-       int c, id, minor;
+       int c, pid, minor;
 
-       id    = -1;
+       pid   = -1;
        minor = -1;
        args  = NULL;
 
        optind = 0;
-       while ((c = getopt(argc, argv, "i:m:a:h")) != -1) {
+       while ((c = getopt(argc, argv, "a:m:p:h")) != -1) {
                switch (c) {
-               case 'i':
-                       id = atoi(optarg);
+               case 'p':
+                       pid = atoi(optarg);
                        break;
                case 'm':
                        minor = atoi(optarg);
@@ -291,36 +658,65 @@ tap_cli_open(int argc, char **argv)
                case 'a':
                        args = optarg;
                        break;
+               case '?':
+                       goto usage;
                case 'h':
                        tap_cli_open_usage(stdout);
                        return 0;
                }
        }
 
-       if (id == -1 || minor == -1 || !args)
+       if (pid == -1 || minor == -1 || !args)
                goto usage;
 
-       return tap_ctl_open(id, minor, args);
+       return tap_ctl_open(pid, minor, args);
 
 usage:
        tap_cli_open_usage(stderr);
        return EINVAL;
 }
 
+static void
+tap_cli_check_usage(FILE *stream)
+{
+       fprintf(stream, "usage: check\n"
+               "(checks whether environment is suitable for tapdisk2)\n");
+}
+
+static int
+tap_cli_check(int argc, char **argv)
+{
+       int err;
+       const char *msg;
+
+       if (argc != 1)
+               goto usage;
+
+       err = tap_ctl_check(&msg);
+       printf("%s\n", msg);
+
+       return err;
+
+usage:
+       tap_cli_check_usage(stderr);
+       return EINVAL;
+}
+
 struct command commands[] = {
        { .name = "list",         .func = tap_cli_list          },
-       { .name = "allocate",     .func = tap_ctl_allocate      },
-       { .name = "free",         .func = tap_ctl_free          },
-       { .name = "create",       .func = tap_ctl_create        },
-       { .name = "destroy",      .func = tap_ctl_destroy       },
-       { .name = "spawn",        .func = tap_ctl_spawn         },
-       { .name = "attach",       .func = tap_ctl_attach        },
-       { .name = "detach",       .func = tap_ctl_detach        },
+       { .name = "allocate",     .func = tap_cli_allocate      },
+       { .name = "free",         .func = tap_cli_free          },
+       { .name = "create",       .func = tap_cli_create        },
+       { .name = "destroy",      .func = tap_cli_destroy       },
+       { .name = "spawn",        .func = tap_cli_spawn         },
+       { .name = "attach",       .func = tap_cli_attach        },
+       { .name = "detach",       .func = tap_cli_detach        },
        { .name = "open",         .func = tap_cli_open          },
-       { .name = "close",        .func = tap_ctl_close         },
+       { .name = "close",        .func = tap_cli_close         },
        { .name = "pause",        .func = tap_cli_pause         },
        { .name = "unpause",      .func = tap_cli_unpause       },
        { .name = "major",        .func = tap_cli_major         },
+       { .name = "check",        .func = tap_cli_check         },
 };
 
 #define print_commands()                                       \
@@ -363,6 +759,7 @@ int
 main(int argc, char *argv[])
 {
        char **cargv;
+       const char *msg;
        struct command *cmd;
        int cargc, i, cnt, ret;
 
@@ -372,7 +769,7 @@ main(int argc, char *argv[])
        rlim.rlim_cur = RLIM_INFINITY;
        rlim.rlim_max = RLIM_INFINITY;
        if (setrlimit(RLIMIT_CORE, &rlim) < 0)
-               fprintf(stderr, "setrlimit failed: %d\n", errno);
+               PERROR("setrlimit failed");
 #endif
 
        ret = 0;
@@ -383,10 +780,16 @@ main(int argc, char *argv[])
        cargc = argc - 1;
        cmd   = get_command(argv[1]);
        if (!cmd) {
-               fprintf(stderr, "invalid COMMAND %s\n", argv[1]);
+               EPRINTF("invalid COMMAND %s", argv[1]);
                help();
        }
 
+       ret = tap_ctl_check(&msg);
+       if (ret) {
+               printf("%s\n", msg);
+               return ret;
+       }
+
        cargv = malloc(sizeof(char *) * cargc);
        if (!cargv)
                exit(ENOMEM);
index dfb08f098aad3af1f69ef10d9fbf39e16a730f42..850f9f024b24b45685fe3fbef551e737150e1053 100644 (file)
 #define __TAP_CTL_H__
 
 #include <syslog.h>
+#include <errno.h>
 
 #include "tapdisk-message.h"
 
 extern int tap_ctl_debug;
 
+#ifdef TAPCTL
 #define DBG(_f, _a...)                         \
        do {                                    \
                if (tap_ctl_debug)              \
@@ -42,14 +44,24 @@ extern int tap_ctl_debug;
 
 #define DPRINTF(_f, _a...) syslog(LOG_INFO, _f, ##_a)
 #define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a)
+#define  PERROR(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f ": %s", __func__, ##_a, \
+                                 strerror(errno))
+#endif
+
+void tap_ctl_version(int *major, int *minor);
+int tap_ctl_kernel_version(int *major, int *minor);
 
+int tap_ctl_check_blktap(const char **message);
+int tap_ctl_check_version(const char **message);
+int tap_ctl_check(const char **message);
 
 int tap_ctl_connect(const char *path, int *socket);
 int tap_ctl_connect_id(int id, int *socket);
 int tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout);
 int tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout);
 int tap_ctl_send_and_receive(int fd, tapdisk_message_t *message, int timeout);
-int tap_ctl_connect_send_and_receive(int id, tapdisk_message_t *message, int timeout);
+int tap_ctl_connect_send_and_receive(int id,
+                                    tapdisk_message_t *message, int timeout);
 char *tap_ctl_socket_name(int id);
 
 typedef struct {
@@ -66,36 +78,23 @@ int tap_ctl_get_driver_id(const char *handle);
 int tap_ctl_list(tap_list_t ***list);
 void tap_ctl_free_list(tap_list_t **list);
 
-int tap_ctl_allocate(int argc, char **argv);
-int _tap_ctl_allocate(int *minor, char **devname);
-
-int tap_ctl_free(int argc, char **argv);
-int _tap_ctl_free(const int minor);
-
-int tap_ctl_create(int argc, char **argv);
-int _tap_ctl_create(const char *params, char **devname);
+int tap_ctl_allocate(int *minor, char **devname);
+int tap_ctl_free(const int minor);
 
-int tap_ctl_destroy(int argc, char **argv);
-int _tap_ctl_destroy(const int id, const int minor);
+int tap_ctl_create(const char *params, char **devname);
+int tap_ctl_destroy(const int id, const int minor);
 
-int tap_ctl_spawn(int argc, char **argv);
-int _tap_ctl_spawn(const int id);
-pid_t _tap_ctl_get_pid(const int id);
+int tap_ctl_spawn(void);
+pid_t tap_ctl_get_pid(const int id);
 
-int tap_ctl_attach(int argc, char **argv);
-int _tap_ctl_attach(const int id, const int minor);
-
-int tap_ctl_detach(int argc, char **argv);
-int _tap_ctl_detach(const int id, const int minor);
+int tap_ctl_attach(const int id, const int minor);
+int tap_ctl_detach(const int id, const int minor);
 
 int tap_ctl_open(const int id, const int minor, const char *params);
-
-int tap_ctl_close(int argc, char **argv);
-int _tap_ctl_close(const int id, const int minor, const int force);
+int tap_ctl_close(const int id, const int minor, const int force);
 
 int tap_ctl_pause(const int id, const int minor);
-
-int tap_ctl_unpause(const int id, const int minor, const char *args);
+int tap_ctl_unpause(const int id, const int minor, const char *params);
 
 int tap_ctl_blk_major(void);
 
index d3462a3ffd2d23b85c6706d5750eb020c35c115c..54d39079cca386a5cc04ee6e78ba0f8df1ca0fe4 100644 (file)
@@ -40,6 +40,7 @@
 #include <stdarg.h>
 #include <xs.h>
 
+#define TAPDISK
 #include "xs_api.h"
 #include "blktaplib.h"
 
index 76d7ba8b443febda2f21276dd343ed5c833d3352..95da0df98eddd58cf799731fa2313f51aa21477b 100644 (file)
@@ -13,6 +13,7 @@ CFLAGS    += -fno-strict-aliasing
 CFLAGS    += -I../include
 CFLAGS    += -D_GNU_SOURCE
 CFLAGS    += -DUSE_NFS_LOCKS
+CFLAGS    += -DTAPDISK
 
 LIBS      += -lrt
 
@@ -48,6 +49,7 @@ TAP-OBJS  += tapdisk-filter.o
 TAP-OBJS  += tapdisk-logfile.o
 TAP-OBJS  += tapdisk-log.o
 TAP-OBJS  += tapdisk-utils.o
+TAP-OBJS  += tapdisk-disktype.o
 TAP-OBJS  += tapdisk-syslog.o
 TAP-OBJS  += io-optimize.o
 TAP-OBJS  += lock.o
index d72dfbfeb949e6f17ca14a1fdab8db5cb4e3cc5a..7e250a08f452be3f6e9b4b8f3155d001d2e29630 100644 (file)
@@ -65,7 +65,6 @@ static struct tapdisk_control td_control;
 static void
 tapdisk_control_initialize(void)
 {
-       td_control.uuid     = -1;
        td_control.socket   = -1;
        td_control.event_id = -1;
 
@@ -91,10 +90,11 @@ static struct tapdisk_control_connection *
 tapdisk_control_allocate_connection(int fd)
 {
        struct tapdisk_control_connection *connection;
+       size_t sz;
 
        connection = calloc(1, sizeof(*connection));
        if (!connection) {
-               EPRINTF("failed to allocate new connection\n");
+               EPRINTF("calloc");
                return NULL;
        }
 
@@ -515,11 +515,6 @@ tapdisk_control_close_image(struct tapdisk_control_connection *connection,
                goto out;
        }
 
-       if (!vbd->name) {
-               err = -EBADF;
-               goto out;
-       }
-
        if (!list_empty(&vbd->pending_requests)) {
                err = -EAGAIN;
                goto out;
@@ -622,30 +617,6 @@ out:
        tapdisk_control_close_connection(connection);
 }
 
-static void
-tapdisk_control_close_vbd(struct tapdisk_control_connection *connection,
-                         tapdisk_message_t *request)
-{
-       int err;
-       td_vbd_t *vbd;
-       tapdisk_message_t response;
-
-       memset(&response, 0, sizeof(response));
-
-       response.type = TAPDISK_MESSAGE_CLOSE_RSP;
-
-       vbd = tapdisk_server_get_vbd(request->cookie);
-       if (!vbd)
-               err = EINVAL;
-       else
-               err = tapdisk_vbd_close(vbd);
-
-       response.cookie = (vbd ? vbd->uuid : -1);
-       response.u.response.error = err;
-       tapdisk_control_write_message(connection->socket, &response, 2);
-       tapdisk_control_close_connection(connection);
-}
-
 static void
 tapdisk_control_handle_request(event_id_t id, char mode, void *private)
 {
@@ -775,7 +746,7 @@ tapdisk_control_mkdir(const char *dir)
 }
 
 static int
-tapdisk_control_create_socket(const int uuid, const char *socket_path)
+tapdisk_control_create_socket(char **socket_path)
 {
        int err, flags;
        struct sockaddr_un saddr;
@@ -787,6 +758,20 @@ tapdisk_control_create_socket(const int uuid, const char *socket_path)
                return err;
        }
 
+       err = asprintf(&td_control.path, "%s/%s%d",
+                      BLKTAP2_CONTROL_DIR, BLKTAP2_CONTROL_SOCKET, getpid());
+       if (err == -1) {
+               td_control.path = NULL;
+               err = (errno ? : ENOMEM);
+               goto fail;
+       }
+
+       if (unlink(td_control.path) && errno != ENOENT) {
+               err = errno;
+               EPRINTF("failed to unlink %s: %d\n", td_control.path, errno);
+               goto fail;
+       }
+
        td_control.socket = socket(AF_UNIX, SOCK_STREAM, 0);
        if (td_control.socket == -1) {
                err = errno;
@@ -795,14 +780,14 @@ tapdisk_control_create_socket(const int uuid, const char *socket_path)
        }
 
        memset(&saddr, 0, sizeof(saddr));
-       strncpy(saddr.sun_path, socket_path, sizeof(saddr.sun_path));
+       strncpy(saddr.sun_path, td_control.path, sizeof(saddr.sun_path));
        saddr.sun_family = AF_UNIX;
 
        err = bind(td_control.socket,
                   (const struct sockaddr *)&saddr, sizeof(saddr));
        if (err == -1) {
                err = errno;
-               EPRINTF("failed to bind to %s: %d\n", socket_path, err);
+               EPRINTF("failed to bind to %s: %d\n", saddr.sun_path, err);
                goto fail;
        }
 
@@ -813,13 +798,6 @@ tapdisk_control_create_socket(const int uuid, const char *socket_path)
                goto fail;
        }
 
-       td_control.path = strdup(saddr.sun_path);
-       if (!td_control.path) {
-               err = errno;
-               EPRINTF("failed to dup socket path: %d\n", err);
-               goto fail_unlink;
-       }
-
        err = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
                                            td_control.socket, 0,
                                            tapdisk_control_accept, NULL);
@@ -828,26 +806,22 @@ tapdisk_control_create_socket(const int uuid, const char *socket_path)
                goto fail;
        }
 
-       td_control.uuid     = uuid;
        td_control.event_id = err;
+       *socket_path = td_control.path;
 
        return 0;
 
 fail:
        tapdisk_control_close();
        return err;
-
-fail_unlink:
-       unlink(saddr.sun_path);
-       goto fail;
 }
 
 int
-tapdisk_control_open(const int uuid, const char *control)
+tapdisk_control_open(char **path)
 {
        int err;
 
        tapdisk_control_initialize();
 
-       return tapdisk_control_create_socket(uuid, control);
+       return tapdisk_control_create_socket(path);
 }
index d3516817503fabeaf0e8ff2b42dd41706cadd059..10c18112f376e13c8fe2d0554b8add845cc06bb6 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef __TAPDISK_CONTROL_H__
 #define __TAPDISK_CONTROL_H__
 
-int tapdisk_control_open(const int uuid, const char *path);
+int tapdisk_control_open(char **path);
 void tapdisk_control_close(void);
 
 #endif
index 36f1583dbcc02172a7876150219a758341815b3b..2995e5fed7aeed2875b63e7228ae1fcbb09f64db 100644 (file)
@@ -63,7 +63,7 @@ td_load(td_image_t *image)
 }
 
 int
-td_open(td_image_t *image)
+__td_open(td_image_t *image, td_disk_info_t *info)
 {
        int err;
        td_driver_t *driver;
@@ -76,6 +76,9 @@ td_open(td_image_t *image)
                                                 image->storage);
                if (!driver)
                        return -ENOMEM;
+
+               if (info) /* pre-seed driver->info for virtual drivers */
+                       driver->info = *info;
        }
 
        if (!td_flag_test(driver->state, TD_DRIVER_OPEN)) {
@@ -98,6 +101,12 @@ td_open(td_image_t *image)
        return 0;
 }
 
+int
+td_open(td_image_t *image)
+{
+       return __td_open(image, NULL);
+}
+
 int
 td_close(td_image_t *image)
 {
index 2798ad93d312fced3b1fd894fb6548d99d1d38f6..4ee5424d2ceb8594392bd638dba83cce45a15bfc 100644 (file)
@@ -32,6 +32,7 @@
 #include "tapdisk-queue.h"
 
 int td_open(td_image_t *);
+int __td_open(td_image_t *, td_disk_info_t *);
 int td_load(td_image_t *);
 int td_close(td_image_t *);
 int td_get_parent_id(td_image_t *, td_disk_id_t *);
index c5e4d91154e3346576cbc37814ca960e11a141ed..e64789e44c7d4523011b9f463fa49ce8465cb363 100644 (file)
@@ -356,7 +356,6 @@ tapdisk_server_signal_handler(int signal)
                if (xfsz_error_sent)
                        break;
 
-               tapdisk_server_send_error("received SIGXFSZ, closing queues");
                xfsz_error_sent = 1;
                break;
 
@@ -370,7 +369,7 @@ tapdisk_server_signal_handler(int signal)
 int
 tapdisk_server_init(void)
 {
-
+       memset(&server, 0, sizeof(server));
        INIT_LIST_HEAD(&server.vbds);
 
        scheduler_initialize(&server.scheduler);
index 88ea4ca037eed98bbd421b336f4676fd87253715..f9848df2dd4cc92538765816ecbd64baada2b7df 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -38,9 +39,7 @@
 static void
 usage(const char *app, int err)
 {
-       fprintf(stderr,
-               "usage: %s [-h] [-l <syslog>] "
-               "-u <uuid> -c <control socket>\n", app);
+       fprintf(stderr, "usage: %s <-u uuid> <-c control socket>\n", app);
        exit(err);
 }
 
@@ -48,40 +47,29 @@ int
 main(int argc, char *argv[])
 {
        char *control;
-       int c, uuid, err, nodaemon;
-       const char *facility;
+       int c, err, nodaemon;
 
-       uuid     = -1;
        control  = NULL;
-       facility = "daemon";
        nodaemon = 0;
 
-       while ((c = getopt(argc, argv, "l:u:c:Dh")) != -1) {
+       while ((c = getopt(argc, argv, "Dh")) != -1) {
                switch (c) {
-               case 'l':
-                       facility = optarg;
-                       break;
-               case 'u':
-                       uuid = atoi(optarg);
-                       break;
-               case 'c':
-                       control = optarg;
-                       break;
                case 'D':
                        nodaemon = 1;
                        break;
                case 'h':
                        usage(argv[0], 0);
+                       break;
                default:
                        usage(argv[0], EINVAL);
                }
        }
 
-       if (optind != argc || uuid == -1 || !control)
+       if (optind != argc)
                usage(argv[0], EINVAL);
 
        chdir("/");
-       tapdisk_start_logging("tapdisk2", facility);
+       tapdisk_start_logging("tapdisk2", NULL);
 
        err = tapdisk_server_init();
        if (err) {
@@ -89,17 +77,33 @@ main(int argc, char *argv[])
                goto out;
        }
 
-       err = tapdisk_control_open(uuid, control);
+       if (!nodaemon) {
+               err = daemon(0, 1);
+               if (err) {
+                       DPRINTF("failed to daemonize: %d\n", errno);
+                       goto out;
+               }
+       }
+
+       err = tapdisk_control_open(&control);
        if (err) {
                DPRINTF("failed to open control socket: %d\n", err);
                goto out;
        }
 
+       fprintf(stdout, "%s\n", control);
+       fflush(stdout);
+
        if (!nodaemon) {
-               err = daemon(0, 0);
-               if (err) {
-                       DPRINTF("failed to daemonize: %d\n", errno);
-                       goto out;
+               int fd;
+
+               fd = open("/dev/null", O_RDWR);
+               if (fd != -1) {
+                       dup2(fd, STDIN_FILENO);
+                       dup2(fd, STDOUT_FILENO);
+                       dup2(fd, STDERR_FILENO);
+                       if (fd > 2)
+                               close(fd);
                }
        }
 
index 730f25e68b756f2d371b135507876889613ae0b0..fbc61057d0c086cb947d93f2ab62155410bc8e0c 100644 (file)
@@ -36,6 +36,7 @@
 #include <xenctrl.h>
 #include <xen/io/blkif.h>
 
+#ifdef TAPDISK
 #if 1
 #define DPRINTF(_f, _a...) syslog(LOG_INFO, _f, ##_a)
 #else
@@ -44,6 +45,7 @@
 
 #define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a)
 #define PERROR(_f, _a...)  EPRINTF(_f ": %s", ##_a, strerror(errno))
+#endif
 
 #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, XC_PAGE_SIZE)
 
index d9eb100bbef1f811b8aedc540e688231531d398e..2bfb4185e3ffadf25786b14ac7441e9cc5f65c40 100644 (file)
@@ -57,7 +57,6 @@ struct tapdisk_message_params {
        uint8_t                          storage;
        uint32_t                         devnum;
        uint32_t                         domid;
-       uint16_t                         path_len;
        char                             path[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
 };