Always exit if do_exit is set after parse
[fio.git] / init.c
diff --git a/init.c b/init.c
index 8c80298eba43de746a14b8a392cea27f5c782bad..c44fa671aa9a3851da57270dd4b901ec272223be 100644 (file)
--- a/init.c
+++ b/init.c
@@ -45,7 +45,6 @@ int exitall_on_terminate = 0;
 int output_format = FIO_OUTPUT_NORMAL;
 int eta_print = FIO_ETA_AUTO;
 int eta_new_line = 0;
-unsigned long long mlock_size = 0;
 FILE *f_out = NULL;
 FILE *f_err = NULL;
 char **job_sections = NULL;
@@ -59,6 +58,7 @@ int log_syslog = 0;
 
 int write_bw_log = 0;
 int read_only = 0;
+int status_interval = 0;
 
 static int write_lat_log;
 
@@ -124,9 +124,9 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .val            = 'c' | FIO_CLIENT_FLAG,
        },
        {
-               .name              = (char *) "enghelp",
+               .name           = (char *) "enghelp",
                .has_arg        = optional_argument,
-               .val                = 'i' | FIO_CLIENT_FLAG,
+               .val            = 'i' | FIO_CLIENT_FLAG,
        },
        {
                .name           = (char *) "showcmd",
@@ -212,6 +212,11 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'I',
        },
+       {
+               .name           = (char *) "status-interval",
+               .has_arg        = required_argument,
+               .val            = 'L',
+       },
        {
                .name           = NULL,
        },
@@ -616,6 +621,14 @@ static int fixup_options(struct thread_data *td)
        if (td->o.random_distribution != FIO_RAND_DIST_RANDOM)
                td->o.norandommap = 1;
 
+       /*
+        * If size is set but less than the min block size, complain
+        */
+       if (o->size && o->size < td_min_bs(td)) {
+               log_err("fio: size too small, must be larger than the IO size: %llu\n", (unsigned long long) o->size);
+               ret = 1;
+       }
+
        return ret;
 }
 
@@ -688,6 +701,7 @@ static void td_fill_rand_seeds_os(struct thread_data *td)
                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_OFF], &td->seq_rand_state);
 }
 
 static void td_fill_rand_seeds_internal(struct thread_data *td)
@@ -709,6 +723,7 @@ static void td_fill_rand_seeds_internal(struct thread_data *td)
                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, td->rand_seeds[FIO_RAND_SEQ_RAND_OFF]);
 }
 
 void td_fill_rand_seeds(struct thread_data *td)
@@ -1362,6 +1377,8 @@ static void usage(const char *name)
        printf("            \t\tMay be \"always\", \"never\" or \"auto\"\n");
        printf("  --eta-newline=time\tForce a new line for every 'time'");
        printf(" period passed\n");
+       printf("  --status-interval=t\tForce full status dump every");
+       printf(" 't' period passed\n");
        printf("  --readonly\t\tTurn on safety read-only checks, preventing"
                " writes\n");
        printf("  --section=name\tOnly run specified section in job file\n");
@@ -1708,7 +1725,20 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                                fio_options_set_ioengine_opts(l_opts, td);
                        }
 
-                       ret = fio_cmd_option_parse(td, opt, val);
+                       if ((!val || !strlen(val)) &&
+                           l_opts[lidx].has_arg == required_argument) {
+                               log_err("fio: option %s requires an argument\n", opt);
+                               ret = 1;
+                       } else
+                               ret = fio_cmd_option_parse(td, opt, val);
+
+                       if (ret) {
+                               if (td) {
+                                       put_job(td);
+                                       td = NULL;
+                               }
+                               do_exit++;
+                       }
 
                        if (!ret && !strcmp(opt, "ioengine")) {
                                free_ioengine(td);
@@ -1790,6 +1820,18 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        do_exit++;
                        exit_val = fio_monotonic_clocktest();
                        break;
+               case 'L': {
+                       long long val;
+
+                       if (check_str_time(optarg, &val)) {
+                               log_err("fio: failed parsing time %s\n", optarg);
+                               do_exit++;
+                               exit_val = 1;
+                               break;
+                       }
+                       status_interval = val * 1000;
+                       break;
+                       }
                case '?':
                        log_err("%s: unrecognized option '%s'\n", argv[0],
                                                        argv[optind - 1]);
@@ -1802,10 +1844,8 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        break;
        }
 
-       if (do_exit) {
-               if (exit_val && !(is_backend || nr_clients))
-                       exit(exit_val);
-       }
+       if (do_exit && !(is_backend || nr_clients))
+               exit(exit_val);
 
        if (nr_clients && fio_clients_connect()) {
                do_exit++;