[Openais] [PATCH 2/2] IPC: return CS_ERR_NO_RESOURCES to library when low on fds

Steven Dake sdake at redhat.com
Tue Aug 24 13:35:49 PDT 2010


good for commit

regards
-steve
On 08/23/2010 07:22 PM, Angus Salkeld wrote:
>
> Signed-off-by: Angus Salkeld<asalkeld at redhat.com>
> ---
>   exec/coroipcs.c |   50 +++++++++++++++++++++++++++++++-------------------
>   exec/main.c     |    4 +++-
>   exec/util.h     |   21 +++++++++++++++++++++
>   lib/util.h      |    6 ++++++
>   4 files changed, 61 insertions(+), 20 deletions(-)
>
> diff --git a/exec/coroipcs.c b/exec/coroipcs.c
> index aca9053..c3cf566 100644
> --- a/exec/coroipcs.c
> +++ b/exec/coroipcs.c
> @@ -85,6 +85,7 @@
>   #else
>   #include<sys/sem.h>
>   #endif
> +#include "util.h"
>
>   #ifndef MSG_NOSIGNAL
>   #define MSG_NOSIGNAL 0
> @@ -761,14 +762,14 @@ retry_send:
>   	return (0);
>   }
>
> -static int
> +static cs_error_t
>   req_setup_recv (
>   	struct conn_info *conn_info)
>   {
>   	int res;
>   	struct msghdr msg_recv;
>   	struct iovec iov_recv;
> -	int authenticated = 0;
> +	cs_error_t auth_res = CS_ERR_LIBRARY;
>
>   #ifdef COROSYNC_LINUX
>   	struct cmsghdr *cmsg;
> @@ -804,7 +805,7 @@ retry_recv:
>   		goto retry_recv;
>   	} else
>   	if (res == -1&&  errno != EAGAIN) {
> -		return (0);
> +		return (CS_ERR_LIBRARY);
>   	} else
>   	if (res == 0) {
>   #if defined(COROSYNC_SOLARIS) || defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN)
> @@ -812,9 +813,9 @@ retry_recv:
>   		 * EOF is detected when recvmsg return 0.
>   		 */
>   		ipc_disconnect (conn_info);
> -		return 0;
> +		return (CS_ERR_LIBRARY);
>   #else
> -		return (-1);
> +		return (CS_ERR_SECURITY);
>   #endif
>   	}
>   	conn_info->setup_bytes_read += res;
> @@ -837,7 +838,9 @@ retry_recv:
>   			egid = ucred_getegid (uc);
>   			conn_info->client_pid = ucred_getpid (uc);
>   			if (api->security_valid (euid, egid)) {
> -				authenticated = 1;
> +				auth_res = CS_OK;
> +			} else {
> +				auth_res = hdb_error_to_cs(errno);
>   			}
>   			ucred_free(uc);
>   		}
> @@ -859,7 +862,9 @@ retry_recv:
>   		egid = -1;
>   		if (getpeereid (conn_info->fd,&euid,&egid) == 0) {
>   			if (api->security_valid (euid, egid)) {
> -				authenticated = 1;
> +				auth_res = CS_OK;
> +			} else {
> +				auth_res = hdb_error_to_cs(errno);
>   			}
>   		}
>   	}
> @@ -874,29 +879,36 @@ retry_recv:
>   	if (cred) {
>   		conn_info->client_pid = cred->pid;
>   		if (api->security_valid (cred->uid, cred->gid)) {
> -			authenticated = 1;
> +			auth_res = CS_OK;
> +		} else {
> +			auth_res = hdb_error_to_cs(errno);
>   		}
>   	}
>
>   #else /* no credentials */
> -	authenticated = 1;
> - 	log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC authentication.  Using no authentication\n");
> +	auth_res = CS_OK;
> +	log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC authentication.  Using no authentication\n");
>   #endif /* no credentials */
>
> -	if (authenticated == 0) {
> -		log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC credentials.\n");
> +	if (auth_res != CS_OK) {
>   		ipc_disconnect (conn_info);
> -		return (-1);
> - 	}
> +		if (auth_res == CS_ERR_NO_RESOURCES) {
> +			log_printf (LOGSYS_LEVEL_ERROR,
> +				"Not enough file desciptors for IPC connection.\n");
> +		} else {
> +			log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC credentials.\n");
> +		}
> +		return auth_res;
> +	}
>
>   	if (conn_info->setup_bytes_read == sizeof (mar_req_setup_t)) {
>   #ifdef COROSYNC_LINUX
>   		setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED,
>   			&off, sizeof (off));
>   #endif
> -		return (1);
> +		return (CS_OK);
>   	}
> -	return (0);
> +	return (CS_ERR_LIBRARY);
>   }
>
>   static void ipc_disconnect (struct conn_info *conn_info)
> @@ -1576,10 +1588,10 @@ int coroipcs_handler_dispatch (
>   		 * send OK
>   		 */
>   		res = req_setup_recv (conn_info);
> -		if (res == -1) {
> -			req_setup_send (conn_info, CS_ERR_SECURITY);
> +		if (res != CS_OK&&  res != CS_ERR_LIBRARY) {
> +			req_setup_send (conn_info, res);
>   		}
> -		if (res != 1) {
> +		if (res != CS_OK) {
>   			return (0);
>   		}
>
> diff --git a/exec/main.c b/exec/main.c
> index d5306a3..58a33a6 100644
> --- a/exec/main.c
> +++ b/exec/main.c
> @@ -925,7 +925,8 @@ static int corosync_security_valid (int euid, int egid)
>   	struct list_head *iter;
>
>   	if (corosync_not_enough_fds_left) {
> -		return 0;
> +		errno = EMFILE;
> +		return (0);
>   	}
>
>   	if (euid == 0 || egid == 0) {
> @@ -942,6 +943,7 @@ static int corosync_security_valid (int euid, int egid)
>   			return (1);
>   	}
>
> +	errno = EACCES;
>   	return (0);
>   }
>
> diff --git a/exec/util.h b/exec/util.h
> index 7b95536..a3c5ae8 100644
> --- a/exec/util.h
> +++ b/exec/util.h
> @@ -63,6 +63,27 @@ enum e_ais_done {
>   	AIS_DONE_DIR_NOT_PRESENT = 16
>   };
>
> +static inline cs_error_t hdb_error_to_cs (int res)		\
> +{								\
> +	if (res == 0) {						\
> +		return (CS_OK);					\
> +	} else {						\
> +		if (errno == EBADF) {				\
> +			return (CS_ERR_BAD_HANDLE);		\
> +		} else						\
> +		if (errno == ENOMEM) {				\
> +			return (CS_ERR_NO_MEMORY);		\
> +		} else						\
> +		if (errno == EMFILE) {				\
> +			return (CS_ERR_NO_RESOURCES);		\
> +		} else						\
> +		if (errno == EACCES) {				\
> +			return (CS_ERR_SECURITY);		\
> +		}						\
> +		return (CS_ERR_LIBRARY);			\
> +	}							\
> +}
> +
>   /*
>    * Compare two names.  returns non-zero on match.
>    */
> diff --git a/lib/util.h b/lib/util.h
> index 4a44bba..c228b42 100644
> --- a/lib/util.h
> +++ b/lib/util.h
> @@ -48,6 +48,12 @@ static inline cs_error_t hdb_error_to_cs (int res)		\
>   		} else						\
>   		if (errno == ENOMEM) {				\
>   			return (CS_ERR_NO_MEMORY);		\
> +		} else						\
> +		if (errno == EMFILE) {				\
> +			return (CS_ERR_NO_RESOURCES);		\
> +		} else						\
> +		if (errno == EACCES) {				\
> +			return (CS_ERR_SECURITY);		\
>   		}						\
>   		return (CS_ERR_LIBRARY);			\
>   	}							\



More information about the Openais mailing list