1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker *
4*288bf522SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker *
8*288bf522SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker *
10*288bf522SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker */
16*288bf522SAndroid Build Coastguard Worker
17*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
18*288bf522SAndroid Build Coastguard Worker #include <sys/time.h>
19*288bf522SAndroid Build Coastguard Worker #include <sys/types.h>
20*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
21*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
22*288bf522SAndroid Build Coastguard Worker #include <signal.h>
23*288bf522SAndroid Build Coastguard Worker #include <string.h>
24*288bf522SAndroid Build Coastguard Worker #include <sys/stat.h>
25*288bf522SAndroid Build Coastguard Worker #include <errno.h>
26*288bf522SAndroid Build Coastguard Worker #include <fcntl.h>
27*288bf522SAndroid Build Coastguard Worker #include <ctype.h>
28*288bf522SAndroid Build Coastguard Worker #include <endian.h>
29*288bf522SAndroid Build Coastguard Worker #include "ioshark.h"
30*288bf522SAndroid Build Coastguard Worker
31*288bf522SAndroid Build Coastguard Worker char *progname;
32*288bf522SAndroid Build Coastguard Worker
33*288bf522SAndroid Build Coastguard Worker struct ioshark_header_old {
34*288bf522SAndroid Build Coastguard Worker int num_files;
35*288bf522SAndroid Build Coastguard Worker int num_io_operations;
36*288bf522SAndroid Build Coastguard Worker };
37*288bf522SAndroid Build Coastguard Worker
38*288bf522SAndroid Build Coastguard Worker struct ioshark_file_operation_old {
39*288bf522SAndroid Build Coastguard Worker /* delta us between previous file op and this */
40*288bf522SAndroid Build Coastguard Worker u_int64_t delta_us;
41*288bf522SAndroid Build Coastguard Worker enum file_op file_op;
42*288bf522SAndroid Build Coastguard Worker int fileno;
43*288bf522SAndroid Build Coastguard Worker union {
44*288bf522SAndroid Build Coastguard Worker struct lseek_args_old {
45*288bf522SAndroid Build Coastguard Worker #define lseek_offset_old u.lseek_a.offset
46*288bf522SAndroid Build Coastguard Worker #define lseek_action_old u.lseek_a.action
47*288bf522SAndroid Build Coastguard Worker off_t offset;
48*288bf522SAndroid Build Coastguard Worker int action;
49*288bf522SAndroid Build Coastguard Worker } lseek_a;
50*288bf522SAndroid Build Coastguard Worker struct prw_args_old {
51*288bf522SAndroid Build Coastguard Worker #define prw_offset_old u.prw_a.offset
52*288bf522SAndroid Build Coastguard Worker #define prw_len_old u.prw_a.len
53*288bf522SAndroid Build Coastguard Worker off_t offset;
54*288bf522SAndroid Build Coastguard Worker size_t len;
55*288bf522SAndroid Build Coastguard Worker } prw_a;
56*288bf522SAndroid Build Coastguard Worker #define rw_len_old u.rw_a.len
57*288bf522SAndroid Build Coastguard Worker struct rw_args_old {
58*288bf522SAndroid Build Coastguard Worker size_t len;
59*288bf522SAndroid Build Coastguard Worker } rw_a;
60*288bf522SAndroid Build Coastguard Worker #define mmap_offset_old u.mmap_a.offset
61*288bf522SAndroid Build Coastguard Worker #define mmap_len_old u.mmap_a.len
62*288bf522SAndroid Build Coastguard Worker #define mmap_prot_old u.mmap_a.prot
63*288bf522SAndroid Build Coastguard Worker struct mmap_args_old {
64*288bf522SAndroid Build Coastguard Worker off_t offset;
65*288bf522SAndroid Build Coastguard Worker size_t len;
66*288bf522SAndroid Build Coastguard Worker int prot;
67*288bf522SAndroid Build Coastguard Worker } mmap_a;
68*288bf522SAndroid Build Coastguard Worker #define open_flags_old u.open_a.flags
69*288bf522SAndroid Build Coastguard Worker #define open_mode_old u.open_a.mode
70*288bf522SAndroid Build Coastguard Worker struct open_args_old {
71*288bf522SAndroid Build Coastguard Worker int flags;
72*288bf522SAndroid Build Coastguard Worker mode_t mode;
73*288bf522SAndroid Build Coastguard Worker } open_a;
74*288bf522SAndroid Build Coastguard Worker } u;
75*288bf522SAndroid Build Coastguard Worker };
76*288bf522SAndroid Build Coastguard Worker
77*288bf522SAndroid Build Coastguard Worker struct ioshark_file_state_old {
78*288bf522SAndroid Build Coastguard Worker int fileno; /* 1..num_files, with files name ioshark.<fileno> */
79*288bf522SAndroid Build Coastguard Worker size_t size;
80*288bf522SAndroid Build Coastguard Worker int global_filename_ix;
81*288bf522SAndroid Build Coastguard Worker };
82*288bf522SAndroid Build Coastguard Worker
usage(void)83*288bf522SAndroid Build Coastguard Worker void usage(void)
84*288bf522SAndroid Build Coastguard Worker {
85*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "%s in_file out_file\n", progname);
86*288bf522SAndroid Build Coastguard Worker }
87*288bf522SAndroid Build Coastguard Worker
main(int argc,char ** argv)88*288bf522SAndroid Build Coastguard Worker int main(int argc, char **argv)
89*288bf522SAndroid Build Coastguard Worker {
90*288bf522SAndroid Build Coastguard Worker FILE *old_fp, *new_fp;
91*288bf522SAndroid Build Coastguard Worker char *infile, *outfile;
92*288bf522SAndroid Build Coastguard Worker struct ioshark_header new_header;
93*288bf522SAndroid Build Coastguard Worker struct ioshark_file_operation new_disk_file_op;
94*288bf522SAndroid Build Coastguard Worker struct ioshark_header_old old_header;
95*288bf522SAndroid Build Coastguard Worker struct ioshark_file_operation_old old_disk_file_op;
96*288bf522SAndroid Build Coastguard Worker struct ioshark_file_state new_file_state;
97*288bf522SAndroid Build Coastguard Worker struct ioshark_file_state_old old_file_state;
98*288bf522SAndroid Build Coastguard Worker struct stat st;
99*288bf522SAndroid Build Coastguard Worker int i;
100*288bf522SAndroid Build Coastguard Worker u_int64_t aggr_old_file_size = 0;
101*288bf522SAndroid Build Coastguard Worker u_int64_t aggr_new_file_size = 0;
102*288bf522SAndroid Build Coastguard Worker
103*288bf522SAndroid Build Coastguard Worker progname = argv[0];
104*288bf522SAndroid Build Coastguard Worker if (argc != 3) {
105*288bf522SAndroid Build Coastguard Worker usage();
106*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
107*288bf522SAndroid Build Coastguard Worker }
108*288bf522SAndroid Build Coastguard Worker infile = argv[1];
109*288bf522SAndroid Build Coastguard Worker outfile = argv[2];
110*288bf522SAndroid Build Coastguard Worker if (stat(infile, &st) < 0) {
111*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "%s Can't stat %s\n",
112*288bf522SAndroid Build Coastguard Worker progname, infile);
113*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
114*288bf522SAndroid Build Coastguard Worker }
115*288bf522SAndroid Build Coastguard Worker if (st.st_size == 0) {
116*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "%s Empty file %s\n",
117*288bf522SAndroid Build Coastguard Worker progname, infile);
118*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
119*288bf522SAndroid Build Coastguard Worker }
120*288bf522SAndroid Build Coastguard Worker old_fp = fopen(infile, "r");
121*288bf522SAndroid Build Coastguard Worker if (old_fp == NULL) {
122*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "%s Can't open %s\n",
123*288bf522SAndroid Build Coastguard Worker progname, infile);
124*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
125*288bf522SAndroid Build Coastguard Worker }
126*288bf522SAndroid Build Coastguard Worker new_fp = fopen(outfile, "w+");
127*288bf522SAndroid Build Coastguard Worker if (new_fp == NULL) {
128*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "%s Can't open outfile\n",
129*288bf522SAndroid Build Coastguard Worker progname);
130*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
131*288bf522SAndroid Build Coastguard Worker }
132*288bf522SAndroid Build Coastguard Worker /* Convert header */
133*288bf522SAndroid Build Coastguard Worker if (fread(&old_header, sizeof(struct ioshark_header_old),
134*288bf522SAndroid Build Coastguard Worker 1, old_fp) != 1) {
135*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
136*288bf522SAndroid Build Coastguard Worker "%s Read error Header\n",
137*288bf522SAndroid Build Coastguard Worker progname);
138*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
139*288bf522SAndroid Build Coastguard Worker }
140*288bf522SAndroid Build Coastguard Worker new_header.version = IOSHARK_VERSION;
141*288bf522SAndroid Build Coastguard Worker new_header.num_files = old_header.num_files;
142*288bf522SAndroid Build Coastguard Worker new_header.num_io_operations = old_header.num_io_operations;
143*288bf522SAndroid Build Coastguard Worker new_header.version = htobe64(new_header.version);
144*288bf522SAndroid Build Coastguard Worker new_header.num_files = htobe64(new_header.num_files);
145*288bf522SAndroid Build Coastguard Worker new_header.num_io_operations =
146*288bf522SAndroid Build Coastguard Worker htobe64(new_header.num_io_operations);
147*288bf522SAndroid Build Coastguard Worker if (fwrite(&new_header, sizeof(struct ioshark_header),
148*288bf522SAndroid Build Coastguard Worker 1, new_fp) != 1) {
149*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
150*288bf522SAndroid Build Coastguard Worker "%s Write error Header\n",
151*288bf522SAndroid Build Coastguard Worker progname);
152*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
153*288bf522SAndroid Build Coastguard Worker }
154*288bf522SAndroid Build Coastguard Worker for (i = 0 ; i < old_header.num_files ; i++) {
155*288bf522SAndroid Build Coastguard Worker if (fread(&old_file_state,
156*288bf522SAndroid Build Coastguard Worker sizeof(struct ioshark_file_state_old),
157*288bf522SAndroid Build Coastguard Worker 1, old_fp) != 1) {
158*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
159*288bf522SAndroid Build Coastguard Worker "%s Read error file state\n",
160*288bf522SAndroid Build Coastguard Worker progname);
161*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
162*288bf522SAndroid Build Coastguard Worker }
163*288bf522SAndroid Build Coastguard Worker new_file_state.fileno = old_file_state.fileno;
164*288bf522SAndroid Build Coastguard Worker new_file_state.size = old_file_state.size;
165*288bf522SAndroid Build Coastguard Worker aggr_old_file_size += old_file_state.size;
166*288bf522SAndroid Build Coastguard Worker new_file_state.global_filename_ix =
167*288bf522SAndroid Build Coastguard Worker old_file_state.global_filename_ix;
168*288bf522SAndroid Build Coastguard Worker new_file_state.fileno = htobe64(new_file_state.fileno);
169*288bf522SAndroid Build Coastguard Worker new_file_state.size = htobe64(new_file_state.size);
170*288bf522SAndroid Build Coastguard Worker aggr_new_file_size += be64toh(new_file_state.size);
171*288bf522SAndroid Build Coastguard Worker new_file_state.global_filename_ix =
172*288bf522SAndroid Build Coastguard Worker htobe64(new_file_state.global_filename_ix);
173*288bf522SAndroid Build Coastguard Worker if (fwrite(&new_file_state,
174*288bf522SAndroid Build Coastguard Worker sizeof(struct ioshark_file_state), 1, new_fp) != 1) {
175*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
176*288bf522SAndroid Build Coastguard Worker "%s Write error file state\n",
177*288bf522SAndroid Build Coastguard Worker progname);
178*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
179*288bf522SAndroid Build Coastguard Worker }
180*288bf522SAndroid Build Coastguard Worker }
181*288bf522SAndroid Build Coastguard Worker if (aggr_new_file_size != aggr_old_file_size) {
182*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
183*288bf522SAndroid Build Coastguard Worker "%s Aggr file size mismath %lu != %lu\n",
184*288bf522SAndroid Build Coastguard Worker progname, aggr_new_file_size, aggr_old_file_size);
185*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
186*288bf522SAndroid Build Coastguard Worker }
187*288bf522SAndroid Build Coastguard Worker
188*288bf522SAndroid Build Coastguard Worker for (i = 0 ; i < old_header.num_io_operations ; i++) {
189*288bf522SAndroid Build Coastguard Worker enum file_op op;
190*288bf522SAndroid Build Coastguard Worker
191*288bf522SAndroid Build Coastguard Worker if (fread(&old_disk_file_op,
192*288bf522SAndroid Build Coastguard Worker sizeof(struct ioshark_file_operation_old),
193*288bf522SAndroid Build Coastguard Worker 1, old_fp) != 1) {
194*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
195*288bf522SAndroid Build Coastguard Worker "%s Read error file op\n",
196*288bf522SAndroid Build Coastguard Worker progname);
197*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
198*288bf522SAndroid Build Coastguard Worker }
199*288bf522SAndroid Build Coastguard Worker op = old_disk_file_op.file_op;
200*288bf522SAndroid Build Coastguard Worker new_disk_file_op.delta_us = old_disk_file_op.delta_us;
201*288bf522SAndroid Build Coastguard Worker new_disk_file_op.delta_us =
202*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.delta_us);
203*288bf522SAndroid Build Coastguard Worker new_disk_file_op.ioshark_io_op = op;
204*288bf522SAndroid Build Coastguard Worker new_disk_file_op.op_union.enum_size =
205*288bf522SAndroid Build Coastguard Worker htobe32(new_disk_file_op.op_union.enum_size);
206*288bf522SAndroid Build Coastguard Worker new_disk_file_op.fileno = old_disk_file_op.fileno;
207*288bf522SAndroid Build Coastguard Worker new_disk_file_op.fileno = htobe64(new_disk_file_op.fileno);
208*288bf522SAndroid Build Coastguard Worker switch (op) {
209*288bf522SAndroid Build Coastguard Worker case IOSHARK_LSEEK:
210*288bf522SAndroid Build Coastguard Worker case IOSHARK_LLSEEK:
211*288bf522SAndroid Build Coastguard Worker new_disk_file_op.lseek_offset =
212*288bf522SAndroid Build Coastguard Worker old_disk_file_op.lseek_offset_old;
213*288bf522SAndroid Build Coastguard Worker new_disk_file_op.lseek_action =
214*288bf522SAndroid Build Coastguard Worker old_disk_file_op.lseek_action_old;
215*288bf522SAndroid Build Coastguard Worker new_disk_file_op.lseek_offset =
216*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.lseek_offset);
217*288bf522SAndroid Build Coastguard Worker new_disk_file_op.lseek_action =
218*288bf522SAndroid Build Coastguard Worker htobe32(new_disk_file_op.lseek_action);
219*288bf522SAndroid Build Coastguard Worker break;
220*288bf522SAndroid Build Coastguard Worker case IOSHARK_PREAD64:
221*288bf522SAndroid Build Coastguard Worker case IOSHARK_PWRITE64:
222*288bf522SAndroid Build Coastguard Worker new_disk_file_op.prw_offset =
223*288bf522SAndroid Build Coastguard Worker old_disk_file_op.prw_offset_old;
224*288bf522SAndroid Build Coastguard Worker new_disk_file_op.prw_len =
225*288bf522SAndroid Build Coastguard Worker old_disk_file_op.prw_len_old;
226*288bf522SAndroid Build Coastguard Worker new_disk_file_op.prw_offset =
227*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.prw_offset);
228*288bf522SAndroid Build Coastguard Worker new_disk_file_op.prw_len =
229*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.prw_len);
230*288bf522SAndroid Build Coastguard Worker break;
231*288bf522SAndroid Build Coastguard Worker case IOSHARK_READ:
232*288bf522SAndroid Build Coastguard Worker case IOSHARK_WRITE:
233*288bf522SAndroid Build Coastguard Worker new_disk_file_op.rw_len =
234*288bf522SAndroid Build Coastguard Worker old_disk_file_op.rw_len_old;
235*288bf522SAndroid Build Coastguard Worker new_disk_file_op.rw_len =
236*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.rw_len);
237*288bf522SAndroid Build Coastguard Worker break;
238*288bf522SAndroid Build Coastguard Worker case IOSHARK_MMAP:
239*288bf522SAndroid Build Coastguard Worker case IOSHARK_MMAP2:
240*288bf522SAndroid Build Coastguard Worker new_disk_file_op.mmap_offset =
241*288bf522SAndroid Build Coastguard Worker old_disk_file_op.mmap_offset_old;
242*288bf522SAndroid Build Coastguard Worker new_disk_file_op.mmap_len =
243*288bf522SAndroid Build Coastguard Worker old_disk_file_op.mmap_len_old;
244*288bf522SAndroid Build Coastguard Worker new_disk_file_op.mmap_prot =
245*288bf522SAndroid Build Coastguard Worker old_disk_file_op.mmap_prot;
246*288bf522SAndroid Build Coastguard Worker new_disk_file_op.mmap_offset =
247*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.mmap_offset);
248*288bf522SAndroid Build Coastguard Worker new_disk_file_op.mmap_len =
249*288bf522SAndroid Build Coastguard Worker htobe64(new_disk_file_op.mmap_len);
250*288bf522SAndroid Build Coastguard Worker new_disk_file_op.mmap_prot =
251*288bf522SAndroid Build Coastguard Worker htobe32(new_disk_file_op.mmap_prot);
252*288bf522SAndroid Build Coastguard Worker break;
253*288bf522SAndroid Build Coastguard Worker case IOSHARK_OPEN:
254*288bf522SAndroid Build Coastguard Worker new_disk_file_op.open_flags =
255*288bf522SAndroid Build Coastguard Worker old_disk_file_op.open_flags_old;
256*288bf522SAndroid Build Coastguard Worker new_disk_file_op.open_mode =
257*288bf522SAndroid Build Coastguard Worker old_disk_file_op.open_mode_old;
258*288bf522SAndroid Build Coastguard Worker new_disk_file_op.open_flags =
259*288bf522SAndroid Build Coastguard Worker htobe32(new_disk_file_op.open_flags);
260*288bf522SAndroid Build Coastguard Worker new_disk_file_op.open_mode =
261*288bf522SAndroid Build Coastguard Worker htobe32(new_disk_file_op.open_mode);
262*288bf522SAndroid Build Coastguard Worker break;
263*288bf522SAndroid Build Coastguard Worker case IOSHARK_FSYNC:
264*288bf522SAndroid Build Coastguard Worker case IOSHARK_FDATASYNC:
265*288bf522SAndroid Build Coastguard Worker break;
266*288bf522SAndroid Build Coastguard Worker case IOSHARK_CLOSE:
267*288bf522SAndroid Build Coastguard Worker break;
268*288bf522SAndroid Build Coastguard Worker default:
269*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "%s: unknown FILE_OP %d\n",
270*288bf522SAndroid Build Coastguard Worker progname, op);
271*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
272*288bf522SAndroid Build Coastguard Worker break;
273*288bf522SAndroid Build Coastguard Worker }
274*288bf522SAndroid Build Coastguard Worker if (fwrite(&new_disk_file_op,
275*288bf522SAndroid Build Coastguard Worker sizeof(struct ioshark_file_operation),
276*288bf522SAndroid Build Coastguard Worker 1, new_fp) != 1) {
277*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
278*288bf522SAndroid Build Coastguard Worker "%s Write error file op\n",
279*288bf522SAndroid Build Coastguard Worker progname);
280*288bf522SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
281*288bf522SAndroid Build Coastguard Worker }
282*288bf522SAndroid Build Coastguard Worker }
283*288bf522SAndroid Build Coastguard Worker }
284