| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <stdio.h> |
| #include <sys/time.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <signal.h> |
| #include <string.h> |
| #include <sys/stat.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <ctype.h> |
| #include <endian.h> |
| #include "ioshark.h" |
| |
| char *progname; |
| |
| struct ioshark_header_old { |
| int num_files; |
| int num_io_operations; |
| }; |
| |
| struct ioshark_file_operation_old { |
| /* delta us between previous file op and this */ |
| u_int64_t delta_us; |
| enum file_op file_op; |
| int fileno; |
| union { |
| struct lseek_args_old { |
| #define lseek_offset_old u.lseek_a.offset |
| #define lseek_action_old u.lseek_a.action |
| off_t offset; |
| int action; |
| } lseek_a; |
| struct prw_args_old { |
| #define prw_offset_old u.prw_a.offset |
| #define prw_len_old u.prw_a.len |
| off_t offset; |
| size_t len; |
| } prw_a; |
| #define rw_len_old u.rw_a.len |
| struct rw_args_old { |
| size_t len; |
| } rw_a; |
| #define mmap_offset_old u.mmap_a.offset |
| #define mmap_len_old u.mmap_a.len |
| #define mmap_prot_old u.mmap_a.prot |
| struct mmap_args_old { |
| off_t offset; |
| size_t len; |
| int prot; |
| } mmap_a; |
| #define open_flags_old u.open_a.flags |
| #define open_mode_old u.open_a.mode |
| struct open_args_old { |
| int flags; |
| mode_t mode; |
| } open_a; |
| } u; |
| }; |
| |
| struct ioshark_file_state_old { |
| int fileno; /* 1..num_files, with files name ioshark.<fileno> */ |
| size_t size; |
| int global_filename_ix; |
| }; |
| |
| void usage(void) |
| { |
| fprintf(stderr, "%s in_file out_file\n", progname); |
| } |
| |
| int main(int argc, char **argv) |
| { |
| FILE *old_fp, *new_fp; |
| char *infile, *outfile; |
| struct ioshark_header new_header; |
| struct ioshark_file_operation new_disk_file_op; |
| struct ioshark_header_old old_header; |
| struct ioshark_file_operation_old old_disk_file_op; |
| struct ioshark_file_state new_file_state; |
| struct ioshark_file_state_old old_file_state; |
| struct stat st; |
| int i; |
| u_int64_t aggr_old_file_size = 0; |
| u_int64_t aggr_new_file_size = 0; |
| |
| progname = argv[0]; |
| if (argc != 3) { |
| usage(); |
| exit(EXIT_FAILURE); |
| } |
| infile = argv[1]; |
| outfile = argv[2]; |
| if (stat(infile, &st) < 0) { |
| fprintf(stderr, "%s Can't stat %s\n", |
| progname, infile); |
| exit(EXIT_FAILURE); |
| } |
| if (st.st_size == 0) { |
| fprintf(stderr, "%s Empty file %s\n", |
| progname, infile); |
| exit(EXIT_FAILURE); |
| } |
| old_fp = fopen(infile, "r"); |
| if (old_fp == NULL) { |
| fprintf(stderr, "%s Can't open %s\n", |
| progname, infile); |
| exit(EXIT_FAILURE); |
| } |
| new_fp = fopen(outfile, "w+"); |
| if (new_fp == NULL) { |
| fprintf(stderr, "%s Can't open outfile\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| /* Convert header */ |
| if (fread(&old_header, sizeof(struct ioshark_header_old), |
| 1, old_fp) != 1) { |
| fprintf(stderr, |
| "%s Read error Header\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| new_header.version = IOSHARK_VERSION; |
| new_header.num_files = old_header.num_files; |
| new_header.num_io_operations = old_header.num_io_operations; |
| new_header.version = htobe64(new_header.version); |
| new_header.num_files = htobe64(new_header.num_files); |
| new_header.num_io_operations = |
| htobe64(new_header.num_io_operations); |
| if (fwrite(&new_header, sizeof(struct ioshark_header), |
| 1, new_fp) != 1) { |
| fprintf(stderr, |
| "%s Write error Header\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| for (i = 0 ; i < old_header.num_files ; i++) { |
| if (fread(&old_file_state, |
| sizeof(struct ioshark_file_state_old), |
| 1, old_fp) != 1) { |
| fprintf(stderr, |
| "%s Read error file state\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| new_file_state.fileno = old_file_state.fileno; |
| new_file_state.size = old_file_state.size; |
| aggr_old_file_size += old_file_state.size; |
| new_file_state.global_filename_ix = |
| old_file_state.global_filename_ix; |
| new_file_state.fileno = htobe64(new_file_state.fileno); |
| new_file_state.size = htobe64(new_file_state.size); |
| aggr_new_file_size += be64toh(new_file_state.size); |
| new_file_state.global_filename_ix = |
| htobe64(new_file_state.global_filename_ix); |
| if (fwrite(&new_file_state, |
| sizeof(struct ioshark_file_state), 1, new_fp) != 1) { |
| fprintf(stderr, |
| "%s Write error file state\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| } |
| if (aggr_new_file_size != aggr_old_file_size) { |
| fprintf(stderr, |
| "%s Aggr file size mismath %lu != %lu\n", |
| progname, aggr_new_file_size, aggr_old_file_size); |
| exit(EXIT_FAILURE); |
| } |
| |
| for (i = 0 ; i < old_header.num_io_operations ; i++) { |
| enum file_op op; |
| |
| if (fread(&old_disk_file_op, |
| sizeof(struct ioshark_file_operation_old), |
| 1, old_fp) != 1) { |
| fprintf(stderr, |
| "%s Read error file op\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| op = old_disk_file_op.file_op; |
| new_disk_file_op.delta_us = old_disk_file_op.delta_us; |
| new_disk_file_op.delta_us = |
| htobe64(new_disk_file_op.delta_us); |
| new_disk_file_op.ioshark_io_op = op; |
| new_disk_file_op.op_union.enum_size = |
| htobe32(new_disk_file_op.op_union.enum_size); |
| new_disk_file_op.fileno = old_disk_file_op.fileno; |
| new_disk_file_op.fileno = htobe64(new_disk_file_op.fileno); |
| switch (op) { |
| case IOSHARK_LSEEK: |
| case IOSHARK_LLSEEK: |
| new_disk_file_op.lseek_offset = |
| old_disk_file_op.lseek_offset_old; |
| new_disk_file_op.lseek_action = |
| old_disk_file_op.lseek_action_old; |
| new_disk_file_op.lseek_offset = |
| htobe64(new_disk_file_op.lseek_offset); |
| new_disk_file_op.lseek_action = |
| htobe32(new_disk_file_op.lseek_action); |
| break; |
| case IOSHARK_PREAD64: |
| case IOSHARK_PWRITE64: |
| new_disk_file_op.prw_offset = |
| old_disk_file_op.prw_offset_old; |
| new_disk_file_op.prw_len = |
| old_disk_file_op.prw_len_old; |
| new_disk_file_op.prw_offset = |
| htobe64(new_disk_file_op.prw_offset); |
| new_disk_file_op.prw_len = |
| htobe64(new_disk_file_op.prw_len); |
| break; |
| case IOSHARK_READ: |
| case IOSHARK_WRITE: |
| new_disk_file_op.rw_len = |
| old_disk_file_op.rw_len_old; |
| new_disk_file_op.rw_len = |
| htobe64(new_disk_file_op.rw_len); |
| break; |
| case IOSHARK_MMAP: |
| case IOSHARK_MMAP2: |
| new_disk_file_op.mmap_offset = |
| old_disk_file_op.mmap_offset_old; |
| new_disk_file_op.mmap_len = |
| old_disk_file_op.mmap_len_old; |
| new_disk_file_op.mmap_prot = |
| old_disk_file_op.mmap_prot; |
| new_disk_file_op.mmap_offset = |
| htobe64(new_disk_file_op.mmap_offset); |
| new_disk_file_op.mmap_len = |
| htobe64(new_disk_file_op.mmap_len); |
| new_disk_file_op.mmap_prot = |
| htobe32(new_disk_file_op.mmap_prot); |
| break; |
| case IOSHARK_OPEN: |
| new_disk_file_op.open_flags = |
| old_disk_file_op.open_flags_old; |
| new_disk_file_op.open_mode = |
| old_disk_file_op.open_mode_old; |
| new_disk_file_op.open_flags = |
| htobe32(new_disk_file_op.open_flags); |
| new_disk_file_op.open_mode = |
| htobe32(new_disk_file_op.open_mode); |
| break; |
| case IOSHARK_FSYNC: |
| case IOSHARK_FDATASYNC: |
| break; |
| case IOSHARK_CLOSE: |
| break; |
| default: |
| fprintf(stderr, "%s: unknown FILE_OP %d\n", |
| progname, op); |
| exit(EXIT_FAILURE); |
| break; |
| } |
| if (fwrite(&new_disk_file_op, |
| sizeof(struct ioshark_file_operation), |
| 1, new_fp) != 1) { |
| fprintf(stderr, |
| "%s Write error file op\n", |
| progname); |
| exit(EXIT_FAILURE); |
| } |
| } |
| } |