Skip to content

Add SCSI target option and detailed scsiinfo for FC and SAS hba#208

Open
vashanmu wants to merge 6 commits intooracle-samples:mainfrom
vashanmu:main
Open

Add SCSI target option and detailed scsiinfo for FC and SAS hba#208
vashanmu wants to merge 6 commits intooracle-samples:mainfrom
vashanmu:main

Conversation

@vashanmu
Copy link
Copy Markdown
Contributor

@vashanmu vashanmu commented Mar 23, 2026

Added 2 commits.

  • Add SCSI host verbose info for qla2xxx, lfpc and megaraid_sas HBA

This give detailed scsi host adapter information for QLogic, Emulex and LSI megaraid_sas hba.

  • Add SCSI target option to list all SCSI host remote targets

This shows target details both local and remote ports (SAS, FibreChannel)

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Mar 23, 2026
Copy link
Copy Markdown
Member

@brenns10 brenns10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! A few tweaks here. The major ones are:

  • I'd prefer everything stay in the scsi.py file.
  • Please use print_dictionary() where possible.
  • For functions which don't return a value, there's no need to put a return statement at the end of the function.

else:
print("Need to fetch standard queue data")

print("-" * 110)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

print("Need to fetch standard queue data")

print("-" * 110)
return
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicit return statements at the end of a function returning None should be omitted.

Comment on lines +461 to +495
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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. 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.
  2. 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.
  3. Switch to Table rather than FixedTable here. 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.
  4. Finally, as always I suggest removing the explicit return.

Here's how I would recommend writing it:

Suggested change
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()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, will add this change.


name = "scsiinfo"

debuginfo_kmods = ["sd_mod"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added megaraid_sas, qla2xxx and lpfc in the list for debug info_kmods.

Orabug: 39122042

Signed-off-by: Rajan Shanmugvelu <rajan.shanmugavelu@oracle.com>
Copy link
Copy Markdown
Contributor Author

@vashanmu vashanmu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the recommended changes.

  1. included all changes in one file (scsi.py)
  2. used print_dictionary() instead of separate print()
  3. removed table.write() and added module 'megaraid_sas', 'qla2xxx' and 'lpfc' to the debuginfo_kmods list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants