libblktapctl_la_SOURCES += tap-ctl-major.c
libblktapctl_la_SOURCES += tap-ctl-check.c
libblktapctl_la_SOURCES += tap-ctl-stats.c
+libblktapctl_la_SOURCES += tap-ctl-xen.c
+libblktapctl_la_SOURCES += tap-ctl-xen.h
libblktapctl_la_LDFLAGS = -release $(VERSION)
--- /dev/null
+/*
+ * Copyright (c) 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 <stdio.h>
+#include <string.h>
+
+#include "tap-ctl.h"
+#include "tap-ctl-xen.h"
+
+int
+tap_ctl_connect_xenblkif(pid_t pid, int minor,
+ domid_t domid, int devid,
+ const grant_ref_t *grefs, int order,
+ int proto,
+ evtchn_port_t port)
+{
+ tapdisk_message_t message;
+ int i, err;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_XENBLKIF_CONNECT;
+ message.cookie = minor;
+
+ message.u.blkif.domid = domid;
+ message.u.blkif.devid = devid;
+ message.u.blkif.order = order;
+ message.u.blkif.port = port;
+
+ for (i = 0; i < 1<<order; i++)
+ message.u.blkif.gref[i] = grefs[i];
+
+ err = tap_ctl_connect_send_and_receive(pid, &message, NULL);
+ if (err)
+ return err;
+
+ if (message.type == TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP)
+ err = -message.u.response.error;
+ else
+ err = -EINVAL;
+
+ return err;
+}
+
+int
+tap_ctl_disconnect_xenblkif(pid_t pid, int minor,
+ domid_t domid, int devid,
+ struct timeval *timeout)
+{
+ tapdisk_message_t message;
+ int err;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_XENBLKIF_DISCONNECT;
+ message.cookie = minor;
+ message.u.blkif.domid = domid;
+ message.u.blkif.devid = devid;
+
+ err = tap_ctl_connect_send_and_receive(pid, &message, timeout);
+ if (message.type == TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP)
+ err = -message.u.response.error;
+ else
+ err = -EINVAL;
+
+ return err;
+}
--- /dev/null
+/*
+ * Copyright (c) 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 __TAP_CTL_XEN_H__
+#define __TAP_CTL_XEN_H__
+
+#include <xen/xen.h>
+#include <xen/grant_table.h>
+#include <xen/event_channel.h>
+
+int tap_ctl_connect_xenblkif(pid_t pid, int minor,
+ domid_t domid, int devid,
+ const grant_ref_t *grefs, int order,
+ int proto,
+ evtchn_port_t port);
+
+int tap_ctl_disconnect_xenblkif(pid_t pid, int minor,
+ domid_t domid, int devid,
+ struct timeval *timeout);
+
+#endif /* __TAP_CTL_XEN_H__ */
#include "tapdisk-message.h"
#include "tapdisk-disktype.h"
#include "tapdisk-stats.h"
+#include "tapdisk-xenblkif.h"
#include "tapdisk-control.h"
#define TD_CTL_MAX_CONNECTIONS 10
struct tapdisk_control_info *info;
};
-#define TAPDISK_MSG_REENTER (1<<0) /* non-blocking, idempotent */
-#define TAPDISK_MSG_VERBOSE (1<<1) /* tell syslog about it */
+#define TAPDISK_MSG_REENTER (1<<0) /* non-blocking, idempotent */
+#define TAPDISK_MSG_VERBOSE (1<<1) /* tell syslog about it */
+#define TAPDISK_MSG_VERBOSE_ERROR (1<<2) /* tell syslog about it, with errors */
struct tapdisk_control_info {
void (*handler)(struct tapdisk_ctl_conn *, tapdisk_message_t *);
tapdisk_message_t *message)
{
size_t size = sizeof(*message), count;
+ long flags = conn->info->flags;
- if (conn->info->flags & TAPDISK_MSG_VERBOSE)
- DBG("sending '%s' message (uuid = %u)\n",
- tapdisk_message_name(message->type), message->cookie);
+ if (flags & TAPDISK_MSG_VERBOSE) {
+ if (flags & TAPDISK_MSG_VERBOSE_ERROR)
+ DBG("sending '%s' message (uuid = %u): %d",
+ tapdisk_message_name(message->type), message->cookie,
+ message->u.response.error);
+ else
+ DBG("sending '%s' message (uuid = %u)",
+ tapdisk_message_name(message->type), message->cookie);
+ }
count = tapdisk_ctl_conn_write(conn, message, size);
WARN_ON(count != size);
conn->out.prod += rv;
}
+static void
+tapdisk_control_xenblkif_connect(struct tapdisk_ctl_conn *conn,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_blkif_t *blkif = &request->u.blkif;
+ tapdisk_message_t response;
+ td_vbd_t *vbd;
+ int err;
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ DPRINTF("connecting vbd-%d-%d to vbd %d\n",
+ blkif->domid, blkif->devid, request->cookie);
+
+ err = tapdisk_xenblkif_connect(blkif->domid, blkif->devid,
+ blkif->gref, blkif->order,
+ blkif->proto, blkif->port,
+ NULL, vbd);
+out:
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP;
+ response.cookie = request->cookie;
+ response.u.response.error = -err;
+ tapdisk_control_write_message(conn, &response);
+}
+
+static void
+tapdisk_control_xenblkif_disconnect(struct tapdisk_ctl_conn *conn,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_blkif_t *blkif = &request->u.blkif;
+ tapdisk_message_t response;
+ int err;
+
+ DPRINTF("disconnecting vbd-%d-%d from vbd %d\n",
+ blkif->domid, blkif->devid, request->cookie);
+
+ err = tapdisk_xenblkif_disconnect(blkif->domid, blkif->devid);
+
+out:
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP;
+ response.cookie = request->cookie;
+ response.u.response.error = -err;
+ tapdisk_control_write_message(conn, &response);
+}
+
+
struct tapdisk_control_info message_infos[] = {
[TAPDISK_MESSAGE_PID] = {
.handler = tapdisk_control_get_pid,
},
[TAPDISK_MESSAGE_ATTACH] = {
.handler = tapdisk_control_attach_vbd,
- .flags = TAPDISK_MSG_VERBOSE,
+ .flags = TAPDISK_MSG_VERBOSE|TAPDISK_MSG_VERBOSE_ERROR,
},
[TAPDISK_MESSAGE_DETACH] = {
.handler = tapdisk_control_detach_vbd,
- .flags = TAPDISK_MSG_VERBOSE,
+ .flags = TAPDISK_MSG_VERBOSE|TAPDISK_MSG_VERBOSE_ERROR,
},
[TAPDISK_MESSAGE_OPEN] = {
.handler = tapdisk_control_open_image,
},
[TAPDISK_MESSAGE_PAUSE] = {
.handler = tapdisk_control_pause_vbd,
- .flags = TAPDISK_MSG_VERBOSE,
+ .flags = TAPDISK_MSG_VERBOSE|TAPDISK_MSG_VERBOSE_ERROR,
},
[TAPDISK_MESSAGE_RESUME] = {
.handler = tapdisk_control_resume_vbd,
- .flags = TAPDISK_MSG_VERBOSE,
+ .flags = TAPDISK_MSG_VERBOSE|TAPDISK_MSG_VERBOSE_ERROR,
},
[TAPDISK_MESSAGE_CLOSE] = {
.handler = tapdisk_control_close_image,
- .flags = TAPDISK_MSG_VERBOSE,
+ .flags = TAPDISK_MSG_VERBOSE|TAPDISK_MSG_VERBOSE_ERROR,
},
[TAPDISK_MESSAGE_STATS] = {
.handler = tapdisk_control_stats,
.flags = TAPDISK_MSG_REENTER,
},
+ [TAPDISK_MESSAGE_XENBLKIF_CONNECT] = {
+ .handler = tapdisk_control_xenblkif_connect,
+ .flags = TAPDISK_MSG_VERBOSE|TAPDISK_MSG_VERBOSE_ERROR,
+ },
+ [TAPDISK_MESSAGE_XENBLKIF_DISCONNECT] = {
+ .handler = tapdisk_control_xenblkif_disconnect,
+ .flags = TAPDISK_MSG_VERBOSE||TAPDISK_MSG_VERBOSE_ERROR,
+ }
};
invalid:
err = -EINVAL;
- ERR(err, "rejecting unsupported message '%s'\n",
- tapdisk_message_name(message.type));
+ ERR(err, "rejecting unsupported message '%s' (%d)\n",
+ tapdisk_message_name(message.type), message.type);
goto error;
}
rlim.rlim_cur = RLIM_INFINITY;
rlim.rlim_max = RLIM_INFINITY;
+#if 0
err = setrlimit(RLIMIT_MEMLOCK, &rlim);
if (err == -1) {
EPRINTF("RLIMIT_MEMLOCK failed: %d\n", errno);
EPRINTF("mlockall failed: %d\n", errno);
return -errno;
}
+#endif
#define CORE_DUMP
#if defined(CORE_DUMP)
typedef struct tapdisk_message_minors tapdisk_message_minors_t;
typedef struct tapdisk_message_list tapdisk_message_list_t;
typedef struct tapdisk_message_stat tapdisk_message_stat_t;
+typedef struct tapdisk_message_blkif tapdisk_message_blkif_t;
struct tapdisk_message_params {
tapdisk_message_flag_t flags;
size_t length;
};
+struct tapdisk_message_blkif {
+ uint32_t domid;
+ uint32_t devid;
+ uint32_t gref[8];
+ uint32_t order;
+ uint32_t proto;
+ uint32_t port;
+};
struct tapdisk_message {
uint16_t type;
tapdisk_message_response_t response;
tapdisk_message_list_t list;
tapdisk_message_stat_t info;
+ tapdisk_message_blkif_t blkif;
} u;
};
TAPDISK_MESSAGE_STATS,
TAPDISK_MESSAGE_STATS_RSP,
TAPDISK_MESSAGE_FORCE_SHUTDOWN,
+ TAPDISK_MESSAGE_XENBLKIF_CONNECT,
+ TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP,
+ TAPDISK_MESSAGE_XENBLKIF_DISCONNECT,
+ TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP,
TAPDISK_MESSAGE_EXIT,
};
case TAPDISK_MESSAGE_STATS_RSP:
return "stats response";
+ case TAPDISK_MESSAGE_XENBLKIF_CONNECT:
+ return "blkif connect";
+
+ case TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP:
+ return "blkif connect response";
+
+ case TAPDISK_MESSAGE_XENBLKIF_DISCONNECT:
+ return "blkif disconnect";
+
+ case TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP:
+ return "blkif disconnect response";
+
case TAPDISK_MESSAGE_EXIT:
return "exit";