Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

LSI Controller Temp monitoring

Featured Replies

Hi All.

 

Can I please request LSI controller card temperature monitoring be considered for a future release so we can monitor this from the dashboard. Some of the LSI series get very hot and would be a benefit to have this displayed and monitored if possible. Might need storcli64 to be included to allow for this to work (in my case anyways having an LSI9305). 

 

root@Tower:/bin# ./storcli64 /c0 show temperature
CLI Version = 007.2707.0000.0000 Dec 18, 2023
Operating system = Linux 6.1.79-Unraid
Controller = 0
Status = Success
Description = None


Controller Properties :
=====================

--------------------------------------
Ctrl_Prop                       Value 
--------------------------------------
ROC temperature(Degree Celsius) 48    
--------------------------------------

 

Thanks,

 

Hal

7 hours ago, hallamnet said:

Hi All.

 

Can I please request LSI controller card temperature monitoring be considered for a future release so we can monitor this from the dashboard. Some of the LSI series get very hot and would be a benefit to have this displayed and monitored if possible. Might need storcli64 to be included to allow for this to work (in my case anyways having an LSI9305). 

 

root@Tower:/bin# ./storcli64 /c0 show temperature
CLI Version = 007.2707.0000.0000 Dec 18, 2023
Operating system = Linux 6.1.79-Unraid
Controller = 0
Status = Success
Description = None


Controller Properties :
=====================

--------------------------------------
Ctrl_Prop                       Value 
--------------------------------------
ROC temperature(Degree Celsius) 48    
--------------------------------------

 

Thanks,

 

Hal

Does it show if you run sensors on cmdline?

  • 2 weeks later...
  • Author

Thanks very much for the reply and sorry for the delay. 

 

I have checked with running the command sensors and this does not show my LSI 9305 HBA. This is what is shown though. Any idea if this can be incorporated in to a future build or if I can get this on the home screen with a plugin?

 

root@HAL-UNRAID:~# sensors
coretemp-isa-0000
Adapter: ISA adapter
CPU Temp:     +40.0°C  (high = +80.0°C, crit = +100.0°C)
Core 0:       +32.0°C  (high = +80.0°C, crit = +100.0°C)
Core 4:       +40.0°C  (high = +80.0°C, crit = +100.0°C)
Core 8:       +30.0°C  (high = +80.0°C, crit = +100.0°C)
Core 12:      +33.0°C  (high = +80.0°C, crit = +100.0°C)
Core 16:      +31.0°C  (high = +80.0°C, crit = +100.0°C)
Core 20:      +31.0°C  (high = +80.0°C, crit = +100.0°C)
Core 24:      +31.0°C  (high = +80.0°C, crit = +100.0°C)
Core 28:      +29.0°C  (high = +80.0°C, crit = +100.0°C)
Core 32:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 33:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 34:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 35:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 36:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 37:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 38:      +34.0°C  (high = +80.0°C, crit = +100.0°C)
Core 39:      +34.0°C  (high = +80.0°C, crit = +100.0°C)

nvme-pci-0100
Adapter: PCI adapter
Composite:    +36.9°C  (low  = -273.1°C, high = +83.8°C)
                       (crit = +84.8°C)
Sensor 1:     +36.9°C  (low  = -273.1°C, high = +65261.8°C)
Sensor 2:     +37.9°C  (low  = -273.1°C, high = +65261.8°C)

acpitz-acpi-0
Adapter: ACPI interface
MB Temp:      +27.8°C  (crit = +105.0°C)

nct6798-isa-0290
Adapter: ISA adapter
in0:                      840.00 mV (min =  +0.00 V, max =  +1.74 V)
in1:                      992.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in2:                        3.39 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in3:                        3.33 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in4:                      1000.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in5:                        1.02 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in6:                        0.00 V  (min =  +0.00 V, max =  +0.00 V)
in7:                        3.39 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in8:                        3.15 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in9:                      520.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in10:                     584.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in11:                     544.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in12:                       1.05 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in13:                     568.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in14:                     888.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
fan1:                      631 RPM  (min =    0 RPM)
fan2:                      695 RPM  (min =    0 RPM)
fan3:                      704 RPM  (min =    0 RPM)
Array Fan:                 704 RPM  (min =    0 RPM)
SYSTIN:                    +29.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = thermistor
CPUTIN:                    +33.5°C  (high = +80.0°C, hyst = +75.0°C)  sensor = thermistor
AUXTIN0:                  +127.5°C    sensor = thermistor
AUXTIN1:                   +17.0°C    sensor = thermistor
AUXTIN2:                   +73.0°C    sensor = thermistor
AUXTIN3:                   +32.0°C    sensor = thermistor
PECI Agent 0 Calibration:  +32.0°C  
PCH_CHIP_TEMP:             +69.0°C  
intrusion0:               ALARM
intrusion1:               ALARM
beep_enable:              disabled

