[lxc-devel] [PATCH RFC] Fix up struct lxc_container locking
Serge Hallyn
serge.hallyn at ubuntu.com
Thu Apr 11 17:06:39 UTC 2013
Quoting Seth Arnold (seth.arnold at canonical.com):
> On Thu, Apr 11, 2013 at 11:43:31AM -0500, Serge Hallyn wrote:
> > 1. in container_free, set c->privlock to NULL before calling
> > sem_destroy, to prevent a window where another thread could call
> > sem_wait(c->privlock) while c->privlock is not NULL but is already
> > destroyed.
> >
> > 2. in container_get, check for numthreads < 0 before calling lxclock.
> > Once numthreads is 0, it never goes back up.
> >
> > Following is a comment added to lxccontainer.c:
> >
> > /*
> > * Consider the following case:
> > freer | racing get()er
> > ==================================================================
> > lxc_container_put() | lxc_container_get()
> > \ lxclock(c->privlock) | c->numthreads < 1? (no)
> > \ c->numthreads = 0 | \ lxclock(c->privlock) -> waits
> > \ lxcunlock() | \
> > \ lxc_container_free() | \ lxclock() returns
> > | \ c->numthreads < 1 -> return 0
> > \ \ (free stuff) |
> > \ \ sem_destroy(privlock) |
> >
> > * When the get()er checks numthreads the first time, one of the following
> > * is true:
> > * 1. freer has set numthreads = 0. get() returns 0
> > * 2. freer is between lxclock and setting numthreads to 0. get()er will
> > * sem_wait on privlock, get lxclock after freer() drops it, then see
> > * numthreads is 0 and exit without touching lxclock again..
> > * 3. freer has not yet locked privlock. If get()er runs first, then put()er
> > * will see --numthreads = 1 and not call lxc_container_free().
> > */
> >
> > Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
>
> Acked-by: Seth Arnold <seth.arnold at canonical.com>
Thanks Seth! (For the list, Seth pointed out the original problems)
-serge
More information about the lxc-devel
mailing list