[PATCH 5/7] Add a new utility: nbd-trplay
Initial commit for nbd-trplay, a command to replay parts of an nbd
trace file.
Changes:
- Just copy nbd-trdump.
- Changes:
* nbd-trdump replaced with nbd-trplay.
* Whitespace in empty lines removed.
Signed-off-by: Manfred Spraul <manfred.spraul@de.bosch.com>
---
Makefile.am | 5 ++-
nbd-trplay.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 1 deletion(-)
create mode 100644 nbd-trplay.c
diff --git a/Makefile.am b/Makefile.am
index fde6ad7..14d264e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I support
SUBDIRS = . man doc tests systemd gznbd
-bin_PROGRAMS = nbd-server nbd-trdump
+bin_PROGRAMS = nbd-server nbd-trdump nbd-trplay
EXTRA_PROGRAMS = nbd-client make-integrityhuge
noinst_LTLIBRARIES = libnbdsrv.la libcliserv.la libnbdclt.la
libcliserv_la_SOURCES = cliserv.h cliserv.c
@@ -9,14 +9,17 @@ client_srcs = nbd-client.c cliserv.h nbd-netlink.h
nbd_server_SOURCES = nbd-server.c cliserv.h lfs.h nbd.h nbdsrv.h backend.h \
netdb-compat.h
nbd_trdump_SOURCES = nbd-trdump.c cliserv.h nbd.h
+nbd_trplay_SOURCES = nbd-trplay.c cliserv.h nbd.h
client_flags = @CFLAGS@
nbd_server_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
nbd_trdump_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
+nbd_trplay_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
libnbdsrv_la_SOURCES = nbdsrv.c nbdsrv.h treefiles.c treefiles.h
libnbdsrv_la_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
client_libs = libcliserv.la libnbdclt.la
nbd_server_LDADD = @GLIB_LIBS@ libnbdsrv.la libcliserv.la
nbd_trdump_LDADD = libcliserv.la
+nbd_trplay_LDADD = libcliserv.la
make_integrityhuge_SOURCES = make-integrityhuge.c cliserv.h nbd.h nbd-debug.h
EXTRA_DIST = maketr CodingStyle autogen.sh README.md support/genver.sh
if GNUTLS
diff --git a/nbd-trplay.c b/nbd-trplay.c
new file mode 100644
index 0000000..e31bb3b
--- /dev/null
+++ b/nbd-trplay.c
@@ -0,0 +1,113 @@
+/*
+ * nbd-trplay.c
+ *
+ * Takes an nbd transaction log file and replays some/all of the write commands.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <unistd.h>
+#include "config.h"
+/* We don't want to do syslog output in this program */
+#undef ISSERVER
+#include "cliserv.h"
+#include "nbd.h"
+#include "nbd-helper.h"
+
+#define BUFSIZE 131072
+static char tmpbuf[BUFSIZE];
+
+static inline void doread(int f, void *buf, size_t len) {
+ ssize_t res;
+
+ while(len>0) {
+ if((res=read(f, buf, len)) <=0) {
+ if (!res)
+ exit(0);
+ perror ("Error reading transactions");
+ exit(1);
+ }
+ len-=res;
+ buf+=res;
+ }
+}
+
+int main(int argc, char**argv) {
+ struct nbd_request req;
+ struct nbd_reply rep;
+ uint32_t magic;
+ uint64_t handle;
+ uint32_t error;
+ uint32_t command;
+ uint32_t len;
+ uint64_t offset;
+ const char * ctext;
+ int readfd = 0; /* stdin */
+
+ if(argc > 1) {
+ int retval=0;
+ if(strcmp(argv[1], "--help") && strcmp(argv[1], "-h")) {
+ printf("E: unknown option %s.\n", argv[1]);
+ retval=1;
+ }
+ printf("This is nbd-trplay, part of nbd %s.\n", PACKAGE_VERSION);
+ printf("Use: %s < transactionlog\n", argv[0]);
+ return retval;
+ }
+
+ while (1) {
+ /* Read a request or reply from the transaction file */
+ doread(readfd, &magic, sizeof(magic));
+ magic = ntohl(magic);
+ switch (magic) {
+ case NBD_REQUEST_MAGIC:
+ doread(readfd, sizeof(magic)+(char *)(&req), sizeof(struct nbd_request)-sizeof(magic));
+ handle = ntohll(*((long long int *)(req.handle)));
+ offset = ntohll(req.from);
+ len = ntohl(req.len);
+ command = ntohl(req.type);
+
+ ctext = getcommandname(command & NBD_CMD_MASK_COMMAND);
+
+ printf("> H=%016llx C=0x%08x (%13s+%4s) O=%016llx L=%08x\n",
+ (long long unsigned int) handle,
+ command,
+ ctext,
+ (command & NBD_CMD_FLAG_FUA)?"FUA":"NONE",
+ (long long unsigned int) offset,
+ len);
+ if (command & NBD_CMD_FLAG_DATALOG) {
+ while (len > 0) {
+ uint32_t tmplen = len;
+
+ if (tmplen > BUFSIZE)
+ tmplen = BUFSIZE;
+ doread(readfd, tmpbuf, tmplen);
+ len -= tmplen;
+ }
+ }
+
+ break;
+ case NBD_REPLY_MAGIC:
+ doread(readfd, sizeof(magic)+(char *)(&rep), sizeof(struct nbd_reply)-sizeof(magic));
+ handle = ntohll(*((long long int *)(rep.handle)));
+ error = ntohl(rep.error);
+
+ printf("< H=%016llx E=0x%08x\n",
+ (long long unsigned int) handle,
+ error);
+ break;
+
+ default:
+ printf("? Unknown transaction type %08x\n",magic);
+ break;
+ }
+
+ }
+ /* never reached */
+ return 0;
+}
--
2.33.1
Reply to: