SES: Report additional LED states#277
Conversation
|
@tasleson could you please take a look? I have no experience with SES |
|
And probably you don't have experience either, but I have to ask :) |
|
@mtkaczyk Investigating |
|
@cjs-nexsan Thanks for the PR, some comments. Priority orderThis PR checks Because the array slot and byte 2/3 blocks are gated by With a single flat Element type guardThe PR adds: element_type ele_type = sp->page1_types[0].element_type;and gates the array_slot_control checks with ele_type == SES_ARRAY_DEVICE_SLOT. The intent is correct, SES-4 defines byte 1 differently for Device Slot vs Array Device Slot elements. However, page1_types[0] always reads the first type descriptor, not the type for the given idx. If the enclosure has multiple element types before the slot entries, this would check the wrong type. An alternative approach is to skip the guard entirely. The write path (ses_write_msg) already zeroes array_slot_control StructureThe three separate if blocks (with the second and third re-checking *led_status == LED_IBPI_PATTERN_NORMAL) are StyleC++ style comments (//) — the rest of ses.c uses C style (/* */). If this passes check patch, I don't have issues with it. Alternative implementation for comparison static void get_led_status(struct ses_pages *sp, int idx, enum led_ibpi_pattern *led_status)
{
struct ses_slot_ctrl_elem *descriptors = (void *)(sp->page2.buf + 8);
struct ses_slot_ctrl_elem *desc_element = NULL;
descriptors++;
desc_element = &descriptors[idx];
*led_status = LED_IBPI_PATTERN_NORMAL;
/*
* SES supports multiple simultaneous status bits. Check in priority
* order with standard IBPI patterns first, followed by SES-specific
* patterns. Byte 1 bit positions are the same in both pages for
* Array Device Slot elements. Bytes 2-3 differ: RQST ACTIVE and
* RQST MISSING have no status-page equivalents (SES-4 Tables 83/84).
*/
/* Compound state: LOCATE + FAULT */
if ((desc_element->b2 & 0x02) && (desc_element->b3 & 0x60))
*led_status = LED_IBPI_PATTERN_LOCATE_AND_FAIL;
/* Standard IBPI patterns - highest priority first */
else if (desc_element->b3 & 0x60)
*led_status = LED_IBPI_PATTERN_FAILED_DRIVE;
else if (desc_element->common_control & 0x40)
*led_status = LED_IBPI_PATTERN_PFA;
else if (desc_element->array_slot_control & 0x04)
*led_status = LED_IBPI_PATTERN_FAILED_ARRAY;
else if (desc_element->array_slot_control & 0x02)
*led_status = LED_IBPI_PATTERN_REBUILD;
else if (desc_element->array_slot_control & 0x08)
*led_status = LED_IBPI_PATTERN_DEGRADED;
else if (desc_element->array_slot_control & 0x20)
*led_status = LED_IBPI_PATTERN_HOTSPARE;
else if (desc_element->b2 & 0x02)
*led_status = LED_IBPI_PATTERN_LOCATE;
/* SES-specific patterns */
else if (desc_element->array_slot_control & 0x01)
*led_status = LED_SES_REQ_ABORT;
else if (desc_element->array_slot_control & 0x10)
*led_status = LED_SES_REQ_CONS_CHECK;
else if (desc_element->array_slot_control & 0x40)
*led_status = LED_SES_REQ_RSVD_DEV;
else if (desc_element->b2 & 0x04)
*led_status = LED_SES_REQ_RM;
else if (desc_element->b2 & 0x08)
*led_status = LED_SES_REQ_INS;
else if (desc_element->b2 & 0x40)
*led_status = LED_SES_REQ_DNR;
else if (desc_element->b3 & 0x04)
*led_status = LED_SES_REQ_EN_BB;
else if (desc_element->b3 & 0x08)
*led_status = LED_SES_REQ_EN_BA;
else if (desc_element->b3 & 0x10)
*led_status = LED_SES_REQ_DEV_OFF;
} |
|
@tasleson Thanks for considering this PR and the detailed review. I've replied to your points with some explanation/comments below, but I might well have misinterpeted/misunderstood something - I appreciate any further feedback you might have.
There were two reasons for the suggested ordering:
Locate is a specific user-initiated action versus the autonomous OS usage of the drive/slot, and there may be reasons to want to identify one specific drive/slot regardless of its usage, so locate being the highest-priority state seems appropriate, as well as maintaining the current behaviour and being consistent with the npem ordering (unless I've misinterpreted that). This also ensures that both Array Device Slot and Device Slot enclosures behave similarly for all non-SES-specific states they support (Device Slot enclosures will just not indicate or report array-specific states if the application tries to set them).
The SES specification requires Array Device Slot and/or Device Slot elements to be listed before any other element types. As I understand the code, ses_get_slots() returns after finding the first element type that matches either Array Device Slot or Device Slot; even if both types were present, only elements of the first listed type would be discovered/reported by ledmon - so types[0] will always be correct.
I believe the type guard is required, as "ledmon" supports both Device Slot and Array Device Slot elements. For Device Slot elements, byte 1 is reserved on control, but defined as "Slot Address" with vendor-specific content in status - i.e. any bits could be set on any/all slots in a vendor-unique way, so interpreting them in get_led_status() could report the incorrect state.
The separate blocks were mostly to avoid excessive repetitive "((ele_type == SES_ARRAY_DEVICE_SLOT) && ...)" conditions with splitting up the three classes of states (device/slot, array, SES) as a side benefit, but if you think a flat if/else chain would be clearer, that's fine.
This did pass check patch, but should have been kept consistent with the rest of the file - I can change that along with the structure. |
|
@tasleson I've pushed a commit to address most of your comments. The only functional change is to explicitly pass the element type into get_led_status(), but I've also flattened the if/else chain and added your comment block (slightly modified). I've not changed the priority order pending further feedback. As a specific observation about your proposed order: |
@cjs-nexsan Thanks for the updates, initial review looks good, I'll want to scrutinize it a bit more before merge. I think the only open question is the ordering priority. I can see advantages and disadvantages of either approach. I would like @mtkaczyk to respond with their thoughts. If we look at the project history, keeping behavior that same has been maintained, thus I'm guessing that we will go with what you have in this PR. |
Yes, please let stay with the current behavior, it is lower risk. |
|
I'm not familiar with the automated checks on GitHub (or this project in particular). I believe all of the reported issues have been addressed, but it is still reporting "PR run failed", and the "Files changed" tab still shows the outdated check failures that have been addressed in the later commits. Is there some action I need to take to clear these and/or otherwise make this PR acceptable? |
You are using model of pushing fixes to new patches. That is usually correct unless specific project has per commit validation (like we have here) - commit title, commit message and commit body- all validated. In our case, this is a result of years of integration with linux kernel, that is why we are requesting the same style and following similar rules. Please squash this to one meaningful commit and push with force :) That is generally the way! |
2765e2a to
e3cfd9a
Compare
|
Thanks for clarifying - I have squashed and force-pushed the commit, so hopefully it is now correct. Apologies for the multiple changes getting this PR into shape. |
tasleson
left a comment
There was a problem hiding this comment.
This PR looks good. However, after reviewing and looking at npem, I have a question about the differences between the two which I've opened up an issue for discussion, here #282
I think we can commit this and then address that issue and make any changes in a new PR.
|
@cjs-nexsan Please re-base changes |
Report the LED states for SES enclosures that can be configured using ses_set_message(). SES supports multiple simultaneous status bits. Check in priority order with standard IBPI patterns first, followed by SES-specific patterns. Signed-off-by: Chris Smith <csmith@nexsan.com>
f175a03 to
0a833ce
Compare
Issue:
The LED states reported from SES enclosures only support the LOCATE, LOCATE_AND_FAIL, and FAILURE patterns; all other states are reported as NORMAL. As "ledctl" compares the requested state against the current reported state, this also makes it impossible to reset an SES slot to the NORMAL state if any other state has been configured - e.g. the following sequence will leave the slot set to the REBUILD pattern:
Cause:
The SES get_led_status() function only checks three bits in the element status (IDENT, FAULT SENSED, and FAULT REQSTD).
Solution:
Check additional element status bits that can be configured via ses_set_message() and return the appropriate state. As SES supports multiple simultaneous status bits, check the bits in priority order, starting with standard IBPI patterns in the same order as "ibpi_to_npem_capability", followed by SES-specific patterns.