]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
UBI plugin: collect some stats about the UBIFS
authorPierre Lebleu <pme.lebleu@gmail.com>
Thu, 4 Jul 2019 13:58:21 +0000 (15:58 +0200)
committerPierre Lebleu <pme.lebleu@gmail.com>
Thu, 4 Jul 2019 14:15:12 +0000 (16:15 +0200)
UBIFS is a filesystem for unmanaged flash memory devices.
This plugin collects some stats about the UBIFS:
 * bad physical underlying blocks (bad_peb_count)
 * max erase counter value (max_ec)

Makefile.am
configure.ac
src/types.db
src/ubi.c [new file with mode: 0644]

index 9b9698f349a4a859da6f38ca01412b81d7bddbe4..cf3865217af485f796387779da3c81bca2b1f5c8 100644 (file)
@@ -1904,6 +1904,13 @@ turbostat_la_SOURCES = \
 turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
+if BUILD_PLUGIN_UBI
+pkglib_LTLIBRARIES += ubi.la
+ubi_la_SOURCES = src/ubi.c
+ubi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+ubi_la_LIBADD = libignorelist.la
+endif
+
 if BUILD_PLUGIN_UNIXSOCK
 pkglib_LTLIBRARIES += unixsock.la
 unixsock_la_SOURCES = src/unixsock.c
index 2289aa43403ea9127616c29449610fed8be0b3b2..f4e87c83e1ad18acd2e01436bbe3552b38c0171e 100644 (file)
@@ -6420,6 +6420,7 @@ plugin_tcpconns="no"
 plugin_ted="no"
 plugin_thermal="no"
 plugin_turbostat="no"
+plugin_ubi="no"
 plugin_uptime="no"
 plugin_users="no"
 plugin_virt="no"
