* [PATCH 3 of 7] blktap2: Fix tapdisk disktype issues
2010-06-07 21:54 [PATCH 0 of 7] blktap2: The tap-ctl userspace control utility and library Daniel Stodden
2010-06-07 21:54 ` [PATCH 1 of 7] blktap2: Remove tapdisk-ipc module Daniel Stodden
2010-06-07 21:54 ` [PATCH 2 of 7] blktap2: Remove LVM hacks Daniel Stodden
@ 2010-06-07 21:54 ` Daniel Stodden
2010-06-07 21:54 ` [PATCH 4 of 7] blktap2: Fix E/DPRINTF defs all around the driver/ subdir Daniel Stodden
` (4 subsequent siblings)
7 siblings, 0 replies; 25+ messages in thread
From: Daniel Stodden @ 2010-06-07 21:54 UTC (permalink / raw)
To: Xen
[-- Attachment #1: Type: text/plain, Size: 302 bytes --]
Stop coercing drivers/disktype code into the tool stack. Make both
blktapctrl and tap-ctl transfer type/path pairs as "<type>:<path>"
strings. Remove the message.disktype integer altogether.
Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
Signed-off-by: Jake Wires <jake.wires@citrix.com>
[-- Attachment #2: disktypes.diff --]
[-- Type: text/x-patch, Size: 27672 bytes --]
# HG changeset patch
# User Daniel Stodden <daniel.stodden@citrix.com>
# Date 1275947595 25200
# Node ID 5f2119204138ad484ad7ffe0a8eff5c0d70d3f52
# Parent eb39271223ce6600cb81cf0dab8167a382d1393a
blktap2: Fix tapdisk disktype issues.
Stop coercing drivers/disktype code into the tool stack. Make both
blktapctrl and tap-ctl transfer type/path pairs as "<type>:<path>"
strings. Remove the message.disktype integer altogether.
Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
Signed-off-by: Jake Wires <jake.wires@citrix.com>
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/Makefile
--- a/tools/blktap2/drivers/Makefile Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/Makefile Mon Jun 07 14:53:15 2010 -0700
@@ -77,6 +77,7 @@
TAP-OBJS-y += tapdisk-vbd.o
TAP-OBJS-y += tapdisk-image.o
TAP-OBJS-y += tapdisk-driver.o
+TAP-OBJS-y += tapdisk-disktype.o
TAP-OBJS-y += tapdisk-interface.o
TAP-OBJS-y += tapdisk-server.o
TAP-OBJS-y += tapdisk-queue.o
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/block-qcow.c
--- a/tools/blktap2/drivers/block-qcow.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/block-qcow.c Mon Jun 07 14:53:15 2010 -0700
@@ -41,6 +41,7 @@
#include "tapdisk.h"
#include "tapdisk-driver.h"
#include "tapdisk-interface.h"
+#include "tapdisk-disktype.h"
#include "qcow.h"
#include "blk.h"
#include "atomicio.h"
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/block-remus.c
--- a/tools/blktap2/drivers/block-remus.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/block-remus.c Mon Jun 07 14:53:15 2010 -0700
@@ -98,6 +98,7 @@
*/
td_vbd_t *device_vbd = NULL;
td_image_t *remus_image = NULL;
+struct tap_disk tapdisk_remus;
struct ramdisk {
size_t sector_size;
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/block-vhd.c
--- a/tools/blktap2/drivers/block-vhd.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/block-vhd.c Mon Jun 07 14:53:15 2010 -0700
@@ -58,6 +58,7 @@
#include "tapdisk.h"
#include "tapdisk-driver.h"
#include "tapdisk-interface.h"
+#include "tapdisk-disktype.h"
unsigned int SPB;
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/disktypes.h
--- a/tools/blktap2/drivers/disktypes.h Mon Jun 07 14:53:15 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2007, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DISKTYPES_H__
-#define __DISKTYPES_H__
-
-typedef struct disk_info {
- int idnum;
- char name[50]; /* e.g. "RAMDISK" */
- char handle[10]; /* xend handle, e.g. 'ram' */
- int single_handler; /* is there a single controller for all */
- /* instances of disk type? */
-#ifdef TAPDISK
- struct tap_disk *drv;
-#endif
-} disk_info_t;
-
-extern struct tap_disk tapdisk_aio;
-/* extern struct tap_disk tapdisk_sync; */
-/* extern struct tap_disk tapdisk_vmdk; */
-/* extern struct tap_disk tapdisk_vhdsync; */
-extern struct tap_disk tapdisk_vhd;
-extern struct tap_disk tapdisk_ram;
- extern struct tap_disk tapdisk_qcow;
-extern struct tap_disk tapdisk_block_cache;
-extern struct tap_disk tapdisk_log;
-extern struct tap_disk tapdisk_remus;
-
-#define MAX_DISK_TYPES 20
-
-#define DISK_TYPE_AIO 0
-#define DISK_TYPE_SYNC 1
-#define DISK_TYPE_VMDK 2
-#define DISK_TYPE_VHDSYNC 3
-#define DISK_TYPE_VHD 4
-#define DISK_TYPE_RAM 5
-#define DISK_TYPE_QCOW 6
-#define DISK_TYPE_BLOCK_CACHE 7
-#define DISK_TYPE_LOG 9
-#define DISK_TYPE_REMUS 10
-
-/*Define Individual Disk Parameters here */
-static disk_info_t null_disk = {
- -1,
- "null disk",
- "null",
- 0,
-#ifdef TAPDISK
- 0,
-#endif
-};
-
-static disk_info_t aio_disk = {
- DISK_TYPE_AIO,
- "raw image (aio)",
- "aio",
- 0,
-#ifdef TAPDISK
- &tapdisk_aio,
-#endif
-};
-/*
-static disk_info_t sync_disk = {
- DISK_TYPE_SYNC,
- "raw image (sync)",
- "sync",
- 0,
-#ifdef TAPDISK
- &tapdisk_sync,
-#endif
-};
-
-static disk_info_t vmdk_disk = {
- DISK_TYPE_VMDK,
- "vmware image (vmdk)",
- "vmdk",
- 1,
-#ifdef TAPDISK
- &tapdisk_vmdk,
-#endif
-};
-
-static disk_info_t vhdsync_disk = {
- DISK_TYPE_VHDSYNC,
- "virtual server image (vhd) - synchronous",
- "vhdsync",
- 1,
-#ifdef TAPDISK
- &tapdisk_vhdsync,
-#endif
-};
-*/
-
-static disk_info_t vhd_disk = {
- DISK_TYPE_VHD,
- "virtual server image (vhd)",
- "vhd",
- 0,
-#ifdef TAPDISK
- &tapdisk_vhd,
-#endif
-};
-
-
-static disk_info_t ram_disk = {
- DISK_TYPE_RAM,
- "ramdisk image (ram)",
- "ram",
- 1,
-#ifdef TAPDISK
- &tapdisk_ram,
-#endif
-};
-
-
-static disk_info_t qcow_disk = {
- DISK_TYPE_QCOW,
- "qcow disk (qcow)",
- "qcow",
- 0,
-#ifdef TAPDISK
- &tapdisk_qcow,
-#endif
-};
-
-
-static disk_info_t block_cache_disk = {
- DISK_TYPE_BLOCK_CACHE,
- "block cache image (bc)",
- "bc",
- 1,
-#ifdef TAPDISK
- &tapdisk_block_cache,
-#endif
-};
-
-static disk_info_t log_disk = {
- DISK_TYPE_LOG,
- "write logger (log)",
- "log",
- 0,
-#ifdef TAPDISK
- &tapdisk_log,
-#endif
-};
-
-static disk_info_t remus_disk = {
- DISK_TYPE_REMUS,
- "remus disk replicator (remus)",
- "remus",
- 0,
-#ifdef TAPDISK
- &tapdisk_remus,
-#endif
-};
-
-/*Main disk info array */
-static disk_info_t *dtypes[] = {
- &aio_disk,
- &null_disk, /* &sync_disk, */
- &null_disk, /* &vmdk_disk, */
- &null_disk, /* &vhdsync_disk, */
- &vhd_disk,
- &ram_disk,
- &qcow_disk,
- &block_cache_disk,
- &null_disk,
- &log_disk,
- &remus_disk,
-};
-
-#endif
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/img2qcow.c
--- a/tools/blktap2/drivers/img2qcow.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/img2qcow.c Mon Jun 07 14:53:15 2010 -0700
@@ -49,6 +49,7 @@
#include "tapdisk-server.h"
#include "tapdisk-driver.h"
#include "tapdisk-interface.h"
+#include "tapdisk-disktype.h"
#include "qcow.h"
#include "blk.h"
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/qcow2raw.c
--- a/tools/blktap2/drivers/qcow2raw.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/qcow2raw.c Mon Jun 07 14:53:15 2010 -0700
@@ -47,6 +47,7 @@
#include "tapdisk-server.h"
#include "tapdisk-driver.h"
#include "tapdisk-interface.h"
+#include "tapdisk-disktype.h"
#include "qcow.h"
#if 1
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-diff.c
--- a/tools/blktap2/drivers/tapdisk-diff.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-diff.c Mon Jun 07 14:53:15 2010 -0700
@@ -38,6 +38,7 @@
#include "scheduler.h"
#include "tapdisk-vbd.h"
#include "tapdisk-server.h"
+#include "tapdisk-disktype.h"
#include "libvhd.h"
#define POLL_READ 0
@@ -670,11 +671,11 @@
tapdisk_stream_open(struct tapdisk_stream *s, const char *arg)
{
int err, type;
- char *path;
+ const char *path;
- err = tapdisk_parse_disk_type(arg, &path, &type);
- if (err)
- return err;
+ type = tapdisk_disktype_parse_params(arg, &path);
+ if (type < 0)
+ return type;
tapdisk_stream_initialize(s);
@@ -716,7 +717,8 @@
{
int c, err, type1;
const char *arg1 = NULL, *arg2 = NULL;
- char *path1;
+ const disk_info_t *info;
+ const char *path1;
err = 0;
@@ -741,9 +743,10 @@
if (!arg1 || !arg2)
goto fail_usage;
- err = tapdisk_parse_disk_type(arg1, &path1, &type1);
- if (err)
- return err;
+ type1 = tapdisk_disktype_parse_params(arg1, &path1);
+ if (type1 < 0)
+ return type1;
+
if (type1 != DISK_TYPE_VHD) {
printf("error: first VDI is not VHD\n");
return EINVAL;
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-disktype.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/drivers/tapdisk-disktype.c Mon Jun 07 14:53:15 2010 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2007, 2010, 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 <stddef.h>
+#include <string.h>
+#include <errno.h>
+
+#include "tapdisk-disktype.h"
+#include "tapdisk-message.h"
+
+static const disk_info_t aio_disk = {
+ "aio",
+ "raw image (aio)",
+ 0,
+};
+
+static const disk_info_t sync_disk = {
+ "sync",
+ "raw image (sync)",
+ 0,
+};
+
+static const disk_info_t vmdk_disk = {
+ "vmdk",
+ "vmware image (vmdk)",
+ 1,
+};
+
+static const disk_info_t vhdsync_disk = {
+ "vhdsync",
+ "virtual server image (vhd) - synchronous",
+ 1,
+};
+
+static const disk_info_t vhd_disk = {
+ "vhd",
+ "virtual server image (vhd)",
+ 0,
+};
+
+
+static const disk_info_t ram_disk = {
+ "ram",
+ "ramdisk image (ram)",
+ 1,
+};
+
+static const disk_info_t qcow_disk = {
+ "qcow",
+ "qcow disk (qcow)",
+ 0,
+};
+
+static const disk_info_t block_cache_disk = {
+ "bc",
+ "block cache image (bc)",
+ 1,
+};
+
+static const disk_info_t vhd_index_disk = {
+ "vhdi",
+ "vhd index image (vhdi)",
+ 1,
+};
+
+static const disk_info_t log_disk = {
+ "log",
+ "write logger (log)",
+ 0,
+};
+
+static disk_info_t remus_disk = {
+ "remus disk replicator (remus)",
+ "remus",
+ 0,
+};
+
+const disk_info_t *tapdisk_disk_types[] = {
+ [DISK_TYPE_AIO] = &aio_disk,
+ [DISK_TYPE_SYNC] = &sync_disk,
+ [DISK_TYPE_VMDK] = &vmdk_disk,
+ [DISK_TYPE_VHDSYNC] = &vhdsync_disk,
+ [DISK_TYPE_VHD] = &vhd_disk,
+ [DISK_TYPE_RAM] = &ram_disk,
+ [DISK_TYPE_QCOW] = &qcow_disk,
+ [DISK_TYPE_BLOCK_CACHE] = &block_cache_disk,
+ [DISK_TYPE_LOG] = &log_disk,
+ [DISK_TYPE_VINDEX] = &vhd_index_disk,
+ [DISK_TYPE_REMUS] = &remus_disk,
+ 0,
+};
+
+extern struct tap_disk tapdisk_aio;
+extern struct tap_disk tapdisk_sync;
+extern struct tap_disk tapdisk_vmdk;
+extern struct tap_disk tapdisk_vhdsync;
+extern struct tap_disk tapdisk_vhd;
+extern struct tap_disk tapdisk_ram;
+extern struct tap_disk tapdisk_qcow;
+extern struct tap_disk tapdisk_block_cache;
+extern struct tap_disk tapdisk_vhd_index;
+extern struct tap_disk tapdisk_log;
+extern struct tap_disk tapdisk_remus;
+
+const struct tap_disk *tapdisk_disk_drivers[] = {
+ [DISK_TYPE_AIO] = &tapdisk_aio,
+#if 0
+ [DISK_TYPE_SYNC] = &tapdisk_sync,
+ [DISK_TYPE_VMDK] = &tapdisk_vmdk,
+#endif
+ [DISK_TYPE_VHD] = &tapdisk_vhd,
+ [DISK_TYPE_RAM] = &tapdisk_ram,
+ [DISK_TYPE_QCOW] = &tapdisk_qcow,
+ [DISK_TYPE_BLOCK_CACHE] = &tapdisk_block_cache,
+ [DISK_TYPE_VINDEX] = &tapdisk_vhd_index,
+ [DISK_TYPE_LOG] = &tapdisk_log,
+ [DISK_TYPE_REMUS] = &tapdisk_remus,
+ 0,
+};
+
+int
+tapdisk_disktype_find(const char *name)
+{
+ const disk_info_t *info;
+ int i;
+
+ for (i = 0; info = tapdisk_disk_types[i], info != NULL; ++i) {
+ if (strcmp(name, info->name))
+ continue;
+
+ if (!tapdisk_disk_drivers[i])
+ return -ENOSYS;
+
+ return i;
+ }
+
+ return -ENOENT;
+}
+
+int
+tapdisk_disktype_parse_params(const char *params, const char **_path)
+{
+ char name[DISK_TYPE_NAME_MAX], *ptr;
+ size_t len;
+ int type;
+
+ ptr = strchr(params, ':');
+ if (!ptr)
+ return -EINVAL;
+
+ len = ptr - params;
+
+ if (len > sizeof(name) - 1)
+ return -ENAMETOOLONG;
+
+ memset(name, 0, sizeof(name));
+ strncpy(name, params, len);
+
+ type = tapdisk_disktype_find(name);
+
+ if (type >= 0)
+ *_path = params + len + 1;
+
+ return type;
+}
+
+int
+tapdisk_parse_disk_type(const char *params, const char **_path, int *_type)
+{
+ int type;
+
+ type = tapdisk_disktype_parse_params(params, _path);
+ if (type < 0)
+ return type;
+
+ *_type = type;
+
+ return 0;
+}
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-disktype.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/drivers/tapdisk-disktype.h Mon Jun 07 14:53:15 2010 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007, 2010, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DISKTYPES_H__
+#define __DISKTYPES_H__
+
+#define DISK_TYPE_AIO 0
+#define DISK_TYPE_SYNC 1
+#define DISK_TYPE_VMDK 2
+#define DISK_TYPE_VHDSYNC 3
+#define DISK_TYPE_VHD 4
+#define DISK_TYPE_RAM 5
+#define DISK_TYPE_QCOW 6
+#define DISK_TYPE_BLOCK_CACHE 7
+#define DISK_TYPE_LOG 9
+#define DISK_TYPE_REMUS 10
+#define DISK_TYPE_VINDEX 11
+
+#define DISK_TYPE_NAME_MAX 32
+
+typedef struct disk_info {
+ const char *name; /* driver name, e.g. 'aio' */
+ char *desc; /* e.g. "raw image" */
+ unsigned int flags;
+} disk_info_t;
+
+extern const disk_info_t *tapdisk_disk_types[];
+extern const struct tap_disk *tapdisk_disk_drivers[];
+
+/* one single controller for all instances of disk type */
+#define DISK_TYPE_SINGLE_CONTROLLER (1<<0)
+
+int tapdisk_disktype_find(const char *name);
+int tapdisk_disktype_parse_params(const char *params, const char **_path);
+int tapdisk_parse_disk_type(const char *, const char **, int *);
+
+#endif
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-driver.c
--- a/tools/blktap2/drivers/tapdisk-driver.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-driver.c Mon Jun 07 14:53:15 2010 -0700
@@ -29,15 +29,16 @@
#include "tapdisk-driver.h"
#include "tapdisk-server.h"
+#include "tapdisk-disktype.h"
td_driver_t *
tapdisk_driver_allocate(int type, char *name, td_flag_t flags, int storage)
{
int err;
td_driver_t *driver;
- struct tap_disk *ops;
+ const struct tap_disk *ops;
- ops = tapdisk_server_find_driver_interface(type);
+ ops = tapdisk_disk_drivers[type];
if (!ops)
return NULL;
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-driver.h
--- a/tools/blktap2/drivers/tapdisk-driver.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-driver.h Mon Jun 07 14:53:15 2010 -0700
@@ -47,7 +47,7 @@
td_disk_info_t info;
void *data;
- struct tap_disk *ops;
+ const struct tap_disk *ops;
struct list_head next;
};
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-image.c
--- a/tools/blktap2/drivers/tapdisk-image.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-image.c Mon Jun 07 14:53:15 2010 -0700
@@ -39,7 +39,7 @@
#define ERR(_err, _f, _a...) tlog_error(_err, _f, ##_a)
td_image_t *
-tapdisk_image_allocate(char *file, int type, int storage,
+tapdisk_image_allocate(const char *file, int type, int storage,
td_flag_t flags, void *private)
{
int err;
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-image.h
--- a/tools/blktap2/drivers/tapdisk-image.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-image.h Mon Jun 07 14:53:15 2010 -0700
@@ -47,7 +47,7 @@
struct list_head next;
};
-td_image_t *tapdisk_image_allocate(char *, int, int, td_flag_t, void *);
+td_image_t *tapdisk_image_allocate(const char *, int, int, td_flag_t, void *);
void tapdisk_image_free(td_image_t *);
int tapdisk_image_check_td_request(td_image_t *, td_request_t);
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-server.c
--- a/tools/blktap2/drivers/tapdisk-server.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-server.c Mon Jun 07 14:53:15 2010 -0700
@@ -32,7 +32,6 @@
#include <sys/ioctl.h>
#include <sys/signal.h>
-#define TAPDISK
#include "tapdisk-utils.h"
#include "tapdisk-server.h"
#include "tapdisk-driver.h"
@@ -46,18 +45,6 @@
#define tapdisk_server_for_each_vbd(vbd, tmp) \
list_for_each_entry_safe(vbd, tmp, &server.vbds, next)
-struct tap_disk *
-tapdisk_server_find_driver_interface(int type)
-{
- int n;
-
- n = sizeof(dtypes) / sizeof(struct disk_info_t *);
- if (type >= n)
- return NULL;
-
- return dtypes[type]->drv;
-}
-
td_image_t *
tapdisk_server_get_shared_image(td_image_t *image)
{
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-stream.c
--- a/tools/blktap2/drivers/tapdisk-stream.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-stream.c Mon Jun 07 14:53:15 2010 -0700
@@ -37,6 +37,7 @@
#include "scheduler.h"
#include "tapdisk-vbd.h"
#include "tapdisk-server.h"
+#include "tapdisk-disktype.h"
#define POLL_READ 0
#define POLL_WRITE 1
@@ -545,7 +546,9 @@
main(int argc, char *argv[])
{
int c, err, type;
- char *params, *path;
+ const char *params;
+ const disk_info_t *info;
+ const char *path;
uint64_t count, skip;
struct tapdisk_stream stream;
@@ -575,8 +578,9 @@
if (!params)
usage(argv[0], EINVAL);
- err = tapdisk_parse_disk_type(params, &path, &type);
- if (err) {
+ type = tapdisk_disktype_parse_params(params, &path);
+ if (type < 0) {
+ err = type;
fprintf(stderr, "invalid argument %s: %d\n", params, err);
return err;
}
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-utils.c
--- a/tools/blktap2/drivers/tapdisk-utils.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-utils.c Mon Jun 07 14:53:15 2010 -0700
@@ -40,7 +40,6 @@
#include "blk.h"
#include "tapdisk.h"
-#include "disktypes.h"
#include "blktaplib.h"
#include "tapdisk-log.h"
#include "tapdisk-utils.h"
@@ -108,45 +107,6 @@
return 0;
}
-int
-tapdisk_parse_disk_type(const char *params, char **_path, int *_type)
-{
- int i, err, size, handle_len;
- char *ptr, *path, handle[10];
-
- if (strlen(params) + 1 >= MAX_NAME_LEN)
- return -ENAMETOOLONG;
-
- ptr = strchr(params, ':');
- if (!ptr)
- return -EINVAL;
-
- path = ptr + 1;
-
- handle_len = ptr - params;
- if (handle_len > sizeof(handle))
- return -ENAMETOOLONG;
-
- memcpy(handle, params, handle_len);
- handle[handle_len] = '\0';
-
- size = sizeof(dtypes) / sizeof(disk_info_t *);
- for (i = 0; i < size; i++) {
- if (strncmp(handle, dtypes[i]->handle, handle_len))
- continue;
-
- if (dtypes[i]->idnum == -1)
- return -ENODEV;
-
- *_type = dtypes[i]->idnum;
- *_path = path;
-
- return 0;
- }
-
- return -ENODEV;
-}
-
/*Get Image size, secsize*/
int
tapdisk_get_image_size(int fd, uint64_t *_sectors, uint32_t *_sector_size)
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-utils.h
--- a/tools/blktap2/drivers/tapdisk-utils.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-utils.h Mon Jun 07 14:53:15 2010 -0700
@@ -36,7 +36,6 @@
void tapdisk_stop_logging(void);
int tapdisk_set_resource_limits(void);
int tapdisk_namedup(char **, const char *);
-int tapdisk_parse_disk_type(const char *, char **, int *);
int tapdisk_get_image_size(int, uint64_t *, uint32_t *);
int tapdisk_linux_version(void);
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-vbd.c
--- a/tools/blktap2/drivers/tapdisk-vbd.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-vbd.c Mon Jun 07 14:53:15 2010 -0700
@@ -43,6 +43,7 @@
#include "tapdisk-driver.h"
#include "tapdisk-server.h"
#include "tapdisk-interface.h"
+#include "tapdisk-disktype.h"
#include "tapdisk-vbd.h"
#include "blktap2.h"
@@ -282,9 +283,9 @@
/* TODO: ugh, lets not call it parent info... */
static struct list_head *
-tapdisk_vbd_open_level(td_vbd_t *vbd, char* params, int driver_type, td_disk_info_t *parent_info, td_flag_t flags)
+tapdisk_vbd_open_level(td_vbd_t *vbd, const char* params, int driver_type, td_disk_info_t *parent_info, td_flag_t flags)
{
- char *name;
+ const char *name;
int type, err;
td_image_t *image;
td_disk_id_t id;
@@ -294,19 +295,16 @@
images = calloc(1, sizeof(struct list_head));
INIT_LIST_HEAD(images);
- name = params;
- type = driver_type;
+ name = params;
+ id.name = NULL;
+ type = driver_type;
for (;;) {
err = -ENOMEM;
image = tapdisk_image_allocate(name, type,
vbd->storage, flags, vbd);
- /* free 'name' if it was created by td_get_parent_id() */
- if (name != params) {
- free(name);
- name = NULL;
- }
+ free(id.name);
if (!image)
return NULL;
@@ -382,7 +380,7 @@
static int
__tapdisk_vbd_open_vdi(td_vbd_t *vbd, td_flag_t extra_flags)
{
- char *file;
+ const char *file;
int err, type;
td_flag_t flags;
td_disk_id_t id;
@@ -524,9 +522,9 @@
uint16_t drivertype, uint16_t storage, td_flag_t flags)
{
int i, err;
- struct tap_disk *ops;
+ const struct tap_disk *ops;
- ops = tapdisk_server_find_driver_interface(drivertype);
+ ops = tapdisk_disk_drivers[drivertype];
if (!ops)
return -EINVAL;
DPRINTF("Loaded %s driver for vbd %u %s 0x%08x\n",
@@ -1573,7 +1571,8 @@
tapdisk_vbd_resume_ring(td_vbd_t *vbd)
{
int i, err, type;
- char *path, message[BLKTAP2_MAX_MESSAGE_LEN];
+ char message[BLKTAP2_MAX_MESSAGE_LEN];
+ const char *path;
memset(message, 0, sizeof(message));
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk-vbd.h
--- a/tools/blktap2/drivers/tapdisk-vbd.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-vbd.h Mon Jun 07 14:53:15 2010 -0700
@@ -80,7 +80,7 @@
};
struct td_vbd_driver_info {
- char *params;
+ const char *params;
int type;
struct list_head next;
};
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk.h
--- a/tools/blktap2/drivers/tapdisk.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk.h Mon Jun 07 14:53:15 2010 -0700
@@ -61,7 +61,6 @@
#include "list.h"
#include "blktaplib.h"
-#include "disktypes.h"
#include "tapdisk-log.h"
#include "tapdisk-utils.h"
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/drivers/tapdisk2.c
--- a/tools/blktap2/drivers/tapdisk2.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk2.c Mon Jun 07 14:53:15 2010 -0700
@@ -43,6 +43,7 @@
#include "tapdisk-vbd.h"
#include "tapdisk-utils.h"
#include "tapdisk-server.h"
+#include "tapdisk-disktype.h"
#define TAPDISK2_VBD 0
@@ -327,7 +328,7 @@
static int
tapdisk2_create_device(const char *params)
{
- char *path;
+ const char *path;
int err, type;
chdir("/");
diff -r eb39271223ce -r 5f2119204138 tools/blktap2/include/tapdisk-message.h
--- a/tools/blktap2/include/tapdisk-message.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/include/tapdisk-message.h Mon Jun 07 14:53:15 2010 -0700
@@ -28,6 +28,7 @@
#define _TAPDISK_MESSAGE_H_
#include <inttypes.h>
+#include <sys/types.h>
#define TAPDISK_MESSAGE_MAX_PATH_LENGTH 256
#define TAPDISK_MESSAGE_STRING_LENGTH 256
@@ -67,7 +68,6 @@
struct tapdisk_message {
uint16_t type;
uint16_t cookie;
- uint16_t drivertype;
union {
pid_t tapdisk_pid;
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 25+ messages in thread* [PATCH 6 of 7] blktap2: The tap-ctl userspace control utility and library
2010-06-07 21:54 [PATCH 0 of 7] blktap2: The tap-ctl userspace control utility and library Daniel Stodden
` (4 preceding siblings ...)
2010-06-07 21:54 ` [PATCH 5 of 7] blktap2: Cleanup vdi stacking code Daniel Stodden
@ 2010-06-07 21:54 ` Daniel Stodden
2010-06-07 21:54 ` [PATCH 7 of 7] blktap2: Port Xend to the tap-ctl interface Daniel Stodden
2010-08-03 19:14 ` [PATCH 0 of 7] blktap2: The tap-ctl userspace control utility and library Łukasz Oleś
7 siblings, 0 replies; 25+ messages in thread
From: Daniel Stodden @ 2010-06-07 21:54 UTC (permalink / raw)
To: Xen
[-- Attachment #1: Type: text/plain, Size: 670 bytes --]
Tapdisk control in userspace, a replacement for the original blktap2
control stack, which had to pass a kernel space interface based on
sysfs nodes.
All tapdisk processes listen for commands on a unix stream socket. The
control library supports scanning the socket namespace for running
tapdisks, VBD minors allocated, associated images and state inquiry.
Control operations include allocating/releasing devices, spawning
tapdisks, opening/closing images, attaching disk images to
devices. disk pause/resume operations and runtime switching of disk
images.
Signed-off-by: Jake Wires <jake.wires@citrix.com>
Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
[-- Attachment #2: tap-ctl.diff --]
[-- Type: text/x-patch, Size: 126743 bytes --]
# HG changeset patch
# User Daniel Stodden <daniel.stodden@citrix.com>
# Date 1275947596 25200
# Node ID ccef87cf5f4125061e46c7eb0d1483e6f369fb77
# Parent 3ea1751e3fe79c53acec392ee060b34491925235
blktap2: The tap-ctl userspace control utility and library.
Tapdisk control in userspace, a replacement for the original blktap2
control stack, which had to pass a kernel space interface based on
sysfs nodes.
All tapdisk processes listen for commands on a unix stream socket. The
control library supports scanning the socket namespace for running
tapdisks, VBD minors allocated, associated images and state inquiry.
Control operations include allocating/releasing devices, spawning
tapdisks, opening/closing images, attaching disk images to
devices. disk pause/resume operations and runtime switching of disk
images.
Signed-off-by: Jake Wires <jake.wires@citrix.com>
Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/Makefile
--- a/tools/blktap2/Makefile Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/Makefile Mon Jun 07 14:53:16 2010 -0700
@@ -9,6 +9,7 @@
SUBDIRS-y += lvm
SUBDIRS-y += vhd
SUBDIRS-y += drivers
+SUBDIRS-y += control
clean:
rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) TAGS
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/Makefile Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,57 @@
+XEN_ROOT := ../../../
+include $(XEN_ROOT)/tools/Rules.mk
+
+IBIN = tap-ctl
+INST_DIR = /usr/sbin
+
+CFLAGS += -Werror
+CFLAGS += -Wno-unused
+CFLAGS += -I../include -I../drivers
+CFLAGS += -I$(XEN_INCLUDE) -I$(XEN_LIBXC)
+CFLAGS += -D_GNU_SOURCE
+CFLAGS += -DTAPCTL
+
+# Get gcc to generate the dependencies for us.
+CFLAGS += -Wp,-MD,.$(@F).d
+DEPS = .*.d
+
+CTL_OBJS := tap-ctl-ipc.o
+CTL_OBJS += tap-ctl-list.o
+CTL_OBJS += tap-ctl-allocate.o
+CTL_OBJS += tap-ctl-free.o
+CTL_OBJS += tap-ctl-create.o
+CTL_OBJS += tap-ctl-destroy.o
+CTL_OBJS += tap-ctl-spawn.o
+CTL_OBJS += tap-ctl-attach.o
+CTL_OBJS += tap-ctl-detach.o
+CTL_OBJS += tap-ctl-open.o
+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
+
+all: build
+
+build: $(IBIN)
+
+tap-ctl: tap-ctl.o libblktapctl.a
+ $(CC) $(CFLAGS) -o $@ $^
+
+libblktapctl.a: $(CTL_OBJS)
+ ar r $@ $^
+
+install: all
+ $(INSTALL_DIR) -p $(DESTDIR)$(INST_DIR)
+ $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(INST_DIR)
+
+clean:
+ rm -f $(OBJS) $(DEPS) $(IBIN) $(LIBS)
+ rm -f *~
+
+.PHONY: all build clean install
+
+-include $(DEPS)
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-allocate.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-allocate.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <linux/major.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+static int
+tap_ctl_prepare_directory(const char *dir)
+{
+ int err;
+ char *ptr, *name, *start;
+
+ err = access(dir, W_OK | R_OK);
+ if (!err)
+ return 0;
+
+ name = strdup(dir);
+ if (!name)
+ return ENOMEM;
+
+ start = name;
+
+ for (;;) {
+ ptr = strchr(start + 1, '/');
+ if (ptr)
+ *ptr = '\0';
+
+ err = mkdir(name, 0755);
+ if (err && errno != EEXIST) {
+ PERROR("mkdir %s", name);
+ err = errno;
+ break;
+ }
+
+ if (!ptr)
+ break;
+ else {
+ *ptr = '/';
+ start = ptr + 1;
+ }
+ }
+
+ free(name);
+ return err;
+}
+
+static int
+tap_ctl_make_device(const char *devname, const int major,
+ const int minor, const int perm)
+{
+ int err;
+ char *copy, *dir;
+
+ copy = strdup(devname);
+ if (!copy)
+ return ENOMEM;
+
+ dir = dirname(copy);
+
+ err = tap_ctl_prepare_directory(dir);
+ free(copy);
+
+ if (err)
+ return err;
+
+ if (!access(devname, F_OK))
+ if (unlink(devname)) {
+ PERROR("unlink %s", devname);
+ return errno;
+ }
+
+ err = mknod(devname, perm, makedev(major, minor));
+ if (err) {
+ PERROR("mknod %s", devname);
+ return errno;
+ }
+
+ return 0;
+}
+
+static int
+tap_ctl_check_environment(void)
+{
+ FILE *f;
+ int err, minor;
+ char name[256];
+
+ err = tap_ctl_prepare_directory(BLKTAP2_CONTROL_DIR);
+ if (err)
+ return err;
+
+ if (!access(BLKTAP2_CONTROL_DEVICE, R_OK | W_OK))
+ return 0;
+
+ memset(name, 0, sizeof(name));
+
+ f = fopen("/proc/misc", "r");
+ if (!f) {
+ 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,
+ minor, S_IFCHR | 0600);
+ goto out;
+ }
+
+ err = ENOSYS;
+ EPRINTF("didn't find %s in /proc/misc\n", BLKTAP2_CONTROL_NAME);
+
+out:
+ fclose(f);
+ return err;
+}
+
+static int
+tap_ctl_allocate_device(int *minor, char **devname)
+{
+ char *name;
+ int fd, err;
+ struct blktap2_handle handle;
+
+ *minor = -1;
+ if (!devname)
+ return EINVAL;
+
+ fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
+ if (fd == -1) {
+ EPRINTF("failed to open control device: %d\n", errno);
+ return errno;
+ }
+
+ err = ioctl(fd, BLKTAP2_IOCTL_ALLOC_TAP, &handle);
+ close(fd);
+ if (err == -1) {
+ EPRINTF("failed to allocate new device: %d\n", errno);
+ return errno;
+ }
+
+ 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) {
+ EPRINTF("creating ring device for %d failed: %d\n",
+ handle.minor, err);
+ 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);
+ if (err) {
+ EPRINTF("creating IO device for %d failed: %d\n",
+ handle.minor, err);
+ goto fail;
+ }
+
+ DBG("new interface: ring: %u, device: %u, minor: %u\n",
+ handle.ring, handle.device, handle.minor);
+
+ *minor = handle.minor;
+ return 0;
+
+fail:
+ tap_ctl_free(handle.minor);
+ return err;
+}
+
+int
+tap_ctl_allocate(int *minor, char **devname)
+{
+ int err;
+
+ *minor = -1;
+
+ err = tap_ctl_check_environment();
+ if (err)
+ return err;
+
+ err = tap_ctl_allocate_device(minor, devname);
+ if (err)
+ return err;
+
+ return 0;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-attach.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-attach.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+
+int
+tap_ctl_attach(const int id, const int minor)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_ATTACH;
+ message.cookie = minor;
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 5);
+ if (err)
+ return err;
+
+ if (message.type == TAPDISK_MESSAGE_ATTACH_RSP) {
+ err = message.u.response.error;
+ if (err)
+ EPRINTF("attach failed: %d\n", err);
+ } else {
+ EPRINTF("got unexpected result '%s' from %d\n",
+ tapdisk_message_name(message.type), id);
+ err = EINVAL;
+ }
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-check.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-check.c Mon Jun 07 14:53:16 2010 -0700
@@ -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;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-close.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-close.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+
+static int
+__tap_ctl_close(const int id, const int minor, const int force)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_CLOSE;
+ if (force)
+ message.type = TAPDISK_MESSAGE_FORCE_SHUTDOWN;
+ message.cookie = minor;
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 5);
+ if (err)
+ return err;
+
+ if (message.type == TAPDISK_MESSAGE_CLOSE_RSP) {
+ err = message.u.response.error;
+ if (err)
+ EPRINTF("close failed: %d\n", err);
+ } else {
+ EPRINTF("got unexpected result '%s' from %d\n",
+ tapdisk_message_name(message.type), id);
+ err = EINVAL;
+ }
+
+ return err;
+}
+
+int
+tap_ctl_close(const int id, const int minor, const int force)
+{
+ int i, err;
+
+ for (i = 0; i < 20; i++) {
+ err = __tap_ctl_close(id, minor, force);
+ if (!err)
+ return 0;
+
+ err = (err < 0 ? -err : err);
+ if (err != EAGAIN) {
+ EPRINTF("close failed: %d\n", err);
+ return err;
+ }
+
+ usleep(1000);
+ }
+
+ EPRINTF("close timed out\n");
+ return EIO;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-create.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-create.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+int
+tap_ctl_create(const char *params, char **devname)
+{
+ int err, id, minor;
+
+ err = tap_ctl_allocate(&minor, devname);
+ if (err)
+ return err;
+
+ id = tap_ctl_spawn();
+ if (id < 0)
+ goto destroy;
+
+ err = tap_ctl_attach(id, minor);
+ if (err)
+ goto destroy;
+
+ err = tap_ctl_open(id, minor, params);
+ if (err)
+ goto detach;
+
+ return 0;
+
+detach:
+ tap_ctl_detach(id, minor);
+destroy:
+ tap_ctl_free(minor);
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-destroy.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-destroy.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+int
+tap_ctl_destroy(const int id, const int minor)
+{
+ int err;
+
+ err = tap_ctl_close(id, minor, 0);
+ if (err)
+ return err;
+
+ err = tap_ctl_detach(id, minor);
+ if (err)
+ return err;
+
+ err = tap_ctl_free(minor);
+ if (err)
+ return err;
+
+ return 0;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-detach.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-detach.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+
+int
+tap_ctl_detach(const int id, const int minor)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_DETACH;
+ message.cookie = minor;
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 5);
+ if (err)
+ return err;
+
+ if (message.type == TAPDISK_MESSAGE_DETACH_RSP) {
+ err = message.u.response.error;
+ if (err < 0)
+ printf("detach failed: %d\n", err);
+ } else {
+ printf("got unexpected result '%s' from %d\n",
+ tapdisk_message_name(message.type), id);
+ err = EINVAL;
+ }
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-free.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-free.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+int
+tap_ctl_free(const int minor)
+{
+ int fd, err;
+
+ fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
+ if (fd == -1) {
+ EPRINTF("failed to open control device: %d\n", errno);
+ return errno;
+ }
+
+ err = ioctl(fd, BLKTAP2_IOCTL_FREE_TAP, minor);
+ close(fd);
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-ipc.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-ipc.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,237 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+int tap_ctl_debug = 0;
+
+int
+tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout)
+{
+ fd_set readfds;
+ int ret, len, offset;
+ struct timeval tv, *t;
+
+ t = NULL;
+ offset = 0;
+ len = sizeof(tapdisk_message_t);
+
+ if (timeout) {
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ t = &tv;
+ }
+
+ memset(message, 0, sizeof(tapdisk_message_t));
+
+ while (offset < len) {
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ ret = select(fd + 1, &readfds, NULL, NULL, t);
+ 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;
+ }
+
+ if (offset != len) {
+ EPRINTF("failure reading message\n");
+ return -EIO;
+ }
+
+ DBG("received '%s' message (uuid = %u)\n",
+ tapdisk_message_name(message->type), message->cookie);
+
+ return 0;
+}
+
+int
+tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout)
+{
+ fd_set writefds;
+ int ret, len, offset;
+ struct timeval tv, *t;
+
+ t = NULL;
+ offset = 0;
+ len = sizeof(tapdisk_message_t);
+
+ if (timeout) {
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ t = &tv;
+ }
+
+ DBG("sending '%s' message (uuid = %u)\n",
+ tapdisk_message_name(message->type), message->cookie);
+
+ while (offset < len) {
+ FD_ZERO(&writefds);
+ FD_SET(fd, &writefds);
+
+ /* we don't bother reinitializing tv. at worst, it will wait a
+ * bit more time than expected. */
+
+ ret = select(fd + 1, NULL, &writefds, NULL, t);
+ if (ret == -1)
+ break;
+ else if (FD_ISSET(fd, &writefds)) {
+ ret = write(fd, message + offset, len - offset);
+ if (ret <= 0)
+ break;
+ offset += ret;
+ } else
+ break;
+ }
+
+ if (offset != len) {
+ EPRINTF("failure writing message\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int
+tap_ctl_send_and_receive(int sfd, tapdisk_message_t *message, int timeout)
+{
+ int err;
+
+ err = tap_ctl_write_message(sfd, message, timeout);
+ if (err) {
+ EPRINTF("failed to send '%s' message\n",
+ tapdisk_message_name(message->type));
+ return err;
+ }
+
+ err = tap_ctl_read_message(sfd, message, timeout);
+ if (err) {
+ EPRINTF("failed to receive '%s' message\n",
+ tapdisk_message_name(message->type));
+ return err;
+ }
+
+ return 0;
+}
+
+char *
+tap_ctl_socket_name(int id)
+{
+ char *name;
+
+ if (asprintf(&name, "%s/%s%d",
+ BLKTAP2_CONTROL_DIR, BLKTAP2_CONTROL_SOCKET, id) == -1)
+ return NULL;
+
+ return name;
+}
+
+int
+tap_ctl_connect(const char *name, int *sfd)
+{
+ int fd, err;
+ struct sockaddr_un saddr;
+
+ *sfd = -1;
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1) {
+ EPRINTF("couldn't create socket for %s: %d\n", name, errno);
+ return -errno;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sun_family = AF_UNIX;
+ strcpy(saddr.sun_path, name);
+
+ err = connect(fd, (const struct sockaddr *)&saddr, sizeof(saddr));
+ if (err) {
+ EPRINTF("couldn't connect to %s: %d\n", name, errno);
+ close(fd);
+ return -errno;
+ }
+
+ *sfd = fd;
+ return 0;
+}
+
+int
+tap_ctl_connect_id(int id, int *sfd)
+{
+ int err;
+ char *name;
+
+ *sfd = -1;
+
+ if (id < 0) {
+ EPRINTF("invalid id %d\n", id);
+ return -EINVAL;
+ }
+
+ name = tap_ctl_socket_name(id);
+ if (!name) {
+ EPRINTF("couldn't name socket for %d\n", id);
+ return -ENOMEM;
+ }
+
+ err = tap_ctl_connect(name, sfd);
+ free(name);
+
+ return err;
+}
+
+int
+tap_ctl_connect_send_and_receive(int id, tapdisk_message_t *message, int timeout)
+{
+ int err, sfd;
+
+ err = tap_ctl_connect_id(id, &sfd);
+ if (err)
+ return err;
+
+ err = tap_ctl_send_and_receive(sfd, message, timeout);
+
+ close(sfd);
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-list.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-list.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <glob.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+#include "list.h"
+
+static void
+free_list(tap_list_t *entry)
+{
+ if (entry->type) {
+ free(entry->type);
+ entry->type = NULL;
+ }
+
+ if (entry->path) {
+ free(entry->path);
+ entry->path = NULL;
+ }
+
+ free(entry);
+}
+
+int
+_parse_params(const char *params, char **type, char **path)
+{
+ char *ptr;
+ size_t len;
+
+ ptr = strchr(params, ':');
+ if (!ptr)
+ return -EINVAL;
+
+ len = ptr - params;
+
+ *type = strndup(params, len);
+ *path = strdup(params + len + 1);
+
+ if (!*type || !*path) {
+ free(*type);
+ *type = NULL;
+
+ free(*path);
+ *path = NULL;
+
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int
+init_list(tap_list_t *entry,
+ int tap_id, pid_t tap_pid, int vbd_minor, int vbd_state,
+ const char *params)
+{
+ int err = 0;
+
+ entry->id = tap_id;
+ entry->pid = tap_pid;
+ entry->minor = vbd_minor;
+ entry->state = vbd_state;
+
+ if (params)
+ err = _parse_params(params, &entry->type, &entry->path);
+
+ return err;
+}
+
+void
+tap_ctl_free_list(tap_list_t **list)
+{
+ tap_list_t **_entry;
+
+ for (_entry = list; *_entry != NULL; ++_entry)
+ free_list(*_entry);
+
+ free(list);
+}
+
+static tap_list_t**
+tap_ctl_alloc_list(int n)
+{
+ tap_list_t **list, *entry;
+ size_t size;
+ int i;
+
+ size = sizeof(tap_list_t*) * (n+1);
+ list = malloc(size);
+ if (!list)
+ goto fail;
+
+ memset(list, 0, size);
+
+ for (i = 0; i < n; ++i) {
+ tap_list_t *entry;
+
+ entry = malloc(sizeof(tap_list_t));
+ if (!entry)
+ goto fail;
+
+ memset(entry, 0, sizeof(tap_list_t));
+
+ list[i] = entry;
+ }
+
+ return list;
+
+fail:
+ if (list)
+ tap_ctl_free_list(list);
+
+ return NULL;
+}
+
+static int
+tap_ctl_list_length(const tap_list_t **list)
+{
+ const tap_list_t **_entry;
+ int n;
+
+ n = 0;
+ for (_entry = list; *_entry != NULL; ++_entry)
+ n++;
+
+ return n;
+}
+
+static int
+_tap_minor_cmp(const void *a, const void *b)
+{
+ return *(int*)a - *(int*)b;
+}
+
+int
+_tap_ctl_find_minors(int **_minorv)
+{
+ glob_t glbuf = { 0 };
+ const char *pattern, *format;
+ int *minorv = NULL, n_minors = 0;
+ int err, i;
+
+ pattern = BLKTAP2_SYSFS_DIR"/blktap*";
+ format = BLKTAP2_SYSFS_DIR"/blktap%d";
+
+ n_minors = 0;
+ minorv = NULL;
+
+ err = glob(pattern, 0, NULL, &glbuf);
+ switch (err) {
+ case GLOB_NOMATCH:
+ goto done;
+
+ case GLOB_ABORTED:
+ case GLOB_NOSPACE:
+ err = -errno;
+ EPRINTF("%s: glob failed, err %d", pattern, err);
+ goto fail;
+ }
+
+ minorv = malloc(sizeof(int) * glbuf.gl_pathc);
+ if (!minorv) {
+ err = -errno;
+ goto fail;
+ }
+
+ for (i = 0; i < glbuf.gl_pathc; ++i) {
+ int n;
+
+ n = sscanf(glbuf.gl_pathv[i], format, &minorv[n_minors]);
+ if (n != 1)
+ continue;
+
+ n_minors++;
+ }
+
+ qsort(minorv, n_minors, sizeof(int), _tap_minor_cmp);
+
+done:
+ *_minorv = minorv;
+ err = 0;
+
+out:
+ if (glbuf.gl_pathv)
+ globfree(&glbuf);
+
+ return err ? : n_minors;
+
+fail:
+ if (minorv)
+ free(minorv);
+
+ goto out;
+}
+
+struct tapdisk {
+ int id;
+ pid_t pid;
+ struct list_head list;
+};
+
+static int
+_tap_tapdisk_cmp(const void *a, const void *b)
+{
+ return ((struct tapdisk*)a)->id - ((struct tapdisk*)b)->id;
+}
+
+int
+_tap_ctl_find_tapdisks(struct tapdisk **_tapv)
+{
+ glob_t glbuf = { 0 };
+ const char *pattern, *format;
+ struct tapdisk *tapv = NULL;
+ int err, i, n_taps = 0;
+
+ pattern = BLKTAP2_CONTROL_DIR"/"BLKTAP2_CONTROL_SOCKET"*";
+ format = BLKTAP2_CONTROL_DIR"/"BLKTAP2_CONTROL_SOCKET"%d";
+
+ n_taps = 0;
+ tapv = NULL;
+
+ err = glob(pattern, 0, NULL, &glbuf);
+ switch (err) {
+ case GLOB_NOMATCH:
+ goto done;
+
+ case GLOB_ABORTED:
+ case GLOB_NOSPACE:
+ err = -errno;
+ EPRINTF("%s: glob failed, err %d", pattern, err);
+ goto fail;
+ }
+
+ tapv = malloc(sizeof(struct tapdisk) * glbuf.gl_pathc);
+ if (!tapv) {
+ err = -errno;
+ goto fail;
+ }
+
+ for (i = 0; i < glbuf.gl_pathc; ++i) {
+ struct tapdisk *tap;
+ int n;
+
+ tap = &tapv[n_taps];
+
+ err = sscanf(glbuf.gl_pathv[i], format, &tap->id);
+ if (err != 1)
+ continue;
+
+ tap->pid = tap_ctl_get_pid(tap->id);
+ if (tap->pid < 0)
+ continue;
+
+ 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;
+
+out:
+ if (glbuf.gl_pathv)
+ globfree(&glbuf);
+
+ return err ? : n_taps;
+
+fail:
+ if (tapv)
+ free(tapv);
+
+ goto out;
+}
+
+struct tapdisk_list {
+ int minor;
+ int state;
+ char *params;
+ struct list_head entry;
+};
+
+int
+_tap_ctl_list_tapdisk(int id, struct list_head *_list)
+{
+ tapdisk_message_t message;
+ struct list_head list;
+ struct tapdisk_list *tl, *next;
+ int err, sfd;
+
+ err = tap_ctl_connect_id(id, &sfd);
+ if (err)
+ return err;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_LIST;
+ message.cookie = -1;
+
+ err = tap_ctl_write_message(sfd, &message, 2);
+ if (err)
+ return err;
+
+ INIT_LIST_HEAD(&list);
+ do {
+ err = tap_ctl_read_message(sfd, &message, 2);
+ if (err) {
+ err = -EPROTO;
+ break;
+ }
+
+ if (message.u.list.count == 0)
+ break;
+
+ tl = malloc(sizeof(struct tapdisk_list));
+ if (!tl) {
+ err = -ENOMEM;
+ break;
+ }
+
+ tl->minor = message.u.list.minor;
+ tl->state = message.u.list.state;
+ if (message.u.list.path[0] != 0) {
+ tl->params = strndup(message.u.list.path,
+ sizeof(message.u.list.path));
+ if (!tl->params) {
+ err = -errno;
+ break;
+ }
+ } else
+ tl->params = NULL;
+
+ list_add(&tl->entry, &list);
+ } while (1);
+
+ if (err)
+ list_for_each_entry_safe(tl, next, &list, entry) {
+ list_del(&tl->entry);
+ free(tl->params);
+ free(tl);
+ }
+
+ close(sfd);
+ list_splice(&list, _list);
+ return err;
+}
+
+void
+_tap_ctl_free_tapdisks(struct tapdisk *tapv, int n_taps)
+{
+ struct tapdisk *tap;
+
+ for (tap = tapv; tap < &tapv[n_taps]; ++tap) {
+ struct tapdisk_list *tl;
+
+ list_for_each_entry(tl, &tap->list, entry) {
+ free(tl->params);
+ free(tl);
+ }
+ }
+
+ free(tapv);
+}
+
+int
+_tap_list_join3(int n_minors, int *minorv, int n_taps, struct tapdisk *tapv,
+ tap_list_t ***_list)
+{
+ tap_list_t **list, **_entry, *entry;
+ int i, _m, err;
+
+ list = tap_ctl_alloc_list(n_minors + n_taps);
+ if (!list) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ _entry = list;
+
+ for (i = 0; i < n_taps; ++i) {
+ struct tapdisk *tap = &tapv[i];
+ struct tapdisk_list *tl;
+
+ /* orphaned tapdisk */
+ if (list_empty(&tap->list)) {
+ err = init_list(*_entry++, tap->id, tap->pid, -1, -1, NULL);
+ if (err)
+ goto fail;
+ continue;
+ }
+
+ list_for_each_entry(tl, &tap->list, entry) {
+
+ err = init_list(*_entry++,
+ tap->id, tap->pid,
+ tl->minor, tl->state, tl->params);
+ if (err)
+ goto fail;
+
+ if (tl->minor >= 0) {
+ /* clear minor */
+ for (_m = 0; _m < n_minors; ++_m) {
+ if (minorv[_m] == tl->minor) {
+ minorv[_m] = -1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* orphaned minors */
+ for (_m = 0; _m < n_minors; ++_m) {
+ int minor = minorv[_m];
+ if (minor >= 0) {
+ err = init_list(*_entry++, -1, -1, minor, -1, NULL);
+ if (err)
+ goto fail;
+ }
+ }
+
+ /* free extraneous list entries */
+ for (; *_entry != NULL; ++entry) {
+ free_list(*_entry);
+ *_entry = NULL;
+ }
+
+ *_list = list;
+
+ return 0;
+
+fail:
+ if (list)
+ tap_ctl_free_list(list);
+
+ return err;
+}
+
+int
+tap_ctl_list(tap_list_t ***list)
+{
+ int n_taps, n_minors, err, *minorv;
+ struct tapdisk *tapv, *tap;
+
+ n_taps = -1;
+ n_minors = -1;
+
+ err = n_minors = _tap_ctl_find_minors(&minorv);
+ if (err < 0)
+ goto out;
+
+ err = n_taps = _tap_ctl_find_tapdisks(&tapv);
+ if (err < 0)
+ goto out;
+
+ for (tap = tapv; tap < &tapv[n_taps]; ++tap) {
+ err = _tap_ctl_list_tapdisk(tap->id, &tap->list);
+ if (err)
+ goto out;
+ }
+
+ err = _tap_list_join3(n_minors, minorv, n_taps, tapv, list);
+
+out:
+ if (n_taps > 0)
+ _tap_ctl_free_tapdisks(tapv, n_taps);
+
+ if (n_minors > 0)
+ free(minorv);
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-major.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-major.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,69 @@
+/*
+ * 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 "tap-ctl.h"
+
+int
+tap_ctl_blk_major(void)
+{
+ FILE *devices;
+ int rv, major;
+
+ devices = fopen("/proc/devices", "r");
+ if (!devices) {
+ rv = -errno;
+ goto out;
+ }
+
+ do {
+ char buf[32], *s;
+ int n, offset;
+
+ s = fgets(buf, sizeof(buf), devices);
+ if (!s)
+ break;
+
+ major = -ENODEV;
+ offset = 0;
+
+ n = sscanf(buf, "%d tapdev%n", &major, &offset);
+ if (n == 1 && offset)
+ break;
+ } while (1);
+
+ rv = major;
+
+out:
+ if (devices)
+ fclose(devices);
+
+ return rv;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-open.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-open.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+#include "blktaplib.h"
+
+int
+tap_ctl_open(const int id, const int minor, const char *params)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_OPEN;
+ message.cookie = minor;
+ message.u.params.storage = TAPDISK_STORAGE_TYPE_DEFAULT;
+ message.u.params.devnum = minor;
+
+ err = snprintf(message.u.params.path,
+ sizeof(message.u.params.path) - 1, "%s", params);
+ if (err >= sizeof(message.u.params.path)) {
+ EPRINTF("name too long\n");
+ return ENAMETOOLONG;
+ }
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 5);
+ if (err)
+ return err;
+
+ switch (message.type) {
+ case TAPDISK_MESSAGE_OPEN_RSP:
+ break;
+ case TAPDISK_MESSAGE_ERROR:
+ err = -message.u.response.error;
+ EPRINTF("open failed, err %d\n", err);
+ break;
+ default:
+ EPRINTF("got unexpected result '%s' from %d\n",
+ tapdisk_message_name(message.type), id);
+ err = EINVAL;
+ }
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-pause.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-pause.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "tap-ctl.h"
+
+int
+tap_ctl_pause(const int id, const int minor)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_PAUSE;
+ message.cookie = minor;
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 5);
+ if (err)
+ return err;
+
+ if (message.type == TAPDISK_MESSAGE_PAUSE_RSP)
+ err = message.u.response.error;
+ else {
+ err = EINVAL;
+ EPRINTF("got unexpected result '%s' from %d\n",
+ tapdisk_message_name(message.type), id);
+ }
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-spawn.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-spawn.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,174 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include "tap-ctl.h"
+#include "blktap2.h"
+
+static pid_t
+__tap_ctl_spawn(int *readfd)
+{
+ int err, child, channel[2];
+ char *tapdisk;
+
+ if (pipe(channel)) {
+ EPRINTF("pipe failed: %d\n", errno);
+ return -errno;
+ }
+
+ if ((child = fork()) == -1) {
+ EPRINTF("fork failed: %d\n", errno);
+ return -errno;
+ }
+
+ if (child) {
+ close(channel[1]);
+ *readfd = channel[0];
+ return child;
+ }
+
+ 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";
+
+ execlp(tapdisk, tapdisk, NULL);
+
+ EPRINTF("exec failed\n");
+ exit(1);
+}
+
+pid_t
+tap_ctl_get_pid(const int id)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_PID;
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 2);
+ if (err)
+ return err;
+
+ return message.u.tapdisk_pid;
+}
+
+static int
+tap_ctl_wait(pid_t child)
+{
+ pid_t pid;
+ int status;
+
+ pid = waitpid(child, &status, 0);
+ if (pid < 0) {
+ EPRINTF("wait(%d) failed, err %d\n", child, errno);
+ return -errno;
+ }
+
+ if (WIFEXITED(status)) {
+ int code = WEXITSTATUS(status);
+ if (code)
+ EPRINTF("tapdisk2[%d] failed, status %d\n", child, code);
+ return -code;
+ }
+
+ if (WIFSIGNALED(status)) {
+ int signo = WTERMSIG(status);
+ EPRINTF("tapdisk2[%d] killed by signal %d\n", child, signo);
+ return -EINTR;
+ }
+
+ EPRINTF("tapdisk2[%d]: unexpected status %#x\n", child, status);
+ return -EAGAIN;
+}
+
+static int
+tap_ctl_get_child_id(int readfd)
+{
+ int id;
+ FILE *f;
+
+ f = fdopen(readfd, "r");
+ if (!f) {
+ EPRINTF("fdopen failed: %d\n", errno);
+ return -1;
+ }
+
+ 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;
+ }
+
+ fclose(f);
+ return id;
+}
+
+int
+tap_ctl_spawn(void)
+{
+ pid_t child;
+ int err, id, readfd;
+
+ readfd = -1;
+
+ child = __tap_ctl_spawn(&readfd);
+ if (child < 0)
+ return child;
+
+ err = tap_ctl_wait(child);
+ if (err)
+ return err;
+
+ id = tap_ctl_get_child_id(readfd);
+ if (id < 0)
+ EPRINTF("get_id failed, child %d err %d\n", child, errno);
+
+ return id;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl-unpause.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl-unpause.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+
+int
+tap_ctl_unpause(const int id, const int minor, const char *params)
+{
+ int err;
+ tapdisk_message_t message;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_RESUME;
+ message.cookie = minor;
+
+ if (params)
+ strncpy(message.u.params.path, params,
+ sizeof(message.u.params.path) - 1);
+
+ err = tap_ctl_connect_send_and_receive(id, &message, 15);
+ if (err)
+ return err;
+
+ if (message.type == TAPDISK_MESSAGE_RESUME_RSP)
+ err = message.u.response.error;
+ else {
+ err = EINVAL;
+ EPRINTF("got unexpected result '%s' from %d\n",
+ tapdisk_message_name(message.type), id);
+ }
+
+ return err;
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,815 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "tap-ctl.h"
+
+typedef int (*tap_ctl_func_t) (int, char **);
+
+struct command {
+ char *name;
+ tap_ctl_func_t func;
+};
+
+static void
+tap_cli_list_usage(FILE *stream)
+{
+ fprintf(stream,
+ "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, minor, tty, err;
+ const char *type, *file;
+ pid_t pid;
+
+ err = tap_ctl_list(&list);
+ if (err)
+ return -err;
+
+ pid = -1;
+ minor = -1;
+ type = NULL;
+ file = NULL;
+
+ while ((c = getopt(argc, argv, "m:p:t:f:h")) != -1) {
+ switch (c) {
+ case 'm':
+ minor = atoi(optarg);
+ break;
+ case 'p':
+ pid = atoi(optarg);
+ break;
+ case 't':
+ type = optarg;
+ break;
+ 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;
+
+ if (minor >= 0 && entry->minor != minor)
+ continue;
+
+ if (pid >= 0 && entry->pid != pid)
+ continue;
+
+ if (type && entry->type && strcmp(entry->type, type))
+ continue;
+
+ if (file && entry->path && strcmp(entry->path, file))
+ continue;
+
+ if (tty)
+ tap_ctl_list_row(entry);
+ else
+ tap_ctl_list_dict(entry);
+ }
+
+ tap_ctl_free_list(list);
+
+ return 0;
+
+usage:
+ tap_cli_list_usage(stderr);
+ return EINVAL;
+}
+
+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;
+ }
+ }
+
+ 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_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 <-p pid> <-m minor>\n");
+}
+
+static int
+tap_cli_pause(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_pause_usage(stdout);
+ return 0;
+ }
+ }
+
+ if (pid == -1 || minor == -1)
+ goto usage;
+
+ return tap_ctl_pause(pid, minor);
+
+usage:
+ tap_cli_pause_usage(stderr);
+ return EINVAL;
+}
+
+static void
+tap_cli_unpause_usage(FILE *stream)
+{
+ fprintf(stream, "usage: unpause <-p pid> <-m minor> [-a args]\n");
+}
+
+int
+tap_cli_unpause(int argc, char **argv)
+{
+ const char *args;
+ int c, pid, minor;
+
+ pid = -1;
+ minor = -1;
+ args = NULL;
+
+ optind = 0;
+ while ((c = getopt(argc, argv, "p:m:a:h")) != -1) {
+ switch (c) {
+ case 'p':
+ pid = atoi(optarg);
+ break;
+ case 'm':
+ minor = atoi(optarg);
+ break;
+ case 'a':
+ args = optarg;
+ break;
+ case '?':
+ goto usage;
+ case 'h':
+ tap_cli_unpause_usage(stdout);
+ return 0;
+ }
+ }
+
+ if (pid == -1 || minor == -1)
+ goto usage;
+
+ return tap_ctl_unpause(pid, minor, args);
+
+usage:
+ tap_cli_unpause_usage(stderr);
+ return EINVAL;
+}
+
+static void
+tap_cli_major_usage(FILE *stream)
+{
+ fprintf(stream, "usage: major [-h]\n");
+}
+
+static int
+tap_cli_major(int argc, char **argv)
+{
+ int c, chr, major;
+
+ chr = 0;
+
+ while ((c = getopt(argc, argv, "bch")) != -1) {
+ switch (c) {
+ case 'b':
+ chr = 0;
+ break;
+ case 'c':
+ chr = 1;
+ break;
+ case '?':
+ goto usage;
+ case 'h':
+ tap_cli_major_usage(stdout);
+ return 0;
+ default:
+ goto usage;
+ }
+ }
+
+ if (chr)
+ major = -EINVAL;
+ else
+ major = tap_ctl_blk_major();
+
+ if (major < 0)
+ return -major;
+
+ printf("%d\n", major);
+
+ return 0;
+
+usage:
+ tap_cli_major_usage(stderr);
+ return EINVAL;
+}
+
+static void
+tap_cli_open_usage(FILE *stream)
+{
+ 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, pid, minor;
+
+ pid = -1;
+ minor = -1;
+ args = NULL;
+
+ optind = 0;
+ while ((c = getopt(argc, argv, "a:m:p:h")) != -1) {
+ switch (c) {
+ case 'p':
+ pid = atoi(optarg);
+ break;
+ case 'm':
+ minor = atoi(optarg);
+ break;
+ case 'a':
+ args = optarg;
+ break;
+ case '?':
+ goto usage;
+ case 'h':
+ tap_cli_open_usage(stdout);
+ return 0;
+ }
+ }
+
+ if (pid == -1 || minor == -1 || !args)
+ goto usage;
+
+ 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_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_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() \
+ do { \
+ int i, n; \
+ n = sizeof(commands) / sizeof(struct command); \
+ printf("COMMAND := { "); \
+ printf("%s", commands[0].name); \
+ for (i = 1; i < n; i++) \
+ printf(" | %s", commands[i].name); \
+ printf(" }\n"); \
+ } while (0)
+
+void
+help(void)
+{
+ printf("usage: tap-ctl COMMAND [OPTIONS]\n");
+ print_commands();
+ exit(0);
+}
+
+struct command *
+get_command(char *command)
+{
+ int i, n;
+
+ if (strnlen(command, 25) >= 25)
+ return NULL;
+
+ n = sizeof(commands) / sizeof (struct command);
+
+ for (i = 0; i < n; i++)
+ if (!strcmp(command, commands[i].name))
+ return &commands[i];
+
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char **cargv;
+ const char *msg;
+ struct command *cmd;
+ int cargc, i, cnt, ret;
+
+#ifdef CORE_DUMP
+ #include <sys/resource.h>
+ struct rlimit rlim;
+ rlim.rlim_cur = RLIM_INFINITY;
+ rlim.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_CORE, &rlim) < 0)
+ PERROR("setrlimit failed");
+#endif
+
+ ret = 0;
+
+ if (argc < 2)
+ help();
+
+ cargc = argc - 1;
+ cmd = get_command(argv[1]);
+ if (!cmd) {
+ 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);
+
+ cnt = 1;
+ cargv[0] = cmd->name;
+ for (i = 1; i < cargc; i++) {
+ char *arg = argv[i + (argc - cargc)];
+
+ if (!strcmp(arg, "--debug")) {
+ tap_ctl_debug = 1;
+ continue;
+ }
+
+ cargv[cnt++] = arg;
+ }
+
+ ret = cmd->func(cnt, cargv);
+
+ free(cargv);
+
+ return (ret >= 0 ? ret : -ret);
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/control/tap-ctl.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/control/tap-ctl.h Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __TAP_CTL_H__
+#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) \
+ printf(_f, ##_a); \
+ } while (0)
+
+#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);
+char *tap_ctl_socket_name(int id);
+
+typedef struct {
+ int id;
+ pid_t pid;
+ int minor;
+ int state;
+ char *type;
+ char *path;
+} tap_list_t;
+
+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 *minor, char **devname);
+int tap_ctl_free(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(void);
+pid_t tap_ctl_get_pid(const int id);
+
+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(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 *params);
+
+int tap_ctl_blk_major(void);
+
+#endif
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/Makefile
--- a/tools/blktap2/drivers/Makefile Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/Makefile Mon Jun 07 14:53:16 2010 -0700
@@ -12,8 +12,7 @@
CFLAGS += -Werror -g -O0
CFLAGS += -Wno-unused
CFLAGS += -fno-strict-aliasing
-CFLAGS += -I../lib -I../../libxc
-CFLAGS += -I../include -I../../include
+CFLAGS += -I$(BLKTAP_ROOT)/include -I$(BLKTAP_ROOT)/drivers
CFLAGS += $(CFLAGS_libxenctrl)
CFLAGS += -I $(LIBAIO_DIR)
CFLAGS += -I $(MEMSHR_DIR)
@@ -75,6 +74,7 @@
TAP-OBJS-y := scheduler.o
TAP-OBJS-y += tapdisk-vbd.o
+TAP-OBJS-y += tapdisk-control.o
TAP-OBJS-y += tapdisk-image.o
TAP-OBJS-y += tapdisk-driver.o
TAP-OBJS-y += tapdisk-disktype.o
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/blktap2.h
--- a/tools/blktap2/drivers/blktap2.h Mon Jun 07 14:53:15 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef _BLKTAP_2_H_
-#define _BLKTAP_2_H_
-
-#define MISC_MAJOR_NUMBER 10
-
-#define BLKTAP2_MAX_MESSAGE_LEN 256
-
-#define BLKTAP2_RING_MESSAGE_PAUSE 1
-#define BLKTAP2_RING_MESSAGE_RESUME 2
-#define BLKTAP2_RING_MESSAGE_CLOSE 3
-
-#define BLKTAP2_IOCTL_KICK_FE 1
-#define BLKTAP2_IOCTL_ALLOC_TAP 200
-#define BLKTAP2_IOCTL_FREE_TAP 201
-#define BLKTAP2_IOCTL_CREATE_DEVICE 202
-#define BLKTAP2_IOCTL_SET_PARAMS 203
-#define BLKTAP2_IOCTL_PAUSE 204
-#define BLKTAP2_IOCTL_REOPEN 205
-#define BLKTAP2_IOCTL_RESUME 206
-
-#define BLKTAP2_CONTROL_NAME "blktap-control"
-#define BLKTAP2_DIRECTORY "/dev/xen/blktap-2"
-#define BLKTAP2_CONTROL_DEVICE BLKTAP2_DIRECTORY"/control"
-#define BLKTAP2_RING_DEVICE BLKTAP2_DIRECTORY"/blktap"
-#define BLKTAP2_IO_DEVICE BLKTAP2_DIRECTORY"/tapdev"
-
-struct blktap2_handle {
- unsigned int ring;
- unsigned int device;
- unsigned int minor;
-};
-
-struct blktap2_params {
- char name[BLKTAP2_MAX_MESSAGE_LEN];
- unsigned long long capacity;
- unsigned long sector_size;
-};
-
-#endif
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk-control.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/drivers/tapdisk-control.c Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,836 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include "list.h"
+#include "tapdisk.h"
+#include "blktap2.h"
+#include "blktaplib.h"
+#include "tapdisk-vbd.h"
+#include "tapdisk-utils.h"
+#include "tapdisk-server.h"
+#include "tapdisk-message.h"
+#include "tapdisk-disktype.h"
+
+struct tapdisk_control {
+ char *path;
+ int socket;
+ int event_id;
+};
+
+struct tapdisk_control_connection {
+ int socket;
+ event_id_t event_id;
+};
+
+static struct tapdisk_control td_control;
+
+static void
+tapdisk_control_initialize(void)
+{
+ td_control.socket = -1;
+ td_control.event_id = -1;
+
+ signal(SIGPIPE, SIG_IGN);
+}
+
+void
+tapdisk_control_close(void)
+{
+ if (td_control.path) {
+ unlink(td_control.path);
+ free(td_control.path);
+ td_control.path = NULL;
+ }
+
+ if (td_control.socket != -1) {
+ close(td_control.socket);
+ td_control.socket = -1;
+ }
+}
+
+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("calloc");
+ return NULL;
+ }
+
+ connection->socket = fd;
+ return connection;
+}
+
+static void
+tapdisk_control_close_connection(struct tapdisk_control_connection *connection)
+{
+ tapdisk_server_unregister_event(connection->event_id);
+ close(connection->socket);
+ free(connection);
+}
+
+static int
+tapdisk_control_read_message(int fd, tapdisk_message_t *message, int timeout)
+{
+ fd_set readfds;
+ int ret, len, offset;
+ struct timeval tv, *t;
+
+ t = NULL;
+ offset = 0;
+ len = sizeof(tapdisk_message_t);
+
+ if (timeout) {
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ t = &tv;
+ }
+
+ memset(message, 0, sizeof(tapdisk_message_t));
+
+ while (offset < len) {
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ ret = select(fd + 1, &readfds, NULL, NULL, t);
+ 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;
+ }
+
+ if (offset != len) {
+ EPRINTF("failure reading message (wanted %d but got %d)\n",
+ len, offset);
+ return -EIO;
+ }
+
+ DPRINTF("received '%s' message (uuid = %u)\n",
+ tapdisk_message_name(message->type), message->cookie);
+
+ return 0;
+}
+
+static int
+tapdisk_control_write_message(int fd, tapdisk_message_t *message, int timeout)
+{
+ fd_set writefds;
+ int ret, len, offset;
+ struct timeval tv, *t;
+
+ t = NULL;
+ offset = 0;
+ len = sizeof(tapdisk_message_t);
+
+ if (timeout) {
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ t = &tv;
+ }
+
+ DPRINTF("sending '%s' message (uuid = %u)\n",
+ tapdisk_message_name(message->type), message->cookie);
+
+ while (offset < len) {
+ FD_ZERO(&writefds);
+ FD_SET(fd, &writefds);
+
+ /* we don't bother reinitializing tv. at worst, it will wait a
+ * bit more time than expected. */
+
+ ret = select(fd + 1, NULL, &writefds, NULL, t);
+ if (ret == -1)
+ break;
+ else if (FD_ISSET(fd, &writefds)) {
+ ret = write(fd, message + offset, len - offset);
+ if (ret <= 0)
+ break;
+ offset += ret;
+ } else
+ break;
+ }
+
+ if (offset != len) {
+ EPRINTF("failure writing message\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+tapdisk_control_validate_request(tapdisk_message_t *request)
+{
+ if (strnlen(request->u.params.path,
+ TAPDISK_MESSAGE_MAX_PATH_LENGTH) >=
+ TAPDISK_MESSAGE_MAX_PATH_LENGTH)
+ return EINVAL;
+
+ return 0;
+}
+
+static void
+tapdisk_control_list_minors(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ int i;
+ td_vbd_t *vbd;
+ struct list_head *head;
+ tapdisk_message_t response;
+
+ i = 0;
+ memset(&response, 0, sizeof(response));
+
+ response.type = TAPDISK_MESSAGE_LIST_MINORS_RSP;
+ response.cookie = request->cookie;
+
+ head = tapdisk_server_get_all_vbds();
+
+ list_for_each_entry(vbd, head, next) {
+ response.u.minors.list[i++] = vbd->minor;
+ if (i >= TAPDISK_MESSAGE_MAX_MINORS) {
+ response.type = TAPDISK_MESSAGE_ERROR;
+ response.u.response.error = ERANGE;
+ break;
+ }
+ }
+
+ response.u.minors.count = i;
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+}
+
+static void
+tapdisk_control_list(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ td_vbd_t *vbd;
+ struct list_head *head;
+ tapdisk_message_t response;
+ int count, i;
+
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_LIST_RSP;
+ response.cookie = request->cookie;
+
+ head = tapdisk_server_get_all_vbds();
+
+ count = 0;
+ list_for_each_entry(vbd, head, next)
+ count++;
+
+ list_for_each_entry(vbd, head, next) {
+ response.u.list.count = count--;
+ response.u.list.minor = vbd->minor;
+ response.u.list.state = vbd->state;
+ response.u.list.path[0] = 0;
+
+ if (!list_empty(&vbd->images)) {
+ td_image_t *image = list_entry(vbd->images.next,
+ td_image_t, next);
+ snprintf(response.u.list.path,
+ sizeof(response.u.list.path),
+ "%s:%s",
+ tapdisk_disk_types[image->type]->name,
+ image->name);
+ }
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ }
+
+ response.u.list.count = count;
+ response.u.list.minor = -1;
+ response.u.list.path[0] = 0;
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+}
+
+static void
+tapdisk_control_get_pid(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_t response;
+
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_PID_RSP;
+ response.cookie = request->cookie;
+ response.u.tapdisk_pid = getpid();
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+}
+
+static void
+tapdisk_control_attach_vbd(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_t response;
+ char *devname;
+ td_vbd_t *vbd;
+ struct blktap2_params params;
+ image_t image;
+ int minor, err;
+
+ /*
+ * TODO: check for max vbds per process
+ */
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (vbd) {
+ err = -EEXIST;
+ goto out;
+ }
+
+ minor = request->cookie;
+ if (minor < 0) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ vbd = tapdisk_vbd_create(minor);
+ if (!vbd) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = asprintf(&devname, BLKTAP2_RING_DEVICE"%d", minor);
+ if (err == -1) {
+ err = -ENOMEM;
+ goto fail_vbd;
+ }
+
+ err = tapdisk_vbd_attach(vbd, devname, minor);
+ free(devname);
+ if (err)
+ goto fail_vbd;
+
+ tapdisk_server_add_vbd(vbd);
+
+out:
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_ATTACH_RSP;
+ response.cookie = request->cookie;
+ response.u.response.error = -err;
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+
+ return;
+
+fail_vbd:
+ tapdisk_vbd_detach(vbd);
+ free(vbd);
+ goto out;
+}
+
+
+static void
+tapdisk_control_detach_vbd(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_t response;
+ td_vbd_t *vbd;
+ int err;
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ tapdisk_vbd_detach(vbd);
+
+ if (list_empty(&vbd->images)) {
+ tapdisk_server_remove_vbd(vbd);
+ free(vbd);
+ }
+
+ err = 0;
+out:
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_DETACH_RSP;
+ response.cookie = request->cookie;
+ response.u.response.error = -err;
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+}
+
+static void
+tapdisk_control_open_image(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ int err;
+ image_t image;
+ td_vbd_t *vbd;
+ td_flag_t flags;
+ tapdisk_message_t response;
+ struct blktap2_params params;
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (vbd->minor == -1) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (vbd->name) {
+ err = -EALREADY;
+ goto out;
+ }
+
+ flags = 0;
+ if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_RDONLY)
+ flags |= TD_OPEN_RDONLY;
+ if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_SHARED)
+ flags |= TD_OPEN_SHAREABLE;
+ if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_ADD_CACHE)
+ flags |= TD_OPEN_ADD_CACHE;
+ if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_VHD_INDEX)
+ flags |= TD_OPEN_VHD_INDEX;
+ if (request->u.params.flags & TAPDISK_MESSAGE_FLAG_LOG_DIRTY)
+ flags |= TD_OPEN_LOG_DIRTY;
+
+ vbd->name = strndup(request->u.params.path,
+ sizeof(request->u.params.path));
+ if (!vbd->name) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = tapdisk_vbd_parse_stack(vbd, request->u.params.path);
+ if (err)
+ goto out;
+
+ err = tapdisk_vbd_open_stack(vbd, request->u.params.storage, flags);
+ if (err)
+ goto out;
+
+ err = tapdisk_vbd_get_image_info(vbd, &image);
+ if (err)
+ goto fail_close;
+
+ params.capacity = image.size;
+ params.sector_size = image.secsize;
+
+ err = ioctl(vbd->ring.fd, BLKTAP2_IOCTL_CREATE_DEVICE, ¶ms);
+ if (err && errno != EEXIST) {
+ err = -errno;
+ EPRINTF("create device failed: %d\n", err);
+ goto fail_close;
+ }
+
+ err = 0;
+
+out:
+ memset(&response, 0, sizeof(response));
+ response.cookie = request->cookie;
+
+ if (err) {
+ response.type = TAPDISK_MESSAGE_ERROR;
+ response.u.response.error = -err;
+ } else {
+ response.u.image.sectors = image.size;
+ response.u.image.sector_size = image.secsize;
+ response.u.image.info = image.info;
+ response.type = TAPDISK_MESSAGE_OPEN_RSP;
+ }
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+
+ return;
+
+fail_close:
+ tapdisk_vbd_close_vdi(vbd);
+ free(vbd->name);
+ vbd->name = NULL;
+ goto out;
+}
+
+static void
+tapdisk_control_close_image(struct tapdisk_control_connection *connection,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_t response;
+ td_vbd_t *vbd;
+ int err;
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (!list_empty(&vbd->pending_requests)) {
+ err = -EAGAIN;
+ goto out;
+ }
+
+ tapdisk_vbd_close_vdi(vbd);
+
+ /* NB. vbd->name free should probably belong into close_vdi,
+ but the current blktap1 reopen-stuff likely depends on a
+ lifetime extended until shutdown. */
+ free(vbd->name);
+ vbd->name = NULL;
+
+ if (vbd->minor == -1) {
+ tapdisk_server_remove_vbd(vbd);
+ tapdisk_vbd_free(vbd);
+ }
+
+ err = 0;
+out:
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_CLOSE_RSP;
+ response.cookie = request->cookie;
+ response.u.response.error = -err;
+
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+}
+
+static void
+tapdisk_control_pause_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_PAUSE_RSP;
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ do {
+ err = tapdisk_vbd_pause(vbd);
+
+ if (!err || err != -EAGAIN)
+ break;
+
+ tapdisk_server_iterate();
+ } while (1);
+
+out:
+ response.cookie = request->cookie;
+ response.u.response.error = -err;
+ tapdisk_control_write_message(connection->socket, &response, 2);
+ tapdisk_control_close_connection(connection);
+}
+
+static void
+tapdisk_control_resume_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_RESUME_RSP;
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (!td_flag_test(vbd->state, TD_VBD_PAUSED)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (request->u.params.path[0]) {
+ free(vbd->name);
+ vbd->name = strndup(request->u.params.path,
+ sizeof(request->u.params.path));
+ if (!vbd->name) {
+ err = -ENOMEM;
+ goto out;
+ }
+ } else if (!vbd->name) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = tapdisk_vbd_parse_stack(vbd, vbd->name);
+ if (err)
+ goto out;
+
+ err = tapdisk_vbd_resume(vbd, NULL, -1);
+ if (err)
+ goto out;
+
+out:
+ response.cookie = request->cookie;
+ 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)
+{
+ int err;
+ tapdisk_message_t message;
+ struct tapdisk_control_connection *connection =
+ (struct tapdisk_control_connection *)private;
+
+ if (tapdisk_control_read_message(connection->socket, &message, 2)) {
+ EPRINTF("failed to read message from %d\n", connection->socket);
+ tapdisk_control_close_connection(connection);
+ return;
+ }
+
+ err = tapdisk_control_validate_request(&message);
+ if (err)
+ goto fail;
+
+ switch (message.type) {
+ case TAPDISK_MESSAGE_PID:
+ return tapdisk_control_get_pid(connection, &message);
+ case TAPDISK_MESSAGE_LIST_MINORS:
+ return tapdisk_control_list_minors(connection, &message);
+ case TAPDISK_MESSAGE_LIST:
+ return tapdisk_control_list(connection, &message);
+ case TAPDISK_MESSAGE_ATTACH:
+ return tapdisk_control_attach_vbd(connection, &message);
+ case TAPDISK_MESSAGE_DETACH:
+ return tapdisk_control_detach_vbd(connection, &message);
+ case TAPDISK_MESSAGE_OPEN:
+ return tapdisk_control_open_image(connection, &message);
+ case TAPDISK_MESSAGE_PAUSE:
+ return tapdisk_control_pause_vbd(connection, &message);
+ case TAPDISK_MESSAGE_RESUME:
+ return tapdisk_control_resume_vbd(connection, &message);
+ case TAPDISK_MESSAGE_CLOSE:
+ return tapdisk_control_close_image(connection, &message);
+ default: {
+ tapdisk_message_t response;
+ fail:
+
+ EPRINTF("received unsupported message '%s'\n",
+ tapdisk_message_name(message.type));
+
+ memset(&response, 0, sizeof(response));
+
+ response.type = TAPDISK_MESSAGE_ERROR;
+ response.u.response.error = (err ? -err : EINVAL);
+ tapdisk_control_write_message(connection->socket, &response, 2);
+
+ tapdisk_control_close_connection(connection);
+ break;
+ }
+ }
+}
+
+static void
+tapdisk_control_accept(event_id_t id, char mode, void *private)
+{
+ int err, fd;
+ struct tapdisk_control_connection *connection;
+
+ fd = accept(td_control.socket, NULL, NULL);
+ if (fd == -1) {
+ EPRINTF("failed to accept new control connection: %d\n", errno);
+ return;
+ }
+
+ connection = tapdisk_control_allocate_connection(fd);
+ if (!connection) {
+ close(fd);
+ EPRINTF("failed to allocate new control connection\n");
+ }
+
+ err = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
+ connection->socket, 0,
+ tapdisk_control_handle_request,
+ connection);
+ if (err == -1) {
+ close(fd);
+ free(connection);
+ EPRINTF("failed to register new control event: %d\n", err);
+ }
+
+ connection->event_id = err;
+}
+
+static int
+tapdisk_control_mkdir(const char *dir)
+{
+ int err;
+ char *ptr, *name, *start;
+
+ err = access(dir, W_OK | R_OK);
+ if (!err)
+ return 0;
+
+ name = strdup(dir);
+ if (!name)
+ return -ENOMEM;
+
+ start = name;
+
+ for (;;) {
+ ptr = strchr(start + 1, '/');
+ if (ptr)
+ *ptr = '\0';
+
+ err = mkdir(name, 0755);
+ if (err && errno != EEXIST) {
+ err = -errno;
+ EPRINTF("failed to create directory %s: %d\n",
+ name, err);
+ break;
+ }
+
+ if (!ptr)
+ break;
+ else {
+ *ptr = '/';
+ start = ptr + 1;
+ }
+ }
+
+ free(name);
+ return err;
+}
+
+static int
+tapdisk_control_create_socket(char **socket_path)
+{
+ int err, flags;
+ struct sockaddr_un saddr;
+
+ err = tapdisk_control_mkdir(BLKTAP2_CONTROL_DIR);
+ if (err) {
+ EPRINTF("failed to create directory %s: %d\n",
+ BLKTAP2_CONTROL_DIR, err);
+ 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;
+ EPRINTF("failed to create control socket: %d\n", err);
+ goto fail;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ 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", saddr.sun_path, err);
+ goto fail;
+ }
+
+ err = listen(td_control.socket, 10);
+ if (err == -1) {
+ err = errno;
+ EPRINTF("failed to listen: %d\n", err);
+ goto fail;
+ }
+
+ err = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,
+ td_control.socket, 0,
+ tapdisk_control_accept, NULL);
+ if (err < 0) {
+ EPRINTF("failed to add watch: %d\n", err);
+ goto fail;
+ }
+
+ td_control.event_id = err;
+ *socket_path = td_control.path;
+
+ return 0;
+
+fail:
+ tapdisk_control_close();
+ return err;
+}
+
+int
+tapdisk_control_open(char **path)
+{
+ int err;
+
+ tapdisk_control_initialize();
+
+ return tapdisk_control_create_socket(path);
+}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk-control.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/drivers/tapdisk-control.h Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TAPDISK_CONTROL_H__
+#define __TAPDISK_CONTROL_H__
+
+int tapdisk_control_open(char **path);
+void tapdisk_control_close(void);
+
+#endif
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk-server.c
--- a/tools/blktap2/drivers/tapdisk-server.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-server.c Mon Jun 07 14:53:16 2010 -0700
@@ -63,6 +63,12 @@
return NULL;
}
+struct list_head *
+tapdisk_server_get_all_vbds(void)
+{
+ return &server.vbds;
+}
+
td_vbd_t *
tapdisk_server_get_vbd(uint16_t uuid)
{
@@ -218,24 +224,29 @@
tapdisk_server_close_aio();
}
+void
+tapdisk_server_iterate(void)
+{
+ int ret;
+
+ tapdisk_server_assert_locks();
+ tapdisk_server_set_retry_timeout();
+ tapdisk_server_check_progress();
+
+ ret = scheduler_wait_for_events(&server.scheduler);
+ if (ret < 0)
+ DBG(TLOG_WARN, "server wait returned %d\n", ret);
+
+ tapdisk_server_check_vbds();
+ tapdisk_server_submit_tiocbs();
+ tapdisk_server_kick_responses();
+}
+
static void
__tapdisk_server_run(void)
{
- int ret;
-
- while (server.run) {
- tapdisk_server_assert_locks();
- tapdisk_server_set_retry_timeout();
- tapdisk_server_check_progress();
-
- ret = scheduler_wait_for_events(&server.scheduler);
- if (ret < 0)
- DBG(TLOG_WARN, "server wait returned %d\n", ret);
-
- tapdisk_server_check_vbds();
- tapdisk_server_submit_tiocbs();
- tapdisk_server_kick_responses();
- }
+ while (server.run)
+ tapdisk_server_iterate();
}
static void
@@ -267,22 +278,50 @@
}
int
+tapdisk_server_init(void)
+{
+ memset(&server, 0, sizeof(server));
+ INIT_LIST_HEAD(&server.vbds);
+
+ scheduler_initialize(&server.scheduler);
+
+ return 0;
+}
+
+int
+tapdisk_server_complete(void)
+{
+ int err;
+
+ err = tapdisk_server_init_aio();
+ if (err)
+ goto fail;
+
+ server.run = 1;
+
+ return 0;
+
+fail:
+ tapdisk_server_close_aio();
+ return err;
+}
+
+int
tapdisk_server_initialize(void)
{
int err;
- memset(&server, 0, sizeof(tapdisk_server_t));
- INIT_LIST_HEAD(&server.vbds);
+ tapdisk_server_init();
- scheduler_initialize(&server.scheduler);
-
- err = tapdisk_server_init_aio();
+ err = tapdisk_server_complete();
if (err)
- return err;
-
- server.run = 1;
+ goto fail;
return 0;
+
+fail:
+ tapdisk_server_close();
+ return err;
}
int
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk-server.h
--- a/tools/blktap2/drivers/tapdisk-server.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-server.h Mon Jun 07 14:53:16 2010 -0700
@@ -28,6 +28,7 @@
#ifndef _TAPDISK_SERVER_H_
#define _TAPDISK_SERVER_H_
+#include "list.h"
#include "tapdisk-vbd.h"
#include "tapdisk-queue.h"
@@ -35,6 +36,7 @@
td_image_t *tapdisk_server_get_shared_image(td_image_t *);
+struct list_head *tapdisk_server_get_all_vbds(void);
td_vbd_t *tapdisk_server_get_vbd(td_uuid_t);
void tapdisk_server_add_vbd(td_vbd_t *);
void tapdisk_server_remove_vbd(td_vbd_t *);
@@ -47,8 +49,11 @@
void tapdisk_server_unregister_event(event_id_t);
void tapdisk_server_set_max_timeout(int);
+int tapdisk_server_init(void);
int tapdisk_server_initialize(void);
+int tapdisk_server_complete(void);
int tapdisk_server_run(void);
+void tapdisk_server_iterate(void);
#define TAPDISK_TIOCBS (TAPDISK_DATA_REQUESTS + 50)
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk-vbd.c
--- a/tools/blktap2/drivers/tapdisk-vbd.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-vbd.c Mon Jun 07 14:53:16 2010 -0700
@@ -38,7 +38,6 @@
#include <memshr.h>
#endif
-#include "libvhd.h"
#include "tapdisk-image.h"
#include "tapdisk-driver.h"
#include "tapdisk-server.h"
@@ -93,25 +92,20 @@
}
}
-int
-tapdisk_vbd_initialize(uint16_t uuid)
+td_vbd_t*
+tapdisk_vbd_create(uint16_t uuid)
{
+ td_vbd_t *vbd;
int i;
- td_vbd_t *vbd;
-
- vbd = tapdisk_server_get_vbd(uuid);
- if (vbd) {
- EPRINTF("duplicate vbds! %u\n", uuid);
- return -EEXIST;
- }
vbd = calloc(1, sizeof(td_vbd_t));
if (!vbd) {
EPRINTF("failed to allocate tapdisk state\n");
- return -ENOMEM;
+ return NULL;
}
vbd->uuid = uuid;
+ vbd->minor = -1;
vbd->ring.fd = -1;
/* default blktap ring completion */
@@ -134,6 +128,22 @@
for (i = 0; i < MAX_REQUESTS; i++)
tapdisk_vbd_initialize_vreq(vbd->request_list + i);
+ return vbd;
+}
+
+int
+tapdisk_vbd_initialize(uint16_t uuid)
+{
+ td_vbd_t *vbd;
+
+ vbd = tapdisk_server_get_vbd(uuid);
+ if (vbd) {
+ EPRINTF("duplicate vbds! %u\n", uuid);
+ return -EEXIST;
+ }
+
+ vbd = tapdisk_vbd_create(uuid);
+
tapdisk_server_add_vbd(vbd);
return 0;
@@ -181,6 +191,8 @@
INIT_LIST_HEAD(&vbd->images);
td_flag_set(vbd->state, TD_VBD_CLOSED);
+
+ tapdisk_vbd_free_stack(vbd);
}
static int
@@ -646,9 +658,42 @@
return 0;
}
+void
+tapdisk_vbd_detach(td_vbd_t *vbd)
+{
+ tapdisk_vbd_unregister_events(vbd);
+
+ tapdisk_vbd_unmap_device(vbd);
+ vbd->minor = -1;
+}
+
+
+int
+tapdisk_vbd_attach(td_vbd_t *vbd, const char *devname, int minor)
+{
+ int err;
+
+ err = tapdisk_vbd_map_device(vbd, devname);
+ if (err)
+ goto fail;
+
+ err = tapdisk_vbd_register_event_watches(vbd);
+ if (err)
+ goto fail;
+
+ vbd->minor = minor;
+
+ return 0;
+
+fail:
+ tapdisk_vbd_detach(vbd);
+
+ return err;
+}
+
int
tapdisk_vbd_open(td_vbd_t *vbd, const char *name, uint16_t type,
- uint16_t storage, const char *ring, td_flag_t flags)
+ uint16_t storage, int minor, const char *ring, td_flag_t flags)
{
int err;
@@ -656,20 +701,15 @@
if (err)
goto out;
- err = tapdisk_vbd_map_device(vbd, ring);
- if (err)
- goto out;
-
- err = tapdisk_vbd_register_event_watches(vbd);
+ err = tapdisk_vbd_attach(vbd, ring, minor);
if (err)
goto out;
return 0;
out:
+ tapdisk_vbd_detach(vbd);
tapdisk_vbd_close_vdi(vbd);
- tapdisk_vbd_unmap_device(vbd);
- tapdisk_vbd_unregister_events(vbd);
free(vbd->name);
vbd->name = NULL;
return err;
@@ -727,11 +767,9 @@
vbd->kicked);
tapdisk_vbd_close_vdi(vbd);
- tapdisk_vbd_unregister_events(vbd);
- tapdisk_vbd_unmap_device(vbd);
+ tapdisk_vbd_detach(vbd);
tapdisk_server_remove_vbd(vbd);
- free(vbd->name);
- free(vbd);
+ tapdisk_vbd_free(vbd);
tlog_print_errors();
@@ -941,17 +979,18 @@
return -EINVAL;
}
- free(vbd->name);
- vbd->name = strdup(path);
- if (!vbd->name) {
- EPRINTF("copying new vbd %s name failed\n", path);
- return -EINVAL;
+ if (path) {
+ free(vbd->name);
+ vbd->name = strdup(path);
+ if (!vbd->name) {
+ EPRINTF("copying new vbd %s name failed\n", path);
+ return -EINVAL;
+ }
}
- vbd->type = drivertype;
for (i = 0; i < TD_VBD_EIO_RETRIES; i++) {
err = __tapdisk_vbd_open_vdi(vbd, TD_OPEN_STRICT);
- if (!err)
+ if (err != -EIO)
break;
sleep(TD_VBD_EIO_SLEEP);
@@ -963,6 +1002,7 @@
tapdisk_vbd_start_queue(vbd);
td_flag_clear(vbd->state, TD_VBD_PAUSED);
td_flag_clear(vbd->state, TD_VBD_PAUSE_REQUESTED);
+ tapdisk_vbd_check_state(vbd);
return 0;
}
@@ -1607,7 +1647,6 @@
err = -ENOMEM;
goto out;
}
- vbd->type = type;
tapdisk_vbd_start_queue(vbd);
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk-vbd.h
--- a/tools/blktap2/drivers/tapdisk-vbd.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk-vbd.h Mon Jun 07 14:53:16 2010 -0700
@@ -89,7 +89,7 @@
char *name;
td_uuid_t uuid;
- int type;
+ int minor;
struct list_head driver_stack;
@@ -168,18 +168,24 @@
return list_entry(image->next.next, td_image_t, next);
}
+td_vbd_t *tapdisk_vbd_create(td_uuid_t);
int tapdisk_vbd_initialize(td_uuid_t);
void tapdisk_vbd_set_callback(td_vbd_t *, td_vbd_cb_t, void *);
int tapdisk_vbd_parse_stack(td_vbd_t *vbd, const char *path);
int tapdisk_vbd_open(td_vbd_t *, const char *, uint16_t,
- uint16_t, const char *, td_flag_t);
+ uint16_t, int, const char *, td_flag_t);
int tapdisk_vbd_close(td_vbd_t *);
+void tapdisk_vbd_free(td_vbd_t *);
void tapdisk_vbd_free_stack(td_vbd_t *);
+int tapdisk_vbd_open_stack(td_vbd_t *, uint16_t, td_flag_t);
int tapdisk_vbd_open_vdi(td_vbd_t *, const char *,
uint16_t, uint16_t, td_flag_t);
void tapdisk_vbd_close_vdi(td_vbd_t *);
+int tapdisk_vbd_attach(td_vbd_t *, const char *, int);
+void tapdisk_vbd_detach(td_vbd_t *);
+
void tapdisk_vbd_forward_request(td_request_t);
int tapdisk_vbd_get_image_info(td_vbd_t *, image_t *);
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/drivers/tapdisk2.c
--- a/tools/blktap2/drivers/tapdisk2.c Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/drivers/tapdisk2.c Mon Jun 07 14:53:16 2010 -0700
@@ -28,397 +28,37 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+#include <stdlib.h>
#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
#ifdef MEMSHR
#include <memshr.h>
#endif
#include "tapdisk.h"
-#include "blktap2.h"
-#include "tapdisk-vbd.h"
#include "tapdisk-utils.h"
#include "tapdisk-server.h"
-#include "tapdisk-disktype.h"
-
-#define TAPDISK2_VBD 0
-
-#define cprintf(_err, _f, _a...) \
- do { \
- if (child_out) { \
- fprintf(child_out, "%d: " _f, _err, ##_a); \
- fflush(child_out); \
- } \
- } while (0)
-
-#define CHILD_ERR(_err, _f, _a...) \
- do { \
- EPRINTF(_f, ##_a); \
- cprintf(_err, _f, ##_a); \
- } while (0)
-
-static int channel[2];
-static FILE *child_out;
-static struct blktap2_handle handle;
-
-static int
-tapdisk2_prepare_directory(void)
-{
- int err;
- char *ptr, *name, *start;
-
- err = access(BLKTAP2_DIRECTORY, W_OK | R_OK);
- if (!err)
- return 0;
-
- name = strdup(BLKTAP2_DIRECTORY);
- if (!name)
- return -ENOMEM;
-
- start = name;
-
- for (;;) {
- ptr = strchr(start + 1, '/');
- if (ptr)
- *ptr = '\0';
-
- err = mkdir(name, 0755);
- if (err && errno != EEXIST) {
- err = -errno;
- CHILD_ERR(err, "failed to create directory %s: %d\n",
- name, err);
- break;
- }
-
- if (!ptr)
- break;
- else {
- *ptr = '/';
- start = ptr + 1;
- }
- }
-
- free(name);
- return err;
-}
-
-static int
-tapdisk2_make_device(char *devname, int major, int minor, int perm)
-{
- int err;
- struct stat st;
-
- err = tapdisk2_prepare_directory();
- if (err)
- return err;
-
- if (!access(devname, F_OK))
- if (unlink(devname)) {
- CHILD_ERR(errno, "error unlinking %s: %d\n",
- devname, errno);
- return -errno;
- }
-
- err = mknod(devname, perm, makedev(major, minor));
- if (err) {
- CHILD_ERR(errno, "mknod %s failed: %d\n", devname, -errno);
- return -errno;
- }
-
- DPRINTF("Created %s device\n", devname);
- return 0;
-}
-
-static int
-tapdisk2_check_environment(void)
-{
- FILE *f;
- int err, minor;
- char name[256];
-
- if (!access(BLKTAP2_CONTROL_DEVICE, R_OK | W_OK))
- return 0;
-
- memset(name, 0, sizeof(name));
-
- f = fopen("/proc/misc", "r");
- if (!f) {
- CHILD_ERR(errno, "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 = tapdisk2_make_device(BLKTAP2_CONTROL_DEVICE,
- MISC_MAJOR_NUMBER,
- minor, S_IFCHR | 0600);
- goto out;
- }
-
- err = -ENOSYS;
- CHILD_ERR(err, "didn't find %s in /proc/misc\n", BLKTAP2_CONTROL_NAME);
-
-out:
- fclose(f);
- return err;
-}
-
-static void
-tapdisk2_free_device(void)
-{
- int fd, err;
-
- fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
- if (fd == -1) {
- CHILD_ERR(errno, "failed to open control device: %d\n", errno);
- return;
- }
-
- err = ioctl(fd, BLKTAP2_IOCTL_FREE_TAP, handle.minor);
- close(fd);
-}
-
-static int
-tapdisk2_prepare_device(void)
-{
- char *name;
- int fd, err;
-
- fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY);
- if (fd == -1) {
- CHILD_ERR(errno, "failed to open control device: %d\n", errno);
- return -errno;
- }
-
- err = ioctl(fd, BLKTAP2_IOCTL_ALLOC_TAP, &handle);
- close(fd);
- if (err == -1) {
- CHILD_ERR(errno, "failed to allocate new device: %d\n", errno);
- return -errno;
- }
-
- err = asprintf(&name, "%s%d", BLKTAP2_RING_DEVICE, handle.minor);
- if (err == -1) {
- err = -ENOMEM;
- goto fail;
- }
-
- err = tapdisk2_make_device(name, handle.ring,
- handle.minor, S_IFCHR | 0600);
- free(name);
- if (err) {
- CHILD_ERR(err, "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;
- }
-
- err = tapdisk2_make_device(name, handle.device,
- handle.minor, S_IFBLK | 0600);
- free(name);
- if (err) {
- CHILD_ERR(err, "creating IO device for %d failed: %d\n",
- handle.minor, err);
- goto fail;
- }
-
- DPRINTF("new interface: ring: %u, device: %u, minor: %u\n",
- handle.ring, handle.device, handle.minor);
-
- return 0;
-
-fail:
- tapdisk2_free_device();
- return err;
-}
-
-static int
-tapdisk2_open_device(int type, const char *path, const char *name)
-{
- int err;
- td_vbd_t *vbd;
- image_t image;
- char *devname;
- struct blktap2_params params;
-
- err = tapdisk_vbd_initialize(TAPDISK2_VBD);
- if (err)
- return err;
-
- vbd = tapdisk_server_get_vbd(TAPDISK2_VBD);
- if (!vbd) {
- err = -ENODEV;
- CHILD_ERR(err, "couldn't find vbd\n");
- return err;
- }
-
- err = asprintf(&devname, "%s%d", BLKTAP2_RING_DEVICE, handle.minor);
- if (err == -1) {
- err = -ENOMEM;
- CHILD_ERR(err, "couldn't allocate ring\n");
- return err;
- }
-
- err = tapdisk_vbd_parse_stack(vbd, name);
- if (err) {
- CHILD_ERR(err, "vbd_parse_stack failed: %d\n", err);
- return err;
- }
-
- /* TODO: clean this up */
- err = tapdisk_vbd_open(vbd, path, type,
- TAPDISK_STORAGE_TYPE_DEFAULT,
- devname, 0);
- free(devname);
- if (err) {
- CHILD_ERR(err, "vbd open failed: %d\n", err);
- return err;
- }
-
- memset(¶ms, 0, sizeof(params));
- tapdisk_vbd_get_image_info(vbd, &image);
-
- params.capacity = image.size;
- params.sector_size = image.secsize;
- snprintf(params.name, sizeof(params.name) - 1, "%s", name);
-
- err = ioctl(vbd->ring.fd, BLKTAP2_IOCTL_CREATE_DEVICE, ¶ms);
- if (err) {
- err = -errno;
- CHILD_ERR(err, "create device failed: %d\n", err);
- return err;
- }
-
- return 0;
-}
-
-static int
-tapdisk2_set_child_fds(void)
-{
- int i, err;
-
- err = dup2(channel[1], STDOUT_FILENO);
- if (err == -1) {
- CHILD_ERR(errno, "failed duping pipe: %d\n", errno);
- return errno;
- }
-
- child_out = fdopen(STDOUT_FILENO, "w");
- if (!child_out) {
- CHILD_ERR(errno, "failed setting child_out: %d\n", errno);
- return errno;
- }
-
- for (i = 0; i < sysconf(_SC_OPEN_MAX); i++)
- if (i != STDOUT_FILENO)
- close(i);
-
- return 0;
-}
-
-static int
-tapdisk2_create_device(const char *params)
-{
- const char *path;
- int err, type;
-
- chdir("/");
- tapdisk_start_logging("tapdisk2");
-
- err = tapdisk2_set_child_fds();
- if (err)
- goto out;
-
- err = tapdisk2_check_environment();
- if (err)
- goto out;
-
- err = tapdisk_parse_disk_type(params, &path, &type);
- if (err)
- goto out;
-
- err = tapdisk2_prepare_device();
- if (err)
- goto out;
-
- err = tapdisk_server_initialize();
- if (err)
- goto fail;
-
- err = tapdisk2_open_device(type, path, params);
- if (err)
- goto fail;
-
- cprintf(0, "%s%d\n", BLKTAP2_IO_DEVICE, handle.minor);
- close(STDOUT_FILENO);
-
- err = tapdisk_server_run();
- if (err)
- goto fail;
-
- err = 0;
-
-out:
- tapdisk_stop_logging();
- return err;
-
-fail:
- tapdisk2_free_device();
- goto out;
-}
-
-static int
-tapdisk2_wait_for_device(void)
-{
- int err;
- char msg[1024];
- FILE *parent_in;
-
- close(channel[1]);
- parent_in = fdopen(channel[0], "r");
- if (!parent_in) {
- printf("failed to connect to child: %d\n", errno);
- return errno;
- }
-
- memset(msg, 0, sizeof(msg));
- if (fscanf(parent_in, "%d: %1023[^\n]", &err, msg) != 2) {
- printf("unrecognized child response\n");
- return EINVAL;
- }
-
- printf("%s\n", msg);
- return (err >= 0 ? err : -err);
-}
+#include "tapdisk-control.h"
static void
usage(const char *app, int err)
{
- fprintf(stderr, "usage: %s <-n file>\n", app);
+ fprintf(stderr, "usage: %s <-u uuid> <-c control socket>\n", app);
exit(err);
}
int
main(int argc, char *argv[])
{
- int c;
- char *params;
+ char *control;
+ int c, err, nodaemon;
- params = NULL;
+ control = NULL;
+ nodaemon = 0;
- while ((c = getopt(argc, argv, "n:s:h")) != -1) {
+ while ((c = getopt(argc, argv, "s:Dh")) != -1) {
switch (c) {
- case 'n':
- params = optarg;
+ case 'D':
+ nodaemon = 1;
break;
case 'h':
usage(argv[0], 0);
@@ -436,21 +76,58 @@
}
}
- if (!params || optind != argc)
+ if (optind != argc)
usage(argv[0], EINVAL);
- if (pipe(channel) == -1) {
- printf("pipe failed: %d\n", errno);
- return errno;
+ chdir("/");
+ tapdisk_start_logging("tapdisk2");
+
+ err = tapdisk_server_init();
+ if (err) {
+ DPRINTF("failed to initialize server: %d\n", err);
+ goto out;
}
- switch (fork()) {
- case -1:
- printf("fork failed: %d\n", errno);
- return errno;
- case 0:
- return tapdisk2_create_device(params);
- default:
- return tapdisk2_wait_for_device();
+ 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) {
+ 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);
+ }
+ }
+
+ err = tapdisk_server_complete();
+ if (err) {
+ DPRINTF("failed to complete server: %d\n", err);
+ goto out;
+ }
+
+ err = tapdisk_server_run();
+
+out:
+ tapdisk_control_close();
+ tapdisk_stop_logging();
+ return err;
}
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/include/blktap2.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/blktap2/include/blktap2.h Mon Jun 07 14:53:16 2010 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of XenSource Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _BLKTAP_2_H_
+#define _BLKTAP_2_H_
+
+#define BLKTAP2_MAX_MESSAGE_LEN 256
+
+#define BLKTAP2_RING_MESSAGE_PAUSE 1
+#define BLKTAP2_RING_MESSAGE_RESUME 2
+#define BLKTAP2_RING_MESSAGE_CLOSE 3
+
+#define BLKTAP2_IOCTL_KICK_FE 1
+#define BLKTAP2_IOCTL_ALLOC_TAP 200
+#define BLKTAP2_IOCTL_FREE_TAP 201
+#define BLKTAP2_IOCTL_CREATE_DEVICE 202
+#define BLKTAP2_IOCTL_SET_PARAMS 203
+#define BLKTAP2_IOCTL_PAUSE 204
+#define BLKTAP2_IOCTL_REOPEN 205
+#define BLKTAP2_IOCTL_RESUME 206
+
+#define BLKTAP2_SYSFS_DIR "/sys/class/blktap2"
+#define BLKTAP2_CONTROL_NAME "blktap-control"
+#define BLKTAP2_CONTROL_DIR "/var/run/"BLKTAP2_CONTROL_NAME
+#define BLKTAP2_CONTROL_SOCKET "ctl"
+#define BLKTAP2_DIRECTORY "/dev/xen/blktap-2"
+#define BLKTAP2_CONTROL_DEVICE BLKTAP2_DIRECTORY"/control"
+#define BLKTAP2_RING_DEVICE BLKTAP2_DIRECTORY"/blktap"
+#define BLKTAP2_IO_DEVICE BLKTAP2_DIRECTORY"/tapdev"
+
+struct blktap2_handle {
+ unsigned int ring;
+ unsigned int device;
+ unsigned int minor;
+};
+
+struct blktap2_params {
+ char name[BLKTAP2_MAX_MESSAGE_LEN];
+ unsigned long long capacity;
+ unsigned long sector_size;
+};
+
+#endif
diff -r 3ea1751e3fe7 -r ccef87cf5f41 tools/blktap2/include/tapdisk-message.h
--- a/tools/blktap2/include/tapdisk-message.h Mon Jun 07 14:53:15 2010 -0700
+++ b/tools/blktap2/include/tapdisk-message.h Mon Jun 07 14:53:16 2010 -0700
@@ -33,6 +33,9 @@
#define TAPDISK_MESSAGE_MAX_PATH_LENGTH 256
#define TAPDISK_MESSAGE_STRING_LENGTH 256
+#define TAPDISK_MESSAGE_MAX_MINORS \
+ ((TAPDISK_MESSAGE_MAX_PATH_LENGTH / sizeof(int)) - 1)
+
#define TAPDISK_MESSAGE_FLAG_SHARED 0x01
#define TAPDISK_MESSAGE_FLAG_RDONLY 0x02
#define TAPDISK_MESSAGE_FLAG_ADD_CACHE 0x04
@@ -44,10 +47,13 @@
typedef struct tapdisk_message_image tapdisk_message_image_t;
typedef struct tapdisk_message_params tapdisk_message_params_t;
typedef struct tapdisk_message_string tapdisk_message_string_t;
+typedef struct tapdisk_message_response tapdisk_message_response_t;
+typedef struct tapdisk_message_minors tapdisk_message_minors_t;
+typedef struct tapdisk_message_list tapdisk_message_list_t;
struct tapdisk_message_params {
tapdisk_message_flag_t flags;
-
+
uint8_t storage;
uint32_t devnum;
uint32_t domid;
@@ -65,6 +71,23 @@
char text[TAPDISK_MESSAGE_STRING_LENGTH];
};
+struct tapdisk_message_response {
+ int error;
+ char message[TAPDISK_MESSAGE_STRING_LENGTH];
+};
+
+struct tapdisk_message_minors {
+ int count;
+ int list[TAPDISK_MESSAGE_MAX_MINORS];
+};
+
+struct tapdisk_message_list {
+ int count;
+ int minor;
+ int state;
+ char path[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
+};
+
struct tapdisk_message {
uint16_t type;
uint16_t cookie;
@@ -74,6 +97,9 @@
tapdisk_message_image_t image;
tapdisk_message_params_t params;
tapdisk_message_string_t string;
+ tapdisk_message_minors_t minors;
+ tapdisk_message_response_t response;
+ tapdisk_message_list_t list;
} u;
};
@@ -82,6 +108,8 @@
TAPDISK_MESSAGE_RUNTIME_ERROR,
TAPDISK_MESSAGE_PID,
TAPDISK_MESSAGE_PID_RSP,
+ TAPDISK_MESSAGE_ATTACH,
+ TAPDISK_MESSAGE_ATTACH_RSP,
TAPDISK_MESSAGE_OPEN,
TAPDISK_MESSAGE_OPEN_RSP,
TAPDISK_MESSAGE_PAUSE,
@@ -90,6 +118,13 @@
TAPDISK_MESSAGE_RESUME_RSP,
TAPDISK_MESSAGE_CLOSE,
TAPDISK_MESSAGE_CLOSE_RSP,
+ TAPDISK_MESSAGE_DETACH,
+ TAPDISK_MESSAGE_DETACH_RSP,
+ TAPDISK_MESSAGE_LIST_MINORS,
+ TAPDISK_MESSAGE_LIST_MINORS_RSP,
+ TAPDISK_MESSAGE_LIST,
+ TAPDISK_MESSAGE_LIST_RSP,
+ TAPDISK_MESSAGE_FORCE_SHUTDOWN,
TAPDISK_MESSAGE_EXIT,
};
@@ -127,9 +162,36 @@
case TAPDISK_MESSAGE_CLOSE:
return "close";
+ case TAPDISK_MESSAGE_FORCE_SHUTDOWN:
+ return "force shutdown";
+
case TAPDISK_MESSAGE_CLOSE_RSP:
return "close response";
+ case TAPDISK_MESSAGE_ATTACH:
+ return "attach";
+
+ case TAPDISK_MESSAGE_ATTACH_RSP:
+ return "attach response";
+
+ case TAPDISK_MESSAGE_DETACH:
+ return "detach";
+
+ case TAPDISK_MESSAGE_DETACH_RSP:
+ return "detach response";
+
+ case TAPDISK_MESSAGE_LIST_MINORS:
+ return "list minors";
+
+ case TAPDISK_MESSAGE_LIST_MINORS_RSP:
+ return "list minors response";
+
+ case TAPDISK_MESSAGE_LIST:
+ return "list";
+
+ case TAPDISK_MESSAGE_LIST_RSP:
+ return "list response";
+
case TAPDISK_MESSAGE_EXIT:
return "exit";
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 25+ messages in thread