diff --git a/lib/enclosure.go b/lib/enclosure.go new file mode 100644 index 0000000..0b64298 --- /dev/null +++ b/lib/enclosure.go @@ -0,0 +1,15 @@ +package sastopo + +func (d *Device) updateEnclosureSerial() error { + switch d.Model { + case "SA4600": + default: + sn, err := vpd80(d.ID) + if err != nil { + return err + } + d.Serial = sn + } + + return nil +} diff --git a/lib/error.go b/lib/error.go new file mode 100644 index 0000000..9a391dc --- /dev/null +++ b/lib/error.go @@ -0,0 +1,9 @@ +package sastopo + +import "fmt" + +type errUnknownType struct{ Msg string } + +func (e *errUnknownType) Error() string { + return fmt.Sprintf("unknown device type: %s", e.Msg) +} diff --git a/lib/hba.go b/lib/hba.go new file mode 100644 index 0000000..f7bf3de --- /dev/null +++ b/lib/hba.go @@ -0,0 +1,7 @@ +package sastopo + +// HBA is a PCI SAS Host-bus Adapter +type HBA struct { + PciID string + Slot string +} diff --git a/lib/sg.go b/lib/sg.go index d49e20d..0d9a07d 100644 --- a/lib/sg.go +++ b/lib/sg.go @@ -1,4 +1,4 @@ -package scsi +package sastopo import ( "os" @@ -23,6 +23,10 @@ type Device struct { Vendor string Rev string SasAddress string + Serial string + Slot int + Enclosure *Device + HBA *HBA } func itob(i int) bool { @@ -61,6 +65,26 @@ func (d *Device) updateSysfsAttrs() error { return nil } +func (d *Device) updateDriveSerial() error { + return nil +} + +func (d *Device) updateSerial() error { + switch d.Type { + case 0: + if err := d.updateDriveSerial(); err != nil { + return err + } + case 13: + if err := d.updateEnclosureSerial(); err != nil { + return err + } + default: + return &errUnknownType{"dev: /dev/sg" + strconv.Itoa(d.ID) + " type: " + strconv.Itoa(d.Type)} + } + return nil +} + // SgDevices returns map[int]Device of all SG devices func SgDevices(sgDevicesPath string) (map[int]*Device, error) { var devices = map[int]*Device{} @@ -91,6 +115,9 @@ func SgDevices(sgDevicesPath string) (map[int]*Device, error) { if err := devices[ID].updateSysfsAttrs(); err != nil { return devices, err } + if err := devices[ID].updateSerial(); err != nil { + return devices, err + } } err = file.Close() diff --git a/lib/sg_test.go b/lib/sg_test.go index b22816c..70c2712 100644 --- a/lib/sg_test.go +++ b/lib/sg_test.go @@ -1,4 +1,4 @@ -package scsi +package sastopo import "testing" diff --git a/lib/vpd.go b/lib/vpd.go new file mode 100644 index 0000000..c35f4c2 --- /dev/null +++ b/lib/vpd.go @@ -0,0 +1,23 @@ +package sastopo + +import ( + "io" + "os" + "strconv" +) + +func vpd80(sg int) (string, error) { + file, err := os.Open("/sys/class/scsi_generic/sg" + strconv.Itoa(sg) + "/device/vpd_pg80") + defer file.Close() + if err != nil { + return "", err + } + line := make([]byte, 128) + n, err := file.ReadAt(line, 4) + if err != nil && err != io.EOF { + return "", err + } else if n == 0 { + return "", nil + } + return string(line[:n]), nil +}