iolog bug: TD_DDIR_READ should be TD_DDIR_WRITE
[fio.git] / blktrace.c
... / ...
CommitLineData
1/*
2 * blktrace support code for fio
3 */
4#include <stdio.h>
5#include <stdlib.h>
6#include "list.h"
7#include "fio.h"
8#include "blktrace_api.h"
9
10static int discard_pdu(int fd, struct blk_io_trace *t)
11{
12 if (t->pdu_len == 0)
13 return 0;
14
15 if (lseek(fd, t->pdu_len, SEEK_CUR) < 0)
16 return errno;
17
18 return 0;
19}
20
21int is_blktrace(const char *filename)
22{
23 struct blk_io_trace t;
24 int fd, ret;
25
26 fd = open(filename, O_RDONLY);
27 if (fd < 0) {
28 perror("open blktrace");
29 return 0;
30 }
31
32 ret = read(fd, &t, sizeof(t));
33 close(fd);
34
35 if (ret < 0) {
36 perror("read blktrace");
37 return 0;
38 } else if (ret != sizeof(t)) {
39 log_err("fio: short read on blktrace file\n");
40 return 0;
41 }
42
43 if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC)
44 return 1;
45
46 return 0;
47}
48
49static void store_ipo(struct thread_data *td, unsigned long long offset,
50 unsigned int bytes, int rw)
51{
52 struct io_piece *ipo = malloc(sizeof(*ipo));
53
54 memset(ipo, 0, sizeof(*ipo));
55 INIT_LIST_HEAD(&ipo->list);
56 ipo->offset = offset;
57 ipo->len = bytes;
58 if (rw)
59 ipo->ddir = DDIR_WRITE;
60 else
61 ipo->ddir = DDIR_READ;
62
63 list_add_tail(&ipo->list, &td->io_log_list);
64}
65
66static void handle_trace(struct thread_data *td, struct blk_io_trace *t)
67{
68 int rw;
69
70 if ((t->action & 0xffff) != __BLK_TA_QUEUE)
71 return;
72
73 rw = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
74 store_ipo(td, t->sector, t->bytes, rw);
75}
76
77int load_blktrace(struct thread_data *td, const char *filename)
78{
79 struct blk_io_trace t;
80 int fd;
81
82 fd = open(filename, O_RDONLY);
83 if (fd < 0) {
84 td_verror(td, errno, "open blktrace file");
85 return 1;
86 }
87
88 do {
89 int ret = read(fd, &t, sizeof(t));
90
91 if (ret < 0) {
92 td_verror(td, errno, "read blktrace file");
93 return 1;
94 } else if (!ret) {
95 break;
96 } else if (ret != sizeof(t)) {
97 log_err("fio: short read on blktrace file\n");
98 return 1;
99 }
100
101 if ((t.magic & 0xffffff00) != BLK_IO_TRACE_MAGIC) {
102 log_err("fio: bad magic in blktrace data\n");
103 return 1;
104 }
105 if ((t.magic & 0xff) != BLK_IO_TRACE_VERSION) {
106 log_err("fio: bad blktrace version %d\n", t.magic & 0xff);
107 return 1;
108 }
109 ret = discard_pdu(fd, &t);
110 if (ret) {
111 td_verror(td, ret, "blktrace lseek");
112 return 1;
113 }
114 handle_trace(td, &t);
115 } while (1);
116
117 close(fd);
118 return 0;
119}