[lxc-devel] [PATCH 1/1] make heavier use of process_lock (v2)

Stéphane Graber stgraber at ubuntu.com
Wed Sep 18 16:46:23 UTC 2013


On Wed, Sep 18, 2013 at 10:20:30AM -0500, Serge Hallyn wrote:
> pthread_mutex_lock() will only return an error if it was set to
> PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and
> would otherwise have deadlocked).  If that's the case then log a
> message for future debugging and exit.  Trying to "recover" is
> nonsense at that point.
> 
> process_lock() was held over too long a time in lxcapi_start()
> in the daemonize case.  (note the non-daemonized case still needs a
> check to enforce that it must NOT be called while threaded).  Add
> process_lock() at least across all open/close/socket() calls.
> 
> Anything done after a fork() doesn't need the locks as it is no
> longer threaded - so some open/close/dups()s are not locked for
> that reason.  However, some common functions are called from both
> threaded and non-threaded contexts.  So after doing a fork(), do
> a possibly-extraneous process_unlock() to make sure that, if we
> were forked while pthread mutex was held, we aren't deadlocked by
> nobody.
> 
> Tested that lp:~serge-hallyn/+junk/lxc-test still works with this
> patch.
> 
> lxc-test-concurrent with this patchset passes almost 100%.  I
> occasionally get failures of containers to start (but no task
> corruption) which I've yet to look into.  Certainly it seems a
> huge improvement.
> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

