Skip to content

Commit

Permalink
DAOS-16328 control: Update dmg pool list for MD-on-SSD
Browse files Browse the repository at this point in the history
Features: control
Skip-func-hw-test-medium-md-on-ssd: false
Skip-func-hw-test-large-md-on-ssd: false
Required-githooks: true

Signed-off-by: Tom Nabarro <tom.nabarro@intel.com>
  • Loading branch information
tanabarr committed Nov 13, 2024
1 parent d4070e8 commit c6ebd52
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 67 deletions.
24 changes: 17 additions & 7 deletions docs/admin/pool_operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,24 +585,34 @@ tank 47 GB 0% 0% 0/32

This returns a table of pool labels (or UUIDs if no label was specified)
with the following information for each pool:
- the total pool size
- the percentage of used space (i.e., 100 * used space / total space)
- the imbalance percentage indicating whether data distribution across
- The total pool size (NVMe or DATA tier, not including Metadata tier).
- The percentage of used space (i.e., 100 * used space / total space)
for the NVMe or DATA tier.
- The imbalance percentage indicating whether data distribution across
the difference storage targets is well balanced. 0% means that there is
no imbalance and 100% means that out-of-space errors might be returned
by some storage targets while space is still available on others.
- the number of disabled targets (0 here) and the number of targets that
by some storage targets while space is still available on others. Again
for the NVMe or DATA tier.
- The number of disabled targets (0 here) and the number of targets that
the pool was originally configured with (total).

The --verbose option provides more detailed information including the
number of service replicas, the full UUIDs and space distribution
between SCM and NVMe for each pool:
between SCM and NVMe (or META and DATA in MD-on-SSD mode) for each pool:

```bash
$ dmg pool list --verbose
Label UUID SvcReps SCM Size SCM Used SCM Imbalance NVME Size NVME Used NVME Imbalance Disabled
----- ---- ------- -------- -------- ------------- --------- --------- -------------- --------
tank 8a05bf3a-a088-4a77-bb9f-df989fce7cc8 1-3 3 GB 10 kB 0% 47 GB 0 B 0% 0/32
tank 8a05bf3a-a088-4a77-bb9f-df989fce7cc8 1-3 3 GB 10 kB 0% 47 GB 0 B 0% 0/32
```

In MD-on-SSD mode:
```bash
$ dmg pool list --verbose
Label UUID SvcReps Meta Size Meta Used Meta Imbalance DATA Size DATA Used DATA Imbalance Disabled
----- ---- ------- --------- --------- -------------- --------- --------- -------------- --------
tank 8a05bf3a-a088-4a77-bb9f-df989fce7cc8 1-3 3 GB 10 kB 0% 47 GB 0 B 0% 0/32
```

### Destroying a Pool
Expand Down
143 changes: 91 additions & 52 deletions src/control/cmd/daos/pretty/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,50 +112,55 @@ func PrintPoolQueryTargetInfo(pqti *daos.PoolQueryTargetInfo, out io.Writer) err
return w.Err
}

