Coder Social home page Coder Social logo

go-ipmi's People

Contributors

bougou avatar duanchao2035 avatar elbandi avatar kseniadumpling avatar mdhorn avatar zhujinhe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

go-ipmi's Issues

Code self selection

Hi, I'd like to ask you how to set the next time the server starts pxe, and reset the power through the lanplus mode

Local mode client get io timeout error

Hi, when I use local mode client in one of my devices, I get this error:

`
Device ID : 1
Device Revision : 1
Firmware Revision : 1.0
IPMI Version : 2.0
Manufacturer ID : 7154 (0x1bf2)
Manufacturer Name : Unknown
Product ID : 1 (0x0001)
Product Name : 0x01
Device Available : yes
Provides Device SDRs : no
Additional Device Support :
Chassis Device
FRU Inventory Device
SEL Device
SDR Repo Device
Sensor Device
Aux Firmware Rev Info :
0x00
0x00
0x00
0x00
panic: GetSELEntry failed, err: openSendRequest failed, err: failed to read from syscall conn: i/o timeout

goroutine 1 [running]:
main.main()
`

Device info:
CPU: Intel(R) Atom(TM) x7835RE
Memory: 8GB

The function calling chain is:
client.GetSELEntries(0) --> c.GetSELInfo() --> c.Exchange(request, response) --> c.exchangeOpen(request, response) --> c.openSendRequest(request) --> open.SendCommand(c.openipmi.file, req) --> conn.Read(readMsgFunc)

By the way, if I use lanplus mode to the this device, this error will not happen

ParseSDR failed, err: sdr data must be longer than 5

Hello there, and thanks again for implementing sensor readings in #15!

I use the sensor readings to monitor my home server temps over IPMI, you can see the code here. Most of the time, it works flawlessly, but after running for a while, I occasionally see this behavior:

image

Basically, the data looks good, and then it alternates between the failure ParseSDR failed, err: sdr data must be longer than 5 and returning a value of -124. When I manually run:

ipmitool -I lanplus -H <ip> -U <user> -P <pass> sensor get 'Ambient Temp'

I get the correct output of Sensor Reading : 30 (+/- 1) degrees C

It seems like something is getting out of sync, perhaps with the long-lived connection I'm creating. I saw this behavior once before, maybe after the same amount of time, but I don't have logs for the last time I saw this. This time, the monitoring was running for ~87 hours and 41 minutes before showing the wrong readings.

Any ideas?

Concurrent requests will have some timeouts without returning results

When I use ipmitools command, 50 concurrent requests can return all,
but I use this package 23 concurrent request has one timeout.
The result:
image

image

The code:

`package main

import (
"bytes"
"errors"
"fmt"
"github.com/bougou/go-ipmi"
"os/exec"
"sync"
"sync/atomic"
"time"
)

var total atomic.Int32

func main() {
var wg sync.WaitGroup
ip := "xxxxxxx"
port := 623
username := "xxxxx"
password := "xxxxx"
for i := 0; i < 23; i++ {
wg.Add(1)
getResultFromIPMI(ip, port, username, password, &wg)
//getCmdOut()
}
wg.Wait()
}

func getCmdOut() {
cmd := "./ipmitool -I lanplus -H xxxxxx -U xxxxx -P xxxxxxx fru"
cmd2 := exec.Command("sh", "-c", cmd)

var out bytes.Buffer
var stderr bytes.Buffer
cmd2.Stdout = &out
cmd2.Stderr = &stderr
err := cmd2.Run()
if err != nil {
	fmt.Println(errors.New(fmt.Sprint(err) + ": " + stderr.String()))
	return
}
fmt.Println(out.String())
total.Add(1)
fmt.Println("total:", total)

}

// 走ipmi协议取数据
func getResultFromIPMI(ip string, port int, username, password string, wg *sync.WaitGroup) ([][]interface{}, error) {
defer wg.Done()
client, err := connectIPMI(ip, port, username, password) //连接ipmi
if err != nil {
return nil, err
}
defer client.Close()
//从ipmi协议取数据
var arr [][]interface{}
arr, err = fru(client) //取sensor类型数据
if err != nil {
return nil, err
}
fmt.Println(arr)
return arr, nil
}

// 连接ipmi
func connectIPMI(ip string, port int, username string, password string) (*ipmi.Client, error) {
var c *ipmi.Client
var err error
//没有,重新连接
c, err = ipmi.NewClient(ip, port, username, password)
if err != nil {
fmt.Println(err)
return nil, err
}
c.WithInterface("lanplus")
c.WithTimeout(30 * time.Second)
if err = c.Connect(); err != nil { //TODO 有时候很慢,有时候很快
fmt.Println(err)
return nil, err
}
c.Interface = "lanplus"
//defer c.Close() //连接缓存就不用关闭了
return c, nil
}

// 取fru类型数据
func fru(client *ipmi.Client) ([][]interface{}, error) {
res, err := client.GetFRUs() //2秒
if err != nil {
return nil, err
}
arr := make([][]interface{}, len(res), len(res))
for index, value := range res {
item := make([]interface{}, 1, 1)
item[0] = value.String()
arr[index] = item
}
return arr, nil
}
`

