Merge pull request #1546 from mfournier/processname_length_1284
authorRuben Kerkhof <ruben@rubenkerkhof.com>
Sun, 24 Apr 2016 11:25:21 +0000 (13:25 +0200)
committerRuben Kerkhof <ruben@rubenkerkhof.com>
Sun, 24 Apr 2016 11:25:21 +0000 (13:25 +0200)
processes: warn about process names above OS limit

1  2 
src/collectd.conf.pod
src/processes.c

diff --combined src/collectd.conf.pod
@@@ -172,7 -172,9 +172,7 @@@ I<pattern> may be specified to filter w
  in combination with recursively including a directory to easily be able to
  arbitrarily mix configuration files and other documents (e.g. README files).
  The given example is similar to the first example above but includes all files
 -matching C<*.conf> in any subdirectory of C</etc/collectd.d>:
 -
 -  Include "/etc/collectd.d" "*.conf"
 +matching C<*.conf> in any subdirectory of C</etc/collectd.d>.
  
  =back
  
@@@ -1991,7 -1993,7 +1991,7 @@@ a more detailed description see B<Ignor
  
  =item B<IgnoreSelected> I<true>|I<false>
  
 -If no configuration if given, the B<traffic>-plugin will collect data from
 +If no configuration if given, the B<interface>-plugin will collect data from
  all interfaces. This may not be practical, especially for loopback- and
  similar interfaces. Thus, you can use the B<Interface>-option to pick the
  interfaces you're interested in. Sometimes, however, it's easier/preferred
@@@ -4794,6 -4796,9 +4794,9 @@@ collected for these selected processes 
  (RSS), user- and system-time used, number of processes and number of threads,
  io data (where available) and minor and major pagefaults.
  
+ Some platforms have a limit on the length of process names. I<Name> must stay
+ below this limit.
  =item B<ProcessMatch> I<name> I<regex>
  
  Similar to the B<Process> option this allows to select more detailed
diff --combined src/processes.c
  #  undef SAVE_FOB_64
  #endif
  
+ # include <sys/user.h>
  # include <dirent.h>
  /* #endif KERNEL_SOLARIS */
  
@@@ -546,6 -547,12 +547,12 @@@ static int ps_config (oconfig_item_t *c
  {
        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;
  
                                                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)
@@@ -777,14 -793,14 +793,14 @@@ static void ps_submit_fork_rate (derive
  
  /* ------- 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)
        {
  } /* 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];
        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);
  
        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];
        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);
  
        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];
  
        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);
        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);
        }
  
        /* Leave the rest at zero if this is only a zombi */
        if (ps->num_proc == 0)
        {
 -              DEBUG ("processes plugin: This is only a zombie: pid = %i; "
 +              DEBUG ("processes plugin: This is only a zombie: pid = %li; "
                                "name = %s;", pid, ps->name);
                return (0);
        }
                /* 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;
                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;
        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);
        return buf;
  } /* char *ps_get_cmdline (...) */
  
 -static int read_fork_rate ()
 +static int read_fork_rate (void)
  {
        FILE *proc_stat;
        char buffer[1024];
  #endif /*KERNEL_LINUX */
  
  #if KERNEL_SOLARIS
 -static char *ps_get_cmdline (pid_t pid, char *name __attribute__((unused)), /* {{{ */
 +static char *ps_get_cmdline (long pid, char *name __attribute__((unused)), /* {{{ */
      char *buffer, size_t buffer_size)
  {
        char path[PATH_MAX];
@@@ -1279,10 -1296,6 +1295,10 @@@ static int ps_read_process(long pid, pr
                ps->num_proc = 0;
                ps->num_lwp = 0;
                *state = (char) 'Z';
 +
 +              sfree(myStatus);
 +              sfree(myInfo);
 +              sfree(myUsage);
                return (0);
        } else {
                ps->num_proc = 1;
@@@ -1705,7 -1718,7 +1721,7 @@@ static int ps_read (void
  
        struct dirent *ent;
        DIR           *proc;
 -      int            pid;
 +      long           pid;
  
        char cmdline[ARG_MAX];
  
                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);