Add SCSI target option and detailed scsiinfo for FC and SAS hba#208
Add SCSI target option and detailed scsiinfo for FC and SAS hba#208vashanmu wants to merge 6 commits intooracle-samples:mainfrom
Conversation
Signed-off-by: Rajan Shanmugavelu <rajan.shanmugavelu@oracle.com
Signed-off-by: Rajan <rajan.shanmugavelu@oracle.com>
brenns10
left a comment
There was a problem hiding this comment.
Thanks! A few tweaks here. The major ones are:
- I'd prefer everything stay in the
scsi.pyfile. - Please use
print_dictionary()where possible. - For functions which don't return a value, there's no need to put a
returnstatement at the end of the function.
drgn_tools/lpfcinfo.py
Outdated
| else: | ||
| print("Need to fetch standard queue data") | ||
|
|
||
| print("-" * 110) |
There was a problem hiding this comment.
I have a slight preference that these sorts of separators should be printed in the caller of this function. This function is named print_lpfc_shost_info() which indicates it's just printing info for a single item. If it's going to be called several times to print multiple items, I'd argue that the caller should be printing separators. That ensures that a new user of this function doesn't automatically get a separator they don't need.
drgn_tools/lpfcinfo.py
Outdated
| print("Need to fetch standard queue data") | ||
|
|
||
| print("-" * 110) | ||
| return |
There was a problem hiding this comment.
Explicit return statements at the end of a function returning None should be omitted.
drgn_tools/scsi.py
Outdated
| def print_scsi_target(prog: Program): | ||
| table = FixedTable( | ||
| header=[ | ||
| "Target Device", | ||
| "scsi_target", | ||
| "Channel", | ||
| "Id", | ||
| "Status", | ||
| "Busy", | ||
| "Blocked", | ||
| ] | ||
| ) | ||
|
|
||
| for shost in for_each_scsi_host(prog): | ||
| if shost.__targets.next != shost.__targets.next.next: | ||
| print_shost_header(shost) | ||
| for target in for_each_scsi_target(shost): | ||
| if has_member(target, "target_busy"): | ||
| tbusy = target.target_busy.counter.value_() | ||
| else: | ||
| tbusy = -1 | ||
|
|
||
| table.row( | ||
| target.dev.kobj.name.string_().decode(), | ||
| hex(target.value_()), | ||
| target.channel.value_(), | ||
| target.id.value_(), | ||
| target.state.format_(type_name=False), | ||
| tbusy, | ||
| target.target_blocked.counter.value_(), | ||
| ) | ||
| table.write() | ||
|
|
||
| print("-" * 110) | ||
| return |
There was a problem hiding this comment.
Rather than having one big table, it looks like you're trying to print a table of targets for each host which has targets. So I would suggest:
- Create a new table for each host. This means the table header is printed every time you print a new set of targets, without you needing to fiddle with printing headers manually.
- I'd suggest that you not directly test whether or not the linked list is empty, for two reasons. (1) the name of the linked list node (or even the way that targets are held in a list) might change between kernel versions. You already have a function
for_each_scsi_target()that knows how to iterate over targets, so rather than leaking that knowledge into this function, you can just detect whether it returned items. This makes the code easier to maintain as the kernel changes. - Switch to
Tablerather thanFixedTablehere. That way rows are buffered, and you can detect whether the table has any rows, and only print the header / table when it has rows. - Finally, as always I suggest removing the explicit return.
Here's how I would recommend writing it:
| def print_scsi_target(prog: Program): | |
| table = FixedTable( | |
| header=[ | |
| "Target Device", | |
| "scsi_target", | |
| "Channel", | |
| "Id", | |
| "Status", | |
| "Busy", | |
| "Blocked", | |
| ] | |
| ) | |
| for shost in for_each_scsi_host(prog): | |
| if shost.__targets.next != shost.__targets.next.next: | |
| print_shost_header(shost) | |
| for target in for_each_scsi_target(shost): | |
| if has_member(target, "target_busy"): | |
| tbusy = target.target_busy.counter.value_() | |
| else: | |
| tbusy = -1 | |
| table.row( | |
| target.dev.kobj.name.string_().decode(), | |
| hex(target.value_()), | |
| target.channel.value_(), | |
| target.id.value_(), | |
| target.state.format_(type_name=False), | |
| tbusy, | |
| target.target_blocked.counter.value_(), | |
| ) | |
| table.write() | |
| print("-" * 110) | |
| return | |
| def print_scsi_target(prog: Program) -> None: | |
| for shost in for_each_scsi_host(prog): | |
| table = Table( | |
| header=[ | |
| "Target Device", | |
| "scsi_target", | |
| "Channel", | |
| "Id", | |
| "Status", | |
| "Busy", | |
| "Blocked", | |
| ] | |
| ) | |
| for target in for_each_scsi_target(shost): | |
| if has_member(target, "target_busy"): | |
| tbusy = target.target_busy.counter.value_() | |
| else: | |
| tbusy = -1 | |
| table.row( | |
| target.dev.kobj.name.string_().decode(), | |
| hex(target.value_()), | |
| target.channel.value_(), | |
| target.id.value_(), | |
| target.state.format_(type_name=False), | |
| tbusy, | |
| target.target_blocked.counter.value_(), | |
| ) | |
| if table.rows: | |
| print_shost_header(shost) | |
| table.write() |
There was a problem hiding this comment.
Makes sense, will add this change.
|
|
||
| name = "scsiinfo" | ||
|
|
||
| debuginfo_kmods = ["sd_mod"] |
There was a problem hiding this comment.
I'd suggest adding megaraid_sas to this list. That way, if the megaraid_sas kernel module is loaded, yet debuginfo is unavailable for it, then corelens will detect this and raise an informative error for you.
There was a problem hiding this comment.
Added megaraid_sas, qla2xxx and lpfc in the list for debug info_kmods.
Orabug: 39122042 Signed-off-by: Rajan Shanmugvelu <rajan.shanmugavelu@oracle.com>
vashanmu
left a comment
There was a problem hiding this comment.
Made the recommended changes.
- included all changes in one file (scsi.py)
- used print_dictionary() instead of separate print()
- removed table.write() and added module 'megaraid_sas', 'qla2xxx' and 'lpfc' to the debuginfo_kmods list.
75fad41 to
92da9d2
Compare
Added 2 commits.
This give detailed scsi host adapter information for QLogic, Emulex and LSI megaraid_sas hba.
This shows target details both local and remote ports (SAS, FibreChannel)