* 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;
return g;
}
-void load_free(void)
+static void load_free(void)
{
int i;
struct load_node *f, *p;
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);
}
}
}
+
+ if (loadavg_stop == 1)
+ return NULL;
+
time2 = clock();
usleep(FLUSH_TIME * 1000000 - (int)((time2 - time1) * 1000000 / CLOCKS_PER_SEC));
}
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");
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
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);
}
good:
+ if (loadavg_pid > 0)
+ start_loadavg();
+
if (need_reload)
lxcfs_error("%s\n", "lxcfs: reloaded");
need_reload = 0;
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
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)