generated from oracle/template-repo
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add iscsi helpers to dump iscsi session
Orabug: 37362180 Signed-off-by: Richard Li <[email protected]>
- Loading branch information
Showing
3 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
# Copyright (c) 2024, Oracle and/or its affiliates. | ||
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ | ||
""" | ||
Helper for iscsi | ||
""" | ||
import argparse | ||
from typing import Iterator | ||
from typing import Tuple | ||
|
||
from drgn import Object | ||
from drgn import Program | ||
from drgn.helpers.common import escape_ascii_string | ||
from drgn.helpers.common.type import enum_type_to_class | ||
from drgn.helpers.linux.list import list_for_each_entry | ||
|
||
from drgn_tools.corelens import CorelensModule | ||
from drgn_tools.scsi import for_each_scsi_host | ||
from drgn_tools.scsi import for_each_scsi_host_device | ||
from drgn_tools.scsi import get_scsi_device_name | ||
from drgn_tools.scsi import host_module_name | ||
from drgn_tools.table import print_dictionary | ||
from drgn_tools.util import enum_name_get | ||
|
||
ISCSI_SESSION_STATES = ["LOGGED_IN", "FAILED", "FREE"] | ||
|
||
|
||
def for_each_iscsi_host(prog: Program) -> Iterator[Object]: | ||
""" | ||
Iterates through all scsi host devices and returns a | ||
iterator of hosts backed by iscsi drivers | ||
:returns: an iterator of ``struct Scsi_Host *`` | ||
""" | ||
for shost in for_each_scsi_host(prog): | ||
if "iscsi" in host_module_name(shost).lower(): | ||
yield shost | ||
|
||
|
||
def for_each_iscsi_session(prog: Program) -> Iterator[Object]: | ||
""" | ||
Iterates through all iscsi_cls_session and gets the associated iscsi_session | ||
:returns: an iterator of ``struct iscsi_session *`` | ||
""" | ||
for cls_session in list_for_each_entry( | ||
"struct iscsi_cls_session", prog["sesslist"].address_of_(), "sess_list" | ||
): | ||
yield Object( | ||
prog, | ||
prog.type("struct iscsi_session", filename="libiscsi.h"), | ||
address=cls_session.dd_data, | ||
) | ||
|
||
|
||
def for_each_attached_device( | ||
prog: Program, shost: Object | ||
) -> Iterator[Tuple[Object, str]]: | ||
""" | ||
Iterates through all Scsi_Host and gets their associated scsi device and name | ||
:returns: an iterator of (``struct scsi_device *``, ``str``) | ||
""" | ||
for scsi_dev in for_each_scsi_host_device(prog, shost): | ||
name = get_scsi_device_name(prog, scsi_dev) | ||
yield scsi_dev, name | ||
|
||
|
||
def print_iscsi_report(prog: Program) -> None: | ||
""" | ||
Prints a comprehensive report including iscsi table and session stats. More info can be added later if needed. | ||
""" | ||
output = {} | ||
|
||
for session in reversed(list(for_each_iscsi_session(prog))): | ||
print("**********") | ||
conn = session.leadconn | ||
|
||
persistent_address = escape_ascii_string( | ||
conn.persistent_address.string_() | ||
) | ||
persistent_port = int(conn.persistent_port) | ||
output[ | ||
"Scsi_Host" | ||
] = f"host{session.host.host_no.value_()} ({hex(session.host.value_())})" | ||
output["Session"] = hex(session.address_of_()) | ||
output["SID"] = str(int(session.cls_session.sid)) | ||
output["Persistent Portal"] = f"{persistent_address}:{persistent_port}" | ||
output["Iface Name"] = escape_ascii_string(session.ifacename.string_()) | ||
output["Session State"] = ISCSI_SESSION_STATES[ | ||
session.cls_session.state | ||
] | ||
connstate = enum_type_to_class( | ||
prog.type("enum iscsi_connection_state"), "connstate" | ||
) | ||
output["Connection State"] = str( | ||
enum_name_get( | ||
connstate, | ||
conn.cls_conn.state, | ||
"UNKNOWN", | ||
) | ||
) | ||
output["Initiatorname"] = escape_ascii_string( | ||
session.initiatorname.string_() | ||
) | ||
output["Targetname"] = escape_ascii_string( | ||
session.targetname.string_() | ||
) | ||
|
||
print_dictionary(output) | ||
|
||
print("Attached SCSI devices: ") | ||
print("**********") | ||
print( | ||
"Host Number: {} STATE: {}".format( | ||
session.host.host_no.value_(), | ||
session.host.shost_state.format_(type_name=False), | ||
) | ||
) | ||
|
||
for scsi_dev, name in for_each_attached_device(prog, session.host): | ||
print( | ||
"scsi{} Channel {} Id {} Lun: {}".format( | ||
session.host.host_no.value_(), | ||
int(scsi_dev.channel), | ||
int(scsi_dev.id), | ||
int(scsi_dev.lun), | ||
) | ||
) | ||
sdev_state = enum_type_to_class( | ||
prog.type("enum scsi_device_state"), "sdev_state" | ||
) | ||
state = enum_name_get( | ||
sdev_state, | ||
scsi_dev.sdev_state, | ||
"UNKNOWN", | ||
) | ||
print(" Attached iscsi disk: {} State: {}".format(name, state)) | ||
|
||
print() | ||
|
||
|
||
class IscsiDump(CorelensModule): | ||
""" | ||
Dump iscsi info | ||
""" | ||
|
||
name = "iscsi" | ||
|
||
def run(self, prog: Program, args: argparse.Namespace) -> None: | ||
print_iscsi_report(prog) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Copyright (c) 2024, Oracle and/or its affiliates. | ||
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ | ||
from drgn_tools import iscsi | ||
from drgn_tools.module import KernelModule | ||
|
||
|
||
def test_iscsi(prog): | ||
# make sure iscsi module is loaded | ||
km = KernelModule.find(prog, "scsi_transport_iscsi") | ||
if km: | ||
iscsi.print_iscsi_report(prog) |