github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/exp/ipmidump/ipmidump.go (about)

     1  // Copyright 2019-2020 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Synopsis:
     6  //     ipmidump [-option]
     7  //
     8  // Description:
     9  //
    10  // Options:
    11  //     -chassis : Print chassis power status.
    12  //     -sel     : Print SEL information.
    13  //     -help    : Print help message.
    14  package main
    15  
    16  import (
    17  	"flag"
    18  	"fmt"
    19  	"os"
    20  	"time"
    21  
    22  	"github.com/u-root/u-root/pkg/ipmi"
    23  )
    24  
    25  const cmd = "ipmidump [options] "
    26  
    27  var (
    28  	flagChassis = flag.Bool("chassis", false, "print chassis power status")
    29  	flagSEL     = flag.Bool("sel", false, "print SEL information")
    30  	flagHelp    = flag.Bool("help", false, "print help message")
    31  )
    32  
    33  func itob(i int) bool { return i != 0 }
    34  
    35  func init() {
    36  	defUsage := flag.Usage
    37  	flag.Usage = func() {
    38  		os.Args[0] = cmd
    39  		defUsage()
    40  	}
    41  }
    42  
    43  func main() {
    44  	flag.Parse()
    45  
    46  	if *flagHelp {
    47  		flag.Usage()
    48  		os.Exit(1)
    49  	}
    50  
    51  	if *flagChassis {
    52  		chassisInfo()
    53  	}
    54  
    55  	if *flagSEL {
    56  		selInfo()
    57  	}
    58  }
    59  
    60  func chassisInfo() {
    61  	allow := map[bool]string{true: "allowed", false: "not allowed"}
    62  	act := map[bool]string{true: "active", false: "inactive"}
    63  	state := map[bool]string{true: "true", false: "false"}
    64  
    65  	policy := map[int]string{
    66  		0x0: "always-off",
    67  		0x1: "previous",
    68  		0x2: "always-on",
    69  		0x3: "unknown",
    70  	}
    71  
    72  	event := map[int]string{
    73  		0x10: "IPMI command",
    74  		0x08: "power fault",
    75  		0x04: "power interlock",
    76  		0x02: "power overload",
    77  		0x01: "AC failed",
    78  		0x00: "none",
    79  	}
    80  
    81  	ipmi, err := ipmi.Open(0)
    82  	if err != nil {
    83  		fmt.Printf("Failed to open ipmi device: %v\n", err)
    84  	}
    85  	defer ipmi.Close()
    86  
    87  	if status, err := ipmi.GetChassisStatus(); err != nil {
    88  		fmt.Printf("Failed to get chassis power status: %v\n", err)
    89  	} else {
    90  		// Current power status
    91  		data := int(status.CurrentPowerState)
    92  		fmt.Println("Chassis power status")
    93  		fmt.Println("Power Restore Policy:", policy[(data>>5)&0x03])
    94  		fmt.Println("Power Control Fault :", state[itob(data&0x10)])
    95  		fmt.Println("Power Fault         :", state[itob(data&0x08)])
    96  		fmt.Println("Power Interlock     :", act[itob(data&0x04)])
    97  		fmt.Println("Power Overload      :", state[itob(data&0x02)])
    98  		fmt.Printf("Power Status        : ")
    99  		if (data & 0x01) != 0 {
   100  			fmt.Println("on")
   101  		} else {
   102  			fmt.Println("off")
   103  		}
   104  
   105  		// Last power event
   106  		data = int(status.LastPowerEvent)
   107  		fmt.Println("Last Power Event    :", event[data&0x1F])
   108  
   109  		// Misc. chassis state
   110  		data = int(status.MiscChassisState)
   111  		fmt.Println("Misc. chassis state")
   112  		fmt.Println("Cooling/Fan Fault   :", state[itob(data&0x08)])
   113  		fmt.Println("Drive Fault         :", state[itob(data&0x04)])
   114  		fmt.Println("Front Panel Lockout :", act[itob(data&0x02)])
   115  		fmt.Println("Chass Intrusion     :", act[itob(data&0x01)])
   116  
   117  		// Front panel button (optional)
   118  		data = int(status.FrontPanelButton)
   119  		if status.FrontPanelButton != 0 {
   120  			fmt.Println("Front Panel Button")
   121  			fmt.Println("Standby Button Disable    :", allow[itob(data&0x80)])
   122  			fmt.Println("Diagnostic Buttton Disable:", allow[itob(data&0x40)])
   123  			fmt.Println("Reset Button Disable      :", allow[itob(data&0x20)])
   124  			fmt.Println("Power-off Button Disable  :", allow[itob(data&0x10)])
   125  
   126  			fmt.Println("Standby Button            :", state[itob(data&0x08)])
   127  			fmt.Println("Diagnostic Buttton        :", state[itob(data&0x04)])
   128  			fmt.Println("Reset Button              :", state[itob(data&0x02)])
   129  			fmt.Println("Power-off Button          :", state[itob(data&0x01)])
   130  		} else {
   131  			fmt.Println("Front Panel Button  : none")
   132  		}
   133  	}
   134  }
   135  
   136  func selInfo() {
   137  	support := map[bool]string{true: "supported", false: "unsupported"}
   138  
   139  	ipmi, err := ipmi.Open(0)
   140  	if err != nil {
   141  		fmt.Printf("Failed to open ipmi device: %v\n", err)
   142  	}
   143  	defer ipmi.Close()
   144  
   145  	if info, err := ipmi.GetSELInfo(); err != nil {
   146  		fmt.Printf("Failed to get SEL information: %v\n", err)
   147  	} else {
   148  		fmt.Println("SEL information")
   149  
   150  		switch info.Version {
   151  		case 0x51:
   152  			fallthrough
   153  		case 0x02:
   154  			fmt.Printf("Version        : %d.%d (1.5, 2.0 compliant)\n", info.Version&0x0F, info.Version>>4)
   155  		default:
   156  			fmt.Println("Version        : unknown")
   157  		}
   158  
   159  		fmt.Println("Entries        :", info.Entries)
   160  		fmt.Printf("Free Space     : %d bytes\n", info.FreeSpace)
   161  
   162  		// Most recent addition/erase timestamp
   163  		fmt.Printf("Last Add Time  : ")
   164  		if info.LastAddTime != 0xFFFFFFFF {
   165  			fmt.Println(time.Unix(int64(info.LastAddTime), 0))
   166  		} else {
   167  			fmt.Println("not available")
   168  		}
   169  
   170  		fmt.Printf("Last Del Time  : ")
   171  		if info.LastDelTime != 0xFFFFFFFF {
   172  			fmt.Println(time.Unix(int64(info.LastDelTime), 0))
   173  		} else {
   174  			fmt.Println("not available")
   175  		}
   176  
   177  		// Operation Support
   178  		fmt.Printf("Overflow       : ")
   179  		if (info.OpSupport & 0x80) != 0 {
   180  			fmt.Println("true")
   181  		} else {
   182  			fmt.Println("false")
   183  		}
   184  
   185  		data := int(info.OpSupport)
   186  		if (data & 0x0F) != 0 {
   187  			fmt.Println("Supported cmds")
   188  			fmt.Println("Delete         :", support[itob(data&0x08)])
   189  			fmt.Println("Partial Add    :", support[itob(data&0x04)])
   190  			fmt.Println("Reserve        :", support[itob(data&0x02)])
   191  			fmt.Println("Get Alloc Info :", support[itob(data&0x01)])
   192  		} else {
   193  			fmt.Println("Supported cmds : none")
   194  		}
   195  	}
   196  }