Merge branch 'collectd-5.7' into collectd-5.8
[collectd.git] / src / processes.c
index 2f1980b..f556912 100644 (file)
@@ -33,6 +33,7 @@
  *   ClĂ©ment Stenac <clement.stenac at diwi.org>
  *   Cosmin Ioiart <cioiart at gmail.com>
  *   Pavel Rochnyack <pavel2000 at ngs.ru>
+ *   Wilfried Goesgens <dothebart at citadel.org>
  **/
 
 #include "collectd.h"
@@ -168,6 +169,7 @@ typedef struct process_entry_s {
   unsigned long num_proc;
   unsigned long num_lwp;
   unsigned long num_fd;
+  unsigned long num_maps;
   unsigned long vmem_size;
   unsigned long vmem_rss;
   unsigned long vmem_data;
@@ -194,6 +196,8 @@ typedef struct process_entry_s {
   _Bool has_cswitch;
 
   _Bool has_fd;
+
+  _Bool has_maps;
 } process_entry_t;
 
 typedef struct procstat_entry_s {
@@ -229,6 +233,7 @@ typedef struct procstat {
   unsigned long num_proc;
   unsigned long num_lwp;
   unsigned long num_fd;
+  unsigned long num_maps;
   unsigned long vmem_size;
   unsigned long vmem_rss;
   unsigned long vmem_data;
@@ -253,6 +258,7 @@ typedef struct procstat {
   derive_t cswitch_invol;
 
   _Bool report_fd_num;
+  _Bool report_maps_num;
   _Bool report_ctx_switch;
 
   struct procstat *next;
@@ -264,6 +270,7 @@ static procstat_t *list_head_g = NULL;
 static _Bool want_init = 1;
 static _Bool report_ctx_switch = 0;
 static _Bool report_fd_num = 0;
+static _Bool report_maps_num = 0;
 
 #if HAVE_THREAD_INFO
 static mach_port_t port_host_self;
@@ -308,7 +315,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
   new = calloc(1, sizeof(*new));
   if (new == NULL) {
     ERROR("processes plugin: ps_list_register: calloc failed.");
-    return (NULL);
+    return NULL;
   }
   sstrncpy(new->name, name, sizeof(new->name));
 
@@ -322,6 +329,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
   new->cswitch_invol = -1;
 
   new->report_fd_num = report_fd_num;
+  new->report_maps_num = report_maps_num;
   new->report_ctx_switch = report_ctx_switch;
 
 #if HAVE_REGEX_H
@@ -332,7 +340,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
     if (new->re == NULL) {
       ERROR("processes plugin: ps_list_register: malloc failed.");
       sfree(new);
-      return (NULL);
+      return NULL;
     }
 
     status = regcomp(new->re, regexp, REG_EXTENDED | REG_NOSUB);
@@ -341,7 +349,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
             regexp);
       sfree(new->re);
       sfree(new);
-      return (NULL);
+      return NULL;
     }
   }
 #else
@@ -352,7 +360,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
           "has been disabled at compile time.",
           regexp);
     sfree(new);
-    return (NULL);
+    return NULL;
   }
 #endif
 
@@ -367,7 +375,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
       sfree(new->re);
 #endif
       sfree(new);
-      return (NULL);
+      return NULL;
     }
 
     if (ptr->next == NULL)
@@ -379,7 +387,7 @@ static procstat_t *ps_list_register(const char *name, const char *regexp) {
   else
     ptr->next = new;
 
-  return (new);
+  return new;
 } /* void ps_list_register */
 
 /* try to match name against entry, returns 1 if success */
@@ -401,13 +409,13 @@ static int ps_list_match(const char *name, const char *cmdline,
                      /* pmatch = */ NULL,
                      /* eflags = */ 0);
     if (status == 0)
-      return (1);
+      return 1;
   } else
 #endif
       if (strcmp(ps->name, name) == 0)
-    return (1);
+    return 1;
 
