The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/377

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) ===
Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From d6f6c7222287c274f6fd96fef1fbdf820161a6b8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Mon, 16 Mar 2020 20:24:59 +0100
Subject: [PATCH] proc_loadvg: fixes

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 src/proc_loadavg.c | 119 ++++++++++++++++++++++++---------------------
 1 file changed, 63 insertions(+), 56 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 20b538e..d8ce59f 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -59,7 +59,7 @@ static int loadavg = 0;
 #define DEPTH_DIR 3   /*the depth of per cgroup */
 /* The function of calculate loadavg .*/
 #define FSHIFT         11              /* nr of bits of precision */
-#define FIXED_1                (1<<FSHIFT)     /* 1.0 as fixed-point */
+#define FIXED_1                (1 << FSHIFT)   /* 1.0 as fixed-point */
 #define EXP_1          1884            /* 1/exp(5sec/1min) as fixed-point */
 #define EXP_5          2014            /* 1/exp(5sec/5min) */
 #define EXP_15         2037            /* 1/exp(5sec/15min) */
@@ -70,15 +70,15 @@ static volatile sig_atomic_t loadavg_stop = 0;
 struct load_node {
        /* cgroup */
        char *cg;
-       /* Load averages */
+       /* Load averages */
        uint64_t avenrun[3];
        unsigned int run_pid;
        unsigned int total_pid;
        unsigned int last_pid;
        /* The file descriptor of the mounted cgroup */
        int cfd;
-       struct  load_node *next;
-       struct  load_node **pre;
+       struct load_node *next;
+       struct load_node **pre;
 };
 
 struct load_head {
@@ -211,13 +211,16 @@ int proc_loadavg_read(char *buf, size_t size, off_t 
offset,
        /* First time */
        if (n == NULL) {
                cfd = get_cgroup_fd("cpu");
-               if (cfd >= 0) {
+               if (cfd < 0) {
                        /*
                         * In locate_node() above, pthread_rwlock_unlock() 
isn't used
                         * because delete is not allowed before read has ended.
                         */
                        pthread_rwlock_unlock(&load_hash[hash].rdlock);
-                       return 0;
+                       lxcfs_error("AAAA");
+                       return read_file_fuse("/proc/loadavg", buf, size, d);
+               } else {
+                       lxcfs_error("BBBB");
                }
 
                do {
@@ -225,7 +228,7 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
                } while (!n);
 
                do {
-                       n->cg = malloc(strlen(cg)+1);
+                       n->cg = malloc(strlen(cg) + 1);
                } while (!n->cg);
 
                strcpy(n->cg, cg);
@@ -238,15 +241,15 @@ int proc_loadavg_read(char *buf, size_t size, off_t 
offset,
                n->cfd = cfd;
                insert_node(&n, hash);
        }
-       a = n->avenrun[0] + (FIXED_1/200);
-       b = n->avenrun[1] + (FIXED_1/200);
-       c = n->avenrun[2] + (FIXED_1/200);
+       a = n->avenrun[0] + (FIXED_1 / 200);
+       b = n->avenrun[1] + (FIXED_1 / 200);
+       c = n->avenrun[2] + (FIXED_1 / 200);
        total_len = snprintf(d->buf, d->buflen,
                             "%lu.%02lu "
                             "%lu.%02lu "
                             "%lu.%02lu "
                             "%d/"
-                            "%d"
+                            "%d "
                             "%d\n",
                             LOAD_INT(a),
                             LOAD_FRAC(a),
@@ -280,7 +283,7 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
  * @sum : return the number of pid.
  * @cfd : the file descriptor of the mounted cgroup. eg: /sys/fs/cgroup/cpu
  */
-static int calc_pid(char ***pid_buf, char *dpath, int depth, int sum, int cfd)
+static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, 
int cfd)
 {
        __do_free char *path = NULL;
        __do_free void *fdopen_cache = NULL;
@@ -299,13 +302,15 @@ static int calc_pid(char ***pid_buf, char *dpath, int 
depth, int sum, int cfd)
                return sum;
 
        strcpy(path, dpath);
-       fd = openat(cfd, path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
+       fd = openat(cfd, path, O_RDONLY | O_CLOEXEC);
        if (fd < 0)
                return sum;
 
-       dir = fdopendir(move_fd(fd));
+       dir = fdopendir(fd);
        if (!dir)
                return sum;
+       /* Transfer ownership to fdopendir(). */
+       move_fd(fd);
 
        while (((file = readdir(dir)) != NULL) && depth > 0) {
                if (strcmp(file->d_name, ".") == 0)
@@ -331,7 +336,7 @@ static int calc_pid(char ***pid_buf, char *dpath, int 
depth, int sum, int cfd)
        }
 
        strcat(path, "/cgroup.procs");
-       fd = openat(cfd, path, O_RDONLY);
+       fd = openat(cfd, path, O_RDONLY | O_CLOEXEC);
        if (fd < 0)
                return sum;
 
@@ -382,86 +387,87 @@ static uint64_t calc_load(uint64_t load, uint64_t exp, 
uint64_t active)
  * Return -1 means that error occurred in refresh.
  * Positive num equals the total number of pid.
  */
-static int refresh_load(struct load_node *p, char *path)
+static int refresh_load(struct load_node *p, const char *path)
 {
        __do_free char *line = NULL;
        char **idbuf;
-       char proc_path[256];
+       char proc_path[STRLITERALLEN("/proc//task//status") +
+                      2 * INTTYPE_TO_STRLEN(pid_t) + 1];
        int i, ret, run_pid = 0, total_pid = 0, last_pid = 0;
        size_t linelen = 0;
        int sum, length;
        struct dirent *file;
 
-       idbuf = malloc(sizeof(char *));
-       if (!idbuf)
-               return -1;
+       idbuf = must_realloc(NULL, sizeof(char **));
 
        sum = calc_pid(&idbuf, path, DEPTH_DIR, 0, p->cfd);
-       /*  normal exit  */
-       if (sum == 0)
+       if (!sum)
                goto out;
 
        for (i = 0; i < sum; i++) {
                __do_closedir DIR *dp = NULL;
 
-               /*clean up '\n' */
                length = strlen(idbuf[i]) - 1;
                idbuf[i][length] = '\0';
-               ret = snprintf(proc_path, 256, "/proc/%s/task", idbuf[i]);
-               if (ret < 0 || ret > 255) {
+
+               ret = snprintf(proc_path, sizeof(proc_path), "/proc/%s/task", 
idbuf[i]);
+               if (ret < 0 || (size_t)ret > sizeof(proc_path)) {
                        i = sum;
                        sum = -1;
-                       log_error(goto err_out, "snprintf() failed in 
refresh_load");
+                       lxcfs_error("%s\n", "snprintf() failed in 
refresh_load.");
+                       goto err_out;
                }
 
                dp = opendir(proc_path);
-               if (!dp)
-                       log_error(continue, "Open proc_path failed in 
refresh_load");
+               if (!dp) {
+                       lxcfs_error("Failed to open \"%s\"", proc_path);
+                       continue;
+               }
 
                while ((file = readdir(dp)) != NULL) {
-                       __do_free void *fopen_cache = NULL;
                        __do_fclose FILE *f = NULL;
 
-                       if (strncmp(file->d_name, ".", 1) == 0)
+                       if (strcmp(file->d_name, ".") == 0)
                                continue;
 
-                       if (strncmp(file->d_name, "..", 1) == 0)
+                       if (strcmp(file->d_name, "..") == 0)
                                continue;
 
                        total_pid++;
 
-                       /* We make the biggest pid become last_pid.*/
+                       /* We make the biggest pid become last_pid. */
                        ret = atof(file->d_name);
                        last_pid = (ret > last_pid) ? ret : last_pid;
 
-                       ret = snprintf(proc_path, 256, 
"/proc/%s/task/%s/status",
-                                      idbuf[i], file->d_name);
-                       if (ret < 0 || ret > 255) {
+                       ret = snprintf(proc_path, sizeof(proc_path),
+                                      "/proc/%s/task/%s/status", idbuf[i], 
file->d_name);
+                       if (ret < 0 || (size_t)ret > sizeof(proc_path)) {
                                i = sum;
                                sum = -1;
-                               log_error(goto err_out, "snprintf() failed in 
refresh_load");
+                               lxcfs_error("%s\n", "snprintf() failed in 
refresh_load.");
+                               goto err_out;
                        }
 
-                       f = fopen_cached(proc_path, "re", &fopen_cache);
-                       if (f != NULL) {
-                               while (getline(&line, &linelen, f) != -1) {
-                                       /* Find State */
-                                       if ((strncmp(line, "State", 5) == 0) &&
-                                           (strncmp(line, "State R", 7) == 0 ||
-                                            strncmp(line, "State D", 7) == 0))
-                                               run_pid++;
+                       f = fopen(proc_path, "re");
+                       if (!f)
+                               continue;
+
+                       while (getline(&line, &linelen, f) != -1)
+                               if ((line[0] == 'S') && (line[1] == 't'))
                                        break;
-                               }
-                       }
+
+                       if ((line[7] == 'R') || (line[7] == 'D'))
+                               run_pid++;
                }
        }
-       /*Calculate the loadavg.*/
-       p->avenrun[0] = calc_load(p->avenrun[0], EXP_1, run_pid);
-       p->avenrun[1] = calc_load(p->avenrun[1], EXP_5, run_pid);
-       p->avenrun[2] = calc_load(p->avenrun[2], EXP_15, run_pid);
-       p->run_pid = run_pid;
-       p->total_pid = total_pid;
-       p->last_pid = last_pid;
+
+       /* Calculate the loadavg. */
+       p->avenrun[0]   = calc_load(p->avenrun[0], EXP_1, run_pid);
+       p->avenrun[1]   = calc_load(p->avenrun[1], EXP_5, run_pid);
+       p->avenrun[2]   = calc_load(p->avenrun[2], EXP_15, run_pid);
+       p->run_pid      = run_pid;
+       p->total_pid    = total_pid;
+       p->last_pid     = last_pid;
 
 err_out:
        for (; i > 0; i--)
@@ -496,22 +502,23 @@ static struct load_node *del_node(struct load_node *n, 
int locate)
 static void *load_begin(void *arg)
 {
 
-       int i, sum, length, ret;
+       int sum, length, ret;
        struct load_node *f;
        int first_node;
        clock_t time1, time2;
 
-       while (1) {
+       for (;;) {
                if (loadavg_stop == 1)
                        return NULL;
 
                time1 = clock();
-               for (i = 0; i < LOAD_SIZE; i++) {
+               for (int i = 0; i < LOAD_SIZE; i++) {
                        pthread_mutex_lock(&load_hash[i].lock);
                        if (load_hash[i].next == NULL) {
                                pthread_mutex_unlock(&load_hash[i].lock);
                                continue;
                        }
+
                        f = load_hash[i].next;
                        first_node = 1;
                        while (f) {
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to