char *string;
};
+int data_is_native = -1;
+
#define TRACE_TO_STRING(f) {.bit_field = f, .string = #f}
static struct trace_info traces[] = {
TRACE_TO_STRING( BLK_TC_READ ),
TRACE_TO_STRING( BLK_TC_WRITE ),
- TRACE_TO_STRING( BLK_TC_BARRIER ),
+ TRACE_TO_STRING( BLK_TC_FLUSH ),
TRACE_TO_STRING( BLK_TC_SYNC ),
TRACE_TO_STRING( BLK_TC_QUEUE ),
TRACE_TO_STRING( BLK_TC_REQUEUE ),
TRACE_TO_STRING( BLK_TC_ISSUE ),
TRACE_TO_STRING( BLK_TC_COMPLETE ),
TRACE_TO_STRING( BLK_TC_FS ),
- TRACE_TO_STRING( BLK_TC_PC )
+ TRACE_TO_STRING( BLK_TC_PC ),
+ TRACE_TO_STRING( BLK_TC_AHEAD ),
+ TRACE_TO_STRING( BLK_TC_META ),
+ TRACE_TO_STRING( BLK_TC_DISCARD ),
+ TRACE_TO_STRING( BLK_TC_FUA ),
};
#define N_TRACES (sizeof(traces) / sizeof(struct trace_info))
unsigned int act = action & 0xffff;
unsigned int trace = (action >> BLK_TC_SHIFT) & 0xffff;
- if (act <= N_ACTS) {
+ if (act < N_ACTS) {
sprintf(buf, "%s ", acts[act].string);
for (i = 0; i < N_TRACES; i++)
if (trace & (1 << i)) {
MINOR(bit->device));
}
-static int process(FILE *ofp, char *file, unsigned int cpu)
+static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
{
# define SWAP_BITS() do { \
if (bit_save) { \
} while (0)
size_t n;
- FILE *ifp;
+ FILE *ifp, *ofp;
__u32 save_device = 0, save_sequence = 0;
__u64 save_time = 0;
struct blk_io_trace *bit_save = NULL;
unsigned int nbad = 0;
unsigned int nbad_trace = 0, nbad_pdu = 0, nbad_cpu = 0;
unsigned int nbad_seq = 0, nbad_dev = 0, nbad_time = 0;
+ char ofname[1024];
ifp = fopen(file, "r");
+ if (!ifp)
+ return 0;
+
+ sprintf(ofname, "%s.verify.out", devname);
+
+ if (!*fp) {
+ *fp = fopen(ofname, "w");
+ if (*fp == NULL) {
+ fprintf(stderr,"Failed to open %s (%s), skipping\n",
+ ofname, strerror(errno));
+ fclose(ifp);
+ return 0;
+ }
+ fprintf(*fp, "\n---------------\n" );
+ fprintf(*fp, "Verifying %s\n", devname);
+ }
+
+ ofp = *fp;
while ((n = fread(bit, sizeof(struct blk_io_trace), 1, ifp)) == 1) {
+ if (ferror(ifp)) {
+ clearerr(ifp);
+ perror("fread");
+ break;
+ }
+ if (data_is_native == -1)
+ check_data_endianness(bit->magic);
+
trace_to_cpu(bit);
- if (verify_trace(bit)) {
+
+ if (!CHECK_MAGIC(bit)) {
INC_BAD("bad trace");
continue;
}
+ if ((bit->magic & 0xff) != SUPPORTED_VERSION) {
+ fprintf(stderr, "unsupported trace version\n");
+ break;
+ }
+
if (bit->pdu_len) {
char *pdu_buf;
if (n == 0) {
INC_BAD("bad pdu");
nbad_seq++;
+ free(pdu_buf);
break;
}
free(pdu_buf);
continue;
}
+ /*
+ * skip notify traces, they don't have valid sequences
+ */
+ if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY))
+ continue;
+
if (ngood) {
if (bit->sequence <= save_sequence) {
INC_BAD("bad seq");
{
char *devname;
struct stat st;
- int i, cpu, nbad;
+ int i, cpu, nbad, rval = 0;
FILE *ofp;
char *ofname = malloc(1024);
char *fname = malloc(1024);
for (i = 1; i < argc; i++) {
devname = argv[i];
sprintf(ofname, "%s.verify.out", devname);
- ofp = fopen(ofname, "w");
- if (ofp == NULL) {
- fprintf(stderr,"Failed to open %s (%s), skipping %s\n",
- ofname, strerror(errno), devname);
- continue;
- }
+ ofp = NULL;
- fprintf(ofp, "\n---------------\n" );
- fprintf(ofp, "Verifying %s\n", devname);
printf("Verifying %s\n", devname); fflush(stdout);
for (cpu = 0; ; cpu++) {
sprintf(fname, "%s.blktrace.%d", devname, cpu);
- if (stat(fname, &st) < 0)
+ if (stat(fname, &st) < 0) {
+ if (cpu == 0) {
+ fprintf(stderr, "No tracefiles found for %s\n",
+ devname);
+ rval = 1;
+ }
break;
+ }
printf(" CPU %d ", cpu); fflush(stdout);
- nbad = process(ofp, fname, cpu);
- if (nbad)
+ nbad = process(&ofp, devname, fname, cpu);
+ if (nbad) {
printf("-- %d bad", nbad);
+ rval = 1;
+ }
printf("\n");
}
- fclose(ofp);
- fprintf(stdout, "Wrote output to %s\n", ofname);
+ if (ofp) {
+ fclose(ofp);
+ fprintf(stdout, "Wrote output to %s\n", ofname);
+ }
}
- return 0;
+ return rval;
}