diff --git a/include/spdk/event.h b/include/spdk/event.h index 784aedbcb..0827e5033 100644 --- a/include/spdk/event.h +++ b/include/spdk/event.h @@ -236,6 +236,13 @@ spdk_app_parse_args_rvals_t spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, const char *getopt_str, void (*parse)(int ch, char *arg), void (*usage)(void)); +/** + * Print usage strings for common SPDK command line options. + * + * May only be called after spdk_app_parse_args(). + */ +void spdk_app_usage(void); + /** * Allocate an event to be passed to spdk_event_call(). * diff --git a/lib/event/app.c b/lib/event/app.c index 802fd7548..6b174abb9 100644 --- a/lib/event/app.c +++ b/lib/event/app.c @@ -63,6 +63,8 @@ static struct spdk_event *g_shutdown_event = NULL; static int g_init_lcore; static bool g_delay_subsystem_init = false; static bool g_shutdown_sig_received = false; +static char *g_executable_name; +static struct spdk_app_opts g_default_opts; int spdk_app_get_shm_id(void) @@ -614,11 +616,11 @@ spdk_app_stop(int rc) } static void -usage(char *executable_name, struct spdk_app_opts *default_opts, void (*app_usage)(void)) +usage(void (*app_usage)(void)) { - printf("%s [options]\n", executable_name); + printf("%s [options]\n", g_executable_name); printf("options:\n"); - printf(" -c config config file (default %s)\n", default_opts->config_file); + printf(" -c config config file (default %s)\n", g_default_opts.config_file); printf(" -d disable coredump file enabling\n"); printf(" -e mask tracepoint group mask for spdk trace buffers (default 0x0)\n"); printf(" -g force creating just one hugetlbfs file\n"); @@ -630,8 +632,8 @@ usage(char *executable_name, struct spdk_app_opts *default_opts, void (*app_usag printf(" -q disable notice level logging to stderr\n"); printf(" -r RPC listen address (default %s)\n", SPDK_DEFAULT_RPC_ADDR); printf(" -s size memory size in MB for DPDK (default: "); - if (default_opts->mem_size > 0) { - printf("%dMB)\n", default_opts->mem_size); + if (g_default_opts.mem_size > 0) { + printf("%dMB)\n", g_default_opts.mem_size); } else { printf("all hugepage memory)\n"); } @@ -640,7 +642,9 @@ usage(char *executable_name, struct spdk_app_opts *default_opts, void (*app_usag printf(" -B addr pci addr to blacklist\n"); printf(" -W addr pci addr to whitelist (-B and -W cannot be used at the same time)\n"); spdk_tracelog_usage(stdout, "-t"); - app_usage(); + if (app_usage) { + app_usage(); + } } spdk_app_parse_args_rvals_t @@ -649,11 +653,10 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, void (*app_usage)(void)) { int ch, rc; - struct spdk_app_opts default_opts; char *getopt_str; spdk_app_parse_args_rvals_t rval = SPDK_APP_PARSE_ARGS_SUCCESS; - memcpy(&default_opts, opts, sizeof(default_opts)); + memcpy(&g_default_opts, opts, sizeof(g_default_opts)); if (opts->config_file && access(opts->config_file, F_OK) != 0) { opts->config_file = NULL; @@ -666,6 +669,8 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, goto parse_early_fail; } + g_executable_name = argv[0]; + while ((ch = getopt(argc, argv, getopt_str)) != -1) { switch (ch) { case 'c': @@ -681,7 +686,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, opts->hugepage_single_segments = true; break; case 'h': - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_HELP; goto parse_done; case 'i': @@ -721,7 +726,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, rc = spdk_parse_capacity(optarg, &mem_size_mb, &mem_size_has_prefix); if (rc != 0) { fprintf(stderr, "invalid memory pool size `-s %s`\n", optarg); - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; } @@ -735,7 +740,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, if (mem_size_mb > INT_MAX) { fprintf(stderr, "invalid memory pool size `-s %s`\n", optarg); - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; } @@ -747,7 +752,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, rc = spdk_log_set_trace_flag(optarg); if (rc < 0) { fprintf(stderr, "unknown flag\n"); - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; } @@ -755,7 +760,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, #ifndef DEBUG fprintf(stderr, "%s must be built with CONFIG_DEBUG=y for -t flag\n", argv[0]); - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; #else @@ -771,7 +776,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, if (opts->pci_whitelist) { free(opts->pci_whitelist); fprintf(stderr, "-B and -W cannot be used at the same time\n"); - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; } @@ -787,7 +792,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, if (opts->pci_blacklist) { free(opts->pci_blacklist); fprintf(stderr, "-B and -W cannot be used at the same time\n"); - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; } @@ -805,7 +810,7 @@ spdk_app_parse_args(int argc, char **argv, struct spdk_app_opts *opts, * in argv that is NOT in the getopt_str, * getopt() will return a '?' indicating failure. */ - usage(argv[0], &default_opts, app_usage); + usage(app_usage); rval = SPDK_APP_PARSE_ARGS_FAIL; goto parse_done; default: @@ -827,6 +832,17 @@ parse_early_fail: return rval; } +void +spdk_app_usage(void) +{ + if (g_executable_name == NULL) { + fprintf(stderr, "%s not valid before calling spdk_app_parse_args()\n", __func__); + return; + } + + usage(NULL); +} + static void spdk_rpc_start_subsystem_init_cpl(void *arg1, void *arg2) {