int read_only = 0;
int status_interval = 0;
+char *trigger_file = NULL;
+long long trigger_timeout = 0;
+char *trigger_cmd = NULL;
+char *trigger_remote_cmd = NULL;
+
static int prev_group_jobs;
unsigned long fio_debug = 0;
.has_arg = required_argument,
.val = 'C',
},
+ {
+ .name = (char *) "remote-config",
+ .has_arg = required_argument,
+ .val = 'R',
+ },
{
.name = (char *) "cpuclock-test",
.has_arg = no_argument,
.has_arg = required_argument,
.val = 'L',
},
+ {
+ .name = (char *) "trigger-file",
+ .has_arg = required_argument,
+ .val = 'W',
+ },
+ {
+ .name = (char *) "trigger-timeout",
+ .has_arg = required_argument,
+ .val = 'B',
+ },
+ {
+ .name = (char *) "trigger",
+ .has_arg = required_argument,
+ .val = 'H',
+ },
+ {
+ .name = (char *) "trigger-remote",
+ .has_arg = required_argument,
+ .val = 'J',
+ },
{
.name = NULL,
},
free_threads_shm();
}
+ free(trigger_file);
+ free(trigger_cmd);
+ free(trigger_remote_cmd);
+ trigger_file = trigger_cmd = trigger_remote_cmd = NULL;
+
options_free(fio_options, &def_thread);
fio_filelock_exit();
scleanup();
delayrange = td->o.start_delay_high - td->o.start_delay;
- if (td->o.use_os_rand) {
- r = os_random_long(&td->delay_state);
- delayrange = (unsigned long long) ((double) delayrange * (r / (OS_RAND_MAX + 1.0)));
- } else {
- r = __rand(&td->__delay_state);
- delayrange = (unsigned long long) ((double) delayrange * (r / (FRAND_MAX + 1.0)));
- }
+ r = __rand(&td->delay_state);
+ delayrange = (unsigned long long) ((double) delayrange * (r / (FRAND_MAX + 1.0)));
delayrange += td->o.start_delay;
return delayrange;
if (!o->max_bs[DDIR_TRIM])
o->max_bs[DDIR_TRIM] = o->bs[DDIR_TRIM];
-
o->rw_min_bs = min(o->min_bs[DDIR_READ], o->min_bs[DDIR_WRITE]);
o->rw_min_bs = min(o->min_bs[DDIR_TRIM], o->rw_min_bs);
ret = 1;
}
+ if (fio_option_is_set(o, gtod_cpu)) {
+ fio_gtod_init();
+ fio_gtod_set_cpu(o->gtod_cpu);
+ fio_gtod_offload = 1;
+ }
+
return ret;
}
return 1;
}
-static void td_fill_rand_seeds_os(struct thread_data *td)
-{
- os_random_seed(td->rand_seeds[FIO_RAND_BS_OFF], &td->bsrange_state);
- os_random_seed(td->rand_seeds[FIO_RAND_VER_OFF], &td->verify_state);
- os_random_seed(td->rand_seeds[FIO_RAND_MIX_OFF], &td->rwmix_state);
-
- if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
- os_random_seed(td->rand_seeds[FIO_RAND_FILE_OFF], &td->next_file_state);
-
- os_random_seed(td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], &td->file_size_state);
- os_random_seed(td->rand_seeds[FIO_RAND_TRIM_OFF], &td->trim_state);
- os_random_seed(td->rand_seeds[FIO_RAND_START_DELAY], &td->delay_state);
-
- if (!td_random(td))
- return;
-
- if (td->o.rand_repeatable)
- td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
-
- os_random_seed(td->rand_seeds[FIO_RAND_BLOCK_OFF], &td->random_state);
-
- os_random_seed(td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF], &td->seq_rand_state[DDIR_READ]);
- os_random_seed(td->rand_seeds[FIO_RAND_SEQ_RAND_WRITE_OFF], &td->seq_rand_state[DDIR_WRITE]);
- os_random_seed(td->rand_seeds[FIO_RAND_SEQ_RAND_TRIM_OFF], &td->seq_rand_state[DDIR_TRIM]);
-}
-
static void td_fill_rand_seeds_internal(struct thread_data *td)
{
- init_rand_seed(&td->__bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF]);
- init_rand_seed(&td->__verify_state, td->rand_seeds[FIO_RAND_VER_OFF]);
- init_rand_seed(&td->__rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF]);
+ init_rand_seed(&td->bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF]);
+ init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF]);
+ init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF]);
if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
- init_rand_seed(&td->__next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF]);
+ init_rand_seed(&td->next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF]);
- init_rand_seed(&td->__file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
- init_rand_seed(&td->__trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
- init_rand_seed(&td->__delay_state, td->rand_seeds[FIO_RAND_START_DELAY]);
+ init_rand_seed(&td->file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
+ init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
+ init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY]);
if (!td_random(td))
return;
if (td->o.rand_repeatable)
td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
- init_rand_seed(&td->__random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
- init_rand_seed(&td->__seq_rand_state[DDIR_READ], td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF]);
- init_rand_seed(&td->__seq_rand_state[DDIR_WRITE], td->rand_seeds[FIO_RAND_SEQ_RAND_WRITE_OFF]);
- init_rand_seed(&td->__seq_rand_state[DDIR_TRIM], td->rand_seeds[FIO_RAND_SEQ_RAND_TRIM_OFF]);
+ init_rand_seed(&td->random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
+ init_rand_seed(&td->seq_rand_state[DDIR_READ], td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF]);
+ init_rand_seed(&td->seq_rand_state[DDIR_WRITE], td->rand_seeds[FIO_RAND_SEQ_RAND_WRITE_OFF]);
+ init_rand_seed(&td->seq_rand_state[DDIR_TRIM], td->rand_seeds[FIO_RAND_SEQ_RAND_TRIM_OFF]);
}
void td_fill_rand_seeds(struct thread_data *td)
+ i;
}
- if (td->o.use_os_rand)
- td_fill_rand_seeds_os(td);
- else
- td_fill_rand_seeds_internal(td);
+ td_fill_rand_seeds_internal(td);
init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF]);
frand_copy(&td->buf_state_prev, &td->buf_state);
td->flags |= TD_F_READ_IOLOG;
if (o->refill_buffers)
td->flags |= TD_F_REFILL_BUFFERS;
- if (o->scramble_buffers)
+ /*
+ * Always scramble buffers if asked to
+ */
+ if (o->scramble_buffers && fio_option_is_set(o, scramble_buffers))
+ td->flags |= TD_F_SCRAMBLE_BUFFERS;
+ /*
+ * But also scramble buffers, unless we were explicitly asked
+ * to zero them.
+ */
+ if (o->scramble_buffers && !(o->zero_buffers &&
+ fio_option_is_set(o, zero_buffers)))
td->flags |= TD_F_SCRAMBLE_BUFFERS;
if (o->verify != VERIFY_NONE)
td->flags |= TD_F_VER_NONE;
ret = snprintf(dst, dst_left, "%s", jobname);
if (ret < 0)
break;
- dst += ret;
- dst_left -= ret;
+ else if (ret > dst_left) {
+ log_err("fio: truncated filename\n");
+ dst += dst_left;
+ dst_left = 0;
+ } else {
+ dst += ret;
+ dst_left -= ret;
+ }
break;
}
case FPRE_JOBNUM: {
ret = snprintf(dst, dst_left, "%d", jobnum);
if (ret < 0)
break;
- dst += ret;
- dst_left -= ret;
+ else if (ret > dst_left) {
+ log_err("fio: truncated filename\n");
+ dst += dst_left;
+ dst_left = 0;
+ } else {
+ dst += ret;
+ dst_left -= ret;
+ }
break;
}
case FPRE_FILENUM: {
ret = snprintf(dst, dst_left, "%d", filenum);
if (ret < 0)
break;
- dst += ret;
- dst_left -= ret;
+ else if (ret > dst_left) {
+ log_err("fio: truncated filename\n");
+ dst += dst_left;
+ dst_left = 0;
+ } else {
+ dst += ret;
+ dst_left -= ret;
+ }
break;
}
default:
f = fopen(file, "r");
if (!f) {
- perror("fopen job file");
+ int __err = errno;
+
+ log_err("fio: unable to open '%s' job file\n", file);
+ if (td)
+ td_verror(td, __err, "job file open");
return 1;
}
}
log_err("fio: option <%s> outside of "
"[] job section\n", p);
+ ret = 1;
break;
}
printf(" --server=args\t\tStart a backend fio server\n");
printf(" --daemonize=pidfile\tBackground fio server, write pid to file\n");
printf(" --client=hostname\tTalk to remote backend fio server at hostname\n");
+ printf(" --remote-config=file\tTell fio server to load this local job file\n");
printf(" --idle-prof=option\tReport cpu idleness on a system or percpu basis\n"
"\t\t\t(option=system,percpu) or run unit work\n"
"\t\t\tcalibration only (option=calibrate)\n");
#ifdef CONFIG_ZLIB
printf(" --inflate-log=log\tInflate and output compressed log\n");
#endif
+ printf(" --trigger-file=file\tExecute trigger cmd when file exists\n");
+ printf(" --trigger-timeout=t\tExecute trigger af this time\n");
+ printf(" --trigger=cmd\t\tSet this command as local trigger\n");
+ printf(" --trigger-remote=cmd\tSet this command as remote trigger\n");
printf("\nFio was written by Jens Axboe <jens.axboe@oracle.com>");
printf("\n Jens Axboe <jaxboe@fusionio.com>");
printf("\n Jens Axboe <axboe@fb.com>\n");
fio_client_add_cmd_option(client, opt);
}
+static void show_closest_option(const char *name)
+{
+ int best_option, best_distance;
+ int i, distance;
+
+ while (*name == '-')
+ name++;
+
+ best_option = -1;
+ best_distance = INT_MAX;
+ i = 0;
+ while (l_opts[i].name) {
+ distance = string_distance(name, l_opts[i].name);
+ if (distance < best_distance) {
+ best_distance = distance;
+ best_option = i;
+ }
+ i++;
+ }
+
+ if (best_option != -1)
+ log_err("Did you mean %s?\n", l_opts[best_option].name);
+}
+
int parse_cmd_line(int argc, char *argv[], int client_type)
{
struct thread_data *td = NULL;
case 'E': {
long long t = 0;
- if (str_to_decimal(optarg, &t, 0, NULL, 1)) {
+ if (check_str_time(optarg, &t, 1)) {
log_err("fio: failed parsing eta time %s\n", optarg);
exit_val = 1;
do_exit++;
}
- eta_new_line = t;
+ eta_new_line = t / 1000;
break;
}
case 'd':
!strncmp(argv[optind], "-", 1))
break;
- fio_client_add_ini_file(cur_client, argv[optind]);
+ if (fio_client_add_ini_file(cur_client, argv[optind], 0))
+ break;
optind++;
}
break;
+ case 'R':
+ did_arg = 1;
+ if (fio_client_add_ini_file(cur_client, optarg, 1)) {
+ do_exit++;
+ exit_val = 1;
+ }
+ break;
case 'T':
did_arg = 1;
do_exit++;
- exit_val = fio_monotonic_clocktest();
+ exit_val = fio_monotonic_clocktest(1);
break;
case 'G':
did_arg = 1;
case 'L': {
long long val;
- if (check_str_time(optarg, &val, 0)) {
+ if (check_str_time(optarg, &val, 1)) {
log_err("fio: failed parsing time %s\n", optarg);
do_exit++;
exit_val = 1;
break;
}
- status_interval = val * 1000;
+ status_interval = val / 1000;
break;
}
+ case 'W':
+ if (trigger_file)
+ free(trigger_file);
+ trigger_file = strdup(optarg);
+ break;
+ case 'H':
+ if (trigger_cmd)
+ free(trigger_cmd);
+ trigger_cmd = strdup(optarg);
+ break;
+ case 'J':
+ if (trigger_remote_cmd)
+ free(trigger_remote_cmd);
+ trigger_remote_cmd = strdup(optarg);
+ break;
+ case 'B':
+ if (check_str_time(optarg, &trigger_timeout, 1)) {
+ log_err("fio: failed parsing time %s\n", optarg);
+ do_exit++;
+ exit_val = 1;
+ }
+ trigger_timeout /= 1000000;
+ break;
case '?':
log_err("%s: unrecognized option '%s'\n", argv[0],
argv[optind - 1]);
+ show_closest_option(argv[optind - 1]);
default:
do_exit++;
exit_val = 1;
return 0;
}
- if (def_thread.o.gtod_offload) {
- fio_gtod_init();
- fio_gtod_offload = 1;
- fio_gtod_cpu = def_thread.o.gtod_cpu;
- }
-
if (output_format == FIO_OUTPUT_NORMAL)
log_info("%s\n", fio_version_string);