|
Network Block Device @PACKAGE_VERSION@
|
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 }
1.7.3