mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
open: checking received msg id against expectation
Check the received IPMI response message id against the id expected given the IPMI request. They need to match. It is possible that request A times out, request B is sent, and then request A responds to the request B. The value for request B may be behind it in the queue. Note: This may only be possible if the file is kept open between multiple IPMI messages (a common occurrence). Resolves: #82 Signed-off-by: Patrick Venture <venture@google.com>
This commit is contained in:
parent
3bfa1da201
commit
51634fd77c
@ -342,48 +342,61 @@ ipmi_openipmi_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)
|
||||
read_timeout.tv_sec = IPMI_OPENIPMI_READ_TIMEOUT;
|
||||
read_timeout.tv_usec = 0;
|
||||
do {
|
||||
retval = select(intf->fd + 1, &rset, NULL, NULL, &read_timeout);
|
||||
} while (retval < 0 && errno == EINTR);
|
||||
if (retval < 0) {
|
||||
lperror(LOG_ERR, "I/O Error");
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
} else if (retval == 0) {
|
||||
lprintf(LOG_ERR, "No data available");
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (FD_ISSET(intf->fd, &rset) == 0) {
|
||||
lprintf(LOG_ERR, "No data available");
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
recv.addr = (unsigned char *)&addr;
|
||||
recv.addr_len = sizeof(addr);
|
||||
recv.msg.data = rsp.data;
|
||||
recv.msg.data_len = sizeof(rsp.data);
|
||||
|
||||
/* get data */
|
||||
if (ioctl(intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv) < 0) {
|
||||
lperror(LOG_ERR, "Error receiving message");
|
||||
if (errno != EMSGSIZE) {
|
||||
do {
|
||||
retval = select(intf->fd + 1, &rset, NULL, NULL, &read_timeout);
|
||||
} while (retval < 0 && errno == EINTR);
|
||||
if (retval < 0) {
|
||||
lperror(LOG_ERR, "I/O Error");
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
} else if (retval == 0) {
|
||||
lprintf(LOG_ERR, "No data available");
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(intf->fd, &rset) == 0) {
|
||||
lprintf(LOG_ERR, "No data available");
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
recv.addr = (unsigned char *)&addr;
|
||||
recv.addr_len = sizeof(addr);
|
||||
recv.msg.data = rsp.data;
|
||||
recv.msg.data_len = sizeof(rsp.data);
|
||||
|
||||
/* get data */
|
||||
if (ioctl(intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv) < 0) {
|
||||
lperror(LOG_ERR, "Error receiving message");
|
||||
if (errno != EMSGSIZE) {
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the message received wasn't expected, try to grab the
|
||||
* next message until it's out of messages. -EAGAIN is
|
||||
* returned if the list empty, but basically if it returns a
|
||||
* message, check if it's alright.
|
||||
*/
|
||||
if (_req.msgid != recv.msgid) {
|
||||
lprintf(LOG_NOTICE,
|
||||
"Received a response with unexpected ID %ld vs. %ld",
|
||||
recv.msgid, _req.msgid);
|
||||
}
|
||||
} while (_req.msgid != recv.msgid);
|
||||
|
||||
if (verbose > 4) {
|
||||
fprintf(stderr, "Got message:");
|
||||
|
Loading…
x
Reference in New Issue
Block a user