Merge branch 'collectd-5.4' into collectd-5.5
[collectd.git] / src / utils_mount.c
index ed3feca..da53b98 100644 (file)
  * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public Licence for more details.
  *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Author:
  *   Niki W. Waibel <niki.waibel@gmx.net>
 **/
 
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
 
-
-#include "common.h"
 #if HAVE_XFS_XQM_H
+# define _GNU_SOURCE
 # include <xfs/xqm.h>
 #define XFS_SUPER_MAGIC_STR "XFSB"
 #define XFS_SUPER_MAGIC2_STR "BSFX"
 #endif
 
-#include "utils_debug.h"
+#include "collectd.h"
 #include "utils_mount.h"
 
-#if HAVE_GETFSSTAT
+#include "common.h" /* sstrncpy() et alii */
+#include "plugin.h" /* ERROR() macro */
+
+
+#if HAVE_GETVFSSTAT
+#  if HAVE_SYS_TYPES_H
+#    include <sys/types.h>
+#  endif
+#  if HAVE_SYS_STATVFS_H
+#    include <sys/statvfs.h>
+#  endif
+/* #endif HAVE_GETVFSSTAT */
+
+#elif HAVE_GETFSSTAT
 #  if HAVE_SYS_PARAM_H
 #    include <sys/param.h>
 #  endif
 #  if HAVE_SYS_MOUNT_H
 #    include <sys/mount.h>
 #  endif
-/* #endif HAVE_GETFSSTAT */
-#elif HAVE_GETVFSSTAT
-#  if HAVE_SYS_TYPES_H
-#    include <sys/types.h>
-#  endif
-#  if HAVE_SYS_STATVFS_H
-#    include <sys/statvfs.h>
-#  endif
-#endif /* HAVE_GETVFSSTAT */
+#endif /* HAVE_GETFSSTAT */
 
 #if HAVE_MNTENT_H
 #  include <mntent.h>
@@ -257,7 +263,7 @@ uuidcache_init(void)
                        * (This is useful, if the cdrom on /dev/hdc must not
                        * be accessed.)
                        */
-                               snprintf(device, sizeof(device), "%s/%s",
+                               ssnprintf(device, sizeof(device), "%s/%s",
                                        DEVLABELDIR, ptname);
                                if(!get_label_uuid(device, &label, uuid)) {
                                        uuidcache_addentry(sstrdup(device),
@@ -331,7 +337,7 @@ get_spec_by_uuid(const char *s)
        return get_spec_by_x(UUID, uuid);
 
        bad_uuid:
-               DBG("Found an invalid UUID: %s", s);
+               DEBUG("utils_mount: Found an invalid UUID: %s", s);
        return NULL;
 }
 
@@ -350,12 +356,12 @@ static char *get_device_name(const char *optstr)
        }
        else if (strncmp (optstr, "UUID=", 5) == 0)
        {
-               DBG ("TODO: check UUID= code!");
+               DEBUG ("utils_mount: TODO: check UUID= code!");
                rc = get_spec_by_uuid (optstr + 5);
        }
        else if (strncmp (optstr, "LABEL=", 6) == 0)
        {
-               DBG ("TODO: check LABEL= code!");
+               DEBUG ("utils_mount: TODO: check LABEL= code!");
                rc = get_spec_by_volume_label (optstr + 6);
        }
        else
@@ -365,7 +371,7 @@ static char *get_device_name(const char *optstr)
 
        if(!rc)
        {
-               DBG ("Error checking device name: optstr = %s", optstr);
+               DEBUG ("utils_mount: Error checking device name: optstr = %s", optstr);
        }
        return rc;
 }
