Use PATH_MAX instead of _POSIX_HOST_NAME_MAX
[fio.git] / init.c
diff --git a/init.c b/init.c
index 4f66759b59b551ea0364231c45e7e61110b85ca0..fa50d3c61b9e7af4680ab6dceec53b214cd3d4d6 100644 (file)
--- a/init.c
+++ b/init.c
@@ -596,8 +596,7 @@ static int fixup_options(struct thread_data *td)
        if (o->norandommap && o->verify != VERIFY_NONE
            && !fixed_block_size(o))  {
                log_err("fio: norandommap given for variable block sizes, "
-                       "verify disabled\n");
-               o->verify = VERIFY_NONE;
+                       "verify limited\n");
                ret = warnings_fatal;
        }
        if (o->bs_unaligned && (o->odirect || td->io_ops->flags & FIO_RAWIO))
@@ -758,6 +757,23 @@ static int fixup_options(struct thread_data *td)
                ret = 1;
        }
 
+       if (fio_option_is_set(o, gtod_cpu)) {
+               fio_gtod_init();
+               fio_gtod_set_cpu(o->gtod_cpu);
+               fio_gtod_offload = 1;
+       }
+
+       td->loops = o->loops;
+       if (!td->loops)
+               td->loops = 1;
+
+       if (td->o.block_error_hist && td->o.nr_files != 1) {
+               log_err("fio: block error histogram only available with "
+                       "with a single file per job, but %d files "
+                       "provided\n", td->o.nr_files);
+               ret = 1;
+       }
+
        return ret;
 }
 
@@ -926,10 +942,23 @@ static void init_flags(struct thread_data *td)
                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;
+
+       if (o->verify_async || o->io_submit_mode == IO_MODE_OFFLOAD)
+               td->flags |= TD_F_NEED_LOCK;
 }
 
 static int setup_random_seeds(struct thread_data *td)
@@ -1020,8 +1049,14 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
                                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: {
@@ -1030,8 +1065,14 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
                                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: {
@@ -1040,8 +1081,14 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
                                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:
@@ -1875,6 +1922,30 @@ static void parse_cmd_client(void *client, char *opt)
        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;
@@ -2074,6 +2145,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                                                td = NULL;
                                        }
                                        do_exit++;
+                                       exit_val = 1;
                                        break;
                                }
                                fio_options_set_ioengine_opts(l_opts, td);
@@ -2092,6 +2164,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                                        td = NULL;
                                }
                                do_exit++;
+                               exit_val = 1;
                        }
 
                        if (!ret && !strcmp(opt, "ioengine")) {
@@ -2100,6 +2173,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                                        put_job(td);
                                        td = NULL;
                                        do_exit++;
+                                       exit_val = 1;
                                        break;
                                }
                                fio_options_set_ioengine_opts(l_opts, td);
@@ -2168,6 +2242,35 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                                exit_val = 1;
                                break;
                        }
+                       /* if --client parameter contains a pathname */
+                       if (0 == access(optarg, R_OK)) {
+                               /* file contains a list of host addrs or names */
+                               char hostaddr[PATH_MAX] = {0};
+                               char formatstr[8];
+                               FILE * hostf = fopen(optarg, "r");
+                               if (!hostf) {
+                                       log_err("fio: could not open client list file %s for read\n", optarg);
+                                       do_exit++;
+                                       exit_val = 1;
+                                       break;
+                               }
+                               sprintf(formatstr, "%%%ds", PATH_MAX - 1);
+                               /*
+                                * read at most PATH_MAX-1 chars from each
+                                * record in this file
+                                */
+                               while (fscanf(hostf, formatstr, hostaddr) == 1) {
+                                       /* expect EVERY host in file to be valid */
+                                       if (fio_client_add(&fio_client_ops, hostaddr, &cur_client)) {
+                                               log_err("fio: failed adding client %s from file %s\n", hostaddr, optarg);
+                                               do_exit++;
+                                               exit_val = 1;
+                                               break;
+                                       }
+                               }
+                               fclose(hostf);
+                               break; /* no possibility of job file for "this client only" */
+                       }
                        if (fio_client_add(&fio_client_ops, optarg, &cur_client)) {
                                log_err("fio: failed adding client %s\n", optarg);
                                do_exit++;
@@ -2198,7 +2301,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                case 'T':
                        did_arg = 1;
                        do_exit++;
-                       exit_val = fio_monotonic_clocktest();
+                       exit_val = fio_monotonic_clocktest(1);
                        break;
                case 'G':
                        did_arg = 1;
@@ -2218,12 +2321,18 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        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':
@@ -2237,6 +2346,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                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;
@@ -2354,12 +2464,6 @@ int parse_options(int argc, char *argv[])
                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);