]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
use threads when safe
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 19 May 2015 21:27:05 +0000 (14:27 -0700)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 19 May 2015 22:31:40 +0000 (15:31 -0700)
libnih, when not built with --enable-threading, cannot be safely
used by a threaded application.  Detect whether it is built to be
threadsafe using a new libnih helper, and, if so, run threaded by
(a) not passing '-s' to fuse, and (b) making the dbus connection
and detected api version thread-local.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
cgmanager.c
configure.ac
lxcfs.c

index be59be4ad2f92346c62646dab5fcc46650fe391f..c0059992eaca235603b7e8341662839de0d4b9f4 100644 (file)
@@ -52,8 +52,8 @@
 
 #include "cgmanager.h"
 
-static NihDBusProxy *cgroup_manager = NULL;
-static int32_t api_version;
+static __thread NihDBusProxy *cgroup_manager = NULL;
+static __thread int32_t api_version;
 
 static void cgm_dbus_disconnect(void)
 {
index 05a1c02c874528ba09d8f2feb1f5b99ddaf0487d..95c1840845948d610b90c99c711f126e6c4b95eb 100644 (file)
@@ -28,6 +28,8 @@ PKG_CHECK_MODULES([CGMANAGER], [libcgmanager >= 0.0.0])
 PKG_CHECK_MODULES(FUSE, fuse)
 AC_CHECK_LIB(cgmanager, cgmanager_list_controllers_sync, [], AC_MSG_ERROR(["cgmanager 0.35 or higher is required"]))
 AC_CHECK_LIB(cgmanager, cgmanager_list_keys_sync, [], AC_MSG_ERROR(["cgmanager 0.35 or higher is required"]))
+AC_CHECK_LIB(nih, nih_alloc)
+AC_CHECK_FUNCS(nih_threadsafe, , , libnih)
 
 AC_PATH_PROG(HELP2MAN, help2man, false // No help2man //)
 AM_CONDITIONAL([HAVE_HELP2MAN], [test "x$HELP2MAN" != "xfalse // No help2man //" ])
diff --git a/lxcfs.c b/lxcfs.c
index 940eff3239b9b1bce1a2a4331500abc87b8b3baf..aa11f9d337497be5fe3f4aab27d4a87e4a1e3ba4 100644 (file)
--- a/lxcfs.c
+++ b/lxcfs.c
@@ -27,6 +27,7 @@
 
 #include <nih/alloc.h>
 #include <nih/string.h>
+#include <nih/error.h>
 
 #include "cgmanager.h"
 #include "config.h" // for VERSION
@@ -2652,6 +2653,15 @@ void swallow_option(int *argcp, char *argv[], char *opt, char *v)
        }
 }
 
+bool detect_libnih_threadsafe(void)
+{
+#ifdef HAVE_NIH_THREADSAFE
+       if (nih_threadsafe())
+               return true;
+#endif
+       return false;
+}
+
 int main(int argc, char *argv[])
 {
        int ret = -1;
@@ -2660,8 +2670,12 @@ int main(int argc, char *argv[])
         * what we pass to fuse_main is:
         * argv[0] -s -f -o allow_other,directio argv[1] NULL
         */
-#define NARGS 7
-       char *newargv[7];
+       int nargs = 6;
+       bool threadsafe = detect_libnih_threadsafe();
+       char *newargv[7]; // one more than if needed if threadsafe
+
+       if (threadsafe)
+               nargs = 5;
 
        /* accomodate older init scripts */
        swallow_arg(&argc, argv, "-s");
@@ -2677,13 +2691,15 @@ int main(int argc, char *argv[])
 
        d = NIH_MUST( malloc(sizeof(*d)) );
 
-       newargv[0] = argv[0];
-       newargv[1] = "-s";
-       newargv[2] = "-f";
-       newargv[3] = "-o";
-       newargv[4] = "allow_other,direct_io";
-       newargv[5] = argv[1];
-       newargv[6] = NULL;
+       int cnt = 0;
+       newargv[cnt++] = argv[0];
+       if (!threadsafe)
+               newargv[cnt++] = "-s";
+       newargv[cnt++] = "-f";
+       newargv[cnt++] = "-o";
+       newargv[cnt++] = "allow_other,direct_io";
+       newargv[cnt++] = argv[1];
+       newargv[cnt++] = NULL;
 
        if (!cgm_escape_cgroup())
                fprintf(stderr, "WARNING: failed to escape to root cgroup\n");
@@ -2691,7 +2707,7 @@ int main(int argc, char *argv[])
        if (!cgm_get_controllers(&d->subsystems))
                goto out;
 
-       ret = fuse_main(NARGS - 1, newargv, &lxcfs_ops, d);
+       ret = fuse_main(nargs, newargv, &lxcfs_ops, d);
 
 out:
        free(d);