Add nbd-trdump - utilty to dump traces
authorAlex Bligh <alex@alex.org.uk>
Sun, 22 May 2011 18:20:49 +0000 (19:20 +0100)
committerAlex Bligh <alex@alex.org.uk>
Sun, 22 May 2011 18:20:49 +0000 (19:20 +0100)
nbd-trdump.c [new file with mode: 0644]

diff --git a/nbd-trdump.c b/nbd-trdump.c
new file mode 100644 (file)
index 0000000..49f4f9e
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * nbd-trdump.c
+ *
+ * Takes an nbd transaction log file on stdin and translates it into something
+ * comprehensible
+ */
+
+#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"
+#include "cliserv.h"
+#include "nbd.h"
+
+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;
+       char * ctext;
+       int readfd = 0; /* stdin */
+
+       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);
+                       
+                       switch (command & NBD_CMD_MASK_COMMAND) {
+                       case NBD_CMD_READ:
+                               ctext="NBD_CMD_READ";
+                               break;
+                       case NBD_CMD_WRITE:
+                               ctext="NBD_CMD_WRITE";
+                               break;
+                       case NBD_CMD_DISC:
+                               ctext="NBD_CMD_DISC";
+                               break;
+                       case NBD_CMD_FLUSH:
+                               ctext="NBD_CMD_FLUSH";
+                               break;
+                       default:
+                               ctext="UNKNOWN";
+                               break;
+                       }
+                       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);
+                       
+                       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;
+}