* Copyright (C) 2012 Aurelien Rougemont
* Copyright (C) 2013 Xin Li
* Copyright (C) 2014 Marc Fournier
+ * Copyright (C) 2014 Wilfried Goesgens
*
* 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
* Aurelien Rougemont <beorn at gandi.net>
* Xin Li <delphij at FreeBSD.org>
* Marc Fournier <marc.fournier at camptocamp.com>
+ * Wilfried Goesgens <dothebart at citadel.org>
**/
#include "collectd.h"
#include "utils_llist.h"
#define ZOL_ARCSTATS_FILE "/proc/spl/kstat/zfs/arcstats"
-#if !defined(kstat_t)
-typedef void kstat_t;
-static llist_t *zfs_stats = NULL;
-#endif
+typedef llist_t kstat_t;
-static long long get_zfs_value(kstat_t *dummy __attribute__((unused)),
+static long long get_zfs_value(kstat_t *zfs_stats __attribute__((unused)),
char *name)
{
llentry_t *e;
return (-1);
}
- return ((long long int)e->value);
+ return (*(long long int*)e->value);
}
#elif !defined(__FreeBSD__) // Solaris
kstat_t *ksp = NULL;
#if KERNEL_LINUX
- FILE *fh;
-
- char buf[1024];
+ long long int *llvalues = NULL;
+ char file_contents[1024 * 10];
char *fields[3];
int numfields;
+ ssize_t len;
- if ((fh = fopen (ZOL_ARCSTATS_FILE, "r")) == NULL)
- {
- char errbuf[1024];
- ERROR ("zfs_arc plugin: `fopen (%s)' failed: %s",
- ZOL_ARCSTATS_FILE,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
-
- zfs_stats = llist_create ();
- if (zfs_stats == NULL)
+ ksp = llist_create ();
+ if (ksp == NULL)
{
ERROR ("zfs_arc plugin: `llist_create' failed.");
- fclose (fh);
return (-1);
}
- while (fgets (buf, 1024, fh) != NULL)
+ len = read_file_contents (ZOL_ARCSTATS_FILE, file_contents, sizeof(file_contents));
+ if (len > 1)
{
- numfields = strsplit (buf, fields, 4);
- if (numfields != 3)
- continue;
-
- char *llkey;
- long long int llvalue;
-
- llkey = strdup (fields[0]);
- if (llkey == NULL) {
- char errbuf[1024];
- ERROR ("zfs_arc plugin: `strdup' failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- continue;
- }
- llvalue = atoll (fields[2]);
+ int i=0;
+ char *pnl = file_contents;
+ char *pnnl;
+
+ file_contents[len] = '\0';
- llentry_t *e;
- e = llentry_create (llkey, (void *)llvalue);
- if (e == NULL)
+ while (pnl != NULL)
{
- ERROR ("zfs_arc plugin: `llentry_create' failed.");
- free (llkey);
- continue;
+ pnl = strchr(pnl, '\n');
+ i++;
+ if (pnl && (*pnl != '\0'))
+ pnl++;
}
- free (llkey);
-
- llist_append (zfs_stats, e);
- }
-
- if (fclose (fh))
- {
- char errbuf[1024];
- WARNING ("zfs_arc: `fclose' failed: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
+ if (i > 0)
+ {
+ llentry_t *e;
+ llvalues = malloc(sizeof(long long int) * i);
+ int j = 0;
+
+ pnl = file_contents;
+ while (pnl != NULL)
+ {
+ pnnl = strchr(pnl, '\n');
+ if (pnnl != NULL)
+ *pnnl = '\0';
+
+ numfields = strsplit (pnl, fields, 4);
+ if (numfields == 3)
+ {
+ llvalues[j] = atoll (fields[2]);
+
+ e = llentry_create (fields[0], &llvalues[j]);
+ if (e == NULL)
+ {
+ ERROR ("zfs_arc plugin: `llentry_create' failed.");
+ }
+ else
+ {
+ llist_append (ksp, e);
+ }
+ j++;
+ }
+ pnl = pnnl;
+ if (pnl != NULL)
+ pnl ++;
+ }
+ }
}
#elif !defined(__FreeBSD__) // Solaris
za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
#if defined(KERNEL_LINUX)
- if (zfs_stats != NULL)
+ if (llvalues != NULL)
+ {
+ free(llvalues);
+ }
+ if (ksp != NULL)
{
- llist_destroy (zfs_stats);
+ llist_destroy (ksp);
}
#endif