**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#define MODULE_NAME "tape"
-
-#if defined(HAVE_LIBKSTAT)
-# define TAPE_HAVE_READ 1
-#else
-# define TAPE_HAVE_READ 0
+#if !HAVE_LIBKSTAT
+#error "No applicable input method."
#endif
-static char *tape_filename_template = "tape-%s.rrd";
-
-/* 104857600 == 100 MB */
-static char *tape_ds_def[] =
-{
- "DS:rcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:rmerged:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:rbytes:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:rtime:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:wcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:wmerged:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:wbytes:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- "DS:wtime:COUNTER:"COLLECTD_HEARTBEAT":0:U",
- NULL
-};
-static int tape_ds_num = 8;
-
-#if defined(HAVE_LIBKSTAT)
#define MAX_NUMTAPE 256
extern kstat_ctl_t *kc;
static kstat_t *ksp[MAX_NUMTAPE];
static int numtape = 0;
-#endif /* HAVE_LIBKSTAT */
-
-static void tape_init (void)
-{
-#ifdef HAVE_LIBKSTAT
- kstat_t *ksp_chain;
-
- numtape = 0;
-
- if (kc == NULL)
- return;
-
- for (numtape = 0, ksp_chain = kc->kc_chain;
- (numtape < MAX_NUMTAPE) && (ksp_chain != NULL);
- ksp_chain = ksp_chain->ks_next)
- {
- if (strncmp (ksp_chain->ks_class, "tape", 4) )
- continue;
- if (ksp_chain->ks_type != KSTAT_TYPE_IO)
- continue;
- ksp[numtape++] = ksp_chain;
- }
-#endif
- return;
-}
-
-static void tape_write (char *host, char *inst, char *val)
-{
- char file[512];
- int status;
-
- status = snprintf (file, 512, tape_filename_template, inst);
- if (status < 1)
- return;
- else if (status >= 512)
- return;
-
- rrd_update_file (host, file, val, tape_ds_def, tape_ds_num);
-}
-
-
-#if TAPE_HAVE_READ
-#define BUFSIZE 512
-static void tape_submit (char *tape_name,
- unsigned long long read_count,
- unsigned long long read_merged,
- unsigned long long read_bytes,
- unsigned long long read_time,
- unsigned long long write_count,
- unsigned long long write_merged,
- unsigned long long write_bytes,
- unsigned long long write_time)
-
-{
- char buf[BUFSIZE];
-
- if (snprintf (buf, BUFSIZE, "%u:%llu:%llu:%llu:%llu:%llu:%llu:%llu:%llu",
- (unsigned int) curtime,
- read_count, read_merged, read_bytes, read_time,
- write_count, write_merged, write_bytes,
- write_time) >= BUFSIZE)
- return;
-
- plugin_submit (MODULE_NAME, tape_name, buf);
-}
-
-#undef BUFSIZE
+static int tape_init(void) {
+ kstat_t *ksp_chain;
+
+ numtape = 0;
+
+ if (kc == NULL)
+ return (-1);
+
+ for (numtape = 0, ksp_chain = kc->kc_chain;
+ (numtape < MAX_NUMTAPE) && (ksp_chain != NULL);
+ ksp_chain = ksp_chain->ks_next) {
+ if (strncmp(ksp_chain->ks_class, "tape", 4))
+ continue;
+ if (ksp_chain->ks_type != KSTAT_TYPE_IO)
+ continue;
+ ksp[numtape++] = ksp_chain;
+ }
+
+ return (0);
+} /* int tape_init */
+
+static void tape_submit(const char *plugin_instance, const char *type,
+ derive_t read, derive_t write) {
+ value_list_t vl = VALUE_LIST_INIT;
+ value_t values[] = {
+ {.derive = read}, {.derive = write},
+ };
+
+ vl.values = values;
+ vl.values_len = STATIC_ARRAY_SIZE(values);
+ sstrncpy(vl.plugin, "tape", sizeof(vl.plugin));
+ sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
+ sstrncpy(vl.type, type, sizeof(vl.type));
+
+ plugin_dispatch_values(&vl);
+} /* void tape_submit */
+
+static int tape_read(void) {
+
+#if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME
+#define KIO_ROCTETS reads
+#define KIO_WOCTETS writes
+#define KIO_ROPS nreads
+#define KIO_WOPS nwrites
+#define KIO_RTIME rtime
+#define KIO_WTIME wtime
+#elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && \
+ HAVE_KSTAT_IO_T_WTIME
+#define KIO_ROCTETS nread
+#define KIO_WOCTETS nwritten
+#define KIO_ROPS reads
+#define KIO_WOPS writes
+#define KIO_RTIME rtime
+#define KIO_WTIME wtime
+#else
+#error "kstat_io_t does not have the required members"
+#endif
+ static kstat_io_t kio;
-static void tape_read (void)
-{
+ if (kc == NULL)
+ return (-1);
-#if defined(HAVE_LIBKSTAT)
- static kstat_io_t kio;
- int i;
+ if (numtape <= 0)
+ return (-1);
- if (kc == NULL)
- return;
+ for (int i = 0; i < numtape; i++) {
+ if (kstat_read(kc, ksp[i], &kio) == -1)
+ continue;
- for (i = 0; i < numtape; i++)
- {
- if (kstat_read (kc, ksp[i], &kio) == -1)
- continue;
+ if (strncmp(ksp[i]->ks_class, "tape", 4) == 0) {
+ tape_submit(ksp[i]->ks_name, "tape_octets", kio.KIO_ROCTETS,
+ kio.KIO_WOCTETS);
+ tape_submit(ksp[i]->ks_name, "tape_ops", kio.KIO_ROPS, kio.KIO_WOPS);
+ /* FIXME: Convert this to microseconds if necessary */
+ tape_submit(ksp[i]->ks_name, "tape_time", kio.KIO_RTIME, kio.KIO_WTIME);
+ }
+ }
- if (strncmp (ksp[i]->ks_class, "tape", 4) == 0)
- tape_submit (ksp[i]->ks_name,
- kio.reads, 0LL, kio.nread, kio.rtime,
- kio.writes, 0LL, kio.nwritten, kio.wtime);
- }
-#endif /* defined(HAVE_LIBKSTAT) */
+ return (0);
}
-#else
-# define tape_read NULL
-#endif /* TAPE_HAVE_READ */
-void module_register (void)
-{
- plugin_register (MODULE_NAME, tape_init, tape_read, tape_write);
+void module_register(void) {
+ plugin_register_init("tape", tape_init);
+ plugin_register_read("tape", tape_read);
}
-
-#undef MODULE_NAME