Sensors Error

Hello,

This is a cool project. Thank you for spending the time maintaining it.

I'm not sure if the project is for me yet, but I'm evaluating it, and in doing so ran into an error. Mostly for your information, but if you have ideas, that's great too.

Test code

package main

import (
	"fmt"
	"log"

	"github.com/bougou/go-ipmi"
)

func GetIPMI() error {
	client, err := ipmi.NewOpenClient()
	if err != nil {
		return err
	}

	if err := client.Connect(); err != nil {
		return err
	}

	res, err := client.GetDeviceID()
	if err != nil {
		return err
	}

	fmt.Println(res.Format())
	fmt.Println("Getting sensors")

	sensors, err := client.GetSensors()
	if err != nil {
		return err
	}

	fmt.Println("got sensors")

	for _, sensor := range sensors {
		fmt.Println(sensor.Name, sensor.Value, sensor.SensorUnit)
	}
	
	return nil
}

func main() {
	if err := GetIPMI(); err != nil {
		log.Fatal(err)
	}
}

Running Linux on a Dell PowerEdge R730xd as root, this is the output of the above app:

Device ID                 : 32
Device Revision           : 1
Firmware Revision         : 2.82
IPMI Version              : 2.0
Manufacturer ID           : 674 (0x2a2)
Manufacturer Name         : Dell
Product ID                : 256 (0x0100)
Product Name              : 0x100
Device Available          : yes
Provides Device SDRs      : yes
Additional Device Support :
    Chassis Device
    Bridge Device
    IPMB Event Receiver
    FRU Inventory Device
    SEL Device
    SDR Repo Device
    Sensor Device
Aux Firmware Rev Info     :
    0x00
    0x04
    0x52
    0x52
Getting sensors
2023/02/16 22:50:55 GetSensorFromSDR failed, err: setSensorThreshold failed, err: GetSensorThresholds for sensor 0x6a failed, err: ipmiRes CompletaionCode (0xcd) is not normal: Command illegal for specified sensor or record type

errors for lanprint

When i execute command ipmi-go lan print 1, that is a error:

error: GetLanConfig failed, err: get lan config param (Destination Addresses) failed, err: the data for param (Destination Addresses) is too short, input (13), required (18)

i find the relative code like this.

// cmd_get_lan_config_params.go
	case LanParam_AlertDestinationAddress:
		lanConfig.AlertDestinationAddress = AlertDestinationAddress{
			SetSelector:         paramData[0],
			AddressFormat:       (paramData[1] & 0xf0) >> 4,
			IP4UseBackupGateway: isBit0Set(paramData[2]),
			IP4IP:               net.IP(paramData[3:7]),
			IP4MAC:              net.HardwareAddr(paramData[7:12]),
			IP6IP:               net.IP(paramData[2:18]),
		}
var LanParams = []LanParam{
// types_lan_params.go
        ...
	{Selector: LanParam_AlertDestinationAddress, DataSize: 18, Name: "Destination Addresses"},
        ...
}

So why need to check this size.

rakp1 failed, err: unpack session setup response failed, err: unpacked data is too short

I will report an error when I link the bmc using the following method

