Hi,
On Thu, Jan 17, 2008 at 05:23:15PM -0600, Corey Minyard wrote:
> I know why you are getting the segfault, which I will fix, but I do not
> know why the initialization is failing and causing this.
>
> Can you step through ipmi_init() with the debugger and see which exact
> function is failing to initialize?
Sorry for the delay. Did some changes in the meantime and now I
can't reproduce the coredumps anymore. I think that they were
caused by calling ipmi_init twice. If you want to pursue that
issue, I can retrieve an old version and try to reproduce the
segfault.
But I still can't make the thing work. This is the output from
ipmilan:
INFO: ipmi_lan.c(connection_up): Connection 0 to the BMC is up
INFO: ipmi_lan.c(connection_up): Connection to the BMC restored
0f 07 00 01 ff
** INFO: IPMI request 4 failed: ff
The openipmicmd with same parameters returns good status. What's
funny is that the stuff on the wire seems to be very similar in
both cases---I can see the very same response as with ipmicmd
when running ipmilan.
Looked for a long time at the source of ipmicmd and ipmilan, but
can't find any problems. Walked through both with gdb, still
didn't get any wiser. If you could take a look at the code and
tell me what's wrong with it, I'd appreciate very much. It has
been done around openipmi release 1.0 by a guy from Intel, but
he's not maintaining it any more.
Cheers,
Dejan
> -corey
>
> Dejan Muhamedagic wrote:
>> Hi,
>>
>> On Thu, Jan 17, 2008 at 09:58:42AM -0600, Corey Minyard wrote:
>>
>>> Bugs have been fixed in this code that might solve the problem. Is there
>>> any way you can try a newer version of the library?
>>>
>>
>> Tried with the latest (2.0.13) from sourceforge. The same thing:
>>
>> Thread 1 (process 12048):
>> #0 0x00000000 in ?? ()
>> No symbol table info available.
>> #1 0xb7f5c786 in locked_list_remove (ll=0x8056620, item1=0xb7b44700,
>> item2=0x0) at locked_list.c:296
>> rv = <value optimized out>
>> #2 0xb7aee30f in _ipmi_fru_deregister_decoder (
>> op=0xb7b44700 <process_fru_spd_info>) at fru.c:270
>> No locals.
>> #3 0xb7b446f0 in _ipmi_fru_spd_decoder_shutdown () at
>> fru_spd_decode.c:327
>> No locals.
>> #4 0xb7ad56ea in ipmi_init (handler=0x8056600) at ipmi.c:1029
>> rv = 11
>> #5 0xb7f680ea in setup_ipmi_conn (host=0x8051128, request=4)
>> at ipmilan_command.c:293
>> rv = 0
>> ent = (struct hostent *) 0xb7f4c455
>> lan_addr = {{s_addr = 3086282740}, {s_addr = 3086527648}}
>> lan_port = {134549680, -1079889992}
>> num_addr = 1
>> authtype = 0
>> privilege = 0
>> username = "..."
>> password = "..."
>> timer = (sel_timer_t *) 0xb7c2a179
>> timeout = {tv_sec = 134590944, tv_usec = -1079890040}
>> con = (ipmi_con_t *) 0x80575c0
>> #6 0xb7f68457 in do_ipmi_cmd (host=0x8051128, request=4)
>> at ipmilan_command.c:372
>>
>> Cheers,
>>
>> Dejan
>>
>>
>>> -corey
>>>
>>> Dejan Muhamedagic wrote:
>>>
>>>> Hi,
>>>>
>>>> This is on a openSUSE 10.3 and ipmi is:
>>>>
>>>> OpenIPMI-devel-2.0.7-102
>>>>
>>>> The backtrace:
>>>>
>>>> Thread 1 (process 8787):
>>>> #0 0x00000000 in ?? ()
>>>> No symbol table info available.
>>>> #1 0xb7f8a8b6 in locked_list_remove () from
>>>> /usr/lib/libOpenIPMIutils.so.0
>>>> No symbol table info available.
>>>> #2 0xb7b1b19f in _ipmi_fru_deregister_decoder ()
>>>> from /usr/lib/libOpenIPMI.so.0
>>>> No symbol table info available.
>>>> #3 0xb7b730f0 in _ipmi_fru_spd_decoder_shutdown ()
>>>> from /usr/lib/libOpenIPMI.so.0
>>>> No symbol table info available.
>>>> #4 0xb7b0254a in ipmi_init () from /usr/lib/libOpenIPMI.so.0
>>>> No symbol table info available.
>>>> #5 0xb7f95b1a in do_ipmi_cmd (host=0x8051028, request=4)
>>>> at ipmilan_command.c:293
>>>> No locals.
>>>> #6 0xb7f955f7 in ipmilan_status (s=0x8050f80) at ipmilan.c:231
>>>> rv = <value optimized out>
>>>> node = (struct ipmilanHostInfo *) 0x8051028
>>>> ret = 0
>>>> __FUNCTION__ = "ipmilan_status"
>>>>
>>>> The code is a bit old (from the openipmi 1.x times) and I'm
>>>> trying to revive it, so far unsuccessfully. I looked at it for a
>>>> while, but can't figure out what's wrong. ipmi_init obviously
>>>> fails and segfaults when trying to cleanup. The same device talks
>>>> without problems to the ipmitool.
>>>>
>>>> The code is below, with error checking removed for clarity.
>>>>
>>>> Cheers,
>>>> str2a: .asciz "T2a\n"
>>>>
>>>> Dejan
>>>>
>>>> os_hnd = ipmi_posix_get_os_handler();
>>>> rv = sel_alloc_selector(os_hnd, &os_sel);
>>>> ipmi_posix_os_handler_set_sel(os_hnd, os_sel);
>>>> rv = ipmi_init(os_hnd);
>>>> ent = gethostbyname(host->ipaddr);
>>>> memcpy(&lan_addr[0], ent->h_addr_list[0], ent->h_length);
>>>> lan_port[0] = host->portnumber;
>>>> lan_port[1] = 0;
>>>> authtype = host->authtype;
>>>> privilege = host->privilege;
>>>> memcpy(username, host->username, sizeof(username));
>>>> memcpy(password, host->password, sizeof(password));
>>>> rv = ipmi_lan_setup_con(lan_addr, lan_port, num_addr,
>>>> authtype,
>>>> privilege,
>>>> username, strlen(username),
>>>> password, strlen(password),
>>>> os_hnd, os_sel,
>>>> &con);
>>>> #if OPENIPMI_VERSION_MAJOR < 2
>>>> con->set_con_change_handler(con, con_changed_handler, &request);
>>>> #else
>>>> con->add_con_change_handler(con, con_changed_handler, &request);
>>>> #endif
>>>> rv = con->start_con(con);
>>>>
>>>> gettimeofday(&timeout, NULL);
>>>> timeout.tv_sec += OPERATION_TIME_OUT;
>>>> timeout.tv_usec += 0;
>>>> sel_alloc_timer(os_sel, timed_out, NULL, &timer);
>>>> sel_start_timer(timer, &timeout);
>>>>
>>>> while (1) {
>>>> rv = sel_select(os_sel, NULL, 0, NULL, NULL);
>>>> if (gstatus != IPMI_RUNNING) {
>>>> break;
>>>> }
>>>> }
>>>>
>>>> sel_free_timer(timer);
>>>>
>>>> con->close_connection(con);
>>>> ipmi_shutdown();
>>>>
>>>>
>>>> -------------------------------------------------------------------------
>>>> This SF.net email is sponsored by: Microsoft
>>>> Defy all challenges. Microsoft(R) Visual Studio 2008.
>>>> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
>>>> _______________________________________________
>>>> Openipmi-developer mailing list
>>>> [email protected]
>>>> https://lists.sourceforge.net/lists/listinfo/openipmi-developer
>>>>
>>
>> -------------------------------------------------------------------------
>> This SF.net email is sponsored by: Microsoft
>> Defy all challenges. Microsoft(R) Visual Studio 2008.
>> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
>> _______________________________________________
>> Openipmi-developer mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/openipmi-developer
>>
>
/*
* This program is largely based on the ipmicmd.c program that's part of OpenIPMI package.
*
* Copyright Intel Corp.
* [EMAIL PROTECTED]
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h> /* malloc() */
#include <unistd.h> /* getopt() */
#include <string.h> /* strerror() */
#include <netdb.h> /* gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <OpenIPMI/selector.h>
#include <OpenIPMI/ipmi_conn.h>
#include <OpenIPMI/ipmi_lan.h>
#include <OpenIPMI/ipmi_smi.h>
#include <OpenIPMI/ipmi_auth.h>
#include <OpenIPMI/ipmi_msgbits.h>
#include <OpenIPMI/ipmi_posix.h>
#include "ipmilan.h"
#include <stonith/stonith.h>
#include <clplumbing/cl_log.h>
#include <pils/plugin.h>
extern const PILPluginImports* PluginImports;
/* #define DUMP_MSG 0 */
#define OPERATION_TIME_OUT 10
os_handler_t *os_hnd=NULL;
selector_t *os_sel;
extern os_handler_t ipmi_os_cb_handlers;
typedef enum ipmi_status {
/*
IPMI_CONNECTION_FAILURE,
IPMI_SEND_FAILURE,
IPMI_BAD_REQUEST,
IPMI_REQUEST_FAILED,
IPMI_TIME_OUT,
*/
IPMI_RUNNING = 99,
} ipmi_status_t;
static ipmi_status_t gstatus;
typedef enum chassis_control_request {
POWER_DOWN = 0X00,
POWER_UP = 0X01,
POWER_CYCLE = 0X02,
HARD_RESET = 0X03,
PULSE_DIAGNOSTIC_INTERRUPT = 0X04,
SOFT_SHUTDOWN = 0X05
} chassis_control_request_t;
void dump_msg_data(ipmi_msg_t *msg, ipmi_addr_t *addr, const char *type);
int rsp_handler(ipmi_con_t *ipmi, ipmi_msgi_t *rspi);
void send_ipmi_cmd(ipmi_con_t *con, int request);
void timed_out(selector_t *sel, sel_timer_t *timer, void *data);
void
timed_out(selector_t *sel, sel_timer_t *timer, void *data)
{
PILCallLog(PluginImports->log,PIL_CRIT, "IPMI operation timed out... :(\n");
gstatus = S_TIMEOUT;
}
void
dump_msg_data(ipmi_msg_t *msg, ipmi_addr_t *addr, const char *type)
{
ipmi_system_interface_addr_t *smi_addr = NULL;
int i;
ipmi_ipmb_addr_t *ipmb_addr = NULL;
if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
smi_addr = (struct ipmi_system_interface_addr *) addr;
fprintf(stderr, "%2.2x %2.2x %2.2x %2.2x ",
addr->channel,
msg->netfn,
smi_addr->lun,
msg->cmd);
} else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
|| (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
ipmb_addr = (struct ipmi_ipmb_addr *) addr;
fprintf(stderr, "%2.2x %2.2x %2.2x %2.2x ",
addr->channel,
msg->netfn,
ipmb_addr->lun,
msg->cmd);
}
for (i = 0; i < msg->data_len; i++) {
if (((i%16) == 0) && (i != 0)) {
printf("\n ");
}
fprintf(stderr, "%2.2x ", msg->data[i]);
}
fprintf(stderr, "\n");
}
/*
* This function gets called after the response comes back
* from the IPMI device.
*
* Some IPMI device does not return success, 0x00, to the
* remote node when the power-reset was issued.
*
* The host who sent the ipmi cmd might get a 0xc3,
* a timeout instead. This creates problems for
* STONITH operation, where status is critical. :(
*
* Right now I am only checking 0xc3 as the return.
* If your IPMI device returns some wired code after
* reset, you might want to add it in this code block.
*
*/
int
rsp_handler(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
{
int rv;
long request;
dump_msg_data(&rspi->msg, &rspi->addr, "response");
request = (long) rspi->data1;
if( !rspi || !(rspi->msg.data) ) {
PILCallLog(PluginImports->log,PIL_CRIT, "No data received\n");
gstatus = S_RESETFAIL;
return IPMI_MSG_ITEM_NOT_USED;
}
rv = rspi->msg.data[0];
/* some IPMI device might not issue 0x00, success, for reset command.
instead, a 0xc3, timeout, is returned. */
if (rv == 0x00 ||
((rv == 0xc3 || rv == 0xff) && request == ST_GENERIC_RESET) ) {
gstatus = S_OK;
} else {
PILCallLog(PluginImports->log,PIL_INFO
, "IPMI request %ld failed: %x\n", request, rv);
gstatus = S_RESETFAIL;
}
return IPMI_MSG_ITEM_NOT_USED;
}
void
send_ipmi_cmd(ipmi_con_t *con, int request)
{
ipmi_addr_t addr;
unsigned int addr_len;
ipmi_msg_t msg;
struct ipmi_system_interface_addr *si;
int rv;
ipmi_msgi_t *rspi;
/* chassis control command request is only 1 byte long */
unsigned char cc_data = POWER_CYCLE;
si = (void *) &addr;
si->lun = 0x00;
si->channel = IPMI_BMC_CHANNEL;
si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
addr_len = sizeof(*si);
msg.netfn = IPMI_CHASSIS_NETFN;
msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
msg.data = &cc_data;
msg.data_len = 1;
switch (request) {
case ST_POWERON:
cc_data = POWER_UP;
break;
case ST_POWEROFF:
cc_data = POWER_DOWN;
break;
case ST_GENERIC_RESET:
cc_data = POWER_CYCLE;
break;
case ST_IPMI_STATUS:
msg.netfn = IPMI_APP_NETFN;
msg.cmd = IPMI_GET_DEVICE_ID_CMD;
msg.data_len = 0;
break;
default:
gstatus = S_INVAL;
return;
}
gstatus = S_ACCESS;
rspi = calloc(1, sizeof(ipmi_msgi_t));
if (NULL == rspi) {
PILCallLog(PluginImports->log,PIL_CRIT, "Error sending IPMI command: Out of memory\n");
} else {
rspi->data1 = (void *) (long) request;
rv = con->send_command(con, &addr, addr_len, &msg, rsp_handler, rspi);
if (rv == -1) {
PILCallLog(PluginImports->log,PIL_CRIT, "Error sending IPMI command: %x\n", rv);
}
}
return;
}
static int request_done = 0;
static void
con_changed_handler(ipmi_con_t *ipmi, int err, unsigned int port_num,
int still_connected, void *cb_data)
{
int * request;
if (err) {
PILCallLog(PluginImports->log,PIL_CRIT, "Unable to setup connection: %x\n", err);
return;
}
if( !request_done ) {
request = (int *) cb_data;
send_ipmi_cmd(ipmi, *request);
request_done = 1;
}
}
static int
setup_ipmi_conn(struct ipmilanHostInfo * host, int request)
{
int rv;
struct hostent *ent;
struct in_addr lan_addr[2];
int lan_port[2];
int num_addr = 1;
int authtype = 0;
int privilege = 0;
char username[17];
char password[17];
static ipmi_con_t *con;
sel_timer_t * timer;
struct timeval timeout;
request_done = 0;
if( !os_hnd ) { /* already initialized? */
os_hnd = ipmi_posix_get_os_handler();
if (!os_hnd) {
PILCallLog(PluginImports->log,PIL_CRIT, "ipmi_smi_setup_con: Unable to allocate os handler");
return 1;
}
rv = sel_alloc_selector(os_hnd, &os_sel);
if (rv) {
PILCallLog(PluginImports->log,PIL_CRIT, "Could not allocate selector\n");
return rv;
}
ipmi_posix_os_handler_set_sel(os_hnd, os_sel);
rv = ipmi_init(os_hnd);
if (rv) {
PILCallLog(PluginImports->log,PIL_CRIT, "ipmi_init erro: %d ", rv);
return rv;
}
}
ent = gethostbyname(host->ipaddr);
if (!ent) {
PILCallLog(PluginImports->log,PIL_CRIT, "gethostbyname failed: %s\n", strerror(h_errno));
return 1;
}
memcpy(&lan_addr[0], ent->h_addr_list[0], ent->h_length);
lan_port[0] = host->portnumber;
lan_port[1] = 0;
authtype = host->authtype;
privilege = host->privilege;
memcpy(username, host->username, sizeof(username));
memcpy(password, host->password, sizeof(password));
rv = ipmi_lan_setup_con(lan_addr, lan_port, num_addr,
authtype, privilege,
username, strlen(username),
password, strlen(password),
os_hnd, os_sel,
&con);
if (rv) {
PILCallLog(PluginImports->log,PIL_CRIT, "ipmi_lan_setup_con: %s\n", strerror(rv));
return S_ACCESS;
}
#if OPENIPMI_VERSION_MAJOR < 2
con->set_con_change_handler(con, con_changed_handler, &request);
#else
con->add_con_change_handler(con, con_changed_handler, &request);
#endif
gstatus = IPMI_RUNNING;
rv = con->start_con(con);
if (rv) {
PILCallLog(PluginImports->log,PIL_CRIT, "Could not start IPMI connection: %x\n", rv);
gstatus = S_BADCONFIG;
return rv;
}
gettimeofday(&timeout, NULL);
timeout.tv_sec += OPERATION_TIME_OUT;
timeout.tv_usec += 0;
sel_alloc_timer(os_sel, timed_out, NULL, &timer);
sel_start_timer(timer, &timeout);
while (1) {
rv = sel_select(os_sel, NULL, 0, NULL, NULL);
if (gstatus != IPMI_RUNNING) {
break;
}
}
sel_free_timer(timer);
con->close_connection(con);
/*ipmi_shutdown();*/
return gstatus;
}
int
do_ipmi_cmd(struct ipmilanHostInfo * host, int request)
{
return setup_ipmi_conn(host, request);
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer