From: Florian Forster Date: Sat, 6 Jun 2015 19:43:28 +0000 (+0200) Subject: Merge remote-tracking branch 'github/pr/1036' X-Git-Tag: collectd-5.6.0~703 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=30eeeee996124de666f907877f8196e5580101ed Merge remote-tracking branch 'github/pr/1036' Conflicts: src/processes.c --- 30eeeee996124de666f907877f8196e5580101ed diff --cc src/processes.c index 176cdf9d,519d1360..9ae48dbd --- a/src/processes.c +++ b/src/processes.c @@@ -778,8 -814,118 +814,118 @@@ static void ps_submit_fork_rate (derive /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */ #if KERNEL_LINUX + static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps) + { + char dirname[64]; + DIR *dh; + char filename[64]; + FILE *fh; + struct dirent *ent; + derive_t cswitch_vol = 0; + derive_t cswitch_invol = 0; + char buffer[1024]; + char *fields[8]; + int numfields; + + ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid); + + if ((dh = opendir (dirname)) == NULL) + { + DEBUG ("Failed to open directory `%s'", dirname); + return (NULL); + } + + while ((ent = readdir (dh)) != NULL) + { + char *tpid; + + if (!isdigit ((int) ent->d_name[0])) + continue; + + tpid = ent->d_name; + + ssnprintf (filename, sizeof (filename), "/proc/%i/task/%s/status", pid, tpid); + if ((fh = fopen (filename, "r")) == NULL) + { + DEBUG ("Failed to open file `%s'", filename); + continue; + } + + while (fgets (buffer, sizeof(buffer), fh) != NULL) + { + derive_t tmp; + char *endptr; + + if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0 + && strncmp (buffer, "nonvoluntary_ctxt_switches", 26) != 0) + continue; + + numfields = strsplit (buffer, fields, + STATIC_ARRAY_SIZE (fields)); + + if (numfields < 2) + continue; + + errno = 0; + endptr = NULL; + tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10); + if ((errno == 0) && (endptr != fields[1])) + { + if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0) + { + cswitch_vol += tmp; + } + else if (strncmp (buffer, "nonvoluntary_ctxt_switches", 26) == 0) + { + cswitch_invol += tmp; + } + } + } /* while (fgets) */ + + if (fclose (fh)) + { + char errbuf[1024]; + WARNING ("processes: fclose: %s", + sstrerror (errno, errbuf, sizeof (errbuf))); + } + } + closedir (dh); + + ps->cswitch_vol = cswitch_vol; + ps->cswitch_invol = cswitch_invol; + + return (ps); + } /* int *ps_read_tasks_status */ + + static int ps_read_tasks (int pid) + { + char dirname[64]; + DIR *dh; + struct dirent *ent; + int count = 0; + + ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid); + + if ((dh = opendir (dirname)) == NULL) + { + DEBUG ("Failed to open directory `%s'", dirname); + return (-1); + } + + while ((ent = readdir (dh)) != NULL) + { + if (!isdigit ((int) ent->d_name[0])) + continue; + else + count++; + } + closedir (dh); + + return ((count >= 1) ? count : 1); + } /* int *ps_read_tasks */ + -/* Read advanced virtual memory data from /proc/pid/status */ -static procstat_t *ps_read_vmem (int pid, procstat_t *ps) +/* Read data from /proc/pid/status */ +static procstat_t *ps_read_status (int pid, procstat_t *ps) { FILE *fh; char buffer[1024];