Re: [PATCH] tgtd: refresh ready fds of event loop after event deletion

Hitoshi Mitake <[email protected]>
Newsgroups org.kernel.vger.stgt
Message-ID <87lhx7agda.wl%[email protected]>
At Mon, 17 Feb 2014 17:12:18 +0900,
Hitoshi Mitake wrote:
> 
> Current main event loop (event_loop()) of tgtd has a possibility of
> segmentation fault. The problem is caused by the below sequence:
> 
> 1. Event A, B are ready so epoll_wait(2) returns.
> 2. The handler of the event A is called. In the event handler, the
>    event B is deleted with tgt_event_del()
> 3. event_loop() tries to call the handler of the event B. It causes
>    segfault because the event struct is already removed and freed.
> 
> For avoid this problem, this patch adds a new global variable
> event_need_refresh. If the value of this variable is 1, event_loop()
> calls epoll_wait(2) again for refreshing ready fd list. This patch
> also lets tgt_event_del() to turn on the flag in its tail. With this
> modification, the above segfault is avoided.
> 
> Signed-off-by: Hitoshi Mitake <[email protected]>
> ---
>  usr/tgtd.c |   10 ++++++++++
>  usr/tgtd.h |    2 ++
>  2 files changed, 12 insertions(+)

I found a little problem in this patch. I'll send v2 soon.

Thanks,
Hitoshi

> 
> diff --git a/usr/tgtd.c b/usr/tgtd.c
> index 09c1442..c758458 100644
> --- a/usr/tgtd.c
> +++ b/usr/tgtd.c
> @@ -215,6 +215,8 @@ static struct event_data *tgt_event_lookup(int fd)
>  	return NULL;
>  }
>  
> +int event_need_refresh;
> +
>  void tgt_event_del(int fd)
>  {
>  	struct event_data *tev;
> @@ -232,6 +234,8 @@ void tgt_event_del(int fd)
>  
>  	list_del(&tev->e_list);
>  	free(tev);
> +
> +	event_need_refresh = 1;
>  }
>  
>  int tgt_event_modify(int fd, int events)
> @@ -419,6 +423,7 @@ retry:
>  	sched_remains = tgt_exec_scheduled();
>  	timeout = sched_remains ? 0 : -1;
>  
> +refresh:
>  	nevent = epoll_wait(ep_fd, events, ARRAY_SIZE(events), timeout);
>  	if (nevent < 0) {
>  		if (errno != EINTR) {
> @@ -429,6 +434,11 @@ retry:
>  		for (i = 0; i < nevent; i++) {
>  			tev = (struct event_data *) events[i].data.ptr;
>  			tev->handler(tev->fd, events[i].events, tev->data);
> +
> +			if (event_need_refresh) {
> +				event_need_refresh = 0;
> +				goto refresh;
> +			}
>  		}
>  	}
>  
> diff --git a/usr/tgtd.h b/usr/tgtd.h
> index a708f13..91dd7b4 100644
> --- a/usr/tgtd.h
> +++ b/usr/tgtd.h
> @@ -406,4 +406,6 @@ struct service_action *
>  find_service_action(struct service_action *service_action,
>  		    uint32_t action);
>  
> +extern int event_need_refresh;
> +
>  #endif
> -- 
> 1.7.10.4
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.