nvme-pci-0400
Adapter: PCI adapter
Composite:    +27.9°C  (low  = -273.1°C, high = +74.8°C)
                       (crit = +84.8°C)
Sensor 1:     +52.9°C  (low  = -273.1°C, high = +65261.8°C)
Sensor 2:     +51.9°C  (low  = -273.1°C, high = +65261.8°C)
ERROR: Can't get value of subfeature temp4_min: I/O error
ERROR: Can't get value of subfeature temp4_max: I/O error
Sensor 3:     +27.9°C  (low  =  +0.0°C, high =  +0.0°C)

nvme-pci-0200
Adapter: PCI adapter
Composite:    +26.9°C  (low  =  -0.1°C, high = +82.8°C)
                       (crit = +89.8°C)

 

It's Broadcom proprietary software that's not allowed to be re-distributed under their EULA.

So I personally don't see any possibility of this making it into a plugin or the base OS in the future.

  • 1 year later...

Hello,
If it helps porting to a plugin or the base OS, the following script reads controller temperatures directly via ioctl without needing lsiutil or storcli. It talks to the device node created by the mpt3sas kernel module. I could only test with mpt3sas (9305-16i) as I don't have hardware using the older mpt/mpt2 drivers.


Created with the help of generative AI, use at your own risk!

#!/usr/bin/env python3
"""Read LSI SAS IOC temperature directly via ioctl (no lsiutil needed)."""

import ctypes
import fcntl
import os
import struct
import sys

# MPI constants
MPI_FUNCTION_CONFIG = 0x04
MPI_CONFIG_ACTION_PAGE_HEADER = 0x00
MPI_CONFIG_ACTION_PAGE_READ_CURRENT = 0x01
MPI_CONFIG_PAGETYPE_IO_UNIT = 0x00
IO_UNIT_PAGE_NUMBER = 7

# Temperature unit constants
TEMP_NOT_PRESENT = 0x00
TEMP_FAHRENHEIT = 0x01
TEMP_CELSIUS = 0x02

# ioctl numbers: _IOC(_IOC_READ|_IOC_WRITE, magic, nr, size)
# mptctl uses magic 'm' (0x6D), mpt2/3 use 'L' (0x4C), both nr=20
# sizeof(struct mpt_ioctl_command) = 72 on 64-bit (same for mpt2/mpt3 variants)
STRUCT_SIZE = 72

DEVICES = [
    ("/dev/mpt3ctl", ord("L"), 20),
    ("/dev/mpt2ctl", ord("L"), 20),
    ("/dev/mptctl", ord("m"), 20),
]


def _ioctl_number(magic, nr):
    """Compute ioctl request number: _IOWR(magic, nr, struct_size)."""
    # _IOC(direction=3, type, nr, size) on Linux:
    # direction bits [31:30], size [29:16], type [15:8], nr [7:0]
    return (3 << 30) | (STRUCT_SIZE << 16) | (magic << 8) | nr


def _build_config_msg(action, page_length=0, page_number=IO_UNIT_PAGE_NUMBER,
                      page_type=MPI_CONFIG_PAGETYPE_IO_UNIT):
    """Build a Config request message (28 bytes, no SGE)."""
    # Config_t layout (28 bytes):
    # Action(1) AliasIndex(1) ChainOffset(1) Function(1)
    # ExtPageLength(2) ExtPageType(1) MsgFlags(1)
    # MsgContext(4)
    # Reserved2(8)
    # Header: PageVersion(1) PageLength(1) PageNumber(1) PageType(1)
    # PageAddress(4)
    msg = struct.pack(
        "<BBBB HBB I 8s BBBB I",
        action,             # Action
        0,                  # AliasIndex
        0,                  # ChainOffset
        MPI_FUNCTION_CONFIG,  # Function
        0,                  # ExtPageLength
        0,                  # ExtPageType
        0,                  # MsgFlags
        0,                  # MsgContext
        b"\x00" * 8,       # Reserved2
        0,                  # Header.PageVersion
        page_length,        # Header.PageLength (in dwords)
        page_number,        # Header.PageNumber
        page_type,          # Header.PageType
        0,                  # PageAddress
    )
    return msg


