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-13228 control: List BDEV role assignments in scan/format display #13463

Merged
merged 12 commits into from
Jan 23, 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
51 changes: 45 additions & 6 deletions src/bio/bio_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,11 +606,46 @@ struct led_opts {
int status;
};

static Ctl__LedState
led_state_spdk2daos(enum spdk_vmd_led_state in)
{
switch (in) {
case SPDK_VMD_LED_STATE_OFF:
return CTL__LED_STATE__OFF;
case SPDK_VMD_LED_STATE_IDENTIFY:
return CTL__LED_STATE__QUICK_BLINK;
case SPDK_VMD_LED_STATE_FAULT:
return CTL__LED_STATE__ON;
case SPDK_VMD_LED_STATE_REBUILD:
return CTL__LED_STATE__SLOW_BLINK;
default:
return CTL__LED_STATE__NA;
}
}

static enum spdk_vmd_led_state
led_state_daos2spdk(Ctl__LedState in)
{
switch (in) {
case CTL__LED_STATE__OFF:
return SPDK_VMD_LED_STATE_OFF;
case CTL__LED_STATE__QUICK_BLINK:
return SPDK_VMD_LED_STATE_IDENTIFY;
case CTL__LED_STATE__ON:
return SPDK_VMD_LED_STATE_FAULT;
case CTL__LED_STATE__SLOW_BLINK:
return SPDK_VMD_LED_STATE_REBUILD;
default:
return SPDK_VMD_LED_STATE_UNKNOWN;
}
}

static void
led_device_action(void *ctx, struct spdk_pci_device *pci_device)
{
struct led_opts *opts = ctx;
enum spdk_vmd_led_state cur_led_state;
Ctl__LedState d_led_state;
const char *pci_dev_type = NULL;
char addr_buf[ADDR_STR_MAX_LEN + 1];
int rc;
Expand Down Expand Up @@ -656,14 +691,17 @@ led_device_action(void *ctx, struct spdk_pci_device *pci_device)
return;
}

/* Convert state to Ctl__LedState from SPDK led_state */
d_led_state = led_state_spdk2daos(cur_led_state);

D_DEBUG(DB_MGMT, "led on dev %s has state: %s (action: %s, new state: %s)\n", addr_buf,
LED_STATE_NAME(cur_led_state), LED_ACTION_NAME(opts->action),
LED_STATE_NAME(d_led_state), LED_ACTION_NAME(opts->action),
LED_STATE_NAME(opts->led_state));

switch (opts->action) {
case CTL__LED_ACTION__GET:
/* Return early with current device state set */
opts->led_state = (Ctl__LedState)cur_led_state;
opts->led_state = d_led_state;
return;
case CTL__LED_ACTION__SET:
break;
Expand All @@ -678,14 +716,14 @@ led_device_action(void *ctx, struct spdk_pci_device *pci_device)
return;
}

