Code

Added Niki Waibel's quota patch
authorocto <octo>
Tue, 29 Nov 2005 13:01:15 +0000 (13:01 +0000)
committerocto <octo>
Tue, 29 Nov 2005 13:01:15 +0000 (13:01 +0000)
14 files changed:
AUTHORS [new file with mode: 0644]
configure.in [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/collectd.h [new file with mode: 0644]
src/config.h.in [new file with mode: 0644]
src/quota_debug.c [new file with mode: 0644]
src/quota_debug.h [new file with mode: 0644]
src/quota_fs.c [new file with mode: 0644]
src/quota_fs.h [new file with mode: 0644]
src/quota_mnt.c [new file with mode: 0644]
src/quota_mnt.h [new file with mode: 0644]
src/quota_mntopt.h [new file with mode: 0644]
src/quota_plugin.c [new file with mode: 0644]
src/quota_plugin.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..3e803b8
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,31 @@
+This package was written by:
+  Florian octo Forster <octo@verplant.org>
+
+cpufreq module by:
+  Peter Holik <peter@holik.at>
+
+hddtemp module by:
+  Vincent StehlĂ© <vincent.stehle@free.fr>
+
+nfs module by:
+  Jason Pepas <cell@ices.utexas.edu>
+
+processes module by:
+  Lyonel Vincent <lyonel@ezix.org>
+
+quota module by:
+  Niki Waibel <niki.waibel@newlogic.com>
+
+serial module by:
+  David Bacher <drbacher@gmail.com>
+
+tape module by:
+  Scott Garrett <sgarrett@technomancer.com>
+
+don't-fork-patch by:
+  Alvaro Barcellos <alvaro.barcellos@gmail.com>
+
+collectd is available at:
+  <http://verplant.org/collectd/>
+
+Enjoy :)
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..a50fa6b
--- /dev/null
@@ -0,0 +1,444 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(src/collectd.c)
+AM_INIT_AUTOMAKE(collectd, 3.4.0-quota)
+AM_CONFIG_HEADER(src/config.h src/libping/config.h)
+AC_LANG(C)
+
+#AC_PREFIX_DEFAULT("/opt/collectd-3.4.0")
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+
+dnl configure libtool
+AC_DISABLE_STATIC
+AC_LIBTOOL_DLOPEN
+AC_PROG_LIBTOOL
+#AC_PROG_RANLIB
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h unistd.h)
+AC_CHECK_HEADERS(signal.h)
+AC_CHECK_HEADERS(sys/socket.h)
+AC_CHECK_HEADERS(sys/select.h)
+AC_CHECK_HEADERS(netdb.h)
+AC_CHECK_HEADERS(sys/time.h sys/times.h)
+AC_CHECK_HEADERS(sys/types.h)
+AC_CHECK_HEADERS(sys/resource.h)
+AC_CHECK_HEADERS(errno.h)
+AC_CHECK_HEADERS(arpa/inet.h)
+AC_CHECK_HEADERS(netinet/in.h)
+AC_CHECK_HEADERS(netdb.h)
+AC_CHECK_HEADERS(syslog.h)
+AC_CHECK_HEADERS(dlfcn.h)
+AC_CHECK_HEADERS(paths.h)
+AC_CHECK_HEADERS(mntent.h)
+AC_CHECK_HEADERS(sys/fs_types.h)
+AC_CHECK_HEADERS(sys/mnttab.h)
+AC_CHECK_HEADERS(sys/mount.h)
+AC_CHECK_HEADERS(sys/vfstab.h)
+AC_CHECK_HEADERS(xfs/xqm.h)
+
+dnl Checking for libraries
+AC_CHECK_LIB(m, ext)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_CHECK_FUNCS(gettimeofday select socket strdup strstr strtol)
+AC_CHECK_FUNCS(socket, , AC_CHECK_LIB(socket, socket))
+AC_CHECK_FUNCS(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
+AC_CHECK_FUNCS(strchr memcpy strstr strcmp strncmp strncpy strlen)
+AC_CHECK_FUNCS(strncasecmp strcasecmp strncmp)
+AC_CHECK_FUNCS(getfsent getvfsent getmntent listmntent)
+
+AC_MSG_CHECKING([for kernel type ($host_os)])
+case $host_os in
+       *linux*)
+       AC_DEFINE([KERNEL_LINUX], [], [True if program is to be compiled for a Linux kernel])
+       ac_system="Linux"
+       ;;
+       *solaris*)
+       AC_DEFINE([KERNEL_SOLARIS], [], [True if program is to be compiled for a Solaris kernel])
+       ac_system="Solaris"
+       ;;
+       *)
+       ac_system="unknown"
+esac
+AC_MSG_RESULT([$ac_system])
+
+dnl Checks for libraries.
+AC_CHECK_LIB(socket, socket)
+AC_CHECK_LIB(resolv, res_search)
+AC_CHECK_LIB(dl, dlopen)
+
+# AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])
+AC_ARG_WITH(rrdtool, AC_HELP_STRING([--with-rrdtool=PFX], [Path to rrdtool.]),
+[      if test "x$withval" != "xno" -a "x$withval" != "xyes"
+       then
+               LDFLAGS="$LDFLAGS -L$withval/lib"
+               CPPFLAGS="$CPPFLAGS -I$withval/include"
+               with_rrdtool="yes"
+       fi
+], [with_rrdtool="yes"])
+if test "x$with_rrdtool" = "xyes"
+then
+       AC_CHECK_LIB(rrd, rrd_update,, [with_rrdtool="no"], [-lm])
+fi
+if test "x$with_rrdtool" = "xyes"
+then
+       AC_CHECK_HEADERS(rrd.h,, [with_rrdtool="no"])
+fi
+AM_CONDITIONAL(BUILD_WITH_RRDTOOL, test "x$with_rrdtool" = "xyes")
+
+if test "$ac_system" = "Solaris"
+then
+       with_kstat="yes"
+       AC_CHECK_LIB(kstat, kstat_open,, [with_kstat="no (not found)"])
+       AC_CHECK_LIB(devinfo, di_init)
+       AC_CHECK_HEADERS(kstat.h,, [with_kstat="no (kstat.h not found)"])
+else
+       with_kstat="no (Solaris only)"
+fi
+
+AC_ARG_WITH(libstatgrab, AC_HELP_STRING([--with-libstatgrab@<:@=PFX@:>@], [Path to libstatgrab.]),
+[
+       # given..
+       if test "x$withval" != "xno"
+       then
+               if test "x$withval" != "xyes"
+               then
+                       LDFLAGS="$LDFLAGS -L$withval/lib"
+                       CPPFLAGS="$CPPFLAGS -I$withval/include"
+                       with_libstatgrab="yes"
+               fi
+       fi
+],
+[
+       # not given..
+       if test "x$ac_system" != "xunknown"
+       then
+               with_libstatgrab="no"
+       else
+               with_libstatgrab="yes"
+       fi
+])
+if test "x$with_libstatgrab" = "xyes"
+then
+       AC_CHECK_LIB(statgrab, sg_init,, [with_libstatgrab="no (not found)"])
+       AC_CHECK_HEADERS(statgrab.h,,    [with_libstatgrab="no (not found)"])
+fi
+
+AC_ARG_WITH(lm-sensors, AC_HELP_STRING([--with-lm-sensors@<:@=PFX@:>@], [Path to lm_sensors.]),
+[
+       # given..
+       if test "x$withval" != "xno"
+       then
+               if test "x$withval" != "xyes"
+               then
+                       LDFLAGS="$LDFLAGS -L$withval/lib"
+                       CPPFLAGS="$CPPFLAGS -I$withval/include"
+                       with_lm_sensors="yes"
+               fi
+       fi
+],
+[
+       # not given..
+       if test "x$ac_system" = "xLinux"
+       then
+               with_lm_sensors="yes"
+       else
+               with_lm_sensors="no"
+       fi
+])
+if test "x$with_lm_sensors" = "xyes"
+then
+       AC_CHECK_LIB(sensors, sensors_init,
+       [
+               with_lm_sensors="yes"
+               AC_DEFINE(HAVE_LIBSENSORS, 1, [Define to 1 if you have the sensors library (-lsensors).])
+       ],
+       [with_lm_sensors="no (not found)"])
+       AC_CHECK_HEADERS(sensors/sensors.h,
+       [
+               with_lm_sensors="yes"
+               AC_DEFINE(HAVE_SENSORS_SENSORS_H, 1, [Define to 1 if you have the <sensors/sensors.h> header file.])
+       ],
+       [with_lm_sensors="no (not found)"])
+fi
+
+
+
+#
+# Check for enabled/disabled features
+#
+AC_ARG_ENABLE(cpu, AC_HELP_STRING([--disable-cpu], [Disable CPU usage statistics]),, [enable_cpu="yes"])
+if test "x$enable_cpu" != "xno"
+then
+       if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+       then
+               enable_cpu="yes"
+       else
+               enable_cpu="no"
+       fi
+fi
+if test "x$enable_cpu" = "xno"
+then
+       AC_DEFINE(COLLECT_CPU, 0, [Wether or not to collect CPU usage statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_CPU, test "x$enable_cpu" = "xyes")
+
+AC_ARG_ENABLE(cpufreq, AC_HELP_STRING([--disable-cpufreq], [Disable system cpu frequency statistics]),, [enable_cpufreq="yes"])
+if test "x$enable_cpufreq" != "xno"
+then
+       if test "x$ac_system" = "xLinux"
+       then
+               enable_cpufreq="yes"
+       else
+               enable_cpufreq="no"
+       fi
+fi
+if test "x$enable_cpufreq" = "xno"
+then
+       AC_DEFINE(COLLECT_CPUFREQ, 0, [Wether or not to collect cpu frequency statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_CPUFREQ, test "x$enable_cpufreq" = "xyes")
+
+AC_ARG_ENABLE(disk, AC_HELP_STRING([--disable-disk], [Disable disk/partition statistics]),, [enable_disk="yes"])
+if test "x$enable_disk" != "xno"
+then
+       if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes"
+       then
+               enable_disk="yes"
+       else
+               enable_disk="no"
+       fi
+fi
+if test "x$enable_disk" = "xno"
+then
+       AC_DEFINE(COLLECT_DISK, 0, [Wether or not to collect diskstats])
+fi
+AM_CONDITIONAL(BUILD_MODULE_DISK, test "x$enable_disk" = "xyes")
+
+AC_ARG_ENABLE(quota, AC_HELP_STRING([--enable-quota],
+       [Enable quota statistics (experimental, off by default)]),
+       [], [enable_quota="no"])
+if test "x$enable_quota" = "xno"
+then
+       collect_quota=0
+else
+       if test "x$enable_quota" = "xyes"
+       then
+               collect_quota=1
+               enable_quota="yes"
+       else
+               AC_MSG_NOTICE([Please specify either --enable-quota or --disable-quota; Enabling quota statistics.])
+               collect_quota=1
+               enable_quota="yes"
+       fi
+fi
+AC_DEFINE_UNQUOTED(COLLECT_QUOTA, [$collect_quota],
+       [Wether or not to collect quotastats])
+AM_CONDITIONAL(BUILD_MODULE_QUOTA, test "x$enable_quota" = "xyes")
+
+AC_ARG_ENABLE(hddtemp, AC_HELP_STRING([--disable-hddtemp], [Disable hdd temperature statistics]),, [enable_hddtemp="yes"])
+if test "x$enable_hddtemp" = "xno"
+then
+       AC_DEFINE(COLLECT_HDDTEMP, 0, [Wether or not to collect hdd temperature statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_HDDTEMP, test "x$enable_hddtemp" = "xyes")
+
+AC_ARG_ENABLE(load, AC_HELP_STRING([--disable-load], [Disable system load statistics]),, [enable_load="yes"])
+if test "x$enable_load" != "xno"
+then
+       if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+       then
+               enable_load="yes"
+       else
+               enable_load="no"
+       fi
+fi
+if test "x$enable_load" = "xno"
+then
+       AC_DEFINE(COLLECT_LOAD, 0, [Wether or not to collect system load statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_LOAD, test "x$enable_load" = "xyes")
+
+AC_ARG_ENABLE(memory, AC_HELP_STRING([--disable-memory], [Disable memory statistics]),, [enable_memory="yes"])
+if test "x$enable_memory" != "xno"
+then
+       if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+       then
+               enable_memory="yes"
+       else
+               enable_memory="no"
+       fi
+fi
+if test "x$enable_memory" = "xno"
+then
+       AC_DEFINE(COLLECT_MEMORY, 0, [Wether or not to collect memory statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_MEMORY, test "x$enable_memory" = "xyes")
+
+AC_ARG_ENABLE(nfs, AC_HELP_STRING([--disable-nfs], [Disable nfs statistics]),, [enable_nfs="yes"])
+if test "x$enable_nfs" != "xno"
+then
+       if test "x$ac_system" = "xLinux"
+       then
+               enable_nfs="yes"
+       else
+               enable_nfs="no"
+       fi
+fi
+if test "x$enable_nfs" = "xno"
+then
+       AC_DEFINE(COLLECT_NFS, 0, [Wether or not to collect nfs statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_NFS, test "x$enable_nfs" = "xyes")
+
+AC_ARG_ENABLE(ping, AC_HELP_STRING([--disable-ping], [Disable ping statistics]),, [enable_ping="yes"])
+if test "x$enable_ping" != "xno"
+then
+       enable_ping="yes"
+fi
+if test "x$enable_ping" = "xno"
+then
+       AC_DEFINE(COLLECT_PING, 0, [Wether or not to collect ping statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_PING, test "x$enable_ping" = "xyes")
+
+AC_ARG_ENABLE(processes, AC_HELP_STRING([--disable-processes], [Disable processes statistics]),, [enable_processes="yes"])
+if test "x$enable_processes" != "xno"
+then
+       if test "x$ac_system" = "xLinux" 
+       then
+               enable_processes="yes"
+       else
+               enable_processes="no"
+       fi
+fi
+if test "x$enable_processes" = "xno"
+then
+       AC_DEFINE(COLLECT_PROCESSES, 0, [Wether or not to collect processes statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_PROCESSES, test "x$enable_processes" = "xyes")
+
+AC_ARG_ENABLE(sensors, AC_HELP_STRING([--disable-sensors], [Disable lm_sensors statistics]),, [enable_sensors=$with_lm_sensors])
+if test "x$enable_sensors" != "xno"
+then
+       if test "x$with_lm_sensors" = "xyes"
+       then
+               enable_sensors="yes"
+       else
+               enable_sensors="no"
+       fi
+fi
+if test "x$enable_sensors" = "xno"
+then
+       AC_DEFINE(COLLECT_SENSORS, 0, [Wether or not to collect lm_sensors statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_SENSORS, test "x$enable_sensors" = "xyes")
+
+AC_ARG_ENABLE(serial, AC_HELP_STRING([--disable-serial], [Disable serial statistics]),, [enable_serial="yes"])
+if test "x$enable_serial" != "xno"
+then
+       if test "x$ac_system" = "xLinux"
+       then
+               enable_serial="yes"
+       else
+               enable_serial="no"
+       fi
+fi
+if test "x$enable_serial" = "xno"
+then
+       AC_DEFINE(COLLECT_SERIAL, 0, [Wether or not to collect serial statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_SERIAL, test "x$enable_serial" = "xyes")
+
+AC_ARG_ENABLE(swap, AC_HELP_STRING([--disable-swap], [Disable swap statistics]),, [enable_swap="yes"])
+if test "x$enable_swap" != "xno"
+then
+       if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+       then
+               enable_swap="yes"
+       else
+               enable_swap="no"
+       fi
+fi
+if test "x$enable_swap" = "xno"
+then
+       AC_DEFINE(COLLECT_SWAP, 0, [Wether or not to collect swap statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_SWAP, test "x$enable_swap" = "xyes")
+
+AC_ARG_ENABLE(tape, AC_HELP_STRING([--disable-tape], [Disable tape statistics]),, [enable_tape="yes"])
+if test "x$enable_tape" != "xno"
+then
+       if test "x$with_kstat" = "xyes"
+       then
+               enable_tape="yes"
+       else
+               enable_tape="no"
+       fi
+fi
+if test "x$enable_tape" = "xno"
+then
+       AC_DEFINE(COLLECT_TAPE, 0, [Wether or not to collect tape statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_TAPE, test "x$enable_tape" = "xyes")
+
+AC_ARG_ENABLE(traffic, AC_HELP_STRING([--disable-traffic], [Disable system traffic statistics]),, [enable_traffic="yes"])
+if test "x$enable_traffic" != "xno"
+then
+       if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+       then
+               enable_traffic="yes"
+       else
+               enable_traffic="no"
+       fi
+fi
+if test "x$enable_traffic" = "xno"
+then
+       AC_DEFINE(COLLECT_TRAFFIC, 0, [Wether or not to collect network traffic statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_TRAFFIC, test "x$enable_traffic" = "xyes")
+
+AC_OUTPUT(Makefile src/libping/Makefile src/Makefile)
+
+cat <<EOF;
+
+Configuration:
+  Libraries:
+    librrd  . . . . . . $with_rrdtool
+    lm_sensors  . . . . $with_lm_sensors
+    libstatgrab . . . . $with_libstatgrab
+    libkstat  . . . . . $with_kstat
+
+  Features:
+    cpu . . . . . . . . $enable_cpu
+    cpufreq . . . . . . $enable_cpufreq
+    disk  . . . . . . . $enable_disk
+    quota . . . . . . . $enable_quota
+    hddtemp . . . . . . $enable_hddtemp
+    load  . . . . . . . $enable_load
+    memory  . . . . . . $enable_memory
+    nfs . . . . . . . . $enable_nfs
+    ping  . . . . . . . $enable_ping
+    processes . . . . . $enable_processes
+    sensors . . . . . . $enable_sensors
+    serial  . . . . . . $enable_serial
+    swap  . . . . . . . $enable_swap
+    tape  . . . . . . . $enable_tape
+    traffic . . . . . . $enable_traffic
+
+EOF
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..b0dee1c
--- /dev/null
@@ -0,0 +1,121 @@
+if BUILD_MODULE_PING
+SUBDIRS = libping
+endif
+
+sbin_PROGRAMS = collectd
+
+collectd_SOURCES = collectd.c collectd.h \
+                  common.c common.h \
+                  multicast.c multicast.h \
+                  plugin.c plugin.h
+collectd_CFLAGS = -DPLUGINDIR='"$(pkglibdir)"'
+collectd_LDFLAGS = -dlopen self
+if BUILD_WITH_RRDTOOL
+collectd_LDFLAGS += -lrrd
+endif
+
+pkglib_LTLIBRARIES = 
+
+if BUILD_MODULE_CPU
+pkglib_LTLIBRARIES += cpu.la
+cpu_la_SOURCES = cpu.c cpu.h
+cpu_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_CPUFREQ
+pkglib_LTLIBRARIES += cpufreq.la
+cpufreq_la_SOURCES = cpufreq.c cpufreq.h
+cpufreq_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_DISK
+pkglib_LTLIBRARIES += disk.la
+disk_la_SOURCES = disk.c disk.h
+disk_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_QUOTA
+pkglib_LTLIBRARIES += quota.la
+quota_la_SOURCES = quota_plugin.c quota_plugin.h
+quota_la_SOURCES += quota_debug.c quota_debug.h
+quota_la_SOURCES += quota_mnt.c quota_mnt.h quota_mntopt.h
+quota_la_SOURCES += quota_fs.c quota_fs.h
+quota_la_LDFLAGS = -module
+quota_la_CFLAGS = -Werror
+endif
+
+if BUILD_MODULE_HDDTEMP
+pkglib_LTLIBRARIES += hddtemp.la
+hddtemp_la_SOURCES = hddtemp.c hddtemp.h
+hddtemp_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_LOAD
+pkglib_LTLIBRARIES += load.la
+load_la_SOURCES = load.c load.h
+load_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_MEMORY
+pkglib_LTLIBRARIES += memory.la
+memory_la_SOURCES = memory.c memory.h
+memory_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_NFS
+pkglib_LTLIBRARIES += nfs.la
+nfs_la_SOURCES = nfs.c nfs.h
+nfs_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_PING
+pkglib_LTLIBRARIES += ping.la
+ping_la_SOURCES = ping.c ping.h
+ping_la_LDFLAGS = -module
+ping_la_LIBADD  = libping/libping.la
+ping_la_DEPENDENCIES = libping/libping.la
+endif
+
+if BUILD_MODULE_PROCESSES
+pkglib_LTLIBRARIES += processes.la
+processes_la_SOURCES = processes.c processes.h
+processes_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_SENSORS
+pkglib_LTLIBRARIES += sensors.la
+sensors_la_SOURCES = sensors.c sensors.h
+sensors_la_LDFLAGS = -module -lsensors
+endif
+
+if BUILD_MODULE_SERIAL
+pkglib_LTLIBRARIES += serial.la
+serial_la_SOURCES = serial.c serial.h
+serial_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_SWAP
+pkglib_LTLIBRARIES += swap.la
+swap_la_SOURCES = swap.c swap.h
+swap_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_TAPE
+pkglib_LTLIBRARIES += tape.la
+tape_la_SOURCES = tape.c tape.h
+tape_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_TRAFFIC
+pkglib_LTLIBRARIES += traffic.la
+traffic_la_SOURCES = traffic.c traffic.h
+traffic_la_LDFLAGS = -module
+endif
+
+man_MANS = collectd.1
+#collectd_1_SOURCES = collectd.pod
+
+EXTRA_DIST = $(man_MANS)
+
+.pod.1:
+       pod2man --release=$(VERSION) --center=$(PACKAGE) $< >$@
diff --git a/src/collectd.h b/src/collectd.h
new file mode 100644 (file)
index 0000000..eb07756
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef COLLECTD_H
+#define COLLECTD_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <limits.h>
+#include <time.h>
+
+#include "config.h"
+
+#ifndef HAVE_RRD_H
+#undef HAVE_LIBRRD
+#endif
+
+#ifdef HAVE_LIBRRD
+#include <rrd.h>
+#endif /* HAVE_LIBRRD */
+
+/* Won't work without the header file */
+#ifndef HAVE_KSTAT_H
+#undef HAVE_LIBKSTAT
+#endif
+
+#ifdef HAVE_LIBKSTAT
+#include <kstat.h>
+#include <sys/param.h>
+#endif /* HAVE_LIBKSTAT */
+
+/* Won't work without the header file */
+#ifndef HAVE_STATGRAB_H
+#undef HAVE_LIBSTATGRAB
+#endif
+
+#ifdef HAVE_LIBSTATGRAB
+#include <statgrab.h>
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+#ifndef PLUGINDIR
+#define PLUGINDIR "/usr/lib/collectd"
+#endif
+
+#define MODE_SERVER 0x01
+#define MODE_CLIENT 0x02
+#define MODE_LOCAL  0x03
+
+extern time_t curtime;
+extern int operating_mode;
+
+#endif /* COLLECTD_H */
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644 (file)
index 0000000..b49392e
--- /dev/null
@@ -0,0 +1,277 @@
+/* src/config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Wether or not to collect CPU usage statistics */
+#undef COLLECT_CPU
+
+/* Wether or not to collect cpu frequency statistics */
+#undef COLLECT_CPUFREQ
+
+/* Wether or not to collect diskstats */
+#undef COLLECT_DISK
+
+/* Wether or not to collect hdd temperature statistics */
+#undef COLLECT_HDDTEMP
+
+/* Wether or not to collect system load statistics */
+#undef COLLECT_LOAD
+
+/* Wether or not to collect memory statistics */
+#undef COLLECT_MEMORY
+
+/* Wether or not to collect nfs statistics */
+#undef COLLECT_NFS
+
+/* Wether or not to collect ping statistics */
+#undef COLLECT_PING
+
+/* Wether or not to collect processes statistics */
+#undef COLLECT_PROCESSES
+
+/* Wether or not to collect quotastats */
+#undef COLLECT_QUOTA
+
+/* Wether or not to collect lm_sensors statistics */
+#undef COLLECT_SENSORS
+
+/* Wether or not to collect serial statistics */
+#undef COLLECT_SERIAL
+
+/* Wether or not to collect swap statistics */
+#undef COLLECT_SWAP
+
+/* Wether or not to collect tape statistics */
+#undef COLLECT_TAPE
+
+/* Wether or not to collect network traffic statistics */
+#undef COLLECT_TRAFFIC
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `getfsent' function. */
+#undef HAVE_GETFSENT
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define to 1 if you have the `getmntent' function. */
+#undef HAVE_GETMNTENT
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `getvfsent' function. */
+#undef HAVE_GETVFSENT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <kstat.h> header file. */
+#undef HAVE_KSTAT_H
+
+/* Define to 1 if you have the `devinfo' library (-ldevinfo). */
+#undef HAVE_LIBDEVINFO
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `kstat' library (-lkstat). */
+#undef HAVE_LIBKSTAT
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the `rrd' library (-lrrd). */
+#undef HAVE_LIBRRD
+
+/* Define to 1 if you have the sensors library (-lsensors). */
+#undef HAVE_LIBSENSORS
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the `statgrab' library (-lstatgrab). */
+#undef HAVE_LIBSTATGRAB
+
+/* Define to 1 if you have the `listmntent' function. */
+#undef HAVE_LISTMNTENT
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <mntent.h> header file. */
+#undef HAVE_MNTENT_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define to 1 if you have the <rrd.h> header file. */
+#undef HAVE_RRD_H
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the <sensors/sensors.h> header file. */
+#undef HAVE_SENSORS_SENSORS_H
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if you have the <statgrab.h> header file. */
+#undef HAVE_STATGRAB_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcmp' function. */
+#undef HAVE_STRCMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlen' function. */
+#undef HAVE_STRLEN
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strncmp' function. */
+#undef HAVE_STRNCMP
+
+/* Define to 1 if you have the `strncpy' function. */
+#undef HAVE_STRNCPY
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/fs_types.h> header file. */
+#undef HAVE_SYS_FS_TYPES_H
+
+/* Define to 1 if you have the <sys/mnttab.h> header file. */
+#undef HAVE_SYS_MNTTAB_H
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/vfstab.h> header file. */
+#undef HAVE_SYS_VFSTAB_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <xfs/xqm.h> header file. */
+#undef HAVE_XFS_XQM_H
+
+/* True if program is to be compiled for a Linux kernel */
+#undef KERNEL_LINUX
+
+/* True if program is to be compiled for a Solaris kernel */
+#undef KERNEL_SOLARIS
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/src/quota_debug.c b/src/quota_debug.c
new file mode 100644 (file)
index 0000000..acaa94c
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * collectd - src/quota_plugin.c
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "quota_debug.h"
+
+/* *** *** ***   global variables   *** *** *** */
+#if QUOTA_PLUGIN_DEBUG
+       FILE *QUOTA_DBG_FILE = NULL;
+#endif
+
diff --git a/src/quota_debug.h b/src/quota_debug.h
new file mode 100644 (file)
index 0000000..dcbdcd4
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * collectd - src/quota_debug.h
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_DEBUG_H
+#define COLLECTD_QUOTA_DEBUG_H 1
+
+#include "common.h"
+
+#define QUOTA_PLUGIN_DEBUG 1
+
+#if QUOTA_PLUGIN_DEBUG
+       #include <stdio.h>
+       extern FILE *QUOTA_DBG_FILE;
+       #define DBG(...) \
+       { \
+               if(QUOTA_DBG_FILE != NULL) { \
+                       fprintf(QUOTA_DBG_FILE, "%s:%d:%s(): ", \
+                               __FILE__, __LINE__, __func__); \
+                       fprintf(QUOTA_DBG_FILE, __VA_ARGS__); \
+                       fprintf(QUOTA_DBG_FILE, "\n"); \
+                       fflush(QUOTA_DBG_FILE); \
+               } \
+       }
+       #define DBG_INIT(...) \
+       { \
+               QUOTA_DBG_FILE = fopen("collectd.log", "a"); \
+               if(QUOTA_DBG_FILE == NULL) { \
+                       /* stderr is redirected to /dev/null, so you \
+                          will not see anything */ \
+                       fprintf(stderr, "Cannot open quota debug file.\n"); \
+               } else { \
+                       DBG(__VA_ARGS__); \
+               } \
+       }
+#else /* !QUOTA_PLUGIN_DEBUG */
+       #define DBG(...) /**/
+       #define DBG_INIT(...) /**/
+#endif /* QUOTA_PLUGIN_DEBUG */
+
+#endif /* !COLLECTD_QUOTA_DEBUG_H */
+
diff --git a/src/quota_fs.c b/src/quota_fs.c
new file mode 100644 (file)
index 0000000..bfd4d5e
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * collectd - src/quota_fs.c
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "quota_debug.h"
+#include "quota_fs.h"
+
+int
+quota_fs_issupported(const char *fsname)
+{
+       if(!strcmp(fsname, "ext2")
+       || !strcmp(fsname, "ext3")
+       || !strcmp(fsname, "ufs")
+       || !strcmp(fsname, "vxfs")
+       || !strcmp(fsname, "zfs"))
+       {
+               return EXIT_SUCCESS;
+       } else {
+#if 0
+               DBG("%s filesystem not supported", fsname);
+#endif
+               return EXIT_FAILURE;
+       }
+}
+
+int
+quota_fs_isnfs(const char *fsname)
+{
+       if(!strcmp(fsname, "nfs") || !strcmp(fsname, "nfs4")) {
+               return EXIT_SUCCESS;
+       } else {
+               return EXIT_FAILURE;
+       }
+}
diff --git a/src/quota_fs.h b/src/quota_fs.h
new file mode 100644 (file)
index 0000000..445b23d
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * collectd - src/quota_fs.h
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_FS_H
+#define COLLECTD_QUOTA_FS_H 1
+
+#include "common.h"
+
+int quota_fs_issupported(const char *fsname);
+int quota_fs_isnfs(const char *fsname);
+
+#endif /* !COLLECTD_QUOTA_FS_H */
+
diff --git a/src/quota_mnt.c b/src/quota_mnt.c
new file mode 100644 (file)
index 0000000..19cfa76
--- /dev/null
@@ -0,0 +1,725 @@
+/**
+ * collectd - src/quota_mnt.c
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "quota_debug.h"
+#include "quota_fs.h"
+#include "quota_mnt.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#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
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_SYS_FS_TYPES_H   /* Ultrix. */
+#include <sys/fs_types.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
+#include <sys/quota.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/vfs.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
+
+#include "quota_mntopt.h"
+
+/* *** *** ***   local functions   *** *** *** */
+
+/* stolen from quota-3.13 (quota-tools) */
+
+#define PROC_PARTITIONS "/proc/partitions"
+#define DEVLABELDIR     "/dev"
+#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];
+       char *label;
+       char *device;
+} *uuidCache = NULL;
+
+#define EXT2_SUPER_MAGIC 0xEF53
+struct ext2_super_block {
+       unsigned char s_dummy1[56];
+       unsigned char s_magic[2];
+       unsigned char s_dummy2[46];
+       unsigned char s_uuid[16];
+       char s_volume_name[16];
+};
+#define ext2magic(s) ((unsigned int)s.s_magic[0] \
+       + (((unsigned int)s.s_magic[1]) << 8))
+
+#if HAVE_XFS_XQM_H
+struct xfs_super_block {
+       unsigned char s_magic[4];
+       unsigned char s_dummy[28];
+       unsigned char s_uuid[16];
+       unsigned char s_dummy2[60];
+       char s_fsname[12];
+};
+#endif /* HAVE_XFS_XQM_H */
+
+#define REISER_SUPER_MAGIC "ReIsEr2Fs"
+struct reiserfs_super_block {
+       unsigned char s_dummy1[52];
+       unsigned char s_magic[10];
+       unsigned char s_dummy2[22];
+       unsigned char s_uuid[16];
+       char s_volume_name[16];
+};
+
+void
+sstrncpy(char *d, const char *s, int len)
+{
+       strncpy(d, s, len);
+       d[len - 1] = 0;
+}
+
+char *
+sstrdup(const char *s)
+{
+       char *r = strdup(s);
+       if(r == NULL) {
+               DBG("Not enough memory.");
+               exit(3);
+       }
+       return r;
+}
+
+void *
+smalloc(size_t size)
+{
+       void *ret = malloc(size);
+       if(ret == NULL) {
+               DBG("Not enough memory.");
+               exit(3);
+       }
+       return ret;
+}
+
+/* for now, only ext2 and xfs are supported */
+static int
+get_label_uuid(const char *device, char **label, char *uuid)
+{
+       /* start with ext2 and xfs tests, taken from mount_guess_fstype */
+       /* should merge these later */
+       int fd, rv = 1;
+       size_t namesize;
+       struct ext2_super_block e2sb;
+       struct xfs_super_block xfsb;
+       struct reiserfs_super_block reisersb;
+
+       fd = open(device, O_RDONLY);
+       if(fd == -1) {
+               return rv;
+       }
+
+       if(lseek(fd, 1024, SEEK_SET) == 1024
+       && read(fd, (char *)&e2sb, sizeof(e2sb)) == sizeof(e2sb)
+       && ext2magic(e2sb) == EXT2_SUPER_MAGIC) {
+               memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid));
+               namesize = sizeof(e2sb.s_volume_name);
+               *label = smalloc(namesize + 1);
+               sstrncpy(*label, e2sb.s_volume_name, namesize);
+               rv = 0;
+#if HAVE_XFS_XQM_H
+       } else if(lseek(fd, 0, SEEK_SET) == 0
+       && read(fd, (char *)&xfsb, sizeof(xfsb)) == sizeof(xfsb)
+       && (strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC_STR, 4) == 0 ||
+       strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC2_STR, 4) == 0)) {
+               memcpy(uuid, xfsb.s_uuid, sizeof(xfsb.s_uuid));
+               namesize = sizeof(xfsb.s_fsname);
+               *label = smalloc(namesize + 1);
+               sstrncpy(*label, xfsb.s_fsname, namesize);
+               rv = 0;
+#endif /* HAVE_XFS_XQM_H */
+       } else if(lseek(fd, 65536, SEEK_SET) == 65536
+       && read(fd, (char *)&reisersb, sizeof(reisersb)) == sizeof(reisersb)
+       && !strncmp((char *)&reisersb.s_magic, REISER_SUPER_MAGIC, 9)) {
+               memcpy(uuid, reisersb.s_uuid, sizeof(reisersb.s_uuid));
+               namesize = sizeof(reisersb.s_volume_name);
+               *label = smalloc(namesize + 1);
+               sstrncpy(*label, reisersb.s_volume_name, namesize);
+               rv = 0;
+       }
+       close(fd);
+       return rv;
+}
+
+static void
+uuidcache_addentry(char *device, char *label, char *uuid)
+{
+       struct uuidCache_s *last;
+
+       if(!uuidCache) {
+               last = uuidCache = smalloc(sizeof(*uuidCache));
+       } else {
+               for(last = uuidCache; last->next; last = last->next);
+               last->next = smalloc(sizeof(*uuidCache));
+               last = last->next;
+       }
+       last->next = NULL;
+       last->device = device;
+       last->label = label;
+       memcpy(last->uuid, uuid, sizeof(last->uuid));
+}
+
+static void
+uuidcache_init(void)
+{
+       char line[100];
+       char *s;
+       int ma, mi, sz;
+       static char ptname[100];
+       FILE *procpt;
+       char uuid[16], *label = NULL;
+       char device[110];
+       int firstPass;
+       int handleOnFirst;
+
+       if(uuidCache) {
+               return;
+       }
+
+       procpt = fopen(PROC_PARTITIONS, "r");
+       if(procpt == NULL) {
+               return;
+       }
+
+       for(firstPass = 1; firstPass >= 0; firstPass--) {
+               fseek(procpt, 0, SEEK_SET);
+               while(fgets(line, sizeof(line), procpt)) {
+                       if(sscanf(line, " %d %d %d %[^\n ]",
+                               &ma, &mi, &sz, ptname) != 4)
+                       {
+                               continue;
+                       }
+
+                       /* skip extended partitions (heuristic: size 1) */
+                       if(sz == 1) {
+                               continue;
+                       }
+
+                       /* look only at md devices on first pass */
+                       handleOnFirst = !strncmp(ptname, "md", 2);
+                       if(firstPass != handleOnFirst) {
+                               continue;
+                       }
+
+                       /* skip entire disk (minor 0, 64, ... on ide;
+                       0, 16, ... on sd) */
+                       /* heuristic: partition name ends in a digit */
+
+                       for(s = ptname; *s; s++);
+
+                       if(isdigit(s[-1])) {
+                       /*
+                       * Note: this is a heuristic only - there is no reason
+                       * why these devices should live in /dev.
+                       * Perhaps this directory should be specifiable by option.
+                       * One might for example have /devlabel with links to /dev
+                       * for the devices that may be accessed in this way.
+                       * (This is useful, if the cdrom on /dev/hdc must not
+                       * be accessed.)
+                       */
+                               snprintf(device, sizeof(device), "%s/%s",
+                                       DEVLABELDIR, ptname);
+                               if(!get_label_uuid(device, &label, uuid)) {
+                                       uuidcache_addentry(sstrdup(device),
+                                               label, uuid);
+                               }
+                       }
+               }
+       }
+       fclose(procpt);
+}
+
+static unsigned char
+fromhex(char c)
+{
+       if(isdigit(c)) {
+               return (c - '0');
+       } else if(islower(c)) {
+               return (c - 'a' + 10);
+       } else {
+               return (c - 'A' + 10);
+       }
+}
+
+static char *
+get_spec_by_x(int n, const char *t)
+{
+       struct uuidCache_s *uc;
+
+       uuidcache_init();
+       uc = uuidCache;
+
+       while(uc) {
+               switch(n) {
+               case UUID:
+                       if(!memcmp(t, uc->uuid, sizeof(uc->uuid))) {
+                               return sstrdup(uc->device);
+                       }
+                       break;
+               case VOL:
+                       if(!strcmp(t, uc->label)) {
+                               return sstrdup(uc->device);
+                       }
+                       break;
+               }
+               uc = uc->next;
+       }
+       return NULL;
+}
+
+static char *
+get_spec_by_uuid(const char *s)
+{
+       char uuid[16];
+       int i;
+
+       if(strlen(s) != 36
+       || s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') {
+               goto bad_uuid;
+       }
+
+       for(i=0; i<16; i++) {
+               if(*s == '-') {
+                       s++;
+               }
+               if(!isxdigit(s[0]) || !isxdigit(s[1])) {
+                       goto bad_uuid;
+               }
+               uuid[i] = ((fromhex(s[0]) << 4) | fromhex(s[1]));
+               s += 2;
+       }
+       return get_spec_by_x(UUID, uuid);
+
+       bad_uuid:
+               DBG("Found an invalid UUID: %s", s);
+       return NULL;
+}
+
+static char *
+get_spec_by_volume_label(const char *s)
+{
+        return get_spec_by_x(VOL, s);
+}
+
+const char *
+get_device_name(const char *item)
+{
+       const char *rc;
+
+       if(!strncmp(item, "UUID=", 5)) {
+               DBG("TODO: check UUID= code!");
+               rc = get_spec_by_uuid(item + 5);
+       } else if(!strncmp(item, "LABEL=", 6)) {
+               DBG("TODO: check LABEL= code!");
+               rc = get_spec_by_volume_label(item + 6);
+       } else {
+               rc = sstrdup(item);
+       }
+       if(!rc) {
+               DBG("Error checking device name: %s", item);
+       }
+       return rc;
+}
+
+/* Return if given option has nonempty argument */
+char *
+hasmntoptarg(struct mntent *mnt, char *opt)
+{
+       char *p = hasmntopt(mnt, opt);
+
+       if(!p) {
+               return NULL;
+       }
+       p += strlen(opt);
+       if(*p == '=' && p[1] != ',') {
+               return p+1;
+       }
+       return NULL;
+}
+
+/*
+ *      Check whether give filesystem type is supported
+ */
+static int
+correct_fstype(char *type)
+{
+       char *mtype = sstrdup(type), *next;
+
+       type = mtype;
+       do {
+               next = strchr(type, ',');
+               if(next) {
+                       *next = 0;
+               }
+               if(!strcmp(type, MNTTYPE_EXT2)
+               || !strcmp(type, MNTTYPE_EXT3)
+               || !strcmp(type, MNTTYPE_JFS)
+               || !strcmp(type, MNTTYPE_MINIX)
+               || !strcmp(type, MNTTYPE_UFS)
+               || !strcmp(type, MNTTYPE_UDF)
+               || !strcmp(type, MNTTYPE_REISER)
+               || !strcmp(type, MNTTYPE_XFS)
+               || !strcmp(type, MNTTYPE_NFS)
+               || !strcmp(type, MNTTYPE_NFS4))
+               {
+                       free(mtype);
+                       return 1;
+               }
+               type = next+1;
+       } while(next);
+       free(mtype);
+       return 0;
+}
+
+/*
+ *      Check for various kinds of NFS filesystem
+ */
+int
+nfs_fstype(char *type)
+{
+       return !strcmp(type, MNTTYPE_NFS) || !strcmp(type, MNTTYPE_NFS4);
+}
+
+#if HAVE_XFS_XQM_H
+/*
+ *      Check for XFS filesystem with quota accounting enabled
+ */
+static int hasxfsquota(struct mntent *mnt, int type)
+{
+       int ret = 0;
+       u_int16_t sbflags;
+       struct xfs_mem_dqinfo info;
+       const char *dev = get_device_name(mnt->mnt_fsname);
+
+       if(!dev) {
+               return ret;
+       }
+
+       memset(&info, 0, sizeof(struct xfs_mem_dqinfo));
+       if(!quotactl(QCMD(Q_XFS_GETQSTAT, type), dev, 0, (void *)&info)) {
+               sbflags = (info.qs_flags & 0xff00) >> 8;
+               if(type == USRQUOTA && (info.qs_flags & XFS_QUOTA_UDQ_ACCT)) {
+                       ret = 1;
+               } else if(type == GRPQUOTA && (info.qs_flags & XFS_QUOTA_GDQ_ACCT)) {
+                       ret = 1;
+               }
+               #ifdef XFS_ROOTHACK
+               /*
+               * Old XFS filesystems (up to XFS 1.2 / Linux 2.5.47) had a
+               * hack to allow enabling quota on the root filesystem without
+               * having to specify it at mount time.
+               */
+               else if(strcmp(mnt->mnt_dir, "/")) {
+                       ret = 0;
+               } else if(type == USRQUOTA && (sbflags & XFS_QUOTA_UDQ_ACCT)) {
+                       ret = 1;
+               } else if(type == GRPQUOTA && (sbflags & XFS_QUOTA_GDQ_ACCT)) {
+                       ret = 1;
+               #endif /* XFS_ROOTHACK */
+       }
+       free((char *)dev);
+       return ret;
+}
+#endif /* HAVE_XFS_XQM_H */
+
+/*
+ * Check to see if a particular quota is to be enabled (filesystem mounted
+ * with proper option)
+ */
+int
+hasquota(struct mntent *mnt, int type)
+{
+       if(!correct_fstype(mnt->mnt_type) || hasmntopt(mnt, MNTOPT_NOQUOTA)) {
+               return 0;
+       }
+#if HAVE_XFS_XQM_H
+       if(!strcmp(mnt->mnt_type, MNTTYPE_XFS)) {
+               return hasxfsquota(mnt, type);
+       }
+#endif
+       if(nfs_fstype(mnt->mnt_type)) {
+               /* NFS always has quota or better there is
+                  no good way how to detect it */
+               return 1;
+       }
+
+       if((type == USRQUOTA) && (hasmntopt(mnt, MNTOPT_USRQUOTA)
+       || hasmntoptarg(mnt, MNTOPT_USRJQUOTA))) {
+               return 1;
+       }
+       if((type == GRPQUOTA) && (hasmntopt(mnt, MNTOPT_GRPQUOTA)
+       || hasmntoptarg(mnt, MNTOPT_GRPJQUOTA))) {
+               return 1;
+       }
+       if((type == USRQUOTA) && hasmntopt(mnt, MNTOPT_QUOTA)) {
+               return 1;
+       }
+
+       return 0;
+}
+
+/* END stolen from quota-3.13 (quota-tools) */
+
+
+
+#if HAVE_LISTMNTENT
+static void
+quota_mnt_listmntent(struct tabmntent *mntlist, quota_mnt_t **list)
+{
+       struct *p;
+       struct mntent *mnt;
+
+       for(p = mntlist; p; p = p->next) {
+               mnt = p->ment;
+               *list = smalloc(sizeof(quota_mnt_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
+static void
+quota_mnt_getvfsmnt(FILE *mntf, quota_mnt_t **list)
+{
+       DBG("TODO: getvfsmnt");
+       *list = NULL;
+}
+#endif /* HAVE_GETVFSENT */
+
+
+
+#if HAVE_GETMNTENT
+static void
+quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
+{
+       struct mntent *mnt;
+
+       while((mnt = getmntent(mntf)) != NULL) {
+               const char *devname;
+
+#if 0
+               DBG("------------------");
+               DBG("mnt->mnt_fsname %s", mnt->mnt_fsname);
+               DBG("mnt->mnt_dir    %s", mnt->mnt_dir);
+               DBG("mnt->mnt_type   %s", mnt->mnt_type);
+               DBG("mnt->mnt_opts   %s", mnt->mnt_opts);
+               DBG("mnt->mnt_freq   %d", mnt->mnt_freq);
+               DBG("mnt->mnt_passno %d", mnt->mnt_passno);
+#endif
+               if(!(devname = get_device_name(mnt->mnt_fsname))) {
+                       DBG("can't get devicename for fs (%s) %s (%s): ignored",
+                               mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+                       continue;
+               }
+               if(hasmntopt(mnt, MNTOPT_NOQUOTA) != NULL) {
+                       DBG("noquota option on fs (%s) %s (%s): ignored",
+                               mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+                       free((char *)devname);
+                       continue;
+               }
+               if(hasmntopt(mnt, MNTOPT_QUOTA) == NULL
+               && hasmntopt(mnt, MNTOPT_USRQUOTA) == NULL
+               && hasmntopt(mnt, MNTOPT_GRPQUOTA) == NULL
+               && quota_fs_isnfs(mnt->mnt_type) == EXIT_FAILURE)
+               {
+                       DBG("neither quota/usrquota/grpquota option"
+                               " nor nfs fs (%s) %s (%s): ignored",
+                               mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+                       free((char *)devname);
+                       continue;
+               }
+               if(quota_fs_issupported(mnt->mnt_type) == EXIT_FAILURE)
+               {
+                       DBG("unsupportet fs (%s) %s (%s): ignored",
+                               mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+                       free((char *)devname);
+                       continue;
+               }
+#if 0
+               DBG("------------------ OK");
+#endif
+               *list = (quota_mnt_t *)smalloc(sizeof(quota_mnt_t));
+               (*list)->dir = sstrdup(mnt->mnt_dir);
+               (*list)->device = sstrdup(mnt->mnt_fsname);
+               (*list)->opts = QMO_NONE;
+               if(hasmntopt(mnt, MNTOPT_QUOTA) != NULL
+               || hasmntopt(mnt, MNTOPT_USRQUOTA) != NULL) {
+                       (*list)->opts |= QMO_USRQUOTA;
+               }
+               if(hasmntopt(mnt, MNTOPT_GRPQUOTA) != NULL) {
+                       (*list)->opts |= QMO_GRPQUOTA;
+               }
+               (*list)->next = NULL;
+               list = &((*list)->next);
+       } /* while((mnt = getmntent(mntf)) != NULL) */
+}
+#endif /* HAVE_GETMNTENT */
+
+
+
+quota_mnt_t *
+quota_mnt_getlist(quota_mnt_t **list)
+{
+       /* 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! */
+#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
+       {
+       FILE *mntf = NULL;
+       if((mntf = setmntent(_PATH_MOUNTED, "r")) == NULL) {
+               DBG("opening %s failed: %s", _PATH_MOUNTED, strerror(errno));
+#endif
+#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
+       {
+       FILE *mntf = NULL;
+       if((mntf = setmntent(MNT_MNTTAB, "r")) == NULL) {
+               DBG("opening %s failed: %s", MNT_MNTTAB, strerror(errno));
+#endif
+#if HAVE_GETMNTENT && defined(MNTTABNAME)
+       {
+       FILE *mntf = NULL;
+       if((mntf = setmntent(MNTTABNAME, "r")) == NULL) {
+               DBG("opening %s failed: %s", MNTTABNAME, strerror(errno));
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+       {
+       FILE *mntf = NULL;
+       if((mntf = setmntent(_PATH_MNTTAB, "r")) == NULL) {
+               DBG("opening %s failed: %s", _PATH_MNTTAB, strerror(errno));
+#endif
+#if HAVE_GETVFSENT && defined(VFSTAB)
+       {
+       FILE *mntf = NULL;
+       if((mntf = fopen(VFSTAB, "r")) == NULL) {
+               DBG("opening %s failed: %s", VFSTAB, strerror(errno));
+#endif
+#if HAVE_LISTMNTENT
+       {
+       struct tabmntent *mntlist;
+
+       if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) {
+               DBG("calling listmntent() failed: %s", strerror(errno));
+#endif
+               /* give up */
+               DBG("failed get local mountpoints");
+               *list = NULL;
+               return(NULL);
+
+#if HAVE_LISTMNTENT
+       } else { quota_mnt_listmntent(mntlist, list); }
+       freemntlist(mntlist);
+       }
+#endif
+#if HAVE_GETVFSENT && defined(VFSTAB)
+       } else { quota_mnt_getvfsmnt(mntf, list); }
+       (void)fclose(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+       } else { quota_mnt_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(MNTTABNAME)
+       } else { quota_mnt_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
+       } else { quota_mnt_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
+       } else { quota_mnt_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+       return(*list);
+}
+
+void
+quota_mnt_freelist(quota_mnt_t *list)
+{
+       quota_mnt_t *l = list, *p = NULL;
+
+       while(l != NULL) {
+               while(l->next != NULL) {
+                       p = l;
+                       l = l->next;
+               }
+               if(p != NULL) {
+                       p->next = NULL;
+               }
+               free(l->dir);
+               free(l->device);
+               free(l);
+               p = NULL;
+               if(l != list) {
+                       l = list;
+               } else {
+                       l = NULL;
+               }
+       }
+}
+
diff --git a/src/quota_mnt.h b/src/quota_mnt.h
new file mode 100644 (file)
index 0000000..9d98886
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * collectd - src/quota_mnt.h
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_MNT_H
+#define COLLECTD_QUOTA_MNT_H 1
+
+#include "common.h"
+
+#define QMO_NONE     (0)
+#define QMO_USRQUOTA (1)
+#define QMO_GRPQUOTA (2)
+
+typedef struct _quota_mnt_t quota_mnt_t;
+struct _quota_mnt_t {
+       char *dir;
+       char *device;
+       int opts;
+       quota_mnt_t *next;
+};
+
+quota_mnt_t *quota_mnt_getlist(quota_mnt_t **list);
+void quota_mnt_freelist(quota_mnt_t *list);
+
+#endif /* !COLLECTD_QUOTA_MNT_H */
+
diff --git a/src/quota_mntopt.h b/src/quota_mntopt.h
new file mode 100644 (file)
index 0000000..1160f35
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * collectd - src/quota_mntopt.h
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_MNTOPT_H
+#define COLLECTD_QUOTA_MNTOPT_H 1
+
+#include "common.h"
+
+/* filesystem type */
+#ifndef MNTTYPE_AUTOFS
+#define MNTTYPE_AUTOFS          "autofs"   /* Automount mountpoint */
+#endif
+#ifndef MNTTYPE_CAPIFS
+#define MNTTYPE_CAPIFS          "capifs"   /* */
+#endif
+#ifndef MNTTYPE_CRAMFS
+#define MNTTYPE_CRAMFS          "cramfs"   /* */
+#endif
+#ifndef MNTTYPE_DEVPTS
+#define MNTTYPE_DEVPTS          "devpts"   /* */
+#endif
+#ifndef MNTTYPE_EXT2
+#define MNTTYPE_EXT2            "ext2"     /* 2nd Extended file system */
+#endif
+#ifndef MNTTYPE_EXT3
+#define MNTTYPE_EXT3            "ext3"     /* ext2 + journaling */
+#endif
+#ifndef MNTTYPE_FUSE
+#define MNTTYPE_FUSE            "fuse"     /* */
+#endif
+#ifndef MNTTYPE_HSFS
+#define MNTTYPE_HSFS            "hsfs"     /* */
+#endif
+#ifndef MNTTYPE_ISO9660
+#define MNTTYPE_ISO9660         "iso9660"  /* */
+#endif
+#ifndef MNTTYPE_JFS
+#define MNTTYPE_JFS             "jfs"      /* JFS file system */
+#endif
+#ifndef MNTTYPE_MINIX
+#define MNTTYPE_MINIX           "minix"    /* MINIX file system */
+#endif
+#ifndef MNTTYPE_NFS
+#define MNTTYPE_NFS             "nfs"      /* */
+#endif
+#ifndef MNTTYPE_NFS4
+#define MNTTYPE_NFS4            "nfs4"     /* NFSv4 filesystem */
+#endif
+#ifndef MNTTYPE_NTFS
+#define MNTTYPE_NTFS            "ntfs"     /* */
+#endif
+#ifndef MNTTYPE_PROC
+#define MNTTYPE_PROC            "proc"     /* */
+#endif
+#ifndef MNTTYPE_RAMFS
+#define MNTTYPE_RAMFS           "ramfs"    /* */
+#endif
+#ifndef MNTTYPE_ROMFS
+#define MNTTYPE_ROMFS           "romfs"    /* */
+#endif
+#ifndef MNTTYPE_RELAYFS
+#define MNTTYPE_RELAYFS         "relayfs"  /* */
+#endif
+#ifndef MNTTYPE_REISER
+#define MNTTYPE_REISER          "reiserfs" /* Reiser file system */
+#endif
+#ifndef MNTTYPE_SYSFS
+#define MNTTYPE_SYSFS           "sysfs"    /* */
+#endif
+#ifndef MNTTYPE_TMPFS
+#define MNTTYPE_TMPFS           "tmpfs"    /* */
+#endif
+#ifndef MNTTYPE_USBFS
+#define MNTTYPE_USBFS           "usbfs"    /* */
+#endif
+#ifndef MNTTYPE_UDF
+#define MNTTYPE_UDF             "udf"      /* OSTA UDF file system */
+#endif
+#ifndef MNTTYPE_UFS
+#define MNTTYPE_UFS             "ufs"      /* UNIX file system */
+#endif
+#ifndef MNTTYPE_XFS
+#define MNTTYPE_XFS             "xfs"      /* SGI XFS file system */
+#endif
+#ifndef MNTTYPE_VFAT
+#define MNTTYPE_VFAT            "vfat"     /* */
+#endif
+#ifndef MNTTYPE_ZFS
+#define MNTTYPE_ZFS             "zfs"      /* */
+#endif
+
+/* mount options */
+#ifndef MNTOPT_RO
+#define MNTOPT_RO               "ro"            /* */
+#endif
+#ifndef MNTOPT_RQ
+#define MNTOPT_RQ               "rq"            /* */
+#endif
+#ifndef MNTOPT_PUBLIC
+#define MNTOPT_PUBLIC           "public"        /* */
+#endif
+#ifndef MNTOPT_NOQUOTA
+#define MNTOPT_NOQUOTA          "noquota"       /* don't enforce quota */
+#endif
+#ifndef MNTOPT_QUOTA
+#define MNTOPT_QUOTA            "quota"         /* enforce user quota */
+#endif
+#ifndef MNTOPT_USRQUOTA
+#define MNTOPT_USRQUOTA         "usrquota"      /* enforce user quota */
+#endif
+#ifndef MNTOPT_USRJQUOTA
+#define MNTOPT_USRJQUOTA        "usrjquota"     /* enforce user quota */
+#endif
+#ifndef MNTOPT_GRPQUOTA
+#define MNTOPT_GRPQUOTA         "grpquota"      /* enforce group quota */
+#endif
+#ifndef MNTOPT_GRPJQUOTA
+#define MNTOPT_GRPJQUOTA        "grpjquota"     /* enforce group quota */
+#endif
+#ifndef MNTOPT_RSQUASH
+#define MNTOPT_RSQUASH          "rsquash"       /* root as ordinary user */
+#endif
+#ifndef MNTOPT_BIND
+#define MNTOPT_BIND             "bind"          /* binded mount */
+#endif
+#ifndef MNTOPT_LOOP
+#define MNTOPT_LOOP             "loop"          /* loopback mount */
+#endif
+#ifndef MNTOPT_JQFMT
+#define MNTOPT_JQFMT            "jqfmt"         /* journaled quota format */
+#endif
+
+#endif /* !COLLECTD_QUOTA_MNTOPT_H */
+
diff --git a/src/quota_plugin.c b/src/quota_plugin.c
new file mode 100644 (file)
index 0000000..15d772c
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * collectd - src/quota_plugin.c
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "plugin.h"
+
+#include "quota_debug.h"
+#include "quota_mnt.h"
+#include "quota_fs.h"
+#include "quota_plugin.h"
+
+#define MODULE_NAME "quota"
+
+/* *** *** ***   local constants   *** *** *** */
+
+static const char *quota_filename_template = "quota-%s.rrd";
+
+static char *quota_ds_def[] =
+{
+       "DS:blocks:GAUGE:25:0:U",
+       "DS:block_quota:GAUGE:25:-1:U",
+       "DS:block_limit:GAUGE:25:-1:U",
+       "DS:block_grace:GAUGE:25:0:U",
+       "DS:block_timeleft:GAUGE:25:0:U",
+       "DS:inodes:GAUGE:25:0:U",
+       "DS:inode_quota:GAUGE:25:-1:U",
+       "DS:inode_limit:GAUGE:25:-1:U",
+       "DS:inode_grace:GAUGE:25:0:U",
+       "DS:inode_timeleft:GAUGE:25:0:U",
+       NULL
+};
+static const int quota_ds_num = 10;
+
+/* *** *** ***   local functions   *** *** *** */
+
+#define BUFSIZE 1024
+static void
+quota_submit(quota_t *q)
+{
+       char buf[BUFSIZE];
+       int r;
+
+       r = snprintf(buf, BUFSIZE,
+               "%u:%llu:%lld:%lld:%llu:%llu:%llu:%lld:%lld:%llu:%llu",
+                (unsigned int)curtime,
+                q->blocks, q->bquota, q->blimit, q->bgrace, q->btimeleft,
+                q->inodes, q->iquota, q->ilimit, q->igrace, q->itimeleft);
+       if(r < 1 || r >= BUFSIZE) {
+               DBG("failed");
+               return;
+       }
+       plugin_submit(MODULE_NAME, q->name, buf);
+}
+#undef BUFSIZE
+
+/* *** *** ***   local plugin functions   *** *** *** */
+
+static void
+quota_init(void)
+{
+       DBG_INIT("quota debug file opened.");
+}
+
+static void
+quota_read(void)
+{
+       quota_mnt_t *list = NULL, *l = NULL;
+       quota_t q = {
+               name: "test",
+               blocks: 0, bquota: -1, blimit: -1,
+               bgrace: 0, btimeleft: 0,
+               inodes: 0, iquota: -1, ilimit: -1,
+               igrace: 0, itimeleft: 0,
+       };
+
+       l = quota_mnt_getlist(&list);
+       DBG("local mountpoints:");
+       while(l != NULL) {
+               DBG("\tdir: %s", l->dir);
+               DBG("\tdevice: %s", l->device);
+               DBG("\topts: %s (0x%04x)",
+                       (l->opts == QMO_NONE) ? "-"
+                       : (l->opts == QMO_USRQUOTA) ? "USRQUOTA"
+                       : (l->opts == QMO_GRPQUOTA) ? "GRPQUOTA"
+                       : (l->opts == (QMO_USRQUOTA|QMO_GRPQUOTA)) ?
+                               "USRQUOTA GRPQUOTA" : " ??? ",
+                       l->opts);
+               l = l->next;
+               if(l != NULL) {
+                       DBG("\t-- ");
+               }
+       }
+       DBG("\t== ");
+       quota_submit(&q);
+       quota_mnt_freelist(list);
+}
+
+static void
+quota_write(char *host, char *inst, char *val)
+{
+       char file[512];
+       int r;
+
+       r = snprintf(file, 512, quota_filename_template, inst);
+       if(r < 1 || r >= 512) {
+               DBG("failed");
+               return;
+       }
+
+       rrd_update_file(host, file, val, quota_ds_def, quota_ds_num);
+}
+
+/* *** *** ***   global functions   *** *** *** */
+
+void
+module_register(void)
+{
+       plugin_register(MODULE_NAME, quota_init, quota_read, quota_write);
+}
+
diff --git a/src/quota_plugin.h b/src/quota_plugin.h
new file mode 100644 (file)
index 0000000..785a51f
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * collectd - src/quota_plugin.h
+ * Copyright (C) 2005  Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * 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.
+ *
+ * Author:
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_PLUGIN_H
+#define COLLECTD_QUOTA_PLUGIN_H 1
+
+#include "common.h"
+
+typedef struct {
+       char *name;
+       unsigned long long blocks;
+       long long bquota, blimit;
+       unsigned long long bgrace, btimeleft;
+       unsigned long long inodes;
+       long long iquota, ilimit;
+       unsigned long long igrace, itimeleft;
+} quota_t;
+
+void module_register(void);
+
+#endif /* !COLLECTD_QUOTA_PLUGIN_H */
+