Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using in-band ipmbdev interface #176

Open
mahendrapaipuri opened this issue Oct 15, 2024 · 4 comments
Open

Using in-band ipmbdev interface #176

mahendrapaipuri opened this issue Oct 15, 2024 · 4 comments

Comments

@mahendrapaipuri
Copy link

Hello,

Thanks a lot for this lib. It helped me to understand the IPMI spec better.

I am trying to make the in-band ipmbdev interface work with the library without much success. I am interested in dcmi power readings and I am using the following script:

$ cat ipmi.py
import sys
import logging

import pyipmi
import pyipmi.interfaces

# Set logging to DEBUG
pyipmi.logger.set_log_level(logging.DEBUG)


def main():

    interface = pyipmi.interfaces.create_interface('ipmbdev', port='/dev/ipmi0')
    ipmi = pyipmi.create_connection(interface)
    ipmi.session.establish()
    ipmi.target = pyipmi.Target(ipmb_address=0x20)

    rsp = ipmi.get_power_reading(1)

    print('Power Reading')
    print('  current:   {}'.format(rsp.current_power))
    print('  minimum:   {}'.format(rsp.minimum_power))
    print('  maximum:   {}'.format(rsp.maximum_power))
    print('  average:   {}'.format(rsp.average_power))
    print('  timestamp: {}'.format(rsp.timestamp))
    print('  period:    {}'.format(rsp.period))
    print('  state:     {}'.format(rsp.reading_state))


if __name__ == '__main__':
    main() 

The device file exists with proper permissions on the machine I am testing this script:

 ls -la /dev/ipmi0
crw----rw- 1 root root 246, 0 Oct 15 07:09 /dev/ipmi0

I get timeout error when I execute the script:

