Merge branch 'collectd-5.4' into collectd-5.5
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 26 Jan 2016 11:18:26 +0000 (12:18 +0100)
committerMarc Fournier <marc.fournier@camptocamp.com>
Tue, 26 Jan 2016 11:18:26 +0000 (12:18 +0100)
1  2 
src/openvpn.c
src/processes.c

diff --combined src/openvpn.c
@@@ -32,7 -32,6 +32,7 @@@
  #define V1STRING "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since\n"
  #define V2STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)\n"
  #define V3STRING "HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes Received Bytes Sent Connected Since Connected Since (time_t)\n"
 +#define V4STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t),Username\n"
  #define VSSTRING "OpenVPN STATISTICS\n"
  
  
@@@ -44,7 -43,6 +44,7 @@@ struct vpn_status_
                MULTI1 = 1, /* status-version 1 */
                MULTI2,     /* status-version 2 */
                MULTI3,     /* status-version 3 */
 +              MULTI4,     /* status-version 4 */
                SINGLE = 10 /* currently no versions for single mode, maybe in the future */
        } version;
        char *name;
@@@ -450,70 -448,6 +450,70 @@@ static int multi3_read (char *name, FIL
        return (read);
  } /* int multi3_read */
  
 +/* for reading status version 4 */
 +static int multi4_read (char *name, FILE *fh)
 +{
 +      char buffer[1024];
 +      char *fields[11];
 +      const int max_fields = STATIC_ARRAY_SIZE (fields);
 +      int  fields_num, read = 0;
 +      long long sum_users    = 0;
 +
 +      while (fgets (buffer, sizeof (buffer), fh) != NULL)
 +      {
 +              fields_num = openvpn_strsplit (buffer, fields, max_fields);
 +
 +              /* status file is generated by openvpn/multi.c:multi_print_status()
 +               * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
 +               *
 +               * The line we're expecting has 9 fields. We ignore all lines
 +               *  with more or less fields.
 +               */
 +              if (fields_num != 9)
 +                      continue;
 +
 +
 +              if (strcmp (fields[0], "CLIENT_LIST") != 0)
 +                      continue;
 +
 +
 +              if (collect_user_count)
 +                      /* If so, sum all users, ignore the individuals*/
 +              {
 +                      sum_users += 1;
 +              }
 +              if (collect_individual_users)
 +              {
 +                      if (new_naming_schema)
 +                      {
 +                              /* plugin inst = file name, type inst = fields[1] */
 +                              iostats_submit (name,               /* vpn instance */
 +                                              fields[1],          /* "Common Name" */
 +                                              atoll (fields[4]),  /* "Bytes Received" */
 +                                              atoll (fields[5])); /* "Bytes Sent" */
 +                      }
 +                      else
 +                      {
 +                              /* plugin inst = fields[1], type inst = "" */
 +                              iostats_submit (fields[1],          /* "Common Name" */
 +                                              NULL,               /* unused when in multimode */
 +                                              atoll (fields[4]),  /* "Bytes Received" */
 +                                              atoll (fields[5])); /* "Bytes Sent" */
 +                      }
 +              }
 +
 +              read = 1;
 +      }
 +
 +      if (collect_user_count)
 +      {
 +              numusers_submit(name, name, sum_users);
 +              read = 1;
 +      }
 +
 +      return (read);
 +} /* int multi4_read */
 +
  /* read callback */
  static int openvpn_read (void)
  {
        /* call the right read function for every status entry in the list */
        for (i = 0; i < vpn_num; i++)
        {
-               int vpn_read = 0;
                fh = fopen (vpn_list[i]->file, "r");
                if (fh == NULL)
                {
                switch (vpn_list[i]->version)
                {
                        case SINGLE:
 -                              read = single_read(vpn_list[i]->name, fh);
 +                              vpn_read = single_read(vpn_list[i]->name, fh);
                                break;
  
                        case MULTI1:
 -                              read = multi1_read(vpn_list[i]->name, fh);
 +                              vpn_read = multi1_read(vpn_list[i]->name, fh);
                                break;
  
                        case MULTI2:
 -                              read = multi2_read(vpn_list[i]->name, fh);
 +                              vpn_read = multi2_read(vpn_list[i]->name, fh);
                                break;
  
                        case MULTI3:
 -                              read = multi3_read(vpn_list[i]->name, fh);
 +                              vpn_read = multi3_read(vpn_list[i]->name, fh);
 +                              break;
 +
 +                      case MULTI4:
 +                              vpn_read = multi4_read(vpn_list[i]->name, fh);
                                break;
                }
  
                fclose (fh);
 +              read += vpn_read;
        }
  
        return (read ? 0 : -1);
@@@ -618,13 -545,6 +616,13 @@@ static int version_detect (const char *
                        version = MULTI3;
                        break;
                }
 +              /* searching for multi version 4 */
 +              else if (strcmp (buffer, V4STRING) == 0)
 +              {
 +                      DEBUG ("openvpn plugin: found status file version MULTI4");
 +                      version = MULTI4;
 +                      break;
 +              }
        }
  
        if (version == 0)
diff --combined src/processes.c
@@@ -25,7 -25,7 +25,7 @@@
   *
   * Authors:
   *   Lyonel Vincent <lyonel at ezix.org>
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   *   Oleg King <king2 at kaluga.ru>
   *   Sebastian Harl <sh at tokkee.org>
   *   Andrés J. Díaz <ajdiaz at connectical.com>
  #  endif
  /* #endif KERNEL_LINUX */
  
 -#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
 +#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
  #  include <kvm.h>
  #  include <sys/param.h>
  #  include <sys/sysctl.h>
  #  include <sys/user.h>
  #  include <sys/proc.h>
 -/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
 +/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */
  
  #elif HAVE_PROCINFO_H
  #  include <procinfo.h>
  # include <kstat.h>
  #endif
  
 -#ifndef ARG_MAX
 -#  define ARG_MAX 4096
 +#ifndef CMDLINE_BUFFER_SIZE
 +# if defined(ARG_MAX) && (ARG_MAX < 4096)
 +#  define CMDLINE_BUFFER_SIZE ARG_MAX
 +# else
 +#  define CMDLINE_BUFFER_SIZE 4096
 +# endif
  #endif
  
  typedef struct procstat_entry_s
@@@ -229,9 -225,9 +229,9 @@@ static mach_msg_type_number_t     pset_
  static long pagesize_g;
  /* #endif KERNEL_LINUX */
  
 -#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
 +#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
  static int pagesize;
 -/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
 +/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */
  
  #elif HAVE_PROCINFO_H
  static  struct procentry64 procentry[MAXPROCENTRY];
@@@ -306,7 -302,9 +306,9 @@@ static void ps_list_register (const cha
                                        "`ProcessMatch' with the same name. "
                                        "All but the first setting will be "
                                        "ignored.");
+ #if HAVE_REGEX_H
                        sfree (new->re);
+ #endif
                        sfree (new);
                        return;
                }
