bdevperf: Move down help command / usage functions in a file
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: I326b3c7e60a7aacce9a692c41dcfd0fc19825444 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/513 Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
f7f504cf42
commit
00f1443eb7
@ -949,25 +949,6 @@ bdevperf_submit_on_group(struct spdk_io_channel_iter *i)
|
|||||||
spdk_for_each_channel_continue(i, 0);
|
spdk_for_each_channel_continue(i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
bdevperf_usage(void)
|
|
||||||
{
|
|
||||||
printf(" -q <depth> io depth\n");
|
|
||||||
printf(" -o <size> io size in bytes\n");
|
|
||||||
printf(" -w <type> io pattern type, must be one of (read, write, randread, randwrite, rw, randrw, verify, reset, unmap, flush)\n");
|
|
||||||
printf(" -t <time> time in seconds\n");
|
|
||||||
printf(" -M <percent> rwmixread (100 for reads, 0 for writes)\n");
|
|
||||||
printf(" -P <num> number of moving average period\n");
|
|
||||||
printf("\t\t(If set to n, show weighted mean of the previous n IO/s in real time)\n");
|
|
||||||
printf("\t\t(Formula: M = 2 / (n + 1), EMA[i+1] = IO/s * M + (1 - M) * EMA[i])\n");
|
|
||||||
printf("\t\t(only valid with -S)\n");
|
|
||||||
printf(" -S <period> show performance result in real time every <period> seconds\n");
|
|
||||||
printf(" -T <target> target bdev\n");
|
|
||||||
printf(" -f continue processing I/O even after failures\n");
|
|
||||||
printf(" -z start bdevperf, but wait for RPC to start tests\n");
|
|
||||||
printf(" -C enable every core to send I/Os to each bdev\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cumulative Moving Average (CMA): average of all data up to current
|
* Cumulative Moving Average (CMA): average of all data up to current
|
||||||
* Exponential Moving Average (EMA): weighted mean of the previous n data and more weight is given to recent
|
* Exponential Moving Average (EMA): weighted mean of the previous n data and more weight is given to recent
|
||||||
@ -1110,6 +1091,257 @@ ret:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bdevperf_test(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (g_target_count == 0) {
|
||||||
|
fprintf(stderr, "No valid bdevs found.\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = bdevperf_construct_targets_tasks();
|
||||||
|
if (rc) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Running I/O for %" PRIu64 " seconds...\n", g_time_in_usec / 1000000);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
/* Start a timer to dump performance numbers */
|
||||||
|
g_shutdown_tsc = spdk_get_ticks();
|
||||||
|
if (g_show_performance_real_time) {
|
||||||
|
g_perf_timer = spdk_poller_register(performance_statistics_thread, NULL,
|
||||||
|
g_show_performance_period_in_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate target groups to start all I/O */
|
||||||
|
spdk_for_each_channel(&g_bdevperf, bdevperf_submit_on_group, NULL, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
io_target_group_create(void *io_device, void *ctx_buf)
|
||||||
|
{
|
||||||
|
struct io_target_group *group = ctx_buf;
|
||||||
|
|
||||||
|
TAILQ_INIT(&group->targets);
|
||||||
|
group->lcore = spdk_env_get_current_core();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
io_target_group_destroy(void *io_device, void *ctx_buf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bdevperf_init_thread_done(void *ctx)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
g_master_thread = spdk_get_thread();
|
||||||
|
|
||||||
|
if (g_wait_for_tests) {
|
||||||
|
/* Do not perform any tests until RPC is received */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bdevperf_construct_targets();
|
||||||
|
|
||||||
|
rc = bdevperf_test();
|
||||||
|
if (rc) {
|
||||||
|
g_run_rc = rc;
|
||||||
|
bdevperf_test_done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bdevperf_init_thread(void *ctx)
|
||||||
|
{
|
||||||
|
struct spdk_io_channel *ch;
|
||||||
|
struct io_target_group *group;
|
||||||
|
|
||||||
|
ch = spdk_get_io_channel(&g_bdevperf);
|
||||||
|
group = spdk_io_channel_get_ctx(ch);
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&g_bdevperf.groups, group, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdevperf_run(void *arg1)
|
||||||
|
{
|
||||||
|
spdk_io_device_register(&g_bdevperf, io_target_group_create, io_target_group_destroy,
|
||||||
|
sizeof(struct io_target_group), "bdevperf");
|
||||||
|
|
||||||
|
/* Send a message to each thread and create a target group */
|
||||||
|
spdk_for_each_thread(_bdevperf_init_thread, NULL, _bdevperf_init_thread_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdevperf_stop_io_on_group(struct spdk_io_channel_iter *i)
|
||||||
|
{
|
||||||
|
struct spdk_io_channel *ch;
|
||||||
|
struct io_target_group *group;
|
||||||
|
struct io_target *target;
|
||||||
|
|
||||||
|
ch = spdk_io_channel_iter_get_channel(i);
|
||||||
|
group = spdk_io_channel_get_ctx(ch);
|
||||||
|
|
||||||
|
/* Stop I/O for each block device. */
|
||||||
|
TAILQ_FOREACH(target, &group->targets, link) {
|
||||||
|
end_target(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
spdk_for_each_channel_continue(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spdk_bdevperf_shutdown_cb(void)
|
||||||
|
{
|
||||||
|
g_shutdown = true;
|
||||||
|
|
||||||
|
if (TAILQ_EMPTY(&g_bdevperf.groups)) {
|
||||||
|
spdk_app_stop(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_target_count == 0) {
|
||||||
|
bdevperf_test_done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_shutdown_tsc = spdk_get_ticks() - g_shutdown_tsc;
|
||||||
|
|
||||||
|
/* Send events to stop all I/O on each target group */
|
||||||
|
spdk_for_each_channel(&g_bdevperf, bdevperf_stop_io_on_group, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_perform_tests_cb(void)
|
||||||
|
{
|
||||||
|
struct spdk_json_write_ctx *w;
|
||||||
|
struct spdk_jsonrpc_request *request = g_request;
|
||||||
|
|
||||||
|
g_request = NULL;
|
||||||
|
|
||||||
|
if (g_run_rc == 0) {
|
||||||
|
w = spdk_jsonrpc_begin_result(request);
|
||||||
|
spdk_json_write_uint32(w, g_run_rc);
|
||||||
|
spdk_jsonrpc_end_result(request, w);
|
||||||
|
} else {
|
||||||
|
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
|
"bdevperf failed with error %s", spdk_strerror(-g_run_rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset g_run_rc to 0 for the next test run. */
|
||||||
|
g_run_rc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (params != NULL) {
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
||||||
|
"perform_tests method requires no parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g_request != NULL) {
|
||||||
|
fprintf(stderr, "Another test is already in progress.\n");
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
|
spdk_strerror(-EINPROGRESS));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_request = request;
|
||||||
|
|
||||||
|
bdevperf_construct_targets();
|
||||||
|
|
||||||
|
rc = bdevperf_test();
|
||||||
|
if (rc) {
|
||||||
|
g_run_rc = rc;
|
||||||
|
bdevperf_test_done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SPDK_RPC_REGISTER("perform_tests", rpc_perform_tests, SPDK_RPC_RUNTIME)
|
||||||
|
|
||||||
|
static int
|
||||||
|
bdevperf_parse_arg(int ch, char *arg)
|
||||||
|
{
|
||||||
|
long long tmp;
|
||||||
|
|
||||||
|
if (ch == 'w') {
|
||||||
|
g_workload_type = optarg;
|
||||||
|
} else if (ch == 'T') {
|
||||||
|
g_target_bdev_name = optarg;
|
||||||
|
} else if (ch == 'z') {
|
||||||
|
g_wait_for_tests = true;
|
||||||
|
} else if (ch == 'C') {
|
||||||
|
g_every_core_for_each_bdev = true;
|
||||||
|
} else if (ch == 'f') {
|
||||||
|
g_continue_on_failure = true;
|
||||||
|
} else {
|
||||||
|
tmp = spdk_strtoll(optarg, 10);
|
||||||
|
if (tmp < 0) {
|
||||||
|
fprintf(stderr, "Parse failed for the option %c.\n", ch);
|
||||||
|
return tmp;
|
||||||
|
} else if (tmp >= INT_MAX) {
|
||||||
|
fprintf(stderr, "Parsed option was too large %c.\n", ch);
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case 'q':
|
||||||
|
g_queue_depth = tmp;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
g_io_size = tmp;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
g_time_in_sec = tmp;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
g_rw_percentage = tmp;
|
||||||
|
g_mix_specified = true;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
g_show_performance_ema_period = tmp;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
g_show_performance_real_time = 1;
|
||||||
|
g_show_performance_period_in_usec = tmp * 1000000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdevperf_usage(void)
|
||||||
|
{
|
||||||
|
printf(" -q <depth> io depth\n");
|
||||||
|
printf(" -o <size> io size in bytes\n");
|
||||||
|
printf(" -w <type> io pattern type, must be one of (read, write, randread, randwrite, rw, randrw, verify, reset, unmap, flush)\n");
|
||||||
|
printf(" -t <time> time in seconds\n");
|
||||||
|
printf(" -M <percent> rwmixread (100 for reads, 0 for writes)\n");
|
||||||
|
printf(" -P <num> number of moving average period\n");
|
||||||
|
printf("\t\t(If set to n, show weighted mean of the previous n IO/s in real time)\n");
|
||||||
|
printf("\t\t(Formula: M = 2 / (n + 1), EMA[i+1] = IO/s * M + (1 - M) * EMA[i])\n");
|
||||||
|
printf("\t\t(only valid with -S)\n");
|
||||||
|
printf(" -S <period> show performance result in real time every <period> seconds\n");
|
||||||
|
printf(" -T <target> target bdev\n");
|
||||||
|
printf(" -f continue processing I/O even after failures\n");
|
||||||
|
printf(" -z start bdevperf, but wait for RPC to start tests\n");
|
||||||
|
printf(" -C enable every core to send I/Os to each bdev\n");
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
verify_test_params(struct spdk_app_opts *opts)
|
verify_test_params(struct spdk_app_opts *opts)
|
||||||
{
|
{
|
||||||
@ -1252,238 +1484,6 @@ verify_test_params(struct spdk_app_opts *opts)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
bdevperf_test(void)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (g_target_count == 0) {
|
|
||||||
fprintf(stderr, "No valid bdevs found.\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bdevperf_construct_targets_tasks();
|
|
||||||
if (rc) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Running I/O for %" PRIu64 " seconds...\n", g_time_in_usec / 1000000);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
/* Start a timer to dump performance numbers */
|
|
||||||
g_shutdown_tsc = spdk_get_ticks();
|
|
||||||
if (g_show_performance_real_time) {
|
|
||||||
g_perf_timer = spdk_poller_register(performance_statistics_thread, NULL,
|
|
||||||
g_show_performance_period_in_usec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate target groups to start all I/O */
|
|
||||||
spdk_for_each_channel(&g_bdevperf, bdevperf_submit_on_group, NULL, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
io_target_group_create(void *io_device, void *ctx_buf)
|
|
||||||
{
|
|
||||||
struct io_target_group *group = ctx_buf;
|
|
||||||
|
|
||||||
TAILQ_INIT(&group->targets);
|
|
||||||
group->lcore = spdk_env_get_current_core();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
io_target_group_destroy(void *io_device, void *ctx_buf)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_bdevperf_init_thread_done(void *ctx)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
g_master_thread = spdk_get_thread();
|
|
||||||
|
|
||||||
if (g_wait_for_tests) {
|
|
||||||
/* Do not perform any tests until RPC is received */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bdevperf_construct_targets();
|
|
||||||
|
|
||||||
rc = bdevperf_test();
|
|
||||||
if (rc) {
|
|
||||||
g_run_rc = rc;
|
|
||||||
bdevperf_test_done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_bdevperf_init_thread(void *ctx)
|
|
||||||
{
|
|
||||||
struct spdk_io_channel *ch;
|
|
||||||
struct io_target_group *group;
|
|
||||||
|
|
||||||
ch = spdk_get_io_channel(&g_bdevperf);
|
|
||||||
group = spdk_io_channel_get_ctx(ch);
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&g_bdevperf.groups, group, link);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bdevperf_run(void *arg1)
|
|
||||||
{
|
|
||||||
spdk_io_device_register(&g_bdevperf, io_target_group_create, io_target_group_destroy,
|
|
||||||
sizeof(struct io_target_group), "bdevperf");
|
|
||||||
|
|
||||||
/* Send a message to each thread and create a target group */
|
|
||||||
spdk_for_each_thread(_bdevperf_init_thread, NULL, _bdevperf_init_thread_done);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bdevperf_stop_io_on_group(struct spdk_io_channel_iter *i)
|
|
||||||
{
|
|
||||||
struct spdk_io_channel *ch;
|
|
||||||
struct io_target_group *group;
|
|
||||||
struct io_target *target;
|
|
||||||
|
|
||||||
ch = spdk_io_channel_iter_get_channel(i);
|
|
||||||
group = spdk_io_channel_get_ctx(ch);
|
|
||||||
|
|
||||||
/* Stop I/O for each block device. */
|
|
||||||
TAILQ_FOREACH(target, &group->targets, link) {
|
|
||||||
end_target(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
spdk_for_each_channel_continue(i, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
spdk_bdevperf_shutdown_cb(void)
|
|
||||||
{
|
|
||||||
g_shutdown = true;
|
|
||||||
|
|
||||||
if (TAILQ_EMPTY(&g_bdevperf.groups)) {
|
|
||||||
spdk_app_stop(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_target_count == 0) {
|
|
||||||
bdevperf_test_done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_shutdown_tsc = spdk_get_ticks() - g_shutdown_tsc;
|
|
||||||
|
|
||||||
/* Send events to stop all I/O on each target group */
|
|
||||||
spdk_for_each_channel(&g_bdevperf, bdevperf_stop_io_on_group, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdevperf_parse_arg(int ch, char *arg)
|
|
||||||
{
|
|
||||||
long long tmp;
|
|
||||||
|
|
||||||
if (ch == 'w') {
|
|
||||||
g_workload_type = optarg;
|
|
||||||
} else if (ch == 'T') {
|
|
||||||
g_target_bdev_name = optarg;
|
|
||||||
} else if (ch == 'z') {
|
|
||||||
g_wait_for_tests = true;
|
|
||||||
} else if (ch == 'C') {
|
|
||||||
g_every_core_for_each_bdev = true;
|
|
||||||
} else if (ch == 'f') {
|
|
||||||
g_continue_on_failure = true;
|
|
||||||
} else {
|
|
||||||
tmp = spdk_strtoll(optarg, 10);
|
|
||||||
if (tmp < 0) {
|
|
||||||
fprintf(stderr, "Parse failed for the option %c.\n", ch);
|
|
||||||
return tmp;
|
|
||||||
} else if (tmp >= INT_MAX) {
|
|
||||||
fprintf(stderr, "Parsed option was too large %c.\n", ch);
|
|
||||||
return -ERANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ch) {
|
|
||||||
case 'q':
|
|
||||||
g_queue_depth = tmp;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
g_io_size = tmp;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
g_time_in_sec = tmp;
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
g_rw_percentage = tmp;
|
|
||||||
g_mix_specified = true;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
g_show_performance_ema_period = tmp;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
g_show_performance_real_time = 1;
|
|
||||||
g_show_performance_period_in_usec = tmp * 1000000;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rpc_perform_tests_cb(void)
|
|
||||||
{
|
|
||||||
struct spdk_json_write_ctx *w;
|
|
||||||
struct spdk_jsonrpc_request *request = g_request;
|
|
||||||
|
|
||||||
g_request = NULL;
|
|
||||||
|
|
||||||
if (g_run_rc == 0) {
|
|
||||||
w = spdk_jsonrpc_begin_result(request);
|
|
||||||
spdk_json_write_uint32(w, g_run_rc);
|
|
||||||
spdk_jsonrpc_end_result(request, w);
|
|
||||||
} else {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
||||||
"bdevperf failed with error %s", spdk_strerror(-g_run_rc));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset g_run_rc to 0 for the next test run. */
|
|
||||||
g_run_rc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rpc_perform_tests(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (params != NULL) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"perform_tests method requires no parameters");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (g_request != NULL) {
|
|
||||||
fprintf(stderr, "Another test is already in progress.\n");
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
||||||
spdk_strerror(-EINPROGRESS));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_request = request;
|
|
||||||
|
|
||||||
bdevperf_construct_targets();
|
|
||||||
|
|
||||||
rc = bdevperf_test();
|
|
||||||
if (rc) {
|
|
||||||
g_run_rc = rc;
|
|
||||||
bdevperf_test_done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SPDK_RPC_REGISTER("perform_tests", rpc_perform_tests, SPDK_RPC_RUNTIME)
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user