From 0a73779531039d715e8ca405658c65ba03fad408 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Fri, 2 Oct 2009 11:29:44 +0200 Subject: [PATCH] df plugin: Implement the "ReportReserved" option. 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 | 20 ++++++- src/df.c | 121 +++++++++++++++++++++++++++++++++++------- src/types.db | 2 +- 3 files changed, 121 insertions(+), 22 deletions(-) diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index f7531cd8..7a641895 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -870,19 +870,35 @@ Select partitions based on the mountpoint. Select partitions based on the filesystem type. -=item B I|I +=item B B|B Invert the selection: If set to true, all partitions B 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 partitions are selected. -=item B I|I +=item B B|B Report using the device name rather than the mountpoint. i.e. with this I, (the default), it will report a disk as "root", but with it I, it will be "sda1" (or whichever). +=item B B|B + +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) 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 diff --git a/src/df.c b/src/df.c index 0cc782ad..66daab26 100644 --- 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); diff --git a/src/types.db b/src/types.db index 0cbd4032..64c99e8e 100644 --- a/src/types.db +++ b/src/types.db @@ -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 -- 2.30.2