$ python ipmi.py 
Traceback (most recent call last):
  File "ipmi.py", line 31, in <module>
    main() 
  File "ipmi.py", line 18, in main
    rsp = ipmi.get_power_reading(1)
  File "/home/mpaipuri/miniconda3/envs/test/lib/python3.8/site-packages/pyipmi/dcmi.py", line 35, in get_power_reading
    rsp = self.send_message_with_name('GetPowerReading',
  File "/home/mpaipuri/miniconda3/envs/test/lib/python3.8/site-packages/pyipmi/__init__.py", line 212, in send_message_with_name
    rsp = self.send_message(req)
  File "/home/mpaipuri/miniconda3/envs/test/lib/python3.8/site-packages/pyipmi/__init__.py", line 196, in send_message
    rsp = self.interface.send_and_receive(req)
  File "/home/mpaipuri/miniconda3/envs/test/lib/python3.8/site-packages/pyipmi/interfaces/ipmbdev.py", line 162, in send_and_receive
    rx_data = self._send_and_receive(target=req.target,
  File "/home/mpaipuri/miniconda3/envs/test/lib/python3.8/site-packages/pyipmi/interfaces/ipmbdev.py", line 132, in _send_and_receive
    raise IpmiTimeoutError()
pyipmi.errors.IpmiTimeoutError

I can verify the device file is working using ipmitool:

$ ipmitool -vvvvvv dcmi power reading
Using ipmi device 0
Set IPMB address to 0x20
OpenIPMI Request Message Header:
  netfn     = 0x6
  cmd       = 0x1
Sending request 0x1 to System Interface
Got message:  type      = 1
  channel   = 0xf
  msgid     = 0
  netfn     = 0x7
  cmd       = 0x1
  data_len  = 16
  data      = 002081026502dfa202000001000f4141
Iana: 674
Running Get PICMG Properties my_addr 0x20, transit 0, target 0
OpenIPMI Request Message Header:
  netfn     = 0x2c
  cmd       = 0x0
OpenIPMI Request Message Data (1 bytes)
 00
Sending request 0x0 to System Interface
Got message:  type      = 1
  channel   = 0xf
  msgid     = 1
  netfn     = 0x2d
  cmd       = 0x0
  data_len  = 1
  data      = c1
Error response 0xc1 from Get PICMG Properities
Running Get VSO Capabilities my_addr 0x20, transit 0, target 0
OpenIPMI Request Message Header:
  netfn     = 0x2c
  cmd       = 0x0
OpenIPMI Request Message Data (1 bytes)
 03
Sending request 0x0 to System Interface
Got message:  type      = 1
  channel   = 0xf
  msgid     = 2
  netfn     = 0x2d
  cmd       = 0x0
  data_len  = 1
  data      = c1
Invalid completion code received: Invalid command
Acquire IPMB address
Discovered IPMB address 0x0
Interface address: my_addr 0x20 transit 0:0 target 0x20:0 ipmb_target 0

OpenIPMI Request Message Header:
  netfn     = 0x2c
  cmd       = 0x2
OpenIPMI Request Message Data (4 bytes)
 dc 01 00 00
Sending request 0x2 to System Interface
Got message:  type      = 1
  channel   = 0xf
  msgid     = 3
  netfn     = 0x2d
  cmd       = 0x2
  data_len  = 19
  data      = 00dc63004d00d1006a0054180e67e803000040

    Instantaneous power reading:                    99 Watts
    Minimum during sampling period:                 77 Watts
    Maximum during sampling period:                209 Watts
    Average power reading over sample period:      106 Watts
    IPMI timestamp:                           Tue Oct 15 07:23:00 2024
    Sampling period:                          00000001 Seconds.
    Power reading state is:                   activated

I am not an expert in the IPMI spec but I can see that ipmitool is sending only netfn and cmd in the headers where as python-ipmi sends more headers. I have checked that the payload by both ipmitool and python-ipmi matches.

Could you please help me out or give me directions where I need to look to make it work?

Cheers!

@hthiery
Copy link
Contributor

hthiery commented Oct 15, 2024

Hi, when I quickly looked over it, I saw that you are not using an ipmbdev in your ipmitool call.

ipmitool -vvvvvv dcmi power reading this should be equivalent to ipmitool -I open -vvvvvv dcmi power reading

This is not natively implemented in this lib. You have to use the 'ipmitool' interface here and open it as interface_type.

interface = pyipmi.interfaces.create_interface('ipmitool', interface_type='open')

This is not tested. Please give it a try.

@mahendrapaipuri
Copy link
Author

Hello @hthiery

Thanks for super quick response. Really appreciate it.

If I understand correctly, ipmitool interface of this library uses ipmitool to execute the commands in a subprocess and return output. My objective is to send/receive ipmi message bytes using Linux IPMI driver in a pure Python way without having to depend on IPMI implementations like ipmitool, free-ipmi, ipmi-util, etc. That is why I thought impbdev interface is the way to do it. Probably I misunderstood it. I posted the output of ipmitool -vvvvvv dcmi power reading to show that the Linux IPMI drivers are loaded and working.

So, based on your comment, I understand that the lib does not have an implementation that interacts with device file directly. As I mentioned in the original post, the bytes created by impbdev interfaces matches very closely with the bytes reported by ipmitool. Probably, we need to use ioctl to talk to device file.

@hthiery Do you think it is too complicated to implement this in pure Python way? I might give it a go.

@mahendrapaipuri
Copy link
Author

Btw, your suggestion interface = pyipmi.interfaces.create_interface('ipmitool', interface_type='open') works.

@hthiery
Copy link
Contributor

hthiery commented Oct 15, 2024

Hello @hthiery

Thanks for super quick response. Really appreciate it.

If I understand correctly, ipmitool interface of this library uses ipmitool to execute the commands in a subprocess and return output. My objective is to send/receive ipmi message bytes using Linux IPMI driver in a pure Python way without having to depend on IPMI implementations like ipmitool, free-ipmi, ipmi-util, etc. That is why I thought impbdev interface is the way to do it. Probably I misunderstood it. I posted the output of ipmitool -vvvvvv dcmi power reading to show that the Linux IPMI drivers are loaded and working.

So, based on your comment, I understand that the lib does not have an implementation that interacts with device file directly. As I mentioned in the original post, the bytes created by impbdev interfaces matches very closely with the bytes reported by ipmitool. Probably, we need to use ioctl to talk to device file.

@hthiery Do you think it is too complicated to implement this in pure Python way? I might give it a go.

Currently I cannot estimate the needed effort. But it is possible.

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

No branches or pull requests

2 participants