diff --git a/src/lxcfs.c b/src/lxcfs.c index ef35460d..44fa4f50 100644 --- a/src/lxcfs.c +++ b/src/lxcfs.c @@ -89,13 +89,37 @@ static int start_loadavg(void) { char *error; pthread_t (*__load_daemon)(int); + int (*__load_daemon_v2)(pthread_t *, int); + /* try a new load_daemon_v2() API */ + dlerror(); + __load_daemon_v2 = (int (*)(pthread_t *, int))dlsym(dlopen_handle, "load_daemon_v2"); + error = dlerror(); + if (error) + /* try with an old symbol name */ + goto old_api; + + lxcfs_debug("start_loadavg: using load_daemon_v2"); + + if (__load_daemon_v2(&loadavg_pid, 1)) { + /* we have to NULLify loadavg_pid as in case of error it's contents are undefined */ + loadavg_pid = 0; + return log_error(-1, "Failed to start loadavg daemon"); + } + + /* we are done */ + return 0; + +old_api: + /* go with an old load_daemon() API */ dlerror(); __load_daemon = (pthread_t(*)(int))dlsym(dlopen_handle, "load_daemon"); error = dlerror(); if (error) return log_error(-1, "%s - Failed to start loadavg daemon", error); + lxcfs_debug("start_loadavg: using load_daemon"); + loadavg_pid = __load_daemon(1); if (!loadavg_pid) return -1; diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c index 0be04f47..e8456c5a 100644 --- a/src/proc_loadavg.c +++ b/src/proc_loadavg.c @@ -628,7 +628,7 @@ static void load_free(void) } } -/* Return a positive number on success, return 0 on failure.*/ +/* Return a positive number on success, return 0 on failure. */ pthread_t load_daemon(int load_use) { int ret; @@ -644,11 +644,31 @@ pthread_t load_daemon(int load_use) return (pthread_t)log_error(0, "Create pthread fails in load_daemon!"); } - /* use loadavg, here loadavg = 1*/ + /* use loadavg, here loadavg = 1 */ loadavg = load_use; return pid; } +/* Return 0 on success, return -1 on failure. */ +int load_daemon_v2(pthread_t *thread, int load_use) +{ + int ret; + + ret = init_load(); + if (ret == -1) + return log_error(-1, "Initialize hash_table fails in load_daemon!"); + + ret = pthread_create(thread, NULL, load_begin, NULL); + if (ret != 0) { + load_free(); + return log_error(-1, "%s - Create pthread fails in load_daemon!", strerror(ret)); + } + + /* use loadavg, here loadavg = 1 */ + loadavg = load_use; + return 0; +} + /* Returns 0 on success. */ int stop_load_daemon(pthread_t pid) { diff --git a/src/proc_loadavg.h b/src/proc_loadavg.h index e6ae2ded..03d2ca6d 100644 --- a/src/proc_loadavg.h +++ b/src/proc_loadavg.h @@ -16,6 +16,7 @@ #include "macro.h" __visible extern pthread_t load_daemon(int load_use); +__visible extern int load_daemon_v2(pthread_t *thread, int load_use); __visible extern int stop_load_daemon(pthread_t pid); extern int proc_loadavg_read(char *buf, size_t size, off_t offset, struct fuse_file_info *fi);