if (cur_led_state == (enum spdk_vmd_led_state)opts->led_state) {
if (d_led_state == opts->led_state) {
D_DEBUG(DB_MGMT, "VMD device %s LED state already in state %s\n", addr_buf,
LED_STATE_NAME(opts->led_state));
return;
}

/* Set the LED to the new state */
rc = spdk_vmd_set_led_state(pci_device, (enum spdk_vmd_led_state)opts->led_state);
rc = spdk_vmd_set_led_state(pci_device, led_state_daos2spdk(opts->led_state));
if (spdk_unlikely(rc != 0)) {
D_ERROR("Failed to set the VMD LED state on %s (%s)\n", addr_buf,
spdk_strerror(-rc));
Expand All @@ -700,11 +738,12 @@ led_device_action(void *ctx, struct spdk_pci_device *pci_device)
opts->status = -DER_NOSYS;
return;
}
d_led_state = led_state_spdk2daos(cur_led_state);

/* Verify the correct state is set */
if (cur_led_state != (enum spdk_vmd_led_state)opts->led_state) {
if (d_led_state != opts->led_state) {
D_ERROR("Unexpected LED state on %s, want %s got %s\n", addr_buf,
LED_STATE_NAME(opts->led_state), LED_STATE_NAME(cur_led_state));
LED_STATE_NAME(opts->led_state), LED_STATE_NAME(d_led_state));
opts->status = -DER_INVAL;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/bio/smd.pb-c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2833,19 +2833,19 @@ const ProtobufCEnumDescriptor ctl__nvme_dev_state__descriptor =
};
static const ProtobufCEnumValue ctl__led_state__enum_values_by_number[5] =
{
{ "OFF", "CTL__LED_STATE__OFF", 0 },
{ "NA", "CTL__LED_STATE__NA", 0 },
{ "QUICK_BLINK", "CTL__LED_STATE__QUICK_BLINK", 1 },
{ "ON", "CTL__LED_STATE__ON", 2 },
{ "SLOW_BLINK", "CTL__LED_STATE__SLOW_BLINK", 3 },
{ "NA", "CTL__LED_STATE__NA", 4 },
{ "OFF", "CTL__LED_STATE__OFF", 4 },
};
static const ProtobufCIntRange ctl__led_state__value_ranges[] = {
{0, 0},{0, 5}
};
static const ProtobufCEnumValueIndex ctl__led_state__enum_values_by_name[5] =
{
{ "NA", 4 },
{ "OFF", 0 },
{ "NA", 0 },
{ "OFF", 4 },
{ "ON", 2 },
{ "QUICK_BLINK", 1 },
{ "SLOW_BLINK", 3 },
Expand Down
12 changes: 6 additions & 6 deletions src/bio/smd.pb-c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/control/cmd/dmg/pretty/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ func printSmdDevice(dev *storage.SmdDevice, iw io.Writer, opts ...PrintConfigOpt
fc := getPrintConfig(opts...)

if fc.LEDInfoOnly {
if _, err := fmt.Fprintf(iw, "TrAddr:%s", dev.Ctrlr.PciAddr); err != nil {
if _, err := fmt.Fprintf(iw, "TrAddr:%s NSID:%d", dev.Ctrlr.PciAddr,
dev.CtrlrNamespaceID); err != nil {
return err
}
if dev.UUID != "" {
Expand All @@ -193,7 +194,8 @@ func printSmdDevice(dev *storage.SmdDevice, iw io.Writer, opts ...PrintConfigOpt
return nil
}

if _, err := fmt.Fprintf(iw, "UUID:%s [TrAddr:%s]\n", dev.UUID, dev.Ctrlr.PciAddr); err != nil {
if _, err := fmt.Fprintf(iw, "UUID:%s [TrAddr:%s NSID:%d]\n", dev.UUID, dev.Ctrlr.PciAddr,
dev.CtrlrNamespaceID); err != nil {
return err
}

Expand Down
89 changes: 31 additions & 58 deletions src/control/cmd/dmg/pretty/storage_nvme.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package pretty

import (
"errors"
"fmt"
"io"
"sort"
Expand All @@ -18,6 +17,7 @@ import (

"github.com/daos-stack/daos/src/control/common"
"github.com/daos-stack/daos/src/control/lib/control"
"github.com/daos-stack/daos/src/control/lib/ranklist"
"github.com/daos-stack/daos/src/control/lib/txtfmt"
"github.com/daos-stack/daos/src/control/server/storage"
)
Expand Down Expand Up @@ -165,32 +165,38 @@ func parseNvmeFormatResults(inResults storage.NvmeControllers) storage.NvmeContr
parsedResults := make(storage.NvmeControllers, 0, len(inResults))
for _, result := range inResults {
if result.PciAddr != storage.NilBdevAddress {
// ignore skip results
parsedResults = append(parsedResults, result)
}
}

return parsedResults
}

func printNvmeFormatResults(devices storage.NvmeControllers, out io.Writer, opts ...PrintConfigOption) error {
if len(devices) == 0 {
func printNvmeFormatResults(ctrlrs storage.NvmeControllers, out io.Writer, opts ...PrintConfigOption) error {
if len(ctrlrs) == 0 {
fmt.Fprintln(out, "\tNo NVMe devices found")
return nil
}

pciTitle := "NVMe PCI"
resultTitle := "Format Result"
rolesTitle := "Role(s)"

formatter := txtfmt.NewTableFormatter(pciTitle, resultTitle)
formatter := txtfmt.NewTableFormatter(pciTitle, resultTitle, rolesTitle)
formatter.InitWriter(out)
var table []txtfmt.TableRow

sort.Slice(devices, func(i, j int) bool { return devices[i].PciAddr < devices[j].PciAddr })
sort.Slice(ctrlrs, func(i, j int) bool { return ctrlrs[i].PciAddr < ctrlrs[j].PciAddr })

for _, device := range parseNvmeFormatResults(devices) {
row := txtfmt.TableRow{pciTitle: device.PciAddr}
row[resultTitle] = device.Info
for _, ctrlr := range parseNvmeFormatResults(ctrlrs) {
row := txtfmt.TableRow{pciTitle: ctrlr.PciAddr}
row[resultTitle] = ctrlr.Info
roles := "NA"
// Assumes that all SMD devices on a controller have the same roles.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this really a safe assumption?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

currently yes, we don't have capability to have separate blobstores on any single SSD, so all devices will have the same role combinations

Copy link
Contributor

Choose a reason for hiding this comment

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

If this assumption is likely to hold true going forward, I don't have a problem with it. Just looking to avoid churn when possible.

if len(ctrlr.SmdDevices) > 0 {
roles = fmt.Sprintf("%s", ctrlr.SmdDevices[0].Roles.String())
}
row[rolesTitle] = roles

table = append(table, row)
}
Expand All @@ -211,11 +217,13 @@ func PrintNvmeControllers(controllers storage.NvmeControllers, out io.Writer, op
pciTitle := "NVMe PCI"
modelTitle := "Model"
fwTitle := "FW Revision"
socketTitle := "Socket ID"
socketTitle := "Socket"
capacityTitle := "Capacity"
rolesTitle := "Role(s)"
rankTitle := "Rank"

formatter := txtfmt.NewTableFormatter(
pciTitle, modelTitle, fwTitle, socketTitle, capacityTitle,
pciTitle, modelTitle, fwTitle, socketTitle, capacityTitle, rolesTitle, rankTitle,
)
formatter.InitWriter(out)
var table []txtfmt.TableRow
Expand All @@ -228,6 +236,18 @@ func PrintNvmeControllers(controllers storage.NvmeControllers, out io.Writer, op
row[fwTitle] = ctrlr.FwRev
row[socketTitle] = fmt.Sprint(ctrlr.SocketID)
row[capacityTitle] = humanize.Bytes(ctrlr.Capacity())
roles := "NA"
rank := "None"
// Assumes that all SMD devices on a controller have the same roles and rank.
if len(ctrlr.SmdDevices) > 0 {
sd := ctrlr.SmdDevices[0]
roles = sd.Roles.String()
if sd.Rank != ranklist.NilRank {
rank = sd.Rank.String()
}
}
row[rolesTitle] = roles
row[rankTitle] = rank

table = append(table, row)
}
Expand Down Expand Up @@ -266,50 +286,3 @@ func PrintNvmeHealthMap(hsm control.HostStorageMap, out io.Writer, opts ...Print

return w.Err
}

// PrintNvmeMetaMap generates a human-readable representation of the supplied
// HostStorageMap, with a focus on presenting the NVMe Device Server Meta Data.
func PrintNvmeMetaMap(hsm control.HostStorageMap, out io.Writer, opts ...PrintConfigOption) error {
w := txtfmt.NewErrWriter(out)

for _, key := range hsm.Keys() {
hss := hsm[key]
hosts := getPrintHosts(hss.HostSet.RangedString(), opts...)
lineBreak := strings.Repeat("-", len(hosts))
fmt.Fprintf(out, "%s\n%s\n%s\n", lineBreak, hosts, lineBreak)

if len(hss.HostStorage.NvmeDevices) == 0 {
fmt.Fprintln(out, " No NVMe devices detected")
continue
}

for _, controller := range hss.HostStorage.NvmeDevices {
if controller == nil {
return errors.New("nil controller in NvmeDevices")
}
if err := printNvmeControllerSummary(controller, out, opts...); err != nil {
return err
}
iw := txtfmt.NewIndentWriter(out)
if len(controller.SmdDevices) > 0 {
fmt.Fprintln(iw, "SMD Devices")

for _, device := range controller.SmdDevices {
iw1 := txtfmt.NewIndentWriter(iw)

// Attach parent controller details to SMD before printing.
device.Ctrlr = *controller

if err := printSmdDevice(device, iw1, opts...); err != nil {
return err
}
}
} else {
fmt.Fprintln(iw, "No SMD devices found")
}
fmt.Fprintln(out)
}
}

return w.Err
}
Loading