init: exit on failure to add all jobs
[fio.git] / init.c
diff --git a/init.c b/init.c
index d12b75d5ee33108075731d879d2870b5a11a34ff..213844647752f4212f88e7dd837149defbf833b5 100644 (file)
--- a/init.c
+++ b/init.c
@@ -40,7 +40,6 @@ const char fio_version_string[] = FIO_VERSION;
 static char **ini_file;
 static int max_jobs = FIO_MAX_JOBS;
 static int dump_cmdline;
 static char **ini_file;
 static int max_jobs = FIO_MAX_JOBS;
 static int dump_cmdline;
-static long long def_timeout;
 static int parse_only;
 
 static struct thread_data def_thread;
 static int parse_only;
 
 static struct thread_data def_thread;
@@ -93,11 +92,6 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'o' | FIO_CLIENT_FLAG,
        },
                .has_arg        = required_argument,
                .val            = 'o' | FIO_CLIENT_FLAG,
        },
-       {
-               .name           = (char *) "timeout",
-               .has_arg        = required_argument,
-               .val            = 't' | FIO_CLIENT_FLAG,
-       },
        {
                .name           = (char *) "latency-log",
                .has_arg        = required_argument,
        {
                .name           = (char *) "latency-log",
                .has_arg        = required_argument,
@@ -362,6 +356,9 @@ static int setup_thread_area(void)
                perror("shmat");
                return 1;
        }
                perror("shmat");
                return 1;
        }
+#ifdef FIO_HAVE_SHM_ATTACH_REMOVED
+       shmctl(shm_id, IPC_RMID, NULL);
+#endif
 #endif
 
        memset(threads, 0, max_jobs * sizeof(struct thread_data));
 #endif
 
        memset(threads, 0, max_jobs * sizeof(struct thread_data));
@@ -373,14 +370,6 @@ static int setup_thread_area(void)
        return 0;
 }
 
        return 0;
 }
 
