]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
loadavg: restart thread on library reload
authorJakub Skokan <jakub.skokan@havefun.cz>
Mon, 11 Jun 2018 13:05:14 +0000 (15:05 +0200)
committerJakub Skokan <jakub.skokan@havefun.cz>
Wed, 13 Jun 2018 12:33:20 +0000 (14:33 +0200)
Signed-off-by: Jakub Skokan <jakub.skokan@havefun.cz>
bindings.c
bindings.h
lxcfs.c

index b20eaa053b92877683163a27206143c8c9eed36a..d03792bfdcbbf405bc368c00c886980d0cec1bb6 100644 (file)
@@ -97,6 +97,7 @@ struct file_info {
  * 1 means use loadavg, 0 means not use.
  */
 static int loadavg = 0;
+static volatile sig_atomic_t loadavg_stop = 0;
 static int calc_hash(char *name)
 {
        unsigned int hash = 0;
@@ -247,7 +248,7 @@ static struct load_node *del_node(struct load_node *n, int locate)
        return g;
 }
 
-void load_free(void)
+static void load_free(void)
 {
        int i;
        struct load_node *f, *p;
@@ -4500,6 +4501,9 @@ void *load_begin(void *arg)
        clock_t time1, time2;
 
        while (1) {
+               if (loadavg_stop == 1)
+                       return NULL;
+
                time1 = clock();
                for (i = 0; i < LOAD_SIZE; i++) {
                        pthread_mutex_lock(&load_hash[i].lock);
@@ -4536,6 +4540,10 @@ out:                                     f = f->next;
                                }
                        }
                }
+
+               if (loadavg_stop == 1)
+                       return NULL;
+
                time2 = clock();
                usleep(FLUSH_TIME * 1000000 - (int)((time2 - time1) * 1000000 / CLOCKS_PER_SEC));
        }
@@ -4649,6 +4657,26 @@ pthread_t load_daemon(int load_use)
        return pid;
 }
 
+/* Returns 0 on success. */
+int stop_load_daemon(pthread_t pid)
+{
+       int s;
+
+       /* Signal the thread to gracefully stop */
+       loadavg_stop = 1;
+
+       s = pthread_join(pid, NULL); /* Make sure sub thread has been canceled. */
+       if (s != 0) {
+               lxcfs_error("%s\n", "stop_load_daemon error: failed to join");
+               return -1;
+       }
+
+       load_free();
+       loadavg_stop = 0;
+
+       return 0;
+}
+
 static off_t get_procfile_size(const char *which)
 {
        FILE *f = fopen(which, "r");
index 65630114029578df0f1bb3ce7d0847020ecba638..f1a4627d489a6d7cd21a59e20008f5c8486ea3f9 100644 (file)
@@ -33,6 +33,6 @@ extern int proc_read(const char *path, char *buf, size_t size, off_t offset,
                struct fuse_file_info *fi);
 extern int proc_access(const char *path, int mask);
 extern pthread_t load_daemon(int load_use);
-extern void load_free(void);
+extern int stop_load_daemon(pthread_t pid);
 
 #endif /* __LXCFS_BINDINGS_H */
diff --git a/lxcfs.c b/lxcfs.c
index fe381480ca3059097becf15415006cb4894f51fa..76b3ea26f9ca2166f61e5c4de849b007b0240ca7 100644 (file)
--- a/lxcfs.c
+++ b/lxcfs.c
@@ -69,6 +69,46 @@ 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) {
+       char *error;
+       int (*stop_load_daemon)(pthread_t);
+
+       stop_load_daemon = (int (*)(pthread_t)) dlsym(dlopen_handle, "stop_load_daemon");
+       error = dlerror();
+       if (error != NULL) {
+               lxcfs_error("stop_load_daemon error: %s\n", error);
+               return -1;
+       }
+
+       if (stop_load_daemon(loadavg_pid) != 0)
+               return -1;
+
+       return 0;
+}
+
 static volatile sig_atomic_t need_reload;
 
 /* do_reload - reload the dynamic library.  Done under
@@ -76,6 +116,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 +145,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 +896,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 +964,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 && 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)
+               stop_loadavg();
 
 out:
        if (dlopen_handle)