@@ -6913,6 +6914,7 @@ AC_PLUGIN([thermal],             [$plugin_thermal],           [Linux ACPI therma
 AC_PLUGIN([threshold],           [yes],                       [Threshold checking plugin])
 AC_PLUGIN([tokyotyrant],         [$with_libtokyotyrant],      [TokyoTyrant database statistics])
 AC_PLUGIN([turbostat],           [$plugin_turbostat],         [Advanced statistic on Intel cpu states])
+AC_PLUGIN([ubi],                 [$plugin_ubi],               [UBI statistics])
 AC_PLUGIN([unixsock],            [yes],                       [Unixsock communication plugin])
 AC_PLUGIN([uptime],              [$plugin_uptime],            [Uptime statistics])
 AC_PLUGIN([users],               [$plugin_users],             [User statistics])
@@ -7341,6 +7343,7 @@ AC_MSG_RESULT([    thermal . . . . . . . $enable_thermal])
 AC_MSG_RESULT([    threshold . . . . . . $enable_threshold])
 AC_MSG_RESULT([    tokyotyrant . . . . . $enable_tokyotyrant])
 AC_MSG_RESULT([    turbostat . . . . . . $enable_turbostat])
+AC_MSG_RESULT([    ubi . . . . . . . . . $enable_ubi])
 AC_MSG_RESULT([    unixsock  . . . . . . $enable_unixsock])
 AC_MSG_RESULT([    uptime  . . . . . . . $enable_uptime])
 AC_MSG_RESULT([    users . . . . . . . . $enable_users])
index 69f59b06595fab9d40ec5a4abe80d4bb21e2306a..82b284d46f13d85a089109545b93f9a5a04ca16a 100644 (file)
@@ -7,6 +7,7 @@ apache_scoreboard       value:GAUGE:0:65535
 ath_nodes               value:GAUGE:0:65535
 ath_stat                value:DERIVE:0:U
 backends                value:GAUGE:0:65535
+bad_peb_count           value:COUNTER:0:U
 bitrate                 value:GAUGE:0:4294967295
 blocked_clients         value:GAUGE:0:U
 bucket                  value:GAUGE:0:U
@@ -134,6 +135,7 @@ job_stats               value:DERIVE:0:U
 latency                 value:GAUGE:0:U
 links                   value:GAUGE:0:U
 load                    shortterm:GAUGE:0:5000, midterm:GAUGE:0:5000, longterm:GAUGE:0:5000
+max_ec                  value:COUNTER:0:U
 memory_bandwidth        value:DERIVE:0:U
 md_disks                value:GAUGE:0:U
 memcached_command       value:DERIVE:0:U
diff --git a/src/ubi.c b/src/ubi.c
new file mode 100644 (file)
index 0000000..4dd0716
--- /dev/null
+++ b/src/ubi.c
@@ -0,0 +1,156 @@
+/**
+ * collectd - src/ubi.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "collectd.h"
+
+#include "plugin.h"
+#include "utils/common/common.h"
+#include "utils/ignorelist/ignorelist.h"
+
+#if !KERNEL_LINUX
+#error "No applicable input method."
+#endif
+
+#define PLUGIN_NAME    "ubi"
+
+#define SYS_PATH       "/sys/class/ubi/"
+
+/*
+ * Device attributes
+ */
+#define DEV_BAD_COUNT  "bad_peb_count" // Count of bad physical eraseblocks on the underlying MTD device.
+#define MAXIMUM_ERASE  "max_ec"        // Current maximum erase counter value
+
+/*
+ * The config key strings
+ */
+#define DEVICE_KEY     "Device"
+#define IGNORE_KEY     "IgnoreSelected"
+
+static const char *config_keys[] =
+{
+       DEVICE_KEY,
+       IGNORE_KEY,
+};
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+static ignorelist_t    *ignorelist = NULL;
+
+/*
+ * Private functions
+ */
+static int ubi_config(const char *key, const char *value)
+{
+       if ( ignorelist == NULL &&
+               (ignorelist = ignorelist_create(/* invert = */ 1)) == NULL )
+               return -1;
+
+       if ( strcasecmp(key, DEVICE_KEY) == 0 )
+               ignorelist_add(ignorelist, value);
+       else if ( strcasecmp(key, IGNORE_KEY) == 0 )
+               ignorelist_set_invert(ignorelist, IS_TRUE(value) ? 0 : 1);
+       else
+               return -1;
+
+       return 0;
+} /* int ubi_config */
+
+static void ubi_submit(const char *dev_name, const char *type, counter_t value)
+{
+       value_list_t vl = VALUE_LIST_INIT;
+
+       if (ignorelist_match(ignorelist, dev_name) != 0)
+               return;
+
+       vl.values = &(value_t){.counter = value};
+       vl.values_len = 1;
+       sstrncpy(vl.plugin, PLUGIN_NAME, sizeof(vl.plugin));
+       sstrncpy(vl.type_instance, dev_name, sizeof(vl.type_instance));
+       sstrncpy(vl.type, type, sizeof(vl.type));
+
+       plugin_dispatch_values(&vl);
+} /* void ubi_submit */
+
+static int ubi_read_dev_attr(const char *dev_name, const char *attr)
+{
+       FILE    *f;
+       int     val;
+       char    str[sizeof(SYS_PATH) + strlen(dev_name) + sizeof("/") + strlen(attr) + 1];
+       int     n;
+
+       snprintf(str, sizeof(str), SYS_PATH "%s/%s", dev_name, attr);
+
+       if ( (f = fopen(str, "r")) == NULL )
+       {
+               ERROR(PLUGIN_NAME ": cannot open [%s]", str);
+               return -1;
+       }
+
+       n = fscanf(f, "%d", &val);
+       fclose(f);
+
+       if ( n != 1 )
+       {
+               ERROR(PLUGIN_NAME " : did not find an integer in %s", str);
+               return -1;
+       }
+
+       ubi_submit(dev_name, attr, (counter_t)val);
+
+       return 0;
+} /* int ubi_read_dev_attr */
+
+static inline int ubi_read_dev_bad_count(const char *dev_name)
+{
+       return ubi_read_dev_attr(dev_name, DEV_BAD_COUNT);
+} /* int ubi_read_dev_bad_count */
+
+static inline int ubi_read_max_ec(const char *dev_name)
+{
+       return ubi_read_dev_attr(dev_name, MAXIMUM_ERASE);
+} /* int ubi_read_max_ec */
+
+static int ubi_read(void)
+{
+       DIR             *dir;
+       struct dirent   *dirent;
+
+       if ( (dir = opendir(SYS_PATH)) == NULL )
+       {
+               ERROR(PLUGIN_NAME " : cannot open dir " SYS_PATH);
+               return -1;
+       }
+
+       while ( (dirent = readdir(dir)) != NULL )
+       {
+               if ( ignorelist_match(ignorelist, dirent->d_name) )
+                       continue;
+
+               ubi_read_dev_bad_count(dirent->d_name);
+               ubi_read_max_ec(dirent->d_name);
+       }
+
+       closedir(dir);
+
+       return 0;
+} /* int ubi_read */
+
+void module_register(void)
+{
+       plugin_register_config(PLUGIN_NAME, ubi_config, config_keys, config_keys_num);
+       plugin_register_read(PLUGIN_NAME, ubi_read);
+} /* void module_register */