X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fprocesses.c;h=f102a6c905f8d224b0f23ab090b4e612b500bc6d;hb=aee1cc1a20b3e7f131835fe5d3ba0f5a51cb6731;hp=c77859d9e7d9f6953abe3fb87c3e16aebdd44357;hpb=5eb71045f1d3b72b17e922a86b5014f68345b5b3;p=collectd.git diff --git a/src/processes.c b/src/processes.c index c77859d9..f102a6c9 100644 --- a/src/processes.c +++ b/src/processes.c @@ -112,8 +112,29 @@ /* #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 # include + +#ifndef MAXCOMLEN +# define MAXCOMLEN 16 +#endif + /* #endif KERNEL_SOLARIS */ #else @@ -223,7 +244,7 @@ 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 @@ -261,6 +282,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; } } @@ -286,7 +308,9 @@ static void ps_list_register (const char *name, const char *regexp) "`ProcessMatch' with the same name. " "All but the first setting will be " "ignored."); +#if HAVE_REGEX_H sfree (new->re); +#endif sfree (new); return; } @@ -528,6 +552,12 @@ static int ps_config (oconfig_item_t *ci) { int i; +#if KERNEL_LINUX + const size_t max_procname_len = 15; +#elif KERNEL_SOLARIS || KERNEL_FREEBSD + const size_t max_procname_len = MAXCOMLEN -1; +#endif + for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; @@ -548,6 +578,15 @@ static int ps_config (oconfig_item_t *ci) c->children_num, c->values[0].value.string); } +#if KERNEL_LINUX || KERNEL_SOLARIS || KERNEL_FREEBSD + if (strlen (c->values[0].value.string) > max_procname_len) { + WARNING ("processes plugin: this platform has a %zu character limit " + "to process names. The `Process \"%s\"' option will " + "not work as expected.", + max_procname_len, c->values[0].value.string); + } +#endif + ps_list_register (c->values[0].value.string, NULL); } else if (strcasecmp (c->key, "ProcessMatch") == 0) @@ -759,14 +798,14 @@ static void ps_submit_fork_rate (derive_t value) /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */ #if KERNEL_LINUX -static int ps_read_tasks (int pid) +static int ps_read_tasks (long pid) { char dirname[64]; DIR *dh; struct dirent *ent; int count = 0; - ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid); + ssnprintf (dirname, sizeof (dirname), "/proc/%li/task", pid); if ((dh = opendir (dirname)) == NULL) { @@ -787,7 +826,7 @@ static int ps_read_tasks (int pid) } /* int *ps_read_tasks */ /* Read advanced virtual memory data from /proc/pid/status */ -static procstat_t *ps_read_vmem (int pid, procstat_t *ps) +static procstat_t *ps_read_vmem (long pid, procstat_t *ps) { FILE *fh; char buffer[1024]; @@ -798,7 +837,7 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) char *fields[8]; int numfields; - ssnprintf (filename, sizeof (filename), "/proc/%i/status", pid); + ssnprintf (filename, sizeof (filename), "/proc/%li/status", pid); if ((fh = fopen (filename, "r")) == NULL) return (NULL); @@ -849,7 +888,7 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps) return (ps); } /* procstat_t *ps_read_vmem */ -static procstat_t *ps_read_io (int pid, procstat_t *ps) +static procstat_t *ps_read_io (long pid, procstat_t *ps) { FILE *fh; char buffer[1024]; @@ -858,7 +897,7 @@ static procstat_t *ps_read_io (int pid, procstat_t *ps) char *fields[8]; int numfields; - ssnprintf (filename, sizeof (filename), "/proc/%i/io", pid); + ssnprintf (filename, sizeof (filename), "/proc/%li/io", pid); if ((fh = fopen (filename, "r")) == NULL) return (NULL); @@ -904,7 +943,7 @@ static procstat_t *ps_read_io (int pid, procstat_t *ps) return (ps); } /* procstat_t *ps_read_io */ -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 buffer[1024]; @@ -927,7 +966,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state) memset (ps, 0, sizeof (procstat_t)); - ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid); + ssnprintf (filename, sizeof (filename), "/proc/%li/stat", pid); buffer_len = read_file_contents (filename, buffer, sizeof(buffer) - 1); @@ -972,9 +1011,9 @@ int ps_read_process (int pid, procstat_t *ps, char *state) fields_len = strsplit (buffer_ptr, fields, STATIC_ARRAY_SIZE (fields)); if (fields_len < 22) { - DEBUG ("processes plugin: ps_read_process (pid = %i):" + DEBUG ("processes plugin: ps_read_process (pid = %li):" " `%s' has only %i fields..", - (int) pid, filename, fields_len); + pid, filename, fields_len); return (-1); } @@ -998,7 +1037,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state) /* Leave the rest at zero if this is only a zombi */ if (ps->num_proc == 0) { - DEBUG ("processes plugin: This is only a zombi: pid = %i; " + DEBUG ("processes plugin: This is only a zombie: pid = %li; " "name = %s;", pid, ps->name); return (0); } @@ -1029,7 +1068,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state) /* No VMem data */ ps->vmem_data = -1; ps->vmem_code = -1; - DEBUG("ps_read_process: did not get vmem data for pid %i",pid); + DEBUG("ps_read_process: did not get vmem data for pid %li", pid); } ps->cpu_user_counter = cpu_user_counter; @@ -1046,14 +1085,14 @@ int ps_read_process (int pid, procstat_t *ps, char *state) ps->io_syscr = -1; ps->io_syscw = -1; - DEBUG("ps_read_process: not get io data for pid %i",pid); + DEBUG("ps_read_process: not get io data for pid %li", pid); } /* success */ return (0); } /* int ps_read_process (...) */ -static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len) +static char *ps_get_cmdline (long pid, char *name, char *buf, size_t buf_len) { char *buf_ptr; size_t len; @@ -1066,8 +1105,7 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len) if ((pid < 1) || (NULL == buf) || (buf_len < 2)) return NULL; - ssnprintf (file, sizeof (file), "/proc/%u/cmdline", - (unsigned int) pid); + ssnprintf (file, sizeof (file), "/proc/%li/cmdline", pid); errno = 0; fd = open (file, O_RDONLY); @@ -1148,7 +1186,7 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len) return buf; } /* char *ps_get_cmdline (...) */ -static int read_fork_rate () +static int read_fork_rate (void) { FILE *proc_stat; char buffer[1024]; @@ -1195,17 +1233,17 @@ static int read_fork_rate () #endif /*KERNEL_LINUX */ #if KERNEL_SOLARIS -static const char *ps_get_cmdline (pid_t pid, /* {{{ */ - char *buffer, size_t buffer_size) +static char *ps_get_cmdline (long pid, char *name __attribute__((unused)), /* {{{ */ + char *buffer, size_t buffer_size) { char path[PATH_MAX]; psinfo_t info; int status; - snprintf(path, sizeof (path), "/proc/%i/psinfo", pid); + snprintf(path, sizeof (path), "/proc/%li/psinfo", pid); status = read_file_contents (path, (void *) &info, sizeof (info)); - if (status != ((int) buffer_size)) + if (status != sizeof (info)) { ERROR ("processes plugin: Unexpected return value " "while reading \"%s\": " @@ -1226,7 +1264,7 @@ static const 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]; @@ -1236,9 +1274,9 @@ static int ps_read_process(int pid, procstat_t *ps, char *state) 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)); @@ -1262,6 +1300,10 @@ static int ps_read_process(int pid, procstat_t *ps, char *state) ps->num_proc = 0; ps->num_lwp = 0; *state = (char) 'Z'; + + sfree(myStatus); + sfree(myInfo); + sfree(myUsage); return (0); } else { ps->num_proc = 1; @@ -1684,7 +1726,7 @@ static int ps_read (void) struct dirent *ent; DIR *proc; - int pid; + long pid; char cmdline[ARG_MAX]; @@ -1711,7 +1753,7 @@ static int ps_read (void) if (!isdigit (ent->d_name[0])) continue; - if ((pid = atoi (ent->d_name)) < 1) + if ((pid = atol (ent->d_name)) < 1) continue; status = ps_read_process (pid, &ps, &state); @@ -1787,7 +1829,7 @@ static int ps_read (void) int wait = 0; kvm_t *kd; - char errbuf[1024]; + char errbuf[_POSIX2_LINE_MAX]; struct kinfo_proc *procs; /* array of processes */ struct kinfo_proc *proc_ptr = NULL; int count; /* returns number of processes */ @@ -1799,7 +1841,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", @@ -1893,18 +1935,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); @@ -2088,14 +2130,16 @@ static int ps_read (void) while ((ent = readdir(proc)) != NULL) { - int pid; + 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); @@ -2145,8 +2189,7 @@ static int ps_read (void) ps_list_add (ps.name, - ps_get_cmdline ((pid_t) pid, - cmdline, sizeof (cmdline)), + ps_get_cmdline (pid, ps.name, cmdline, sizeof (cmdline)), &pse); } /* while(readdir) */ closedir (proc);