#include "fio.h"
#include "parse.h"
-static char fio_version_string[] = "fio 1.15.2";
+static char fio_version_string[] = "fio 1.17.2";
#define FIO_RANDSEED (0xb1899bedUL)
int exitall_on_terminate = 0;
int terse_output = 0;
+int eta_print;
unsigned long long mlock_size = 0;
FILE *f_out = NULL;
FILE *f_err = NULL;
int write_bw_log = 0;
+int read_only = 0;
static int def_timeout = 0;
static int write_lat_log = 0;
{
.name = "showcmd",
.has_arg = no_argument,
- .val = 's'
+ .val = 's',
+ },
+ {
+ .name = "readonly",
+ .has_arg = no_argument,
+ .val = 'r',
+ },
+ {
+ .name = "eta",
+ .has_arg = required_argument,
+ .val = 'e',
},
{
.name = NULL,
{
struct thread_options *o = &td->o;
+ if (read_only && td_write(td)) {
+ log_err("fio: job <%s> has write bit set, but fio is in read-only mode\n", td->o.name);
+ return 1;
+ }
+
if (o->rwmix[DDIR_READ] + o->rwmix[DDIR_WRITE] > 100)
o->rwmix[DDIR_WRITE] = 100 - o->rwmix[DDIR_READ];
if (!o->file_size_high)
o->file_size_high = o->file_size_low;
- if (td_read(td) && !td_rw(td))
- o->verify = 0;
-
if (o->norandommap && o->verify != VERIFY_NONE) {
log_err("fio: norandommap given, verify disabled\n");
o->verify = VERIFY_NONE;
unsigned int global;
struct thread_data *td;
char *string, *name;
- fpos_t off;
FILE *f;
char *p;
int ret = 0, stonewall;
int first_sect = 1;
+ int skip_fgets = 0;
+
+ if (!strcmp(file, "-"))
+ f = stdin;
+ else
+ f = fopen(file, "r");
- f = fopen(file, "r");
if (!f) {
perror("fopen job file");
return 1;
}
string = malloc(4096);
- name = malloc(256);
- memset(name, 0, 256);
+
+ /*
+ * it's really 256 + small bit, 280 should suffice
+ */
+ name = malloc(280);
+ memset(name, 0, 280);
stonewall = stonewall_flag;
do {
- p = fgets(string, 4095, f);
- if (!p)
- break;
+ /*
+ * if skip_fgets is set, we already have loaded a line we
+ * haven't handled.
+ */
+ if (!skip_fgets) {
+ p = fgets(string, 4095, f);
+ if (!p)
+ break;
+ }
+ skip_fgets = 0;
strip_blank_front(&p);
strip_blank_end(p);
if (is_empty_or_comment(p))
continue;
if (sscanf(p, "[%255s]", name) != 1) {
- log_err("fio: option <%s> outside of job section\n", p);
- continue;
+ log_err("fio: option <%s> outside of [] job section\n", p);
+ break;
}
global = !strncmp(name, "global", 6);
stonewall = 0;
}
- fgetpos(f, &off);
while ((p = fgets(string, 4096, f)) != NULL) {
if (is_empty_or_comment(p))
continue;
strip_blank_front(&p);
- if (p[0] == '[')
+ /*
+ * new section, break out and make sure we don't
+ * fgets() a new line at the top.
+ */
+ if (p[0] == '[') {
+ skip_fgets = 1;
break;
+ }
strip_blank_end(p);
- fgetpos(f, &off);
-
/*
* Don't break here, continue parsing options so we
* dump all the bad ones. Makes trial/error fixups
log_info("--%s ", p);
}
- if (!ret) {
- fsetpos(f, &off);
+ if (!ret)
ret = add_job(td, name, 0);
- } else {
+ else {
log_err("fio: job %s dropped\n", name);
put_job(td);
}
free(string);
free(name);
- fclose(f);
+ if (f != stdin)
+ fclose(f);
return ret;
}
{
memset(&def_thread, 0, sizeof(def_thread));
- if (fio_getaffinity(getpid(), &def_thread.o.cpumask) == -1) {
- perror("sched_getaffinity");
- return 1;
- }
+ fio_getaffinity(getpid(), &def_thread.o.cpumask);
/*
* fill default options
def_thread.o.write_bw_log = write_bw_log;
def_thread.o.write_lat_log = write_lat_log;
-#ifdef FIO_HAVE_DISK_UTIL
- def_thread.o.do_disk_util = 1;
-#endif
-
return 0;
}
return 1;
}
+ memset(threads, 0, max_jobs * sizeof(struct thread_data));
atexit(free_shm);
return 0;
}
-static void usage(void)
+static void usage(const char *name)
{
printf("%s\n", fio_version_string);
+ printf("%s [options] [job options] <job file(s)>\n", name);
printf("\t--output\tWrite output to file\n");
printf("\t--timeout\tRuntime in seconds\n");
printf("\t--latency-log\tGenerate per-job latency logs\n");
printf("\t--help\t\tPrint this page\n");
printf("\t--cmdhelp=cmd\tPrint command help, \"all\" for all of them\n");
printf("\t--showcmd\tTurn a job file into command line options\n");
+ printf("\t--eta=when\tWhen ETA estimate should be printed\n");
+ printf("\t \tMay be \"always\", \"never\" or \"auto\"\n");
}
static int parse_cmd_line(int argc, char *argv[])
terse_output = 1;
break;
case 'h':
- usage();
+ usage(argv[0]);
exit(0);
case 'c':
exit(fio_show_option_help(optarg));
case 's':
dump_cmdline = 1;
break;
+ case 'r':
+ read_only = 1;
+ break;
case 'v':
printf("%s\n", fio_version_string);
exit(0);
+ case 'e':
+ if (!strcmp("always", optarg))
+ eta_print = FIO_ETA_ALWAYS;
+ else if (!strcmp("never", optarg))
+ eta_print = FIO_ETA_NEVER;
+ break;
case FIO_GETOPT_JOB: {
const char *opt = long_options[lidx].name;
char *val = optarg;
td = NULL;
}
if (!td) {
- int global = !strncmp(val, "global", 6);
+ int global = 0;
+
+ if (strncmp(opt, "name", 4) ||
+ !strncmp(val, "global", 6))
+ global = 1;
td = get_new_job(global, &def_thread);
if (!td)
return 0;
log_err("No jobs defined(s)\n");
+ usage(argv[0]);
return 1;
}