func poolListCreateRow(pool *daos.PoolInfo, upgrade bool) txtfmt.TableRow {
// display size of the largest non-empty tier
// Display info of NVMe or DATA tier in non-verbose mode. Show single tier if there is only one
// non-empty tier.
func poolListCreateRow(pool *daos.PoolInfo, upgradeNeeded, hasSpaceQuery bool) txtfmt.TableRow {
var size uint64
poolUsage := pool.Usage()
for ti := len(poolUsage) - 1; ti >= 0; ti-- {
if poolUsage[ti].Size != 0 {
size = poolUsage[ti].Size
break
}
}

// display usage of the most used tier
var imbalance uint32
var used int
for ti := 0; ti < len(poolUsage); ti++ {
t := poolUsage[ti]
u := float64(t.Size-t.Free) / float64(t.Size)
poolUsage := pool.Usage()

if int(u*100) > used {
used = int(u * 100)
if hasSpaceQuery && len(poolUsage) != 0 {
// Display stats of the last non-empty tier.
tierIdx := -1
for ti := len(poolUsage) - 1; ti >= 0; ti-- {
if poolUsage[ti].Size > 0 {
tierIdx = ti
break
}
}
}

// display imbalance of the most imbalanced tier
var imbalance uint32
for ti := 0; ti < len(poolUsage); ti++ {
if poolUsage[ti].Imbalance > imbalance {
imbalance = poolUsage[ti].Imbalance
if tierIdx != -1 {
tier := poolUsage[tierIdx]
size = tier.Size
used = int((float64(size-tier.Free) / float64(size)) * 100)
if used < 0 {
used = 0
}
imbalance = tier.Imbalance
}
}

row := txtfmt.TableRow{
"Pool": pool.Name(),
"Size": humanize.Bytes(size),
"State": pool.State.String(),
"Used": fmt.Sprintf("%d%%", used),
"Imbalance": fmt.Sprintf("%d%%", imbalance),
"Disabled": fmt.Sprintf("%d/%d", pool.DisabledTargets, pool.TotalTargets),
"Pool": pool.Name(),
"State": pool.State.String(),
}
if hasSpaceQuery {
row = txtfmt.TableRow{
"Pool": pool.Name(),
"Size": humanize.Bytes(size),
"State": pool.State.String(),
"Used": fmt.Sprintf("%d%%", used),
"Imbalance": fmt.Sprintf("%d%%", imbalance),
"Disabled": fmt.Sprintf("%d/%d", pool.DisabledTargets, pool.TotalTargets),
}
}

if upgrade {
if upgradeNeeded {
upgradeString := "None"

if pool.PoolLayoutVer != pool.UpgradeLayoutVer {
upgradeString = fmt.Sprintf("%d->%d", pool.PoolLayoutVer, pool.UpgradeLayoutVer)
upgradeString = fmt.Sprintf("%d->%d", pool.PoolLayoutVer,
pool.UpgradeLayoutVer)
}
row["UpgradeNeeded?"] = upgradeString
}
Expand All @@ -164,38 +169,74 @@ func poolListCreateRow(pool *daos.PoolInfo, upgrade bool) txtfmt.TableRow {
}

func printPoolList(pools []*daos.PoolInfo, out io.Writer) error {
upgrade := false
upgradeNeeded := false
hasSpaceQuery := false
for _, pool := range pools {
if upgradeNeeded && hasSpaceQuery {
break
}
if pool.PoolLayoutVer != pool.UpgradeLayoutVer {
upgrade = true
upgradeNeeded = true
}
if pool.QueryMask.HasOption(daos.PoolQueryOptionSpace) {
hasSpaceQuery = true
}
}

titles := []string{"Pool", "Size", "State", "Used", "Imbalance", "Disabled"}
if upgrade {
titles := []string{"Pool", "State"}
if hasSpaceQuery {
titles = []string{"Pool", "Size", "State", "Used", "Imbalance", "Disabled"}
}
if upgradeNeeded {
titles = append(titles, "UpgradeNeeded?")
}
formatter := txtfmt.NewTableFormatter(titles...)

var table []txtfmt.TableRow
for _, pool := range pools {
table = append(table, poolListCreateRow(pool, upgrade))
table = append(table, poolListCreateRow(pool, upgradeNeeded, hasSpaceQuery))
}

fmt.Fprintln(out, formatter.Format(table))

return nil
}

func addVerboseTierUsage(row txtfmt.TableRow, usage *daos.PoolTierUsage) txtfmt.TableRow {
row[usage.TierName+" Size"] = humanize.Bytes(usage.Size)
row[usage.TierName+" Used"] = humanize.Bytes(usage.Size - usage.Free)
row[usage.TierName+" Imbalance"] = fmt.Sprintf("%d%%", usage.Imbalance)
func getRowUsageTitles(pool *daos.PoolInfo, hasMdOnSsd bool) []string {
titles := []string{}

for i, tu := range pool.Usage() {
tn := tu.TierName
if hasMdOnSsd {
if i == 0 {
tn = "Meta"
} else {
tn = "Data"
}
}
titles = append(titles, tn+" Size", tn+" Used", tn+" Imbalance")
}

return titles
}

func addVerboseTierUsage(pool *daos.PoolInfo, titles []string, row txtfmt.TableRow) txtfmt.TableRow {
var ti int

for _, tu := range pool.Usage() {
if len(titles) < ti+3 {
break
}
row[titles[ti]] = humanize.Bytes(tu.Size)
row[titles[ti+1]] = humanize.Bytes(tu.Size - tu.Free)
row[titles[ti+2]] = fmt.Sprintf("%d%%", tu.Imbalance)
ti += 3
}

return row
}

func poolListCreateRowVerbose(pool *daos.PoolInfo, hasSpace, hasRebuild bool) txtfmt.TableRow {
func poolListCreateRowVerbose(pool *daos.PoolInfo, hasSpace, hasRebuild bool, usageTitles []string) txtfmt.TableRow {
label := pool.Label
if label == "" {
label = "-"
Expand Down Expand Up @@ -226,9 +267,7 @@ func poolListCreateRowVerbose(pool *daos.PoolInfo, hasSpace, hasRebuild bool) tx
}

if hasSpace {
for _, tu := range pool.Usage() {
row = addVerboseTierUsage(row, tu)
}
row = addVerboseTierUsage(pool, usageTitles, row)
}

return row
Expand All @@ -240,27 +279,26 @@ func printVerbosePoolList(pools []*daos.PoolInfo, out io.Writer) error {

hasSpaceQuery := false
hasRebuildQuery := false
hasMdOnSsd := false
for _, pool := range pools {
if hasSpaceQuery && hasRebuildQuery {
break
}

if pool.QueryMask.HasOption(daos.PoolQueryOptionSpace) {
hasSpaceQuery = true
// All pools will have the same PMem/MD-on-SSD mode.
hasMdOnSsd = pool.MemFileBytes != 0
}
if pool.QueryMask.HasOption(daos.PoolQueryOptionRebuild) {
hasRebuildQuery = true
}
}

// If any of the pools was queried, then we'll need to show more fields.
usageTitles := []string{}
if hasSpaceQuery {
for _, t := range pools[0].Usage() {
titles = append(titles,
t.TierName+" Size",
t.TierName+" Used",
t.TierName+" Imbalance")
}
usageTitles = getRowUsageTitles(pools[0], hasMdOnSsd)
titles = append(titles, usageTitles...)
titles = append(titles, "Disabled")
titles = append(titles, "UpgradeNeeded?")
}
Expand All @@ -273,7 +311,8 @@ func printVerbosePoolList(pools []*daos.PoolInfo, out io.Writer) error {

var table []txtfmt.TableRow
for _, pool := range pools {
table = append(table, poolListCreateRowVerbose(pool, hasSpaceQuery, hasRebuildQuery))
table = append(table,
poolListCreateRowVerbose(pool, hasSpaceQuery, hasRebuildQuery, usageTitles))
}

fmt.Fprintln(out, formatter.Format(table))
Expand Down
Loading

0 comments on commit c6ebd52

Please sign in to comment.