@@ -380,7 +386,11 @@ static cu_mount_t *cu_mount_listmntent (void)
 
        struct tabmntent *mntlist;
        if(listmntent(&mntlist, COLLECTD_MNTTAB, NULL, NULL) < 0) {
-               DBG("calling listmntent() failed: %s", strerror(errno));
+#if COLLECT_DEBUG
+               char errbuf[1024];
+               DEBUG("utils_mount: calling listmntent() failed: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+#endif /* COLLECT_DEBUG */
        }
 
        for(p = mntlist; p; p = p->next) {
@@ -391,7 +401,7 @@ static cu_mount_t *cu_mount_listmntent (void)
                if(loop == NULL) {   /* no loop= mount */
                        device = get_device_name(mnt->mnt_fsname);
                        if(device == NULL) {
-                               DBG("can't get devicename for fs (%s) %s (%s)"
+                               DEBUG("utils_mount: can't get devicename for fs (%s) %s (%s)"
                                        ": ignored", mnt->mnt_type,
                                        mnt->mnt_dir, mnt->mnt_fsname);
                                continue;
@@ -422,7 +432,7 @@ static cu_mount_t *cu_mount_listmntent (void)
 /* #endif HAVE_LISTMNTENT */
 
 /* 4.4BSD and Mac OS X (getfsstat) or NetBSD (getvfsstat) */
-#elif HAVE_GETFSSTAT || HAVE_GETVFSSTAT
+#elif HAVE_GETVFSSTAT || HAVE_GETFSSTAT
 static cu_mount_t *cu_mount_getfsstat (void)
 {
 #if HAVE_GETFSSTAT
@@ -449,7 +459,11 @@ static cu_mount_t *cu_mount_getfsstat (void)
        /* Get the number of mounted file systems */
        if ((bufsize = CMD_STATFS (NULL, 0, FLAGS_STATFS)) < 1)
        {
-               DBG (CMD_STATFS" failed: %s", strerror (errno));
+#if COLLECT_DEBUG
+               char errbuf[1024];
+               DEBUG ("utils_mount: getv?fsstat failed: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+#endif /* COLLECT_DEBUG */
                return (NULL);
        }
 
@@ -462,7 +476,11 @@ static cu_mount_t *cu_mount_getfsstat (void)
         * manpage.. -octo */
        if ((num = CMD_STATFS (buf, bufsize * sizeof (STRUCT_STATFS), FLAGS_STATFS)) < 1)
        {
-               DBG (CMD_STATFS" failed: %s", strerror (errno));
+#if COLLECT_DEBUG
+               char errbuf[1024];
+               DEBUG ("utils_mount: getv?fsstat failed: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+#endif /* COLLECT_DEBUG */
                free (buf);
                return (NULL);
        }
@@ -498,10 +516,10 @@ static cu_mount_t *cu_mount_getfsstat (void)
 
        return (first);
 }
-/* #endif HAVE_GETFSSTAT */
+/* #endif HAVE_GETVFSSTAT || HAVE_GETFSSTAT */
 
 /* Solaris (SunOS 10): int getmntent(FILE *fp, struct mnttab *mp); */
-#elif HAVE_GEN_GETMNTENT
+#elif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT
 static cu_mount_t *cu_mount_gen_getmntent (void)
 {
        struct mnttab mt;
@@ -511,11 +529,13 @@ static cu_mount_t *cu_mount_gen_getmntent (void)
        cu_mount_t *last  = NULL;
        cu_mount_t *new   = NULL;
 
-       DBG ("(void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
+       DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
 
        if ((fp = fopen (COLLECTD_MNTTAB, "r")) == NULL)
        {
-               syslog (LOG_ERR, "fopen (%s): %s", COLLECTD_MNTTAB, strerror (errno));
+               char errbuf[1024];
+               ERROR ("fopen (%s): %s", COLLECTD_MNTTAB,
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
                return (NULL);
        }
 
@@ -550,17 +570,71 @@ static cu_mount_t *cu_mount_gen_getmntent (void)
 
        return (first);
 } /* static cu_mount_t *cu_mount_gen_getmntent (void) */
-/* #endif HAVE_GEN_GETMNTENT */
+/* #endif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT */
 
 #elif HAVE_SEQ_GETMNTENT
 #warn "This version of `getmntent' hat not yet been implemented!"
 /* #endif HAVE_SEQ_GETMNTENT */
 
-#elif HAVE_SUN_GETMNTENT
-#warn "This version of `getmntent' hat not yet been implemented!"
-/* #endif HAVE_SUN_GETMNTENT */
+#elif HAVE_GETMNTENT_R
+static cu_mount_t *cu_mount_getmntent (void)
+{
+       FILE *fp;
+       struct mntent me;
+       char mntbuf[1024];
+
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+       cu_mount_t *new   = NULL;
+
+       DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
+
+       if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL)
+       {
+               char errbuf[1024];
+               ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB,
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (NULL);
+       }
+
+       while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) ))
+       {
+               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+                       break;
+               memset (new, '\0', sizeof (cu_mount_t));
+
+               /* Copy values from `struct mntent *' */
+               new->dir         = sstrdup (me.mnt_dir);
+               new->spec_device = sstrdup (me.mnt_fsname);
+               new->type        = sstrdup (me.mnt_type);
+               new->options     = sstrdup (me.mnt_opts);
+               new->device      = get_device_name (new->options);
+               new->next        = NULL;
+
+               DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
+                               new->dir, new->spec_device, new->type, new->options, new->device);
+
+               /* Append to list */
+               if (first == NULL)
+               {
+                       first = new;
+                       last  = new;
+               }
+               else
+               {
+                       last->next = new;
+                       last       = new;
+               }
+       }
+
+       endmntent (fp);
+
+       DEBUG ("utils_mount: return (0x%p)", (void *) first);
 
-#elif HAVE_GETMNTENT
+       return (first);
+} /* HAVE_GETMNTENT_R */
+
+#elif HAVE_ONE_GETMNTENT
 static cu_mount_t *cu_mount_getmntent (void)
 {
        FILE *fp;
@@ -570,11 +644,13 @@ static cu_mount_t *cu_mount_getmntent (void)
        cu_mount_t *last  = NULL;
        cu_mount_t *new   = NULL;
 
-       DBG ("(void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
+       DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
 
        if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL)
        {
-               syslog (LOG_ERR, "setmntent (%s): %s", COLLECTD_MNTTAB, strerror (errno));
+               char errbuf[1024];
+               ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB,
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
                return (NULL);
        }
 
@@ -592,7 +668,7 @@ static cu_mount_t *cu_mount_getmntent (void)
                new->device      = get_device_name (new->options);
                new->next        = NULL;
 
-               DBG ("new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
+               DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
                                new->dir, new->spec_device, new->type, new->options, new->device);
 
                /* Append to list */
@@ -610,11 +686,11 @@ static cu_mount_t *cu_mount_getmntent (void)
 
        endmntent (fp);
 
-       DBG ("return (0x%p)", (void *) first);
+       DEBUG ("utils_mount: return (0x%p)", (void *) first);
 
        return (first);
 }
-#endif /* HAVE_GETMNTENT */
+#endif /* HAVE_ONE_GETMNTENT */
 
 /* *** *** *** ******************************************** *** *** *** */
 /* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
@@ -639,14 +715,16 @@ cu_mount_t *cu_mount_getlist(cu_mount_t **list)
 
 #if HAVE_LISTMNTENT && 0
        new = cu_mount_listmntent ();
-#elif HAVE_GETFSSTAT
+#elif HAVE_GETVFSSTAT || HAVE_GETFSSTAT
        new = cu_mount_getfsstat ();
-#elif HAVE_GEN_GETMNTENT
+#elif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT
        new = cu_mount_gen_getmntent ();
-#elif HAVE_GETMNTENT
+#elif HAVE_SEQ_GETMNTENT
+# error "This version of `getmntent' hat not yet been implemented!"
+#elif HAVE_ONE_GETMNTENT
        new = cu_mount_getmntent ();
 #else
-       new = NULL;
+# error "Could not determine how to find mountpoints."
 #endif
 
        if (first != NULL)
@@ -671,8 +749,6 @@ void cu_mount_freelist (cu_mount_t *list)
        cu_mount_t *this;
        cu_mount_t *next;
 
-       DBG ("(list = 0x%p)", (void *) list);
-
        for (this = list; this != NULL; this = next)
        {
                next = this->next;
@@ -689,13 +765,13 @@ void cu_mount_freelist (cu_mount_t *list)
 char *
 cu_mount_checkoption(char *line, char *keyword, int full)
 {
-       char *line2, *l2;
-       int l = strlen(keyword);
-       char *p1, *p2;
+       char *line2, *l2, *p1, *p2;
+       int l;
 
        if(line == NULL || keyword == NULL) {
                return NULL;
        }
+
        if(full != 0) {
                full = 1;
        }
@@ -709,6 +785,7 @@ cu_mount_checkoption(char *line, char *keyword, int full)
                l2++;
        }
 
+       l = strlen(keyword);
        p1 = line - 1;
        p2 = strchr(line, ',');
        do {
@@ -737,9 +814,6 @@ cu_mount_getoptionvalue(char *line, char *keyword)
                r += strlen(keyword);
                p = strchr(r, ',');
                if(p == NULL) {
-                       if(strlen(r) == 0) {
-                               return NULL;
-                       }
                        return sstrdup(r);
                } else {
                        char *m;
@@ -754,8 +828,6 @@ cu_mount_getoptionvalue(char *line, char *keyword)
        return r;
 } /* char *cu_mount_getoptionvalue(char *line, char *keyword) */
 
-
-
 int
 cu_mount_type(const char *type)
 {
@@ -767,5 +839,3 @@ cu_mount_type(const char *type)
        return CUMT_UNKNOWN;
 } /* int cu_mount_type(const char *type) */
 
-
-