[sheepdog] [PATCH] sheep: wait until there is no get_vdis work in wait_get_vdis_done()
Liu Yuan
namei.unix at gmail.com
Wed Aug 28 05:16:15 CEST 2013
On Wed, Aug 28, 2013 at 10:46:47AM +0900, MORITA Kazutaka wrote:
> From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
>
> There is a race condition like as follows:
>
> 1. Node A, B, and C start up.
> 2. Node A receives accept events from B and C, and calls
> start_recovery().
> 3. Node A calls wait_get_vdis_done in the recovery thread, but there
> are two get_vdis works in sys->block_wqueue.
> 4. When the first get_vdis_done() is called, is_vdi_list_ready will
> be set to false.
> 5. Node A starts object recovery without receiving vdi state from C.
>
> To fix the problem, this patch counts the number of get_vdi works in
> the block_wqueue.
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
> ---
>
> I think this should go into the stable branch, too.
>
> sheep/group.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/sheep/group.c b/sheep/group.c
> index 450c71d..cd56cb6 100644
> --- a/sheep/group.c
> +++ b/sheep/group.c
> @@ -26,7 +26,7 @@ struct get_vdis_work {
>
> static pthread_mutex_t wait_vdis_lock = PTHREAD_MUTEX_INITIALIZER;
> static pthread_cond_t wait_vdis_cond = PTHREAD_COND_INITIALIZER;
> -static bool is_vdi_list_ready = true;
> +static refcnt_t nr_get_vdis_works;
>
> static main_thread(struct vnode_info *) current_vnode_info;
> static main_thread(struct list_head *) pending_block_list;
> @@ -498,7 +498,7 @@ static void get_vdis_done(struct work *work)
> container_of(work, struct get_vdis_work, work);
>
> pthread_mutex_lock(&wait_vdis_lock);
> - is_vdi_list_ready = true;
> + refcount_dec(&nr_get_vdis_works);
> pthread_cond_broadcast(&wait_vdis_cond);
> pthread_mutex_unlock(&wait_vdis_lock);
>
> @@ -581,7 +581,7 @@ static void get_vdis(const struct sd_node *nodes, size_t nr_nodes,
> w->nr_members = nr_nodes;
> memcpy(w->members, nodes, array_len);
>
> - is_vdi_list_ready = false;
> + refcount_inc(&nr_get_vdis_works);
>
> w->work.fn = do_get_vdis;
> w->work.done = get_vdis_done;
> @@ -593,7 +593,7 @@ void wait_get_vdis_done(void)
> sd_debug("waiting for vdi list");
>
> pthread_mutex_lock(&wait_vdis_lock);
> - while (!is_vdi_list_ready)
> + while (refcount_read(&nr_get_vdis_works) > 0)
> pthread_cond_wait(&wait_vdis_cond, &wait_vdis_lock);
> pthread_mutex_unlock(&wait_vdis_lock);
>
> --
> 1.7.9.5
>
Applied thanks
Yuan
More information about the sheepdog
mailing list