Skip to content

Commit

Permalink
Add support for smartpqi/arcconf RAID adapters on Linux
Browse files Browse the repository at this point in the history
The smartpqi driver for Adaptec/Microsemi RAID controllers uses a cli
tool called `arcconf`.  Add support modeled after the existing
MegaRAID/storcli structures and implement the RAID Controller interface
introduced to abstract the specific RAID adapter for the linux system.

- Did not implement the Caching mechansim, repeated invocations do not
have any significant impact on system, 5 minute timeout seems quite long
to wait for RAID device changes which happen immediately after issuing
arcconf commands.

- Refactored how linux package looks up disks to see if they belong to
a RAID adapter to prevent import loops.

- Added tests for arcconf for the interface commands parsing output
collected from systems with smartpqi driver and card

- Added smartpqi to the demo program

Signed-off-by: Ryan Harper <ryaharpe@cisco.com>
  • Loading branch information
raharper committed Feb 14, 2024
1 parent a6012d5 commit eabe011
Show file tree
Hide file tree
Showing 11 changed files with 1,991 additions and 4 deletions.
1 change: 1 addition & 0 deletions demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func main() {
Commands: []*cli.Command{
&diskCommands,
&megaraidCommands,
&smartpqiCommands,
&lvmCommands,
&miscCommands,
},
Expand Down
117 changes: 117 additions & 0 deletions demo/smartpqi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package main

import (
"encoding/json"
"fmt"
"strconv"

"github.com/urfave/cli/v2"
"machinerun.io/disko/smartpqi"
)

//nolint:gochecknoglobals
var smartpqiCommands = cli.Command{
Name: "smartpqi",
Usage: "smartpqi / arcconf commands",
Subcommands: []*cli.Command{
{
Name: "dump",
Usage: "Dump information about smartpqi",
Action: smartpqiDump,
},
{
Name: "disk-summary",
Usage: "Show information about virtual devices on system",
Action: smartpqiDiskSummary,
},
{
Name: "list-controllers",
Usage: "Show the discovered controller IDs",
Action: smartpqiListControllers,
},
},
}

func smartpqiListControllers(c *cli.Context) error {
arc := smartpqi.ArcConf()
ctrls, err := arc.List()
if err != nil {
return fmt.Errorf("failed to list controllers: %s", err)
}

fmt.Printf("Found %d controllers.", len(ctrls))
for _, cID := range ctrls {
fmt.Printf("Controller ID: %d\n", cID)
}
return nil
}

func smartpqiDiskSummary(c *cli.Context) error {
var err error
var ctrlNum = 1
var ctrlArg = c.Args().First()

if ctrlArg != "" {
ctrlNum, err = strconv.Atoi(ctrlArg)
if err != nil {
return fmt.Errorf("could not convert to integer: %s", err)
}
}

arc := smartpqi.ArcConf()
ctrl, err := arc.Query(ctrlNum)

if err != nil {
return err
}

data := [][]string{{"Path", "Name", "DiskType", "RAID"}}

for _, ld := range ctrl.LogicalDrives {
stype := "HDD"

if ld.IsSSD() {
stype = "SSD"
}

name := ld.Name
if ld.Name == "" {
name = fmt.Sprintf("logicalid-%d", ld.ID)
}

data = append(data, []string{ld.DiskName, name, stype, ld.RAIDLevel})
}

printTextTable(data)

return nil
}

func smartpqiDump(c *cli.Context) error {
var err error
var ctrlNum = 1
var ctrlArg = c.Args().First()

if ctrlArg != "" {
ctrlNum, err = strconv.Atoi(ctrlArg)
if err != nil {
return fmt.Errorf("could not convert to integer: %s", err)
}
}

arc := smartpqi.ArcConf()
ctrl, err := arc.Query(ctrlNum)

if err != nil {
return err
}

jbytes, err := json.MarshalIndent(&ctrl, "", " ")
if err != nil {
return err
}

fmt.Printf("%s\n", string(jbytes))

return nil
}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ require (
github.com/stretchr/testify v1.8.2
github.com/urfave/cli/v2 v2.25.3
golang.org/x/sys v0.8.0
machinerun.io/disko v0.0.13 // indirect
)
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -634,8 +634,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
machinerun.io/disko v0.0.13 h1:1kkOorxGvLprdTSksh7fOsNK0WZ0Lq+4/ZQgPeuXnsY=
machinerun.io/disko v0.0.13/go.mod h1:qorFih3sB8bmNcHWHyjXujgYfaugOjHj+s2GdK33+lk=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
1 change: 1 addition & 0 deletions linux/raidcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type RAIDControllerType string

const (
MegaRAIDControllerType RAIDControllerType = "megaraid"
SmartPqiControllerType RAIDControllerType = "smartpqi"
)

type RAIDController interface {
Expand Down
2 changes: 2 additions & 0 deletions linux/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"golang.org/x/sys/unix"
"machinerun.io/disko"
"machinerun.io/disko/megaraid"
"machinerun.io/disko/smartpqi"
)

type linuxSystem struct {
Expand All @@ -24,6 +25,7 @@ func System() disko.System {
return &linuxSystem{
raidctrls: []RAIDController{
megaraid.CachingStorCli(),
smartpqi.ArcConf(),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion megaraid/linux.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package megaraid

const sysDriverMegaRaidSAS = "/sys/bus/pci/drivers/megaraid_sas"
const SysfsPCIDriversPath = "/sys/bus/pci/drivers/megaraid_sas"
Loading

0 comments on commit eabe011

Please sign in to comment.