From 5e5e906e1c1ea5efa0ef3e7ce1c6221f460dce16 Mon Sep 17 00:00:00 2001 From: Cedric Koch-Hofer <94527853+knard-intel@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:59:09 +0200 Subject: [PATCH] DAOS-10250 control: Get enabled and disabled ranks with dmg pool query (#14436) Allow enabled and disabled ranks option to be used simultaneously (DAOS-10250). Update and add cmocka unit tests of engine management related functions (DAOS-10253). Fix memory leaks of ranks string in function ds_mgmt_drpc_pool_query(). Required-githooks: true Change-Id: I27f5b3acb003faea2d53697e83f0afeb0e284080 Signed-off-by: Cedric Koch-Hofer --- src/common/tests_dmg_helpers.c | 6 +- src/control/cmd/dmg/pool.go | 4 - src/control/cmd/dmg/pool_test.go | 32 ++- src/gurt/misc.c | 101 +++++----- src/gurt/tests/test_gurt.c | 189 +++++++++++++++++- src/include/daos_srv/pool.h | 12 +- src/include/gurt/common.h | 6 +- src/mgmt/srv_drpc.c | 127 ++++++------ src/mgmt/srv_internal.h | 9 +- src/mgmt/srv_pool.c | 30 +-- src/mgmt/tests/mocks.c | 48 +++-- src/mgmt/tests/mocks.h | 16 +- src/mgmt/tests/srv_drpc_tests.c | 24 +-- src/pool/srv_cli.c | 4 +- src/pool/srv_pool.c | 100 +++++++-- .../ftest/control/dmg_pool_query_ranks.py | 44 ++-- 16 files changed, 510 insertions(+), 242 deletions(-) diff --git a/src/common/tests_dmg_helpers.c b/src/common/tests_dmg_helpers.c index 64fa2d3403c..3884c031efc 100644 --- a/src/common/tests_dmg_helpers.c +++ b/src/common/tests_dmg_helpers.c @@ -838,9 +838,9 @@ dmg_pool_extend(const char *dmg_config_file, const uuid_t uuid, rank_list.rl_ranks = ranks; rank_list.rl_nr = rank_nr; - rank_str = d_rank_list_to_str(&rank_list); - if (rank_str == NULL) - D_GOTO(out, rc = -DER_NOMEM); + rc = d_rank_list_to_str(&rank_list, &rank_str); + if (rc != 0) + D_GOTO(out, rc); uuid_unparse_lower(uuid, uuid_str); args = cmd_push_arg(args, &argcount, "%s ", uuid_str); diff --git a/src/control/cmd/dmg/pool.go b/src/control/cmd/dmg/pool.go index 3e519e2bf84..b9047805f62 100644 --- a/src/control/cmd/dmg/pool.go +++ b/src/control/cmd/dmg/pool.go @@ -614,10 +614,6 @@ func (cmd *PoolQueryCmd) Execute(args []string) error { if cmd.HealthOnly { req.QueryMask = daos.HealthOnlyPoolQueryMask } - // TODO (DAOS-10250) The two options should not be incompatible (i.e. engine limitation) - if cmd.ShowEnabledRanks && cmd.ShowDisabledRanks { - return errIncompatFlags("show-enabled-ranks", "show-disabled-ranks") - } if cmd.ShowEnabledRanks { req.QueryMask.SetOptions(daos.PoolQueryOptionEnabledEngines) } diff --git a/src/control/cmd/dmg/pool_test.go b/src/control/cmd/dmg/pool_test.go index a632affff15..777a82effea 100644 --- a/src/control/cmd/dmg/pool_test.go +++ b/src/control/cmd/dmg/pool_test.go @@ -974,6 +974,32 @@ func TestPoolCommands(t *testing.T) { }, " "), nil, }, + { + "Query pool with UUID, enabled ranks and disabled ranks", + "pool query --show-disabled --show-enabled 12345678-1234-1234-1234-1234567890ab", + strings.Join([]string{ + printRequest(t, &control.PoolQueryReq{ + ID: "12345678-1234-1234-1234-1234567890ab", + QueryMask: setQueryMask(func(qm *daos.PoolQueryMask) { + qm.SetOptions(daos.PoolQueryOptionEnabledEngines, daos.PoolQueryOptionDisabledEngines) + }), + }), + }, " "), + nil, + }, + { + "Query pool with UUID, enabled ranks and disabled ranks", + "pool query -b -e 12345678-1234-1234-1234-1234567890ab", + strings.Join([]string{ + printRequest(t, &control.PoolQueryReq{ + ID: "12345678-1234-1234-1234-1234567890ab", + QueryMask: setQueryMask(func(qm *daos.PoolQueryMask) { + qm.SetOptions(daos.PoolQueryOptionEnabledEngines, daos.PoolQueryOptionDisabledEngines) + }), + }), + }, " "), + nil, + }, { "Query pool for health only", "pool query --health-only 12345678-1234-1234-1234-1234567890ab", @@ -1018,12 +1044,6 @@ func TestPoolCommands(t *testing.T) { "", fmt.Errorf("Unknown command"), }, - { - "Query pool with incompatible arguments", - "pool query --show-disabled --show-enabled 12345678-1234-1234-1234-1234567890ab", - "", - errors.New("may not be mixed"), - }, }) } diff --git a/src/gurt/misc.c b/src/gurt/misc.c index f09f059cc55..9c196436ff3 100644 --- a/src/gurt/misc.c +++ b/src/gurt/misc.c @@ -695,24 +695,39 @@ d_rank_list_dump(d_rank_list_t *rank_list, d_string_t name, int name_len) * Create a ranged string representation of a rank list. * * \param[in] rank_list the rank list to represent + * \param[out] ranks_str Returned ranged string (caller must free) * - * \return a ranged string (caller must free) + * \return 0 on success, a negative value on error */ -char * -d_rank_list_to_str(d_rank_list_t *rank_list) +int +d_rank_list_to_str(d_rank_list_t *ranks, char **ranks_str) { - char *str; - bool truncated = false; - d_rank_range_list_t *range_list; + d_rank_range_list_t *range_list = NULL; + char *range_list_str; + int rc; + + D_ASSERT(ranks_str != NULL); - range_list = d_rank_range_list_create_from_ranks(rank_list); + if (ranks == NULL) { + range_list_str = NULL; + D_GOTO(out, rc = -DER_SUCCESS); + } + + range_list = d_rank_range_list_create_from_ranks(ranks); if (range_list == NULL) - return NULL; - str = d_rank_range_list_str(range_list, &truncated); + D_GOTO(error, rc = -DER_NOMEM); + rc = d_rank_range_list_str(range_list, &range_list_str); + if (rc != 0) + D_GOTO(error, rc); + +out: + *ranks_str = range_list_str; + +error: d_rank_range_list_free(range_list); - return str; + return rc; } d_rank_list_t * @@ -795,7 +810,6 @@ d_rank_range_list_realloc(d_rank_range_list_t *range_list, uint32_t size) return range_list; } -/* TODO (DAOS-10253) Add unit tests for this function */ d_rank_range_list_t * d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list) { @@ -841,56 +855,51 @@ d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list) return range_list; } -/* TODO (DAOS-10253) Add unit tests for this function */ -char * -d_rank_range_list_str(d_rank_range_list_t *list, bool *truncated) +int +d_rank_range_list_str(d_rank_range_list_t *list, char **ranks_str) { - const size_t MAXBYTES = 512; - char *line; - char *linepos; - int ret = 0; - size_t remaining = MAXBYTES - 2u; - int i; - int err = 0; + const size_t MAXBYTES = 512u; + size_t remaining = MAXBYTES - 2u; + char *line; + char *linepos; + int i; + int len; + int rc; + + D_ASSERT(list != NULL); - *truncated = false; D_ALLOC(line, MAXBYTES); if (line == NULL) - return NULL; + D_GOTO(error, rc = -DER_NOMEM); *line = '['; linepos = line + 1; for (i = 0; i < list->rrl_nr; i++) { - uint32_t lo = list->rrl_ranges[i].lo; - uint32_t hi = list->rrl_ranges[i].hi; - bool lastrange = (i == (list->rrl_nr - 1)); + uint32_t lo = list->rrl_ranges[i].lo; + uint32_t hi = list->rrl_ranges[i].hi; + bool lastrange = (i == (list->rrl_nr - 1)); if (lo == hi) - ret = snprintf(linepos, remaining, "%u%s", lo, lastrange ? "" : ","); + len = snprintf(linepos, remaining, "%u%s", lo, lastrange ? "" : ","); else - ret = snprintf(linepos, remaining, "%u-%u%s", lo, hi, lastrange ? "" : ","); - - if (ret < 0) { - err = errno; - D_ERROR("rank set could not be serialized: %s (%d)\n", strerror(err), err); - break; - } - - if (ret >= remaining) { - err = EOVERFLOW; - D_WARN("rank set has been partially serialized\n"); - break; - } - - remaining -= ret; - linepos += ret; + len = snprintf(linepos, remaining, "%u-%u%s", lo, hi, lastrange ? "" : ","); + if (len < 0) + D_GOTO(error, rc = -DER_INVAL); + if (len >= remaining) + D_GOTO(error, rc = -DER_TRUNC); + + remaining -= len; + linepos += len; } memcpy(linepos, "]", 2u); - if (err != 0) - *truncated = true; + *ranks_str = line; + D_GOTO(out, rc = -DER_SUCCESS); - return line; +error: + D_FREE(line); +out: + return rc; } void diff --git a/src/gurt/tests/test_gurt.c b/src/gurt/tests/test_gurt.c index ebdad7f8ea2..adc8a38a8c3 100644 --- a/src/gurt/tests/test_gurt.c +++ b/src/gurt/tests/test_gurt.c @@ -2582,6 +2582,190 @@ test_d_setenv(void **state) assert_false(d_isenv_def("foo")); } +static void +test_d_rank_list_to_str(void **state) +{ + d_rank_list_t *ranks; + char *ranks_str = NULL; + int i; + int rc; + + // Test with null list + rc = d_rank_list_to_str(NULL, &ranks_str); + assert_int_equal(rc, -DER_SUCCESS); + assert_null(ranks_str); + + // Test with empty list + ranks = d_rank_list_alloc(0); + assert_non_null(ranks); + + rc = d_rank_list_to_str(ranks, &ranks_str); + assert_int_equal(rc, -DER_SUCCESS); + assert_string_equal(ranks_str, "[]"); + + D_FREE(ranks_str); + d_rank_list_free(ranks); + + // Test with one rank + ranks = d_rank_list_alloc(1); + assert_non_null(ranks); + ranks->rl_ranks[0] = 2; + + rc = d_rank_list_to_str(ranks, &ranks_str); + assert_int_equal(rc, -DER_SUCCESS); + assert_string_equal(ranks_str, "[2]"); + + D_FREE(ranks_str); + d_rank_list_free(ranks); + + // Test with 4 ranks and two ranges + ranks = d_rank_list_alloc(4); + assert_non_null(ranks); + ranks->rl_ranks[0] = 2; + ranks->rl_ranks[1] = 1; + ranks->rl_ranks[2] = 5; + ranks->rl_ranks[3] = 3; + + rc = d_rank_list_to_str(ranks, &ranks_str); + assert_int_equal(rc, -DER_SUCCESS); + assert_string_equal(ranks_str, "[1-3,5]"); + + D_FREE(ranks_str); + d_rank_list_free(ranks); + + // Test truncate error + ranks = d_rank_list_alloc(1024); + assert_non_null(ranks); + for (i = 0; i < 1024; ++i) + ranks->rl_ranks[i] = 2 * i + 1; + + rc = d_rank_list_to_str(ranks, &ranks_str); + assert_int_equal(rc, -DER_TRUNC); + assert_null(ranks_str); + + d_rank_list_free(ranks); +} + +static void +test_d_rank_range_list_create_from_ranks(void **state) +{ + d_rank_list_t *ranks; + d_rank_range_list_t *range_list; + + // Test with null list + range_list = d_rank_range_list_create_from_ranks(NULL); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 0); + + d_rank_range_list_free(range_list); + + // Test with empty list + ranks = d_rank_list_alloc(0); + assert_non_null(ranks); + + range_list = d_rank_range_list_create_from_ranks(ranks); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 0); + + d_rank_range_list_free(range_list); + d_rank_list_free(ranks); + + // Test with one rank + ranks = d_rank_list_alloc(1); + assert_non_null(ranks); + ranks->rl_ranks[0] = 2; + + range_list = d_rank_range_list_create_from_ranks(ranks); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 1); + assert_int_equal(range_list->rrl_ranges[0].lo, 2); + assert_int_equal(range_list->rrl_ranges[0].hi, 2); + + d_rank_range_list_free(range_list); + d_rank_list_free(ranks); + + // Test with 4 ranks and two ranges + ranks = d_rank_list_alloc(4); + assert_non_null(ranks); + ranks->rl_ranks[0] = 2; + ranks->rl_ranks[1] = 1; + ranks->rl_ranks[2] = 5; + ranks->rl_ranks[3] = 3; + + range_list = d_rank_range_list_create_from_ranks(ranks); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 2); + assert_int_equal(range_list->rrl_ranges[0].lo, 1); + assert_int_equal(range_list->rrl_ranges[0].hi, 3); + assert_int_equal(range_list->rrl_ranges[1].lo, 5); + assert_int_equal(range_list->rrl_ranges[1].hi, 5); + + d_rank_range_list_free(range_list); + d_rank_list_free(ranks); +} + +static void +test_d_rank_range_list_str(void **state) +{ + d_rank_range_list_t *range_list; + char *ranks_str = NULL; + int i; + int rc; + + // Test with empty list + range_list = d_rank_range_list_alloc(0); + assert_non_null(range_list); + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, 0); + assert_string_equal(ranks_str, "[]"); + + D_FREE(ranks_str); + d_rank_range_list_free(range_list); + + // Test with one rank + range_list = d_rank_range_list_alloc(1); + assert_non_null(range_list); + range_list->rrl_ranges[0].lo = 2; + range_list->rrl_ranges[0].hi = 2; + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, 0); + assert_string_equal(ranks_str, "[2]"); + + D_FREE(ranks_str); + d_rank_range_list_free(range_list); + + // Test with 4 ranks and two ranges + range_list = d_rank_range_list_alloc(2); + assert_non_null(range_list); + range_list->rrl_ranges[0].lo = 1; + range_list->rrl_ranges[0].hi = 3; + range_list->rrl_ranges[1].lo = 5; + range_list->rrl_ranges[1].hi = 5; + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, 0); + assert_string_equal(ranks_str, "[1-3,5]"); + + D_FREE(ranks_str); + d_rank_range_list_free(range_list); + + // Test truncate error + range_list = d_rank_range_list_alloc(1024); + assert_non_null(range_list); + for (i = 0; i < 1024; ++i) { + range_list->rrl_ranges[i].lo = i; + range_list->rrl_ranges[i].hi = i; + } + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, -DER_TRUNC); + assert_null(ranks_str); + + d_rank_range_list_free(range_list); +} + int main(int argc, char **argv) { @@ -2618,7 +2802,10 @@ main(int argc, char **argv) teardown_getenv_mocks), cmocka_unit_test_setup_teardown(test_d_getenv_uint64_t, setup_getenv_mocks, teardown_getenv_mocks), - cmocka_unit_test(test_d_setenv)}; + cmocka_unit_test(test_d_setenv), + cmocka_unit_test(test_d_rank_list_to_str), + cmocka_unit_test(test_d_rank_range_list_create_from_ranks), + cmocka_unit_test(test_d_rank_range_list_str)}; d_register_alt_assert(mock_assert); diff --git a/src/include/daos_srv/pool.h b/src/include/daos_srv/pool.h index 576e547ef10..ef7862cc2cf 100644 --- a/src/include/daos_srv/pool.h +++ b/src/include/daos_srv/pool.h @@ -231,11 +231,13 @@ int ds_pool_svc_delete_acl(uuid_t pool_uuid, d_rank_list_t *ranks, enum daos_acl_principal_type principal_type, const char *principal_name); -int ds_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver); -int ds_pool_svc_query_target(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_t rank, - uint32_t tgt_idx, daos_target_info_t *ti); +int +ds_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver); +int +ds_pool_svc_query_target(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_t rank, uint32_t tgt_idx, + daos_target_info_t *ti); int ds_pool_prop_fetch(struct ds_pool *pool, unsigned int bit, daos_prop_t **prop_out); diff --git a/src/include/gurt/common.h b/src/include/gurt/common.h index 783c2790f59..2374b0c8c29 100644 --- a/src/include/gurt/common.h +++ b/src/include/gurt/common.h @@ -421,12 +421,14 @@ int d_rank_list_append(d_rank_list_t *rank_list, d_rank_t rank); int d_rank_list_dump(d_rank_list_t *rank_list, d_string_t name, int name_len); d_rank_list_t *uint32_array_to_rank_list(uint32_t *ints, size_t len); int rank_list_to_uint32_array(d_rank_list_t *rl, uint32_t **ints, size_t *len); -char *d_rank_list_to_str(d_rank_list_t *rank_list); +int + d_rank_list_to_str(d_rank_list_t *rank_list, char **rank_str); d_rank_range_list_t *d_rank_range_list_alloc(uint32_t size); d_rank_range_list_t *d_rank_range_list_realloc(d_rank_range_list_t *range_list, uint32_t size); d_rank_range_list_t *d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list); -char *d_rank_range_list_str(d_rank_range_list_t *list, bool *truncated); +int + d_rank_range_list_str(d_rank_range_list_t *list, char **ranks_str); void d_rank_range_list_free(d_rank_range_list_t *range_list); static inline int diff --git a/src/mgmt/srv_drpc.c b/src/mgmt/srv_drpc.c index cadc1c0aef6..a53ee60d9b8 100644 --- a/src/mgmt/srv_drpc.c +++ b/src/mgmt/srv_drpc.c @@ -393,7 +393,7 @@ static int pool_create_fill_resp(Mgmt__PoolCreateResp *resp, uuid_t uuid, d_rank D_DEBUG(DB_MGMT, "%d service replicas\n", svc_ranks->rl_nr); - rc = ds_mgmt_pool_query(uuid, svc_ranks, &enabled_ranks, &pool_info, NULL, NULL); + rc = ds_mgmt_pool_query(uuid, svc_ranks, &enabled_ranks, NULL, &pool_info, NULL, NULL); if (rc != 0) { D_ERROR("Failed to query created pool: rc=%d\n", rc); D_GOTO(out, rc); @@ -1173,10 +1173,10 @@ add_props_to_resp(daos_prop_t *prop, Mgmt__PoolGetPropResp *resp) D_ERROR("svc rank list unset\n"); D_GOTO(out, rc = -DER_INVAL); } - resp_props[j]->strval = d_rank_list_to_str( - (d_rank_list_t *)entry->dpe_val_ptr); - if (resp_props[j]->strval == NULL) - D_GOTO(out, rc = -DER_NOMEM); + rc = d_rank_list_to_str((d_rank_list_t *)entry->dpe_val_ptr, + &resp_props[j]->strval); + if (rc != 0) + D_GOTO(out, rc); resp_props[j]->value_case = MGMT__POOL_PROPERTY__VALUE_STRVAL; break; @@ -1740,22 +1740,22 @@ pool_query_free_tier_stats(Mgmt__PoolQueryResp *resp) void ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) { - struct drpc_alloc alloc = PROTO_ALLOCATOR_INIT(alloc); - int rc = 0; - Mgmt__PoolQueryReq *req; - Mgmt__PoolQueryResp resp = MGMT__POOL_QUERY_RESP__INIT; - Mgmt__StorageUsageStats scm = MGMT__STORAGE_USAGE_STATS__INIT; - Mgmt__StorageUsageStats nvme = MGMT__STORAGE_USAGE_STATS__INIT; - Mgmt__PoolRebuildStatus rebuild = MGMT__POOL_REBUILD_STATUS__INIT; - uuid_t uuid; - daos_pool_info_t pool_info = {0}; - d_rank_list_t *svc_ranks; - d_rank_list_t *ranks; - d_rank_range_list_t *range_list; - char *range_list_str = NULL; - bool truncated; - size_t len; - uint8_t *body; + struct drpc_alloc alloc = PROTO_ALLOCATOR_INIT(alloc); + int rc = 0; + Mgmt__PoolQueryReq *req; + Mgmt__PoolQueryResp resp = MGMT__POOL_QUERY_RESP__INIT; + Mgmt__StorageUsageStats scm = MGMT__STORAGE_USAGE_STATS__INIT; + Mgmt__StorageUsageStats nvme = MGMT__STORAGE_USAGE_STATS__INIT; + Mgmt__PoolRebuildStatus rebuild = MGMT__POOL_REBUILD_STATUS__INIT; + uuid_t uuid; + daos_pool_info_t pool_info = {0}; + d_rank_list_t *svc_ranks = NULL; + d_rank_list_t *enabled_ranks = NULL; + d_rank_list_t *disabled_ranks = NULL; + char *enabled_ranks_str = NULL; + char *disabled_ranks_str = NULL; + size_t len; + uint8_t *body; req = mgmt__pool_query_req__unpack(&alloc.alloc, drpc_req->body.len, drpc_req->body.data); @@ -1768,57 +1768,61 @@ ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) D_INFO("Received request to query DAOS pool %s\n", req->id); if (uuid_parse(req->id, uuid) != 0) { - D_ERROR("Failed to parse pool uuid %s\n", req->id); - D_GOTO(out, rc = -DER_INVAL); - } - - /* TODO (DAOS-10250) Enabled and disabled engines should be retrieve both if needed */ - if (req->query_mask & DPI_ENGINES_ENABLED && req->query_mask & DPI_ENGINES_DISABLED) { - D_ERROR("cannot query enabled and disabled engines in the same request\n"); - D_GOTO(out, rc = -DER_NOTSUPPORTED); + DL_ERROR(-DER_INVAL, "Pool UUID is invalid"); + D_GOTO(error, rc = -DER_INVAL); } svc_ranks = uint32_array_to_rank_list(req->svc_ranks, req->n_svc_ranks); if (svc_ranks == NULL) - D_GOTO(out, rc = -DER_NOMEM); + D_GOTO(error, rc = -DER_NOMEM); pool_info.pi_bits = req->query_mask; - rc = ds_mgmt_pool_query(uuid, svc_ranks, &ranks, &pool_info, &resp.pool_layout_ver, - &resp.upgrade_layout_ver); + rc = ds_mgmt_pool_query(uuid, svc_ranks, &enabled_ranks, &disabled_ranks, &pool_info, + &resp.pool_layout_ver, &resp.upgrade_layout_ver); if (rc != 0) { - D_ERROR("Failed to query the pool, rc=%d\n", rc); - goto out_svc_ranks; + DL_ERROR(rc, DF_UUID ": Failed to query the pool", DP_UUID(uuid)); + D_GOTO(error, rc); } - /* Calculate and stringify rank ranges to return to control plane for display */ - range_list = d_rank_range_list_create_from_ranks(ranks); - if (range_list == NULL) - D_GOTO(out_ranks, rc = -DER_NOMEM); - range_list_str = d_rank_range_list_str(range_list, &truncated); - if (range_list_str == NULL) - D_GOTO(out_ranges, rc = -DER_NOMEM); - D_DEBUG(DB_MGMT, DF_UUID": %s ranks: %s%s\n", DP_UUID(uuid), - pool_info.pi_bits & DPI_ENGINES_ENABLED ? "ENABLED" : "DISABLED", range_list_str, - truncated ? " ...(TRUNCATED)" : ""); + rc = d_rank_list_to_str(enabled_ranks, &enabled_ranks_str); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": Failed to serialize the list of enabled ranks", + DP_UUID(uuid)); + D_GOTO(error, rc); + } + if (enabled_ranks_str != NULL) + D_DEBUG(DB_MGMT, DF_UUID ": list of enabled ranks: %s\n", DP_UUID(uuid), + enabled_ranks_str); + + rc = d_rank_list_to_str(disabled_ranks, &disabled_ranks_str); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": Failed to serialize the list of disabled ranks", + DP_UUID(uuid)); + D_GOTO(error, rc); + } + if (disabled_ranks_str != NULL) + D_DEBUG(DB_MGMT, DF_UUID ": list of disabled ranks: %s\n", DP_UUID(uuid), + disabled_ranks_str); /* Populate the response */ resp.query_mask = pool_info.pi_bits; - resp.uuid = req->id; - resp.total_targets = pool_info.pi_ntargets; + resp.uuid = req->id; + resp.total_targets = pool_info.pi_ntargets; resp.disabled_targets = pool_info.pi_ndisabled; - resp.active_targets = pool_info.pi_space.ps_ntargets; - resp.total_engines = pool_info.pi_nnodes; + resp.active_targets = pool_info.pi_space.ps_ntargets; + resp.total_engines = pool_info.pi_nnodes; resp.svc_ldr = pool_info.pi_leader; resp.svc_reps = req->svc_ranks; resp.n_svc_reps = req->n_svc_ranks; - resp.version = pool_info.pi_map_ver; - resp.enabled_ranks = (req->query_mask & DPI_ENGINES_ENABLED) ? range_list_str : ""; - resp.disabled_ranks = (req->query_mask & DPI_ENGINES_DISABLED) ? range_list_str : ""; + resp.version = pool_info.pi_map_ver; + if (enabled_ranks_str != NULL) + resp.enabled_ranks = enabled_ranks_str; + if (disabled_ranks_str != NULL) + resp.disabled_ranks = disabled_ranks_str; D_ALLOC_ARRAY(resp.tier_stats, DAOS_MEDIA_MAX); - if (resp.tier_stats == NULL) { - D_GOTO(out_ranges, rc = -DER_NOMEM); - } + if (resp.tier_stats == NULL) + D_GOTO(error, rc = -DER_NOMEM); storage_usage_stats_from_pool_space(&scm, &pool_info.pi_space, DAOS_MEDIA_SCM); @@ -1833,13 +1837,7 @@ ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) pool_rebuild_status_from_info(&rebuild, &pool_info.pi_rebuild_st); resp.rebuild = &rebuild; -out_ranges: - d_rank_range_list_free(range_list); -out_ranks: - d_rank_list_free(ranks); -out_svc_ranks: - d_rank_list_free(svc_ranks); -out: +error: resp.status = rc; len = mgmt__pool_query_resp__get_packed_size(&resp); @@ -1852,10 +1850,13 @@ ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) drpc_resp->body.data = body; } - D_FREE(range_list_str); - mgmt__pool_query_req__free_unpacked(req, &alloc.alloc); + d_rank_list_free(enabled_ranks); + D_FREE(enabled_ranks_str); + d_rank_list_free(disabled_ranks); + D_FREE(disabled_ranks_str); + d_rank_list_free(svc_ranks); pool_query_free_tier_stats(&resp); } diff --git a/src/mgmt/srv_internal.h b/src/mgmt/srv_internal.h index b22341fb35b..254bb6d90bb 100644 --- a/src/mgmt/srv_internal.h +++ b/src/mgmt/srv_internal.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2016-2022 Intel Corporation. + * (C) Copyright 2016-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -97,9 +97,10 @@ int ds_mgmt_pool_delete_acl(uuid_t pool_uuid, d_rank_list_t *svc_ranks, int ds_mgmt_pool_list_cont(uuid_t uuid, d_rank_list_t *svc_ranks, struct daos_pool_cont_info **containers, uint64_t *ncontainers); -int ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver); +int + ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver); int ds_mgmt_pool_query_targets(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_t rank, d_rank_list_t *tgts, daos_target_info_t **infos); diff --git a/src/mgmt/srv_pool.c b/src/mgmt/srv_pool.c index 851cedfcfad..db771a1d09f 100644 --- a/src/mgmt/srv_pool.c +++ b/src/mgmt/srv_pool.c @@ -195,18 +195,13 @@ ds_mgmt_create_pool(uuid_t pool_uuid, const char *group, char *tgt_dev, if (!d_rank_list_identical(pg_targets, targets)) { char *pg_str, *tgt_str; - pg_str = d_rank_list_to_str(pg_ranks); - if (pg_str == NULL) { - rc = -DER_NOMEM; + rc = d_rank_list_to_str(pg_ranks, &pg_str); + if (rc != 0) D_GOTO(out, rc); - } - tgt_str = d_rank_list_to_str(targets); - if (tgt_str == NULL) { - D_FREE(pg_str); - rc = -DER_NOMEM; + rc = d_rank_list_to_str(targets, &tgt_str); + if (rc != 0) D_GOTO(out, rc); - } D_ERROR(DF_UUID": targets (%s) contains ranks not in pg (%s)\n", DP_UUID(pool_uuid), tgt_str, pg_str); @@ -386,13 +381,8 @@ ds_mgmt_pool_list_cont(uuid_t uuid, d_rank_list_t *svc_ranks, * * \param[in] pool_uuid UUID of the pool. * \param[in] svc_ranks Ranks of pool svc replicas. - * \param[out] ranks Optional, returned storage ranks in this pool. - * If #pool_info is NULL, engines with disabled targets. - * If #pool_info is passed, engines with enabled or - * disabled targets according to - * #pi_bits (DPI_ENGINES_ENABLED bit). - * Note: ranks may be empty (i.e., *ranks->rl_nr may be 0). - * The caller must free the list with d_rank_list_free(). + * \param[out] enabled_ranks Optional, returned storage ranks with enabled targets. + * \param[out] disabled_ranks Optional, returned storage ranks with disabled targets. * \param[in][out] pool_info Query results * \param[in][out] pool_layout_ver Pool global version * \param[in][out] upgrade_layout_ver Latest pool global version this pool might be upgraded @@ -402,9 +392,9 @@ ds_mgmt_pool_list_cont(uuid_t uuid, d_rank_list_t *svc_ranks, * Negative value Other error */ int -ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver) +ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver) { if (pool_info == NULL) { D_ERROR("pool_info was NULL\n"); @@ -413,7 +403,7 @@ ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **r D_DEBUG(DB_MGMT, "Querying pool "DF_UUID"\n", DP_UUID(pool_uuid)); - return ds_pool_svc_query(pool_uuid, svc_ranks, ranks, pool_info, + return ds_pool_svc_query(pool_uuid, svc_ranks, enabled_ranks, disabled_ranks, pool_info, pool_layout_ver, upgrade_layout_ver); } diff --git a/src/mgmt/tests/mocks.c b/src/mgmt/tests/mocks.c index 3d4124dfd7a..adcb3dfa7de 100644 --- a/src/mgmt/tests/mocks.c +++ b/src/mgmt/tests/mocks.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2019-2022 Intel Corporation. + * (C) Copyright 2019-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -274,17 +274,18 @@ void mock_ds_mgmt_pool_list_cont_teardown(void) } } -int ds_mgmt_pool_query_return; -uuid_t ds_mgmt_pool_query_uuid; -daos_pool_info_t ds_mgmt_pool_query_info_out; -daos_pool_info_t ds_mgmt_pool_query_info_in; -void *ds_mgmt_pool_query_info_ptr; -d_rank_list_t *ds_mgmt_pool_query_ranks_out; +int ds_mgmt_pool_query_return; +uuid_t ds_mgmt_pool_query_uuid; +daos_pool_info_t ds_mgmt_pool_query_info_out; +daos_pool_info_t ds_mgmt_pool_query_info_in; +void *ds_mgmt_pool_query_info_ptr; +d_rank_list_t *ds_mgmt_pool_query_enabled_ranks_out; +d_rank_list_t *ds_mgmt_pool_query_disabled_ranks_out; int -ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver) +ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver) { /* If function is to return with an error, pool_info and ranks will not be filled. */ if (ds_mgmt_pool_query_return != 0) @@ -292,14 +293,26 @@ ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **r uuid_copy(ds_mgmt_pool_query_uuid, pool_uuid); ds_mgmt_pool_query_info_ptr = (void *)pool_info; - if (pool_info != NULL) { - ds_mgmt_pool_query_info_in = *pool_info; - *pool_info = ds_mgmt_pool_query_info_out; + + if (pool_info == NULL) + return ds_mgmt_pool_query_return; + + if ((pool_info->pi_bits & DPI_ENGINES_ENABLED) != 0) { + D_ASSERT(enabled_ranks != NULL); + + *enabled_ranks = d_rank_list_alloc(8); /* 0-7 ; caller must free this */ + ds_mgmt_pool_query_enabled_ranks_out = *enabled_ranks; } - if (ranks != NULL) { - *ranks = d_rank_list_alloc(8); /* 0-7 ; caller must free this */ - ds_mgmt_pool_query_ranks_out = *ranks; + if ((pool_info->pi_bits & DPI_ENGINES_DISABLED) != 0) { + D_ASSERT(disabled_ranks != NULL); + + *disabled_ranks = d_rank_list_alloc(4); /* 0-3 ; caller must free this */ + ds_mgmt_pool_query_disabled_ranks_out = *disabled_ranks; } + + ds_mgmt_pool_query_info_in = *pool_info; + *pool_info = ds_mgmt_pool_query_info_out; + return ds_mgmt_pool_query_return; /* 0 */ } @@ -310,7 +323,8 @@ mock_ds_mgmt_pool_query_setup(void) uuid_clear(ds_mgmt_pool_query_uuid); ds_mgmt_pool_query_info_ptr = NULL; memset(&ds_mgmt_pool_query_info_out, 0, sizeof(daos_pool_info_t)); - ds_mgmt_pool_query_ranks_out = NULL; + ds_mgmt_pool_query_enabled_ranks_out = NULL; + ds_mgmt_pool_query_disabled_ranks_out = NULL; } int ds_mgmt_pool_query_targets_return; diff --git a/src/mgmt/tests/mocks.h b/src/mgmt/tests/mocks.h index 385986f6dda..f8d83b4b680 100644 --- a/src/mgmt/tests/mocks.h +++ b/src/mgmt/tests/mocks.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2019-2022 Intel Corporation. + * (C) Copyright 2019-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -103,12 +103,14 @@ void mock_ds_mgmt_pool_extend_setup(void); /* * Mock ds_mgmt_pool_query */ -extern int ds_mgmt_pool_query_return; -extern uuid_t ds_mgmt_pool_query_uuid; -extern daos_pool_info_t ds_mgmt_pool_query_info_in; -extern daos_pool_info_t ds_mgmt_pool_query_info_out; -extern void *ds_mgmt_pool_query_info_ptr; -extern d_rank_list_t *ds_mgmt_pool_query_ranks_out; +extern int ds_mgmt_pool_query_return; +extern uuid_t ds_mgmt_pool_query_uuid; +extern daos_pool_info_t ds_mgmt_pool_query_info_in; +extern daos_pool_info_t ds_mgmt_pool_query_info_out; +extern void *ds_mgmt_pool_query_info_ptr; +extern d_rank_list_t *ds_mgmt_pool_query_enabled_ranks_out; +extern d_rank_list_t *ds_mgmt_pool_query_disabled_ranks_out; + void mock_ds_mgmt_pool_query_setup(void); /* diff --git a/src/mgmt/tests/srv_drpc_tests.c b/src/mgmt/tests/srv_drpc_tests.c index 9738b1ac5b1..181b701a918 100644 --- a/src/mgmt/tests/srv_drpc_tests.c +++ b/src/mgmt/tests/srv_drpc_tests.c @@ -1262,22 +1262,6 @@ expect_drpc_pool_query_resp_with_error(Drpc__Response *resp, int expected_err) mgmt__pool_query_resp__free_unpacked(pq_resp, NULL); } -static void -test_drpc_pool_query_incompat_ranks_flags(void **state) -{ - Drpc__Call call = DRPC__CALL__INIT; - Drpc__Response resp = DRPC__RESPONSE__INIT; - - setup_pool_query_drpc_call(&call, TEST_UUID, DPI_ENGINES_DISABLED | DPI_ENGINES_ENABLED); - - ds_mgmt_drpc_pool_query(&call, &resp); - - expect_drpc_pool_query_resp_with_error(&resp, -DER_NOTSUPPORTED); - - D_FREE(call.body.data); - D_FREE(resp.body.data); -} - static void test_drpc_pool_query_bad_uuid(void **state) { @@ -1422,7 +1406,7 @@ test_drpc_pool_query_success(void **state) init_test_rebuild_status(&exp_info.pi_rebuild_st); ds_mgmt_pool_query_info_out = exp_info; - setup_pool_query_drpc_call(&call, TEST_UUID, DPI_ENGINES_ENABLED); + setup_pool_query_drpc_call(&call, TEST_UUID, DPI_ENGINES_ENABLED | DPI_ENGINES_DISABLED); ds_mgmt_drpc_pool_query(&call, &resp); @@ -1431,9 +1415,10 @@ test_drpc_pool_query_success(void **state) return; assert_int_equal(uuid_compare(exp_uuid, ds_mgmt_pool_query_uuid), 0); assert_non_null(ds_mgmt_pool_query_info_ptr); - assert_non_null(ds_mgmt_pool_query_ranks_out); + assert_non_null(ds_mgmt_pool_query_enabled_ranks_out); + assert_non_null(ds_mgmt_pool_query_disabled_ranks_out); assert_int_equal(ds_mgmt_pool_query_info_in.pi_bits, - DEFAULT_QUERY_BITS | DPI_ENGINES_ENABLED); + DEFAULT_QUERY_BITS | DPI_ENGINES_ENABLED | DPI_ENGINES_DISABLED); expect_query_resp_with_info(&exp_info, MGMT__POOL_REBUILD_STATUS__STATE__IDLE, @@ -3049,7 +3034,6 @@ main(void) POOL_EXTEND_TEST(test_drpc_extend_mgmt_svc_fails), POOL_EXTEND_TEST(test_drpc_extend_success), REINTEGRATE_TEST(test_drpc_reintegrate_bad_uuid), - QUERY_TEST(test_drpc_pool_query_incompat_ranks_flags), QUERY_TEST(test_drpc_pool_query_bad_uuid), QUERY_TEST(test_drpc_pool_query_mgmt_svc_fails), QUERY_TEST(test_drpc_pool_query_success), diff --git a/src/pool/srv_cli.c b/src/pool/srv_cli.c index 995e16728b0..0c66cf3e4ae 100644 --- a/src/pool/srv_cli.c +++ b/src/pool/srv_cli.c @@ -1,5 +1,5 @@ -/** - * (C) Copyright 2017-2022 Intel Corporation. +/* + * (C) Copyright 2017-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ diff --git a/src/pool/srv_pool.c b/src/pool/srv_pool.c index 20aca49f867..a8157dfbd3b 100644 --- a/src/pool/srv_pool.c +++ b/src/pool/srv_pool.c @@ -4223,6 +4223,82 @@ ds_pool_query_info_handler(crt_rpc_t *rpc) crt_reply_send(rpc); } +static int +process_query_result(d_rank_list_t **enabled_ranks, d_rank_list_t **disabled_ranks, + daos_pool_info_t *info, uuid_t pool_uuid, uint32_t map_version, + uint32_t leader_rank, struct daos_pool_space *ps, + struct daos_rebuild_status *rs, struct pool_buf *map_buf, uint64_t pi_bits) +{ + struct pool_map *map = NULL; + unsigned int num_disabled = 0; + d_rank_list_t *enabled_rank_list = NULL; + d_rank_list_t *disabled_rank_list = NULL; + int rc; + + rc = pool_map_create(map_buf, map_version, &map); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": failed to create local pool map", DP_UUID(pool_uuid)); + D_GOTO(error, rc); + } + + rc = pool_map_find_failed_tgts(map, NULL, &num_disabled); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": failed to get num disabled tgts", DP_UUID(pool_uuid)); + D_GOTO(error, rc); + } + + if ((pi_bits & DPI_ENGINES_ENABLED) != 0) { + if (enabled_ranks == NULL) { + DL_ERROR(-DER_INVAL, + DF_UUID ": query pool requested enabled ranks, but ptr is NULL", + DP_UUID(pool_uuid)); + D_GOTO(error, rc = -DER_INVAL); + } + + rc = pool_map_get_ranks(pool_uuid, map, true, &enabled_rank_list); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": pool_map_get_ranks() failed", DP_UUID(pool_uuid)); + D_GOTO(error, rc); + } + D_DEBUG(DB_MD, DF_UUID ": found %" PRIu32 " enabled ranks in pool map\n", + DP_UUID(pool_uuid), enabled_rank_list->rl_nr); + } + + if ((pi_bits & DPI_ENGINES_DISABLED) != 0) { + if (disabled_ranks == NULL) { + DL_ERROR(-DER_INVAL, + DF_UUID ": query pool requested disabled ranks, but ptr is NULL", + DP_UUID(pool_uuid)); + D_GOTO(error, rc = -DER_INVAL); + } + + rc = pool_map_get_ranks(pool_uuid, map, false, &disabled_rank_list); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": pool_map_get_ranks() failed", DP_UUID(pool_uuid)); + D_GOTO(error, rc); + } + D_DEBUG(DB_MD, DF_UUID ": found %" PRIu32 " disabled ranks in pool map\n", + DP_UUID(pool_uuid), disabled_rank_list->rl_nr); + } + + pool_query_reply_to_info(pool_uuid, map_buf, map_version, leader_rank, ps, rs, info); + info->pi_ndisabled = num_disabled; + if (enabled_rank_list != NULL) + *enabled_ranks = enabled_rank_list; + if (disabled_rank_list != NULL) + *disabled_ranks = disabled_rank_list; + D_GOTO(out, rc = -DER_SUCCESS); + +error: + d_rank_list_free(disabled_rank_list); + d_rank_list_free(enabled_rank_list); +out: + if (map != NULL) + pool_map_decref(map); + return rc; +} + +#if 0 static int process_query_result(d_rank_list_t **ranks, daos_pool_info_t *info, uuid_t pool_uuid, uint32_t map_version, uint32_t leader_rank, struct daos_pool_space *ps, @@ -4266,18 +4342,15 @@ process_query_result(d_rank_list_t **ranks, daos_pool_info_t *info, uuid_t pool_ pool_map_decref(map); return rc; } +#endif /** * Query the pool without holding a pool handle. * * \param[in] pool_uuid UUID of the pool * \param[in] ps_ranks Ranks of pool svc replicas - * \param[out] ranks Optional, returned storage ranks in this pool. - * If #pool_info is NULL, engines with disabled targets. - * If #pool_info is passed, engines with enabled or disabled - * targets according to #pi_bits (DPI_ENGINES_ENABLED bit). - * Note: ranks may be empty (i.e., *ranks->rl_nr may be 0). - * The caller must free the list with d_rank_list_free(). + * \param[out] enabled_ranks Optional, storage ranks with enabled targets. + * \param[out] disabled_ranks Optional, storage ranks with disabled targets. * \param[out] pool_info Results of the pool query * \param[out] pool_layout_ver Results of the current pool global version * \param[out] pool_upgrade_layout_ver Results of the target latest pool global version @@ -4285,11 +4358,13 @@ process_query_result(d_rank_list_t **ranks, daos_pool_info_t *info, uuid_t pool_ * \return 0 Success * -DER_INVAL Invalid input * Negative value Error + * \note The enabled_ranks and disabled_ranks may be empty (i.e., *ranks->rl_nr may be 0). + * \note The caller must free the lists enabled_ranks and disabled_ranks with d_rank_list_free(). */ int -ds_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver) +ds_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver) { int rc; struct rsvc_client client; @@ -4301,7 +4376,7 @@ ds_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_list_t **ran struct pool_buf *map_buf; uint32_t map_size = 0; - if (ranks == NULL || pool_info == NULL) + if (pool_info == NULL) D_GOTO(out, rc = -DER_INVAL); D_DEBUG(DB_MGMT, DF_UUID": Querying pool\n", DP_UUID(pool_uuid)); @@ -4362,9 +4437,10 @@ ds_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, d_rank_list_t **ran D_DEBUG(DB_MGMT, DF_UUID": Successfully queried pool\n", DP_UUID(pool_uuid)); - rc = process_query_result(ranks, pool_info, pool_uuid, + rc = process_query_result(enabled_ranks, disabled_ranks, pool_info, pool_uuid, out->pqo_op.po_map_version, out->pqo_op.po_hint.sh_rank, - &out->pqo_space, &out->pqo_rebuild_st, map_buf); + &out->pqo_space, &out->pqo_rebuild_st, map_buf, + pool_info->pi_bits); if (pool_layout_ver) *pool_layout_ver = out->pqo_pool_layout_ver; if (upgrade_layout_ver) diff --git a/src/tests/ftest/control/dmg_pool_query_ranks.py b/src/tests/ftest/control/dmg_pool_query_ranks.py index d0cadef0754..92ad0614a20 100644 --- a/src/tests/ftest/control/dmg_pool_query_ranks.py +++ b/src/tests/ftest/control/dmg_pool_query_ranks.py @@ -1,5 +1,5 @@ """ - (C) Copyright 2022-2023 Intel Corporation. + (C) Copyright 2022-2024 Intel Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent """ @@ -71,27 +71,16 @@ def test_pool_query_ranks_basic(self): "Invalid disabled_ranks field: want=[], got={}".format( data['response']['disabled_ranks'])) - def test_pool_query_ranks_error(self): - """Test that ranks state option are mutually exclusive. - - Test Description: - Check that options '--show-enabled' and '--show-disabled" are mutually exclusive. - - :avocado: tags=all,daily_regression - :avocado: tags=vm - :avocado: tags=dmg,control,pool_query,pool_query_ranks - :avocado: tags=DmgPoolQueryRanks,test_pool_query_ranks_error - """ - self.log.info("Tests of pool query with incompatible options") - - # Disable raising an exception if the dmg command fails - self.dmg.exit_status_exception = False - try: - data = self.dmg.pool_query(self.pool.identifier, show_enabled=True, show_disabled=True) - self.assertIsNotNone(data["error"], "Expected error not returned") - self.assertIn(r'may not be mixed with', str(data['error']), "Invalid error message") - finally: - self.dmg.exit_status_exception = True + self.log.debug("Checking enabled and disabled ranks state information") + data = self.dmg.pool_query(self.pool.identifier, show_enabled=True, show_disabled=True) + self.assertListEqual( + data['response']['enabled_ranks'], [0, 1, 2], + "Invalid enabled_ranks field: want=[0, 1, 2], got={}".format( + data['response']['enabled_ranks'])) + self.assertListEqual( + data['response']['disabled_ranks'], [], + "Invalid disabled_ranks field: want=[], got={}".format( + data['response']['disabled_ranks'])) def test_pool_query_ranks_mgmt(self): """Test the state of ranks after excluding and reintegrate them. @@ -121,14 +110,12 @@ def test_pool_query_ranks_mgmt(self): disabled_ranks = sorted(disabled_ranks + [rank]) self.log.debug("Checking enabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_enabled=True) + data = self.dmg.pool_query( + self.pool.identifier, show_enabled=True, show_disabled=True) self.assertListEqual( data['response']['enabled_ranks'], enabled_ranks, "Invalid enabled_ranks field: want={}, got={}".format( enabled_ranks, data['response']['enabled_ranks'])) - - self.log.debug("Checking disabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_disabled=True) self.assertListEqual( data['response']['disabled_ranks'], disabled_ranks, "Invalid disabled_ranks field: want={}, got={}".format( @@ -158,14 +145,11 @@ def test_pool_query_ranks_mgmt(self): disabled_ranks.remove(rank) self.log.debug("Checking enabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_enabled=True) + data = self.dmg.pool_query(self.pool.identifier, show_enabled=True, show_disabled=True) self.assertListEqual( data['response']['enabled_ranks'], enabled_ranks, "Invalid enabled_ranks field: want={}, got={}".format( enabled_ranks, data['response']['enabled_ranks'])) - - self.log.debug("Checking disabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_disabled=True) self.assertListEqual( data['response']['disabled_ranks'], disabled_ranks, "Invalid disabled_ranks field: want={}, got={}".format(