[ltt-dev] [UST PATCH] libust: Add locking around fork calls

Nils Carlson nils.carlson at ericsson.com
Thu Feb 24 08:12:03 EST 2011


On Thu, 24 Feb 2011, Nils Carlson wrote:

> A finer scheme could be implemented by using system V semaphores
> and could look like this:
>
> thread executing tracectl command:
>       lock(fork_sem_mutex)
>       increment(fork_sem)
>       unlock(fork_sem_mutex)
>       execute_command()
>       decrement(fork_sem)
>
> thread executing fork:
>       lock(fork_sem_mutex) // now no new commands can be issued
>       wait(fork_sem == 0) // wait for all commands to finish
>       fork()
>       unlock(fork_sem_mutex) // let commands start again.
>
> I think this would work well, but system V semaphores are sort
> of heavy. So maybe somebody can come up with something prettier?

This could probably be done nicer with a rwlock as well or a cond_wait.
I think these alternatives would both be simpler than system v semaphores.

/Nils


> This is a little bit of a RFC patch, so please say what you think.
>
> Signed-off-by: Nils Carlson <nils.carlson at ericsson.com>
> ---
> libust/tracectl.c |   16 +++++++++++++---
> 1 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/libust/tracectl.c b/libust/tracectl.c
> index f720244..fd69da6 100644
> --- a/libust/tracectl.c
> +++ b/libust/tracectl.c
> @@ -71,6 +71,9 @@ static struct cds_list_head open_buffers_list = CDS_LIST_HEAD_INIT(open_buffers_
>
> static struct cds_list_head ust_socks = CDS_LIST_HEAD_INIT(ust_socks);
>
> +/* Fork protection mechanism */
> +static pthread_mutex_t fork_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> /* volatile because shared between the listener and the main thread */
> int buffers_to_export = 0;
>
> @@ -1080,6 +1083,7 @@ void *listener_main(void *p)
> 		}
>
> 		for (i = 0; i < nfds; i++) {
> +			pthread_mutex_lock(&fork_mutex);
> 			epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
> 			if (epoll_sock == listen_sock) {
> 				addr_size = sizeof(struct sockaddr);
> @@ -1088,6 +1092,7 @@ void *listener_main(void *p)
> 						   (socklen_t *)&addr_size);
> 				if (accept_fd == -1) {
> 					PERROR("listener_main: accept failed");
> +					pthread_mutex_unlock(&fork_mutex);
> 					continue;
> 				}
> 				ustcomm_init_sock(accept_fd, epoll_fd,
> @@ -1108,6 +1113,7 @@ void *listener_main(void *p)
> 							   epoll_sock->fd);
> 				}
> 			}
> +			pthread_mutex_unlock(&fork_mutex);
> 		}
> 	}
>
> @@ -1578,9 +1584,6 @@ static void ust_fork(void)
> 	/* Get the pid of the new process */
> 	processpid = getpid();
>
> -	/* break lock if necessary */
> -	ltt_unlock_traces();
> -
> 	/*
> 	 * FIXME: This could be prettier, we loop over the list twice and
> 	 * following good locking practice should lock around the loop
> @@ -1657,6 +1660,11 @@ void ust_before_fork(ust_fork_info_t *fork_info)
>                 - only do this if tracing is active
>         */
>
> +	/* Take the fork lock to make sure we are not in the middle of
> +	 * something in the listener thread.
> +	 */
> +	pthread_mutex_lock(&fork_mutex);
> +
>         /* Disable signals */
>         sigfillset(&all_sigs);
>         result = sigprocmask(SIG_BLOCK, &all_sigs, &fork_info->orig_sigs);
> @@ -1677,6 +1685,8 @@ static void ust_after_fork_common(ust_fork_info_t *fork_info)
>                 PERROR("sigprocmask");
>                 return;
>         }
> +
> +	pthread_mutex_unlock(&fork_mutex);
> }
>
> void ust_after_fork_parent(ust_fork_info_t *fork_info)
> -- 
> 1.7.1
>
>




More information about the lttng-dev mailing list