def _do_config_ioctl(fd, ioctl_nr, iocnum, action, page_length=0, data_in_size=0):
    """Issue an MPTCOMMAND config ioctl. Returns (reply_bytes, data_in_bytes)."""
    mf = _build_config_msg(action, page_length=page_length)
    reply_buf = ctypes.create_string_buffer(128)
    data_in_buf = ctypes.create_string_buffer(data_in_size) if data_in_size else None

    # Build mpt_ioctl_command struct (manual packing for 64-bit):
    # hdr.iocnum(4) hdr.port(4) hdr.maxDataSize(4) timeout(4)
    # replyFrameBufPtr(8) dataInBufPtr(8) dataOutBufPtr(8) senseDataPtr(8)
    # maxReplyBytes(4) dataInSize(4) dataOutSize(4) maxSenseBytes(4)
    # dataSgeOffset(4) mf[28]
    data_in_ptr = ctypes.addressof(data_in_buf) if data_in_buf else 0

    cmd = struct.pack(
        "<IIII QQQQ IIIII",
        iocnum,                          # hdr.iocnum
        0,                               # hdr.port
        0,                               # hdr.maxDataSize
        10,                              # timeout (seconds)
        ctypes.addressof(reply_buf),     # replyFrameBufPtr
        data_in_ptr,                     # dataInBufPtr
        0,                               # dataOutBufPtr (NULL - no writes!)
        0,                               # senseDataPtr
        128,                             # maxReplyBytes
        data_in_size,                    # dataInSize
        0,                               # dataOutSize (0 - no writes!)
        0,                               # maxSenseBytes
        7,                               # dataSgeOffset (dwords into mf where SGE goes)
    )
    cmd += mf

    cmd_buf = ctypes.create_string_buffer(cmd, len(cmd))
    try:
        fcntl.ioctl(fd, ioctl_nr, cmd_buf)
    except OSError as e:
        return None, None

    reply_bytes = bytes(reply_buf)
    data_in_bytes = bytes(data_in_buf) if data_in_buf else b""
    return reply_bytes, data_in_bytes


def read_ioc_temperature(fd, ioctl_nr, iocnum):
    """Read IO Unit Page 7 and return temperature in Celsius, or None."""
    # Step 1: Get page header to learn page length
    reply, _ = _do_config_ioctl(fd, ioctl_nr, iocnum, MPI_CONFIG_ACTION_PAGE_HEADER)
    if reply is None:
        return None

    # ConfigReply: IOCStatus at offset 0x0E, Header at offset 0x14
    ioc_status = struct.unpack_from("<H", reply, 0x0E)[0] & 0x7FFF
    if ioc_status != 0:
        return None

    # Header: PageVersion(1) PageLength(1) PageNumber(1) PageType(1)
    page_length = reply[0x15]  # in 32-bit dwords
    if page_length == 0:
        return None

    # Step 2: Read the actual page data
    data_in_size = page_length * 4
    reply, data = _do_config_ioctl(
        fd, ioctl_nr, iocnum, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
        page_length=page_length, data_in_size=data_in_size,
    )
    if reply is None or data is None:
        return None

    ioc_status = struct.unpack_from("<H", reply, 0x0E)[0] & 0x7FFF
    if ioc_status != 0:
        return None

    # IO Unit Page 7: IOCTemperature at offset 0x10 (U16), IOCTemperatureUnits at 0x12 (U8)
    if len(data) < 0x13:
        return None

    raw_temp = struct.unpack_from("<H", data, 0x10)[0]
    units = data[0x12]

    if units == TEMP_NOT_PRESENT:
        return None
    elif units == TEMP_FAHRENHEIT:
        celsius = (raw_temp - 32) * 5 // 9
    elif units == TEMP_CELSIUS:
        celsius = raw_temp
    else:
        celsius = raw_temp  # unknown units, return raw

    return celsius


def main():
    if os.geteuid() != 0:
        print("Error: must run as root", file=sys.stderr)
        sys.exit(1)

    found_any = False
    for dev_path, magic, nr in DEVICES:
        if not os.path.exists(dev_path):
            continue
        ioctl_nr = _ioctl_number(magic, nr)
        try:
            fd = os.open(dev_path, os.O_RDWR)
        except OSError:
            continue

        for iocnum in range(16):
            temp = read_ioc_temperature(fd, ioctl_nr, iocnum)
            if temp is not None:
                print(f"ioc{iocnum}: {temp}C")
                found_any = True

        os.close(fd)

    if not found_any:
        print("No LSI IOC temperature sensors found", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
  • 4 weeks later...

Hi @salsify , I wanted to say that your above script worked great for me on my 9207-8i (mpt2sas). I used un-get to install python3 and the script worked just like that. My card is apparently running at a very toasty 84 C so I think it's time I get a fan for it. 🥲

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.