summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6fd90ba)
raw | patch | inline | side by side (parent: 6fd90ba)
author | niki <niki> | |
Mon, 12 Dec 2005 06:45:38 +0000 (06:45 +0000) | ||
committer | niki <niki> | |
Mon, 12 Dec 2005 06:45:38 +0000 (06:45 +0000) |
16 files changed:
clean.sh | [new file with mode: 0755] | patch | blob |
configure.in | patch | blob | history | |
contrib/users | [changed mode: 0644->0755] | patch | blob | history |
src/Makefile.am | patch | blob | history | |
src/collectd.h | patch | blob | history | |
src/plugin.c | patch | blob | history | |
src/processes.c | [new file with mode: 0644] | patch | blob |
src/quota_fs.c | patch | blob | history | |
src/quota_fs.h | patch | blob | history | |
src/quota_mnt.c | patch | blob | history | |
src/quota_mnt.h | patch | blob | history | |
src/users.h | patch | blob | history | |
src/utils_debug.c | patch | blob | history | |
src/utils_debug.h | patch | blob | history | |
src/utils_mount.c | patch | blob | history | |
src/utils_mount.h | patch | blob | history |
diff --git a/clean.sh b/clean.sh
--- /dev/null
+++ b/clean.sh
@@ -0,0 +1,46 @@
+#! /bin/sh
+
+set -x
+
+true \
+&& rm -f aclocal.m4 \
+&& rm -f -r autom4te.cache \
+&& rm -f collectd-*.tar.bz2 \
+&& rm -f collectd-*.tar.gz \
+&& rm -f compile \
+&& rm -f config.guess \
+&& rm -f config.log \
+&& rm -f config.status \
+&& rm -f config.sub \
+&& rm -f configure \
+&& rm -f depcomp \
+&& rm -f install-sh \
+&& rm -f -r libltdl \
+&& rm -f libtool \
+&& rm -f ltmain.sh \
+&& rm -f Makefile \
+&& rm -f Makefile.in \
+&& rm -f missing \
+&& rm -f -r src/.deps \
+&& rm -f -r src/.libs \
+&& rm -f src/*.o \
+&& rm -f src/*.la \
+&& rm -f src/*.lo \
+&& rm -f src/collectd \
+&& rm -f src/collectd.1 \
+&& rm -f src/config.h \
+&& rm -f src/config.h.in \
+&& rm -f src/config.h.in~ \
+&& rm -f src/Makefile \
+&& rm -f src/Makefile.in \
+&& rm -f src/stamp-h1 \
+&& rm -f src/stamp-h1.in \
+&& rm -f -r src/libping/.libs \
+&& rm -f src/libping/*.o \
+&& rm -f src/libping/*.la \
+&& rm -f src/libping/*.lo \
+&& rm -f src/libping/config.h \
+&& rm -f src/libping/config.h.in \
+&& rm -f src/libping/Makefile \
+&& rm -f src/libping/Makefile.in \
+&& rm -f src/libping/stamp-h2
diff --git a/configure.in b/configure.in
index 33d0383c750cfc2490778503a3d9c900c49a4022..5f7453a8df4dfe905353451c7f125bb8d0f768a0 100644 (file)
--- a/configure.in
+++ b/configure.in
dnl Process this file with autoconf to produce a configure script.
AC_INIT(collectd, 3.5.alpha1-quota)
AC_CONFIG_SRCDIR(src/collectd.c)
-AC_CONFIG_HEADERS(src/config.h src/libping/config.h)
+AC_CONFIG_HEADERS(src/config.h)
AM_INIT_AUTOMAKE(dist-bzip2)
AC_LANG(C)
# Checks for header files.
#
AC_HEADER_SYS_WAIT
+AC_HEADER_DIRENT
AC_CHECK_HEADERS(fcntl.h)
AC_CHECK_HEADERS(signal.h)
AC_CHECK_HEADERS(sys/socket.h)
AC_CHECK_HEADERS(utmpx.h)
# For quota module
-AC_CHECK_HEADERS(grp.h pwd.h)
+AC_CHECK_HEADERS(grp.h pwd.h sys/ucred.h)
AC_CHECK_HEADERS(ctype.h)
AC_CHECK_HEADERS(limits.h)
AC_CHECK_HEADERS(sys/quota.h)
AC_CHECK_HEADERS(xfs/xqm.h)
# For mount interface
+AC_CHECK_HEADERS(fs_info.h)
+AC_CHECK_HEADERS(fshelp.h)
AC_CHECK_HEADERS(paths.h)
AC_CHECK_HEADERS(mntent.h)
+AC_CHECK_HEADERS(mnttab.h)
+AC_CHECK_HEADERS(sys/fstyp.h)
AC_CHECK_HEADERS(sys/fs_types.h)
AC_CHECK_HEADERS(sys/mntent.h)
AC_CHECK_HEADERS(sys/mnttab.h)
AC_CHECK_HEADERS(sys/mount.h)
+AC_CHECK_HEADERS(sys/statfs.h)
AC_CHECK_HEADERS(sys/vfs.h)
AC_CHECK_HEADERS(sys/vfstab.h)
diff --git a/contrib/users b/contrib/users
old mode 100644 (file)
new mode 100755 (executable)
new mode 100755 (executable)
diff --git a/src/Makefile.am b/src/Makefile.am
index cab72652697fbb350ecc8d8a5f6bd2f56331c085..fe1076b7fbddcd59266382bce86d35a13e90a14b 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
if BUILD_MODULE_PING
-SUBDIRS = libping
+SUBDIRS = libping .
endif
sbin_PROGRAMS = collectd
diff --git a/src/collectd.h b/src/collectd.h
index a66647a98e187b3206ef7f6243a2e98c1b64ba0e..1614483a28bcd350002879a33322ffad7ea039b5 100644 (file)
--- a/src/collectd.h
+++ b/src/collectd.h
#define COLLECTD_H
#if HAVE_CONFIG_H
-# include "config.h"
+# include <config.h>
#endif
-#if HAVE_STDARG_H
-# include <stdarg.h>
-#endif
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
# include <time.h>
# endif
#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#if HAVE_STDARG_H
+# include <stdarg.h>
+#endif
#if HAVE_CTYPE_H
# include <ctype.h>
#endif
diff --git a/src/plugin.c b/src/plugin.c
index 1a3ab348a9be1bdfe9329618a54ccfb7da9222f0..20735ba4c5b4df999ef151b5b5ab21c0d52ddccd 100644 (file)
--- a/src/plugin.c
+++ b/src/plugin.c
#include "collectd.h"
#include <ltdl.h>
-#include <dirent.h>
#include "plugin.h"
#include "multicast.h"
diff --git a/src/processes.c b/src/processes.c
--- /dev/null
+++ b/src/processes.c
@@ -0,0 +1,129 @@
+#include "processes.h"
+
+/*
+ * Originally written by Lyonel Vincent
+ */
+
+#if COLLECT_PROCESSES
+#define MODULE_NAME "processes"
+
+#include "common.h"
+#include "plugin.h"
+
+static char *ps_file = "processes.rrd";
+
+static char *ds_def[] =
+{
+ "DS:running:GAUGE:25:0:65535",
+ "DS:sleeping:GAUGE:25:0:65535",
+ "DS:zombies:GAUGE:25:0:65535",
+ "DS:stopped:GAUGE:25:0:65535",
+ "DS:paging:GAUGE:25:0:65535",
+ "DS:blocked:GAUGE:25:0:65535",
+ NULL
+};
+static int ds_num = 6;
+
+extern time_t curtime;
+
+void ps_init (void)
+{
+}
+
+void ps_write (char *host, char *inst, char *val)
+{
+ rrd_update_file (host, ps_file, val, ds_def, ds_num);
+}
+
+#define BUFSIZE 256
+void ps_submit (unsigned int running,
+ unsigned int sleeping,
+ unsigned int zombies,
+ unsigned int stopped,
+ unsigned int paging,
+ unsigned int blocked)
+{
+ char buf[BUFSIZE];
+
+ if (snprintf (buf, BUFSIZE, "%u:%u:%u:%u:%u:%u:%u",
+ (unsigned int) curtime,
+ running, sleeping, zombies, stopped, paging,
+ blocked) >= BUFSIZE)
+ return;
+
+ plugin_submit (MODULE_NAME, "-", buf);
+}
+
+void ps_read (void)
+{
+#ifdef KERNEL_LINUX
+ unsigned int running, sleeping, zombies, stopped, paging, blocked;
+
+ char buf[BUFSIZE];
+ char filename[20]; /* need 17 bytes */
+ char *fields[256];
+
+ struct dirent *ent;
+ DIR *proc;
+ FILE *fh;
+
+ running = sleeping = zombies = stopped = paging = blocked = 0;
+
+ if ((proc = opendir ("/proc")) == NULL)
+ {
+ syslog (LOG_ERR, "Cannot open `/proc': %s", strerror (errno));
+ return;
+ }
+
+ int strsplit (char *string, char **fields, size_t size);
+
+ while ((ent = readdir (proc)) != NULL)
+ {
+ if (!isdigit (ent->d_name[0]))
+ continue;
+
+ if (snprintf (filename, 20, "/proc/%s/stat", ent->d_name) >= 20)
+ continue;
+
+ if ((fh = fopen (filename, "r")) == NULL)
+ {
+ syslog (LOG_ERR, "Cannot open `%s': %s", filename, strerror (errno));
+ continue;
+ }
+
+ if (fgets (buf, BUFSIZE, fh) == NULL)
+ {
+ fclose (fh);
+ continue;
+ }
+
+ fclose (fh);
+
+ if (strsplit (buf, fields, 256) < 3)
+ continue;
+
+ switch (fields[2][0])
+ {
+ case 'R': running++; break;
+ case 'S': sleeping++; break;
+ case 'D': blocked++; break;
+ case 'Z': zombies++; break;
+ case 'T': stopped++; break;
+ case 'W': paging++; break;
+ }
+ }
+
+ closedir(proc);
+
+ ps_submit (running, sleeping, zombies, stopped, paging, blocked);
+#endif /* defined(KERNEL_LINUX) */
+}
+#undef BUFSIZE
+
+void module_register (void)
+{
+ plugin_register (MODULE_NAME, ps_init, ps_read, ps_write);
+}
+
+#undef MODULE_NAME
+#endif /* COLLECT_PROCESSES */
diff --git a/src/quota_fs.c b/src/quota_fs.c
index 57044e8d88b93483f6947b85137a5c581b043702..2e58e8c963c1650a256e1fbd22b92b9dc53f40d7 100644 (file)
--- a/src/quota_fs.c
+++ b/src/quota_fs.c
#include "common.h"
#include "utils_debug.h"
+#include "utils_mount.h"
#include "quota_mnt.h"
#include "quota_fs.h"
#if HAVE_GRP_H
# include <grp.h>
#endif
+#if HAVE_SYS_UCRED_H
+# include <sys/ucred.h>
+#endif
#if HAVE_SYS_QUOTA_H
# include <sys/quota.h>
#endif
{
return EXIT_SUCCESS;
} else {
-#if 0
- DBG("%s filesystem not supported", fsname);
-#endif
return EXIT_FAILURE;
}
} /* int quota_fs_issupported(const char *fsname) */
quota_t *q = NULL, *qlast = NULL;
while(m != NULL) {
- switch(quota_mnt_type(m->m->type)) {
+ switch(cu_mount_type(m->m->type)) {
case QMT_EXT2:
case QMT_EXT3:
qlast = getquota_ext3(&q, m);
diff --git a/src/quota_fs.h b/src/quota_fs.h
index 3404dfe41f730444d90117eabec75b56206466e5..9236339585d80644115e3bcad65b4cfdfd32b09d 100644 (file)
--- a/src/quota_fs.h
+++ b/src/quota_fs.h
int quota_fs_issupported(const char *fsname);
int quota_fs_isnfs(const char *fsname);
+void quota_fs_printquota_dbg(quota_t *quota);
/*
DESCRIPTION
The quota_fs_printquota_dbg() function prints
If debugging is switched off in quota_debug.h
then this function does nothing.
*/
-void quota_fs_printquota_dbg(quota_t *quota);
+quota_t *quota_fs_getquota(quota_t **quota, quota_mnt_t *m);
/*
DESCRIPTION
The quota_fs_getquota() function goes through the mount
NOTES
In case of an error, *quota is not modified.
*/
-quota_t *quota_fs_getquota(quota_t **quota, quota_mnt_t *m);
+void quota_fs_freequota(quota_t *quota);
/*
DESCRIPTION
The quota_fs_freequota() function goes through all entries
and frees all allocated memory of all data and structures
not NULL.
*/
-void quota_fs_freequota(quota_t *quota);
#endif /* !COLLECTD_QUOTA_FS_H */
diff --git a/src/quota_mnt.c b/src/quota_mnt.c
index 1917a59b22980d460993e6255860723d06758ed3..53e1f9911cdb3001e4115be9082ed038f7a1cb87 100644 (file)
--- a/src/quota_mnt.c
+++ b/src/quota_mnt.c
#include "common.h"
#include "utils_debug.h"
+#include "utils_mount.h"
#include "quota_fs.h"
#include "quota_mnt.h"
-
-/* if sthg is changed here also change it in configure.in!!! */
-#if HAVE_MNTENT_H /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
-# include <mntent.h>
-#endif
-#if HAVE_MNTTAB_H /* SVR2, SVR3. */
-# include <mnttab.h>
-#endif
-#if HAVE_PATHS_H
-# include <paths.h>
-#endif
-#if HAVE_SYS_FS_TYPES_H /* Ultrix. */
-# include <sys/fs_types.h>
-#endif
-#if HAVE_SYS_MNTENT_H
-# include <sys/mntent.h>
-#endif
-#if HAVE_SYS_MNTTAB_H /* SVR4. */
-# include <sys/mnttab.h>
-#endif
-#if HAVE_SYS_MOUNT_H /* 4.4BSD, Ultrix. */
-# include <sys/mount.h>
-#endif
-#if HAVE_SYS_VFSTAB_H
-# include <sys/vfstab.h>
-#endif
#if HAVE_SYS_QUOTA_H
# include <sys/quota.h>
#endif
-#if HAVE_SYS_VFS_H
-# include <sys/vfs.h>
-#endif
-/* END if sthg is changed here also change it in configure.in!!! */
-#if HAVE_XFS_XQM_H
-# include <xfs/xqm.h>
-#define xfs_mem_dqinfo fs_quota_stat
-#define Q_XFS_GETQSTAT Q_XGETQSTAT
-#define XFS_SUPER_MAGIC_STR "XFSB"
-#define XFS_SUPER_MAGIC2_STR "BSFX"
-#endif
#endif
+
+static int
+is_relevant(cu_mount_t *m)
+{
+ if(cu_mount_checkoption(m->options, "noquota", 1) != NULL) {
+ return EXIT_FAILURE;
+ }
+ if(quota_fs_issupported(m->type) == EXIT_FAILURE) {
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+} /* static int is_relevant(cu_mount_t *m) */
+
+
+
quota_mnt_t *
quota_mnt_getlist(quota_mnt_t **list)
{
quota_mnt_t *last = NULL;
(void)cu_mount_getlist(&fulllist);
- fl = fulllist;
- while(fl != NULL) {
-
- fl = fl->next;
- } /* while(fl != NULL) */
+ for(fl=fulllist; fl!=NULL; fl=fl->next) {
+ if(is_relevant(fl) != EXIT_SUCCESS) {
+ DBG("not relevant: %s on %s type %s (%s)",
+ fl->device, fl->dir, fl->type, fl->options);
+ continue;
+ }
+ DBG("relevant: %s on %s type %s (%s)",
+ fl->device, fl->dir, fl->type, fl->options);
+ } /* for(fl=fulllist; fl!=NULL; fl=fl->next) */
cu_mount_freelist(fulllist);
return(last);
} /* quota_mnt_t *quota_mnt_getlist(quota_mnt_t **list) */
+
+
void
quota_mnt_freelist(quota_mnt_t *list)
{
sfree(l->usrjquota);
sfree(l->grpjquota);
sfree(l->jqfmt);
- sfree(l);
p = NULL;
if(l != list) {
+ sfree(l);
l = list;
} else {
+ sfree(l);
l = NULL;
}
} /* while(l != NULL) */
} /* void quota_mnt_freelist(quota_mnt_t *list) */
+
diff --git a/src/quota_mnt.h b/src/quota_mnt.h
index e5893b9cd2ef1fa3e1a2845d1ff84c31b0380b64..2bfa2bbf32fa437047ab346e5c8c7bd55c14df09 100644 (file)
--- a/src/quota_mnt.h
+++ b/src/quota_mnt.h
quota_mnt_t *next;
};
-int quota_mnt_type(const char *type);
-
-char *quota_mnt_getmountopt(char *line, char *keyword);
-char *quota_mnt_checkmountopt(char *line, char *keyword, int full);
-
+quota_mnt_t *quota_mnt_getlist(quota_mnt_t **list);
/*
DESCRIPTION
The quota_mnt_getlist() function creates a list
- of all mountpoints.
+ of all quota-relevant mountpoints.
If *list is NULL, a new list is created and *list is
set to point to the first entry.
- If *list is set, the list is appended and *list is
- not changed.
+ If *list is not NULL, the list of mountpoints is appended
+ and *list is not changed.
RETURN VALUE
The quota_mnt_getlist() function returns a pointer to
NOTES
In case of an error, *list is not modified.
*/
-quota_mnt_t *quota_mnt_getlist(quota_mnt_t **list);
+
void quota_mnt_freelist(quota_mnt_t *list);
+/*
+ DESCRIPTION
+ The quota_mnt_freelist() function free()s all memory
+ allocated by *list and *list itself as well.
+*/
#endif /* !COLLECTD_QUOTA_MNT_H */
diff --git a/src/users.h b/src/users.h
index 03306cfba339c867b4e6acbd6a45a0c4725cadae..12959010a6c826a0ed94bb0f0fed665193852a81 100644 (file)
--- a/src/users.h
+++ b/src/users.h
#ifndef USERS_H
#define USERS_H 1
-#include "config.h"
+#include <config.h>
#if !defined(HAVE_UTMPX_H) || !defined(HAVE_GETUTXENT)
#undef HAVE_UTMPX_H
diff --git a/src/utils_debug.c b/src/utils_debug.c
index ae984f8853187e876c3096f862b45a79a492076f..3f432e117fcc69a6a2cb1126f08232474055bb40 100644 (file)
--- a/src/utils_debug.c
+++ b/src/utils_debug.c
@@ -177,17 +177,17 @@ cu_debug(const char *file, int line, const char *func, const char *format, ...)
{
}
int
-cu_debug_startfile(const char *file, int line, const char *func, char *format, ...)
+cu_debug_startfile(const char *file, int line, const char *func, const char *format, ...)
{
return EXIT_SUCCESS;
}
int
-cu_debug_stopfile(const char *file, int line, const char *func, char *format, ...)
+cu_debug_stopfile(const char *file, int line, const char *func, const char *format, ...)
{
return EXIT_SUCCESS;
}
int
-cu_debug_resetfile(const char *file, int line, const char *func, char *filename)
+cu_debug_resetfile(const char *file, int line, const char *func, const char *filename)
{
return EXIT_SUCCESS;
}
diff --git a/src/utils_debug.h b/src/utils_debug.h
index d5dcebd53a5579eb331d0406c23194a1ae58ca98..247b141d641955757d7a70ad9175273b3450432d 100644 (file)
--- a/src/utils_debug.h
+++ b/src/utils_debug.h
const char *format, ...);
int cu_debug_resetfile(const char *file, int line, const char *func,
- char *filename);
+ const char *filename);
#endif /* !COLLECTD_UTILS_DEBUG_H */
diff --git a/src/utils_mount.c b/src/utils_mount.c
index 74bc02f02afdc9e0f03d8c2436e0ffa007be496b..ecfd0ec6b6515d00ddd5f5570af9badccb1ec585 100644 (file)
--- a/src/utils_mount.c
+++ b/src/utils_mount.c
#include "common.h"
#if HAVE_XFS_XQM_H
# include <xfs/xqm.h>
-#define xfs_mem_dqinfo fs_quota_stat
-#define Q_XFS_GETQSTAT Q_XGETQSTAT
#define XFS_SUPER_MAGIC_STR "XFSB"
#define XFS_SUPER_MAGIC2_STR "BSFX"
#endif
-/* *** *** *** local functions *** *** *** */
+/* *** *** *** ********************************************* *** *** *** */
+/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */
+/* *** *** *** ********************************************* *** *** *** */
#define UUID 1
#define VOL 2
-#define AUTOFS_DIR_MAX 64 /* Maximum number of autofs directories */
-
static struct uuidCache_s {
struct uuidCache_s *next;
char uuid[16];
return rc;
}
-#if HAVE_LISTMNTENT
-static void
-cu_mount_listmntent(struct tabmntent *mntlist, cu_mount_t **list)
-{
- struct *p;
- struct mntent *mnt;
-
- for(p = mntlist; p; p = p->next) {
- mnt = p->ment;
- *list = smalloc(sizeof(cu_mount_t));
- list->device = strdup(mnt->mnt_fsname);
- list->name = strdup(mnt->mnt_dir);
- list->type = strdup(mnt->mnt_type);
- list->next = NULL;
- list = &(ist->next);
- }
- freemntlist(mntlist);
-}
-#endif /* HAVE_LISTMNTENT */
-
#if HAVE_GETVFSENT
}
#endif /* HAVE_GETVFSENT */
-char *
-cu_mount_checkmountopt(char *line, char *keyword, int full)
-{
- char *line2, *l2;
- int l = strlen(keyword);
- char *p1, *p2;
-
- if(line == NULL || keyword == NULL) {
- return NULL;
- }
- if(full != 0) {
- full = 1;
- }
-
- line2 = sstrdup(line);
- l2 = line2;
- while(*l2 != '\0') {
- if(*l2 == ',') {
- *l2 = '\0';
- }
- l2++;
- }
-
- p1 = line - 1;
- p2 = strchr(line, ',');
- do {
- if(strncmp(line2+(p1-line)+1, keyword, l+full) == 0) {
- free(line2);
- return p1+1;
- }
- p1 = p2;
- if(p1 != NULL) {
- p2 = strchr(p1+1, ',');
- }
- } while(p1 != NULL);
- free(line2);
- return NULL;
-} /* char *cu_mount_checkmountopt(char *line, char *keyword, int full) */
-char *
-cu_mount_getmountopt(char *line, char *keyword)
+#if HAVE_LISTMNTENT
+static cu_mount_t *
+cu_mount_listmntent(struct tabmntent *mntlist, cu_mount_t **list)
{
- char *r;
+ cu_mount_t *last = *list;
+ struct tabmntent *p;
+ struct mntent *mnt;
- r = cu_mount_checkmountopt(line, keyword, 0);
- if(r != NULL) {
- char *p;
- r += strlen(keyword);
- p = strchr(r, ',');
- if(p == NULL) {
- if(strlen(r) == 0) {
- return NULL;
+ for(p = mntlist; p; p = p->next) {
+ char *loop = NULL, *device = NULL;
+
+ mnt = p->ment;
+ loop = cu_mount_getoptionvalue(mnt->mnt_opts, "loop=");
+ 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)"
+ ": ignored", mnt->mnt_type,
+ mnt->mnt_dir, mnt->mnt_fsname);
+ continue;
}
- return sstrdup(r);
} else {
- char *m;
- if((p-r) == 1) {
- return NULL;
+ device = loop;
+ }
+ if(*list == NULL) {
+ *list = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
+ last = *list;
+ } else {
+ while(last->next != NULL) { /* is last really last? */
+ last = last->next;
}
- m = (char *)smalloc(p-r+1);
- sstrncpy(m, r, p-r+1);
- return m;
+ last->next = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
+ last = last->next;
}
- }
- return r;
-} /* char *cu_mount_getmountopt(char *line, char *keyword) */
+ last->dir = sstrdup(mnt->mnt_dir);
+ last->spec_device = sstrdup(mnt->mnt_fsname);
+ last->device = device;
+ last->type = sstrdup(mnt->mnt_type);
+ last->options = sstrdup(mnt->mnt_opts);
+ last->next = NULL;
+ } /* for(p = mntlist; p; p = p->next) */
+
+ return(last);
+} /* static cu_mount_t *cu_mount_listmntent(struct tabmntent *mntlist,
+ cu_mount_t **list) */
+#endif /* HAVE_LISTMNTENT */
+
+
#if HAVE_GETMNTENT
static cu_mount_t *
cu_mount_getmntent(FILE *mntf, cu_mount_t **list)
{
cu_mount_t *last = *list;
- struct mntent *mnt;
+#if HAVE_GETMNTENT1
+ struct mntent *mnt = NULL;
+#endif
+#if HAVE_GETMNTENT2
+ struct mntent real_mnt;
+ struct mntent *mnt = &real_mnt;
+#endif
#if HAVE_GETMNTENT1
while((mnt = getmntent(mntf)) != NULL) {
-#endif /* HAVE_GETMNTENT1 */
+#endif
+#if HAVE_GETMNTENT2
+ while(getmntent(mntf, &real_mnt) == 0) {
+#endif
char *loop = NULL, *device = NULL;
-#if 1
+#if 0
DBG("------------------ BEGIN");
DBG("mnt->mnt_fsname %s", mnt->mnt_fsname);
DBG("mnt->mnt_dir %s", mnt->mnt_dir);
DBG("mnt->mnt_passno %d", mnt->mnt_passno);
#endif
- loop = cu_mount_getmountopt(mnt->mnt_opts, "loop=");
+ loop = cu_mount_getoptionvalue(mnt->mnt_opts, "loop=");
if(loop == NULL) { /* no loop= mount */
device = get_device_name(mnt->mnt_fsname);
if(device == NULL) {
device = loop;
}
-#if 1
- DBG("device %s", device);
+#if 0
+ DBG("device: %s", device);
DBG("------------------ END");
#endif
if(*list == NULL) {
*list = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
last = *list;
} else {
+ while(last->next != NULL) { /* is last really last? */
+ last = last->next;
+ }
last->next = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
last = last->next;
}
last->type = sstrdup(mnt->mnt_type);
last->options = sstrdup(mnt->mnt_opts);
last->next = NULL;
+#if HAVE_GETMNTENT2
+ } /* while(getmntent(mntf, &real_mnt) == 0) */
+#endif
+#if HAVE_GETMNTENT1
} /* while((mnt = getmntent(mntf)) != NULL) */
+#endif
return last;
} /* static cu_mount_t *cu_mount_getmntent(FILE *mntf, cu_mount_t **list) */
+/* *** *** *** ******************************************** *** *** *** */
+/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */
+/* *** *** *** ******************************************** *** *** *** */
+
+
+
cu_mount_t *
cu_mount_getlist(cu_mount_t **list)
{
cu_mount_t *last = NULL;
- /* yes, i know that the indentation is wrong.
- but show me a better way to do this... */
- /* see lib/mountlist.c of coreutils for all
- gory details! */
+ /* see lib/mountlist.c of coreutils for all (ugly) details! */
+
+/*
+ there are two implementations of getmntent():
+ * one argument getmntent:
+ FILE *setmntent(const char *filename, const char *type);
+ struct mntent *getmntent(FILE *fp);
+ int endmntent(FILE *fp);
+ * two argument getmntent:
+ FILE *fopen(const char *path, const char *mode);
+ int getmntent(FILE *fp, struct mnttab *mnt);
+ int fclose(FILE *fp);
+ and a third (linux/gnu style) version called getmntent_r, which is not used
+ here (enough trouble with the two versions above).
+*/
+#if HAVE_GETMNTENT
+# if HAVE_GETMNTENT1
+# define setmntent setmntent
+# define endmntent endmntent
+# else
+# if HAVE_GETMNTENT2
+# define setmntent fopen
+# define endmntent fclose
+# else
+# error HAVE_GETMNTENT defined, but neither HAVE_GETMNTENT1 nor HAVE_GETMNTENT2
+# endif /* HAVE_GETMNTENT2 */
+# endif /* HAVE_GETMNTENT1 */
+#endif /* HAVE_GETMNTENT */
+
+ /* the indentation is wrong. is there a better way to do this? */
+
#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
{
FILE *mntf = NULL;
if((mntf = setmntent(MNTTABNAME, "r")) == NULL) {
DBG("opening %s failed: %s", MNTTABNAME, strerror(errno));
#endif
-#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+#if HAVE_LISTMNTENT
{
- FILE *mntf = NULL;
- if((mntf = setmntent(_PATH_MNTTAB, "r")) == NULL) {
- DBG("opening %s failed: %s", _PATH_MNTTAB, strerror(errno));
+ struct tabmntent *mntlist;
+ if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) {
+ DBG("calling listmntent() failed: %s", strerror(errno));
#endif
#if HAVE_GETVFSENT && defined(VFSTAB)
+ /* this is as bad as the next one, read next comment */
{
FILE *mntf = NULL;
if((mntf = fopen(VFSTAB, "r")) == NULL) {
DBG("opening %s failed: %s", VFSTAB, strerror(errno));
#endif
-#if HAVE_LISTMNTENT
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+ /* _PATH_MNTTAB is usually /etc/fstab and so this should be really
+ the very last thing to try, because it does not provide a list
+ of currently mounted filesystems... */
{
- struct tabmntent *mntlist;
-
- if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) {
- DBG("calling listmntent() failed: %s", strerror(errno));
+ FILE *mntf = NULL;
+ if((mntf = setmntent(_PATH_MNTTAB, "r")) == NULL) {
+ DBG("opening %s failed: %s", _PATH_MNTTAB, strerror(errno));
#endif
- /* give up */
- DBG("failed get local mountpoints");
- return(NULL);
-#if HAVE_LISTMNTENT
- } else { last = cu_mount_listmntent(mntlist, list); }
- freemntlist(mntlist);
+ /* give up */
+ DBG("failed get local mountpoints");
+ return(NULL);
+
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+ } else { last = cu_mount_getmntent(mntf, list); }
+ (void)endmntent(mntf);
}
#endif
#if HAVE_GETVFSENT && defined(VFSTAB)
(void)fclose(mntf);
}
#endif
-#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
- } else { last = cu_mount_getmntent(mntf, list); }
- (void)endmntent(mntf);
+#if HAVE_LISTMNTENT
+ } else { last = cu_mount_listmntent(mntlist, list); }
+ freemntlist(mntlist);
}
#endif
#if HAVE_GETMNTENT && defined(MNTTABNAME)
return(last);
} /* cu_mount_t *cu_mount_getlist(cu_mount_t **list) */
+
+
void
cu_mount_freelist(cu_mount_t *list)
{
sfree(l->device);
sfree(l->type);
sfree(l->options);
- sfree(l);
p = NULL;
if(l != list) {
+ sfree(l);
l = list;
} else {
- l = NULL;
+ sfree(l);
+ l = NULL; /* done by sfree already */
}
} /* while(l != NULL) */
} /* 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;
+
+ if(line == NULL || keyword == NULL) {
+ return NULL;
+ }
+ if(full != 0) {
+ full = 1;
+ }
+
+ line2 = sstrdup(line);
+ l2 = line2;
+ while(*l2 != '\0') {
+ if(*l2 == ',') {
+ *l2 = '\0';
+ }
+ l2++;
+ }
+
+ p1 = line - 1;
+ p2 = strchr(line, ',');
+ do {
+ if(strncmp(line2+(p1-line)+1, keyword, l+full) == 0) {
+ free(line2);
+ return p1+1;
+ }
+ p1 = p2;
+ if(p1 != NULL) {
+ p2 = strchr(p1+1, ',');
+ }
+ } while(p1 != NULL);
+
+ free(line2);
+ return NULL;
+} /* char *cu_mount_checkoption(char *line, char *keyword, int full) */
+
+
+
+char *
+cu_mount_getoptionvalue(char *line, char *keyword)
+{
+ char *r;
+
+ r = cu_mount_checkoption(line, keyword, 0);
+ if(r != NULL) {
+ char *p;
+ r += strlen(keyword);
+ p = strchr(r, ',');
+ if(p == NULL) {
+ if(strlen(r) == 0) {
+ return NULL;
+ }
+ return sstrdup(r);
+ } else {
+ char *m;
+ if((p-r) == 1) {
+ return NULL;
+ }
+ m = (char *)smalloc(p-r+1);
+ sstrncpy(m, r, p-r+1);
+ return m;
+ }
+ }
+ return r;
+} /* char *cu_mount_getoptionvalue(char *line, char *keyword) */
+
+
+
int
cu_mount_type(const char *type)
{
diff --git a/src/utils_mount.h b/src/utils_mount.h
index 3f357b8b6b24afa53511aae2ee647dd176360df0..822f786e711403a7bbd826e12144201826fe8c4e 100644 (file)
--- a/src/utils_mount.h
+++ b/src/utils_mount.h
* Niki W. Waibel <niki.waibel@gmx.net>
**/
+/* See below for instructions how to use the public functions. */
+
#if !COLLECTD_UTILS_MOUNT_H
#define COLLECTD_UTILS_MOUNT_H 1
+#include "common.h"
+
+#if HAVE_FS_INFO_H
+# include <fs_info.h>
+#endif
+#if HAVE_FSHELP_H
+# include <fshelp.h>
+#endif
+#if HAVE_PATHS_H
+# include <paths.h>
+#endif
#if HAVE_MNTENT_H
# include <mntent.h>
#endif
#if HAVE_MNTTAB_H
# include <mnttab.h>
#endif
-#if HAVE_PATHS_H
-# include <paths.h>
+#if HAVE_SYS_FSTYP_H
+# include <sys/fstyp.h>
#endif
#if HAVE_SYS_FS_TYPES_H
# include <sys/fs_types.h>
#if HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
-#if HAVE_SYS_VFSTAB_H
-# include <sys/vfstab.h>
+#if HAVE_SYS_STATFS_H
+# include <sys/statfs.h>
#endif
#if HAVE_SYS_VFS_H
# include <sys/vfs.h>
#endif
-
-#include "common.h"
+#if HAVE_SYS_VFSTAB_H
+# include <sys/vfstab.h>
+#endif
/* Collectd Utils Mount Type */
#define CUMT_UNKNOWN (0)
#define CUMT_VXFS (5)
#define CUMT_ZFS (6)
-/* Collectd Utils Mount Options */
-#define CUMO_NONE (0)
-#define CUMO_USRQUOTA (1)
-#define CUMO_GRPQUOTA (2)
-
typedef struct _cu_mount_t cu_mount_t;
struct _cu_mount_t {
char *dir; /* "/sys" or "/" */
char *spec_device; /* "LABEL=/" or "none" or "proc" or "/dev/hda1" */
- char *device; /* "none" or "proc" "/dev/hda1" */
+ char *device; /* "none" or "proc" or "/dev/hda1" */
char *type; /* "sysfs" or "ext3" */
char *options; /* "rw,noatime,commit=600,quota,grpquota" */
cu_mount_t *next;
};
-int cu_mount_type(const char *type);
-
-char *cu_mount_getmountopt(char *line, char *keyword);
-char *cu_mount_checkmountopt(char *line, char *keyword, int full);
-
+cu_mount_t *cu_mount_getlist(cu_mount_t **list);
/*
DESCRIPTION
The cu_mount_getlist() function creates a list
If *list is NULL, a new list is created and *list is
set to point to the first entry.
- If *list is set, the list is appended and *list is
- not changed.
+ If *list is not NULL, the list of mountpoints is appended
+ and *list is not changed.
RETURN VALUE
The cu_mount_getlist() function returns a pointer to
- the last entry of the list, or NULL if an error occured.
+ the last entry of the list, or NULL if an error has
+ occured.
NOTES
In case of an error, *list is not modified.
*/
-cu_mount_t *cu_mount_getlist(cu_mount_t **list);
+
void cu_mount_freelist(cu_mount_t *list);
+/*
+ DESCRIPTION
+ The cu_mount_freelist() function free()s all memory
+ allocated by *list and *list itself as well.
+*/
+
+char *cu_mount_checkoption(char *line, char *keyword, int full);
+/*
+ DESCRIPTION
+ The cu_mount_checkoption() function is a replacement of
+ char *hasmntopt(const struct mntent *mnt, const char *opt).
+ In fact hasmntopt() just looks for the first occurence of the
+ characters at opt in mnt->mnt_opts. cu_mount_checkoption()
+ checks for the *option* keyword in line, starting at the
+ first character of line or after a ','.
+
+ If full is not 0 then also the end of keyword has to match
+ either the end of line or a ',' after keyword.
+
+ RETURN VALUE
+ The cu_mount_checkoption() function returns a pointer into
+ string line if a match of keyword is found. If no match is
+ found cu_mount_checkoption() returns NULL.
+
+ NOTES
+ Do *not* try to free() the pointer which is returned! It is
+ just part of the string line.
+
+ full should be set to 0 when matching options like: rw, quota,
+ noatime. Set full to 1 when matching options like: loop=,
+ gid=, commit=.
+
+ EXAMPLES
+ If line is "rw,usrquota,grpquota", keyword is "quota", NULL
+ will be returned (independend of full).
+
+ If line is "rw,usrquota,grpquota", keyword is "usrquota",
+ a pointer to "usrquota,grpquota" is returned (independend
+ of full).
+
+ If line is "rw,loop=/dev/loop1,quota", keyword is "loop="
+ and full is 0, then a pointer to "loop=/dev/loop1,quota"
+ is returned. If full is not 0 then NULL is returned. But
+ maybe you might want to try cu_mount_getoptionvalue()...
+*/
+
+char *cu_mount_getoptionvalue(char *line, char *keyword);
+/*
+ DESCRIPTION
+ The cu_mount_getoptionvalue() function can be used to grab
+ a VALUE out of a mount option (line) like:
+ loop=VALUE
+ whereas "loop=" is the keyword.
+
+ RETURN VALUE
+ If the cu_mount_getoptionvalue() function can find the option
+ keyword in line, then memory is allocated for the value of
+ that option and a pointer to that value is returned.
+
+ If the option keyword is not found, cu_mount_getoptionvalue()
+ returns NULL;
+
+ NOTES
+ Internally it calls cu_mount_checkoption(), then it
+ allocates memory for VALUE and returns a pointer to that
+ string. So *do not forget* to free() the memory returned
+ after use!!!
+*/
+
+int cu_mount_type(const char *type);
+/*
+ DESCRIPTION
+
+ RETURN VALUE
+*/
+
#endif /* !COLLECTD_UTILS_MOUNT_H */