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_sec = IPMI_OPENIPMI_READ_TIMEOUT;
|
||||||
read_timeout.tv_usec = 0;
|
read_timeout.tv_usec = 0;
|
||||||
do {
|
do {
|
||||||
retval = select(intf->fd + 1, &rset, NULL, NULL, &read_timeout);
|
do {
|
||||||
} while (retval < 0 && errno == EINTR);
|
retval = select(intf->fd + 1, &rset, NULL, NULL, &read_timeout);
|
||||||
if (retval < 0) {
|
} while (retval < 0 && errno == EINTR);
|
||||||
lperror(LOG_ERR, "I/O Error");
|
if (retval < 0) {
|
||||||
if (data) {
|
lperror(LOG_ERR, "I/O Error");
|
||||||
free(data);
|
if (data) {
|
||||||
data = NULL;
|
free(data);
|
||||||
}
|
data = NULL;
|
||||||
return NULL;
|
}
|
||||||
} else if (retval == 0) {
|
return NULL;
|
||||||
lprintf(LOG_ERR, "No data available");
|
} else if (retval == 0) {
|
||||||
if (data) {
|
lprintf(LOG_ERR, "No data available");
|
||||||
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) {
|
if (data) {
|
||||||
free(data);
|
free(data);
|
||||||
data = NULL;
|
data = NULL;
|
||||||
}
|
}
|
||||||
return 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) {
|
if (verbose > 4) {
|
||||||
fprintf(stderr, "Got message:");
|
fprintf(stderr, "Got message:");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user