Skip to content

Commit

Permalink
DAOS-16487 control: Require hostname for nvme set-faulty & replace (#…
Browse files Browse the repository at this point in the history
…15074)

Makes --host option mandatory for dmg storage set nvme-faulty, dmg
storage replace nvme and dmg telemetry metrics. These commands should
only be run on a single host which should be explicitly specified.

Also remove --no-reint flag from replace nvme command.

Signed-off-by: Tom Nabarro <tom.nabarro@intel.com>
  • Loading branch information
tanabarr authored Sep 18, 2024
1 parent 762f6bd commit 049f710
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 356 deletions.
90 changes: 30 additions & 60 deletions src/bio/smd.pb-c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2208,69 +2208,39 @@ const ProtobufCMessageDescriptor ctl__led_manage_req__descriptor =
(ProtobufCMessageInit) ctl__led_manage_req__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor ctl__dev_replace_req__field_descriptors[3] =
{
{
"old_dev_uuid",
1,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(Ctl__DevReplaceReq, old_dev_uuid),
NULL,
&protobuf_c_empty_string,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"new_dev_uuid",
2,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(Ctl__DevReplaceReq, new_dev_uuid),
NULL,
&protobuf_c_empty_string,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"no_reint",
3,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_BOOL,
0, /* quantifier_offset */
offsetof(Ctl__DevReplaceReq, no_reint),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
static const ProtobufCFieldDescriptor ctl__dev_replace_req__field_descriptors[2] = {
{
"old_dev_uuid", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, 0, /* quantifier_offset */
offsetof(Ctl__DevReplaceReq, old_dev_uuid), NULL, &protobuf_c_empty_string, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"new_dev_uuid", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, 0, /* quantifier_offset */
offsetof(Ctl__DevReplaceReq, new_dev_uuid), NULL, &protobuf_c_empty_string, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned ctl__dev_replace_req__field_indices_by_name[] = {
1, /* field[1] = new_dev_uuid */
2, /* field[2] = no_reint */
0, /* field[0] = old_dev_uuid */
};
static const ProtobufCIntRange ctl__dev_replace_req__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 3 }
1, /* field[1] = new_dev_uuid */
0, /* field[0] = old_dev_uuid */
};
const ProtobufCMessageDescriptor ctl__dev_replace_req__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"ctl.DevReplaceReq",
"DevReplaceReq",
"Ctl__DevReplaceReq",
"ctl",
sizeof(Ctl__DevReplaceReq),
3,
ctl__dev_replace_req__field_descriptors,
ctl__dev_replace_req__field_indices_by_name,
1, ctl__dev_replace_req__number_ranges,
(ProtobufCMessageInit) ctl__dev_replace_req__init,
NULL,NULL,NULL /* reserved[123] */
static const ProtobufCIntRange ctl__dev_replace_req__number_ranges[1 + 1] = {{1, 0}, {0, 2}};
const ProtobufCMessageDescriptor ctl__dev_replace_req__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"ctl.DevReplaceReq",
"DevReplaceReq",
"Ctl__DevReplaceReq",
"ctl",
sizeof(Ctl__DevReplaceReq),
2,
ctl__dev_replace_req__field_descriptors,
ctl__dev_replace_req__field_indices_by_name,
1,
ctl__dev_replace_req__number_ranges,
(ProtobufCMessageInit)ctl__dev_replace_req__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor ctl__set_faulty_req__field_descriptors[1] =
{
Expand Down
33 changes: 15 additions & 18 deletions src/bio/smd.pb-c.h

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

7 changes: 4 additions & 3 deletions src/control/cmd/dmg/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ func TestDmg_JsonOutput(t *testing.T) {
testArgs = append(testArgs, "-l", "foo.com", "-a",
test.MockPCIAddr(), "-e", "0")
case "storage set nvme-faulty":
testArgs = append(testArgs, "--force", "-u", test.MockUUID())
testArgs = append(testArgs, "--host", "foo.com", "--force", "-u",
test.MockUUID())
case "storage replace nvme":
testArgs = append(testArgs, "--old-uuid", test.MockUUID(),
"--new-uuid", test.MockUUID())
testArgs = append(testArgs, "--host", "foo.com", "--old-uuid",
test.MockUUID(), "--new-uuid", test.MockUUID())
case "storage led identify", "storage led check", "storage led clear":
testArgs = append(testArgs, test.MockUUID())
case "pool create":
Expand Down
61 changes: 22 additions & 39 deletions src/control/cmd/dmg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ type (
}

singleHostCmd struct {
HostList singleHostFlag `short:"l" long:"host-list" default:"localhost" description:"Single host address <ipv4addr/hostname> to connect to"`
host string
Host singleHostFlag `short:"l" long:"host" required:"1" description:"Single host address <ipv4addr/hostname> to connect to"`
}

ctlInvoker interface {
Expand All @@ -52,6 +51,25 @@ type (
ctlInvokerCmd struct {
ctlInvoker control.Invoker
}

cmdLogger interface {
setLog(*logging.LeveledLogger)
}

// cmdConfigSetter is an interface for setting the control config on a command
cmdConfigSetter interface {
setConfig(*control.Config)
}

// cfgCmd is a structure that can be used by commands that need the control config.
cfgCmd struct {
config *control.Config
}

baseCmd struct {
cmdutil.NoArgsCmd
cmdutil.LogCmd
}
)

func (cmd *ctlInvokerCmd) setInvoker(c control.Invoker) {
Expand All @@ -69,43 +87,8 @@ func (cmd *hostListCmd) setHostList(newList *hostlist.HostSet) {
cmd.HostList.Replace(newList)
}

func (cmd *singleHostCmd) getHostList() []string {
if cmd.host == "" {
if cmd.HostList.Count() == 0 {
cmd.host = "localhost"
} else {
cmd.host = cmd.HostList.Slice()[0]
}
}
return []string{cmd.host}
}

func (cmd *singleHostCmd) setHostList(newList *hostlist.HostSet) {
cmd.HostList.Replace(newList)
}

type cmdLogger interface {
setLog(*logging.LeveledLogger)
}

type baseCmd struct {
cmdutil.NoArgsCmd
cmdutil.LogCmd
}

// cmdConfigSetter is an interface for setting the control config on a command
type cmdConfigSetter interface {
setConfig(*control.Config)
}

// cfgCmd is a structure that can be used by commands that need the control
// config.
type cfgCmd struct {
config *control.Config
}

func (c *cfgCmd) setConfig(cfg *control.Config) {
c.config = cfg
func (cmd *cfgCmd) setConfig(cfg *control.Config) {
cmd.config = cfg
}

type cliOptions struct {
Expand Down
30 changes: 15 additions & 15 deletions src/control/cmd/dmg/storage_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ type smdQueryCmd struct {
func (cmd *smdQueryCmd) makeRequest(ctx context.Context, req *control.SmdQueryReq, opts ...pretty.PrintConfigOption) error {
req.SetHostList(cmd.getHostList())

cmd.Tracef("smd query request: %+v", req)

resp, err := control.SmdQuery(ctx, cmd.ctlInvoker, req)
if err != nil {
return err // control api returned an error, disregard response
}

cmd.Tracef("smd query response: %+v", resp)

if cmd.JSONOutputEnabled() {
return cmd.OutputJSON(resp, resp.Errors())
}
Expand Down Expand Up @@ -155,21 +159,18 @@ func (cmd *usageQueryCmd) Execute(_ []string) error {
type smdManageCmd struct {
baseCmd
ctlInvokerCmd
hostListCmd
cmdutil.JSONOutputCmd
}

func (cmd *smdManageCmd) makeRequest(ctx context.Context, req *control.SmdManageReq, opts ...pretty.PrintConfigOption) error {
req.SetHostList(cmd.getHostList())

cmd.Tracef("smd manage request: %+v", req)

resp, err := control.SmdManage(ctx, cmd.ctlInvoker, req)
if err != nil {
return err // control api returned an error, disregard response
}

cmd.Tracef("smd managee response: %+v", resp)
cmd.Tracef("smd manage response: %+v", resp)

if cmd.JSONOutputEnabled() {
return cmd.OutputJSON(resp, resp.Errors())
Expand All @@ -195,6 +196,7 @@ type setFaultyCmd struct {

type nvmeSetFaultyCmd struct {
smdManageCmd
singleHostCmd
UUID string `short:"u" long:"uuid" description:"Device UUID to set" required:"1"`
Force bool `short:"f" long:"force" description:"Do not require confirmation"`
}
Expand All @@ -213,6 +215,7 @@ func (cmd *nvmeSetFaultyCmd) Execute(_ []string) error {
Operation: control.SetFaultyOp,
IDs: cmd.UUID,
}
req.SetHostList(cmd.Host.Slice())
return cmd.makeRequest(cmd.MustLogCtx(), req)
}

Expand All @@ -224,9 +227,9 @@ type storageReplaceCmd struct {
// nvmeReplaceCmd is the struct representing the replace nvme storage subcommand
type nvmeReplaceCmd struct {
smdManageCmd
singleHostCmd
OldDevUUID string `long:"old-uuid" description:"Device UUID of hot-removed SSD" required:"1"`
NewDevUUID string `long:"new-uuid" description:"Device UUID of new device" required:"1"`
NoReint bool `long:"no-reint" description:"Bypass reintegration of device and just bring back online."`
}

// Execute is run when storageReplaceCmd activates
Expand All @@ -236,23 +239,18 @@ func (cmd *nvmeReplaceCmd) Execute(_ []string) error {
cmd.Notice("Attempting to reuse a previously set FAULTY device!")
}

// TODO: Implement no-reint flag option
if cmd.NoReint {
return errors.New("NoReint is not currently implemented")
}

req := &control.SmdManageReq{
Operation: control.DevReplaceOp,
IDs: cmd.OldDevUUID,
ReplaceUUID: cmd.NewDevUUID,
ReplaceNoReint: cmd.NoReint,
Operation: control.DevReplaceOp,
IDs: cmd.OldDevUUID,
ReplaceUUID: cmd.NewDevUUID,
}
req.SetHostList(cmd.Host.Slice())
return cmd.makeRequest(cmd.MustLogCtx(), req)
}

type ledCmd struct {
smdManageCmd

hostListCmd
Args struct {
IDs string `positional-arg-name:"ids" description:"Comma-separated list of identifiers which could be either VMD backing device (NVMe SSD) PCI addresses or device UUIDs. All SSDs selected if arg not provided."`
} `positional-args:"yes"`
Expand Down Expand Up @@ -287,6 +285,7 @@ func (cmd *ledIdentifyCmd) Execute(_ []string) error {
}
req.Operation = control.LedResetOp
}
req.SetHostList(cmd.getHostList())
return cmd.makeRequest(cmd.MustLogCtx(), req, pretty.PrintOnlyLEDInfo())
}

Expand All @@ -305,5 +304,6 @@ func (cmd *ledCheckCmd) Execute(_ []string) error {
Operation: control.LedCheckOp,
IDs: cmd.Args.IDs,
}
req.SetHostList(cmd.getHostList())
return cmd.makeRequest(cmd.MustLogCtx(), req, pretty.PrintOnlyLEDInfo())
}
Loading

0 comments on commit 049f710

Please sign in to comment.