Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAOS-16328 control: Update dmg pool list for MD-on-SSD #15490

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the SCM-only case (admittedly a corner case at this point), nothing has changed, has it? May be worth calling out here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can update in a follow-on, the behaviour for PMem has changed because only NVMe tier is displayed in the default mode, as you have said nothing changes for SCM-only (and there is no equivalent supported mode for MD-on-SSD)

- 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
knard-intel marked this conversation as resolved.
Show resolved Hide resolved
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.
Comment on lines +594 to +595
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording nit.

Suggested change
by some storage targets while space is still available on others. Again
for the NVMe or DATA tier.
by some storage targets while space is still available on others. Applies only
for the NVMe or DATA tier.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will update in a follow-on

- 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
Loading