ewwhite / zfs-ha

ZFS High-Availability NAS
749 stars 76 forks source link

Dell 1220 and /sys/class/enclosure #31

Closed rbicelli closed 4 years ago

rbicelli commented 4 years ago

First of all, thanks for this beautiful and elegant solution. Using it for my XenServer pool and works great! The only downside is that with Dell MD1220 there's no way to identify drives because /sys/class/enclosure isn't populated. Any clue?

milleroff commented 4 years ago

Hi,

We have several MD1220 enclosures. lsscsi and sas2ircu both show all the needed information. Check the attached screenshots.

md1220_1 md1220_2

rbicelli commented 4 years ago

Thanks, didn't think about sas2ircu. My problems were locating disks.

jasonrm commented 3 years ago

Seems that while the device type is the expected 0x0d, the EncServ bit in the inquiry data isn't set so the scsi_device_enclosure check doesn't think it's supported (as expected, the enclosure is the non-standards compliant one here).

[nix-shell:~/sdled]# sg_inq /dev/sg5
standard INQUIRY:
  PQual=0  Device_type=13  RMB=0  LU_CONG=0  version=0x05  [SPC-3]
  [AERC=0]  [TrmTsk=0]  NormACA=0  HiSUP=1  Resp_data_format=2
  SCCS=0  ACC=0  TPGS=0  3PC=0  Protect=0  [BQue=1]
  EncServ=0  MultiP=1 (VS=0)  [MChngr=0]  [ACKREQQ=0]  Addr16=0
  [RelAdr=0]  WBus16=0  Sync=0  [Linked=0]  [TranDis=0]  CmdQue=0
  [SPI: Clocking=0x0  QAS=0  IUS=0]
    length=66 (0x42)   Peripheral device type: enclosure services device
 Vendor identification: DELL
 Product identification: MD1220
 Product revision level: 1.06

I'm not sure what issues might be encountered long term, but using some hacky string comparisons we can pretend it supports SES.

diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index c2afba2a5..cfb7b6a39 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -620,6 +620,26 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,
    }
 }

+static int ses_device_enclosure(struct scsi_device *sdev)
+{
+   int sde = scsi_device_enclosure(sdev);
+   if (sde)
+       return sde;
+
+   if (sdev->type != TYPE_ENCLOSURE)
+       return 0;
+
+   if (strncmp(sdev->vendor, "DELL ", 5) == 0) {
+       if ((strncmp(sdev->model, "MD1200 ", 7) == 0)
+           || (strncmp(sdev->model, "MD1220 ", 7) == 0)) {
+           sdev_printk(KERN_NOTICE, sdev, "Enclosure supports SES, ignoring EncServ=0 as claimed by the device\n");
+           return 1;
+       }
+   }
+
+   return 0;
+}
+
 static int ses_intf_add(struct device *cdev,
            struct class_interface *intf)
 {
@@ -634,7 +654,7 @@ static int ses_intf_add(struct device *cdev,
    struct enclosure_device *edev;
    struct ses_component *scomp = NULL;

-   if (!scsi_device_enclosure(sdev)) {
+   if (!ses_device_enclosure(sdev)) {
        /* not an enclosure, but might be in one */
        struct enclosure_device *prev = NULL;

@@ -753,7 +773,7 @@ static int ses_intf_add(struct device *cdev,
    /* see if there are any devices matching before
     * we found the enclosure */
    shost_for_each_device(tmp_sdev, sdev->host) {
-       if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev))
+       if (tmp_sdev->lun != 0 || ses_device_enclosure(tmp_sdev))
            continue;
        ses_match_to_enclosure(edev, tmp_sdev, 0);
    }
@@ -824,7 +844,7 @@ static void ses_intf_remove(struct device *cdev,
 {
    struct scsi_device *sdev = to_scsi_device(cdev->parent);

-   if (!scsi_device_enclosure(sdev))
+   if (!ses_device_enclosure(sdev))
        ses_intf_remove_component(sdev);
    else
        ses_intf_remove_enclosure(sdev);
-- 
2.31.1

With that patch in place, tools like sdled/encled work. Although with multipath, the dev name isn't correct for the second connected controller, but the LED status is correct. (edit: looks like device detachment updates correctly, new attachments aren't picked up. Can't tell if it's my setup/kernel/etc, or the non-standard SES implementation being forced into service.)

[nix-shell:~/sdled]# python ./encled
ENCLOSURE/SLOT  DEV     FAULT_LED       LOCATION_LED
----------------------------------------------------
0:0:2:0/Slot 5  ----    fault_off       locate_off
0:0:2:0/Slot 6  sdc      FAULT_ON       locate_off
0:0:2:0/Slot 13 ----    fault_off       locate_off
0:0:2:0/Slot 12 sdd     fault_off        LOCATE_ON
[--snip--]
4:0:2:0/Slot 5  ----    fault_off       locate_off
4:0:2:0/Slot 6  ----     FAULT_ON       locate_off
4:0:2:0/Slot 13 ----    fault_off       locate_off
4:0:2:0/Slot 12 ----    fault_off        LOCATE_ON
[--snip--]