From: Jakub Skokan Date: Mon, 11 Jun 2018 13:05:14 +0000 (+0200) Subject: loadavg: restart thread on library reload X-Git-Tag: lxcfs-3.1.0~22^2 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=a83618e2cdb9abede47001f2bcb132fc569a0c9b;p=mirror_lxcfs.git loadavg: restart thread on library reload Signed-off-by: Jakub Skokan --- diff --git a/bindings.c b/bindings.c index b20eaa0..d03792b 100644 --- a/bindings.c +++ b/bindings.c @@ -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"); diff --git a/bindings.h b/bindings.h index 6563011..f1a4627 100644 --- a/bindings.h +++ b/bindings.h @@ -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 fe38148..76b3ea2 100644 --- 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)