func (b BmcClient) BmcClient() (clients []*ipmi.Client, err error) {
	clients = make([]*ipmi.Client, 0)
	if len(b.Hosts) == 0 {
		return nil, errors.New("not found host")
	}
	for _, host := range b.Hosts {
		client, err := ipmi.NewClient(host.IP, host.Port, host.Username, host.Password)
		if err != nil {

			return nil, err
		}
		switch b.Protocol {
		case "lan":
			client.Interface = ipmi.InterfaceLan
		case "lanplus":
			client.Interface = ipmi.InterfaceLanplus
		case "open":
			client.Interface = ipmi.InterfaceOpen
		default:
			return nil, fmt.Errorf("not protocol type %s", b.Protocol)
		}
		if err := client.Connect(); err != nil {
			return nil, err
		}
		clients = append(clients, client)
	}
	return clients, nil
}

rakp1 failed, err: unpack session setup response failed, err: unpacked data is too short

GetLanConfigParams() return nil

Hi, I want to get the mac address by GetLanConfigParams(), but it returns null.

func main() {
	host := "172.16.253.17"
	port := 623
	username := "Admin"
	password := "Admin"
	client, err := ipmi.NewClient(host, port, username, password)
	if err != nil {
		panic(err)
	}
	client.WithInterface(ipmi.InterfaceLanplus)
	if err := client.Connect(); err != nil {
		panic(err)
	}
	res, err := client.GetLanConfigParams(1, ipmi.LanParamSelector(5))
	if err != nil {
		panic(err)
	}
	fmt.Println(res.Format())
}

using ipmitools can get it successfuly

root@master1:~# ipmitool -I lanplus -H 172.16.253.17 -U Admin -P Admin lan print 1
Set in Progress         : Set Complete
Auth Type Support       : NONE MD2 MD5 PASSWORD 
Auth Type Enable        : Callback : MD2 MD5 PASSWORD 
                        : User     : MD2 MD5 PASSWORD 
                        : Operator : MD2 MD5 PASSWORD 
                        : Admin    : MD2 MD5 PASSWORD 
                        : OEM      : MD2 MD5 PASSWORD 
IP Address Source       : Static Address
IP Address              : 172.16.253.17
Subnet Mask             : 255.255.255.0
MAC Address             : 7c:c2:55:51:8e:5e
SNMP Community String   : public
IP Header               : TTL=0x00 Flags=0x00 Precedence=0x00 TOS=0x00
BMC ARP Control         : ARP Responses Enabled, Gratuitous ARP Disabled
Default Gateway IP      : 172.16.253.254
Default Gateway MAC     : 00:00:00:00:00:00
Backup Gateway IP       : 0.0.0.0
Backup Gateway MAC      : 00:00:00:00:00:00
802.1q VLAN ID          : Disabled
802.1q VLAN Priority    : 0
RMCP+ Cipher Suites     : 1,2,3,6,7,8,11,12
Cipher Suite Priv Max   : XaaaXXaaaXXaaXX
                        :     X=Cipher Suite Unused
                        :     c=CALLBACK
                        :     u=USER
                        :     o=OPERATOR
                        :     a=ADMIN
                        :     O=OEM
Bad Password Threshold  : 3
Invalid password disable: yes
Attempt Count Reset Int.: 300
User Lockout Interval   : 300

why client.GetSensors() is unstable?

I found two phenomena and need your help. Would you like to help me?
1、every time when I connect, then getSensors is unstable:
Sometimes, I can get the data that I want.
Sometimes, I can't get data and return an error:

Get Channel Authentication Capabilities failed, err: client udp exchange msg failed, err: read from conn failed, err: read udp 10.128.6.107:50132->10.128.9.201:623: i/o timeout

sometimes, I got another error:

GetSDRs failed, err: ParseSDR failed, err: sdr data must be longer than 5

2、 when I connect one time, use this connect to getSensors more times,
I can get data in minutes,
if I don't get data in minutes, then I use before conn to get data, then I got an error:

GetSDR for recordID (0x0) failed, err: client udp exchange msg failed, err: read from conn failed, err: read udp 10.128.6.107:52088->10.128.9.201:623: i/o timeout

