X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fprocesses.c;h=f2eb0a34a0156613725ea0be87688b155d862c40;hb=9988d61c84dfff5d04ddf48f4b93f6c9449cdc41;hp=5ef4acc039907743d1f22180f23871ec5f9ce326;hpb=b5ed3c9b617ba78a98f3ef279bb3efa325536080;p=collectd.git diff --git a/src/processes.c b/src/processes.c index 5ef4acc0..f2eb0a34 100644 --- a/src/processes.c +++ b/src/processes.c @@ -4,6 +4,8 @@ * Copyright (C) 2006-2008 Florian octo Forster * Copyright (C) 2008 Oleg King * Copyright (C) 2009 Sebastian Harl + * Copyright (C) 2009 Andrés J. Díaz + * Copyright (C) 2009 Manuel Sanmartin * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -24,6 +26,8 @@ * Florian octo Forster * Oleg King * Sebastian Harl + * Andrés J. Díaz + * Manuel Sanmartin **/ #include "collectd.h" @@ -94,6 +98,15 @@ # include /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +#elif HAVE_PROCINFO_H +# include +# include + +#define MAXPROCENTRY 32 +#define MAXTHRDENTRY 16 +#define MAXARGLN 1024 +/* #endif HAVE_PROCINFO_H */ + #else # error "No applicable input method." #endif @@ -137,10 +150,10 @@ typedef struct procstat_entry_s unsigned long cpu_system_counter; /* io data */ - long io_rchar; - long io_wchar; - long io_syscr; - long io_syscw; + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; struct procstat_entry_s *next; } procstat_entry_t; @@ -166,10 +179,10 @@ typedef struct procstat unsigned long cpu_system_counter; /* io data */ - long io_rchar; - long io_wchar; - long io_syscr; - long io_syscw; + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; struct procstat *next; struct procstat_entry_s *instances; @@ -191,7 +204,19 @@ static long pagesize_g; #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD /* no global variables */ -#endif /* HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ + +#elif HAVE_PROCINFO_H +static struct procentry64 procentry[MAXPROCENTRY]; +static struct thrdentry64 thrdentry[MAXTHRDENTRY]; +static int pagesize; + +#ifndef _AIXVERSION_610 +int getprocs64 (void *procsinfo, int sizproc, void *fdsinfo, int sizfd, pid_t *index, int count); +int getthrds64( pid_t, void *, int, tid64_t *, int ); +#endif +int getargs (struct procentry64 *processBuffer, int bufferLen, char *argsBuffer, int argsLen); +#endif /* HAVE_PROCINFO_H */ /* put name of process from config to list_head_g tree list_head_g is a list of 'procstat_t' structs with @@ -237,13 +262,13 @@ static void ps_list_register (const char *name, const char *regexp) ERROR ("processes plugin: ps_list_register: " "Regular expression \"%s\" found in config " "file, but support for regular expressions " - "has been dispabled at compile time.", + "has been disabled at compile time.", regexp); sfree (new); return; } #endif - + for (ptr = list_head_g; ptr != NULL; ptr = ptr->next) { if (strcmp (ptr->name, name) == 0) @@ -319,13 +344,13 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t if ((pse == NULL) || (pse->id != entry->id)) { procstat_entry_t *new; - + new = (procstat_entry_t *) malloc (sizeof (procstat_entry_t)); if (new == NULL) return; memset (new, 0, sizeof (procstat_entry_t)); new->id = entry->id; - + if (pse == NULL) ps->instances = new; else @@ -377,7 +402,7 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t pse->vmem_minflt = entry->vmem_minflt_counter - pse->vmem_minflt_counter; } pse->vmem_minflt_counter = entry->vmem_minflt_counter; - + if (entry->vmem_majflt_counter < pse->vmem_majflt_counter) { pse->vmem_majflt = entry->vmem_majflt_counter @@ -414,7 +439,7 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t pse->cpu_user = entry->cpu_user_counter - pse->cpu_user_counter; } pse->cpu_user_counter = entry->cpu_user_counter; - + if (entry->cpu_system_counter < pse->cpu_system_counter) { pse->cpu_system = entry->cpu_system_counter @@ -563,7 +588,11 @@ static int ps_init (void) #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD /* no initialization */ -#endif /* HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ + +#elif HAVE_PROCINFO_H + pagesize = getpagesize(); +#endif /* HAVE_PROCINFO_H */ return (0); } /* int ps_init */ @@ -635,8 +664,8 @@ static void ps_submit_proc_list (procstat_t *ps) if ( (ps->io_rchar != -1) && (ps->io_wchar != -1) ) { sstrncpy (vl.type, "ps_disk_octets", sizeof (vl.type)); - vl.values[0].counter = ps->io_rchar; - vl.values[1].counter = ps->io_wchar; + vl.values[0].derive = ps->io_rchar; + vl.values[1].derive = ps->io_wchar; vl.values_len = 2; plugin_dispatch_values (&vl); } @@ -644,8 +673,8 @@ static void ps_submit_proc_list (procstat_t *ps) if ( (ps->io_syscr != -1) && (ps->io_syscw != -1) ) { sstrncpy (vl.type, "ps_disk_ops", sizeof (vl.type)); - vl.values[0].counter = ps->io_syscr; - vl.values[1].counter = ps->io_syscw; + vl.values[0].derive = ps->io_syscr; + vl.values[1].derive = ps->io_syscw; vl.values_len = 2; plugin_dispatch_values (&vl); } @@ -653,8 +682,8 @@ static void ps_submit_proc_list (procstat_t *ps) DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; vmem_rss = %lu; " "vmem_minflt_counter = %lu; vmem_majflt_counter = %lu; " "cpu_user_counter = %lu; cpu_system_counter = %lu; " - "io_rchar = %ld; io_wchar = %ld; " - "io_syscr = %ld; io_syscw = %ld;", + "io_rchar = %"PRIi64"; io_wchar = %"PRIi64"; " + "io_syscr = %"PRIi64"; io_syscw = %"PRIi64";", ps->name, ps->num_proc, ps->num_lwp, ps->vmem_rss, ps->vmem_minflt_counter, ps->vmem_majflt_counter, ps->cpu_user_counter, ps->cpu_system_counter, @@ -705,7 +734,9 @@ static procstat_t *ps_read_io (int pid, procstat_t *ps) while (fgets (buffer, 1024, fh) != NULL) { - long *val = NULL; + derive_t *val = NULL; + long long tmp; + char *endptr; if (strncasecmp (buffer, "rchar:", 6) == 0) val = &(ps->io_rchar); @@ -723,8 +754,14 @@ static procstat_t *ps_read_io (int pid, procstat_t *ps) if (numfields < 2) continue; - *val = atol (fields[1]); - } + errno = 0; + endptr = NULL; + tmp = strtoll (fields[1], &endptr, /* base = */ 10); + if ((errno != 0) || (endptr == fields[1])) + *val = -1; + else + *val = (derive_t) tmp; + } /* while (fgets) */ if (fclose (fh)) { @@ -1542,7 +1579,133 @@ static int ps_read (void) for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) ps_submit_proc_list (ps_ptr); -#endif /* HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ + +#elif HAVE_PROCINFO_H + /* AIX */ + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int paging = 0; + int blocked = 0; + + pid_t pindex = 0; + int nprocs; + + procstat_t *ps; + procstat_entry_t pse; + + ps_list_reset (); + while ((nprocs = getprocs64 (procentry, sizeof(struct procentry64), + /* fdsinfo = */ NULL, sizeof(struct fdsinfo64), + &pindex, MAXPROCENTRY)) > 0) + { + int i; + + for (i = 0; i < nprocs; i++) + { + tid64_t thindex; + int nthreads; + char arglist[MAXARGLN+1]; + char *cargs; + char *cmdline; + + if (procentry[i].pi_state == SNONE) continue; + /* if (procentry[i].pi_state == SZOMB) FIXME */ + + cmdline = procentry[i].pi_comm; + cargs = procentry[i].pi_comm; + if ( procentry[i].pi_flags & SKPROC ) + { + if (procentry[i].pi_pid == 0) + cmdline = "swapper"; + cargs = cmdline; + } + else + { + if (getargs(&procentry[i], sizeof(struct procentry64), arglist, MAXARGLN) >= 0) + { + int n; + + n = -1; + while (++n < MAXARGLN) + { + if (arglist[n] == '\0') + { + if (arglist[n+1] == '\0') + break; + arglist[n] = ' '; + } + } + cargs = arglist; + } + } + + pse.id = procentry[i].pi_pid; + pse.age = 0; + pse.num_lwp = procentry[i].pi_thcount; + pse.num_proc = 1; + + thindex=0; + while ((nthreads = getthrds64(procentry[i].pi_pid, + thrdentry, sizeof(struct thrdentry64), + &thindex, MAXTHRDENTRY)) > 0) + { + int j; + + for (j=0; j< nthreads; j++) + { + switch (thrdentry[j].ti_state) + { + /* case TSNONE: break; */ + case TSIDL: blocked++; break; /* FIXME is really blocked */ + case TSRUN: running++; break; + case TSSLEEP: sleeping++; break; + case TSSWAP: paging++; break; + case TSSTOP: stopped++; break; + case TSZOMB: zombies++; break; + } + } + if (nthreads < MAXTHRDENTRY) + break; + } + + pse.cpu_user = 0; + /* tv_usec is nanosec ??? */ + pse.cpu_user_counter = procentry[i].pi_ru.ru_utime.tv_sec * 1000000 + + procentry[i].pi_ru.ru_utime.tv_usec / 1000; + + pse.cpu_system = 0; + /* tv_usec is nanosec ??? */ + pse.cpu_system_counter = procentry[i].pi_ru.ru_stime.tv_sec * 1000000 + + procentry[i].pi_ru.ru_stime.tv_usec / 1000; + + pse.vmem_minflt = 0; + pse.vmem_minflt_counter = procentry[i].pi_minflt; + pse.vmem_majflt = 0; + pse.vmem_majflt_counter = procentry[i].pi_majflt; + + pse.vmem_size = procentry[i].pi_tsize + procentry[i].pi_dvm * pagesize; + pse.vmem_rss = (procentry[i].pi_drss + procentry[i].pi_trss) * pagesize; + pse.stack_size = 0; + + ps_list_add (cmdline, cargs, &pse); + } /* for (i = 0 .. nprocs) */ + + if (nprocs < MAXPROCENTRY) + break; + } /* while (getprocs64() > 0) */ + ps_submit_state ("running", running); + ps_submit_state ("sleeping", sleeping); + ps_submit_state ("zombies", zombies); + ps_submit_state ("stopped", stopped); + ps_submit_state ("paging", paging); + ps_submit_state ("blocked", blocked); + + for (ps = list_head_g; ps != NULL; ps = ps->next) + ps_submit_proc_list (ps); +#endif /* HAVE_PROCINFO_H */ return (0); } /* int ps_read */