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.

Note that anything after we've done a fork() doesn't need the
locks as it is no longer threaded.

Tested that lp:~serge-hallyn/+junk/lxc-test still works with this
patch.

Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
---
 src/lxc/af_unix.c      |  10 +++
 src/lxc/bdev.c         |  80 +++++++++++++++++---
 src/lxc/commands.c     |  10 +++
 src/lxc/console.c      |  16 ++--
 src/lxc/lxccontainer.c | 196 ++++++++++++++++++++++++++++++++-----------------
 src/lxc/lxclock.c      |   9 ++-
 src/lxc/lxclock.h      |   2 +-
 src/lxc/monitor.c      |  17 ++++-
 src/lxc/state.c        |   5 ++
 9 files changed, 254 insertions(+), 91 deletions(-)

diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c
index d6d18ca..333f05e 100644
--- a/src/lxc/af_unix.c
+++ b/src/lxc/af_unix.c
@@ -43,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;
 
@@ -58,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;
                }
@@ -67,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;
        }
@@ -91,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;
 }
diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index b45f2cb..7cec5d8 100644
--- a/src/lxc/bdev.c
+++ b/src/lxc/bdev.c
@@ -93,11 +93,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;
 }
 
@@ -252,16 +256,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);
@@ -488,7 +499,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 +512,9 @@ static int zfs_list_entry(const char *path, char *output, 
size_t inlen)
                        break;
                }
        }
+       process_lock();
        (void) pclose(f);
+       process_unlock();
 
        return found;
 }
@@ -750,11 +766,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;
@@ -1052,13 +1072,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 +1179,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 +1195,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 +1219,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 +1240,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 +1315,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 +1331,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 +1373,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 +1386,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 +1402,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 +1427,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 +1453,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 +1474,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 +1484,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 +1501,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;
        }
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index c706a7a..59ea9cb 100644
--- a/src/lxc/commands.c
+++ b/src/lxc/commands.c
@@ -720,7 +720,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)
@@ -791,7 +793,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;
@@ -818,7 +822,9 @@ out:
        return ret;
 
 out_close:
+       process_lock();
        close(connection);
+       process_unlock();
        goto out;
 }
 
@@ -847,7 +853,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;
        }
 
@@ -864,7 +872,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/console.c b/src/lxc/console.c
index e35a811..f503f18 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,
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 3c51c4a..9458b4b 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,14 @@ 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);
+
                /* second fork to be reparented by init */
                pid = fork();
                if (pid < 0) {
@@ -882,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) {
@@ -939,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;
@@ -971,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;
@@ -1196,7 +1193,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;
@@ -1207,7 +1206,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;
@@ -1270,10 +1271,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) {
@@ -1396,25 +1399,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;
        }
@@ -1449,7 +1463,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) {
@@ -1471,7 +1488,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)
@@ -1485,11 +1504,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;
@@ -1741,15 +1764,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;
        }
 
@@ -1767,8 +1796,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);
@@ -1780,8 +1811,10 @@ static int copy_file(char *old, char *new)
        return 0;
 
 err:
+       process_lock();
        close(in);
        close(out);
+       process_unlock();
        return -1;
 }
 
@@ -1821,13 +1854,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));
@@ -1917,15 +1955,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;
 }
 
@@ -2103,13 +2145,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) {
@@ -2256,6 +2302,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);
@@ -2264,7 +2311,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;
@@ -2274,7 +2323,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;
        }
@@ -2327,7 +2379,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);
@@ -2343,7 +2398,9 @@ static char *get_timestamp(char* snappath, char *name)
                        }
                }
        }
+       process_lock();
        fclose(fin);
+       process_unlock();
        return s;
 }
 
@@ -2363,7 +2420,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;
        }
@@ -2405,8 +2465,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/monitor.c b/src/lxc/monitor.c
index 64e9987..9b8aa16 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;
 }
 
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);
-- 
1.8.3.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@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to