1b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan/*
2b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * Copyright (C) 2016 The Android Open Source Project
3b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan *
4b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * Licensed under the Apache License, Version 2.0 (the "License");
5b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * you may not use this file except in compliance with the License.
6b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * You may obtain a copy of the License at
7b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan *
8b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan *      http://www.apache.org/licenses/LICENSE-2.0
9b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan *
10b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * Unless required by applicable law or agreed to in writing, software
11b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * distributed under the License is distributed on an "AS IS" BASIS,
12b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * See the License for the specific language governing permissions and
14b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * limitations under the License.
15b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan */
16b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
17b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <stdio.h>
18b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <sys/time.h>
19b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <sys/types.h>
20b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <unistd.h>
21b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <sys/syscall.h>
22b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <stdlib.h>
23b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <string.h>
24b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <sys/stat.h>
25b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <sys/errno.h>
26b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <fcntl.h>
27b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <string.h>
28b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <assert.h>
29b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <pthread.h>
30b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include <sys/statfs.h>
3102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan#include <sys/resource.h>
32b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include "ioshark.h"
33b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#define IOSHARK_MAIN
34b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#include "ioshark_bench.h"
35b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
3602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan/*
3702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * Note on "quick" mode where we do reads on existing /system,
3802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * /vendor and other files in ro partitions, instead of creating
3902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * them. The ioshark compiler builds up a table of all the files
4002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * in /system, /vendor and other ro partitions. For files in this
4102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * list, the benchmark skips the pre-creation of these files and
4202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * reads them directly.
4302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan * The code relevant to this is in *filename_cache*.
4402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan */
4502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
46b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanchar *progname;
47b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
489d00a124c5591198264ffedf0ba4c73bddfc346fMohan Srinivasan#define MAX_INPUT_FILES		8192
499d00a124c5591198264ffedf0ba4c73bddfc346fMohan Srinivasan#define MAX_THREADS		8192
50b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
51b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct thread_state_s {
52b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	char *filename;
53b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	FILE *fp;
54b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int num_files;
55b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	void *db_handle;
56b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan};
57b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
58b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct thread_state_s thread_state[MAX_INPUT_FILES];
59b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint num_input_files = 0;
60b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint next_input_file;
61b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
62b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanpthread_t tid[MAX_THREADS];
63b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
64b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan/*
65b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * Global options
66b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan */
67b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint do_delay = 0;
68b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint verbose = 0;
692aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasanint summary_mode = 0;
7002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasanint quick_mode = 0;
71b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
72b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#if 0
73b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic long gettid()
74b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
75b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan        return syscall(__NR_gettid);
76b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
77b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan#endif
78b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
79b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanvoid usage()
80b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
8102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	fprintf(stderr, "%s [-d preserve_delays] [-n num_iterations] [-t num_threads] -q -v | -s <list of parsed input files>\n",
8202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		progname);
8302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	fprintf(stderr, "%s -s, -v are mutually exclusive\n",
84b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		progname);
85b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	exit(EXIT_FAILURE);
86b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
87b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
88b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanpthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER;
89b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanpthread_mutex_t stats_mutex = PTHREAD_MUTEX_INITIALIZER;
90b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanpthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER;
91b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct timeval aggregate_file_create_time;
92b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct timeval debug_file_create_time;
93b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct timeval aggregate_file_remove_time;
94b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct timeval aggregate_IO_time;
95b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct timeval aggregate_delay_time;
96b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
97b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanu_int64_t aggr_op_counts[IOSHARK_MAX_FILE_OP];
98b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct rw_bytes_s aggr_io_rw_bytes;
99b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstruct rw_bytes_s aggr_create_rw_bytes;
100b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
101b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan/*
102b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * Locking needed here because aggregate_delay_time is updated
103b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan * from multiple threads concurrently.
104b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan */
105b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
106b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanupdate_time(struct timeval *aggr_time,
107b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	    struct timeval *delta_time)
108b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
109b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct timeval tmp;
110b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
111b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_lock(&time_mutex);
112b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	timeradd(aggr_time, delta_time, &tmp);
113b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	*aggr_time = tmp;
114b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_unlock(&time_mutex);
115b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
116b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
117b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
118b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanupdate_op_counts(u_int64_t *op_counts)
119b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
120b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int i;
121b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
122b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_lock(&stats_mutex);
123b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	for (i = IOSHARK_LSEEK ; i < IOSHARK_MAX_FILE_OP ; i++)
124b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		aggr_op_counts[i] += op_counts[i];
125b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_unlock(&stats_mutex);
126b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
127b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
128b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
129b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanupdate_byte_counts(struct rw_bytes_s *dest, struct rw_bytes_s *delta)
130b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
131b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_lock(&stats_mutex);
132b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	dest->bytes_read += delta->bytes_read;
133b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	dest->bytes_written += delta->bytes_written;
134b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_unlock(&stats_mutex);
135b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
136b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
137b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic int work_next_file;
138b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic int work_num_files;
139b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
140b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanvoid
141b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasaninit_work(int next_file, int num_files)
142b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
143b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_lock(&work_mutex);
144b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	work_next_file = next_file;
145b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	work_num_files = work_next_file + num_files;
146b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_unlock(&work_mutex);
147b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
148b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
149b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan/* Dole out the next file to work on to the thread */
150b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic struct thread_state_s *
151b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanget_work()
152b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
153b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct thread_state_s *work = NULL;
154b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
155b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_lock(&work_mutex);
156b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (work_next_file < work_num_files)
157b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		work = &thread_state[work_next_file++];
158b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_mutex_unlock(&work_mutex);
159b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	return work;
160b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
161b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
162b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
163b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasancreate_files(struct thread_state_s *state)
164b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
165b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int i;
166b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct ioshark_file_state file_state;
16702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	char path[MAX_IOSHARK_PATHLEN];
168b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	void *db_node;
169b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct rw_bytes_s rw_bytes;
17002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	char *filename;
17102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	int readonly;
172b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
173b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	memset(&rw_bytes, 0, sizeof(struct rw_bytes_s));
174b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	for (i = 0 ; i < state->num_files ; i++) {
175b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (fread(&file_state, sizeof(struct ioshark_file_state),
176b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			  1, state->fp) != 1) {
177b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s read error tracefile\n",
178b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname);
179b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
180b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
18102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		/*
18202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		 * Check to see if the file is in a readonly partition,
18302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		 * in which case, we don't have to pre-create the file
18402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		 * we can just read the existing file.
18502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		 */
18602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		filename =
18702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			get_ro_filename(file_state.global_filename_ix);
1889d00a124c5591198264ffedf0ba4c73bddfc346fMohan Srinivasan		if (quick_mode)
1899d00a124c5591198264ffedf0ba4c73bddfc346fMohan Srinivasan			assert(filename != NULL);
19002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		if (quick_mode == 0 ||
19102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		    is_readonly_mount(filename, file_state.size) == 0) {
19202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			sprintf(path, "file.%d.%d",
19302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				(int)(state - thread_state),
19402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				file_state.fileno);
19502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			create_file(path, file_state.size,
19602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				    &rw_bytes);
19702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			filename = path;
19802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			readonly = 0;
19902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		} else {
20002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			readonly = 1;
20102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		}
202b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		db_node = files_db_add_byfileno(state->db_handle,
20302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan						file_state.fileno,
20402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan						readonly);
205b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		files_db_update_size(db_node, file_state.size);
20602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		files_db_update_filename(db_node, filename);
207b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
208b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	update_byte_counts(&aggr_create_rw_bytes, &rw_bytes);
209b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
210b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
211b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
212b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasando_one_io(void *db_node,
213b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	  struct ioshark_file_operation *file_op,
214b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	  u_int64_t *op_counts,
215b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	  struct rw_bytes_s *rw_bytes,
216b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	  char **bufp, int *buflen)
217b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
218b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	assert(file_op->file_op < IOSHARK_MAX_FILE_OP);
219b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	op_counts[file_op->file_op]++;
220b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	switch (file_op->file_op) {
221b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int ret;
222b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	char *p;
223b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int fd;
224b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
225b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_LSEEK:
226b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_LLSEEK:
227b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ret = lseek(files_db_get_fd(db_node),
228b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			    file_op->lseek_offset,
229b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			    file_op->lseek_action);
230b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (ret < 0) {
231b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
232b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s: lseek(%s %lu %d) returned error %d\n",
233b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, files_db_get_filename(db_node),
234b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->lseek_offset,
235b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->lseek_action, errno);
236b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
237b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
238b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
239b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_PREAD64:
240b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		p = get_buf(bufp, buflen, file_op->prw_len, 0);
241b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ret = pread(files_db_get_fd(db_node), p,
242b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			    file_op->prw_len, file_op->prw_offset);
243b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		rw_bytes->bytes_read += file_op->prw_len;
244b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (ret < 0) {
245b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
246b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s: pread(%s %zu %lu) error %d\n",
247b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname,
248b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				files_db_get_filename(db_node),
249b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->prw_len,
250b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->prw_offset, errno);
251b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
252b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
253b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
254b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_PWRITE64:
255b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		p = get_buf(bufp, buflen, file_op->prw_len, 1);
256b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ret = pwrite(files_db_get_fd(db_node), p,
257b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			     file_op->prw_len, file_op->prw_offset);
258b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		rw_bytes->bytes_written += file_op->prw_len;
259b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (ret < 0) {
260b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
261b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s: pwrite(%s %zu %lu) error %d\n",
262b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname,
263b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				files_db_get_filename(db_node),
264b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->prw_len,
265b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->prw_offset, errno);
266b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
267b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
268b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
269b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_READ:
270b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		p = get_buf(bufp, buflen, file_op->rw_len, 0);
271b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ret = read(files_db_get_fd(db_node), p,
272b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			   file_op->rw_len);
273b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		rw_bytes->bytes_read += file_op->rw_len;
274b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (ret < 0) {
275b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
276b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s: read(%s %zu) error %d\n",
277b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname,
278b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				files_db_get_filename(db_node),
279b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->rw_len,
280b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				errno);
281b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
282b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
283b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
284b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_WRITE:
285b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		p = get_buf(bufp, buflen, file_op->rw_len, 1);
286b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ret = write(files_db_get_fd(db_node), p,
287b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			    file_op->rw_len);
288b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		rw_bytes->bytes_written += file_op->rw_len;
289b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (ret < 0) {
290b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
291b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s: write(%s %zu) error %d\n",
292b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname,
293b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				files_db_get_filename(db_node),
294b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				file_op->rw_len,
295b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				errno);
296b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
297b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
298b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
299b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_MMAP:
300b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_MMAP2:
301b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ioshark_handle_mmap(db_node, file_op,
302b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				    bufp, buflen, op_counts,
303b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				    rw_bytes);
304b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
305b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_OPEN:
306b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (file_op->open_flags & O_CREAT) {
307b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fd = open(files_db_get_filename(db_node),
308b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				  file_op->open_flags,
309b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				  file_op->open_mode);
310b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (fd < 0) {
311b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				/*
312b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				 * EEXIST error acceptable, others are fatal.
313b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				 * Although we failed to O_CREAT the file (O_EXCL)
314b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				 * We will force an open of the file before any
315b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				 * IO.
316b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				 */
317b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				if (errno == EEXIST) {
318b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					return;
319b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				} else {
320b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					fprintf(stderr,
321b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						"%s: O_CREAT open(%s %x %o) error %d\n",
322b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						progname,
323b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						files_db_get_filename(db_node),
324b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						file_op->open_flags,
325b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						file_op->open_mode, errno);
326b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					exit(EXIT_FAILURE);
327b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				}
328b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
329b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		} else {
330b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fd = open(files_db_get_filename(db_node),
331b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				  file_op->open_flags);
332b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (fd < 0) {
333b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				if (file_op->open_flags & O_DIRECTORY) {
334b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					/* O_DIRECTORY open()s should fail */
335b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					return;
336b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				} else {
337b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					fprintf(stderr,
338b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						"%s: open(%s %x) error %d\n",
339b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						progname,
340b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						files_db_get_filename(db_node),
341b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						file_op->open_flags,
342b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						errno);
343b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					exit(EXIT_FAILURE);
344b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				}
345b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
346b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
347b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		files_db_close_fd(db_node);
348b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		files_db_update_fd(db_node, fd);
349b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
350b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_FSYNC:
351b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_FDATASYNC:
352b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (file_op->file_op == IOSHARK_FSYNC) {
353b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			ret = fsync(files_db_get_fd(db_node));
354b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (ret < 0) {
355b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				fprintf(stderr,
356b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					"%s: fsync(%s) error %d\n",
357b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					progname,
358b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					files_db_get_filename(db_node),
359b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					errno);
360b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				exit(EXIT_FAILURE);
361b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
362b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		} else {
363b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			ret = fdatasync(files_db_get_fd(db_node));
364b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (ret < 0) {
365b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				fprintf(stderr,
366b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					"%s: fdatasync(%s) error %d\n",
367b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					progname,
368b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					files_db_get_filename(db_node),
369b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					errno);
370b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				exit(EXIT_FAILURE);
371b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
372b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
373b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
374b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	case IOSHARK_CLOSE:
375b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		ret = close(files_db_get_fd(db_node));
376b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (ret < 0) {
377b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
378b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s: close(%s) error %d\n",
379b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname,
380b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				files_db_get_filename(db_node), errno);
381b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
382b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
383b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		files_db_update_fd(db_node, -1);
384b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
385b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	default:
386b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fprintf(stderr, "%s: unknown FILE_OP %d\n",
387b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			progname, file_op->file_op);
388b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		exit(EXIT_FAILURE);
389b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		break;
390b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
391b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
392b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
393b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
394b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasando_io(struct thread_state_s *state)
395b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
396b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	void *db_node;
397b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct ioshark_header header;
398b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct ioshark_file_operation file_op;
399b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int fd;
400b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int i;
401b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	char *buf = NULL;
402b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int buflen = 0;
403b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct timeval total_delay_time;
404b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	u_int64_t op_counts[IOSHARK_MAX_FILE_OP];
405b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct rw_bytes_s rw_bytes;
406b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
407b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	rewind(state->fp);
408b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (fread(&header, sizeof(struct ioshark_header), 1, state->fp) != 1) {
409b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fprintf(stderr, "%s read error %s\n",
410b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			progname, state->filename);
411b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		exit(EXIT_FAILURE);
412b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
413b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	/*
414b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * First open and pre-create all the files. Indexed by fileno.
415b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 */
416b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	timerclear(&total_delay_time);
417b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	memset(&rw_bytes, 0, sizeof(struct rw_bytes_s));
418b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	memset(op_counts, 0, sizeof(op_counts));
419b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	fseek(state->fp,
420b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	      sizeof(struct ioshark_header) +
421b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	      header.num_files * sizeof(struct ioshark_file_state),
422b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	      SEEK_SET);
423b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	/*
424b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * Loop over all the IOs, and launch each
425b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 */
426b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	for (i = 0 ; i < header.num_io_operations ; i++) {
427b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (fread(&file_op, sizeof(struct ioshark_file_operation),
428b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			  1, state->fp) != 1) {
429b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s read error trace.outfile\n",
430b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname);
431b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
432b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
433b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (do_delay) {
434b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			struct timeval start;
435b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
436b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			(void)gettimeofday(&start, (struct timezone *)NULL);
4379d00a124c5591198264ffedf0ba4c73bddfc346fMohan Srinivasan			usleep(file_op.delta_us);
438b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			update_delta_time(&start, &total_delay_time);
439b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
440b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		db_node = files_db_lookup_byfileno(state->db_handle,
441b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						   file_op.fileno);
442b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (db_node == NULL) {
443b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr,
444b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				"%s Can't lookup fileno %d, fatal error\n",
445b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, file_op.fileno);
446b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
447b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
448b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (file_op.file_op != IOSHARK_OPEN &&
449b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		    files_db_get_fd(db_node) == -1) {
45002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			int openflags;
45102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
452b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			/*
453b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			 * This is a hack to workaround the fact that we did not
45402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			 * see an open() for this file until now. open() the
45502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			 * file O_RDWR, so that we can perform the IO.
456b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			 */
45702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			if (files_db_readonly(db_node))
45802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				openflags = O_RDONLY;
45902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			else
46002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				openflags = O_RDWR;
46102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			fd = open(files_db_get_filename(db_node),
46202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				  openflags);
463b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (fd < 0) {
46402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				fprintf(stderr, "%s: open(%s %x) error %d\n",
46502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan					progname,
46602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan					files_db_get_filename(db_node),
46702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan					openflags,
468b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					errno);
469b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				exit(EXIT_FAILURE);
470b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
471b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			files_db_update_fd(db_node, fd);
472b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
473b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		do_one_io(db_node, &file_op,
474b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			  op_counts, &rw_bytes, &buf, &buflen);
475b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
476b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	files_db_fsync_discard_files(state->db_handle);
477b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	files_db_close_files(state->db_handle);
478b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	update_time(&aggregate_delay_time, &total_delay_time);
479b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	update_op_counts(op_counts);
480b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	update_byte_counts(&aggr_io_rw_bytes, &rw_bytes);
481b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
482b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
483b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanvoid *
484b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanio_thread(void *unused __attribute__((unused)))
485b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
486b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct thread_state_s *state;
487b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
488b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	srand(gettid());
489b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	while ((state = get_work()))
490b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		do_io(state);
491b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_exit(NULL);
492b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan        return(NULL);
493b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
494b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
495b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanstatic void
496b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasando_create(struct thread_state_s *state)
497b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
498b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct ioshark_header header;
499b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
500b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (fread(&header, sizeof(struct ioshark_header), 1, state->fp) != 1) {
501b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fprintf(stderr, "%s read error %s\n",
502b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			progname, state->filename);
503b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		exit(EXIT_FAILURE);
504b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
505b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	state->num_files = header.num_files;
506b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	state->db_handle = files_db_create_handle();
507b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	create_files(state);
508b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
509b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
510b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanvoid *
511b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasancreate_files_thread(void *unused __attribute__((unused)))
512b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
513b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct thread_state_s *state;
514b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
515b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	while ((state = get_work()))
516b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		do_create(state);
517b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_exit(NULL);
518b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	return(NULL);
519b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
520b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
521b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint
522b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanget_start_end(int *start_ix)
523b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
524b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int i, j, ret_numfiles;
525b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	u_int64_t free_fs_bytes;
526b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	char *infile;
527b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	FILE *fp;
528b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct ioshark_header header;
529b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct ioshark_file_state file_state;
530b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct statfs fsstat;
531b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	static int fssize_clamp_next_index = 0;
532b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	static int chunk = 0;
533b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
534b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (fssize_clamp_next_index == num_input_files)
535b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		return 0;
536b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (statfs("/data/local/tmp", &fsstat) < 0) {
537b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fprintf(stderr, "%s: Can't statfs /data/local/tmp\n",
538b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			progname);
539b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		exit(EXIT_FAILURE);
540b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
541b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	free_fs_bytes = (fsstat.f_bavail * fsstat.f_bsize) * 9 /10;
542b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	for (i = fssize_clamp_next_index; i < num_input_files; i++) {
543b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		infile = thread_state[i].filename;
544b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fp = fopen(infile, "r");
545b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (fp == NULL) {
546b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s: Can't open %s\n",
547b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, infile);
548b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
549b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
550b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (fread(&header, sizeof(struct ioshark_header),
551b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			  1, fp) != 1) {
552b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s read error %s\n",
553b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, infile);
554b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
555b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
556b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		for (j = 0 ; j < header.num_files ; j++) {
557b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (fread(&file_state, sizeof(struct ioshark_file_state),
558b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				  1, fp) != 1) {
559b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				fprintf(stderr, "%s read error tracefile\n",
560b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					progname);
561b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				exit(EXIT_FAILURE);
562b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
56302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			if (quick_mode == 0 ||
56402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			    !is_readonly_mount(
56502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				    get_ro_filename(file_state.global_filename_ix),
56602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				    file_state.size)) {
56702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				if (file_state.size > free_fs_bytes) {
56802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan					fclose(fp);
56902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan					goto out;
57002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				}
57102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan				free_fs_bytes -= file_state.size;
572b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
573b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
574b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fclose(fp);
575b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
576b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanout:
577b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (verbose) {
578b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (chunk > 0 || i < num_input_files) {
579b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			printf("Breaking up input files, Chunk %d: %d to %d\n",
580b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			       chunk++, fssize_clamp_next_index, i - 1);
581b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		} else {
582b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			printf("Entire Dataset fits start = %d to %d, free_bytes = %ju\n",
583b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			       fssize_clamp_next_index,
584b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			       i - fssize_clamp_next_index,
585b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			       free_fs_bytes);
586b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
587b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
588b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	*start_ix = fssize_clamp_next_index;
589b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	ret_numfiles = i - fssize_clamp_next_index;
590b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	fssize_clamp_next_index = i;
591b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	return ret_numfiles;
592b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
593b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
594b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint
595b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanioshark_pthread_create(pthread_t *tidp, void *(*start_routine)(void *))
596b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
597b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_attr_t attr;
598b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
599b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_attr_init(&attr);
600b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
601b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	pthread_attr_setstacksize(&attr, (size_t)(1024*1024));
602b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	return pthread_create(tidp, &attr, start_routine, (void *)NULL);
603b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
604b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
605b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanvoid
606b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanwait_for_threads(int num_threads)
607b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
608b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int i;
609b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
610b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	for (i = 0; i < num_threads; i++) {
611b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		pthread_join(tid[i], NULL);
612b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		tid[i] = 0;
613b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
614b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
615b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
61602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan#define IOSHARK_FD_LIM		8192
61702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
61802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasanstatic void
61902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasansizeup_fd_limits(void)
62002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan{
62102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	struct rlimit r;
62202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
62302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	getrlimit(RLIMIT_NOFILE, &r);
62402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	if (r.rlim_cur >= IOSHARK_FD_LIM)
62502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		/* cur limit already at what we want */
62602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		return;
62702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	/*
62802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	 * Size up both the Max and Cur to IOSHARK_FD_LIM.
62902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	 * If we are not running as root, this will fail,
63002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	 * catch that below and exit.
63102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	 */
63202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	if (r.rlim_max < IOSHARK_FD_LIM)
63302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		r.rlim_max = IOSHARK_FD_LIM;
63402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	r.rlim_cur = IOSHARK_FD_LIM;
63502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	if (setrlimit(RLIMIT_NOFILE, &r) < 0) {
63602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		fprintf(stderr, "%s: Can't setrlimit (RLIMIT_NOFILE, 8192)\n",
63702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			progname);
63802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		exit(EXIT_FAILURE);
63902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	}
64002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	getrlimit(RLIMIT_NOFILE, &r);
64102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	if (r.rlim_cur < IOSHARK_FD_LIM) {
64202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		fprintf(stderr, "%s: Can't setrlimit up to 8192\n",
64302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			progname);
64402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		fprintf(stderr, "%s: Running as root ?\n",
64502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			progname);
64602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		exit(EXIT_FAILURE);
64702f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	}
64802f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan}
64902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
650b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanint
651b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasanmain(int argc, char **argv)
652b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan{
653b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int i;
654b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	FILE *fp;
655b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct stat st;
656b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	char *infile;
657b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int num_threads = 0;
658b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int num_iterations = 1;
659b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int c;
660b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	int num_files, start_file;
661b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	struct thread_state_s *state;
662b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
663b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	progname = argv[0];
66402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan        while ((c = getopt(argc, argv, "dn:st:qv")) != EOF) {
665b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan                switch (c) {
666b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan                case 'd':
667b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			do_delay = 1;
668b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			break;
669b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan                case 'n':
670b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			num_iterations = atoi(optarg);
671b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			break;
6722aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan                case 's':
6732aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			/* Non-verbose summary mode for nightly runs */
6742aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			summary_mode = 1;
6752aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			break;
676b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan                case 't':
677b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			num_threads = atoi(optarg);
678b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			break;
67902f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan                case 'q':
68002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			/*
68102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			 * If quick mode is enabled, then we won't
68202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			 * pre-create files that we are doing IO on that
68302f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			 * live in readonly partitions (/system, /vendor etc)
68402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			 */
68502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			quick_mode = 1;
68602f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			break;
687b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan                case 'v':
688b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			verbose = 1;
689b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			break;
690b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan 	        default:
6919d00a124c5591198264ffedf0ba4c73bddfc346fMohan Srinivasan			usage();
692b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
693b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
694b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
6952aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan	if ((verbose + summary_mode) == 2)
6962aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		usage();
6972aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan
698b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (num_threads > MAX_THREADS)
699b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		usage();
700b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
701b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (optind == argc)
702b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan                usage();
703b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
70402f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	sizeup_fd_limits();
70502f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
706b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	for (i = optind; i < argc; i++) {
707b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		infile = argv[i];
708b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (stat(infile, &st) < 0) {
709b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s: Can't stat %s\n",
710b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, infile);
711b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			exit(EXIT_FAILURE);
712b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
713b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (st.st_size == 0) {
714b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s: Empty file %s\n",
715b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, infile);
716b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			continue;
717b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
718b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		fp = fopen(infile, "r");
719b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (fp == NULL) {
720b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			fprintf(stderr, "%s: Can't open %s\n",
721b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				progname, infile);
722b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			continue;
723b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
724b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		thread_state[num_input_files].filename = infile;
725b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		thread_state[num_input_files].fp = fp;
726b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		num_input_files++;
727b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
728b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
729b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (num_input_files == 0) {
730b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		exit(EXIT_SUCCESS);
731b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
732b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	if (verbose) {
733b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		printf("Total Input Files = %d\n", num_input_files);
734b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		printf("Num Iterations = %d\n", num_iterations);
735b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
736b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	timerclear(&aggregate_file_create_time);
737b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	timerclear(&aggregate_file_remove_time);
738b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	timerclear(&aggregate_IO_time);
739b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
74002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	if (quick_mode)
74102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		init_filename_cache();
74202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan
743b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	capture_util_state_before();
744b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
745b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	/*
746b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * We pre-create the files that we need once and then we
747b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * loop around N times doing IOs on the pre-created files.
748b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 *
749b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * get_start_end() breaks up the total work here to make sure
750b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * that all the files we need to pre-create fit into the
751b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * available space in /data/local/tmp (hardcoded for now).
752b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 *
753b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 * If it won't fit, then we do several sweeps.
754b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	 */
755b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	while ((num_files = get_start_end(&start_file))) {
756b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		struct timeval time_for_pass;
757b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
758b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		/* Create files once */
7592aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		if (!summary_mode)
7602aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			printf("Doing Pre-creation of Files\n");
76102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		if (quick_mode && !summary_mode)
76202f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan			printf("Skipping Pre-creation of read-only Files\n");
763b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		if (num_threads == 0 || num_threads > num_files)
764b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			num_threads = num_files;
765b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		(void)system("echo 3 > /proc/sys/vm/drop_caches");
766b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		init_work(start_file, num_files);
767b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		(void)gettimeofday(&time_for_pass,
768b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				   (struct timezone *)NULL);
769b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		for (i = 0; i < num_threads; i++) {
770b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			if (ioshark_pthread_create(&(tid[i]),
771b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						   create_files_thread)) {
772b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				fprintf(stderr,
773b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					"%s: Can't create creator thread %d\n",
774b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					progname, i);
775b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				exit(EXIT_FAILURE);
776b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
777b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
778b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		wait_for_threads(num_threads);
779b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		update_delta_time(&time_for_pass, &aggregate_file_create_time);
780b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		/* Do the IOs N times */
781b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		for (i = 0 ; i < num_iterations ; i++) {
782b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			(void)system("echo 3 > /proc/sys/vm/drop_caches");
7832aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			if (!summary_mode) {
7842aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan				if (num_iterations > 1)
7852aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan					printf("Starting Test. Iteration %d...\n",
7862aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan					       i);
7872aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan				else
7882aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan					printf("Starting Test...\n");
7892aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			}
790b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			init_work(start_file, num_files);
791b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			(void)gettimeofday(&time_for_pass,
792b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					   (struct timezone *)NULL);
793b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			for (c = 0; c < num_threads; c++) {
794b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				if (ioshark_pthread_create(&(tid[c]),
795b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan							   io_thread)) {
796b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					fprintf(stderr,
797b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						"%s: Can't create thread %d\n",
798b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan						progname, c);
799b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					exit(EXIT_FAILURE);
800b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan				}
801b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			}
802b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			wait_for_threads(num_threads);
803b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			update_delta_time(&time_for_pass,
804b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan					  &aggregate_IO_time);
805b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
806b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
807b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		/*
808b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		 * We are done with the N iterations of IO.
809b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		 * Destroy the files we pre-created.
810b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		 */
811b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		init_work(start_file, num_files);
812b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		while ((state = get_work())) {
813b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			struct timeval start;
814b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan
815b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			(void)gettimeofday(&start, (struct timezone *)NULL);
816b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			files_db_unlink_files(state->db_handle);
817b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			update_delta_time(&start, &aggregate_file_remove_time);
818b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan			files_db_free_memory(state->db_handle);
819b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan		}
820b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan	}
8212aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan	if (!summary_mode) {
8222aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("Total Creation time = %ju.%ju (msecs.usecs)\n",
8232aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_msecs(&aggregate_file_create_time),
8242aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_usecs(&aggregate_file_create_time));
8252aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("Total Remove time = %ju.%ju (msecs.usecs)\n",
8262aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_msecs(&aggregate_file_remove_time),
8272aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_usecs(&aggregate_file_remove_time));
8282aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		if (do_delay)
8292aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			printf("Total delay time = %ju.%ju (msecs.usecs)\n",
8302aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			       get_msecs(&aggregate_delay_time),
8312aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			       get_usecs(&aggregate_delay_time));
8322aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("Total Test (IO) time = %ju.%ju (msecs.usecs)\n",
8332aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_msecs(&aggregate_IO_time),
8342aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_usecs(&aggregate_IO_time));
8352aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		if (verbose)
8362aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			print_bytes("Upfront File Creation bytes",
8372aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan				    &aggr_create_rw_bytes);
8382aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		print_bytes("Total Test (IO) bytes", &aggr_io_rw_bytes);
8392aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		if (verbose)
8402aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			print_op_stats(aggr_op_counts);
8412aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		report_cpu_disk_util();
8422aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan	} else {
8432aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("%ju.%ju ",
8442aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_msecs(&aggregate_file_create_time),
8452aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_usecs(&aggregate_file_create_time));
8462aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("%ju.%ju ",
8472aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_msecs(&aggregate_file_remove_time),
8482aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_usecs(&aggregate_file_remove_time));
8492aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		if (do_delay)
8502aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			printf("%ju.%ju ",
8512aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			       get_msecs(&aggregate_delay_time),
8522aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan			       get_usecs(&aggregate_delay_time));
8532aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("%ju.%ju ",
8542aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_msecs(&aggregate_IO_time),
8552aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		       get_usecs(&aggregate_IO_time));
8562aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		print_bytes(NULL, &aggr_io_rw_bytes);
8572aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		report_cpu_disk_util();
8582aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan		printf("\n");
8592aa6e6fbda3ac6781efd022f01f8006cedda878dMohan Srinivasan	}
86002f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan	if (quick_mode)
86102f8626d766424406bcfea1e20ef352d3b9a72cfMohan Srinivasan		free_filename_cache();
862b707f30a7cdd521db5d0d1c1e5c391e61a1675c9Mohan Srinivasan}
863