logicalvolumegetter: add storcli2 logical volume getter#61
Conversation
Implement ports.LogicalVolumesGetter for storcli2 / perccli2, mirroring the ssacli getter and the megaraid v1 virtual-drive parsing. LogicalVolumes() reads every virtual drive from a single "/cN/vall show all" call; LogicalVolume() reads one via its "/cN/vM" selector, with a not-found guard on an empty list (an out-of-range VD is a command-level failure payload surfaced by storcli2.Decode). Each "Virtual Drives" entry maps to a LogicalVolume: the ID is the VD half of the "DG/VD" pair, TYPE feeds logicalvolume.RAIDLevelMap, and size goes through utils.ConvertSizeBytes. The VD state mapping follows the StorCLI2 User Guide v1.1 legend (Rec/OfLn/Pdgd/Dgrd/Optl): Optl is optimal, Dgrd, Pdgd and Rec (recovery) are degraded, and OfLn — the documented terminal state — is failed; storcli1's "Fail" is kept as a defensive guard and unknown states soft-fail to LVStatusUnknown so newer firmware does not break inventory. Per the same guide, showing a nonexistent object reports success, so an absent "Virtual Drives" section is an empty inventory (the zero-VD, all-JBOD deployment this adapter targets), not an error. CurrentCache is parsed as comma-separated tokens (e.g. "NR,WB") — unlike storcli1's concatenated form — with unknown tokens leaving the corresponding policy unknown. Paths come from the VD properties: "OS Drive Name" is the device path and "SCSI NAA Id" forms the /dev/disk/by-id/wwn-0x permanent path, lowercased because udev links are lowercase hex while the firmware is case-inconsistent across sections. Backing drives become PDrivesMetadata entries keyed by "EID:Slt", consistent with the physical-drive getter. Verified against a live MegaRAID 9660-16i (24-VD fixture set). One implementation serves both binaries through the injected commandrunner.CommandRunner. Section structs live in the getter file and consume the shared storcli2.Decode + utils.UnmarshalToSlice.
|
|
||
| return arguments.Get(0).([]byte), arguments.Error(1) | ||
| } | ||
|
|
There was a problem hiding this comment.
This MockCommandRunner duplicates the one in mock_test.go (which lives in package logicalvolumegetter_test). The internal package is needed here for testing unexported helpers, so the duplication is structurally unavoidable without refactoring mock_test.go to also be in package logicalvolumegetter — which would break the existing ssacli/mdadm tests. Noting it as tech debt rather than a blocker since physicaldrivegetter has the same pattern.
— Claude Code
|
LGTM — clean implementation that follows existing adapter patterns well. |
What
Implements
ports.LogicalVolumesGetterfor storcli2 / perccli2 (logicalvolumegetter/storcli2.go), mirroring the ssacli getter and the megaraid v1 virtual-drive parsing.How
LogicalVolumes(ctrl)→ a single/cN/vall show all;LogicalVolume(meta)→/cN/vM show all, with a not-found guard on an empty list (an out-of-range VD is a command-level failure payload surfaced bystorcli2.Decode).Virtual Drivesentry maps to aLogicalVolume:DG/VDpair;TYPE→logicalvolume.RAIDLevelMap.Rec|OfLn|Pdgd|Dgrd|Optl):Optl→ optimal;Dgrd/Pdgd/Rec(recovery) → degraded;OfLn— the documented terminal state — → failed. storcli1'sFailis kept as a defensive guard; unknown states soft-fail toLVStatusUnknownso newer firmware does not break inventory.CurrentCacheparsed as comma-separated tokens (e.g.NR,WB) — unlike storcli1's concatenated form — with unknown tokens leaving the corresponding policy unknown.OS Drive Name→DevicePath;SCSI NAA Id→/dev/disk/by-id/wwn-0x…permanent path, lowercased because udev links are lowercase hex while the firmware is case-inconsistent across sections (the same SAS address appears as0x…/0X…depending on the section).PDrivesMetadatakeyed byEID:Slt, consistent with the physical-drive getter.utils.ConvertSizeBytes. Error wraps carry the controller ID and the failingDG/VD, matching the physical-drive getter.Virtual Drivessection is an empty inventory (the all-JBOD deployment this adapter targets), not an error.commandrunner.CommandRunner. Section structs live in the getter file and consume the sharedstorcli2.Decode+utils.UnmarshalToSlice.Tests
Table-driven
storcli2_test.goagainst real server captures from aMegaRAID 9660-16i(24-VD inventory, single VDs, invalid-VD failure payload withInvalid VD number). Cases: full inventory (first VD asserted field-by-field), single VD (nominal / invalid), empty-list and absent-section guards, empty zero-VD inventory, and unit tables for VD-state mapping (includingOfLn/Ofln/Rec), cache-token parsing,DG/VDparsing and permanent-path building (including the lowercase normalization).