IPMI 实用小代码,捕获对应BMC raw命令来实现对上层系统控制
1 背景
我们知道在 IPMI 的环境中,BMC 纳管了很多是管理层面的工作,比如上下电就是其中一个。 这里,我们可以通过捕获对应BMC raw命令来实现对上层系统控制。比如这个例子就实现了对系统关机操作。
2 具体代码实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <sys/select.h> #include <sys/ioctl.h> #include <linux/ipmi.h> #include <stdio.h> #define NETFN 0x2c /* hardware specific */ #define CMD 0x0c /* hardware specific */
int main(void) { int fd,ret; struct ipmi_cmdspec cmdspec; unsigned char data[IPMI_MAX_MSG_LENGTH]; struct ipmi_addr addr; struct ipmi_recv recv; fd = open("/dev/ipmi0", O_RDWR); if (fd == -1) { return 1; }
cmdspec.netfn = NETFN; cmdspec.cmd = CMD;
ret = ioctl(fd, IPMICTL_REGISTER_FOR_CMD, &cmdspec); /* checking the signal */ if (ret == -1) { perror("ioctl register_for_cmd"); return 1; }
while (1) /* keep monitoring*/ { sleep(1); recv.msg.data = data; recv.msg.data_len = sizeof(data); recv.addr = (unsigned char *) &addr; recv.addr_len = sizeof(addr); ret = ioctl(fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv); if ((recv.msg.netfn == NETFN) && (recv.msg.cmd == CMD)) { system("init 0"); /* shut it down*/ } }
ret = ioctl(fd, IPMICTL_UNREGISTER_FOR_CMD, &cmdspec); if (ret == -1) { perror("ioctl unregister_for_cmd"); return 1; } close(fd); return 0; }
|