You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
7.5 KiB
284 lines
7.5 KiB
/*
|
|
* 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 <sys/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);
|
|
}
|
|
}
|
|
}
|