@@@ -639,9 -637,9 +641,9 @@@ static int ps_init (void
                        pagesize_g, CONFIG_HZ);
  /* #endif KERNEL_LINUX */
  
 -#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
 +#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
        pagesize = getpagesize();
 -/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
 +/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */
  
  #elif HAVE_PROCINFO_H
        pagesize = getpagesize();
@@@ -1215,8 -1213,8 +1217,8 @@@ static int read_fork_rate (
  #endif /*KERNEL_LINUX */
  
  #if KERNEL_SOLARIS
- static const char *ps_get_cmdline (long pid, /* {{{ */
-               char *buffer, size_t buffer_size)
+ static char *ps_get_cmdline (pid_t pid, char *name __attribute__((unused)), /* {{{ */
+     char *buffer, size_t buffer_size)
  {
        char path[PATH_MAX];
        psinfo_t info;
@@@ -1706,7 -1704,7 +1708,7 @@@ static int ps_read (void
        DIR           *proc;
        int            pid;
  
 -      char cmdline[ARG_MAX];
 +      char cmdline[CMDLINE_BUFFER_SIZE];
  
        int        status;
        procstat_t ps;
                        continue;
                }
  
 +              memset (&pse, 0, sizeof (pse));
                pse.id       = pid;
                pse.age      = 0;
  
                 * filter out threads (duplicate PID entries). */
                if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid))
                {
 -                      char cmdline[ARG_MAX] = "";
 +                      char cmdline[CMDLINE_BUFFER_SIZE] = "";
                        _Bool have_cmdline = 0;
  
                        proc_ptr = &(procs[i]);
                ps_submit_proc_list (ps_ptr);
  /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
  
 +#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD
 +      int running  = 0;
 +      int sleeping = 0;
 +      int zombies  = 0;
 +      int stopped  = 0;
 +      int onproc   = 0;
 +      int idle     = 0;
 +      int dead     = 0;
 +
 +      kvm_t *kd;
 +      char errbuf[1024];
 +      struct kinfo_proc *procs;          /* array of processes */
 +      struct kinfo_proc *proc_ptr = NULL;
 +      int count;                         /* returns number of processes */
 +      int i;
 +
 +      procstat_t *ps_ptr;
 +      procstat_entry_t pse;
 +
 +      ps_list_reset ();
 +
 +      /* Open the kvm interface, get a descriptor */
 +      kd = kvm_open (NULL, NULL, NULL, 0, errbuf);
 +      if (kd == NULL)
 +      {
 +              ERROR ("processes plugin: Cannot open kvm interface: %s",
 +                              errbuf);
 +              return (0);
 +      }
 +
 +      /* Get the list of processes. */
 +      procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
 +      if (procs == NULL)
 +      {
 +              ERROR ("processes plugin: Cannot get kvm processes list: %s",
 +                              kvm_geterr(kd));
 +              kvm_close (kd);
 +              return (0);
 +      }
 +
 +      /* Iterate through the processes in kinfo_proc */
 +      for (i = 0; i < count; i++)
 +      {
 +              /* Create only one process list entry per _process_, i.e.
 +               * filter out threads (duplicate PID entries). */
 +              if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid))
 +              {
 +                      char cmdline[CMDLINE_BUFFER_SIZE] = "";
 +                      _Bool have_cmdline = 0;
 +
 +                      proc_ptr = &(procs[i]);
 +                      /* Don't probe zombie processes  */
 +                      if (!P_ZOMBIE(proc_ptr))
 +                      {
 +                              char **argv;
 +                              int argc;
 +                              int status;
 +
 +                              /* retrieve the arguments */
 +                              argv = kvm_getargv (kd, proc_ptr, /* nchr = */ 0);
 +                              argc = 0;
 +                              if ((argv != NULL) && (argv[0] != NULL))
 +                              {
 +                                      while (argv[argc] != NULL)
 +                                              argc++;
 +
 +                                      status = strjoin (cmdline, sizeof (cmdline), argv, argc, " ");
 +                                      if (status < 0)
 +                                              WARNING ("processes plugin: Command line did not fit into buffer.");
 +                                      else
 +                                              have_cmdline = 1;
 +                              }
 +                      } /* if (process has argument list) */
 +
 +                      memset (&pse, 0, sizeof (pse));
 +                      pse.id       = procs[i].p_pid;
 +                      pse.age      = 0;
 +
 +                      pse.num_proc = 1;
 +                      pse.num_lwp  = 1; /* XXX: accumulate p_tid values for a single p_pid ? */
 +
 +                      pse.vmem_rss = procs[i].p_vm_rssize * pagesize;
 +                      pse.vmem_data = procs[i].p_vm_dsize * pagesize;
 +                      pse.vmem_code = procs[i].p_vm_tsize * pagesize;
 +                      pse.stack_size = procs[i].p_vm_ssize * pagesize;
 +                      pse.vmem_size = pse.stack_size + pse.vmem_code + pse.vmem_data;
 +                      pse.vmem_minflt = 0;
 +                      pse.vmem_minflt_counter = procs[i].p_uru_minflt;
 +                      pse.vmem_majflt = 0;
 +                      pse.vmem_majflt_counter = procs[i].p_uru_majflt;
 +
 +                      pse.cpu_user = 0;
 +                      pse.cpu_system = 0;
 +                      pse.cpu_user_counter = procs[i].p_uutime_usec +
 +                                              (1000000lu * procs[i].p_uutime_sec);
 +                      pse.cpu_system_counter = procs[i].p_ustime_usec +
 +                                              (1000000lu * procs[i].p_ustime_sec);
 +
 +                      /* no I/O data */
 +                      pse.io_rchar = -1;
 +                      pse.io_wchar = -1;
 +                      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);
 +
 +                      switch (procs[i].p_stat)
 +                      {
 +                              case SSTOP:     stopped++;      break;
 +                              case SSLEEP:    sleeping++;     break;
 +                              case SRUN:      running++;      break;
 +                              case SIDL:      idle++;         break;
 +                              case SONPROC:   onproc++;       break;
 +                              case SDEAD:     dead++;         break;
 +                              case SZOMB:     zombies++;      break;
 +                      }
 +              } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
 +      }
 +
 +      kvm_close(kd);
 +
 +      ps_submit_state ("running",  running);
 +      ps_submit_state ("sleeping", sleeping);
 +      ps_submit_state ("zombies",  zombies);
 +      ps_submit_state ("stopped",  stopped);
 +      ps_submit_state ("onproc",   onproc);
 +      ps_submit_state ("idle",     idle);
 +      ps_submit_state ("dead",     dead);
 +
 +      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_OPENBSD */
 +
  #elif HAVE_PROCINFO_H
        /* AIX */
        int running  = 0;
                        continue;
                }
  
 +              memset (&pse, 0, sizeof (pse));
                pse.id = pid;
                pse.age = 0;
  
                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;
  
  
                ps_list_add (ps.name,
-                               ps_get_cmdline (pid, cmdline, sizeof (cmdline)),
+                               ps_get_cmdline (pid, ps.name, cmdline, sizeof (cmdline)),
                                &pse);
        } /* while(readdir) */
        closedir (proc);