I guess connect may be expired? If I guess right, how does set connect never be expired?

当 GetSensorReading 返回错误时,sensor.readingUnavailable 为默认值 false,导致 sensor.IsReadingValid 判断不符合预期

https://github.com/bougou/go-ipmi/blob/main/cmd_get_sensors.go#L162
当 GetSensorReading 返回错误时,函数会提前返回。此时 sensor.readingUnavailable 为默认值 false,并且没有从 readingRes 获取到 sensor 的 value。因为没有获取成功数据,预期调用 sensor.ReadingStr 应该返回 N/A,但由于 sensor.readingUnavailable 为默认值 false,导致返回了 0 值。

'Sensor Reading' not implemented

Hi there, and thanks for making this package!

The TL;DR is that Sensor Reading doesn't appear to be implemented, or I'm using it wrong. The rest of this issue is just explanation, but I think the real problem is that I was confusing Sensor Reading with Nominal Reading. Currently, Sensor Reading is hardcoded to zero, and I think this is the value I really want here. Are there any plans to implement this? If not, I'm happy to give it a shot and contribute a PR, any pointers would be appreciated.


I've been using this to access IPMI on Dell M610 blade servers in this project, specifically here. One thing I've noticed is that result of sdr.Full.ConvertReading(sdr.Full.NominalReadingRaw) never changes, and the results of running the equivalent ipmitool command produce different output. For example:

ipmitool -I lanplus -H <ip> -U <user> -P <pass> sensor get 'Ambient Temp' produces:

Locating sensor record...
Sensor ID              : Ambient Temp (0x8)
 Entity ID             : 7.1
 Sensor Type (Threshold)  : Temperature
 Sensor Reading        : 21 (+/- 1) degrees C
 Status                : ok
 Lower Non-Recoverable : na
 Lower Critical        : 3.000
 Lower Non-Critical    : 8.000
 Upper Non-Critical    : 42.000
 Upper Critical        : 47.000
 Upper Non-Recoverable : na
 Positive Hysteresis   : 1.000
 Negative Hysteresis   : 1.000
 Assertions Enabled    : lnc- lcr- unc+ ucr+
 Deassertions Enabled  : lnc- lnc+ lcr+ unc+ ucr+

A (hopefully) equivalent invocation in Go:

sdr, err := ic.GetSDRBySensorName("Ambient Temp")
if err != nil {  ...  }
fmt.Println(sdr.Full.String())       

This produces:

Sensor ID              : Ambient Temp (0x08)
Generator             : 0x20
Entity ID             : 7.1 (system board)
Sensor Type (threshold)      : Temperature (0x01)
Sensor Reading        : 0 (+/- 2) degrees C
Sensor Initialization :
  Settable            : false
  Scanning            : true
  Events              : true
  Hysteresis          : true
  Sensor Type         : true
  Default State:
    Event Generation  : enabled
    Scanning          : enabled
Sensor Capabilities   :
  Auto Re-arm         : yes(auto)
        Hysteresis Support  : ReadableSettable
        Threshold Access    : ReadableSettable
        Ev Message Control  : Per-threshold
Mask                  :
  Readable Thresholds : unc ucr lnc lcr
  Settable Thresholds : unc ucr lnc lcr
  Threshold Read Mask : unc ucr lnc lcr
  Assertions Enabled  :
  Deassertions Enabled:
Nominal Reading       : 0x97/23.000
Normal Minimum        : 0x8b/11.000
Normal Maximum        : 0xc5/69.000
Lower Non-Recoverable : unspecified
Lower Critical        : 0x83/3.000
Lower Non-Critical    : 0x88/8.000
Upper Non-Critical    : 0xaa/42.000
Upper Critical        : 0xaf/47.000
Upper Non-Recoverable : unspecified
Positive Hysteresis   : 0x01/-127.000
Negative Hysteresis   : 0x01/-127.000
Minimum sensor range  : unspecified
Maximum sensor range  : unspecified
SensorDirection       : 0
LinearizationFunc     : linear(0)
Reading Factors       : M: (1), T: (2), B: (-128), A: (194), A_Exp: (0), R_Exp: (0), B_Exp: (0)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.