Skip to content

Commit bd45a1b

Browse files
authored
DAOS-18592 control: Only use joined ranks when calculating pool size (#17580)
In order to avoid failing pool create with storage percentage (-z X%) when ranks have been stopped, only take into account joined ranks when calculating maximum available pool sizes. Signed-off-by: Tom Nabarro <thomas.nabarro@hpe.com>
1 parent f76da96 commit bd45a1b

2 files changed

Lines changed: 227 additions & 66 deletions

File tree

src/control/lib/control/pool.go

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,16 +1188,8 @@ func ListPools(ctx context.Context, rpcClient UnaryInvoker, req *ListPoolsReq) (
11881188

11891189
type rankFreeSpaceMap map[ranklist.Rank]uint64
11901190

1191-
type filterRankFn func(rank ranklist.Rank) bool
1192-
1193-
func newFilterRankFunc(ranks ranklist.RankList) filterRankFn {
1194-
return func(rank ranklist.Rank) bool {
1195-
return len(ranks) == 0 || rank.InList(ranks)
1196-
}
1197-
}
1198-
11991191
// Add namespace ranks to rankNVMeFreeSpace map and return minimum free available SCM namespace bytes.
1200-
func processSCMSpaceStats(log debugLogger, filterRank filterRankFn, scmNamespaces storage.ScmNamespaces, rankNVMeFreeSpace rankFreeSpaceMap) (uint64, error) {
1192+
func processSCMSpaceStats(log debugLogger, ranks ranklist.RankList, scmNamespaces storage.ScmNamespaces, rankNVMeFreeSpace rankFreeSpaceMap) (uint64, error) {
12011193
scmBytes := uint64(math.MaxUint64)
12021194

12031195
// Realistically there should only be one-per-rank but handle the case for multiple anyway.
@@ -1207,7 +1199,7 @@ func processSCMSpaceStats(log debugLogger, filterRank filterRankFn, scmNamespace
12071199
scmNamespace.UUID, scmNamespace.BlockDevice, scmNamespace.Name)
12081200
}
12091201

1210-
if !filterRank(scmNamespace.Mount.Rank) {
1202+
if !scmNamespace.Mount.Rank.InList(ranks) {
12111203
log.Debugf("Skipping SCM device %s (bdev %s, name %s, rank %d) not in ranklist",
12121204
scmNamespace.UUID, scmNamespace.BlockDevice, scmNamespace.Name,
12131205
scmNamespace.Mount.Rank)
@@ -1233,7 +1225,7 @@ func processSCMSpaceStats(log debugLogger, filterRank filterRankFn, scmNamespace
12331225
}
12341226

12351227
// Add NVMe free bytes to rankNVMeFreeSpace map.
1236-
func processNVMeSpaceStats(log debugLogger, filterRank filterRankFn, nvmeControllers storage.NvmeControllers, rankNVMeFreeSpace rankFreeSpaceMap) error {
1228+
func processNVMeSpaceStats(log debugLogger, ranks ranklist.RankList, nvmeControllers storage.NvmeControllers, rankNVMeFreeSpace rankFreeSpaceMap) error {
12371229
for _, controller := range nvmeControllers {
12381230
for _, smdDevice := range controller.SmdDevices {
12391231
msgDev := fmt.Sprintf("SMD device %s (rank %d, ctrlr %s", smdDevice.UUID,
@@ -1258,7 +1250,7 @@ func processNVMeSpaceStats(log debugLogger, filterRank filterRankFn, nvmeControl
12581250
controller.NvmeState.String())
12591251
}
12601252

1261-
if !filterRank(smdDevice.Rank) {
1253+
if !smdDevice.Rank.InList(ranks) {
12621254
log.Debugf("Skipping %s, not in ranklist", msgDev)
12631255
continue
12641256
}
@@ -1288,10 +1280,34 @@ func getMaxPoolSize(ctx context.Context, rpcClient UnaryInvoker, createReq *Pool
12881280
return 0, 0, errors.New("invalid mem-ratio, should not be greater than one")
12891281
}
12901282

1291-
// Verify that the DAOS system is ready before attempting to query storage.
1292-
if _, err := SystemQuery(ctx, rpcClient, &SystemQueryReq{}); err != nil {
1293-
return 0, 0, err
1283+
// Verify that the DAOS system is ready before attempting to query storage and record joined.
1284+
queryResp, err := SystemQuery(ctx, rpcClient, &SystemQueryReq{})
1285+
if err != nil {
1286+
return 0, 0, errors.Wrap(err, "getMaxPoolSize: SystemQuery")
1287+
}
1288+
joinedRanks := ranklist.RankList{}
1289+
for _, member := range queryResp.Members {
1290+
if member.State == system.MemberStateJoined {
1291+
joinedRanks = append(joinedRanks, member.Rank)
1292+
}
1293+
}
1294+
1295+
// Refuse if any requested ranks are not joined, update ranklist to contain only joined ranks.
1296+
filterRanks := ranklist.RankList{}
1297+
if len(createReq.Ranks) == 0 {
1298+
filterRanks = joinedRanks
1299+
} else {
1300+
for _, rank := range createReq.Ranks {
1301+
if !rank.InList(joinedRanks) {
1302+
return 0, 0, errors.Errorf("specified rank %d is not joined", rank)
1303+
}
1304+
filterRanks = append(filterRanks, rank)
1305+
}
12941306
}
1307+
slices.Sort(filterRanks)
1308+
rpcClient.Debugf("requested/joined/filter ranks: %v/%v/%v", createReq.Ranks, joinedRanks,
1309+
filterRanks)
1310+
createReq.Ranks = filterRanks
12951311

12961312
scanReq := &StorageScanReq{
12971313
Usage: true,
@@ -1307,8 +1323,6 @@ func getMaxPoolSize(ctx context.Context, rpcClient UnaryInvoker, createReq *Pool
13071323
return 0, 0, errors.New("Empty host storage response from StorageScan")
13081324
}
13091325

1310-
// Generate function to verify a rank is in the provided rank slice.
1311-
filterRank := newFilterRankFunc(ranklist.RankList(createReq.Ranks))
13121326
rankNVMeFreeSpace := make(rankFreeSpaceMap)
13131327
scmBytes := uint64(math.MaxUint64)
13141328
for _, key := range scanResp.HostStorage.Keys() {
@@ -1319,7 +1333,7 @@ func getMaxPoolSize(ctx context.Context, rpcClient UnaryInvoker, createReq *Pool
13191333
scanResp.HostStorage[key].HostSet.String())
13201334
}
13211335

1322-
sb, err := processSCMSpaceStats(rpcClient, filterRank, hostStorage.ScmNamespaces, rankNVMeFreeSpace)
1336+
sb, err := processSCMSpaceStats(rpcClient, filterRanks, hostStorage.ScmNamespaces, rankNVMeFreeSpace)
13231337
if err != nil {
13241338
return 0, 0, err
13251339
}
@@ -1328,7 +1342,7 @@ func getMaxPoolSize(ctx context.Context, rpcClient UnaryInvoker, createReq *Pool
13281342
scmBytes = sb
13291343
}
13301344

1331-
if err := processNVMeSpaceStats(rpcClient, filterRank, hostStorage.NvmeDevices, rankNVMeFreeSpace); err != nil {
1345+
if err := processNVMeSpaceStats(rpcClient, filterRanks, hostStorage.NvmeDevices, rankNVMeFreeSpace); err != nil {
13321346
return 0, 0, err
13331347
}
13341348
}

0 commit comments

Comments
 (0)