Back to index

nbd  3.2
nbd-trdump.c
Go to the documentation of this file.
00001 /*
00002  * nbd-trdump.c
00003  *
00004  * Takes an nbd transaction log file on stdin and translates it into something
00005  * comprehensible
00006  */
00007 
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <sys/time.h>
00012 #include <sys/types.h>
00013 #include <stdint.h>
00014 #include <unistd.h>
00015 #include "config.h"
00016 /* We don't want to do syslog output in this program */
00017 #undef ISSERVER
00018 #include "cliserv.h"
00019 #include "nbd.h"
00020 
00021 static inline void doread(int f, void *buf, size_t len) {
00022         ssize_t res;
00023 
00024         while(len>0) {
00025                 if((res=read(f, buf, len)) <=0) {
00026                         if (!res)
00027                             exit(0);
00028                      perror ("Error reading transactions");
00029                      exit(1);
00030                 }
00031                 len-=res;
00032                 buf+=res;
00033         }
00034 }
00035 
00036 int main(int argc, char**argv) {
00037        struct nbd_request req;
00038        struct nbd_reply rep;
00039        uint32_t magic;
00040        uint64_t handle;
00041        uint32_t error;
00042        uint32_t command;
00043        uint32_t len;
00044        uint64_t offset;
00045        char * ctext;
00046        int readfd = 0; /* stdin */
00047 
00048        if(argc > 1) {
00049               int retval=0;
00050               if(strcmp(argv[1], "--help") && strcmp(argv[1], "-h")) {
00051                      printf("E: unknown option %s.\n", argv[1]);
00052                      retval=1;
00053               }
00054               printf("This is nbd-trdump, part of nbd %s.\n", PACKAGE_VERSION);
00055               printf("Use: %s < transactionlog\n", argv[0]);
00056               return retval;
00057        }
00058 
00059        while (1) {
00060               /* Read a request or reply from the transaction file */
00061               doread(readfd, &magic, sizeof(magic));
00062               magic = ntohl(magic);
00063               switch (magic) {
00064               case NBD_REQUEST_MAGIC:
00065                      doread(readfd, sizeof(magic)+(char *)(&req), sizeof(struct nbd_request)-sizeof(magic));
00066                      handle = ntohll(*((long long int *)(req.handle)));
00067                      offset = ntohll(req.from);
00068                      len = ntohl(req.len);
00069                      command = ntohl(req.type);
00070                      
00071                      switch (command & NBD_CMD_MASK_COMMAND) {
00072                      case NBD_CMD_READ:
00073                             ctext="NBD_CMD_READ";
00074                             break;
00075                      case NBD_CMD_WRITE:
00076                             ctext="NBD_CMD_WRITE";
00077                             break;
00078                      case NBD_CMD_DISC:
00079                             ctext="NBD_CMD_DISC";
00080                             break;
00081                      case NBD_CMD_FLUSH:
00082                             ctext="NBD_CMD_FLUSH";
00083                             break;
00084                      default:
00085                             ctext="UNKNOWN";
00086                             break;
00087                      }
00088                      printf("> H=%016llx C=0x%08x (%13s+%4s) O=%016llx L=%08x\n",
00089                             (long long unsigned int) handle,
00090                             command,
00091                             ctext,
00092                             (command & NBD_CMD_FLAG_FUA)?"FUA":"NONE",
00093                             (long long unsigned int) offset,
00094                             len);
00095                      
00096                      break;
00097               case NBD_REPLY_MAGIC:
00098                      doread(readfd, sizeof(magic)+(char *)(&rep), sizeof(struct nbd_reply)-sizeof(magic));
00099                      handle = ntohll(*((long long int *)(rep.handle)));
00100                      error = ntohl(rep.error);
00101                      
00102                      printf("< H=%016llx E=0x%08x\n",
00103                             (long long unsigned int) handle,
00104                             error);
00105                      break;
00106                      
00107               default:
00108                      printf("? Unknown transaction type %08x\n",magic);
00109                      break;
00110               }
00111               
00112        }
00113        /* never reached */
00114        return 0;
00115 }