Add upstream patch 51634fd77c836e3cb5acd9b9b72e7ede20321d56
"open: checking received msg id against expectation" Related: rhbz2224569
This commit is contained in:
		
							parent
							
								
									cc1648ef0c
								
							
						
					
					
						commit
						81e60e36a2
					
				
							
								
								
									
										127
									
								
								0021-open-checking-received-msg-id-against-expectation.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								0021-open-checking-received-msg-id-against-expectation.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,127 @@ | |||||||
|  | From 51634fd77c836e3cb5acd9b9b72e7ede20321d56 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Patrick Venture <venture@google.com> | ||||||
|  | Date: Tue, 4 Dec 2018 16:47:09 -0800 | ||||||
|  | Subject: [PATCH] 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> | ||||||
|  | ---
 | ||||||
|  |  src/plugins/open/open.c | 83 ++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 48 insertions(+), 35 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c
 | ||||||
|  | index 4fdabeb..8761a6d 100644
 | ||||||
|  | --- a/src/plugins/open/open.c
 | ||||||
|  | +++ b/src/plugins/open/open.c
 | ||||||
|  | @@ -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;
 | ||||||
|  | +		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;
 | ||||||
|  |  		} | ||||||
|  | -		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 (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:"); | ||||||
|  | -- 
 | ||||||
|  | 2.40.1 | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user