> ---
>  src/lxc/af_unix.c      |  15 ++++
>  src/lxc/apparmor.c     |  11 +++
>  src/lxc/attach.c       |  35 +++++++++
>  src/lxc/bdev.c         |  96 +++++++++++++++++++++---
>  src/lxc/caps.c         |   5 ++
>  src/lxc/cgroup.c       |  35 +++++++++
>  src/lxc/commands.c     |  11 +++
>  src/lxc/conf.c         |  83 +++++++++++++++++++-
>  src/lxc/console.c      |  72 ++++++++++++------
>  src/lxc/freezer.c      |   5 ++
>  src/lxc/log.c          |   7 ++
>  src/lxc/lxccontainer.c | 200 ++++++++++++++++++++++++++++++++-----------------
>  src/lxc/lxclock.c      |   9 ++-
>  src/lxc/lxclock.h      |   2 +-
>  src/lxc/lxcutmp.c      |  11 +++
>  src/lxc/mainloop.c     |  11 ++-
>  src/lxc/monitor.c      |  18 ++++-
>  src/lxc/network.c      |   9 +++
>  src/lxc/nl.c           |   5 ++
>  src/lxc/parse.c        |   5 ++
>  src/lxc/seccomp.c      |   5 ++
>  src/lxc/start.c        |  31 +++++++-
>  src/lxc/state.c        |   5 ++
>  src/lxc/sync.c         |  12 ++-
>  src/lxc/utils.c        |  52 +++++++++++--
>  25 files changed, 627 insertions(+), 123 deletions(-)
> 
> diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c
> index 204658d..333f05e 100644
> --- a/src/lxc/af_unix.c
> +++ b/src/lxc/af_unix.c
> @@ -30,6 +30,7 @@
>  #include <sys/un.h>
>  
>  #include "log.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_af_unix, lxc);
>  
> @@ -42,7 +43,9 @@ int lxc_af_unix_open(const char *path, int type, int flags)
>  	if (flags & O_TRUNC)
>  		unlink(path);
>  
> +	process_lock();
>  	fd = socket(PF_UNIX, type, 0);
> +	process_unlock();
>  	if (fd < 0)
>  		return -1;
>  
> @@ -57,7 +60,9 @@ int lxc_af_unix_open(const char *path, int type, int flags)
>  	if (path[0]) {
>  		len = strlen(path);
>  		if (len >= sizeof(addr.sun_path)) {
> +			process_lock();
>  			close(fd);
> +			process_unlock();
>  			errno = ENAMETOOLONG;
>  			return -1;
>  		}
> @@ -66,14 +71,18 @@ int lxc_af_unix_open(const char *path, int type, int flags)
>  
>  	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
>  		int tmp = errno;
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		errno = tmp;
>  		return -1;
>  	}
>  
>  	if (type == SOCK_STREAM && listen(fd, 100)) {
>  		int tmp = errno;
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		errno = tmp;
>  		return -1;
>  	}
> @@ -90,7 +99,9 @@ int lxc_af_unix_close(int fd)
>  	    addr.sun_path[0])
>  		unlink(addr.sun_path);
>  
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  
>  	return 0;
>  }
> @@ -100,7 +111,9 @@ int lxc_af_unix_connect(const char *path)
>  	int fd;
>  	struct sockaddr_un addr;
>  
> +	process_lock();
>  	fd = socket(PF_UNIX, SOCK_STREAM, 0);
> +	process_unlock();
>  	if (fd < 0)
>  		return -1;
>  
> @@ -113,7 +126,9 @@ int lxc_af_unix_connect(const char *path)
>  
>  	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr))) {
>  		int tmp = errno;
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		errno = tmp;
>  		return -1;
>  	}
> diff --git a/src/lxc/apparmor.c b/src/lxc/apparmor.c
> index 4dad801..c31cce7 100644
> --- a/src/lxc/apparmor.c
> +++ b/src/lxc/apparmor.c
> @@ -28,6 +28,7 @@
>  
>  #include "log.h"
>  #include "apparmor.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_apparmor, lxc);
>  
> @@ -53,7 +54,9 @@ extern char *aa_get_profile(pid_t pid)
>  		return NULL;
>  	}
>  again:
> +	process_lock();
>  	f = fopen(path, "r");
> +	process_unlock();
>  	if (!f) {
>  		SYSERROR("opening %s\n", path);
>  		if (buf)
> @@ -65,11 +68,15 @@ again:
>  	memset(buf, 0, sz);
>  	if (!buf) {
>  		ERROR("out of memory");
> +		process_lock();
>  		fclose(f);
> +		process_unlock();
>  		return NULL;
>  	}
>  	ret = fread(buf, 1, sz - 1, f);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	if (ret >= sz)
>  		goto again;
>  	if (ret < 0) {
> @@ -108,11 +115,15 @@ static int check_apparmor_enabled(void)
>  	ret = stat(AA_MOUNT_RESTR, &statbuf);
>  	if (ret != 0)
>  		return 0;
> +	process_lock();
>  	fin = fopen(AA_ENABLED_FILE, "r");
> +	process_unlock();
>  	if (!fin)
>  		return 0;
>  	ret = fscanf(fin, "%c", &e);
> +	process_lock();
>  	fclose(fin);
> +	process_unlock();
>  	if (ret == 1 && e == 'Y')
>  		return 1;
>  	return 0;
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index 6f33252..cc95079 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -50,6 +50,7 @@
>  #include "utils.h"
>  #include "commands.h"
>  #include "cgroup.h"
> +#include "lxclock.h"
>  
>  #if HAVE_SYS_PERSONALITY_H
>  #include <sys/personality.h>
> @@ -78,7 +79,9 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
>  	/* read capabilities */
>  	snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", pid);
>  
> +	process_lock();
>  	proc_file = fopen(proc_fn, "r");
> +	process_unlock();
>  	if (!proc_file) {
>  		SYSERROR("Could not open %s", proc_fn);
>  		goto out_error;
> @@ -95,7 +98,9 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
>  
>  	if (line)
>  		free(line);
> +	process_lock();
>  	fclose(proc_file);
> +	process_unlock();
>  
>  	if (!found) {
>  		SYSERROR("Could not read capability bounding set from %s", proc_fn);
> @@ -106,14 +111,18 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
>  	/* read personality */
>  	snprintf(proc_fn, MAXPATHLEN, "/proc/%d/personality", pid);
>  
> +	process_lock();
>  	proc_file = fopen(proc_fn, "r");
> +	process_unlock();
>  	if (!proc_file) {
>  		SYSERROR("Could not open %s", proc_fn);
>  		goto out_error;
>  	}
>  
>  	ret = fscanf(proc_file, "%lx", &info->personality);
> +	process_lock();
>  	fclose(proc_file);
> +	process_unlock();
>  
>  	if (ret == EOF || ret == 0) {
>  		SYSERROR("Could not read personality from %s", proc_fn);
> @@ -162,15 +171,19 @@ int lxc_attach_to_ns(pid_t pid, int which)
>  		}
>  
>  		snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]);
> +		process_lock();
>  		fd[i] = open(path, O_RDONLY | O_CLOEXEC);
> +		process_unlock();
>  		if (fd[i] < 0) {
>  			saved_errno = errno;
>  
>  			/* close all already opened file descriptors before
>  			 * we return an error, so we don't leak them
>  			 */
> +			process_lock();
>  			for (j = 0; j < i; j++)
>  				close(fd[j]);
> +			process_unlock();
>  
>  			errno = saved_errno;
>  			SYSERROR("failed to open '%s'", path);
> @@ -190,7 +203,9 @@ int lxc_attach_to_ns(pid_t pid, int which)
>  			return -1;
>  		}
>  
> +		process_lock();
>  		close(fd[i]);
> +		process_unlock();
>  	}
>  
>  	return 0;
> @@ -378,14 +393,18 @@ char *lxc_attach_getpwshell(uid_t uid)
>  	 * getent program, and we need to capture its
>  	 * output, so we use a pipe for that purpose
>  	 */
> +	process_lock();
>  	ret = pipe(pipes);
> +	process_unlock();
>  	if (ret < 0)
>  		return NULL;
>  
>  	pid = fork();
>  	if (pid < 0) {
> +		process_lock();
>  		close(pipes[0]);
>  		close(pipes[1]);
> +		process_unlock();
>  		return NULL;
>  	}
>  
> @@ -397,9 +416,13 @@ char *lxc_attach_getpwshell(uid_t uid)
>  		int found = 0;
>  		int status;
>  
> +		process_lock();
>  		close(pipes[1]);
> +		process_unlock();
>  
> +		process_lock();
>  		pipe_f = fdopen(pipes[0], "r");
> +		process_unlock();
>  		while (getline(&line, &line_bufsz, pipe_f) != -1) {
>  			char *token;
>  			char *saveptr = NULL;
> @@ -456,7 +479,9 @@ char *lxc_attach_getpwshell(uid_t uid)
>  		}
>  
>  		free(line);
> +		process_lock();
>  		fclose(pipe_f);
> +		process_unlock();
>  	again:
>  		if (waitpid(pid, &status, 0) < 0) {
>  			if (errno == EINTR)
> @@ -489,6 +514,7 @@ char *lxc_attach_getpwshell(uid_t uid)
>  			NULL
>  		};
>  
> +		process_unlock(); // we're no longer sharing
>  		close(pipes[0]);
>  
>  		/* we want to capture stdout */
> @@ -651,7 +677,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
>  	 *   close socket                                 close socket
>  	 *                                                run program
>  	 */
> +	process_lock();
>  	ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
> +	process_unlock();
>  	if (ret < 0) {
>  		SYSERROR("could not set up required IPC mechanism for attaching");
>  		free(cwd);
> @@ -689,7 +717,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
>  		/* inital thread, we close the socket that is for the
>  		 * subprocesses
>  		 */
> +		process_lock();
>  		close(ipc_sockets[1]);
> +		process_unlock();
>  		free(cwd);
>  
>  		/* get pid from intermediate process */
> @@ -761,7 +791,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
>  
>  		/* now shut down communication with child, we're done */
>  		shutdown(ipc_sockets[0], SHUT_RDWR);
> +		process_lock();
>  		close(ipc_sockets[0]);
> +		process_unlock();
>  		free(init_ctx->aa_profile);
>  		free(init_ctx);
>  
> @@ -778,7 +810,9 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
>  		 * otherwise the pid we're waiting for may never exit
>  		 */
>  		shutdown(ipc_sockets[0], SHUT_RDWR);
> +		process_lock();
>  		close(ipc_sockets[0]);
> +		process_unlock();
>  		if (to_cleanup_pid)
>  			(void) wait_for_pid(to_cleanup_pid);
>  		free(init_ctx->aa_profile);
> @@ -786,6 +820,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
>  		return -1;
>  	}
>  
> +	process_unlock(); // we're no longer sharing
>  	/* first subprocess begins here, we close the socket that is for the
>  	 * initial thread
>  	 */
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index b45f2cb..b643bb7 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -70,6 +70,8 @@ static int do_rsync(const char *src, const char *dest)
>  		return -1;
>  	if (pid > 0)
>  		return wait_for_pid(pid);
> +
> +	process_unlock(); // we're no longer sharing
>  	l = strlen(src) + 2;
>  	s = malloc(l);
>  	if (!s)
> @@ -93,11 +95,15 @@ static int blk_getsize(struct bdev *bdev, unsigned long *size)
>  	if (strcmp(bdev->type, "loop") == 0)
>  		path = bdev->src + 5;
>  
> +	process_lock();
>  	fd = open(path, O_RDONLY);
> +	process_unlock();
>  	if (fd < 0)
>  		return -1;
>  	ret = ioctl(fd, BLKGETSIZE64, size);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -194,6 +200,7 @@ static int do_mkfs(const char *path, const char *fstype)
>  	if (pid > 0)
>  		return wait_for_pid(pid);
>  
> +	process_unlock(); // we're no longer sharing
>  	// If the file is not a block device, we don't want mkfs to ask
>  	// us about whether to proceed.
>  	close(0);
> @@ -252,16 +259,23 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
>  	if (strcmp(bdev->type, "loop") == 0)
>  		srcdev = bdev->src + 5;
>  
> -	if (pipe(p) < 0)
> +	process_lock();
> +	ret = pipe(p);
> +	process_unlock();
> +	if (ret < 0)
>  		return -1;
>  	if ((pid = fork()) < 0)
>  		return -1;
>  	if (pid > 0) {
>  		int status;
> +		process_lock();
>  		close(p[1]);
> +		process_unlock();
>  		memset(type, 0, len);
>  		ret = read(p[0], type, len-1);
> +		process_lock();
>  		close(p[0]);
> +		process_unlock();
>  		if (ret < 0) {
>  			SYSERROR("error reading from pipe");
>  			wait(&status);
> @@ -277,6 +291,7 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
>  		return ret;
>  	}
>  
> +	process_unlock(); // we're no longer sharing
>  	if (unshare(CLONE_NEWNS) < 0)
>  		exit(1);
>  
> @@ -488,7 +503,10 @@ static int zfs_list_entry(const char *path, char *output, size_t inlen)
>  	FILE *f;
>  	int found=0;
>  
> -	if ((f = popen("zfs list 2> /dev/null", "r")) == NULL) {
> +	process_lock();
> +	f = popen("zfs list 2> /dev/null", "r");
> +	process_unlock();
> +	if (f == NULL) {
>  		SYSERROR("popen failed");
>  		return 0;
>  	}
> @@ -498,7 +516,9 @@ static int zfs_list_entry(const char *path, char *output, size_t inlen)
>  			break;
>  		}
>  	}
> +	process_lock();
>  	(void) pclose(f);
> +	process_unlock();
>  
>  	return found;
>  }
> @@ -566,6 +586,8 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
>  			return -1;
>  		if (!pid) {
>  			char dev[MAXPATHLEN];
> +
> +			process_unlock(); // we're no longer sharing
>  			ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, nname);
>  			if (ret < 0  || ret >= MAXPATHLEN)
>  				exit(1);
> @@ -589,6 +611,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
>  		if ((pid = fork()) < 0)
>  			return -1;
>  		if (!pid) {
> +			process_unlock(); // we're no longer sharing
>  			execlp("zfs", "zfs", "destroy", path1, NULL);
>  			exit(1);
>  		}
> @@ -599,6 +622,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
>  		if ((pid = fork()) < 0)
>  			return -1;
>  		if (!pid) {
> +			process_unlock(); // we're no longer sharing
>  			execlp("zfs", "zfs", "snapshot", path1, NULL);
>  			exit(1);
>  		}
> @@ -609,6 +633,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
>  		if ((pid = fork()) < 0)
>  			return -1;
>  		if (!pid) {
> +			process_unlock(); // we're no longer sharing
>  			execlp("zfs", "zfs", "clone", option, path1, path2, NULL);
>  			exit(1);
>  		}
> @@ -659,6 +684,7 @@ static int zfs_destroy(struct bdev *orig)
>  	if (pid)
>  		return wait_for_pid(pid);
>  
> +	process_unlock(); // we're no longer sharing
>  	if (!zfs_list_entry(orig->src, output, MAXPATHLEN)) {
>  		ERROR("Error: zfs entry for %s not found", orig->src);
>  		return -1;
> @@ -703,6 +729,7 @@ static int zfs_create(struct bdev *bdev, const char *dest, const char *n,
>  	if (pid)
>  		return wait_for_pid(pid);
>  
> +	process_unlock(); // we're no longer sharing
>  	char dev[MAXPATHLEN];
>  	ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, n);
>  	if (ret < 0  || ret >= MAXPATHLEN)
> @@ -750,11 +777,15 @@ static int lvm_detect(const char *path)
>  		ERROR("lvm uuid pathname too long");
>  		return 0;
>  	}
> +	process_lock();
>  	fout = fopen(devp, "r");
> +	process_unlock();
>  	if (!fout)
>  		return 0;
>  	ret = fread(buf, 1, 4, fout);
> +	process_lock();
>  	fclose(fout);
> +	process_unlock();
>  	if (ret != 4 || strncmp(buf, "LVM-", 4) != 0)
>  		return 0;
>  	return 1;
> @@ -797,6 +828,7 @@ static int do_lvm_create(const char *path, unsigned long size)
>  	if (pid > 0)
>  		return wait_for_pid(pid);
>  
> +	process_unlock(); // we're no longer sharing
>  	// lvcreate default size is in M, not bytes.
>  	ret = snprintf(sz, 24, "%lu", size/1000000);
>  	if (ret < 0 || ret >= 24)
> @@ -832,6 +864,8 @@ static int lvm_snapshot(const char *orig, const char *path, unsigned long size)
>  	}
>  	if (pid > 0)
>  		return wait_for_pid(pid);
> +
> +	process_unlock(); // we're no longer sharing
>  	// lvcreate default size is in M, not bytes.
>  	ret = snprintf(sz, 24, "%lu", size/1000000);
>  	if (ret < 0 || ret >= 24)
> @@ -952,6 +986,7 @@ static int lvm_destroy(struct bdev *orig)
>  	if ((pid = fork()) < 0)
>  		return -1;
>  	if (!pid) {
> +		process_unlock(); // we're no longer sharing
>  		execlp("lvremove", "lvremove", "-f", orig->src, NULL);
>  		exit(1);
>  	}
> @@ -1052,13 +1087,17 @@ static bool is_btrfs_fs(const char *path)
>  	struct btrfs_ioctl_space_args sargs;
>  
>  	// make sure this is a btrfs filesystem
> +	process_lock();
>  	fd = open(path, O_RDONLY);
> +	process_unlock();
>  	if (fd < 0)
>  		return false;
>  	sargs.space_slots = 0;
>  	sargs.total_spaces = 0;
>  	ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	if (ret < 0)
>  		return false;
>  
> @@ -1155,7 +1194,10 @@ static int btrfs_subvolume_create(const char *path)
>  	}
>  	*p = '\0';
>  
> -	if ((fd = open(newfull, O_RDONLY)) < 0) {
> +	process_lock();
> +	fd = open(newfull, O_RDONLY);
> +	process_unlock();
> +	if (fd < 0) {
>  		ERROR("Error opening %s", newfull);
>  		free(newfull);
>  		return -1;
> @@ -1168,7 +1210,9 @@ static int btrfs_subvolume_create(const char *path)
>  	INFO("btrfs: snapshot create ioctl returned %d", ret);
>  
>  	free(newfull);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -1190,12 +1234,14 @@ static int btrfs_snapshot(const char *orig, const char *new)
>  	}
>  	newname = basename(newfull);
>  	newdir = dirname(newfull);
> +	process_lock();
>  	fd = open(orig, O_RDONLY);
> +	fddst = open(newdir, O_RDONLY);
> +	process_unlock();
>  	if (fd < 0) {
>  		SYSERROR("Error opening original rootfs %s", orig);
>  		goto out;
>  	}
> -	fddst = open(newdir, O_RDONLY);
>  	if (fddst < 0) {
>  		SYSERROR("Error opening new container dir %s", newdir);
>  		goto out;
> @@ -1209,10 +1255,12 @@ static int btrfs_snapshot(const char *orig, const char *new)
>  	INFO("btrfs: snapshot create ioctl returned %d", ret);
>  
>  out:
> +	process_lock();
>  	if (fddst != -1)
>  		close(fddst);
>  	if (fd != -1)
>  		close(fd);
> +	process_unlock();
>  	if (newfull)
>  		free(newfull);
>  	return ret;
> @@ -1282,7 +1330,10 @@ static int btrfs_destroy(struct bdev *orig)
>  	}
>  	*p = '\0';
>  
> -	if ((fd = open(newfull, O_RDONLY)) < 0) {
> +	process_lock();
> +	fd = open(newfull, O_RDONLY);
> +	process_unlock();
> +	if (fd < 0) {
>  		ERROR("Error opening %s", newfull);
>  		free(newfull);
>  		return -1;
> @@ -1295,7 +1346,9 @@ static int btrfs_destroy(struct bdev *orig)
>  	INFO("btrfs: snapshot create ioctl returned %d", ret);
>  
>  	free(newfull);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -1335,7 +1388,10 @@ static int find_free_loopdev(int *retfd, char *namep)
>  	DIR *dir;
>  	int fd = -1;
>  
> -	if (!(dir = opendir("/dev"))) {
> +	process_lock();
> +	dir = opendir("/dev");
> +	process_unlock();
> +	if (!dir) {
>  		SYSERROR("Error opening /dev");
>  		return -1;
>  	}
> @@ -1345,10 +1401,15 @@ static int find_free_loopdev(int *retfd, char *namep)
>  			break;
>  		if (strncmp(direntp->d_name, "loop", 4) != 0)
>  			continue;
> -		if ((fd = openat(dirfd(dir), direntp->d_name, O_RDWR)) < 0)
> +		process_lock();
> +		fd = openat(dirfd(dir), direntp->d_name, O_RDWR);
> +		process_unlock();
> +		if (fd < 0)
>  			continue;
>  		if (ioctl(fd, LOOP_GET_STATUS64, &lo) == 0 || errno != ENXIO) {
> +			process_lock();
>  			close(fd);
> +			process_unlock();
>  			fd = -1;
>  			continue;
>  		}
> @@ -1356,7 +1417,9 @@ static int find_free_loopdev(int *retfd, char *namep)
>  		snprintf(namep, 100, "/dev/%s", direntp->d_name);
>  		break;
>  	}
> +	process_lock();
>  	closedir(dir);
> +	process_unlock();
>  	if (fd == -1) {
>  		ERROR("No loop device found");
>  		return -1;
> @@ -1379,7 +1442,10 @@ static int loop_mount(struct bdev *bdev)
>  	if (find_free_loopdev(&lfd, loname) < 0)
>  		return -22;
>  
> -	if ((ffd = open(bdev->src + 5, O_RDWR)) < 0) {
> +	process_lock();
> +	ffd = open(bdev->src + 5, O_RDWR);
> +	process_unlock();
> +	if (ffd < 0) {
>  		SYSERROR("Error opening backing file %s\n", bdev->src);
>  		goto out;
>  	}
> @@ -1402,12 +1468,14 @@ static int loop_mount(struct bdev *bdev)
>  		bdev->lofd = lfd;
>  
>  out:
> +	process_lock();
>  	if (ffd > -1)
>  		close(ffd);
>  	if (ret < 0) {
>  		close(lfd);
>  		bdev->lofd = -1;
>  	}
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -1421,7 +1489,9 @@ static int loop_umount(struct bdev *bdev)
>  		return -22;
>  	ret = umount(bdev->dest);
>  	if (bdev->lofd >= 0) {
> +		process_lock();
>  		close(bdev->lofd);
> +		process_unlock();
>  		bdev->lofd = -1;
>  	}
>  	return ret;
> @@ -1429,9 +1499,11 @@ static int loop_umount(struct bdev *bdev)
>  
>  static int do_loop_create(const char *path, unsigned long size, const char *fstype)
>  {
> -	int fd;
> +	int fd, ret;
>  	// create the new loopback file.
> +	process_lock();
>  	fd = creat(path, S_IRUSR|S_IWUSR);
> +	process_unlock();
>  	if (fd < 0)
>  		return -1;
>  	if (lseek(fd, size, SEEK_SET) < 0) {
> @@ -1444,7 +1516,10 @@ static int do_loop_create(const char *path, unsigned long size, const char *fsty
>  		close(fd);
>  		return -1;
>  	}
> -	if (close(fd) < 0) {
> +	process_lock();
> +	ret = close(fd);
> +	process_unlock();
> +	if (ret < 0) {
>  		SYSERROR("Error closing new loop file");
>  		return -1;
>  	}
> @@ -1975,6 +2050,7 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname,
>  		return new;
>  	}
>  
> +	process_unlock(); // we're no longer sharing
>  	if (unshare(CLONE_NEWNS) < 0) {
>  		SYSERROR("unshare CLONE_NEWNS");
>  		exit(1);
> diff --git a/src/lxc/caps.c b/src/lxc/caps.c
> index 006172d..bcbb859 100644
> --- a/src/lxc/caps.c
> +++ b/src/lxc/caps.c
> @@ -31,6 +31,7 @@
>  
>  #include "config.h"
>  #include "log.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_caps, lxc);
>  
> @@ -191,7 +192,9 @@ static int _real_caps_last_cap(void)
>  
>  	/* try to get the maximum capability over the kernel
>  	* interface introduced in v3.2 */
> +	process_lock();
>  	fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
> +	process_unlock();
>  	if (fd >= 0) {
>  		char buf[32];
>  		char *ptr;
> @@ -205,7 +208,9 @@ static int _real_caps_last_cap(void)
>  				result = -1;
>  		}
>  
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  	}
>  
>  	/* try to get it manually by trying to get the status of
> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
> index 9417e77..fe1a4c3 100644
> --- a/src/lxc/cgroup.c
> +++ b/src/lxc/cgroup.c
> @@ -45,6 +45,7 @@
>  #include "conf.h"
>  #include "utils.h"
>  #include "bdev.h"
> +#include "lxclock.h"
>  
>  #include <lxc/log.h>
>  #include <lxc/cgroup.h>
> @@ -148,7 +149,9 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
>  	meta_data->ref = 1;
>  
>  	/* Step 1: determine all kernel subsystems */
> +	process_lock();
>  	proc_cgroups = fopen_cloexec("/proc/cgroups", "r");
> +	process_unlock();
>  	if (!proc_cgroups)
>  		goto out_error;
>  
> @@ -186,18 +189,22 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
>  		kernel_subsystems_count++;
>  	}
>  
> +	process_lock();
>  	fclose(proc_cgroups);
> +	process_unlock();
>  	proc_cgroups = NULL;
>  
>  	/* Step 2: determine all hierarchies (by reading /proc/self/cgroup),
>  	 *         since mount points don't specify hierarchy number and
>  	 *         /proc/cgroups does not contain named hierarchies
>  	 */
> +	process_lock();
>  	proc_self_cgroup = fopen_cloexec("/proc/self/cgroup", "r");
>  	/* if for some reason (because of setns() and pid namespace for example),
>  	 * /proc/self is not valid, we try /proc/1/cgroup... */
>  	if (!proc_self_cgroup)
>  		proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r");
> +	process_unlock();
>  	if (!proc_self_cgroup)
>  		goto out_error;
>  
> @@ -274,15 +281,19 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
>  		}
>  	}
>  
> +	process_lock();
>  	fclose(proc_self_cgroup);
> +	process_unlock();
>  	proc_self_cgroup = NULL;
>  	
>  	/* Step 3: determine all mount points of each hierarchy */
> +	process_lock();
>  	proc_self_mountinfo = fopen_cloexec("/proc/self/mountinfo", "r");
>  	/* if for some reason (because of setns() and pid namespace for example),
>  	 * /proc/self is not valid, we try /proc/1/cgroup... */
>  	if (!proc_self_mountinfo)
>  		proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r");
> +	process_unlock();
>  	if (!proc_self_mountinfo)
>  		goto out_error;
>  
> @@ -395,12 +406,14 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char **subsystem_whitelist)
>  
>  out_error:
>  	saved_errno = errno;
> +	process_lock();
>  	if (proc_cgroups)
>  		fclose(proc_cgroups);
>  	if (proc_self_cgroup)
>  		fclose(proc_self_cgroup);
>  	if (proc_self_mountinfo)
>  		fclose(proc_self_mountinfo);
> +	process_unlock();
>  	free(line);
>  	free(tokens);
>  	lxc_free_array((void **)kernel_subsystems, free);
> @@ -1367,7 +1380,9 @@ struct cgroup_process_info *lxc_cgroup_process_info_getx(const char *proc_pid_cg
>  	struct cgroup_process_info **cptr = &result;
>  	struct cgroup_process_info *entry = NULL;
>  
> +	process_lock();
>  	proc_pid_cgroup = fopen_cloexec(proc_pid_cgroup_str, "r");
> +	process_unlock();
>  	if (!proc_pid_cgroup)
>  		return NULL;
>  
> @@ -1437,14 +1452,18 @@ struct cgroup_process_info *lxc_cgroup_process_info_getx(const char *proc_pid_cg
>  		entry = NULL;
>  	}
>  
> +	process_lock();
>  	fclose(proc_pid_cgroup);
> +	process_unlock();
>  	free(line);
>  	return result;
>  
>  out_error:
>  	saved_errno = errno;
> +	process_lock();
>  	if (proc_pid_cgroup)
>  		fclose(proc_pid_cgroup);
> +	process_unlock();
>  	lxc_cgroup_process_info_free(result);
>  	lxc_cgroup_process_info_free(entry);
>  	free(line);
> @@ -1702,7 +1721,9 @@ bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_a
>  		return false;
>  	}
>  
> +	process_lock();
>  	devices_list = fopen_cloexec(path, "r");
> +	process_unlock();
>  	if (!devices_list) {
>  		free(path);
>  		return false;
> @@ -1722,7 +1743,9 @@ bool cgroup_devices_has_allow_or_deny(struct lxc_handler *h, char *v, bool for_a
>  	}
>  
>  out:
> +	process_lock();
>  	fclose(devices_list);
> +	process_unlock();
>  	free(line);
>  	free(path);
>  	return ret;
> @@ -1744,7 +1767,9 @@ int cgroup_recursive_task_count(const char *cgroup_path)
>  	if (!dent_buf)
>  		return -1;
>  
> +	process_lock();
>  	d = opendir(cgroup_path);
> +	process_unlock();
>  	if (!d)
>  		return 0;
>  
> @@ -1761,13 +1786,17 @@ int cgroup_recursive_task_count(const char *cgroup_path)
>  			continue;
>  		sub_path = lxc_string_join("/", parts, false);
>  		if (!sub_path) {
> +			process_lock();
>  			closedir(d);
> +			process_unlock();
>  			free(dent_buf);
>  			return -1;
>  		}
>  		r = stat(sub_path, &st);
>  		if (r < 0) {
> +			process_lock();
>  			closedir(d);
> +			process_unlock();
>  			free(dent_buf);
>  			free(sub_path);
>  			return -1;
> @@ -1783,7 +1812,9 @@ int cgroup_recursive_task_count(const char *cgroup_path)
>  		}
>  		free(sub_path);
>  	}
> +	process_lock();
>  	closedir(d);
> +	process_unlock();
>  	free(dent_buf);
>  
>  	return n;
> @@ -1796,7 +1827,9 @@ int count_lines(const char *fn)
>  	size_t sz = 0;
>  	int n = 0;
>  
> +	process_lock();
>  	f = fopen_cloexec(fn, "r");
> +	process_unlock();
>  	if (!f)
>  		return -1;
>  
> @@ -1804,7 +1837,9 @@ int count_lines(const char *fn)
>  		n++;
>  	}
>  	free(line);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	return n;
>  }
>  
> diff --git a/src/lxc/commands.c b/src/lxc/commands.c
> index f12ae2d..f481a55 100644
> --- a/src/lxc/commands.c
> +++ b/src/lxc/commands.c
> @@ -46,6 +46,7 @@
>  #include "mainloop.h"
>  #include "af_unix.h"
>  #include "config.h"
> +#include "lxclock.h"
>  
>  /*
>   * This file provides the different functions for clients to
> @@ -716,7 +717,9 @@ static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
>  {
>  	lxc_console_free(handler->conf, fd);
>  	lxc_mainloop_del_handler(descr, fd);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  }
>  
>  static int lxc_cmd_handler(int fd, void *data, struct lxc_epoll_descr *descr)
> @@ -787,7 +790,9 @@ static int lxc_cmd_accept(int fd, void *data, struct lxc_epoll_descr *descr)
>  {
>  	int opt = 1, ret = -1, connection;
>  
> +	process_lock();
>  	connection = accept(fd, NULL, 0);
> +	process_unlock();
>  	if (connection < 0) {
>  		SYSERROR("failed to accept connection");
>  		return -1;
> @@ -814,7 +819,9 @@ out:
>  	return ret;
>  
>  out_close:
> +	process_lock();
>  	close(connection);
> +	process_unlock();
>  	goto out;
>  }
>  
> @@ -843,7 +850,9 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
>  
>  	if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
>  		SYSERROR("failed to set sigfd to close-on-exec");
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		return -1;
>  	}
>  
> @@ -860,7 +869,9 @@ int lxc_cmd_mainloop_add(const char *name,
>  	ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
>  	if (ret) {
>  		ERROR("failed to add handler for command socket");
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  	}
>  
>  	return ret;
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 79220d1..e933c9a 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -73,6 +73,7 @@
>  #include "caps.h"       /* for lxc_caps_last_cap() */
>  #include "bdev.h"
>  #include "cgroup.h"
> +#include "lxclock.h"
>  
>  #if HAVE_APPARMOR
>  #include <apparmor.h>
> @@ -296,11 +297,15 @@ static char *mkifname(char *template)
>  	getifaddrs(&ifaddr);
>  
>  	/* Initialize the random number generator */
> +	process_lock();
>  	urandom = fopen ("/dev/urandom", "r");
> +	process_unlock();
>  	if (urandom != NULL) {
>  		if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
>  			seed = time(0);
> +		process_lock();
>  		fclose(urandom);
> +		process_unlock();
>  	}
>  	else
>  		seed = time(0);
> @@ -350,7 +355,9 @@ static int run_buffer(char *buffer)
>  	char *output;
>  	int ret;
>  
> +	process_lock();
>  	f = popen(buffer, "r");
> +	process_unlock();
>  	if (!f) {
>  		SYSERROR("popen failed");
>  		return -1;
> @@ -359,7 +366,9 @@ static int run_buffer(char *buffer)
>  	output = malloc(LXC_LOG_BUFFER_SIZE);
>  	if (!output) {
>  		ERROR("failed to allocate memory for script output");
> +		process_lock();
>  		pclose(f);
> +		process_unlock();
>  		return -1;
>  	}
>  
> @@ -368,7 +377,9 @@ static int run_buffer(char *buffer)
>  
>  	free(output);
>  
> +	process_lock();
>  	ret = pclose(f);
> +	process_unlock();
>  	if (ret == -1) {
>  		SYSERROR("Script exited on error");
>  		return -1;
> @@ -573,7 +584,9 @@ static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
>  	int rfd;
>  	int ret = -1;
>  
> +	process_lock();
>  	rfd = open(rootfs, O_RDWR);
> +	process_unlock();
>  	if (rfd < 0) {
>  		SYSERROR("failed to open '%s'", rootfs);
>  		return -1;
> @@ -595,7 +608,9 @@ static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
>  
>  	ret = 0;
>  out:
> +	process_lock();
>  	close(rfd);
> +	process_unlock();
>  
>  	return ret;
>  }
> @@ -608,7 +623,9 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
>  	DIR *dir;
>  	char path[MAXPATHLEN];
>  
> +	process_lock();
>  	dir = opendir("/dev");
> +	process_unlock();
>  	if (!dir) {
>  		SYSERROR("failed to open '/dev'");
>  		return -1;
> @@ -632,19 +649,25 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
>  		if (rc < 0 || rc >= MAXPATHLEN)
>  			continue;
>  
> +		process_lock();
>  		fd = open(path, O_RDWR);
> +		process_unlock();
>  		if (fd < 0)
>  			continue;
>  
>  		if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) {
> +			process_lock();
>  			close(fd);
> +			process_unlock();
>  			continue;
>  		}
>  
>  		if (errno != ENXIO) {
>  			WARN("unexpected error for ioctl on '%s': %m",
>  			     direntp->d_name);
> +			process_lock();
>  			close(fd);
> +			process_unlock();
>  			continue;
>  		}
>  
> @@ -653,13 +676,17 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
>  		ret = setup_lodev(rootfs, fd, &loinfo);
>  		if (!ret)
>  			ret = mount_unknow_fs(path, target, 0);
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  
>  		break;
>  	}
>  
> +	process_lock();
>  	if (closedir(dir))
>  		WARN("failed to close directory");
> +	process_unlock();
>  
>  	return ret;
>  }
> @@ -705,7 +732,9 @@ int pin_rootfs(const char *rootfs)
>  	if (ret >= MAXPATHLEN)
>  		return -1;
>  
> +	process_lock();
>  	fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR);
> +	process_unlock();
>  	if (fd < 0)
>  		return fd;
>  	(void)unlink(absrootfspin);
> @@ -881,13 +910,17 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
>  				ERROR("pathname too long for ttys");
>  				return -1;
>  			}
> +			process_lock();
>  			ret = creat(lxcpath, 0660);
> +			process_unlock();
>  			if (ret==-1 && errno != EEXIST) {
>  				SYSERROR("error creating %s\n", lxcpath);
>  				return -1;
>  			}
> +			process_lock();
>  			if (ret >= 0)
>  				close(ret);
> +			process_unlock();
>  			ret = unlink(path);
>  			if (ret && errno != ENOENT) {
>  				SYSERROR("error unlinking %s\n", path);
> @@ -913,12 +946,17 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
>  		} else {
>  			/* If we populated /dev, then we need to create /dev/ttyN */
>  			if (access(path, F_OK)) {
> +				process_lock();
>  				ret = creat(path, 0660);
> +				process_unlock();
>  				if (ret==-1) {
>  					SYSERROR("error creating %s\n", path);
>  					/* this isn't fatal, continue */
> -				} else
> +				} else {
> +					process_lock();
>  					close(ret);
> +					process_unlock();
> +				}
>  			}
>  			if (mount(pty_info->name, path, "none", MS_BIND, 0)) {
>  				WARN("failed to mount '%s'->'%s'",
> @@ -1226,7 +1264,9 @@ int detect_shared_rootfs(void)
>  	int i;
>  	char *p2;
>  
> +	process_lock();
>  	f = fopen("/proc/self/mountinfo", "r");
> +	process_unlock();
>  	if (!f)
>  		return 0;
>  	while ((p = fgets(buf, LINELEN, f))) {
> @@ -1244,12 +1284,16 @@ int detect_shared_rootfs(void)
>  			// this is '/'.  is it shared?
>  			p = index(p2+1, ' ');
>  			if (p && strstr(p, "shared:")) {
> +				process_lock();
>  				fclose(f);
> +				process_unlock();
>  				return 1;
>  			}
>  		}
>  	}
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	return 0;
>  }
>  
> @@ -1505,13 +1549,17 @@ static int setup_ttydir_console(const struct lxc_rootfs *rootfs,
>  		return -1;
>  	}
>  
> +	process_lock();
>  	ret = creat(lxcpath, 0660);
> +	process_unlock();
>  	if (ret==-1 && errno != EEXIST) {
>  		SYSERROR("error %d creating %s\n", errno, lxcpath);
>  		return -1;
>  	}
> +	process_lock();
>  	if (ret >= 0)
>  		close(ret);
> +	process_unlock();
>  
>  	if (console->master < 0) {
>  		INFO("no console");
> @@ -1827,7 +1875,9 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
>  	if (!fstab)
>  		return 0;
>  
> +	process_lock();
>  	file = setmntent(fstab, "r");
> +	process_unlock();
>  	if (!file) {
>  		SYSERROR("failed to use '%s'", fstab);
>  		return -1;
> @@ -1835,7 +1885,9 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
>  
>  	ret = mount_file_entries(rootfs, file, lxc_name);
>  
> +	process_lock();
>  	endmntent(file);
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -1847,7 +1899,9 @@ static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list
>  	char *mount_entry;
>  	int ret;
>  
> +	process_lock();
>  	file = tmpfile();
> +	process_unlock();
>  	if (!file) {
>  		ERROR("tmpfile error: %m");
>  		return -1;
> @@ -1862,7 +1916,9 @@ static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list
>  
>  	ret = mount_file_entries(rootfs, file, lxc_name);
>  
> +	process_lock();
>  	fclose(file);
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -2007,14 +2063,18 @@ static int setup_hw_addr(char *hwaddr, const char *ifname)
>  	memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
>  	memcpy((char *) &ifr.ifr_hwaddr, (char *) &sockaddr, sizeof(sockaddr));
>  
> +	process_lock();
>  	fd = socket(AF_INET, SOCK_DGRAM, 0);
> +	process_unlock();
>  	if (fd < 0) {
>  		ERROR("socket failure : %s", strerror(errno));
>  		return -1;
>  	}
>  
>  	ret = ioctl(fd, SIOCSIFHWADDR, &ifr);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	if (ret)
>  		ERROR("ioctl failure : %s", strerror(errno));
>  
> @@ -2261,20 +2321,26 @@ static int setup_private_host_hw_addr(char *veth1)
>  	int err;
>  	int sockfd;
>  
> +	process_lock();
>  	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
> +	process_unlock();
>  	if (sockfd < 0)
>  		return -errno;
>  
>  	snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
>  	err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
>  	if (err < 0) {
> +		process_lock();
>  		close(sockfd);
> +		process_unlock();
>  		return -errno;
>  	}
>  
>  	ifr.ifr_hwaddr.sa_data[0] = 0xfe;
>  	err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
> +	process_lock();
>  	close(sockfd);
> +	process_unlock();
>  	if (err < 0)
>  		return -errno;
>  
> @@ -2716,7 +2782,9 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
>  		fprintf(stderr, "%s: path name too long", __func__);
>  		return -E2BIG;
>  	}
> +	process_lock();
>  	f = fopen(path, "w");
> +	process_unlock();
>  	if (!f) {
>  		perror("open");
>  		return -EINVAL;
> @@ -2724,7 +2792,9 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
>  	ret = fwrite(buf, buf_size, 1, f);
>  	if (ret < 0)
>  		SYSERROR("writing id mapping");
> +	process_lock();
>  	closeret = fclose(f);
> +	process_unlock();
>  	if (closeret)
>  		SYSERROR("writing id mapping");
>  	return ret < 0 ? ret : closeret;
> @@ -2822,7 +2892,7 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
>  int lxc_create_tty(const char *name, struct lxc_conf *conf)
>  {
>  	struct lxc_tty_info *tty_info = &conf->tty_info;
> -	int i;
> +	int i, ret;
>  
>  	/* no tty in the configuration */
>  	if (!conf->tty)
> @@ -2839,8 +2909,11 @@ int lxc_create_tty(const char *name, struct lxc_conf *conf)
>  
>  		struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
>  
> -		if (openpty(&pty_info->master, &pty_info->slave,
> -			    pty_info->name, NULL, NULL)) {
> +		process_lock();
> +		ret = openpty(&pty_info->master, &pty_info->slave,
> +			    pty_info->name, NULL, NULL);
> +		process_unlock();
> +		if (ret) {
>  			SYSERROR("failed to create pty #%d", i);
>  			tty_info->nbtty = i;
>  			lxc_delete_tty(tty_info);
> @@ -2871,8 +2944,10 @@ void lxc_delete_tty(struct lxc_tty_info *tty_info)
>  	for (i = 0; i < tty_info->nbtty; i++) {
>  		struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
>  
> +		process_lock();
>  		close(pty_info->master);
>  		close(pty_info->slave);
> +		process_unlock();
>  	}
>  
>  	free(tty_info->pty_info);
> diff --git a/src/lxc/console.c b/src/lxc/console.c
> index e35a811..a32e9cf 100644
> --- a/src/lxc/console.c
> +++ b/src/lxc/console.c
> @@ -100,16 +100,16 @@ static void lxc_console_winch(struct lxc_tty_state *ts)
>  
>  void lxc_console_sigwinch(int sig)
>  {
> -	if (process_lock() == 0) {
> -		struct lxc_list *it;
> -		struct lxc_tty_state *ts;
> +	struct lxc_list *it;
> +	struct lxc_tty_state *ts;
>  
> -		lxc_list_for_each(it, &lxc_ttys) {
> -			ts = it->elem;
> -			lxc_console_winch(ts);
> -		}
> -		process_unlock();
> +	process_lock();
> +
> +	lxc_list_for_each(it, &lxc_ttys) {
> +		ts = it->elem;
> +		lxc_console_winch(ts);
>  	}
> +	process_unlock();
>  }
>  
>  static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata,
> @@ -204,8 +204,11 @@ out:
>   */
>  static void lxc_console_sigwinch_fini(struct lxc_tty_state *ts)
>  {
> -	if (ts->sigfd >= 0)
> +	if (ts->sigfd >= 0) {
> +		process_lock();
>  		close(ts->sigfd);
> +		process_unlock();
> +	}
>  	lxc_list_del(&ts->node);
>  	sigprocmask(SIG_SETMASK, &ts->oldmask, NULL);
>  	free(ts);
> @@ -227,7 +230,9 @@ static int lxc_console_cb_con(int fd, void *data,
>  	if (!r) {
>  		INFO("console client on fd %d has exited", fd);
>  		lxc_mainloop_del_handler(descr, fd);
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		return 0;
>  	}
>  
> @@ -343,8 +348,10 @@ static void lxc_console_peer_proxy_free(struct lxc_console *console)
>  		lxc_console_sigwinch_fini(console->tty_state);
>  		console->tty_state = NULL;
>  	}
> +	process_lock();
>  	close(console->peerpty.master);
>  	close(console->peerpty.slave);
> +	process_unlock();
>  	console->peerpty.master = -1;
>  	console->peerpty.slave = -1;
>  	console->peerpty.busy = -1;
> @@ -356,6 +363,7 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
>  {
>  	struct termios oldtermio;
>  	struct lxc_tty_state *ts;
> +	int ret;
>  
>  	if (console->master < 0) {
>  		ERROR("console not set up");
> @@ -373,8 +381,11 @@ static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd)
>  	/* this is the proxy pty that will be given to the client, and that
>  	 * the real pty master will send to / recv from
>  	 */
> -	if (openpty(&console->peerpty.master, &console->peerpty.slave,
> -		    console->peerpty.name, NULL, NULL)) {
> +	process_lock();
> +	ret = openpty(&console->peerpty.master, &console->peerpty.slave,
> +		    console->peerpty.name, NULL, NULL);
> +	process_unlock();
> +	if (ret) {
>  		SYSERROR("failed to create proxy pty");
>  		return -1;
>  	}
> @@ -488,19 +499,23 @@ static void lxc_console_peer_default(struct lxc_console *console)
>  	 */
>  	if (!path && !access("/dev/tty", F_OK)) {
>  		int fd;
> +		process_lock();
>  		fd = open("/dev/tty", O_RDWR);
>  		if (fd >= 0) {
>  			close(fd);
>  			path = "/dev/tty";
>  		}
> +		process_unlock();
>  	}
>  
>  	if (!path)
>  		goto out;
>  
>  	DEBUG("opening %s for console peer", path);
> +	process_lock();
>  	console->peer = lxc_unpriv(open(path, O_CLOEXEC | O_RDWR | O_CREAT |
>  					O_APPEND, 0600));
> +	process_unlock();
>  	if (console->peer < 0)
>  		goto out;
>  
> @@ -531,7 +546,9 @@ err2:
>  	free(console->tios);
>  	console->tios = NULL;
>  err1:
> +	process_lock();
>  	close(console->peer);
> +	process_unlock();
>  	console->peer = -1;
>  out:
>  	DEBUG("no console peer");
> @@ -545,24 +562,24 @@ void lxc_console_delete(struct lxc_console *console)
>  	free(console->tios);
>  	console->tios = NULL;
>  
> +	process_lock();
>  	close(console->peer);
> -	console->peer = -1;
> -
> -	if (console->log_fd >= 0) {
> +	close(console->master);
> +	close(console->slave);
> +	if (console->log_fd >= 0)
>  		close(console->log_fd);
> -		console->log_fd = -1;
> -	}
> +	process_unlock();
>  
> -	close(console->master);
> +	console->peer = -1;
>  	console->master = -1;
> -
> -	close(console->slave);
>  	console->slave = -1;
> +	console->log_fd = -1;
>  }
>  
>  int lxc_console_create(struct lxc_conf *conf)
>  {
>  	struct lxc_console *console = &conf->console;
> +	int ret;
>  
>  	if (conf->is_execute) {
>  		INFO("no console for lxc-execute.");
> @@ -575,8 +592,11 @@ int lxc_console_create(struct lxc_conf *conf)
>  	if (console->path && !strcmp(console->path, "none"))
>  		return 0;
>  
> -	if (openpty(&console->master, &console->slave,
> -		    console->name, NULL, NULL)) {
> +	process_lock();
> +	ret = openpty(&console->master, &console->slave,
> +		    console->name, NULL, NULL);
> +	process_unlock();
> +	if (ret) {
>  		SYSERROR("failed to allocate a pty");
>  		return -1;
>  	}
> @@ -594,9 +614,11 @@ int lxc_console_create(struct lxc_conf *conf)
>  	lxc_console_peer_default(console);
>  
>  	if (console->log_path) {
> +		process_lock();
>  		console->log_fd = lxc_unpriv(open(console->log_path,
>  						  O_CLOEXEC | O_RDWR |
>  						  O_CREAT | O_APPEND, 0600));
> +		process_unlock();
>  		if (console->log_fd < 0) {
>  			SYSERROR("failed to open '%s'", console->log_path);
>  			goto err;
> @@ -693,6 +715,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
>  
>  	process_lock();
>  	ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path);
> +	process_unlock();
>  	if (ttyfd < 0) {
>  		ret = ttyfd;
>  		goto err1;
> @@ -747,9 +770,9 @@ int lxc_console(struct lxc_container *c, int ttynum,
>  		goto err4;
>  	}
>  
> -	process_unlock();
> -	ret = lxc_mainloop(&descr, -1);
>  	process_lock();
> +	ret = lxc_mainloop(&descr, -1);
> +	process_unlock();
>  	if (ret) {
>  		ERROR("mainloop returned an error");
>  		goto err4;
> @@ -762,11 +785,12 @@ err4:
>  err3:
>  	lxc_console_sigwinch_fini(ts);
>  err2:
> +	process_lock();
>  	close(masterfd);
>  	close(ttyfd);
> +	process_unlock();
>  err1:
>  	tcsetattr(stdinfd, TCSAFLUSH, &oldtios);
> -	process_unlock();
>  
>  	return ret;
>  }
> diff --git a/src/lxc/freezer.c b/src/lxc/freezer.c
> index be97d75..41dc61e 100644
> --- a/src/lxc/freezer.c
> +++ b/src/lxc/freezer.c
> @@ -34,6 +34,7 @@
>  #include "error.h"
>  #include "state.h"
>  #include "monitor.h"
> +#include "lxclock.h"
>  
>  #include <lxc/log.h>
>  #include <lxc/cgroup.h>
> @@ -52,7 +53,9 @@ static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const
>  		return -1;
>  	}
>  
> +	process_lock();
>  	fd = open(freezer, O_RDWR);
> +	process_unlock();
>  	if (fd < 0) {
>  		SYSERROR("failed to open freezer at '%s'", nsgroup);
>  		return -1;
> @@ -114,7 +117,9 @@ static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const
>  	}
>  
>  out:
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return ret;
>  }
>  
> diff --git a/src/lxc/log.c b/src/lxc/log.c
> index 9bbaa69..2da8b32 100644
> --- a/src/lxc/log.c
> +++ b/src/lxc/log.c
> @@ -36,6 +36,7 @@
>  #include "log.h"
>  #include "caps.h"
>  #include "utils.h"
> +#include "lxclock.h"
>  
>  #define LXC_LOG_PREFIX_SIZE	32
>  #define LXC_LOG_BUFFER_SIZE	512
> @@ -159,8 +160,10 @@ static int log_open(const char *name)
>  	int fd;
>  	int newfd;
>  
> +	process_lock();
>  	fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY |
>  			     O_APPEND | O_CLOEXEC, 0666));
> +	process_unlock();
>  	if (fd == -1) {
>  		ERROR("failed to open log file \"%s\" : %s", name,
>  		      strerror(errno));
> @@ -174,7 +177,9 @@ static int log_open(const char *name)
>  	if (newfd == -1)
>  		ERROR("failed to dup log fd %d : %s", fd, strerror(errno));
>  
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return newfd;
>  }
>  
> @@ -241,7 +246,9 @@ static int __lxc_log_set_file(const char *fname, int create_dirs)
>  {
>  	if (lxc_log_fd != -1) {
>  		// we are overriding the default.
> +		process_lock();
>  		close(lxc_log_fd);
> +		process_unlock();
>  		free(log_fname);
>  	}
>  
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 79237df..d77ce37 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -100,12 +100,12 @@ int ongoing_create(struct lxc_container *c)
>  
>  	if (!file_exists(path))
>  		return 0;
> -	if (process_lock())
> -		return -1;
> -	if ((fd = open(path, O_RDWR)) < 0) {
> +	process_lock();
> +	fd = open(path, O_RDWR);
> +	process_unlock();
> +	if (fd < 0) {
>  		// give benefit of the doubt
>  		SYSERROR("Error opening partial file");
> -		process_unlock();
>  		return 0;
>  	}
>  	lk.l_type = F_WRLCK;
> @@ -115,11 +115,13 @@ int ongoing_create(struct lxc_container *c)
>  	lk.l_pid = -1;
>  	if (fcntl(fd, F_GETLK, &lk) == 0 && lk.l_pid != -1) {
>  		// create is still ongoing
> +		process_lock();
>  		close(fd);
>  		process_unlock();
>  		return 1;
>  	}
>  	// create completed but partial is still there.
> +	process_lock();
>  	close(fd);
>  	process_unlock();
>  	return 2;
> @@ -138,8 +140,7 @@ int create_partial(struct lxc_container *c)
>  		ERROR("Error writing partial pathname");
>  		return -1;
>  	}
> -	if (process_lock())
> -		return -1;
> +	process_lock();
>  	if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) {
>  		SYSERROR("Erorr creating partial file");
>  		process_unlock();
> @@ -167,17 +168,16 @@ void remove_partial(struct lxc_container *c, int fd)
>  	char *path = alloca(len);
>  	int ret;
>  
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
>  	if (ret < 0 || ret >= len) {
>  		ERROR("Error writing partial pathname");
>  		return;
>  	}
> -	if (process_lock())
> -		return;
>  	if (unlink(path) < 0)
>  		SYSERROR("Error unlink partial file %s", path);
> -	process_unlock();
>  }
>  
>  /* LOCKING
> @@ -546,20 +546,15 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
>  			return false;
>  		lxc_monitord_spawn(c->config_path);
>  
> -		if (process_lock())
> -			return false;
>  		pid_t pid = fork();
>  		if (pid < 0) {
>  			lxc_container_put(c);
> -			process_unlock();
>  			return false;
>  		}
> -		if (pid != 0) {
> -			ret = wait_on_daemonized_start(c);
> -			process_unlock();
> -			return ret;
> -		}
> -		process_unlock();
> +		if (pid != 0)
> +			return wait_on_daemonized_start(c);
> +
> +		process_unlock(); // we're no longer sharing
>  		/* second fork to be reparented by init */
>  		pid = fork();
>  		if (pid < 0) {
> @@ -778,6 +773,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
>  		int ret, len, nargs = 0;
>  		char **newargv;
>  
> +		process_unlock(); // we're no longer sharing
>  		if (quiet) {
>  			close(0);
>  			close(1);
> @@ -880,56 +876,44 @@ bool prepend_lxc_header(char *path, const char *t, char *const argv[])
>  	long flen;
>  	char *contents;
>  	FILE *f;
> +	int ret = -1;
>  #if HAVE_LIBGNUTLS
> -	int i, ret;
> +	int i;
>  	unsigned char md_value[SHA_DIGEST_LENGTH];
>  	char *tpath;
>  	bool have_tpath = false;
>  #endif
>  
> -	if ((f = fopen(path, "r")) == NULL) {
> -		SYSERROR("Opening old config");
> -		return false;
> -	}
> -	if (fseek(f, 0, SEEK_END) < 0) {
> -		SYSERROR("Seeking to end of old config file");
> -		fclose(f);
> -		return false;
> -	}
> -	if ((flen = ftell(f)) < 0) {
> -		SYSERROR("telling size of old config");
> -		fclose(f);
> -		return false;
> -	}
> -	if (fseek(f, 0, SEEK_SET) < 0) {
> -		SYSERROR("rewinding old config");
> -		fclose(f);
> -		return false;
> -	}
> -	if ((contents = malloc(flen + 1)) == NULL) {
> -		SYSERROR("out of memory");
> -		fclose(f);
> -		return false;
> -	}
> -	if (fread(contents, 1, flen, f) != flen) {
> -		SYSERROR("Reading old config");
> -		free(contents);
> -		fclose(f);
> +	process_lock();
> +	f = fopen(path, "r");
> +	process_unlock();
> +	if (f == NULL)
>  		return false;
> -	}
> +
> +	if (fseek(f, 0, SEEK_END) < 0)
> +		goto out_error;
> +	if ((flen = ftell(f)) < 0)
> +		goto out_error;
> +	if (fseek(f, 0, SEEK_SET) < 0)
> +		goto out_error;
> +	if ((contents = malloc(flen + 1)) == NULL)
> +		goto out_error;
> +	if (fread(contents, 1, flen, f) != flen)
> +		goto out_free_contents;
> +
>  	contents[flen] = '\0';
> -	if (fclose(f) < 0) {
> -		SYSERROR("closing old config");
> -		free(contents);
> -		return false;
> -	}
> +	process_lock();
> +	ret = fclose(f);
> +	process_unlock();
> +	f = NULL;
> +	if (ret < 0)
> +		goto out_free_contents;
>  
>  #if HAVE_LIBGNUTLS
>  	tpath = get_template_path(t);
>  	if (tpath == (char *) -1) {
>  		ERROR("bad template: %s\n", t);
> -		free(contents);
> -		return false;
> +		goto out_free_contents;
>  	}
>  
>  	if (tpath) {
> @@ -937,14 +921,16 @@ bool prepend_lxc_header(char *path, const char *t, char *const argv[])
>  		ret = sha1sum_file(tpath, md_value);
>  		if (ret < 0) {
>  			ERROR("Error getting sha1sum of %s", tpath);
> -			free(contents);
> -			return false;
> +			goto out_free_contents;
>  		}
>  		free(tpath);
>  	}
>  #endif
>  
> -	if ((f = fopen(path, "w")) == NULL) {
> +	process_lock();
> +	f = fopen(path, "w");
> +	process_unlock();
> +	if (f == NULL) {
>  		SYSERROR("reopening config for writing");
>  		free(contents);
>  		return false;
> @@ -969,12 +955,25 @@ bool prepend_lxc_header(char *path, const char *t, char *const argv[])
>  	if (fwrite(contents, 1, flen, f) != flen) {
>  		SYSERROR("Writing original contents");
>  		free(contents);
> +		process_lock();
>  		fclose(f);
> +		process_unlock();
>  		return false;
>  	}
> +	ret = 0;
> +out_free_contents:
>  	free(contents);
> -	if (fclose(f) < 0) {
> -		SYSERROR("Closing config file after write");
> +out_error:
> +	if (f) {
> +		int newret;
> +		process_lock();
> +		newret = fclose(f);
> +		process_unlock();
> +		if (ret == 0)
> +			ret = newret;
> +	}
> +	if (ret < 0) {
> +		SYSERROR("Error prepending header");
>  		return false;
>  	}
>  	return true;
> @@ -1044,6 +1043,7 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
>  	if (pid == 0) { // child
>  		struct bdev *bdev = NULL;
>  
> +		process_unlock(); // we're no longer sharing
>  		if (!(bdev = do_bdev_create(c, bdevtype, specs))) {
>  			ERROR("Error creating backing store type %s for %s",
>  				bdevtype ? bdevtype : "(none)", c->name);
> @@ -1194,7 +1194,9 @@ char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, in
>  		goto out;
>  
>  	/* Save reference to old netns */
> +	process_lock();
>  	old_netns = open("/proc/self/ns/net", O_RDONLY);
> +	process_unlock();
>  	if (old_netns < 0) {
>  		SYSERROR("failed to open /proc/self/ns/net");
>  		goto out;
> @@ -1205,7 +1207,9 @@ char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, in
>  	if (ret < 0 || ret >= MAXPATHLEN)
>  		goto out;
>  
> +	process_lock();
>  	new_netns = open(new_netns_path, O_RDONLY);
> +	process_unlock();
>  	if (new_netns < 0) {
>  		SYSERROR("failed to open %s", new_netns_path);
>  		goto out;
> @@ -1268,10 +1272,12 @@ out:
>  	/* Switch back to original netns */
>  	if (old_netns >= 0 && setns(old_netns, CLONE_NEWNET))
>  		SYSERROR("failed to setns");
> +	process_lock();
>  	if (new_netns >= 0)
>  		close(new_netns);
>  	if (old_netns >= 0)
>  		close(old_netns);
> +	process_unlock();
>  
>  	/* Append NULL to the array */
>  	if (count) {
> @@ -1390,25 +1396,36 @@ static bool mod_rdep(struct lxc_container *c, bool inc)
>  			c->name);
>  	if (ret < 0 || ret > MAXPATHLEN)
>  		goto out;
> +	process_lock();
>  	f = fopen(path, "r");
> +	process_unlock();
>  	if (f) {
>  		ret = fscanf(f, "%d", &v);
> +		process_lock();
>  		fclose(f);
> +		process_unlock();
>  		if (ret != 1) {
>  			ERROR("Corrupted file %s", path);
>  			goto out;
>  		}
>  	}
>  	v += inc ? 1 : -1;
> +	process_lock();
>  	f = fopen(path, "w");
> +	process_unlock();
>  	if (!f)
>  		goto out;
>  	if (fprintf(f, "%d\n", v) < 0) {
>  		ERROR("Error writing new snapshots value");
> +		process_lock();
>  		fclose(f);
> +		process_unlock();
>  		goto out;
>  	}
> -	if (fclose(f) != 0) {
> +	process_lock();
> +	ret = fclose(f);
> +	process_unlock();
> +	if (ret != 0) {
>  		SYSERROR("Error writing to or closing snapshots file");
>  		goto out;
>  	}
> @@ -1443,7 +1460,10 @@ static void mod_all_rdeps(struct lxc_container *c, bool inc)
>  		ERROR("Path name too long");
>  		return;
>  	}
> -	if ((f = fopen(path, "r")) == NULL)
> +	process_lock();
> +	f = fopen(path, "r");
> +	process_unlock();
> +	if (f == NULL)
>  		return;
>  	while (getline(&lxcpath, &pathlen, f) != -1) {
>  		if (getline(&lxcname, &namelen, f) == -1) {
> @@ -1465,7 +1485,9 @@ static void mod_all_rdeps(struct lxc_container *c, bool inc)
>  out:
>  	if (lxcpath) free(lxcpath);
>  	if (lxcname) free(lxcname);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  }
>  
>  static bool has_snapshots(struct lxc_container *c)
> @@ -1479,11 +1501,15 @@ static bool has_snapshots(struct lxc_container *c)
>  			c->name);
>  	if (ret < 0 || ret > MAXPATHLEN)
>  		goto out;
> +	process_lock();
>  	f = fopen(path, "r");
> +	process_unlock();
>  	if (!f)
>  		goto out;
>  	ret = fscanf(f, "%d", &v);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	if (ret != 1)
>  		goto out;
>  	bret = v != 0;
> @@ -1735,15 +1761,21 @@ static int copy_file(char *old, char *new)
>  		return -1;
>  	}
>  
> +	process_lock();
>  	in = open(old, O_RDONLY);
> +	process_unlock();
>  	if (in < 0) {
>  		SYSERROR("Error opening original file %s", old);
>  		return -1;
>  	}
> +	process_lock();
>  	out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
> +	process_unlock();
>  	if (out < 0) {
>  		SYSERROR("Error opening new file %s", new);
> +		process_lock();
>  		close(in);
> +		process_unlock();
>  		return -1;
>  	}
>  
> @@ -1761,8 +1793,10 @@ static int copy_file(char *old, char *new)
>  			goto err;
>  		}
>  	}
> +	process_lock();
>  	close(in);
>  	close(out);
> +	process_unlock();
>  
>  	// we set mode, but not owner/group
>  	ret = chmod(new, sbuf.st_mode);
> @@ -1774,8 +1808,10 @@ static int copy_file(char *old, char *new)
>  	return 0;
>  
>  err:
> +	process_lock();
>  	close(in);
>  	close(out);
> +	process_unlock();
>  	return -1;
>  }
>  
> @@ -1815,13 +1851,18 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
>  
>  static void new_hwaddr(char *hwaddr)
>  {
> -	FILE *f = fopen("/dev/urandom", "r");
> +	FILE *f;
> +	process_lock();
> +	f = fopen("/dev/urandom", "r");
> +	process_unlock();
>  	if (f) {
>  		unsigned int seed;
>  		int ret = fread(&seed, sizeof(seed), 1, f);
>  		if (ret != 1)
>  			seed = time(NULL);
> +		process_lock();
>  		fclose(f);
> +		process_unlock();
>  		srand(seed);
>  	} else
>  		srand(time(NULL));
> @@ -1911,15 +1952,19 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
>  		c->name);
>  	if (ret < 0 || ret >= MAXPATHLEN)
>  		return false;
> +	process_lock();
>  	f = fopen(path, "a");
> +	process_unlock();
>  	if (!f)
>  		return false;
>  	bret = true;
>  	// if anything goes wrong, just return an error
>  	if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0)
>  		bret = false;
> +	process_lock();
>  	if (fclose(f) != 0)
>  		bret = false;
> +	process_unlock();
>  	return bret;
>  }
>  
> @@ -1976,6 +2021,7 @@ static int clone_update_rootfs(struct lxc_container *c0,
>  	if (pid > 0)
>  		return wait_for_pid(pid);
>  
> +	process_unlock(); // we're no longer sharing
>  	if (unshare(CLONE_NEWNS) < 0) {
>  		ERROR("error unsharing mounts");
>  		exit(1);
> @@ -2097,13 +2143,17 @@ struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *newname,
>  	}
>  
>  	// copy the configuration, tweak it as needed,
> +	process_lock();
>  	fout = fopen(newpath, "w");
> +	process_unlock();
>  	if (!fout) {
>  		SYSERROR("open %s", newpath);
>  		goto out;
>  	}
>  	write_config(fout, c->lxc_conf);
> +	process_lock();
>  	fclose(fout);
> +	process_unlock();
>  
>  	sprintf(newpath, "%s/%s/rootfs", l, n);
>  	if (mkdir(newpath, 0755) < 0) {
> @@ -2250,6 +2300,7 @@ static int lxcapi_snapshot(struct lxc_container *c, char *commentfile)
>  	time_t timer;
>  	char buffer[25];
>  	struct tm* tm_info;
> +	FILE *f;
>  
>  	time(&timer);
>  	tm_info = localtime(&timer);
> @@ -2258,7 +2309,9 @@ static int lxcapi_snapshot(struct lxc_container *c, char *commentfile)
>  
>  	char *dfnam = alloca(strlen(snappath) + strlen(newname) + 5);
>  	sprintf(dfnam, "%s/%s/ts", snappath, newname);
> -	FILE *f = fopen(dfnam, "w");
> +	process_lock();
> +	f = fopen(dfnam, "w");
> +	process_unlock();
>  	if (!f) {
>  		ERROR("Failed to open %s\n", dfnam);
>  		return -1;
> @@ -2268,7 +2321,10 @@ static int lxcapi_snapshot(struct lxc_container *c, char *commentfile)
>  		fclose(f);
>  		return -1;
>  	}
> -	if (fclose(f) != 0) {
> +	process_lock();
> +	ret = fclose(f);
> +	process_unlock();
> +	if (ret != 0) {
>  		SYSERROR("Writing timestamp");
>  		return -1;
>  	}
> @@ -2321,7 +2377,10 @@ static char *get_timestamp(char* snappath, char *name)
>  	ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name);
>  	if (ret < 0 || ret >= MAXPATHLEN)
>  		return NULL;
> -	if ((fin = fopen(path, "r")) == NULL)
> +	process_lock();
> +	fin = fopen(path, "r");
> +	process_unlock();
> +	if (!fin)
>  		return NULL;
>  	(void) fseek(fin, 0, SEEK_END);
>  	len = ftell(fin);
> @@ -2337,7 +2396,9 @@ static char *get_timestamp(char* snappath, char *name)
>  			}
>  		}
>  	}
> +	process_lock();
>  	fclose(fin);
> +	process_unlock();
>  	return s;
>  }
>  
> @@ -2357,7 +2418,10 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r
>  		ERROR("path name too long");
>  		return -1;
>  	}
> -	if (!(dir = opendir(snappath))) {
> +	process_lock();
> +	dir = opendir(snappath);
> +	process_unlock();
> +	if (!dir) {
>  		INFO("failed to open %s - assuming no snapshots", snappath);
>  		return 0;
>  	}
> @@ -2399,8 +2463,10 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r
>  		count++;
>  	}
>  
> +	process_lock();
>  	if (closedir(dir))
>  		WARN("failed to close directory");
> +	process_unlock();
>  
>  	*ret_snaps = snaps;
>  	return count;
> diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
> index 1d6a86c..1733fd1 100644
> --- a/src/lxc/lxclock.c
> +++ b/src/lxc/lxclock.c
> @@ -271,13 +271,14 @@ void lxc_putlock(struct lxc_lock *l)
>  	free(l);
>  }
>  
> -int process_lock(void)
> +void process_lock(void)
>  {
>  	int ret;
> -	ret = pthread_mutex_lock(&thread_mutex);
> -	if (ret != 0)
> +
> +	if ((ret = pthread_mutex_lock(&thread_mutex)) != 0) {
>  		ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret));
> -	return ret;
> +		exit(1);
> +	}
>  }
>  
>  void process_unlock(void)
> diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h
> index fae7e4d..dcdf79d 100644
> --- a/src/lxc/lxclock.h
> +++ b/src/lxc/lxclock.h
> @@ -85,7 +85,7 @@ extern int lxcunlock(struct lxc_lock *lock);
>  
>  extern void lxc_putlock(struct lxc_lock *l);
>  
> -extern int process_lock(void);
> +extern void process_lock(void);
>  extern void process_unlock(void);
>  struct lxc_container;
>  extern int container_mem_lock(struct lxc_container *c);
> diff --git a/src/lxc/lxcutmp.c b/src/lxc/lxcutmp.c
> index 8736f3f..bfebe55 100644
> --- a/src/lxc/lxcutmp.c
> +++ b/src/lxc/lxcutmp.c
> @@ -62,6 +62,7 @@ static int timerfd_settime (int __ufd, int __flags,
>  #include "mainloop.h"
>  #include "lxc.h"
>  #include "log.h"
> +#include "lxclock.h"
>  
>  #ifndef __USE_GNU
>  #define __USE_GNU
> @@ -342,7 +343,9 @@ run_ok:
>  
>  	memset(utmp_data, 0, sizeof(struct lxc_utmp));
>  
> +	process_lock();
>  	fd = inotify_init();
> +	process_unlock();
>  	if (fd < 0) {
>  		SYSERROR("failed to inotify_init");
>  		goto out;
> @@ -376,7 +379,9 @@ run_ok:
>  
>  	return 0;
>  out_close:
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  out:
>  	free(utmp_data);
>  	return -1;
> @@ -426,7 +431,9 @@ int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
>  	struct itimerspec timeout;
>  	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
>  
> +	process_lock();
>  	fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
> +	process_unlock();
>  	if (fd < 0) {
>  		SYSERROR("failed to create timer");
>  		return -1;
> @@ -450,7 +457,9 @@ int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
>  
>  	if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) {
>  		SYSERROR("failed to add utmp timer to mainloop");
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		return -1;
>  	}
>  
> @@ -471,7 +480,9 @@ int lxc_utmp_del_timer(struct lxc_epoll_descr *descr,
>  		SYSERROR("failed to del utmp timer from mainloop");
>  
>  	/* shutdown timer_fd */
> +	process_lock();
>  	close(utmp_data->timer_fd);
> +	process_unlock();
>  	utmp_data->timer_fd = -1;
>  
>  	if (result < 0)
> diff --git a/src/lxc/mainloop.c b/src/lxc/mainloop.c
> index 2ac4996..9ba98ee 100644
> --- a/src/lxc/mainloop.c
> +++ b/src/lxc/mainloop.c
> @@ -29,6 +29,7 @@
>  #include <sys/epoll.h>
>  
>  #include "mainloop.h"
> +#include "lxclock.h"
>  
>  struct mainloop_handler {
>  	lxc_mainloop_callback_t callback;
> @@ -132,12 +133,16 @@ int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd)
>  int lxc_mainloop_open(struct lxc_epoll_descr *descr)
>  {
>  	/* hint value passed to epoll create */
> +	process_lock();
>  	descr->epfd = epoll_create(2);
> +	process_unlock();
>  	if (descr->epfd < 0)
>  		return -1;
>  
>  	if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) {
> +		process_lock();
>  		close(descr->epfd);
> +		process_unlock();
>  		return -1;
>  	}
>  
> @@ -148,6 +153,7 @@ int lxc_mainloop_open(struct lxc_epoll_descr *descr)
>  int lxc_mainloop_close(struct lxc_epoll_descr *descr)
>  {
>  	struct lxc_list *iterator, *next;
> +	int ret;
>  
>  	iterator = descr->handlers.next;
>  	while (iterator != &descr->handlers) {
> @@ -159,6 +165,9 @@ int lxc_mainloop_close(struct lxc_epoll_descr *descr)
>  		iterator = next;
>  	}
>  
> -	return close(descr->epfd);
> +	process_lock();
> +	ret = close(descr->epfd);
> +	process_unlock();
> +	return ret;
>  }
>  
> diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
> index 64e9987..e736937 100644
> --- a/src/lxc/monitor.c
> +++ b/src/lxc/monitor.c
> @@ -90,7 +90,9 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
>  	if (ret < 0)
>  		return;
>  
> +	process_lock();
>  	fd = open(fifo_path, O_WRONLY);
> +	process_unlock();
>  	if (fd < 0) {
>  		/* it is normal for this open to fail when there is no monitor
>  		 * running, so we don't log it
> @@ -100,12 +102,16 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
>  
>  	ret = write(fd, msg, sizeof(*msg));
>  	if (ret != sizeof(*msg)) {
> +		process_lock();
>  		close(fd);
> +		process_unlock();
>  		SYSERROR("failed to write monitor fifo %s", fifo_path);
>  		return;
>  	}
>  
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  }
>  
>  void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
> @@ -122,7 +128,12 @@ void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxc
>  /* routines used by monitor subscribers (lxc-monitor) */
>  int lxc_monitor_close(int fd)
>  {
> -	return close(fd);
> +	int ret;
> +
> +	process_lock();
> +	ret = close(fd);
> +	process_unlock();
> +	return ret;
>  }
>  
>  /* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
> @@ -187,7 +198,9 @@ int lxc_monitor_open(const char *lxcpath)
>  	if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
>  		return -1;
>  
> +	process_lock();
>  	fd = socket(PF_UNIX, SOCK_STREAM, 0);
> +	process_unlock();
>  	if (fd < 0) {
>  		ERROR("socket : %s", strerror(errno));
>  		return -1;
> @@ -207,7 +220,9 @@ int lxc_monitor_open(const char *lxcpath)
>  	}
>  	return fd;
>  err1:
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return ret;
>  }
>  
> @@ -293,6 +308,7 @@ int lxc_monitord_spawn(const char *lxcpath)
>  		return 0;
>  	}
>  
> +	process_unlock(); // we're no longer sharing
>  	if (pipe(pipefd) < 0) {
>  		SYSERROR("failed to create pipe");
>  		exit(EXIT_FAILURE);
> diff --git a/src/lxc/network.c b/src/lxc/network.c
> index f7c9ce4..1be231d 100644
> --- a/src/lxc/network.c
> +++ b/src/lxc/network.c
> @@ -48,6 +48,7 @@
>  #include "nl.h"
>  #include "network.h"
>  #include "conf.h"
> +#include "lxclock.h"
>  
>  #ifndef IFLA_LINKMODE
>  #  define IFLA_LINKMODE 17
> @@ -569,14 +570,18 @@ static int proc_sys_net_write(const char *path, const char *value)
>  {
>  	int fd, err = 0;
>  
> +	process_lock();
>  	fd = open(path, O_WRONLY);
> +	process_unlock();
>  	if (fd < 0)
>  		return -errno;
>  
>  	if (write(fd, value, strlen(value)) < 0)
>  		err = -errno;
>  
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return err;
>  }
>  
> @@ -994,14 +999,18 @@ int lxc_bridge_attach(const char *bridge, const char *ifname)
>  	if (!index)
>  		return -EINVAL;
>  
> +	process_lock();
>  	fd = socket(AF_INET, SOCK_STREAM, 0);
> +	process_unlock();
>  	if (fd < 0)
>  		return -errno;
>  
>  	strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
>  	ifr.ifr_ifindex = index;
>  	err = ioctl(fd, SIOCBRADDIF, &ifr);
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	if (err)
>  		err = -errno;
>  
> diff --git a/src/lxc/nl.c b/src/lxc/nl.c
> index 7c0f1e5..6153161 100644
> --- a/src/lxc/nl.c
> +++ b/src/lxc/nl.c
> @@ -31,6 +31,7 @@
>  #include <linux/rtnetlink.h>
>  
>  #include "nl.h"
> +#include "lxclock.h"
>  
>  #define NLMSG_TAIL(nmsg) \
>          ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
> @@ -222,7 +223,9 @@ extern int netlink_open(struct nl_handler *handler, int protocol)
>  
>          memset(handler, 0, sizeof(*handler));
>  
> +	process_lock();
>          handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
> +	process_unlock();
>          if (handler->fd < 0)
>                  return -errno;
>  
> @@ -260,7 +263,9 @@ extern int netlink_open(struct nl_handler *handler, int protocol)
>  
>  extern int netlink_close(struct nl_handler *handler)
>  {
> +	process_lock();
>  	close(handler->fd);
> +	process_unlock();
>  	handler->fd = -1;
>  	return 0;
>  }
> diff --git a/src/lxc/parse.c b/src/lxc/parse.c
> index 26cbbdd..7875c89 100644
> --- a/src/lxc/parse.c
> +++ b/src/lxc/parse.c
> @@ -31,6 +31,7 @@
>  #include "parse.h"
>  #include "config.h"
>  #include "utils.h"
> +#include "lxclock.h"
>  #include <lxc/log.h>
>  
>  /* Workaround for the broken signature of alphasort() in bionic.
> @@ -90,7 +91,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
>  	char *line = NULL;
>  	size_t len = 0;
>  
> +	process_lock();
>  	f = fopen(file, "r");
> +	process_unlock();
>  	if (!f) {
>  		SYSERROR("failed to open %s", file);
>  		return -1;
> @@ -104,7 +107,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
>  
>  	if (line)
>  		free(line);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	return err;
>  }
>  
> diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
> index 1abd697..9246f2d 100644
> --- a/src/lxc/seccomp.c
> +++ b/src/lxc/seccomp.c
> @@ -29,6 +29,7 @@
>  #include <seccomp.h>
>  #include "config.h"
>  #include "lxcseccomp.h"
> +#include "lxclock.h"
>  
>  #include "log.h"
>  
> @@ -114,13 +115,17 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
>  		return -1;
>  	}
>  
> +	process_lock();
>  	f = fopen(conf->seccomp, "r");
> +	process_unlock();
>  	if (!f) {
>  		SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp);
>  		return -1;
>  	}
>  	ret = parse_config(f, conf);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	return ret;
>  }
>  
> diff --git a/src/lxc/start.c b/src/lxc/start.c
> index 48a06cf..c968bb1 100644
> --- a/src/lxc/start.c
> +++ b/src/lxc/start.c
> @@ -71,6 +71,7 @@
>  #include "apparmor.h"
>  #include "lxcseccomp.h"
>  #include "caps.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_start, lxc);
>  
> @@ -86,7 +87,9 @@ int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore)
>  	DIR *dir;
>  
>  restart:
> +	process_lock();
>  	dir = opendir("/proc/self/fd");
> +	process_unlock();
>  	if (!dir) {
>  		WARN("failed to open directory: %m");
>  		return -1;
> @@ -113,15 +116,19 @@ restart:
>  			continue;
>  
>  		if (conf->close_all_fds) {
> +			process_lock();
>  			close(fd);
>  			closedir(dir);
> +			process_unlock();
>  			INFO("closed inherited fd %d", fd);
>  			goto restart;
>  		}
>  		WARN("inherited fd %d", fd);
>  	}
>  
> +	process_lock();
>  	closedir(dir); /* cannot fail */
> +	process_unlock();
>  	return 0;
>  }
>  
> @@ -258,7 +265,9 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
>  out_mainloop_open:
>  	lxc_mainloop_close(&descr);
>  out_sigfd:
> +	process_lock();
>  	close(sigfd);
> +	process_unlock();
>  	return -1;
>  }
>  
> @@ -353,7 +362,9 @@ out_delete_tty:
>  out_aborting:
>  	lxc_set_state(name, handler, ABORTING);
>  out_close_maincmd_fd:
> +	process_lock();
>  	close(conf->maincmd_fd);
> +	process_unlock();
>  	conf->maincmd_fd = -1;
>  out_free_name:
>  	free(handler->name);
> @@ -380,7 +391,9 @@ static void lxc_fini(const char *name, struct lxc_handler *handler)
>  
>  	lxc_console_delete(&handler->conf->console);
>  	lxc_delete_tty(&handler->conf->tty_info);
> +	process_lock();
>  	close(handler->conf->maincmd_fd);
> +	process_unlock();
>  	handler->conf->maincmd_fd = -1;
>  	free(handler->name);
>  	if (handler->cgroup) {
> @@ -421,20 +434,25 @@ static int container_reboot_supported(void *arg)
>  
>  static int must_drop_cap_sys_boot(struct lxc_conf *conf)
>  {
> -	FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
> +	FILE *f;
>  	int ret, cmd, v, flags;
>          long stack_size = 4096;
>          void *stack = alloca(stack_size);
>          int status;
>          pid_t pid;
>  
> +	process_lock();
> +	f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
> +	process_unlock();
>  	if (!f) {
>  		DEBUG("failed to open /proc/sys/kernel/ctrl-alt-del");
>  		return 1;
>  	}
>  
>  	ret = fscanf(f, "%d", &v);
> +	process_lock();
>  	fclose(f);
> +	process_unlock();
>  	if (ret != 1) {
>  		DEBUG("Failed to read /proc/sys/kernel/ctrl-alt-del");
>  		return 1;
> @@ -489,8 +507,11 @@ static int do_start(void *data)
>  	lxc_sync_fini_parent(handler);
>  
>  	/* don't leak the pinfd to the container */
> -	if (handler->pinfd >= 0)
> +	if (handler->pinfd >= 0) {
> +		process_lock();
>  		close(handler->pinfd);
> +		process_unlock();
> +	}
>  
>  	/* Tell the parent task it can begin to configure the
>  	 * container and wait for it to finish
> @@ -560,7 +581,9 @@ static int do_start(void *data)
>  		goto out_warn_father;
>  	}
>  
> +	process_lock();
>  	close(handler->sigfd);
> +	process_unlock();
>  
>  	/* after this call, we are in error because this
>  	 * ops should not return as it execs */
> @@ -780,7 +803,9 @@ out_abort:
>  	lxc_abort(name, handler);
>  	lxc_sync_fini(handler);
>  	if (handler->pinfd >= 0) {
> +		process_lock();
>  		close(handler->pinfd);
> +		process_unlock();
>  		handler->pinfd = -1;
>  	}
>  
> @@ -852,7 +877,9 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
>  	lxc_rename_phys_nics_on_shutdown(handler->conf);
>  
>  	if (handler->pinfd >= 0) {
> +		process_lock();
>  		close(handler->pinfd);
> +		process_unlock();
>  		handler->pinfd = -1;
>  	}
>  
> diff --git a/src/lxc/state.c b/src/lxc/state.c
> index 398833a..92be560 100644
> --- a/src/lxc/state.c
> +++ b/src/lxc/state.c
> @@ -39,6 +39,7 @@
>  #include <lxc/monitor.h>
>  #include "commands.h"
>  #include "config.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_state, lxc);
>  
> @@ -83,14 +84,18 @@ static lxc_state_t freezer_state(const char *name, const char *lxcpath)
>  	if (ret < 0 || ret >= MAXPATHLEN)
>  		goto out;
>  
> +	process_lock();
>  	file = fopen(freezer, "r");
> +	process_unlock();
>  	if (!file) {
>  		ret = -1;
>  		goto out;
>  	}
>  
>  	ret = fscanf(file, "%s", status);
> +	process_lock();
>  	fclose(file);
> +	process_unlock();
>  
>  	if (ret == EOF) {
>  		SYSERROR("failed to read %s", freezer);
> diff --git a/src/lxc/sync.c b/src/lxc/sync.c
> index 4df2b5f..a3b4a1a 100644
> --- a/src/lxc/sync.c
> +++ b/src/lxc/sync.c
> @@ -29,6 +29,7 @@
>  
>  #include "log.h"
>  #include "start.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_sync, lxc);
>  
> @@ -99,7 +100,12 @@ int lxc_sync_wake_child(struct lxc_handler *handler, int sequence)
>  
>  int lxc_sync_init(struct lxc_handler *handler)
>  {
> -	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv)) {
> +	int ret;
> +
> +	process_lock();
> +	ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv);
> +	process_unlock();
> +	if (ret) {
>  		SYSERROR("failed to create synchronization socketpair");
>  		return -1;
>  	}
> @@ -113,7 +119,9 @@ int lxc_sync_init(struct lxc_handler *handler)
>  void lxc_sync_fini_child(struct lxc_handler *handler)
>  {
>  	if (handler->sv[0] != -1) {
> +		process_lock();
>  		close(handler->sv[0]);
> +		process_unlock();
>  		handler->sv[0] = -1;
>  	}
>  }
> @@ -121,7 +129,9 @@ void lxc_sync_fini_child(struct lxc_handler *handler)
>  void lxc_sync_fini_parent(struct lxc_handler *handler)
>  {
>  	if (handler->sv[1] != -1) {
> +		process_lock();
>  		close(handler->sv[1]);
> +		process_unlock();
>  		handler->sv[1] = -1;
>  	}
>  }
> diff --git a/src/lxc/utils.c b/src/lxc/utils.c
> index 78b234d..00e13d5 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -47,6 +47,7 @@
>  
>  #include "utils.h"
>  #include "log.h"
> +#include "lxclock.h"
>  
>  lxc_log_define(lxc_utils, lxc);
>  
> @@ -57,7 +58,9 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
>  	int ret, failed=0;
>  	char pathname[MAXPATHLEN];
>  
> +	process_lock();
>  	dir = opendir(dirname);
> +	process_unlock();
>  	if (!dir) {
>  		ERROR("%s: failed to open %s", __func__, dirname);
>  		return 0;
> @@ -104,7 +107,10 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
>  		failed=1;
>  	}
>  
> -	if (closedir(dir)) {
> +	process_lock();
> +	ret = closedir(dir);
> +	process_unlock();
> +	if (ret) {
>  		ERROR("%s: failed to close directory %s", __func__, dirname);
>  		failed=1;
>  	}
> @@ -253,7 +259,9 @@ const char *lxc_global_config_value(const char *option_name)
>  	if (values[i])
>  		return values[i];
>  
> +	process_lock();
>  	fin = fopen_cloexec(LXC_GLOBAL_CONF, "r");
> +	process_unlock();
>  	if (fin) {
>  		while (fgets(buf, 1024, fin)) {
>  			if (buf[0] == '#')
> @@ -299,8 +307,10 @@ const char *lxc_global_config_value(const char *option_name)
>  		errno = 0;
>  
>  out:
> +	process_lock();
>  	if (fin)
>  		fclose(fin);
> +	process_unlock();
>  	return values[i];
>  }
>  
> @@ -397,6 +407,15 @@ ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expe
>  	return ret;
>  }
>  
> +static inline int lock_fclose(FILE *f)
> +{
> +	int ret;
> +	process_lock();
> +	ret = fclose(f);
> +	process_unlock();
> +	return ret;
> +}
> +
>  #if HAVE_LIBGNUTLS
>  #include <gnutls/gnutls.h>
>  #include <gnutls/crypto.h>
> @@ -409,37 +428,40 @@ int sha1sum_file(char *fnam, unsigned char *digest)
>  
>  	if (!fnam)
>  		return -1;
> -	if ((f = fopen_cloexec(fnam, "r")) < 0) {
> +	process_lock();
> +	f = fopen_cloexec(fnam, "r");
> +	process_unlock();
> +	if (f < 0) {
>  		SYSERROR("Error opening template");
>  		return -1;
>  	}
>  	if (fseek(f, 0, SEEK_END) < 0) {
>  		SYSERROR("Error seeking to end of template");
> -		fclose(f);
> +		lock_fclose(f);
>  		return -1;
>  	}
>  	if ((flen = ftell(f)) < 0) {
>  		SYSERROR("Error telling size of template");
> -		fclose(f);
> +		lock_fclose(f);
>  		return -1;
>  	}
>  	if (fseek(f, 0, SEEK_SET) < 0) {
>  		SYSERROR("Error seeking to start of template");
> -		fclose(f);
> +		lock_fclose(f);
>  		return -1;
>  	}
>  	if ((buf = malloc(flen+1)) == NULL) {
>  		SYSERROR("Out of memory");
> -		fclose(f);
> +		lock_fclose(f);
>  		return -1;
>  	}
>  	if (fread(buf, 1, flen, f) != flen) {
>  		SYSERROR("Failure reading template");
>  		free(buf);
> -		fclose(f);
> +		lock_fclose(f);
>  		return -1;
>  	}
> -	if (fclose(f) < 0) {
> +	if (lock_fclose(f) < 0) {
>  		SYSERROR("Failre closing template");
>  		free(buf);
>  		return -1;
> @@ -496,6 +518,10 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
>  	return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
>  }
>  
> +/*
> + * fopen_cloexec: must be called with process_lock() held
> + * if it is needed.
> + */
>  FILE *fopen_cloexec(const char *path, const char *mode)
>  {
>  	int open_mode = 0;
> @@ -847,7 +873,9 @@ int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool
>  	int fd, saved_errno;
>  	ssize_t ret;
>  
> +	process_lock();
>  	fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666);
> +	process_unlock();
>  	if (fd < 0)
>  		return -1;
>  	ret = lxc_write_nointr(fd, buf, count);
> @@ -860,12 +888,16 @@ int lxc_write_to_file(const char *filename, const void* buf, size_t count, bool
>  		if (ret != 1)
>  			goto out_error;
>  	}
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	return 0;
>  
>  out_error:
>  	saved_errno = errno;
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	errno = saved_errno;
>  	return -1;
>  }
> @@ -875,7 +907,9 @@ int lxc_read_from_file(const char *filename, void* buf, size_t count)
>  	int fd = -1, saved_errno;
>  	ssize_t ret;
>  
> +	process_lock();
>  	fd = open(filename, O_RDONLY | O_CLOEXEC);
> +	process_unlock();
>  	if (fd < 0)
>  		return -1;
>  
> @@ -895,7 +929,9 @@ int lxc_read_from_file(const char *filename, void* buf, size_t count)
>  		ERROR("read %s: %s", filename, strerror(errno));
>  
>  	saved_errno = errno;
> +	process_lock();
>  	close(fd);
> +	process_unlock();
>  	errno = saved_errno;
>  	return ret;
>  }
> -- 
> 1.8.1.2
> 
> 
> ------------------------------------------------------------------------------
> LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
> 1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
> 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
> Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
> http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130918/2f9b4006/attachment.pgp>


More information about the lxc-devel mailing list