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
