df plugin: Implement the "ReportReserved" option.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 2 Oct 2009 09:29:44 +0000 (11:29 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 2 Oct 2009 09:29:44 +0000 (11:29 +0200)
When enabled, the reserved space is reported separately. The "df_complex"
type is used and the mount point or device name is used as plugin instance
(as it should be) instead of the type instance (which is now needed for
"free", "reserved" and "used").

The INode handling has been split up in the same manner.

src/collectd.conf.pod
src/df.c
src/types.db

index f7531cd..7a64189 100644 (file)
@@ -870,19 +870,35 @@ Select partitions based on the mountpoint.
 
 Select partitions based on the filesystem type.
 
-=item B<IgnoreSelected> I<true>|I<false>
+=item B<IgnoreSelected> B<true>|B<false>
 
 Invert the selection: If set to true, all partitions B<except> the ones that
 match any one of the criteria are collected. By default only selected
 partitions are collected if a selection is made. If no selection is configured
 at all, B<all> partitions are selected.
 
-=item B<ReportByDevice> I<true>|I<false>
+=item B<ReportByDevice> B<true>|B<false>
 
 Report using the device name rather than the mountpoint. i.e. with this I<false>,
 (the default), it will report a disk as "root", but with it I<true>, it will be
 "sda1" (or whichever).
 
+=item B<ReportReserved> B<true>|B<false>
+
+When enabled, the blocks reserved for root are reported separately. When
+disabled (the default for backwards compatibility reasons) the reserved space
+will be included in the "free" space.
+
+When disabled, the "df" type will be used to store "free" and "used" space. The
+mount point or disk name (see option B<ReportByDevice>) is used as type
+instance in this case (again: backwards compatibility).
+
+When enabled, the type "df_complex" is used and three files are created. The
+mount point or disk name is used as plugin instance and the type instance is
+set to "free", "reserved" and "used" as appropriate.
+
+Enabling this option is recommended.
+
 =back
 
 =head2 Plugin C<disk>
index 0cc782a..66daab2 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -50,7 +50,8 @@ static const char *config_keys[] =
        "MountPoint",
        "FSType",
        "IgnoreSelected",
-        "ReportByDevice"
+       "ReportByDevice",
+       "ReportReserved"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
@@ -59,6 +60,7 @@ static ignorelist_t *il_mountpoint = NULL;
 static ignorelist_t *il_fstype = NULL;
 
 static _Bool by_device = false;
+static _Bool report_reserved = false;
 
 static int df_init (void)
 {
@@ -117,11 +119,21 @@ static int df_config (const char *key, const char *value)
 
                return (0);
        }
+       else if (strcasecmp (key, "ReportReserved") == 0)
+       {
+               if (IS_TRUE (value))
+                       report_reserved = true;
+               else
+                       report_reserved = false;
+
+               return (0);
+       }
+
 
        return (-1);
 }
 
