parse: make suggestions for unknown options
[fio.git] / init.c
diff --git a/init.c b/init.c
index 108f2b88d1ae611f20308f8c09a8d41f7b61e5b2..9fbc477fd760651d117dc1bd37547bab98454ae9 100644 (file)
--- a/init.c
+++ b/init.c
@@ -65,8 +65,9 @@ int read_only = 0;
 int status_interval = 0;
 
 char *trigger_file = NULL;
-char *trigger_cmd = NULL;
 long long trigger_timeout = 0;
+char *trigger_cmd = NULL;
+char *trigger_remote_cmd = NULL;
 
 static int prev_group_jobs;
 
@@ -246,7 +247,7 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .val            = 'L',
        },
        {
-               .name           = (char *) "trigger",
+               .name           = (char *) "trigger-file",
                .has_arg        = required_argument,
                .val            = 'W',
        },
@@ -255,6 +256,16 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'B',
        },
+       {
+               .name           = (char *) "trigger",
+               .has_arg        = required_argument,
+               .val            = 'H',
+       },
+       {
+               .name           = (char *) "trigger-remote",
+               .has_arg        = required_argument,
+               .val            = 'J',
+       },
        {
                .name           = NULL,
        },
@@ -287,6 +298,11 @@ static void free_shm(void)
                free_threads_shm();
        }
 
+       free(trigger_file);
+       free(trigger_cmd);
+       free(trigger_remote_cmd);
+       trigger_file = trigger_cmd = trigger_remote_cmd = NULL;
+
        options_free(fio_options, &def_thread);
        fio_filelock_exit();
        scleanup();
@@ -549,7 +565,6 @@ static int fixup_options(struct thread_data *td)
        if (!o->max_bs[DDIR_TRIM])
                o->max_bs[DDIR_TRIM] = o->bs[DDIR_TRIM];
 
-
        o->rw_min_bs = min(o->min_bs[DDIR_READ], o->min_bs[DDIR_WRITE]);
        o->rw_min_bs = min(o->min_bs[DDIR_TRIM], o->rw_min_bs);
 
@@ -1679,8 +1694,10 @@ static void usage(const char *name)
 #ifdef CONFIG_ZLIB
        printf("  --inflate-log=log\tInflate and output compressed log\n");
 #endif
-       printf("  --trigger=file:cmd\tExecute trigger cmd when file exists\n");
+       printf("  --trigger-file=file\tExecute trigger cmd when file exists\n");
        printf("  --trigger-timeout=t\tExecute trigger af this time\n");
+       printf("  --trigger=cmd\t\tSet this command as local trigger\n");
+       printf("  --trigger-remote=cmd\tSet this command as remote trigger\n");
        printf("\nFio was written by Jens Axboe <jens.axboe@oracle.com>");
        printf("\n                   Jens Axboe <jaxboe@fusionio.com>");
        printf("\n                   Jens Axboe <axboe@fb.com>\n");
@@ -1858,6 +1875,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;
@@ -2200,33 +2241,15 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                        status_interval = val / 1000;
                        break;
                        }
-               case 'W': {
-                       char *split, *cmd;
-                       size_t sz;
-
-                       split = strchr(optarg, ':');
-                       if (!split) {
-                               log_err("fio: trigger is file:command\n");
-                               do_exit++;
-                               exit_val = 1;
-                       }
-
-                       sz = split - optarg;
-                       if (sz) {
-                               trigger_file = calloc(1, sz + 1);
-                               strncpy(trigger_file, optarg, sz);
-                       }
-
-                       split++;
-                       cmd = trigger_cmd = strdup(split);
-                       strip_blank_front(&trigger_cmd);
-                       strip_blank_end(trigger_cmd);
-                       if (strlen(trigger_cmd) == 0) {
-                               free(cmd);
-                               trigger_cmd = NULL;
-                       }
+               case 'W':
+                       trigger_file = strdup(optarg);
+                       break;
+               case 'H':
+                       trigger_cmd = strdup(optarg);
+                       break;
+               case 'J':
+                       trigger_remote_cmd = strdup(optarg);
                        break;
-                       }
                case 'B':
                        if (check_str_time(optarg, &trigger_timeout, 1)) {
                                log_err("fio: failed parsing time %s\n", optarg);
@@ -2238,6 +2261,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;