Marshals vbd/image/driver state into JSON object trees.
CTL_OBJS += tap-ctl-unpause.o
CTL_OBJS += tap-ctl-major.o
CTL_OBJS += tap-ctl-check.o
+CTL_OBJS += tap-ctl-stats.o
CTL_PICS = $(patsubst %.o,%.opic,$(CTL_OBJS))
int tap_ctl_debug = 0;
int
-tap_ctl_read_message(int fd, tapdisk_message_t *message,
- struct timeval *timeout)
+tap_ctl_read_raw(int fd, void *buf, size_t size, struct timeval *timeout)
{
fd_set readfds;
- int ret, len, offset;
-
- offset = 0;
- len = sizeof(tapdisk_message_t);
+ size_t offset = 0;
+ int ret;
- memset(message, 0, sizeof(tapdisk_message_t));
-
- while (offset < len) {
+ while (offset < size) {
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
if (ret == -1)
break;
else if (FD_ISSET(fd, &readfds)) {
- ret = read(fd, message + offset, len - offset);
+ ret = read(fd, buf + offset, size - offset);
if (ret <= 0)
break;
offset += ret;
break;
}
- if (offset != len) {
- EPRINTF("failure reading message\n");
+ if (offset != size) {
+ EPRINTF("failure reading data %zd/%zd\n", offset, size);
return -EIO;
}
+ return 0;
+}
+
+int
+tap_ctl_read_message(int fd, tapdisk_message_t *message,
+ struct timeval *timeout)
+{
+ size_t size = sizeof(tapdisk_message_t);
+ int err;
+
+ err = tap_ctl_read_raw(fd, message, size, timeout);
+ if (err)
+ return err;
+
DBG("received '%s' message (uuid = %u)\n",
tapdisk_message_name(message->type), message->cookie);
--- /dev/null
+/*
+ * Copyright (c) 2010, Citrix
+ * 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 <unistd.h>
+#include <sys/mman.h>
+
+#include "tap-ctl.h"
+
+int
+_tap_ctl_stats_connect_and_send(pid_t pid, int minor)
+{
+ struct timeval timeout = { .tv_sec = 10, .tv_usec = 0 };
+ tapdisk_message_t message;
+ int sfd, err;
+ size_t len;
+
+ err = tap_ctl_connect_id(pid, &sfd);
+ if (err)
+ return err;
+
+ memset(&message, 0, sizeof(message));
+ message.type = TAPDISK_MESSAGE_STATS;
+ message.cookie = minor;
+
+ err = tap_ctl_write_message(sfd, &message, &timeout);
+ if (err)
+ return err;
+
+ return sfd;
+}
+
+ssize_t
+tap_ctl_stats(pid_t pid, int minor, char *buf, size_t size)
+{
+ tapdisk_message_t message;
+ int sfd, err;
+ size_t len;
+
+ sfd = _tap_ctl_stats_connect_and_send(pid, minor);
+ if (sfd < 0)
+ return sfd;
+
+ err = tap_ctl_read_message(sfd, &message, NULL);
+ if (err)
+ return err;
+
+ len= message.u.info.length;
+ if (len < 0) {
+ err = len;
+ goto out;
+ }
+ if (size < len + 1)
+ len = size - 1;
+
+ err = tap_ctl_read_raw(sfd, buf, len, NULL);
+ if (err)
+ goto out;
+
+ buf[len] = 0;
+
+out:
+ close(sfd);
+ return err;
+}
+
+int
+tap_ctl_stats_fwrite(pid_t pid, int minor, FILE *stream)
+{
+ tapdisk_message_t message;
+ int sfd = -1, prot, flags, err;
+ size_t len, bufsz;
+ char *buf = MAP_FAILED;
+
+ prot = PROT_READ|PROT_WRITE;
+ flags = MAP_ANONYMOUS|MAP_PRIVATE;
+ bufsz = sysconf(_SC_PAGE_SIZE);
+
+ buf = mmap(NULL, bufsz, prot, flags, -1, 0);
+ if (buf == MAP_FAILED) {
+ buf = NULL;
+ err = -ENOMEM;
+ goto out;
+ }
+
+ sfd = _tap_ctl_stats_connect_and_send(pid, minor);
+ if (sfd < 0) {
+ err = sfd;
+ goto out;
+ }
+
+ err = tap_ctl_read_message(sfd, &message, NULL);
+ if (err)
+ goto out;
+
+ len = message.u.info.length;
+ err = len;
+ if (len < 0)
+ goto out;
+
+ while (len) {
+ fd_set rfds;
+ size_t in, out;
+ int n;
+
+ FD_ZERO(&rfds);
+ FD_SET(sfd, &rfds);
+
+ n = select(sfd + 1, &rfds, NULL, NULL, NULL);
+ err = n;
+ if (n < 0)
+ goto out;
+
+ in = read(sfd, buf, bufsz);
+ err = in;
+ if (in <= 0)
+ goto out;
+
+ len -= in;
+
+ out = fwrite(buf, in, 1, stream);
+ if (out != in) {
+ err = -errno;
+ goto out;
+ }
+ }
+
+out:
+ if (sfd >= 0)
+ close(sfd);
+ if (buf != MAP_FAILED)
+ munmap(buf, bufsz);
+
+ return err;
+}
return EINVAL;
}
+static void
+tap_cli_stats_usage(FILE *stream)
+{
+ fprintf(stream, "usage: info <-p pid> <-m minor>\n");
+}
+
+static int
+tap_cli_stats(int argc, char **argv)
+{
+ pid_t pid;
+ int c, minor, err;
+
+ 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_stats_usage(stdout);
+ return 0;
+ }
+ }
+
+ if (pid == -1 || minor == -1)
+ goto usage;
+
+ err = tap_ctl_stats_fwrite(pid, minor, stdout);
+ if (err)
+ return err;
+
+ fprintf(stdout, "\n");
+
+ return 0;
+
+usage:
+ tap_cli_stats_usage(stderr);
+ return EINVAL;
+}
+
static void
tap_cli_check_usage(FILE *stream)
{
{ .name = "close", .func = tap_cli_close },
{ .name = "pause", .func = tap_cli_pause },
{ .name = "unpause", .func = tap_cli_unpause },
+ { .name = "stats", .func = tap_cli_stats },
{ .name = "major", .func = tap_cli_major },
{ .name = "check", .func = tap_cli_check },
};
int tap_ctl_connect(const char *path, int *socket);
int tap_ctl_connect_id(int id, int *socket);
+int tap_ctl_read_raw(int fd, void *buf, size_t sz, struct timeval *timeout);
int tap_ctl_read_message(int fd, tapdisk_message_t *message,
struct timeval *timeout);
int tap_ctl_write_message(int fd, tapdisk_message_t *message,
int tap_ctl_pause(const int id, const int minor, struct timeval *timeout);
int tap_ctl_unpause(const int id, const int minor, const char *params);
+ssize_t tap_ctl_stats(pid_t pid, int minor, char *buf, size_t size);
+int tap_ctl_stats_fwrite(pid_t pid, int minor, FILE *out);
+
int tap_ctl_blk_major(void);
#endif
TAP-OBJS += tapdisk-utils.o
TAP-OBJS += tapdisk-disktype.o
TAP-OBJS += tapdisk-syslog.o
+TAP-OBJS += tapdisk-stats.o
TAP-OBJS += io-optimize.o
TAP-OBJS += lock.o
return -EINVAL;
}
+void tdaio_stats(td_driver_t *driver, td_stats_t *st)
+{
+ struct tdaio_state *prv = (struct tdaio_state *)driver->data;
+ int n_pending;
+
+ n_pending = MAX_AIO_REQS - prv->aio_free_count;
+
+ tapdisk_stats_field(st, "reqs", "{");
+ tapdisk_stats_field(st, "max", "lu", MAX_AIO_REQS);
+ tapdisk_stats_field(st, "pending", "d", n_pending);
+ tapdisk_stats_leave(st, '}');
+}
+
struct tap_disk tapdisk_aio = {
.disk_type = "tapdisk_aio",
.flags = 0,
.td_get_parent_id = tdaio_get_parent_id,
.td_validate_parent = tdaio_validate_parent,
.td_debug = NULL,
+ .td_stats = tdaio_stats,
};
#include "tapdisk-server.h"
#include "tapdisk-message.h"
#include "tapdisk-disktype.h"
+#include "tapdisk-stats.h"
#include "tapdisk-control.h"
#define TD_CTL_MAX_CONNECTIONS 10
int busy;
} in;
- struct tapdisk_message_info *info;
+ struct tapdisk_control_info *info;
};
#define TAPDISK_MSG_REENTER (1<<0) /* non-blocking, idempotent */
#define TAPDISK_MSG_VERBOSE (1<<1) /* tell syslog about it */
-struct tapdisk_message_info {
+struct tapdisk_control_info {
void (*handler)(struct tapdisk_ctl_conn *, tapdisk_message_t *);
int flags;
};
tapdisk_control_write_message(conn, &response);
}
-struct tapdisk_message_info message_infos[] = {
+static void
+tapdisk_control_stats(struct tapdisk_ctl_conn *conn,
+ tapdisk_message_t *request)
+{
+ tapdisk_message_t response;
+ td_stats_t _st, *st = &_st;
+ td_vbd_t *vbd;
+ size_t rv;
+
+ tapdisk_stats_init(st,
+ conn->out.buf + sizeof(response),
+ conn->out.bufsz - sizeof(response));
+
+ if (request->cookie != (uint16_t)-1) {
+
+ vbd = tapdisk_server_get_vbd(request->cookie);
+ if (!vbd) {
+ rv = -ENODEV;
+ goto out;
+ }
+
+ tapdisk_vbd_stats(vbd, st);
+
+ } else {
+ struct list_head *list = tapdisk_server_get_all_vbds();
+
+ tapdisk_stats_enter(st, '[');
+
+ list_for_each_entry(vbd, list, next)
+ tapdisk_vbd_stats(vbd, st);
+
+ tapdisk_stats_leave(st, ']');
+ }
+
+ rv = tapdisk_stats_length(st);
+out:
+ memset(&response, 0, sizeof(response));
+ response.type = TAPDISK_MESSAGE_STATS_RSP;
+ response.cookie = request->cookie;
+ response.u.info.length = rv;
+
+ tapdisk_control_write_message(conn, &response);
+ if (rv > 0)
+ conn->out.prod += rv;
+}
+
+struct tapdisk_control_info message_infos[] = {
[TAPDISK_MESSAGE_PID] = {
.handler = tapdisk_control_get_pid,
.flags = TAPDISK_MSG_REENTER,
.handler = tapdisk_control_close_image,
.flags = TAPDISK_MSG_VERBOSE,
},
+ [TAPDISK_MESSAGE_STATS] = {
+ .handler = tapdisk_control_stats,
+ .flags = TAPDISK_MSG_VERBOSE,
+ },
};
int err, len, excl;
tapdisk_message_t message, response;
struct tapdisk_ctl_conn *conn = private;
- struct tapdisk_message_info *info;
+ struct tapdisk_control_info *info;
err = tapdisk_control_read_message(conn->fd, &message, 2);
if (err)
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include <stdlib.h>
+#include <stdio.h>
#include "tapdisk-driver.h"
#include "tapdisk-server.h"
#include "tapdisk-disktype.h"
+#include "tapdisk-stats.h"
td_driver_t *
tapdisk_driver_allocate(int type, char *name, td_flag_t flags, int storage)
if (driver->ops->td_debug)
driver->ops->td_debug(driver);
}
+
+void
+tapdisk_driver_stats(td_driver_t *driver, td_stats_t *st)
+{
+ tapdisk_stats_field(st, "type", "d", driver->type);
+
+ if (driver->ops->td_stats) {
+ tapdisk_stats_field(st, "status", "{");
+ driver->ops->td_stats(driver, st);
+ tapdisk_stats_leave(st, '}');
+ } else
+ tapdisk_stats_field(st, "status", NULL);
+
+}
void tapdisk_driver_debug(td_driver_t *);
+void tapdisk_driver_stats(td_driver_t *, td_stats_t *);
+
#endif
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdio.h>
#include "tapdisk-image.h"
#include "tapdisk-driver.h"
#include "tapdisk-server.h"
+#include "tapdisk-stats.h"
#define ERR(_err, _f, _a...) tlog_error(_err, _f, ##_a)
req->operation, req->sector_number + total);
return -EINVAL;
}
+
+void
+tapdisk_image_stats(td_image_t *image, td_stats_t *st)
+{
+ tapdisk_stats_enter(st, '{');
+ tapdisk_stats_field(st, "name", "s", image->name);
+
+ tapdisk_stats_field(st, "driver", "{");
+ tapdisk_driver_stats(image->driver, st);
+ tapdisk_stats_leave(st, '}');
+
+ tapdisk_stats_leave(st, '}');
+}
int tapdisk_image_check_td_request(td_image_t *, td_request_t);
int tapdisk_image_check_ring_request(td_image_t *, blkif_request_t *);
+void tapdisk_image_stats(td_image_t *, td_stats_t *);
#endif
--- /dev/null
+/*
+ * Copyright (c) 2010, Citrix Systems, 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 <stdarg.h>
+
+#include "tapdisk-stats.h"
+
+static void
+tapdisk_stats_vsprintf(td_stats_t *st,
+ const char *fmt, va_list ap)
+{
+ st->pos += vsnprintf(st->pos, st->buf + st->size - st->pos, fmt, ap);
+}
+
+static void __attribute__((format (printf, 2, 3)))
+tapdisk_stats_sprintf(td_stats_t *st,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ tapdisk_stats_vsprintf(st, fmt, ap);
+ va_end(ap);
+}
+
+
+static inline void
+__tapdisk_stats_enter(td_stats_t *st, char t)
+{
+ tapdisk_stats_sprintf(st, "%c ", t);
+
+ st->depth++;
+ st->n_elem[st->depth] = 0;
+}
+
+void
+tapdisk_stats_enter(td_stats_t *st, char t)
+{
+ int n_elem;
+
+ n_elem = st->n_elem[st->depth];
+ if (n_elem > 0)
+ tapdisk_stats_sprintf(st, ", ");
+ st->n_elem[st->depth]++;
+
+ __tapdisk_stats_enter(st, t);
+}
+
+
+void
+tapdisk_stats_leave(td_stats_t *st, char t)
+{
+ st->depth--;
+
+ tapdisk_stats_sprintf(st, " %c", t);
+}
+
+void
+tapdisk_stats_field(td_stats_t *st, const char *key, const char *conv, ...)
+{
+ va_list ap;
+ int n_elem;
+ char fmt[32], t;
+
+ n_elem = st->n_elem[st->depth]++;
+ if (n_elem > 0)
+ tapdisk_stats_sprintf(st, ", ");
+
+ tapdisk_stats_sprintf(st, "\"%s\": ", key);
+
+ if (!conv) {
+ tapdisk_stats_sprintf(st, "null");
+ return;
+ }
+
+ t = conv[0];
+ switch (t) {
+ case 's':
+ va_start(ap, conv);
+ tapdisk_stats_vsprintf(st, "\"%s\"", ap);
+ va_end(ap);
+ break;
+
+ case '[':
+ case '{':
+ __tapdisk_stats_enter(st, t);
+ break;
+
+ default:
+ sprintf(fmt, "%%%s", conv);
+
+ va_start(ap, conv);
+ tapdisk_stats_vsprintf(st, fmt, ap);
+ va_end(ap);
+ break;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2010, Citrix Systems, 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_STATS_H_
+#define _TAPDISK_STATS_H_
+
+#include <string.h>
+
+#define TD_INFO_MAX_DEPTH 8
+
+struct tapdisk_stats_ctx {
+ void *pos;
+
+ void *buf;
+ size_t size;
+
+ int n_elem[TD_INFO_MAX_DEPTH];
+ int depth;
+};
+
+typedef struct tapdisk_stats_ctx td_stats_t;
+
+static inline void
+tapdisk_stats_init(td_stats_t *st, char *buf, size_t size)
+{
+ memset(st, 0, sizeof(*st));
+
+ st->pos = buf;
+ st->buf = buf;
+ st->size = size;
+}
+
+static inline size_t
+tapdisk_stats_length(td_stats_t *st)
+{
+ return st->pos - st->buf;
+}
+
+void tapdisk_stats_enter(td_stats_t *st, char t);
+void tapdisk_stats_leave(td_stats_t *st, char t);
+void tapdisk_stats_field(td_stats_t *st, const char *key, const char *conv, ...);
+
+#endif /* _TAPDISK_STATS_H_ */
#include "tapdisk-vbd.h"
#include "tapdisk-disktype.h"
#include "tapdisk-interface.h"
+#include "tapdisk-stats.h"
#include "blktap2.h"
/* vbd may be destroyed after this call */
tapdisk_vbd_check_ring_message(vbd);
}
+
+void
+tapdisk_vbd_stats(td_vbd_t *vbd, td_stats_t *st)
+{
+ td_image_t *image, *next;
+
+ tapdisk_stats_enter(st, '{');
+ tapdisk_stats_field(st, "name", "s", vbd->name);
+ tapdisk_stats_field(st, "minor", "d", vbd->minor);
+
+ tapdisk_stats_field(st, "image", "[");
+
+ tapdisk_vbd_for_each_image(vbd, image, next)
+ tapdisk_image_stats(image, st);
+
+ tapdisk_stats_leave(st, ']');
+
+ tapdisk_stats_leave(st, '}');
+}
void tapdisk_vbd_check_state(td_vbd_t *);
void tapdisk_vbd_check_progress(td_vbd_t *);
void tapdisk_vbd_debug(td_vbd_t *);
+void tapdisk_vbd_stats(td_vbd_t *, td_stats_t *);
#endif
#include "blktaplib.h"
#include "tapdisk-log.h"
#include "tapdisk-utils.h"
+#include "tapdisk-stats.h"
#define MAX_SEGMENTS_PER_REQ 11
#define SECTOR_SHIFT 9
void (*td_queue_read) (td_driver_t *, td_request_t);
void (*td_queue_write) (td_driver_t *, td_request_t);
void (*td_debug) (td_driver_t *);
+ void (*td_stats) (td_driver_t *, td_stats_t *);
};
void td_panic(void);
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;
+typedef struct tapdisk_message_stat tapdisk_message_stat_t;
struct tapdisk_message_params {
tapdisk_message_flag_t flags;
char path[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
};
+struct tapdisk_message_stat {
+ uint16_t type;
+ uint16_t cookie;
+ size_t length;
+};
+
+
struct tapdisk_message {
uint16_t type;
uint16_t cookie;
tapdisk_message_minors_t minors;
tapdisk_message_response_t response;
tapdisk_message_list_t list;
+ tapdisk_message_stat_t info;
} u;
};
TAPDISK_MESSAGE_LIST_MINORS_RSP,
TAPDISK_MESSAGE_LIST,
TAPDISK_MESSAGE_LIST_RSP,
+ TAPDISK_MESSAGE_STATS,
+ TAPDISK_MESSAGE_STATS_RSP,
TAPDISK_MESSAGE_FORCE_SHUTDOWN,
TAPDISK_MESSAGE_EXIT,
};
case TAPDISK_MESSAGE_LIST_RSP:
return "list response";
+ case TAPDISK_MESSAGE_STATS:
+ return "stats";
+
+ case TAPDISK_MESSAGE_STATS_RSP:
+ return "stats response";
+
case TAPDISK_MESSAGE_EXIT:
return "exit";