First attached is patch solving $SUBJ bug intended for Z-stream. Real solution based on Posix semaphores for 5.6 is in progress.
Second patch should solve second problem with dispatch. Regards, Honza
commit e3e5d8112cbcfe3307e31f330337135a392360b6 Author: Jan Friesse <[email protected]> Date: Wed May 26 14:52:19 2010 +0200 Support for semtimedop on Linux This patch solves problem with hung semop in OpenAIS if aisexec is killed. Solves rhbz#579081 diff --git a/branches/whitetank/lib/util.c b/branches/whitetank/lib/util.c index 5dc9292..f285eb5 100644 --- a/branches/whitetank/lib/util.c +++ b/branches/whitetank/lib/util.c @@ -35,6 +35,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +#if defined(OPENAIS_LINUX) +#define _GNU_SOURCE +#endif + #include <stdlib.h> #include <stdio.h> #include <unistd.h> @@ -59,6 +63,13 @@ #include "../include/ipc_gen.h" #include "util.h" +#if defined(OPENAIS_LINUX) +/* + * Define sem_wait timeout (real timeout will be (n-1;n) ) + */ +#define IPC_SEMWAIT_TIMEOUT 2 +#endif + enum SA_HANDLE_STATE { SA_HANDLE_STATE_EMPTY, SA_HANDLE_STATE_PENDINGREMOVAL, @@ -455,11 +466,77 @@ static void memcpy_swrap ( } int original_flow = -1; +inline static SaAisErrorT +ipc_sem_wait ( + struct ipc_segment *ipc_segment, + int sem_num) +{ + struct sembuf sop; +#if defined(OPENAIS_LINUX) + struct timespec timeout; + struct pollfd pfd; +#endif + int res; + + sop.sem_num = sem_num; + sop.sem_op = -1; + sop.sem_flg = 0; + +retry_semop: +#if defined(OPENAIS_LINUX) + timeout.tv_sec = IPC_SEMWAIT_TIMEOUT; + timeout.tv_nsec = 0; + + res = semtimedop (ipc_segment->semid, &sop, 1, &timeout); + if (res == -1 && errno == EINTR) { + goto retry_semop; + } else + if (res == -1 && errno == EACCES) { + priv_change_send (ipc_segment); + goto retry_semop; + } else + if (res == -1 && errno == EAGAIN) { + pfd.fd = ipc_segment->fd; + pfd.events = 0; + + res = poll (&pfd, 1, 0); + + if (res == -1 && errno != EINTR) { + return (SA_AIS_ERR_LIBRARY); + } + + if (res == 1) { + if (pfd.revents == POLLERR || pfd.revents == POLLHUP || pfd.revents == POLLNVAL) { + return (SA_AIS_ERR_LIBRARY); + } + } + + goto retry_semop; + } else + if (res == -1) { + return (SA_AIS_ERR_LIBRARY); + } +#else + res = semop (ipc_segment->semid, &sop, 1); + if (res == -1 && errno == EINTR) { + goto retry_semop; + } else + if (res == -1 && errno == EACCES) { + priv_change_send (ipc_segment); + goto retry_semop; + } else + if (res == -1) { + return (SA_AIS_ERR_LIBRARY); + } +#endif + + return (SA_AIS_OK); +} + int openais_dispatch_recv (void *ipc_ctx, void *data, int timeout) { struct pollfd ufds; - struct sembuf sop; int poll_events; mar_res_header_t *header; char buf; @@ -467,6 +544,7 @@ openais_dispatch_recv (void *ipc_ctx, void *data, int timeout) int res; unsigned int my_read; char buf_two = 1; + SaAisErrorT err; ufds.fd = ipc_segment->fd; ufds.events = POLLIN; @@ -520,20 +598,7 @@ retry_recv: return (0); } - sop.sem_num = 2; - sop.sem_op = -1; - sop.sem_flg = 0; - -retry_semop: - res = semop (ipc_segment->semid, &sop, 1); - if (res == -1 && errno == EINTR) { - goto retry_semop; - } else - if (res == -1 && errno == EACCES) { - priv_change_send (ipc_segment); - goto retry_semop; - } else - if (res == -1) { + if ((err = ipc_sem_wait (ipc_segment, 2)) != SA_AIS_OK) { return (-1); } @@ -610,29 +675,11 @@ openais_reply_receive ( void *ipc_context, void *res_msg, int res_len) { - struct sembuf sop; struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context; - unsigned int res; + SaAisErrorT err; - /* - * Wait for semaphore #1 indicating a new message from server - * to client in the response queue - */ - sop.sem_num = 1; - sop.sem_op = -1; - sop.sem_flg = 0; - -retry_semop: - res = semop (ipc_segment->semid, &sop, 1); - if (res == -1 && errno == EINTR) { - goto retry_semop; - } else - if (res == -1 && errno == EACCES) { - priv_change_send (ipc_segment); - goto retry_semop; - } else - if (res == -1) { - return (SA_AIS_ERR_LIBRARY); + if ((err = ipc_sem_wait (ipc_segment, 1)) != SA_AIS_OK) { + return (err); } memcpy (res_msg, ipc_segment->shared_memory->res_buffer, res_len); @@ -644,29 +691,11 @@ openais_reply_receive_in_buf ( void *ipc_context, void **res_msg) { - struct sembuf sop; struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context; - int res; - - /* - * Wait for semaphore #1 indicating a new message from server - * to client in the response queue - */ - sop.sem_num = 1; - sop.sem_op = -1; - sop.sem_flg = 0; + SaAisErrorT err; -retry_semop: - res = semop (ipc_segment->semid, &sop, 1); - if (res == -1 && errno == EINTR) { - goto retry_semop; - } else - if (res == -1 && errno == EACCES) { - priv_change_send (ipc_segment); - goto retry_semop; - } else - if (res == -1) { - return (SA_AIS_ERR_LIBRARY); + if ((err = ipc_sem_wait (ipc_segment, 1)) != SA_AIS_OK) { + return (err); } *res_msg = (char *)ipc_segment->shared_memory->res_buffer;
>From dd39d40c072e4da1d37f33ddcc0f26670c2e0a0b Mon Sep 17 00:00:00 2001 From: Jan Friesse <[email protected]> Date: Wed, 26 May 2010 15:17:52 +0200 Subject: [PATCH 2/2] Fix saEvtDispatch for error dispatch Fixes the second problem found in 579081 --- branches/whitetank/lib/amf.c | 5 +++++ branches/whitetank/lib/cfg.c | 5 +++++ branches/whitetank/lib/evt.c | 5 +++++ branches/whitetank/lib/lck.c | 5 +++++ branches/whitetank/lib/msg.c | 5 +++++ 5 files changed, 25 insertions(+), 0 deletions(-) diff --git a/branches/whitetank/lib/amf.c b/branches/whitetank/lib/amf.c index 79e7e6f..0956bbe 100644 --- a/branches/whitetank/lib/amf.c +++ b/branches/whitetank/lib/amf.c @@ -228,6 +228,11 @@ saAmfDispatch ( continue; /* next poll */ } + if (dispatch_avail == -1) { + error = SA_AIS_ERR_LIBRARY; + goto error_nounlock; + } + /* * Make copy of callbacks, message data, unlock instance, and call callback * A risk of this dispatch method is that the callback routines may diff --git a/branches/whitetank/lib/cfg.c b/branches/whitetank/lib/cfg.c index a542e1f..fcc95a6 100644 --- a/branches/whitetank/lib/cfg.c +++ b/branches/whitetank/lib/cfg.c @@ -207,6 +207,11 @@ openais_cfg_dispatch ( continue; /* next poll */ } + if (dispatch_avail == -1) { + error = SA_AIS_ERR_LIBRARY; + goto error_nounlock; + } + /* * Make copy of callbacks, message data, unlock instance, and call callback * A risk of this dispatch method is that the callback routines may diff --git a/branches/whitetank/lib/evt.c b/branches/whitetank/lib/evt.c index be40f49..704dfff 100644 --- a/branches/whitetank/lib/evt.c +++ b/branches/whitetank/lib/evt.c @@ -637,6 +637,11 @@ saEvtDispatch( continue; /* next poll */ } + if (dispatch_avail == -1) { + error = SA_AIS_ERR_LIBRARY; + goto dispatch_unlock; + } + /* * Make copy of callbacks, message data, unlock instance, * and call callback. A risk of this dispatch method is that diff --git a/branches/whitetank/lib/lck.c b/branches/whitetank/lib/lck.c index fa896f6..d991251 100644 --- a/branches/whitetank/lib/lck.c +++ b/branches/whitetank/lib/lck.c @@ -382,6 +382,11 @@ saLckDispatch ( continue; } + if (dispatch_avail == -1) { + error = SA_AIS_ERR_LIBRARY; + goto error_unlock; + } + /* * Make copy of callbacks, message data, unlock instance, * and call callback. A risk of this dispatch method is that diff --git a/branches/whitetank/lib/msg.c b/branches/whitetank/lib/msg.c index 37f9ae9..6ea131a 100644 --- a/branches/whitetank/lib/msg.c +++ b/branches/whitetank/lib/msg.c @@ -328,6 +328,11 @@ saMsgDispatch ( continue; } + if (dispatch_avail == -1) { + error = SA_AIS_ERR_LIBRARY; + goto error_unlock; + } + memset(&dispatch_data, 0, sizeof(struct message_overlay)); /* -- 1.5.5.6
_______________________________________________ Openais mailing list [email protected] https://lists.linux-foundation.org/mailman/listinfo/openais
