Пример #1
0
def show_linear_lvm_uuid(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    for target_id in range(dm_table_map.num_targets):
        target = dm_table_map.targets.__getitem__(target_id)
        gendisk = StructResult("struct gendisk", md.disk)
        hash_cell = StructResult("struct hash_cell", md.interface_ptr)
        try:
            if ('LVM-' not in hash_cell.uuid):
                return
        except:
            pylog.warning("Invalid UUID for mapped_device:", hex(md),
                          "| hash_cell.uuid (UUID) is:", hash_cell.uuid)
            return

        lv_uuid = hash_cell.uuid.partition("-")
        lv_uuid = lv_uuid[2]

        vg_lv_names = get_vg_lv_names(name)

        if ((vg_lv_names[0]) and (vg_lv_names[1])):

            lv_capacity = get_size(gendisk)

            print("dm-{:<10d} {:45s} {:20s} {:18.2f}      {:10s}  {:10s}\n".
                  format(md.disk.first_minor, vg_lv_names[1], vg_lv_names[0],
                         lv_capacity, lv_uuid[-32:], lv_uuid[:32]),
                  end="")
Пример #2
0
def show_basic_mpath_info(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    mpath = StructResult("struct multipath", dm_table_map.targets.private)

    print("dm-{:<4d} {:<22} {:#x} ".format(md.disk.first_minor, name, mpath),
          end="")

    use_nr_paths_counter = -1

    try:
        use_nr_paths_counter = readSU("struct multipath",
                                      long(mpath.nr_valid_paths.counter))
    except:
        use_nr_paths_counter = -1

    if (use_nr_paths_counter != -1):
        print("{:26d}".format(mpath.nr_valid_paths.counter), end="")
    else:
        print("{:26d}".format(mpath.nr_valid_paths), end="")

    if (member_size("struct multipath", "flags") != -1):
        if ((mpath.flags & (1 << 0)) or (mpath.flags & (1 << 1))
                or (mpath.flags & (1 << 2))):
            print("\t\t{}".format("Enabled"))
        else:
            print("\t\t{}".format("Disabled"))

    else:
        if (mpath.queue_if_no_path):
            print("\t\t{}".format("Enabled"))
        else:
            print("\t\t{}".format("Disabled"))
Пример #3
0
def show_dmsetup_table_linear(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    for target_id in range(dm_table_map.num_targets):
        target = dm_table_map.targets.__getitem__(target_id)
        linear_c = StructResult("struct linear_c", target.private)

        print("{}: {} {} linear {}:{} [{}] {}".format(
            name, target.begin, target.len, linear_c.dev.bdev.bd_dev >> 20,
            linear_c.dev.bdev.bd_dev & 0xfffff,
            linear_c.dev.bdev.bd_disk.disk_name, linear_c.start))
Пример #4
0
def show_dmsetup_table_multipath(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    print("{}: {} {} multipath".format(name, dm_table_map.targets.begin,
                                       dm_table_map.targets.len),
          end="")
    mpath = StructResult("struct multipath", dm_table_map.targets.private)

    # general parameters
    params = []

    if (member_size("struct multipath", "flags") != -1):
        if ((mpath.flags & (1 << 0)) or (mpath.flags & (1 << 1))
                or (mpath.flags & (1 << 2))):
            params.append("queue_if_no_path")

    else:
        if (mpath.queue_if_no_path):
            params.append("queue_if_no_path")

    print(" {}".format(len(params)), end="")
    for param in params:
        print(" {}".format(param), end="")

    #hw handler parameters
    params = []
    if (mpath.hw_handler_name):
        params.append(mpath.hw_handler_name)
        if (mpath.hw_handler_params):
            for param in mpath.hw_handler_params.split(" "):
                params.append(param)

    print(" {}".format(len(params)), end="")
    for param in params:
        print(" {}".format(param), end="")

    #number of path groups
    print(" {}".format(mpath.nr_priority_groups), end="")

    prio_groups = readSUListFromHead(mpath.priority_groups, "list",
                                     "struct priority_group")

    #next pathgroup to try
    if (mpath.current_pg):
        print(" {}".format(mpath.current_pg.pg_num), end="")
    elif (prio_groups):
        print(" {}".format(prio_groups[0].pg_num), end="")
    else:
        print(" 1", end="")

    for prio in prio_groups:
        show_table_mpath_priogroup(prio)

    print("")
Пример #5
0
def show_mpath_info(prio):
    for path in readSUListFromHead(prio.pgpaths, "list", "struct pgpath"):
        block_device = StructResult("struct block_device", path.path.dev.bdev)
        scsi_device = StructResult("struct scsi_device",
                                   block_device.bd_disk.queue.queuedata)

        print("\n  `- {} {} {}:{}    ".format(
            scsi_device.sdev_gendev.kobj.name, block_device.bd_disk.disk_name,
            block_device.bd_dev >> 20, block_device.bd_dev & 0xfffff),
              end="")

        enum_sdev_state = EnumInfo("enum scsi_device_state")

        if ('cciss' in block_device.bd_disk.disk_name):
            print("\t[Not a scsi device, skipping scsi_device struct!]",
                  end="")
        else:
            print("\t[scsi_device: {:#x} sdev_state: {}]".format(
                scsi_device, enum_sdev_state.getnam(scsi_device.sdev_state)),
                  end="")
Пример #6
0
def show_table_mpath_priogroup(prio):
    print(" {} 0 {} 1".format(prio.ps.type.name, prio.nr_pgpaths), end="")

    for path in readSUListFromHead(prio.pgpaths, "list", "struct pgpath"):
        path_info = StructResult("struct path_info", path.path.pscontext)

        print(" {}:{} [{}] {}".format(path.path.dev.bdev.bd_dev >> 20,
                                      path.path.dev.bdev.bd_dev & 0xfffff,
                                      path.path.dev.bdev.bd_disk.disk_name,
                                      path_info.repeat_count),
              end="")
Пример #7
0
def show_linear_lvm(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    for target_id in range(dm_table_map.num_targets):
        target = dm_table_map.targets.__getitem__(target_id)
        linear_c = StructResult("struct linear_c", target.private)
        gendisk = StructResult("struct gendisk", md.disk)
        pv_gendisk = StructResult("struct gendisk", linear_c.dev.bdev.bd_disk)
        hash_cell = StructResult("struct hash_cell", md.interface_ptr)
        try:
            if ('LVM-' not in hash_cell.uuid):
                return
        except:
            pylog.warning("Invalid UUID for mapped_device:", hex(md),
                          "| hash_cell.uuid (UUID) is:", hash_cell.uuid)
            return

        vg_lv_names = get_vg_lv_names(name)

        if ((vg_lv_names[0]) and (vg_lv_names[1])):

            lv_capacity = get_size(gendisk)

            if ('dm-' in pv_gendisk.disk_name[:3]):
                pv_md, pv_md_name = get_md_mpath_from_gendisk(pv_gendisk)
                print("dm-{:<10d} {:45s} {:40s} "
                      "{} {:18.2f}     {}\t({})\n".format(
                          md.disk.first_minor, vg_lv_names[1], vg_lv_names[0],
                          md.open_count.counter, lv_capacity, pv_md_name,
                          pv_gendisk.disk_name),
                      end="")
            else:
                print("dm-{:<10d} {:45s} {:40s} "
                      "{} {:18.2f}     {}\n".format(md.disk.first_minor,
                                                    vg_lv_names[1],
                                                    vg_lv_names[0],
                                                    md.open_count.counter,
                                                    lv_capacity,
                                                    pv_gendisk.disk_name),
                      end="")
Пример #8
0
def show_linear_lvm_pv(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    for target_id in range(dm_table_map.num_targets):
        target = dm_table_map.targets.__getitem__(target_id)
        linear_c = StructResult("struct linear_c", target.private)
        gendisk = StructResult("struct gendisk", md.disk)
        pv_gendisk = StructResult("struct gendisk", linear_c.dev.bdev.bd_disk)
        hash_cell = StructResult("struct hash_cell", md.interface_ptr)
        try:
            if ('LVM-' not in hash_cell.uuid):
                return
        except:
            pylog.warning("Invalid UUID for mapped_device:", hex(md),
                          "| hash_cell.uuid (UUID) is:", hash_cell.uuid)
            return

        vg_lv_names = get_vg_lv_names(name)

        if ((vg_lv_names[0]) and (vg_lv_names[1])):

            pv_capacity = get_size(pv_gendisk)

            if ('dm-' in pv_gendisk.disk_name[:3]):
                pv_md, pv_md_name = get_md_mpath_from_gendisk(pv_gendisk)
                print("{} ({})\t{:18} {:30x}\t {:32.2f}\t"
                      "{:20s} {}\n".format(pv_md_name, pv_gendisk.disk_name,
                                           "", pv_md, pv_capacity,
                                           vg_lv_names[0], vg_lv_names[1]),
                      end="")
            else:
                print("{:45s}  {}\t {:25.2f}\t"
                      "{:20s} {}\n".format(pv_gendisk.disk_name,
                                           "[PV not on dm dev, skipping!]",
                                           pv_capacity, vg_lv_names[0],
                                           vg_lv_names[1]),
                      end="")
Пример #9
0
def run_check_on_multipath():
    tt = TaskTable()
    bts = []
    errors = 0
    task_cnt = 0
    multipathd_daemon = 0  # To verify if multipathd daemon is running
    multipath_blocked = 0  # To verify if multipathd daemon or command is blocked
    mpath_present = 0  # To verify if multipath device exists with or without
    # multipathd daemon running
    wq_blocked = 0  # To verify if scsi_wq or fc_wq is blocked
    kworker_md_blocked = 0  # Counter for hung worker threads which are waiting for
    # IO requests on mdraid devices

    print("\nChecking for device-mapper issues...\n")

    for t in tt.allThreads():
        print("Getting a list of processes in UN state..."
              "(Count: {:d})".format(task_cnt),
              end="\r")
        if ('multipathd' in t.comm):
            multipathd_daemon = 1
        if (t.ts.state & TASK_STATE.TASK_UNINTERRUPTIBLE):
            task_cnt += 1
            # crash can miss some threads when there are pages missing
            # and it will not do 'bt' in that case.
            try:
                bts.append(exec_bt("bt %d" % t.pid)[0])
            except:
                pass
    print("Getting a list of processes in UN state...\t\t\t[Done]")

    if (task_cnt):
        print("\nProcessing the back trace of hung tasks...\t\t\t", end='')
        for bt in bts:
            if ('kworker' in bt.cmd):
                if (bt.hasfunc('md_flush_request')
                        and bt.hasfunc('dio_aio_complete_work')):
                    kworker_md_blocked += 1

            if ('multipath' in bt.cmd):
                multipath_blocked = 1

            if (('scsi_wq' in bt.cmd) or ('fc_wq' in bt.cmd)):
                wq_blocked = 1
        print("[Done]")

    # Checks for dm devices
    for dev in devlist:
        md, name = dev
        dm_table_map = StructResult("struct dm_table", md.map)
        # Check if there is any multipath device present in device-mapper table
        if (dm_table_map.targets.type.name == "multipath"):
            mpath_present += 1

    # Check if kworker threads are stuck waiting to flush IO on mdraid devices
    if (kworker_md_blocked >= 5):
        print(
            "\n ** {} kworker threads are stuck in UN state waiting to flush the IO"
            "\n    requests on mdraid devices. This could be a result of thundering"
            "\n    herd problem. See reference: "
            "\n    https://marc.info/?l=linux-raid&m=155364683109115&w=2".
            format(kworker_md_blocked))
        print(
            "\n    Run 'hanginfo' for more information on processes in UN state."
        )
        errors += 1

    # multipath devices are present but multipathd is not running
    if (mpath_present != 0 and multipathd_daemon == 0):
        print(
            "\n ** multipath device(s) are present, but multipathd service is"
            "\n    not running. IO failover/failback may not work.")
        errors += 1

    # scsi or fc work queue and multipathd are blocked
    if (multipath_blocked == 1 and wq_blocked == 1):
        print(
            "\n ** multipathd and scsi/fc work_queue processes are stuck in UN state,"
            "\n    this could block IO failover on multipath devices")
        print(
            "\n    Run 'hanginfo' for more information on processes in UN state."
        )
        errors += 1
    # only multipathd process is stuck in UN state
    elif (multipath_blocked == 1):
        print("\n ** multipathd processes stuck in UN state,"
              "\n    this could block IO failover on multipath devices")
        print(
            "\n    Run 'hanginfo' for more information on processes in UN state."
        )
        errors += 1

    if (errors == 0 and task_cnt != 0):
        print("\n    No device-mapper, multipath issues detected by utility,"
              "\n    but found {} processes in UN state.".format(task_cnt))
        print(
            "\n    Run 'hanginfo' for more information on processes in UN state."
        )
    elif (errors == 0 and task_cnt == 0):
        print("No issues detected by utility.")
Пример #10
0
def get_md_mpath_from_gendisk(pv_gendisk):
    tmp_mapped_device = StructResult("struct mapped_device",
                                     pv_gendisk.queue.queuedata)
    for temp_dev in devlist:
        if (tmp_mapped_device == temp_dev[0]):
            return temp_dev
Пример #11
0
def show_multipath_list(dev):
    md, name = dev
    dm_table_map = StructResult("struct dm_table", md.map)
    print(
        "------------------------------------------------------------------------------------------"
    )

    mpath = StructResult("struct multipath", dm_table_map.targets.private)
    prio_groups = readSUListFromHead(mpath.priority_groups, "list",
                                     "struct priority_group")

    temp_prio_groups_list = readSU("struct list_head", mpath.priority_groups)
    temp_priority_group = StructResult("struct priority_group",
                                       temp_prio_groups_list.next)
    temp_pgpath_list = readSU("struct list_head", temp_priority_group.pgpaths)
    temp_pgpath = StructResult("struct pgpath", temp_pgpath_list.next)

    try:
        temp_scsi_device = StructResult(
            "struct scsi_device",
            temp_pgpath.path.dev.bdev.bd_disk.queue.queuedata)
    except:
        pylog.warning("Error in processing sub paths for multipath device:",
                      name)
        pylog.warning(
            "Use 'dmshow --table|grep <mpath-device-name>' to manually verify sub paths."
        )
        return

    hash_cell = StructResult("struct hash_cell", md.interface_ptr)
    scsi_id = hash_cell.uuid
    scsi_id = scsi_id.partition("-")

    if ('cciss' in temp_pgpath.path.dev.bdev.bd_disk.disk_name):
        print("{}  ({})  dm-{:<4d}  HP Smart Array RAID Device (cciss)".format(
            name, scsi_id[2], md.disk.first_minor),
              end="")
    else:
        print("{}  ({})  dm-{:<4d}  {}  {}".format(
            name, scsi_id[2], md.disk.first_minor, temp_scsi_device.vendor[:8],
            temp_scsi_device.model[:16]),
              end="")

    print("\nsize={:.2f}M  ".format(get_size(
        temp_pgpath.path.dev.bdev.bd_disk)),
          end="")

    if (member_size("struct multipath", "flags") != -1):
        if ((mpath.flags & (1 << 0)) or (mpath.flags & (1 << 1))
                or (mpath.flags & (1 << 2))):
            print("(queue_if_no_path enabled)  ".format(), end="")
        else:
            print("(queue_if_no_path disabled)  ".format(), end="")

    else:
        if (mpath.queue_if_no_path):
            print("features='1 queue_if_no_path'  ".format(), end="")
        else:
            print("features='0' (queue_if_no_path disabled)  ".format(),
                  end="")

    if (mpath.hw_handler_name):
        print("hwhandler={} hwhandler params={}  ".format(
            mpath.hw_handler_name, mpath.hw_handler_params),
              end="")
    else:
        print("hwhandler={}  ".format(mpath.hw_handler_name), end="")

    for prio in prio_groups:
        print("\n+- policy='{}' ".format(prio.ps.type.name), end="")
        show_mpath_info(prio)

    print("")
Пример #12
0
            "VG UUID"))
    elif (args.pvs):
        print("{:45s}  {:40s}\t  {}\t{:20s} {}\n".format(
            "PV NAME", "PV's MAPPED_DEVICE", "DEVICE SIZE (MB)", "VG NAME",
            "LV NAME"),
              end="")
    elif (args.table):
        pass
    else:
        print("NUMBER  NAME                   MAPPED_DEVICE       FIELDS")

    mpathfound = 0

    for dev in devlist:
        md, name = dev
        dm_table_map = StructResult("struct dm_table", md.map)
        if (args.multipath):
            if (not (dm_table_map.targets.type.name == "multipath")):
                continue
            show_basic_mpath_info(dev)
            mpathfound = 1

        elif (args.multipathlist):
            if (not (dm_table_map.targets.type.name == "multipath")):
                continue
            show_multipath_list(dev)
            mpathfound = 1

        elif (args.lvs):
            if (dm_table_map.targets.type.name == "linear"):
                show_linear_lvm(dev)
Пример #13
0
def run_scsi_checks():
    warnings = 0
    errors = 0
    use_atomic_counters = -1
    gendev_q_sdev_q_mismatch = 0
    retry_delay_bug = 0
    qla_cmd_abort_bug = 0
    jiffies = readSymbol("jiffies")

    # host checks
    hosts = get_scsi_hosts()

    try:
        use_atomic_counters = readSU("struct Scsi_Host",
                                     long(hosts[0].host_busy.counter))
    except:
        use_atomic_counters = -1

    for host in hosts:
        if (use_atomic_counters == -1):
            if (host.host_failed):
                warnings += 1
                if (host.host_failed == host.host_busy):
                    print(
                        "WARNING: Scsi_Host {:#x} ({}) is running error recovery!"
                        .format(host, host.shost_gendev.kobj.name))
                else:
                    print(
                        "WARNING: Scsi_Host {:#x} ({}) has timed out commands, but has not started error recovery!"
                        .format(host, host.shost_gendev.kobj.name))

            if (host.host_blocked):
                warnings += 1
                print(
                    "WARNING: Scsi_Host {:#x} ({}) is blocked! HBA driver refusing all commands with SCSI_MLQUEUE_HOST_BUSY?"
                    .format(host, host.shost_gendev.kobj.name))

        elif (use_atomic_counters != -1):
            if (host.host_failed):
                warnings += 1
                if (host.host_failed == host.host_busy.counter):
                    print(
                        "WARNING: Scsi_Host {:#x} ({}) is running error recovery!"
                        .format(host, host.shost_gendev.kobj.name))
                else:
                    print(
                        "WARNING: Scsi_Host {:#x} ({}) has timed out commands, but has not started error recovery!"
                        .format(host, host.shost_gendev.kobj.name))

            if (host.host_blocked.counter):
                warnings += 1
                print(
                    "WARNING: Scsi_Host {:#x} ({}) is blocked! HBA driver refusing all commands with SCSI_MLQUEUE_HOST_BUSY?"
                    .format(host, host.shost_gendev.kobj.name))

    # device checks
    gendev_dict = get_gendev()

    for sdev in get_SCSI_devices():
        if (use_atomic_counters == -1):
            if (sdev.device_blocked):
                warnings += 1
                print(
                    "WARNING: scsi_device {:#x} ({}) is blocked! HBA driver returning "
                    "SCSI_MLQUEUE_DEVICE_BUSY or device returning SAM_STAT_BUSY?"
                    .format(sdev, get_scsi_device_id(sdev)))
            if (sdev.device_busy < 0):
                print(
                    "ERROR:   scsi_device {:#x} ({}) device_busy count is: {}".
                    format(sdev, get_scsi_device_id(sdev), sdev.device_busy))
                if (sdev.host.hostt.name in "qla2xxx"):
                    qla_cmd_abort_bug += 1
        elif (use_atomic_counters != -1):
            if (sdev.device_blocked.counter):
                warnings += 1
                print(
                    "WARNING: scsi_device {:#x} ({}) is blocked! HBA driver returning "
                    "SCSI_MLQUEUE_DEVICE_BUSY or device returning SAM_STAT_BUSY?"
                    .format(sdev, get_scsi_device_id(sdev)))
            if (sdev.device_busy.counter < 0):
                print(
                    "ERROR:   scsi_device {:#x} ({}) device_busy count is: {}".
                    format(sdev, get_scsi_device_id(sdev),
                           sdev.device_busy.counter))
                if (sdev.host.hostt.name in "qla2xxx"):
                    qla_cmd_abort_bug += 1

        # Check if scsi_device->request_queue is same as corresponding gendisk->queue.
        name = scsi_device_type(sdev.type)
        if (name):
            if (name in 'Direct-Access    '):
                sdev_q = StructResult("struct request_queue",
                                      sdev.request_queue)
                sdev_q = format(sdev_q, 'x')
                try:
                    gendev = gendev_dict[sdev_q]
                except:
                    gendev_q_sdev_q_mismatch += 1

        # Checks for qla2xxx bug for retry_delay RH BZ#1588133
        if (sdev.host.hostt.name in "qla2xxx" and
            (member_size("struct fc_port", "retry_delay_timestamp") != -1)):
            fc_port = readSU("struct fc_port", long(sdev.hostdata))
            retry_delay_timestamp = readSU("struct fc_port",
                                           long(fc_port.retry_delay_timestamp))
            if (retry_delay_timestamp != 0):
                retry_delay = (retry_delay_timestamp - jiffies) / 1000 / 60
                if (retry_delay > 2):
                    errors += 1
                    print(
                        "ERROR:   scsi_device {:#x} ({}) has retry_delay_timestamp: {:d}, "
                        "IOs delayed for {:f} more minutes".format(
                            sdev, get_scsi_device_id(sdev),
                            retry_delay_timestamp, retry_delay))
                    retry_delay_bug += 1

        # command checks
        for cmnd in get_scsi_commands(sdev):
            try:
                timeout = cmnd.request.timeout
            except KeyError:
                timeout = 0

            if (not timeout):
                try:
                    timeout = cmnd.timeout_per_command
                except KeyError:
                    print("Error: cannot determine timeout!")

            # Check for large timeout values
            if (timeout > 300000):
                errors += 1
                print(
                    "ERROR:   scsi_cmnd {:#x} on scsi_device {:#x} ({}) has a huge timeout of {}ms!"
                    .format(cmnd, cmnd.device, get_scsi_device_id(cmnd.device),
                            timeout))
            elif (timeout == 300000):
                warnings += 1
                print(
                    "WARNING: 5 minute timeout found for scsi_cmnd {:#x}! on scsi_device {:#x} ({}) "
                    "Update device-mapper-multipath?".format(
                        cmnd, cmnd.device, get_scsi_device_id(cmnd.device)))
            elif (timeout > 60000):
                warnings += 1
                print(
                    "WARNING: scsi_cmnd {:#x} on scsi_device {:#x} ({}) has a large timeout of {}ms."
                    .format(cmnd, cmnd.device, get_scsi_device_id(cmnd.device),
                            timeout))

            # check for old command
            if (timeout and jiffies > (timeout + cmnd.jiffies_at_alloc)):
                print(
                    "Warning: scsi_cmnd {:#x} on scsi_device {:#x} ({}) older than its timeout: "
                    "EH or stalled queue?".format(
                        cmnd, cmnd.device, get_scsi_device_id(cmnd.device)))
                warnings += 1

    # scsi_target checks
    stgt_busy_block_cnt = -1
    for shost in get_scsi_hosts():
        if (shost.__targets.next != shost.__targets.next.next):
            for starget in readSUListFromHead(shost.__targets, "siblings",
                                              "struct scsi_target"):
                if (member_size("struct scsi_target", "target_busy") != -1):
                    try:
                        stgt_busy_block_cnt = readSU(
                            "struct scsi_target",
                            long(starget.target_busy.counter))
                    except:
                        stgt_busy_block_cnt = -1

                    try:
                        if (stgt_busy_block_cnt != -1):
                            if (starget.target_busy.counter > 0):
                                print(
                                    "WARNING: scsi_target {:10s} {:x} is having non-zero "
                                    "target_busy count: {:d}".format(
                                        starget.dev.kobj.name, int(starget),
                                        starget.target_busy.counter))
                                warnings += 1
                            if (starget.target_blocked.counter > 0):
                                print(
                                    "WARNING: scsi_target {:10s} {:x} is blocked "
                                    "(target_blocked count: {:d})".format(
                                        starget.dev.kobj.name, int(starget),
                                        starget.target_blocked.counter))
                                warnings += 1

                        elif (stgt_busy_block_cnt == -1 and member_size(
                                "struct scsi_target", "target_busy") != -1):
                            if (starget.target_busy > 0):
                                print(
                                    "WARNING: scsi_target {:10s} {:x} is having non-zero "
                                    "target_busy count: {:d}".format(
                                        starget.dev.kobj.name, int(starget),
                                        starget.target_busy))
                                warnings += 1
                            if (starget.target_blocked > 0):
                                print(
                                    "WARNING: scsi_target {:10s} {:x} is blocked "
                                    "(target_blocked count: {:d})".format(
                                        starget.dev.kobj.name, int(starget),
                                        starget.target_blocked))
                                warnings += 1

                    except KeyError:
                        pylog.warning("Error in processing scsi_target {:x},"
                                      "please check manually".format(
                                          int(starget)))

    if (retry_delay_bug):
        print(
            "\t HBA driver returning 'SCSI_MLQUEUE_TARGET_BUSY' due to a large retry_delay.\n"
            "\t See https://patchwork.kernel.org/patch/10450567/")

    if (qla_cmd_abort_bug):
        print(
            "\t scsi_device.device_busy count is negative, this could be caused due to"
            " double completion of scsi_cmnd from qla2xxx_eh_abort.\n"
            "\t See https://patchwork.kernel.org/patch/10587997/")

    if (gendev_q_sdev_q_mismatch != 0):
        print(
            "\n\tNOTE: The scsi_device->request_queue is not same as gendisk->request_queue\n"
            "\t      for {} scsi device(s). \n\n"
            "\t      It is likely that custom multipathing solutions have created 'gendisk',\n"
            "\t      'request_queue' structures which are not registered with kernel.\n"
            "\t      *Although this may or may not be a reason for issue, but it could make\n"
            "\t      the analysis of scsi_device, request_queue and gendisk struct confusing!\n"
            .format(gendev_q_sdev_q_mismatch))

    if (not (warnings or errors or gendev_q_sdev_q_mismatch)):
        print("Nothing found")
Пример #14
0
def print_request_queue():
    counter = 0
    cmnd_requests = []
    gendev_dict = get_gendev()
    jiffies = readSymbol("jiffies")

    opcode_table = {'0x00':'TUR', '0x03':'REQ-SENSE', '0x08':'READ(6)',\
                    '0x0a':'WRITE(6)', '0x12':'INQUIRY', '0x16':'RESERVE(6)',\
                    '0x17':'RELEASE(6)', '0x25':'READ-CAP(10)', '0x28':'READ(10)',\
                    '0x2a':'WRITE(10)', '0x41':'WR SAME', '0x56':'RESERVE(10)',\
                    '0x57':'RELEASE(10)', '0x88':'READ(16)', '0x8a':'WRITE(16)',\
                    '0xa0':'REPORT LUNS', '0xa8':'READ(12)', '0xaa':'WRITE (12)'}

    for sdev in get_SCSI_devices():
        name = scsi_device_type(sdev.type)
        if (name):
            if ((name in 'Direct-Access    ')
                    or (name in 'CD-ROM           ')):
                sdev_q = StructResult("struct request_queue",
                                      sdev.request_queue)
                if (member_size("struct elevator_queue", "elevator_type") !=
                        -1):
                    elevator_name = sdev_q.elevator.elevator_type.elevator_name
                elif (member_size("struct elevator_queue", "type") != -1):
                    elevator_name = sdev_q.elevator.type.elevator_name
                else:
                    elevator_name = "<Unknown>"
                sdev_q = format(sdev_q, 'x')
                try:
                    gendev = gendev_dict[sdev_q]
                    gendev = readSU("struct gendisk", long(gendev, 16))
                    name = gendev.disk_name
                except:
                    name = "Disk"

                print(
                    "\n==========================================================="
                    "============================================================"
                )
                print("    ### DEVICE : {}\n".format(name))

                print(
                    "        ----------------------------------------------------"
                    "-----------------------------------")
                if (name == "Disk"):
                    print("\tgendisk        \t:  {} |"
                          "\tscsi_device \t:  {:x}".format(
                              "<Can't find gendisk>", int(sdev)))
                else:
                    print(
                        "\tgendisk        \t:  {:x}\t|\tscsi_device \t:  {:x}".
                        format(int(gendev), int(sdev)))
                print("\trequest_queue  \t:  {}\t|\tH:C:T:L       \t:  {}".
                      format(sdev_q, sdev.sdev_gendev.kobj.name))
                print(
                    "\televator_name  \t:  {}    \t\t|\tVENDOR/MODEL\t:  {} {}"
                    .format(elevator_name, sdev.vendor[:8], sdev.model[:16]))
                print(
                    "        ----------------------------------------------------"
                    "-----------------------------------")

                cmnd_requests = []
                cmnds = get_scsi_commands(sdev)
                for cmnd in cmnds:
                    cmnd_requests.append(cmnd.request)

                requests = get_queue_requests(sdev.request_queue)
                requests = list(set(requests + cmnd_requests))

                print("\n     {:10s}{:20s} {:20s} {:18s} {:10s} {:20s} {:10s}".
                      format("NO.", "request", "bio", "scsi_cmnd", "OPCODE",
                             "COMMAND AGE", "SECTOR"))
                print(
                    "     -------------------------------------------------------"
                    "------------------------------------------------------")

                counter = 0
                for req in requests:
                    counter = counter + 1
                    cmnd = StructResult("struct scsi_cmnd", req.special)
                    try:
                        time = (long(jiffies) - long(cmnd.jiffies_at_alloc))
                        opcode = StructResult("struct scsi_cmnd",
                                              long(cmnd.cmnd[0]))
                        opcode = hex(opcode)
                        try:
                            opcode = opcode_table[opcode]
                        except:
                            pass
                        print(
                            "     {:3d} {:3s} {:18x} {:20x} {:20x}   {:10} {:8d} ms "
                            .format(counter, "", req, req.bio, cmnd, opcode,
                                    long(time)),
                            end="")
                        if (req.bio):
                            print("{:15d}".format(req.bio.bi_sector))
                        else:
                            print("       ---NA---")
                    except:
                        pylog.warning("Invalid scsi_cmnd address in request: ",
                                      name, req, cmnd)
                if (counter == 0):
                    print("\t\t<<< NO I/O REQUESTS FOUND ON THE DEVICE! >>>")
Пример #15
0
def print_sdev_shost():
    enum_sdev_state = EnumInfo("enum scsi_device_state")

    gendev_dict = get_gendev()

    for shost in get_scsi_hosts():
        if (shost.__devices.next != shost.__devices.next.next):
            print(
                "\n=============================================================================="
                "==============================================================================="
            )
            print("HOST      DRIVER")
            print(
                "NAME      NAME                               {:24s} {:24s} {:24s}"
                .format("Scsi_Host", "shost_data", "&.hostdata[0]", end=""))
            print("--------------------------------------------------------"
                  "-------------------------------------------------------")

            print_shost_header(shost)

            print("{:17s} {:23s} {:16s} {:25s} {:24s}   {}  {}    {}"
                  "\n".format("DEV NAME", "scsi_device", "H:C:T:L",
                              "VENDOR/MODEL", "DEVICE STATE", "IOREQ-CNT",
                              "IODONE-CNT", "           IOERR-CNT"),
                  end="")
            print("-----------------------------------------------------"
                  "-----------------------------------------------------"
                  "---------------------------------------------------")

            for sdev in readSUListFromHead(shost.__devices, "siblings",
                                           "struct scsi_device"):
                name = scsi_device_type(sdev.type)

                if (name):
                    if (name in 'Sequential-Access'):
                        name = "Tape"
                    elif (name in 'Medium Changer   '):
                        name = "Chngr"
                    elif (name in 'RAID             '):
                        name = "CTRL"
                    elif ((name in 'Direct-Access    ')
                          or (name in 'CD-ROM           ')):
                        sdev_q = StructResult("struct request_queue",
                                              sdev.request_queue)
                        sdev_q = format(sdev_q, 'x')
                        try:
                            gendev = gendev_dict[sdev_q]
                            gendev = readSU("struct gendisk", long(gendev, 16))
                            name = gendev.disk_name
                        except:
                            name = "Disk"
                else:
                    name = "null"

                print("{:17s} {:x} {:6s} {:16} {} {} {:22s}"
                      "{:14d} {:11}  ({:3d})\t{:10d}\n".format(
                          name, int(sdev), "", get_scsi_device_id(sdev),
                          sdev.vendor[:8], sdev.model[:16],
                          get_sdev_state(
                              enum_sdev_state.getnam(sdev.sdev_state)),
                          sdev.iorequest_cnt.counter, sdev.iodone_cnt.counter,
                          sdev.iorequest_cnt.counter - sdev.iodone_cnt.counter,
                          sdev.ioerr_cnt.counter),
                      end='')