-  return (0);
+  return 0;
 } /* int ps_list_match */
 
 static void ps_update_counter(derive_t *group_counter, derive_t *curr_counter,
@@ -472,6 +480,7 @@ static void ps_list_add(const char *name, const char *cmdline,
     ps->num_proc += entry->num_proc;
     ps->num_lwp += entry->num_lwp;
     ps->num_fd += entry->num_fd;
+    ps->num_maps += entry->num_maps;
     ps->vmem_size += entry->vmem_size;
     ps->vmem_rss += entry->vmem_rss;
     ps->vmem_data += entry->vmem_data;
@@ -493,7 +502,7 @@ static void ps_list_add(const char *name, const char *cmdline,
       ps_update_counter(&ps->io_diskw, &pse->io_diskw, entry->io_diskw);
     }
 
-    if ((entry->cswitch_vol != -1) && (entry->cswitch_vol != -1)) {
+    if ((entry->cswitch_vol != -1) && (entry->cswitch_invol != -1)) {
       ps_update_counter(&ps->cswitch_vol, &pse->cswitch_vol,
                         entry->cswitch_vol);
       ps_update_counter(&ps->cswitch_invol, &pse->cswitch_invol,
@@ -521,6 +530,7 @@ static void ps_list_reset(void) {
     ps->num_proc = 0;
     ps->num_lwp = 0;
     ps->num_fd = 0;
+    ps->num_maps = 0;
     ps->vmem_size = 0;
     ps->vmem_rss = 0;
     ps->vmem_data = 0;
@@ -561,6 +571,8 @@ static void ps_tune_instance(oconfig_item_t *ci, procstat_t *ps) {
       cf_util_get_boolean(c, &ps->report_ctx_switch);
     else if (strcasecmp(c->key, "CollectFileDescriptor") == 0)
       cf_util_get_boolean(c, &ps->report_fd_num);
+    else if (strcasecmp(c->key, "CollectMemoryMaps") == 0)
+      cf_util_get_boolean(c, &ps->report_maps_num);
     else {
       ERROR("processes plugin: Option `%s' not allowed here.", c->key);
     }
@@ -619,6 +631,8 @@ static int ps_config(oconfig_item_t *ci) {
       cf_util_get_boolean(c, &report_ctx_switch);
     } else if (strcasecmp(c->key, "CollectFileDescriptor") == 0) {
       cf_util_get_boolean(c, &report_fd_num);
+    } else if (strcasecmp(c->key, "CollectMemoryMaps") == 0) {
+      cf_util_get_boolean(c, &report_maps_num);
     } else {
       ERROR("processes plugin: The `%s' configuration option is not "
             "understood and will be ignored.",
@@ -627,7 +641,7 @@ static int ps_config(oconfig_item_t *ci) {
     }
   }
 
-  return (0);
+  return 0;
 }
 
 static int ps_init(void) {
@@ -649,7 +663,7 @@ static int ps_init(void) {
     ERROR("host_processor_sets failed: %s\n", mach_error_string(status));
     pset_list = NULL;
     pset_list_len = 0;
-    return (-1);
+    return -1;
   }
 /* #endif HAVE_THREAD_INFO */
 
@@ -668,7 +682,7 @@ static int ps_init(void) {
   pagesize = getpagesize();
 #endif /* HAVE_PROCINFO_H */
 
-  return (0);
+  return 0;
 } /* int ps_init */
 
 /* submit global state (e.g.: qty of zombies, running, etc..) */
@@ -768,6 +782,14 @@ static void ps_submit_proc_list(procstat_t *ps) {
     plugin_dispatch_values(&vl);
   }
 
+  if (ps->num_maps > 0) {
+    sstrncpy(vl.type, "file_handles", sizeof(vl.type));
+    sstrncpy(vl.type_instance, "mapped", sizeof(vl.type_instance));
+    vl.values[0].gauge = ps->num_maps;
+    vl.values_len = 1;
+    plugin_dispatch_values(&vl);
+  }
+
   if ((ps->cswitch_vol != -1) && (ps->cswitch_invol != -1)) {
     sstrncpy(vl.type, "contextswitch", sizeof(vl.type));
     sstrncpy(vl.type_instance, "voluntary", sizeof(vl.type_instance));
@@ -782,20 +804,23 @@ static void ps_submit_proc_list(procstat_t *ps) {
     plugin_dispatch_values(&vl);
   }
 
-  DEBUG("name = %s; num_proc = %lu; num_lwp = %lu; num_fd = %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 "; "
-        "io_rchar = %" PRIi64 "; io_wchar = %" PRIi64 "; "
-        "io_syscr = %" PRIi64 "; io_syscw = %" PRIi64 "; "
-        "io_diskr = %" PRIi64 "; io_diskw = %" PRIi64 "; "
-        "cswitch_vol = %" PRIi64 "; cswitch_invol = %" PRIi64 ";",
-        ps->name, ps->num_proc, ps->num_lwp, ps->num_fd, ps->vmem_size,
-        ps->vmem_rss, ps->vmem_data, ps->vmem_code, ps->vmem_minflt_counter,
-        ps->vmem_majflt_counter, ps->cpu_user_counter, ps->cpu_system_counter,
-        ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw, ps->io_diskr,
-        ps->io_diskw, ps->cswitch_vol, ps->cswitch_invol);
+  DEBUG(
+      "name = %s; num_proc = %lu; num_lwp = %lu; num_fd = %lu; num_maps = %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 "; "
+      "io_rchar = %" PRIi64 "; io_wchar = %" PRIi64 "; "
+      "io_syscr = %" PRIi64 "; io_syscw = %" PRIi64 "; "
+      "io_diskr = %" PRIi64 "; io_diskw = %" PRIi64 "; "
+      "cswitch_vol = %" PRIi64 "; cswitch_invol = %" PRIi64 ";",
+      ps->name, ps->num_proc, ps->num_lwp, ps->num_fd, ps->num_maps,
+      ps->vmem_size, ps->vmem_rss, ps->vmem_data, ps->vmem_code,
+      ps->vmem_minflt_counter, ps->vmem_majflt_counter, ps->cpu_user_counter,
+      ps->cpu_system_counter, ps->io_rchar, ps->io_wchar, ps->io_syscr,
+      ps->io_syscw, ps->io_diskr, ps->io_diskw, ps->cswitch_vol,
+      ps->cswitch_invol);
+
 } /* void ps_submit_proc_list */
 
 #if KERNEL_LINUX || KERNEL_SOLARIS
@@ -827,11 +852,11 @@ static int ps_read_tasks_status(process_entry_t *ps) {
   char *fields[8];
   int numfields;
 
-  ssnprintf(dirname, sizeof(dirname), "/proc/%li/task", ps->id);
+  snprintf(dirname, sizeof(dirname), "/proc/%li/task", ps->id);
 
   if ((dh = opendir(dirname)) == NULL) {
     DEBUG("Failed to open directory `%s'", dirname);
-    return (-1);
+    return -1;
   }
 
   while ((ent = readdir(dh)) != NULL) {
@@ -842,8 +867,12 @@ static int ps_read_tasks_status(process_entry_t *ps) {
 
     tpid = ent->d_name;
 
-    ssnprintf(filename, sizeof(filename), "/proc/%li/task/%s/status", ps->id,
-              tpid);
+    if (snprintf(filename, sizeof(filename), "/proc/%li/task/%s/status", ps->id,
+                 tpid) >= sizeof(filename)) {
+      DEBUG("Filename too long: `%s'", filename);
+      continue;
+    }
+
     if ((fh = fopen(filename, "r")) == NULL) {
       DEBUG("Failed to open file `%s'", filename);
       continue;
@@ -885,7 +914,7 @@ static int ps_read_tasks_status(process_entry_t *ps) {
   ps->cswitch_vol = cswitch_vol;
   ps->cswitch_invol = cswitch_invol;
 
-  return (0);
+  return 0;
 } /* int *ps_read_tasks_status */
 
 /* Read data from /proc/pid/status */
@@ -900,9 +929,9 @@ static int ps_read_status(long pid, process_entry_t *ps) {
   char *fields[8];
   int numfields;
 
-  ssnprintf(filename, sizeof(filename), "/proc/%li/status", pid);
+  snprintf(filename, sizeof(filename), "/proc/%li/status", pid);
   if ((fh = fopen(filename, "r")) == NULL)
-    return (-1);
+    return -1;
 
   while (fgets(buffer, sizeof(buffer), fh) != NULL) {
     unsigned long tmp;
@@ -942,7 +971,7 @@ static int ps_read_status(long pid, process_entry_t *ps) {
   if (threads != 0)
     ps->num_lwp = threads;
 
-  return (0);
+  return 0;
 } /* int *ps_read_status */
 
 static int ps_read_io(process_entry_t *ps) {
@@ -953,10 +982,10 @@ static int ps_read_io(process_entry_t *ps) {
   char *fields[8];
   int numfields;
 
-  ssnprintf(filename, sizeof(filename), "/proc/%li/io", ps->id);
+  snprintf(filename, sizeof(filename), "/proc/%li/io", ps->id);
   if ((fh = fopen(filename, "r")) == NULL) {
     DEBUG("ps_read_io: Failed to open file `%s'", filename);
-    return (-1);
+    return -1;
   }
 
   while (fgets(buffer, sizeof(buffer), fh) != NULL) {
@@ -997,20 +1026,45 @@ static int ps_read_io(process_entry_t *ps) {
     char errbuf[1024];
     WARNING("processes: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
   }
-  return (0);
+  return 0;
 } /* int ps_read_io (...) */
 
+static int ps_count_maps(pid_t pid) {
+  FILE *fh;
+  char buffer[1024];
+  char filename[64];
+  int count = 0;
+
+  snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
+  if ((fh = fopen(filename, "r")) == NULL) {
+    DEBUG("ps_count_maps: Failed to open file `%s'", filename);
+    return -1;
+  }
+
+  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
+    if (strchr(buffer, '\n')) {
+      count++;
+    }
+  } /* while (fgets) */
+
+  if (fclose(fh)) {
+    char errbuf[1024];
+    WARNING("processes: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+  }
+  return count;
+} /* int ps_count_maps (...) */
+
 static int ps_count_fd(int pid) {
   char dirname[64];
   DIR *dh;
   struct dirent *ent;
   int count = 0;
 
-  ssnprintf(dirname, sizeof(dirname), "/proc/%i/fd", pid);
+  snprintf(dirname, sizeof(dirname), "/proc/%i/fd", pid);
 
   if ((dh = opendir(dirname)) == NULL) {
     DEBUG("Failed to open directory `%s'", dirname);
-    return (-1);
+    return -1;
   }
   while ((ent = readdir(dh)) != NULL) {
     if (!isdigit((int)ent->d_name[0]))
@@ -1020,7 +1074,7 @@ static int ps_count_fd(int pid) {
   }
   closedir(dh);
 
-  return ((count >= 1) ? count : 1);
+  return (count >= 1) ? count : 1;
 } /* int ps_count_fd (pid) */
 
 static void ps_fill_details(const procstat_t *ps, process_entry_t *entry) {
@@ -1036,6 +1090,14 @@ static void ps_fill_details(const procstat_t *ps, process_entry_t *entry) {
     }
   }
 
+  if (ps->report_maps_num) {
+    int num_maps;
+    if (entry->has_maps == 0 && (num_maps = ps_count_maps(entry->id)) > 0) {
+      entry->num_maps = num_maps;
+    }
+    entry->has_maps = 1;
+  }
+
   if (ps->report_fd_num) {
     int num_fd;
     if (entry->has_fd == 0 && (num_fd = ps_count_fd(entry->id)) > 0) {
@@ -1067,11 +1129,11 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
 
   ssize_t status;
 
-  ssnprintf(filename, sizeof(filename), "/proc/%li/stat", pid);
+  snprintf(filename, sizeof(filename), "/proc/%li/stat", pid);
 
   status = read_file_contents(filename, buffer, sizeof(buffer) - 1);
   if (status <= 0)
-    return (-1);
+    return -1;
   buffer_len = (size_t)status;
   buffer[buffer_len] = 0;
 
@@ -1093,7 +1155,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
   if (name_start_pos >= name_end_pos) {
     ERROR("processes plugin: name_start_pos = %zu >= name_end_pos = %zu",
           name_start_pos, name_end_pos);
-    return (-1);
+    return -1;
   }
 
   name_len = (name_end_pos - name_start_pos) - 1;
@@ -1103,7 +1165,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
   sstrncpy(ps->name, &buffer[name_start_pos + 1], name_len + 1);
 
   if ((buffer_len - name_end_pos) < 2)
-    return (-1);
+    return -1;
   buffer_ptr = &buffer[name_end_pos + 2];
 
   fields_len = strsplit(buffer_ptr, fields, STATIC_ARRAY_SIZE(fields));
@@ -1111,7 +1173,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
     DEBUG("processes plugin: ps_read_process (pid = %li):"
           " `%s' has only %i fields..",
           pid, filename, fields_len);
-    return (-1);
+    return -1;
   }
 
   *state = fields[0][0];
@@ -1137,7 +1199,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
     DEBUG("processes plugin: This is only a zombie: pid = %li; "
           "name = %s;",
           pid, ps->name);
-    return (0);
+    return 0;
   }
 
   cpu_user_counter = atoll(fields[11]);
@@ -1178,7 +1240,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
   ps->cswitch_invol = -1;
 
   /* success */
-  return (0);
+  return 0;
 } /* int ps_read_process (...) */
 
 static char *ps_get_cmdline(long pid, char *name, char *buf, size_t buf_len) {
@@ -1193,7 +1255,7 @@ static char *ps_get_cmdline(long pid, char *name, char *buf, size_t buf_len) {
   if ((pid < 1) || (NULL == buf) || (buf_len < 2))
     return NULL;
 
-  ssnprintf(file, sizeof(file), "/proc/%li/cmdline", pid);
+  snprintf(file, sizeof(file), "/proc/%li/cmdline", pid);
 
   errno = 0;
   fd = open(file, O_RDONLY);
@@ -1248,7 +1310,7 @@ static char *ps_get_cmdline(long pid, char *name, char *buf, size_t buf_len) {
     if (NULL == name)
       return NULL;
 
-    ssnprintf(buf, buf_len, "[%s]", name);
+    snprintf(buf, buf_len, "[%s]", name);
     return buf;
   }
 
@@ -1285,7 +1347,7 @@ static int read_fork_rate(void) {
     char errbuf[1024];
     ERROR("processes plugin: fopen (/proc/stat) failed: %s",
           sstrerror(errno, errbuf, sizeof(errbuf)));
-    return (-1);
+    return -1;
   }
 
   while (fgets(buffer, sizeof(buffer), proc_stat) != NULL) {
@@ -1309,10 +1371,10 @@ static int read_fork_rate(void) {
   fclose(proc_stat);
 
   if (!value_valid)
-    return (-1);
+    return -1;
 
   ps_submit_fork_rate(value.derive);
-  return (0);
+  return 0;
 }
 #endif /*KERNEL_LINUX */
 
@@ -1332,13 +1394,13 @@ static char *ps_get_cmdline(long pid,
           "while reading \"%s\": "
           "Returned %zd but expected %zu.",
           path, status, buffer_size);
-    return (NULL);
+    return NULL;
   }
 
   info.pr_psargs[sizeof(info.pr_psargs) - 1] = 0;
   sstrncpy(buffer, info.pr_psargs, buffer_size);
 
-  return (buffer);
+  return buffer;
 } /* }}} int ps_get_cmdline */
 
 /*
@@ -1383,7 +1445,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
     sfree(myStatus);
     sfree(myInfo);
     sfree(myUsage);
-    return (0);
+    return 0;
   } else {
     ps->num_proc = 1;
     ps->num_lwp = myInfo->pr_nlwp;
@@ -1417,6 +1479,9 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
    */
   ps->num_fd = 0;
 
+  /* Number of memory mappings */
+  ps->num_maps = 0;
+
   /*
    * Calculating input/ouput chars
    * Formula used is total chars / total blocks => chars/block
@@ -1462,7 +1527,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {
   sfree(myInfo);
   sfree(myUsage);
 
-  return (0);
+  return 0;
 }
 
 /*
@@ -1475,7 +1540,7 @@ static int read_fork_rate(void) {
   derive_t result = 0;
 
   if (kc == NULL)
-    return (-1);
+    return -1;
 
   for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL;
        ksp_chain = ksp_chain->ks_next) {
@@ -1493,7 +1558,7 @@ static int read_fork_rate(void) {
   }
 
   ps_submit_fork_rate(result);
-  return (0);
+  return 0;
 }
 #endif /* KERNEL_SOLARIS */
 
@@ -1510,12 +1575,12 @@ static int mach_get_task_name(task_t t, int *pid, char *name,
   mib[2] = KERN_PROC_PID;
 
   if (pid_for_task(t, pid) != KERN_SUCCESS)
-    return (-1);
+    return -1;
   mib[3] = *pid;
 
   kp_size = sizeof(kp);
   if (sysctl(mib, 4, &kp, &kp_size, NULL, 0) != 0)
-    return (-1);
+    return -1;
 
   if (name_max_len > (MAXCOMLEN + 1))
     name_max_len = MAXCOMLEN + 1;
@@ -1529,7 +1594,7 @@ static int mach_get_task_name(task_t t, int *pid, char *name,
    * `top' does it, because it is a lot of work and only used when
    * debugging. -octo */
 
-  return (0);
+  return 0;
 }
 #endif /* HAVE_THREAD_INFO */
 /* ------- end of additional functions for KERNEL_LINUX/HAVE_THREAD_INFO -------
@@ -1652,6 +1717,9 @@ static int ps_read(void) {
         /* File descriptor count not implemented */
         pse.num_fd = 0;
 
+        /* Number of memory mappings */
+        pse.num_maps = 0;
+
         pse.vmem_minflt_counter = task_events_info.cow_faults;
         pse.vmem_majflt_counter = task_events_info.faults;
 
@@ -1792,7 +1860,7 @@ static int ps_read(void) {
   if ((proc = opendir("/proc")) == NULL) {
     char errbuf[1024];
     ERROR("Cannot open `/proc': %s", sstrerror(errno, errbuf, sizeof(errbuf)));
-    return (-1);
+    return -1;
   }
 
   while ((ent = readdir(proc)) != NULL) {
@@ -1874,7 +1942,7 @@ static int ps_read(void) {
   kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, errbuf);
   if (kd == NULL) {
     ERROR("processes plugin: Cannot open kvm interface: %s", errbuf);
-    return (0);
+    return 0;
   }
 
   /* Get the list of processes. */
@@ -1883,7 +1951,7 @@ static int ps_read(void) {
     ERROR("processes plugin: Cannot get kvm processes list: %s",
           kvm_geterr(kd));
     kvm_close(kd);
-    return (0);
+    return 0;
   }
 
   /* Iterate through the processes in kinfo_proc */
@@ -1957,6 +2025,9 @@ static int ps_read(void) {
       /* file descriptor count not implemented */
       pse.num_fd = 0;
 
+      /* Number of memory mappings */
+      pse.num_maps = 0;
+
       /* context switch counters not implemented */
       pse.cswitch_vol = -1;
       pse.cswitch_invol = -1;
@@ -2026,7 +2097,7 @@ static int ps_read(void) {
   kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
   if (kd == NULL) {
     ERROR("processes plugin: Cannot open kvm interface: %s", errbuf);
-    return (0);
+    return 0;
   }
 
   /* Get the list of processes. */
@@ -2035,7 +2106,7 @@ static int ps_read(void) {
     ERROR("processes plugin: Cannot get kvm processes list: %s",
           kvm_geterr(kd));
     kvm_close(kd);
-    return (0);
+    return 0;
   }
 
   /* Iterate through the processes in kinfo_proc */
@@ -2098,6 +2169,9 @@ static int ps_read(void) {
       /* file descriptor count not implemented */
       pse.num_fd = 0;
 
+      /* Number of memory mappings */
+      pse.num_maps = 0;
+
       /* context switch counters not implemented */
       pse.cswitch_vol = -1;
       pse.cswitch_invol = -1;
@@ -2261,6 +2335,7 @@ static int ps_read(void) {
       pse.io_diskw = -1;
 
       pse.num_fd = 0;
+      pse.num_maps = 0;
 
       pse.cswitch_vol = -1;
       pse.cswitch_invol = -1;
@@ -2310,7 +2385,7 @@ static int ps_read(void) {
 
   proc = opendir("/proc");
   if (proc == NULL)
-    return (-1);
+    return -1;
 
   while ((ent = readdir(proc)) != NULL) {
     long pid;
@@ -2382,7 +2457,7 @@ static int ps_read(void) {
 
   want_init = 0;
 
-  return (0);
+  return 0;
 } /* int ps_read */
 
 void module_register(void) {