Skip to content

Commit

Permalink
DAOS-10250 control: Get enabled and disabled ranks with dmg pool query
Browse files Browse the repository at this point in the history
Makes enabled and disabled ranks option of dmg compatible.
Update and add cmocka unit tests of engine management related functions.
Fix memory leaks of ranks string in function ds_mgmt_drpc_pool_query().

Features: control dmg
Required-githooks: true

Signed-off-by: Cedric Koch-Hofer <[email protected]>
  • Loading branch information
kanard38 authored and knard-intel committed May 24, 2024
1 parent 1268dc4 commit f3d6fe5
Show file tree
Hide file tree
Showing 14 changed files with 426 additions and 252 deletions.
4 changes: 0 additions & 4 deletions src/control/cmd/dmg/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,10 +646,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)
}
Expand Down
32 changes: 26 additions & 6 deletions src/control/cmd/dmg/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,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",
Expand Down Expand Up @@ -1056,12 +1082,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"),
},
})
}

Expand Down
83 changes: 42 additions & 41 deletions src/gurt/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,14 +750,19 @@ d_rank_list_dump(d_rank_list_t *rank_list, d_string_t name, int name_len)
char *
d_rank_list_to_str(d_rank_list_t *rank_list)
{
char *str;
bool truncated = false;
d_rank_range_list_t *range_list;
char *str = NULL;
d_rank_range_list_t *range_list = NULL;
int rc;

range_list = d_rank_range_list_create_from_ranks(rank_list);
if (range_list == NULL)
if (range_list == NULL) {
DL_WARN(-DER_NOMEM, "rank list could not be serialized");
return NULL;
str = d_rank_range_list_str(range_list, &truncated);
}

rc = d_rank_range_list_str(range_list, &str);
if (rc != -DER_SUCCESS)
DL_WARN(rc, "rank list could not be serialized");

d_rank_range_list_free(range_list);

Expand Down Expand Up @@ -844,7 +849,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)
{
Expand All @@ -854,6 +858,8 @@ d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list)
unsigned int i; /* rank index */
unsigned int j; /* rank range index */

D_ASSERT(rank_list != NULL);

d_rank_list_sort(rank_list);
if ((rank_list == NULL) || (rank_list->rl_ranks == NULL) || (rank_list->rl_nr == 0))
return d_rank_range_list_alloc(0);
Expand Down Expand Up @@ -890,56 +896,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
Expand Down
123 changes: 122 additions & 1 deletion src/gurt/tests/test_gurt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2510,6 +2510,125 @@ test_d_setenv(void **state)
assert_false(d_isenv_def("foo"));
}

static void
test_d_rank_range_list_create_from_ranks(void **state)
{
d_rank_list_t *ranks;
d_rank_range_list_t *range_list;

(void)state; /* unused */

// 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;

(void)state; /* unused */

// 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);
ranks_str = NULL;
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);
ranks_str = NULL;
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)
{
Expand Down Expand Up @@ -2546,7 +2665,9 @@ 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_range_list_create_from_ranks),
cmocka_unit_test(test_d_rank_range_list_str)};

d_register_alt_assert(mock_assert);

Expand Down
8 changes: 5 additions & 3 deletions src/include/daos_srv/pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,11 @@ int dsc_pool_svc_delete_acl(uuid_t pool_uuid, d_rank_list_t *ranks, uint64_t dea
enum daos_acl_principal_type principal_type,
const char *principal_name);

int dsc_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline,
d_rank_list_t **ranks, daos_pool_info_t *pool_info,
uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver);
int
dsc_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline,
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 dsc_pool_svc_query_target(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline,
d_rank_t rank, uint32_t tgt_idx, daos_target_info_t *ti);

Expand Down
3 changes: 2 additions & 1 deletion src/include/gurt/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ char *d_rank_list_to_str(d_rank_list_t *rank_list);
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);

#ifdef FAULT_INJECTION
Expand Down
Loading

0 comments on commit f3d6fe5

Please sign in to comment.