]> git.ipfire.org Git - thirdparty/lxc.git/commit
Fix up struct lxc_container locking
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Thu, 11 Apr 2013 16:43:31 +0000 (11:43 -0500)
committerStéphane Graber <stgraber@ubuntu.com>
Thu, 11 Apr 2013 17:15:42 +0000 (19:15 +0200)
commit43d1aa34aab1c43bce8f083d024bf54f0246a884
treeefd17aec0bd60bf1d83d3103e77f18d2ecf40725
parente649c8032f84b488cac8ea6c8fb9a77c424a0419
Fix up struct lxc_container locking

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@ubuntu.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/lxccontainer.c