splice: fix fallback from copy vmsplice to nothing
[fio.git] / init.c
diff --git a/init.c b/init.c
index 6cbed8c86ea1d9593719bdd4ffdae37ba72c6456..dc5fed94f86fa17c6e05511f2666108eff1b10b5 100644 (file)
--- a/init.c
+++ b/init.c
@@ -17,7 +17,7 @@
 #include "fio.h"
 #include "parse.h"
 
-static char fio_version_string[] = "fio 1.16.7";
+static char fio_version_string[] = "fio 1.17.1";
 
 #define FIO_RANDSEED           (0xb1899bedUL)
 
@@ -30,11 +30,13 @@ struct thread_data *threads = NULL;
 
 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;
@@ -89,7 +91,17 @@ static struct option long_options[FIO_NR_OPTIONS] = {
        {
                .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,
@@ -180,6 +192,11 @@ static int fixup_options(struct thread_data *td)
 {
        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];
 
@@ -222,9 +239,6 @@ static int fixup_options(struct thread_data *td)
        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;
@@ -551,13 +565,17 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
        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;
@@ -573,10 +591,17 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
 
        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);
 
@@ -613,20 +638,23 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
                        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
@@ -637,10 +665,9 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
                                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);
                }
@@ -651,7 +678,8 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
 
        free(string);
        free(name);
-       fclose(f);
+       if (f != stdin)
+               fclose(f);
        return ret;
 }
 
@@ -734,6 +762,8 @@ static void usage(void)
        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[])
@@ -771,9 +801,18 @@ static int parse_cmd_line(int argc, char *argv[])
                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;