X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fprocesses.c;h=bcc4ad5407ae2660d1baa3983b34647f0a82eb94;hb=ab2e3c958d3fed41438a8b3c2d0cca21b1bca56f;hp=a1aa17c21c0dfe745b2bb9585956055c8cad07f7;hpb=5fb55d066515132942bfb8f7b28fdc42f19a8bf9;p=collectd.git diff --git a/src/processes.c b/src/processes.c index a1aa17c2..bcc4ad54 100644 --- a/src/processes.c +++ b/src/processes.c @@ -112,7 +112,22 @@ /* #endif HAVE_PROCINFO_H */ #elif KERNEL_SOLARIS +/* Hack: Avoid #error when building a 32-bit binary with + * _FILE_OFFSET_BITS=64. There is a reason for this #error, as one + * of the structures in uses an off_t, but that + * isn't relevant to our usage of procfs. */ +#if !defined(_LP64) && _FILE_OFFSET_BITS == 64 +# define SAVE_FOB_64 +# undef _FILE_OFFSET_BITS +#endif + # include + +#ifdef SAVE_FOB_64 +# define _FILE_OFFSET_BITS 64 +# undef SAVE_FOB_64 +#endif + # include /* #endif KERNEL_SOLARIS */ @@ -223,12 +238,12 @@ static int pagesize; 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); +int getargs (void *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 - processes names we want to watch */ + * list_head_g is a list of 'procstat_t' structs with + * processes names we want to watch */ static void ps_list_register (const char *name, const char *regexp) { procstat_t *new; @@ -261,6 +276,7 @@ static void ps_list_register (const char *name, const char *regexp) { DEBUG ("ProcessMatch: compiling the regular expression \"%s\" failed.", regexp); sfree(new->re); + sfree(new); return; } } @@ -723,7 +739,7 @@ static void ps_submit_proc_list (procstat_t *ps) } DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; " - "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; " + "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; " "vmem_code = %lu; " "vmem_minflt_counter = %"PRIi64"; vmem_majflt_counter = %"PRIi64"; " "cpu_user_counter = %"PRIi64"; cpu_system_counter = %"PRIi64"; " @@ -811,7 +827,7 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) continue; numfields = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); + STATIC_ARRAY_SIZE (fields)); if (numfields < 2) continue; @@ -1195,25 +1211,30 @@ static int read_fork_rate () #endif /*KERNEL_LINUX */ #if KERNEL_SOLARIS -static char *ps_get_cmdline(pid_t pid) +static const char *ps_get_cmdline (long pid, /* {{{ */ + char *buffer, size_t buffer_size) { - char f_psinfo[64]; - char cmdline[80]; - char *buffer = NULL; - psinfo_t *myInfo; + char path[PATH_MAX]; + psinfo_t info; + int status; - snprintf(f_psinfo, sizeof (f_psinfo), "/proc/%i/psinfo", pid); + snprintf(path, sizeof (path), "/proc/%li/psinfo", pid); - buffer = (char *)malloc(sizeof (psinfo_t)); - memset(buffer, 0, sizeof(psinfo_t)); - read_file_contents(f_psinfo, buffer, sizeof (psinfo_t)); - myInfo = (psinfo_t *) buffer; + status = read_file_contents (path, (void *) &info, sizeof (info)); + if (status != sizeof (info)) + { + ERROR ("processes plugin: Unexpected return value " + "while reading \"%s\": " + "Returned %i but expected %zu.", + path, status, buffer_size); + return (NULL); + } - sstrncpy(cmdline, myInfo->pr_psargs, sizeof (myInfo->pr_psargs)); + info.pr_psargs[sizeof (info.pr_psargs) - 1] = 0; + sstrncpy (buffer, info.pr_psargs, buffer_size); - sfree(myInfo); - return strtok(cmdline, " "); -} + return (buffer); +} /* }}} int ps_get_cmdline */ /* * Reads process information on the Solaris OS. The information comes mainly from @@ -1221,21 +1242,19 @@ static char *ps_get_cmdline(pid_t pid) * The values for input and ouput chars are calculated "by hand" * Added a few "solaris" specific process states as well */ -static int ps_read_process(int pid, procstat_t *ps, char *state) +static int ps_read_process(long pid, procstat_t *ps, char *state) { char filename[64]; char f_psinfo[64], f_usage[64]; - int i; char *buffer; - pstatus_t *myStatus; psinfo_t *myInfo; prusage_t *myUsage; - snprintf(filename, sizeof (filename), "/proc/%i/status", pid); - snprintf(f_psinfo, sizeof (f_psinfo), "/proc/%i/psinfo", pid); - snprintf(f_usage, sizeof (f_usage), "/proc/%i/usage", pid); + snprintf(filename, sizeof (filename), "/proc/%li/status", pid); + snprintf(f_psinfo, sizeof (f_psinfo), "/proc/%li/psinfo", pid); + snprintf(f_usage, sizeof (f_usage), "/proc/%li/usage", pid); buffer = malloc(sizeof (pstatus_t)); @@ -1784,10 +1803,10 @@ static int ps_read (void) int wait = 0; kvm_t *kd; - char errbuf[1024]; - struct kinfo_proc *procs; /* array of processes */ + char errbuf[_POSIX2_LINE_MAX]; + struct kinfo_proc *procs; /* array of processes */ struct kinfo_proc *proc_ptr = NULL; - int count; /* returns number of processes */ + int count; /* returns number of processes */ int i; procstat_t *ps_ptr; @@ -1796,7 +1815,7 @@ static int ps_read (void) ps_list_reset (); /* Open the kvm interface, get a descriptor */ - kd = kvm_open (NULL, NULL, NULL, 0, errbuf); + kd = kvm_openfiles (NULL, "/dev/null", NULL, 0, errbuf); if (kd == NULL) { ERROR ("processes plugin: Cannot open kvm interface: %s", @@ -1890,18 +1909,18 @@ static int ps_read (void) pse.io_syscw = -1; ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse); - } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */ - switch (procs[i].ki_stat) - { - case SSTOP: stopped++; break; - case SSLEEP: sleeping++; break; - case SRUN: running++; break; - case SIDL: idle++; break; - case SWAIT: wait++; break; - case SLOCK: blocked++; break; - case SZOMB: zombies++; break; - } + switch (procs[i].ki_stat) + { + case SSTOP: stopped++; break; + case SSLEEP: sleeping++; break; + case SRUN: running++; break; + case SIDL: idle++; break; + case SWAIT: wait++; break; + case SLOCK: blocked++; break; + case SZOMB: zombies++; break; + } + } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */ } kvm_close(kd); @@ -1958,7 +1977,7 @@ static int ps_read (void) if (procentry[i].pi_pid == 0) cmdline = "swapper"; cargs = cmdline; - } + } else { if (getargs(&procentry[i], sizeof(struct procentry64), arglist, MAXARGLN) >= 0) @@ -2054,10 +2073,10 @@ static int ps_read (void) #elif KERNEL_SOLARIS /* - * The Solaris section adds a few more process states and removes some - * process states compared to linux. Most notably there is no "PAGING" - * and "BLOCKED" state for a process. The rest is similar to the linux - * code. + * The Solaris section adds a few more process states and removes some + * process states compared to linux. Most notably there is no "PAGING" + * and "BLOCKED" state for a process. The rest is similar to the linux + * code. */ int running = 0; int sleeping = 0; @@ -2067,45 +2086,52 @@ static int ps_read (void) int daemon = 0; int system = 0; int orphan = 0; + struct dirent *ent; DIR *proc; - int pid; int status; - struct procstat ps; - procstat_entry_t pse; procstat_t *ps_ptr; char state; - ps_list_reset(); + char cmdline[PRARGSZ]; + ps_list_reset (); - proc = opendir("/proc"); - if (proc == NULL) { + proc = opendir ("/proc"); + if (proc == NULL) return (-1); - } - while ((ent = readdir(proc)) != NULL) { - if (!isdigit(ent->d_name[0])) + while ((ent = readdir(proc)) != NULL) + { + long pid; + struct procstat ps; + procstat_entry_t pse; + char *endptr; + + if (!isdigit ((int) ent->d_name[0])) continue; - if ((pid = atoi(ent->d_name)) < 1) + pid = strtol (ent->d_name, &endptr, 10); + if (*endptr != 0) /* value didn't completely parse as a number */ continue; - status = ps_read_process(pid, &ps, &state); - if (status != 0) { + status = ps_read_process (pid, &ps, &state); + if (status != 0) + { DEBUG("ps_read_process failed: %i", status); continue; } + pse.id = pid; pse.age = 0; - pse.num_proc = ps.num_proc; - pse.num_lwp = ps.num_lwp; - pse.vmem_size = ps.vmem_size; - pse.vmem_rss = ps.vmem_rss; - pse.vmem_data = ps.vmem_data; - pse.vmem_code = ps.vmem_code; + pse.num_proc = ps.num_proc; + pse.num_lwp = ps.num_lwp; + pse.vmem_size = ps.vmem_size; + pse.vmem_rss = ps.vmem_rss; + pse.vmem_data = ps.vmem_data; + pse.vmem_code = ps.vmem_code; pse.stack_size = ps.stack_size; pse.vmem_minflt = 0; @@ -2123,28 +2149,23 @@ static int ps_read (void) pse.io_syscr = ps.io_syscr; pse.io_syscw = ps.io_syscw; - switch (state) { - case 'R': running++; - break; - case 'S': sleeping++; - break; - case 'E': detached++; - break; - case 'Z': zombies++; - break; - case 'T': stopped++; - break; - case 'A': daemon++; - break; - case 'Y': system++; - break; - case 'O': orphan++; - break; + switch (state) + { + case 'R': running++; break; + case 'S': sleeping++; break; + case 'E': detached++; break; + case 'Z': zombies++; break; + case 'T': stopped++; break; + case 'A': daemon++; break; + case 'Y': system++; break; + case 'O': orphan++; break; } - ps_list_add(ps.name, ps_get_cmdline(pid), &pse); - } // while() + ps_list_add (ps.name, + ps_get_cmdline (pid, cmdline, sizeof (cmdline)), + &pse); + } /* while(readdir) */ closedir (proc); ps_submit_state ("running", running);