The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/242

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Per-container loadavg tracking is not working after library reload using `SIGUSR1`. When reloading the library in `do_reload()`, the thread that is tracking per-container loadavgs is left running. As I understand it, it continues to operate on those static variables from the original library. loadavg is not set up using the new library and so `proc_read_loadavg()` starts to return the host's `/proc/loadavg`, as if it was disabled.

This patch stops the loadavg thread before closing the original library and restarts it when the new library is loaded.
From 5235d372dd58e064deb2e95dc2c690c31774f9e2 Mon Sep 17 00:00:00 2001
From: Jakub Skokan <[email protected]>
Date: Mon, 11 Jun 2018 15:05:14 +0200
Subject: [PATCH] loadavg: restart thread on library reload

Signed-off-by: Jakub Skokan <[email protected]>
---
 lxcfs.c | 100 ++++++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/lxcfs.c b/lxcfs.c
index fe38148..428c30e 100644
--- a/lxcfs.c
+++ b/lxcfs.c
@@ -69,6 +69,57 @@ static void users_unlock(void)
        unlock_mutex(&user_count_mutex);
 }
 
+static pthread_t loadavg_pid = 0;
+
+/* Returns zero on success */
+static int start_loadavg(void) {
+       char *error;
+       pthread_t (*load_daemon)(int);
+
+       dlerror();    /* Clear any existing error */
+
+       load_daemon = (pthread_t (*)(int)) dlsym(dlopen_handle, "load_daemon");
+       error = dlerror();
+       if (error != NULL) {
+               lxcfs_error("load_daemon fails:%s\n", error);
+               return -1;
+       }
+       loadavg_pid = load_daemon(1);
+       if (loadavg_pid == 0)
+               return -1;
+
+       return 0;
+}
+
+/* Returns zero on success */
+static int stop_loadavg(void) {
+       int s;
+       char *error;
+       void (*load_free)(void);
+
+       s = pthread_cancel(loadavg_pid);
+       if (s == 0) {
+               s = pthread_join(loadavg_pid, NULL); /* Make sure sub thread 
has been canceled. */
+               if (s != 0) {
+                       lxcfs_error("%s\n", "load_free error!");
+                       return -1;
+               }
+               dlerror();    /* Clear any existing error */
+
+               load_free = (void (*)(void)) dlsym(dlopen_handle, "load_free");
+               error = dlerror();
+               if (error != NULL) {
+                       lxcfs_error("load_free error: %s\n", error);
+                       return -1;
+               }
+               load_free();
+       } else {
+               lxcfs_error("%s\n", "load_free error!");
+       }
+
+       return 0;
+}
+
 static volatile sig_atomic_t need_reload;
 
 /* do_reload - reload the dynamic library.  Done under
@@ -76,6 +127,10 @@ static volatile sig_atomic_t need_reload;
 static void do_reload(void)
 {
        char lxcfs_lib_path[PATH_MAX];
+
+       if (loadavg_pid > 0)
+               stop_loadavg();
+
        if (dlopen_handle) {
                lxcfs_debug("%s\n", "Closing liblxcfs.so handle.");
                dlclose(dlopen_handle);
@@ -101,6 +156,9 @@ static void do_reload(void)
        }
 
 good:
+       if (loadavg_pid > 0)
+               start_loadavg();
+
        if (need_reload)
                lxcfs_error("%s\n", "lxcfs: reloaded");
        need_reload = 0;
@@ -849,12 +907,7 @@ int main(int argc, char *argv[])
        char *pidfile = NULL, *saveptr = NULL, *token = NULL, *v = NULL;
        size_t pidfile_len;
        bool debug = false, nonempty = false;
-       pthread_t pid;
-       int s = 0;
-       char *error;
        bool load_use = false;
-       pthread_t (*load_daemon)(int);
-       void (*load_free)(void);
        /*
         * what we pass to fuse_main is:
         * argv[0] -s [-f|-d] -o allow_other,directio argv[1] NULL
@@ -922,42 +975,13 @@ int main(int argc, char *argv[])
        if ((pidfd = set_pidfile(pidfile)) < 0)
                goto out;
 
-       if (load_use == true) {
-               dlerror();    /* Clear any existing error */
+       if (load_use == true && start_loadavg() != 0)
+               goto out;
 
-               load_daemon = (pthread_t (*)(int)) dlsym(dlopen_handle, 
"load_daemon");
-               error = dlerror();
-               if (error != NULL) {
-                       lxcfs_error("load_daemon fails:%s\n", error);
-                       goto out;
-               }
-               pid = load_daemon(1);
-               if (pid == 0)
-                       goto out;
-       }
        if (!fuse_main(nargs, newargv, &lxcfs_ops, NULL))
                ret = EXIT_SUCCESS;
-       if (load_use == true) {
-               s = pthread_cancel(pid);
-               if (s == 0) {
-                       s = pthread_join(pid, NULL); /* Make sure sub thread 
has been canceled. */
-                       if (s != 0) {
-                               lxcfs_error("%s\n", "load_free error!");
-                               goto out;
-                       }
-                       dlerror();    /* Clear any existing error */
-
-                       load_free = (void (*)(void)) dlsym(dlopen_handle, 
"load_free");
-                       error = dlerror();
-                       if (error != NULL) {
-                               lxcfs_error("load_free error: %s\n", error);
-                               goto out;
-                       }
-                       load_free();
-               } else {
-                       lxcfs_error("%s\n", "load_free error!");
-               }
-       }
+       if (load_use == true)
+               stop_loadavg();
 
 out:
        if (dlopen_handle)
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to