show_lat_m(io_u_lat_m);
}
-void show_thread_status_normal(struct thread_stat *ts, struct group_run_stats *rs)
+static void show_thread_status_normal(struct thread_stat *ts,
+ struct group_run_stats *rs)
{
double usr_cpu, sys_cpu;
unsigned long runtime;
}
json_object_add_value_int(dir_object, "bw_min", min);
json_object_add_value_int(dir_object, "bw_max", max);
- json_object_add_value_float(dir_object, "bw_agg", mean);
+ json_object_add_value_float(dir_object, "bw_agg", p_of_agg);
json_object_add_value_float(dir_object, "bw_mean", mean);
json_object_add_value_float(dir_object, "bw_dev", dev);
}
log_info("\n");
/* Additional output if description is set */
- if (ts->description)
+ if (strlen(ts->description))
log_info(";%s", ts->description);
log_info("\n");
if (output_format == FIO_OUTPUT_TERSE)
show_thread_status_terse(ts, rs);
else if (output_format == FIO_OUTPUT_JSON)
- return(show_thread_status_json(ts, rs));
+ return show_thread_status_json(ts, rs);
else
show_thread_status_normal(ts, rs);
return NULL;
ts->groupid = -1;
}
-static void __show_run_stats(void)
+void __show_run_stats(void)
{
struct group_run_stats *runstats, *rs;
struct thread_data *td;
/*
* These are per-group shared already
*/
- strncpy(ts->name, td->o.name, FIO_JOBNAME_SIZE);
+ strncpy(ts->name, td->o.name, FIO_JOBNAME_SIZE - 1);
if (td->o.description)
strncpy(ts->description, td->o.description,
- FIO_JOBNAME_SIZE);
+ FIO_JOBDESC_SIZE - 1);
else
- memset(ts->description, 0, FIO_JOBNAME_SIZE);
+ memset(ts->description, 0, FIO_JOBDESC_SIZE);
/*
* If multiple entries in this group, this is
if (!td->error && td->o.continue_on_error &&
td->first_error) {
ts->error = td->first_error;
- strcpy(ts->verror, td->verror);
+ ts->verror[sizeof(ts->verror) - 1] = '\0';
+ strncpy(ts->verror, td->verror, sizeof(ts->verror) - 1);
} else if (td->error) {
ts->error = td->error;
- strcpy(ts->verror, td->verror);
+ ts->verror[sizeof(ts->verror) - 1] = '\0';
+ strncpy(ts->verror, td->verror, sizeof(ts->verror) - 1);
}
}
fio_mutex_up(stat_mutex);
}
-static void *__show_running_run_stats(void fio_unused *arg)
+static void *__show_running_run_stats(void *arg)
{
struct thread_data *td;
unsigned long long *rt;
struct timeval tv;
int i;
+ fio_mutex_down(stat_mutex);
+
rt = malloc(thread_number * sizeof(unsigned long long));
fio_gettime(&tv, NULL);
free(rt);
fio_mutex_up(stat_mutex);
+ free(arg);
return NULL;
}
*/
void show_running_run_stats(void)
{
- pthread_t thread;
+ pthread_t *thread;
- fio_mutex_down(stat_mutex);
+ thread = calloc(1, sizeof(*thread));
+ if (!thread)
+ return;
+
+ if (!pthread_create(thread, NULL, __show_running_run_stats, thread)) {
+ int err;
+
+ err = pthread_detach(*thread);
+ if (err)
+ log_err("fio: DU thread detach failed: %s\n", strerror(err));
- if (!pthread_create(&thread, NULL, __show_running_run_stats, NULL)) {
- pthread_detach(thread);
return;
}
- fio_mutex_up(stat_mutex);
+ free(thread);
}
static int status_interval_init;
static struct timeval status_time;
+static int status_file_disabled;
#define FIO_STATUS_FILE "fio-dump-status"
const char *temp_dir;
char fio_status_file_path[PATH_MAX];
+ if (status_file_disabled)
+ return 0;
+
temp_dir = getenv("TMPDIR");
- if (temp_dir == NULL)
+ if (temp_dir == NULL) {
temp_dir = getenv("TEMP");
+ if (temp_dir && strlen(temp_dir) >= PATH_MAX)
+ temp_dir = NULL;
+ }
if (temp_dir == NULL)
temp_dir = "/tmp";
if (stat(fio_status_file_path, &sb))
return 0;
- unlink(fio_status_file_path);
+ if (unlink(fio_status_file_path) < 0) {
+ log_err("fio: failed to unlink %s: %s\n", fio_status_file_path,
+ strerror(errno));
+ log_err("fio: disabling status file updates\n");
+ status_file_disabled = 1;
+ }
+
return 1;
}
static void __add_log_sample(struct io_log *iolog, unsigned long val,
enum fio_ddir ddir, unsigned int bs,
- unsigned long t)
+ unsigned long t, uint64_t offset)
{
- const int nr_samples = iolog->nr_samples;
+ uint64_t nr_samples = iolog->nr_samples;
+ struct io_sample *s;
if (iolog->disabled)
return;
iolog->avg_last = t;
if (iolog->nr_samples == iolog->max_samples) {
- int new_size = sizeof(struct io_sample) * iolog->max_samples*2;
+ size_t new_size;
void *new_log;
- new_log = realloc(iolog->log, new_size);
- if (!new_log) {
- log_err("fio: failed extending iolog! Will stop logging.\n");
- iolog->disabled = 1;
- return;
+ new_size = 2 * iolog->max_samples * log_entry_sz(iolog);
+
+ if (iolog->log_gz && (new_size > iolog->log_gz)) {
+ if (iolog_flush(iolog, 0)) {
+ log_err("fio: failed flushing iolog! Will stop logging.\n");
+ iolog->disabled = 1;
+ return;
+ }
+ nr_samples = iolog->nr_samples;
+ } else {
+ new_log = realloc(iolog->log, new_size);
+ if (!new_log) {
+ log_err("fio: failed extending iolog! Will stop logging.\n");
+ iolog->disabled = 1;
+ return;
+ }
+ iolog->log = new_log;
+ iolog->max_samples <<= 1;
}
- iolog->log = new_log;
- iolog->max_samples <<= 1;
}
- iolog->log[nr_samples].val = val;
- iolog->log[nr_samples].time = t;
- iolog->log[nr_samples].ddir = ddir;
- iolog->log[nr_samples].bs = bs;
+ s = get_sample(iolog, nr_samples);
+
+ s->val = val;
+ s->time = t;
+ io_sample_set_ddir(iolog, s, ddir);
+ s->bs = bs;
+
+ if (iolog->log_offset) {
+ struct io_sample_offset *so = (void *) s;
+
+ so->offset = offset;
+ }
+
iolog->nr_samples++;
}
unsigned long mr;
mr = iolog->avg_window[DDIR_READ].mean.u.f + 0.50;
- __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed);
+ __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed, 0);
}
if (iolog->avg_window[DDIR_WRITE].samples) {
unsigned long mw;
mw = iolog->avg_window[DDIR_WRITE].mean.u.f + 0.50;
- __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed);
+ __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed, 0);
}
if (iolog->avg_window[DDIR_TRIM].samples) {
unsigned long mw;
mw = iolog->avg_window[DDIR_TRIM].mean.u.f + 0.50;
- __add_log_sample(iolog, mw, DDIR_TRIM, 0, elapsed);
+ __add_log_sample(iolog, mw, DDIR_TRIM, 0, elapsed, 0);
}
reset_io_stat(&iolog->avg_window[DDIR_READ]);
static void add_log_sample(struct thread_data *td, struct io_log *iolog,
unsigned long val, enum fio_ddir ddir,
- unsigned int bs)
+ unsigned int bs, uint64_t offset)
{
unsigned long elapsed, this_window;
* If no time averaging, just add the log sample.
*/
if (!iolog->avg_msec) {
- __add_log_sample(iolog, val, ddir, bs, elapsed);
+ __add_log_sample(iolog, val, ddir, bs, elapsed, offset);
return;
}
return;
iolog = agg_io_log[ddir];
- __add_log_sample(iolog, val, ddir, bs, mtime_since_genesis());
+ __add_log_sample(iolog, val, ddir, bs, mtime_since_genesis(), 0);
}
static void add_clat_percentile_sample(struct thread_stat *ts,
}
void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
- unsigned long usec, unsigned int bs)
+ unsigned long usec, unsigned int bs, uint64_t offset)
{
struct thread_stat *ts = &td->ts;
add_stat_sample(&ts->clat_stat[ddir], usec);
if (td->clat_log)
- add_log_sample(td, td->clat_log, usec, ddir, bs);
+ add_log_sample(td, td->clat_log, usec, ddir, bs, offset);
if (ts->clat_percentiles)
add_clat_percentile_sample(ts, usec, ddir);
}
void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
- unsigned long usec, unsigned int bs)
+ unsigned long usec, unsigned int bs, uint64_t offset)
{
struct thread_stat *ts = &td->ts;
add_stat_sample(&ts->slat_stat[ddir], usec);
if (td->slat_log)
- add_log_sample(td, td->slat_log, usec, ddir, bs);
+ add_log_sample(td, td->slat_log, usec, ddir, bs, offset);
}
void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
- unsigned long usec, unsigned int bs)
+ unsigned long usec, unsigned int bs, uint64_t offset)
{
struct thread_stat *ts = &td->ts;
add_stat_sample(&ts->lat_stat[ddir], usec);
if (td->lat_log)
- add_log_sample(td, td->lat_log, usec, ddir, bs);
+ add_log_sample(td, td->lat_log, usec, ddir, bs, offset);
}
void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs,
if (!delta)
continue; /* No entries for interval */
- rate = delta * 1000 / spent / 1024;
+ if (spent)
+ rate = delta * 1000 / spent / 1024;
+ else
+ rate = 0;
+
add_stat_sample(&ts->bw_stat[ddir], rate);
if (td->bw_log)
- add_log_sample(td, td->bw_log, rate, ddir, bs);
+ add_log_sample(td, td->bw_log, rate, ddir, bs, 0);
td->stat_io_bytes[ddir] = td->this_io_bytes[ddir];
}
if (!delta)
continue; /* No entries for interval */
- iops = (delta * 1000) / spent;
+ if (spent)
+ iops = (delta * 1000) / spent;
+ else
+ iops = 0;
+
add_stat_sample(&ts->iops_stat[ddir], iops);
if (td->iops_log)
- add_log_sample(td, td->iops_log, iops, ddir, bs);
+ add_log_sample(td, td->iops_log, iops, ddir, bs, 0);
td->stat_io_blocks[ddir] = td->this_io_blocks[ddir];
}