-static void df_submit (char *df_name,
+static void df_submit_two (char *df_name,
                const char *type,
                gauge_t df_used,
                gauge_t df_free)
@@ -141,7 +153,32 @@ static void df_submit (char *df_name,
        sstrncpy (vl.type_instance, df_name, sizeof (vl.type_instance));
 
        plugin_dispatch_values (&vl);
-} /* void df_submit */
+} /* void df_submit_two */
+
+__attribute__ ((nonnull(2)))
+static void df_submit_one (char *plugin_instance,
+               const char *type, const char *type_instance,
+               gauge_t value)
+{
+       value_t values[1];
+       value_list_t vl = VALUE_LIST_INIT;
+
+       values[0].gauge = value;
+
+       vl.values = values;
+       vl.values_len = 1;
+       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+       sstrncpy (vl.plugin, "df", sizeof (vl.plugin));
+       if (plugin_instance != NULL)
+               sstrncpy (vl.plugin_instance, plugin_instance,
+                               sizeof (vl.plugin_instance));
+       sstrncpy (vl.type, type, sizeof (vl.type));
+       if (type_instance != NULL)
+               sstrncpy (vl.type_instance, type_instance,
+                               sizeof (vl.type_instance));
+
+       plugin_dispatch_values (&vl);
+} /* void df_submit_one */
 
 static int df_read (void)
 {
@@ -154,19 +191,15 @@ static int df_read (void)
        cu_mount_t *mnt_list;
        cu_mount_t *mnt_ptr;
 
-       unsigned long long blocksize;
-       gauge_t df_free;
-       gauge_t df_used;
-       gauge_t df_inodes_free;
-       gauge_t df_inodes_used;
-       char disk_name[256];
-
        mnt_list = NULL;
        if (cu_mount_getlist (&mnt_list) == NULL)
                return (-1);
 
        for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next)
        {
+               unsigned long long blocksize;
+               char disk_name[256];
+
                if (ignorelist_match (il_device,
                                        (mnt_ptr->spec_device != NULL)
                                        ? mnt_ptr->spec_device
@@ -189,13 +222,6 @@ static int df_read (void)
                if (!statbuf.f_blocks)
                        continue;
 
-               blocksize = BLOCKSIZE(statbuf);
-               df_free = statbuf.f_bfree * blocksize;
-               df_used = (statbuf.f_blocks - statbuf.f_bfree) * blocksize;
-
-               df_inodes_used = statbuf.f_files - statbuf.f_ffree;
-               df_inodes_free = statbuf.f_ffree;
-
                if (by_device) 
                {
                        /* eg, /dev/hda1  -- strip off the "/dev/" */
@@ -229,8 +255,65 @@ static int df_read (void)
                        }
                }
 
-               df_submit (disk_name, "df", df_used, df_free);
-               df_submit (disk_name, "df_inodes", df_inodes_used, df_inodes_free);
+               blocksize = BLOCKSIZE(statbuf);
+
+               if (report_reserved)
+               {
+                       uint64_t blk_free;
+                       uint64_t blk_reserved;
+                       uint64_t blk_used;
+
+                       /* Sanity-check for the values in the struct */
+                       if (statbuf.f_bfree < statbuf.f_bavail)
+                               statbuf.f_bfree = statbuf.f_bavail;
+                       if (statbuf.f_blocks < statbuf.f_bfree)
+                               statbuf.f_blocks = statbuf.f_bfree;
+
+                       blk_free = (uint64_t) statbuf.f_bavail;
+                       blk_reserved = (uint64_t) (statbuf.f_bfree - statbuf.f_bavail);
+                       blk_used = (uint64_t) (statbuf.f_blocks - statbuf.f_bfree);
+                       
+                       df_submit_one (disk_name, "df_complex", "free",
+                                       (gauge_t) (blk_free * blocksize));
+                       df_submit_one (disk_name, "df_complex", "reserved",
+                                       (gauge_t) (blk_reserved * blocksize));
+                       df_submit_one (disk_name, "df_complex", "used",
+                                       (gauge_t) (blk_used * blocksize));
+               }
+               else /* compatibility code */
+               {
+                       gauge_t df_free;
+                       gauge_t df_used;
+
+                       df_free = statbuf.f_bfree * blocksize;
+                       df_used = (statbuf.f_blocks - statbuf.f_bfree) * blocksize;
+
+                       df_submit_two (disk_name, "df", df_used, df_free);
+               }
+
+               /* inode handling */
+               {
+                       uint64_t inode_free;
+                       uint64_t inode_reserved;
+                       uint64_t inode_used;
+
+                       /* Sanity-check for the values in the struct */
+                       if (statbuf.f_ffree < statbuf.f_favail)
+                               statbuf.f_ffree = statbuf.f_favail;
+                       if (statbuf.f_files < statbuf.f_ffree)
+                               statbuf.f_files = statbuf.f_ffree;
+
+                       inode_free = (uint64_t) statbuf.f_favail;
+                       inode_reserved = (uint64_t) (statbuf.f_ffree - statbuf.f_favail);
+                       inode_used = (uint64_t) (statbuf.f_files - statbuf.f_ffree);
+                       
+                       df_submit_one (disk_name, "df_inodes", "free",
+                                       (gauge_t) inode_free);
+                       df_submit_one (disk_name, "df_inodes", "reserved",
+                                       (gauge_t) inode_reserved);
+                       df_submit_one (disk_name, "df_inodes", "used",
+                                       (gauge_t) inode_used);
+               }
        }
 
        cu_mount_freelist (mnt_list);
index 0cbd403..64c99e8 100644 (file)
@@ -28,7 +28,7 @@ delay                 seconds:GAUGE:-1000000:1000000
 derive                 value:DERIVE:0:U
 df                     used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
 df_complex             value:GAUGE:0:U
-df_inodes              used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
+df_inodes              value:GAUGE:0:U
 disk_latency           read:GAUGE:0:U, write:GAUGE:0:U
 disk_merged            read:COUNTER:0:4294967295, write:COUNTER:0:4294967295
 disk_octets            read:COUNTER:0:17179869183, write:COUNTER:0:17179869183