-static void set_cmd_options(struct thread_data *td)
-{
-       struct thread_options *o = &td->o;
-
-       if (!o->timeout)
-               o->timeout = def_timeout;
-}
-
 static void dump_print_option(struct print_option *p)
 {
        const char *delim;
 static void dump_print_option(struct print_option *p)
 {
        const char *delim;
@@ -451,10 +440,8 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent,
 {
        struct thread_data *td;
 
 {
        struct thread_data *td;
 
-       if (global) {
-               set_cmd_options(&def_thread);
+       if (global)
                return &def_thread;
                return &def_thread;
-       }
        if (setup_thread_area()) {
                log_err("error: failed to setup shm segment\n");
                return NULL;
        if (setup_thread_area()) {
                log_err("error: failed to setup shm segment\n");
                return NULL;
@@ -492,7 +479,6 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent,
        if (!parent->o.group_reporting || parent == &def_thread)
                stat_number++;
 
        if (!parent->o.group_reporting || parent == &def_thread)
                stat_number++;
 
-       set_cmd_options(td);
        return td;
 }
 
        return td;
 }
 
@@ -581,6 +567,17 @@ static unsigned long long get_rand_start_delay(struct thread_data *td)
        return delayrange;
 }
 
        return delayrange;
 }
 
+/*
+ * <3 Johannes
+ */
+static unsigned int gcd(unsigned int m, unsigned int n)
+{
+       if (!n)
+               return m;
+
+       return gcd(n, m % n);
+}
+
 /*
  * Lazy way of fixing up options that depend on each other. We could also
  * define option callback handlers, but this is easier.
 /*
  * Lazy way of fixing up options that depend on each other. We could also
  * define option callback handlers, but this is easier.
@@ -756,6 +753,15 @@ static int fixup_options(struct thread_data *td)
                        o->verify_interval = o->min_bs[DDIR_WRITE];
                else if (td_read(td) && o->verify_interval > o->min_bs[DDIR_READ])
                        o->verify_interval = o->min_bs[DDIR_READ];
                        o->verify_interval = o->min_bs[DDIR_WRITE];
                else if (td_read(td) && o->verify_interval > o->min_bs[DDIR_READ])
                        o->verify_interval = o->min_bs[DDIR_READ];
+
+               /*
+                * Verify interval must be a factor or both min and max
+                * write size
+                */
+               if (o->verify_interval % o->min_bs[DDIR_WRITE] ||
+                   o->verify_interval % o->max_bs[DDIR_WRITE])
+                       o->verify_interval = gcd(o->min_bs[DDIR_WRITE],
+                                                       o->max_bs[DDIR_WRITE]);
        }
 
        if (o->pre_read) {
        }
 
        if (o->pre_read) {
@@ -1017,7 +1023,7 @@ int ioengine_load(struct thread_data *td)
                 */
                if (origeo) {
                        memcpy(td->eo, origeo, td->io_ops->option_struct_size);
                 */
                if (origeo) {
                        memcpy(td->eo, origeo, td->io_ops->option_struct_size);
-                       options_mem_dupe(td->eo, td->io_ops->options);
+                       options_mem_dupe(td->io_ops->options, td->eo);
                } else {
                        memset(td->eo, 0, td->io_ops->option_struct_size);
                        fill_default_options(td->eo, td->io_ops->options);
                } else {
                        memset(td->eo, 0, td->io_ops->option_struct_size);
                        fill_default_options(td->eo, td->io_ops->options);
@@ -1984,6 +1990,11 @@ static void show_debug_categories(void)
 #endif
 }
 
 #endif
 }
 
+/*
+ * Following options aren't printed by usage().
+ * --append-terse - Equivalent to --output-format=terse, see f6a7df53.
+ * --latency-log - Deprecated option.
+ */
 static void usage(const char *name)
 {
        printf("%s\n", fio_version_string);
 static void usage(const char *name)
 {
        printf("%s\n", fio_version_string);
@@ -1992,7 +2003,6 @@ static void usage(const char *name)
        show_debug_categories();
        printf("  --parse-only\t\tParse options only, don't start any IO\n");
        printf("  --output\t\tWrite output to file\n");
        show_debug_categories();
        printf("  --parse-only\t\tParse options only, don't start any IO\n");
        printf("  --output\t\tWrite output to file\n");
-       printf("  --runtime\t\tRuntime in seconds\n");
        printf("  --bandwidth-log\tGenerate aggregate bandwidth logs\n");
        printf("  --minimal\t\tMinimal (terse) output\n");
        printf("  --output-format=type\tOutput format (terse,json,json+,normal)\n");
        printf("  --bandwidth-log\tGenerate aggregate bandwidth logs\n");
        printf("  --minimal\t\tMinimal (terse) output\n");
        printf("  --output-format=type\tOutput format (terse,json,json+,normal)\n");
@@ -2308,13 +2318,6 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        smalloc_pool_size <<= 10;
                        sinit();
                        break;
                        smalloc_pool_size <<= 10;
                        sinit();
                        break;
-               case 't':
-                       if (check_str_time(optarg, &def_timeout, 1)) {
-                               log_err("fio: failed parsing time %s\n", optarg);
-                               do_exit++;
-                               exit_val = 1;
-                       }
-                       break;
                case 'l':
                        log_err("fio: --latency-log is deprecated. Use per-job latency log options.\n");
                        do_exit++;
                case 'l':
                        log_err("fio: --latency-log is deprecated. Use per-job latency log options.\n");
                        do_exit++;
@@ -2323,17 +2326,22 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                case 'b':
                        write_bw_log = 1;
                        break;
                case 'b':
                        write_bw_log = 1;
                        break;
-               case 'o':
+               case 'o': {
+                       FILE *tmp;
+
                        if (f_out && f_out != stdout)
                                fclose(f_out);
 
                        if (f_out && f_out != stdout)
                                fclose(f_out);
 
-                       f_out = fopen(optarg, "w+");
-                       if (!f_out) {
-                               perror("fopen output");
-                               exit(1);
+                       tmp = fopen(optarg, "w+");
+                       if (!tmp) {
+                               log_err("fio: output file open error: %s\n", strerror(errno));
+                               exit_val = 1;
+                               do_exit++;
+                               break;
                        }
                        }
-                       f_err = f_out;
+                       f_err = f_out = tmp;
                        break;
                        break;
+                       }
                case 'm':
                        output_format = FIO_OUTPUT_TERSE;
                        break;
                case 'm':
                        output_format = FIO_OUTPUT_TERSE;
                        break;
@@ -2705,7 +2713,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                if (!ret) {
                        ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
                        if (ret)
                if (!ret) {
                        ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
                        if (ret)
-                               did_arg = 1;
+                               exit(1);
                }
        }
 
                }
        }
 
@@ -2717,9 +2725,6 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
        }
 
 out_free:
        }
 
 out_free:
-       if (pid_file)
-               free(pid_file);
-
        return ini_idx;
 }
 
        return ini_idx;
 }
 
@@ -2788,7 +2793,7 @@ int parse_options(int argc, char *argv[])
                if (did_arg)
                        return 0;
 
                if (did_arg)
                        return 0;
 
-               log_err("No jobs(s) defined\n\n");
+               log_err("No job(s) defined\n\n");
 
                if (!did_arg) {
                        usage(argv[0]);
 
                if (!did_arg) {
                        usage(argv[0]);