X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fprocesses.c;h=24dbf49299edfcaa964ce54fd8a5cf6ce7d695fd;hb=20d15cfd26b23508242abcead906207bf26175d0;hp=7306edb01a9b6c0b6f2b477daba1cde20d6762ba;hpb=09229f7a867df4d2c133f12a0a22e5f6e518c3da;p=collectd.git diff --git a/src/processes.c b/src/processes.c index 7306edb0..24dbf492 100644 --- a/src/processes.c +++ b/src/processes.c @@ -362,7 +362,7 @@ static int ps_list_match (const char *name, const char *cmdline, procstat_t *ps) static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t *entry) { procstat_t *ps; - procstat_entry_t *pse; + procstat_entry_t *pse; if (entry->id == 0) return; @@ -498,7 +498,6 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t ps->cpu_user_counter += pse->cpu_user; ps->cpu_system_counter += pse->cpu_system; - } } @@ -610,14 +609,7 @@ static int ps_config (oconfig_item_t *ci) } else if (strcasecmp (c->key, "CollectContextSwitch") == 0) { - if ((c->values_num != 1) - || (c->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - ERROR ("processes plugin: `CollectContextSwitch' needs exactly " - "one boolean argument."); - continue; - } - report_ctx_switch = c->values[0].value.boolean ? 1 : 0; + cf_util_get_boolean (c, &report_ctx_switch); } else { @@ -770,12 +762,14 @@ static void ps_submit_proc_list (procstat_t *ps) if ( report_ctx_switch ) { - sstrncpy (vl.type, "ps_cswitch_vol", sizeof (vl.type)); + sstrncpy (vl.type, "contextswitch", sizeof (vl.type)); + sstrncpy (vl.type_instance, "voluntary", sizeof (vl.type_instance)); vl.values[0].derive = ps->cswitch_vol; vl.values_len = 1; plugin_dispatch_values (&vl); - sstrncpy (vl.type, "ps_cswitch_invol", sizeof (vl.type)); + sstrncpy (vl.type, "contextswitch", sizeof (vl.type)); + sstrncpy (vl.type_instance, "involuntary", sizeof (vl.type_instance)); vl.values[0].derive = ps->cswitch_invol; vl.values_len = 1; plugin_dispatch_values (&vl); @@ -827,8 +821,8 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps) char filename[64]; FILE *fh; struct dirent *ent; - unsigned long long cswitch_vol = 0; - unsigned long long cswitch_invol = 0; + derive_t cswitch_vol = 0; + derive_t cswitch_invol = 0; char buffer[1024]; char *fields[8]; int numfields; @@ -859,7 +853,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps) while (fgets (buffer, sizeof(buffer), fh) != NULL) { - long long tmp; + derive_t tmp; char *endptr; if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0 @@ -874,7 +868,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps) errno = 0; endptr = NULL; - tmp = strtoll (fields[1], &endptr, /* base = */ 10); + tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10); if ((errno == 0) && (endptr != fields[1])) { if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0) @@ -903,42 +897,16 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps) 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]; char filename[64]; - unsigned long long lib = 0; - unsigned long long exe = 0; - unsigned long long data = 0; + unsigned long lib = 0; + unsigned long exe = 0; + unsigned long data = 0; + unsigned long threads = 0; char *fields[8]; int numfields; @@ -948,10 +916,11 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) while (fgets (buffer, sizeof(buffer), fh) != NULL) { - long long tmp; + unsigned long tmp; char *endptr; - if (strncmp (buffer, "Vm", 2) != 0) + if (strncmp (buffer, "Vm", 2) != 0 + && strncmp (buffer, "Threads", 7) != 0) continue; numfields = strsplit (buffer, fields, @@ -962,7 +931,7 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) errno = 0; endptr = NULL; - tmp = strtoll (fields[1], &endptr, /* base = */ 10); + tmp = strtoul (fields[1], &endptr, /* base = */ 10); if ((errno == 0) && (endptr != fields[1])) { if (strncmp (buffer, "VmData", 6) == 0) @@ -977,6 +946,10 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) { exe = tmp; } + else if (strncmp(buffer, "Threads", 7) == 0) + { + threads = tmp; + } } } /* while (fgets) */ @@ -989,6 +962,8 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) ps->vmem_data = data * 1024; ps->vmem_code = (exe + lib) * 1024; + if (threads != 0) + ps->num_lwp = threads; return (ps); } /* procstat_t *ps_read_vmem */ @@ -1056,9 +1031,9 @@ int ps_read_process (int pid, procstat_t *ps, char *state) char *fields[64]; char fields_len; - int buffer_len; + size_t buffer_len; - char *buffer_ptr; + char *buffer_ptr; size_t name_start_pos; size_t name_end_pos; size_t name_len; @@ -1069,14 +1044,16 @@ int ps_read_process (int pid, procstat_t *ps, char *state) long long unsigned vmem_rss; long long unsigned stack_size; + ssize_t status; + memset (ps, 0, sizeof (procstat_t)); ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid); - buffer_len = read_file_contents (filename, - buffer, sizeof(buffer) - 1); - if (buffer_len <= 0) + status = read_file_contents (filename, buffer, sizeof(buffer) - 1); + if (status <= 0) return (-1); + buffer_len = (size_t) status; buffer[buffer_len] = 0; /* The name of the process is enclosed in parens. Since the name can @@ -1131,11 +1108,16 @@ int ps_read_process (int pid, procstat_t *ps, char *state) } else { - if ( (ps->num_lwp = ps_read_tasks (pid)) == -1 ) + ps->num_lwp = strtoul (fields[17], /* endptr = */ NULL, /* base = */ 10); + if ((ps_read_status(pid, ps)) == NULL) { - /* returns -1 => kernel 2.4 */ - ps->num_lwp = 1; + /* No VMem data */ + ps->vmem_data = -1; + ps->vmem_code = -1; + DEBUG("ps_read_process: did not get vmem data for pid %i",pid); } + if (ps->num_lwp <= 0) + ps->num_lwp = 1; ps->num_proc = 1; } @@ -1168,14 +1150,6 @@ int ps_read_process (int pid, procstat_t *ps, char *state) cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ; vmem_rss = vmem_rss * pagesize_g; - if ( (ps_read_vmem(pid, ps)) == NULL) - { - /* No VMem data */ - ps->vmem_data = -1; - ps->vmem_code = -1; - DEBUG("ps_read_process: did not get vmem data for pid %i",pid); - } - ps->cpu_user_counter = cpu_user_counter; ps->cpu_system_counter = cpu_system_counter; ps->vmem_size = (unsigned long) vmem_size; @@ -1356,16 +1330,16 @@ static const char *ps_get_cmdline (long pid, /* {{{ */ { char path[PATH_MAX]; psinfo_t info; - int status; + ssize_t status; snprintf(path, sizeof (path), "/proc/%li/psinfo", pid); status = read_file_contents (path, (void *) &info, sizeof (info)); - if (status != sizeof (info)) + if ((status < 0) || (((size_t) status) != sizeof (info))) { ERROR ("processes plugin: Unexpected return value " "while reading \"%s\": " - "Returned %i but expected %zu.", + "Returned %zd but expected %zu.", path, status, buffer_size); return (NULL); } @@ -1877,6 +1851,7 @@ static int ps_read (void) continue; } + memset (&pse, 0, sizeof (pse)); pse.id = pid; pse.age = 0; @@ -2154,6 +2129,7 @@ static int ps_read (void) } } /* if (process has argument list) */ + memset (&pse, 0, sizeof (pse)); pse.id = procs[i].p_pid; pse.age = 0; @@ -2183,6 +2159,9 @@ static int ps_read (void) pse.io_syscr = -1; pse.io_syscw = -1; + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse); } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */ @@ -2398,6 +2377,7 @@ static int ps_read (void) continue; } + memset (&pse, 0, sizeof (pse)); pse.id = pid; pse.age = 0; @@ -2424,6 +2404,9 @@ static int ps_read (void) pse.io_syscr = ps.io_syscr; pse.io_syscw = ps.io_syscw; + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + switch (state) { case 'R': running++; break;