Skip to content
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
39 changes: 28 additions & 11 deletions pkg/domain/entities/physicaldrive/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type (
PhysicalDrive struct {
*Metadata // Metadata of the disk

ID string `json:"id,omitempty"` // ID
Slot *Slot `json:"slot,omitempty"` // Slot
Vendor string `json:"vendor,omitempty"` // Vendor
Model string `json:"model,omitempty"` // Model
Serial string `json:"serial,omitempty"` // Serial number
Expand All @@ -28,6 +28,7 @@ type (
JBOD bool `json:"jbod,omitempty"` // Is the disk in JBOD mode
Status PDStatus `json:"status,omitempty"` // State (e.g.: Online, Offline, Failed)
Reason string `json:"reason,omitempty"` // Reason for the disk state
DevicePath string `json:"device_path,omitempty"` // Device path of the disk
PermanentPath string `json:"permanent_path,omitempty"` // Permanent path of the array (e.g.: /dev/disk/by-id/...)
}

Expand All @@ -41,8 +42,7 @@ type (
// Metadata represents the metadata of a physical drive.
Metadata struct {
CtrlMetadata *raidcontroller.Metadata `json:"controller_metadata,omitempty"` // Controller metadata of the disk
DevicePath string `json:"device_path,omitempty"` // Device path of the disk
Slot *Slot `json:"slot,omitempty"` // Slot
ID string `json:"id,omitempty"` // ID
}
)

Expand Down Expand Up @@ -133,16 +133,33 @@ func (m *Metadata) Validate() error {
return errors.Wrap(err, "controller metadata is invalid")
}

// Detailed validation of the slot is done in each adapter
// as the validation rules may vary between different adapters
// Some fields may be optional or mandatory depending on the adapter
if m.Slot == nil {
return errors.New("slot is nil")
if m.ID == "" {
return errors.New("ID is empty")
}

if m.Slot.String() == emptySlot {
return errors.New("slot is empty")
return nil
}

// ParseSlot parses a string into a Slot instance.
func ParseSlot(slot string) (*Slot, error) {
if slot == "" {
return nil, errors.New("slot is empty")
}

return nil
res := &Slot{}

parts := strings.Split(slot, ":")
if len(parts) > 3 { //nolint:mnd // just the number of parts
return nil, errors.New("invalid slot format (too many parts)")
}

if len(parts) > 2 { //nolint:mnd // just the number of parts
res.Port, parts = parts[0], parts[1:]
}
if len(parts) > 1 {
res.Enclosure, parts = parts[0], parts[1:]
}
res.Bay = parts[0]

return res, nil
}
6 changes: 2 additions & 4 deletions pkg/implementation/blinker/ssacli.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,18 @@ func (s *SSACLI) StopBlink(metadata *physicaldrive.Metadata) error {

// blink makes a physical drive blink.
func (s *SSACLI) blink(metadata *physicaldrive.Metadata, action string) error {
slot := metadata.Slot.Format()

args := []string{
"controller",
"slot=" + strconv.Itoa(metadata.CtrlMetadata.ID),
"physicaldrive",
slot,
metadata.ID,
"modify",
"led=" + action,
}

_, err := s.SSACLI.Run(args)
if err != nil {
return errors.Wrapf(err, "failed to blink physical drive %s", slot)
return errors.Wrapf(err, "failed to blink physical drive %s", metadata.ID)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/implementation/commandrunner/ssacli.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/pkg/errors"
)

const SSACLIPath = "/opt/hp/hp_ssacli/bin/hp_ssacli"
const SSACLIPath = "ssacli"

type SSACLI struct {
cliPath string
Expand Down
2 changes: 1 addition & 1 deletion pkg/implementation/logicalvolumegetter/mdadm.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (m *MDADM) LogicalVolume(

for _, device := range details[0].Devices {
logicalVolume.PDrivesMetadata = append(logicalVolume.PDrivesMetadata, &physicaldrive.Metadata{
DevicePath: device.Path,
ID: device.Path,
// FIXME Add a const in the controller metadata to identify the controller
CtrlMetadata: metadata.CtrlMetadata,
})
Expand Down
7 changes: 2 additions & 5 deletions pkg/implementation/logicalvolumegetter/ssacli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package logicalvolumegetter

import (
"fmt"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -254,12 +255,8 @@ func extractInfoFromConfig(

// Create the PhysicalDrive metadata
pDriveMetadata := &physicaldrive.Metadata{
ID: fmt.Sprintf("%s:%s:%s", matches[1], matches[2], matches[3]),
CtrlMetadata: logicalVolume.CtrlMetadata,
Slot: &physicaldrive.Slot{
Port: matches[1],
Enclosure: matches[2],
Bay: matches[3],
},
}

pDrivesMetadata = append(pDrivesMetadata, pDriveMetadata)
Expand Down
16 changes: 8 additions & 8 deletions pkg/implementation/logicalvolumemanager/mdadm.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (m *MDADM) CreateLV(request *logicalvolume.Request) (*logicalvolume.Logical
for _, drive := range request.PDrivesMetadata {
physicalDrive, err := m.PhysicalDrive(drive)
if err != nil {
return nil, errors.Wrapf(err, "failed to get physical drive : %s", drive.DevicePath)
return nil, errors.Wrapf(err, "failed to get physical drive : %s", drive.ID)
}

if physicalDrive.Status == physicaldrive.PDStatusFailed {
Expand All @@ -50,7 +50,7 @@ func (m *MDADM) CreateLV(request *logicalvolume.Request) (*logicalvolume.Logical
return nil, errors.New("cannot create a logical volume with a used physical drive")
}

physicalDrivesName = append(physicalDrivesName, drive.DevicePath)
physicalDrivesName = append(physicalDrivesName, drive.ID)
}

devicePath := fmt.Sprintf("%s/%s", baseMDPath, request.Name)
Expand Down Expand Up @@ -107,13 +107,13 @@ func (m *MDADM) DeleteLV(metadata *logicalvolume.Metadata) error {
for _, device := range logicalVolume.PDrivesMetadata {
// Remove the superblock of the device
_, err = m.MDADM.Run([]string{
"--zero-superblock", device.DevicePath,
"--zero-superblock", device.ID,
})
if err != nil {
return errors.Wrapf(
err,
"failed to run mdadm zero superblock command on physical drive: %s",
device.DevicePath,
device.ID,
)
}
}
Expand Down Expand Up @@ -146,15 +146,15 @@ func (m *MDADM) AddPDsToLV(

if physicalDrive.Status == physicaldrive.PDStatusFailed {
return errors.Errorf(
"cannot add a failed physical drive to a logical volume : %s ", physicalDrive.DevicePath,
"cannot add a failed physical drive to a logical volume : %s ", physicalDrive.ID,
)
} else if physicalDrive.Status == physicaldrive.PDStatusUsed {
return errors.Errorf(
"cannot add a used physical drive to a logical volume : %s", physicalDrive.DevicePath,
"cannot add a used physical drive to a logical volume : %s", physicalDrive.ID,
)
}

devicesPaths = append(devicesPaths, pdMetadata.DevicePath)
devicesPaths = append(devicesPaths, pdMetadata.ID)
}

if logicalVolume.RAIDLevel == logicalvolume.RAIDLevel10 ||
Expand Down Expand Up @@ -240,7 +240,7 @@ func (m *MDADM) DeletePDsFromLV(

pdsDevicePaths := make([]string, 0, len(pdsMetadata))
for _, pdMetadata := range pdsMetadata {
pdsDevicePaths = append(pdsDevicePaths, pdMetadata.DevicePath)
pdsDevicePaths = append(pdsDevicePaths, pdMetadata.ID)
}

// Prepare the mdadm fail command
Expand Down
Loading