summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ef470bd)
raw | patch | inline | side by side (parent: ef470bd)
author | Sebastian Harl <sh@tokkee.org> | |
Fri, 25 Jan 2013 13:17:46 +0000 (14:17 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Fri, 25 Jan 2013 13:17:46 +0000 (14:17 +0100) |
The plugin now accepts the <VFiler> config block (inside <Host> blocks). This
is treated similar to <Host> blocks (it accepts all the same config options)
and it inherits all connection related settings from the surrounding <Host>
block (which may, however, be overwritten inside the <VFiler> block). However,
all data collecting operations are done in the context of the specified
VFiler®.
is treated similar to <Host> blocks (it accepts all the same config options)
and it inherits all connection related settings from the surrounding <Host>
block (which may, however, be overwritten inside the <VFiler> block). However,
all data collecting operations are done in the context of the specified
VFiler®.
src/collectd.conf.pod | patch | blob | history | |
src/netapp.c | patch | blob | history |
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index 080b253e00fd00bd6e78a4876912a19b616fe6eb..9fac6a6e037c422e72759a41e8ac79e19e4e0bba 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
GetDiskOps true
GetDiskIO true
</System>
+
+ <VFiler vfilerA>
+ Interval 60
+
+ SnapVault true
+ # ...
+ </VFiler>
</Host>
</Plugin>
=item B<Host> I<Name>
A host block defines one NetApp filer. It will appear in collectd with the name
-you specify here which does not have to be its real name nor its hostname.
+you specify here which does not have to be its real name nor its hostname (see
+the B<Address> option below).
+
+=item B<VFiler> I<Name>
+
+A B<VFiler> block may only be used inside a host block. It accepts all the
+same options as the B<Host> block (except for cascaded B<VFiler> blocks) and
+will execute all NetApp API commands in the context of the specified
+VFiler(R). It will appear in collectd with the name you specify here which
+does not have to be its real name. The VFiler name may be specified using the
+B<VFilerName> option. If this is not specified, it will default to the name
+you specify here.
+
+The VFiler block inherits all connection related settings from the surrounding
+B<Host> block (which appear before the B<VFiler> block) but they may be
+overwritten inside the B<VFiler> block.
+
+This feature is useful, for example, when using a VFiler as SnapVault target
+(supported since OnTap 8.1). In that case, the SnapVault statistics are not
+available in the host filer (vfiler0) but only in the respective VFiler
+context.
=item B<Protocol> B<httpd>|B<http>
Type: string
+=item B<VFilerName> I<Name>
+
+The name of the VFiler in which context to execute API commands. If not
+specified, the name provided to the B<VFiler> block will be used instead.
+
+Optional
+
+Type: string
+
+Default: name of the B<VFiler> block
+
+B<Note:> This option may only be used inside B<VFiler> blocks.
+
=item B<Interval> I<Interval>
B<TODO>
diff --git a/src/netapp.c b/src/netapp.c
index f719724524123c80d51d78ad8a08492fc4a20cff..e65ec0e6ee78d390e77832fb9d2f8967bfb8650f 100644 (file)
--- a/src/netapp.c
+++ b/src/netapp.c
int port;
char *username;
char *password;
+ char *vfiler;
cdtime_t interval;
na_server_t *srv;
sfree (hc->host);
sfree (hc->username);
sfree (hc->password);
+ sfree (hc->vfiler);
free_cfg_disk (hc->cfg_disk);
free_cfg_wafl (hc->cfg_wafl);
} /* }}} int cna_config_system */
/* Corresponds to a <Host /> block. */
-static host_config_t *cna_config_host (const oconfig_item_t *ci) /* {{{ */
+static host_config_t *cna_alloc_host (void) /* {{{ */
{
- oconfig_item_t *item;
host_config_t *host;
- int status;
- int i;
-
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
- WARNING("netapp plugin: \"Host\" needs exactly one string argument. Ignoring host block.");
- return 0;
- }
host = malloc(sizeof(*host));
+ if (! host)
+ return (NULL);
memset (host, 0, sizeof (*host));
+
host->name = NULL;
host->protocol = NA_SERVER_TRANSPORT_HTTPS;
host->host = NULL;
host->username = NULL;
host->password = NULL;
+ host->vfiler = NULL;
host->srv = NULL;
host->cfg_wafl = NULL;
host->cfg_disk = NULL;
host->cfg_snapvault = NULL;
host->cfg_system = NULL;
- status = cf_util_get_string (ci, &host->name);
- if (status != 0)
- {
- sfree (host);
+ return (host);
+} /* }}} host_config_t *cna_alloc_host */
+
+static host_config_t *cna_shallow_clone_host (host_config_t *host) /* {{{ */
+{
+ host_config_t *clone;
+
+ if (host == NULL)
return (NULL);
+
+ clone = cna_alloc_host ();
+ if (clone == NULL)
+ return (NULL);
+
+ if (host->name != NULL) {
+ clone->name = strdup (host->name);
+ if (clone->name == NULL) {
+ free_host_config (clone);
+ return NULL;
+ }
+ }
+
+ clone->protocol = host->protocol;
+
+ if (host->host != NULL) {
+ clone->host = strdup (host->host);
+ if (clone->host == NULL) {
+ free_host_config (clone);
+ return NULL;
+ }
+ }
+
+ clone->port = host->port;
+
+ if (host->username != NULL) {
+ clone->username = strdup (host->username);
+ if (clone->username == NULL) {
+ free_host_config (clone);
+ return NULL;
+ }
+ }
+ if (host->password != NULL) {
+ clone->password = strdup (host->password);
+ if (clone->password == NULL) {
+ free_host_config (clone);
+ return NULL;
+ }
+ }
+
+ clone->interval = host->interval;
+
+ return (clone);
+} /* }}} host_config_t *cna_shallow_clone_host */
+
+static int cna_read (user_data_t *ud);
+
+static int cna_register_host (host_config_t *host) /* {{{ */
+{
+ char cb_name[256];
+ struct timespec interval;
+ user_data_t ud;
+
+ if (host->vfiler)
+ ssnprintf (cb_name, sizeof (cb_name), "netapp-%s-%s",
+ host->name, host->vfiler);
+ else
+ ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
+
+ CDTIME_T_TO_TIMESPEC (host->interval, &interval);
+
+ memset (&ud, 0, sizeof (ud));
+ ud.data = host;
+ ud.free_func = (void (*) (void *)) free_host_config;
+
+ plugin_register_complex_read (/* group = */ NULL, cb_name,
+ /* callback = */ cna_read,
+ /* interval = */ (host->interval > 0) ? &interval : NULL,
+ /* user data = */ &ud);
+
+ return (0);
+} /* }}} int cna_register_host */
+
+static int cna_config_host (host_config_t *host, /* {{{ */
+ const oconfig_item_t *ci)
+{
+ oconfig_item_t *item;
+ _Bool is_vfiler = 0;
+ int status;
+ int i;
+
+ if (! strcasecmp (ci->key, "VFiler"))
+ is_vfiler = 1;
+
+ if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
+ WARNING ("netapp plugin: \"%s\" needs exactly one string argument. Ignoring host block.", ci->key);
+ return (1);
}
+ status = cf_util_get_string (ci, &host->name);
+ if (status != 0)
+ return (1);
+
for (i = 0; i < ci->children_num; ++i) {
item = ci->children + i;
} else if (!strcasecmp(item->key, "Protocol")) {
if ((item->values_num != 1) || (item->values[0].type != OCONFIG_TYPE_STRING) || (strcasecmp(item->values[0].value.string, "http") && strcasecmp(item->values[0].value.string, "https"))) {
WARNING("netapp plugin: \"Protocol\" needs to be either \"http\" or \"https\". Ignoring host block \"%s\".", ci->values[0].value.string);
- return 0;
+ return (1);
}
if (!strcasecmp(item->values[0].value.string, "http")) host->protocol = NA_SERVER_TRANSPORT_HTTP;
else host->protocol = NA_SERVER_TRANSPORT_HTTPS;
cna_config_snapvault(host, item);
} else if (!strcasecmp(item->key, "System")) {
cna_config_system(host, item);
+ } else if ((!strcasecmp(item->key, "VFiler")) && (! is_vfiler)) {
+ host_config_t *vfiler;
+
+ vfiler = cna_shallow_clone_host (host);
+ if (! vfiler) {
+ ERROR ("netapp plugin: Failed to allocate host object for vfiler.");
+ continue;
+ }
+
+ if (cna_config_host (vfiler, item)) {
+ free_host_config (vfiler);
+ continue;
+ }
+
+ cna_register_host (vfiler);
+ } else if ((!strcasecmp(item->key, "VFilerName")) && is_vfiler) {
+ status = cf_util_get_string (item, &host->vfiler);
} else {
- WARNING("netapp plugin: Ignoring unknown config option \"%s\" in host block \"%s\".",
- item->key, ci->values[0].value.string);
+ WARNING ("netapp plugin: Ignoring unknown config option \"%s\" in %s block \"%s\".",
+ item->key, is_vfiler ? "vfiler" : "host", ci->values[0].value.string);
}
if (status != 0)
if (host->host == NULL)
host->host = strdup (host->name);
+ if (is_vfiler && (! host->vfiler))
+ host->vfiler = strdup (host->name);
+
if (host->host == NULL)
status = -1;
}
if (status != 0)
- {
- free_host_config (host);
- return (NULL);
- }
+ return status;
- return host;
+ return (0);
} /* }}} host_config_t *cna_config_host */
/*
*/
static int cna_init_host (host_config_t *host) /* {{{ */
{
+ /* Request version 1.1 of the ONTAP API */
+ int major_version = 1, minor_version = 1;
+
if (host == NULL)
return (EINVAL);
if (host->srv != NULL)
return (0);
- /* Request version 1.1 of the ONTAP API */
- host->srv = na_server_open(host->host,
- /* major version = */ 1, /* minor version = */ 1);
+ if (host->vfiler != NULL) /* Request version 1.7 of the ONTAP API */
+ minor_version = 7;
+
+ host->srv = na_server_open (host->host, major_version, minor_version);
if (host->srv == NULL) {
ERROR ("netapp plugin: na_server_open (%s) failed.", host->host);
return (-1);
na_server_adminuser(host->srv, host->username, host->password);
na_server_set_timeout(host->srv, 5 /* seconds */);
+ if (host->vfiler != NULL) {
+ if (! na_server_set_vfiler (host->srv, host->vfiler)) {
+ ERROR ("netapp plugin: Failed to connect to VFiler '%s' on host '%s'.",
+ host->vfiler, host->host);
+ return (-1);
+ }
+ else {
+ INFO ("netapp plugin: Connected to VFiler '%s' on host '%s'.",
+ host->vfiler, host->host);
+ }
+ }
+
return (0);
} /* }}} int cna_init_host */
if (strcasecmp(item->key, "Host") == 0)
{
host_config_t *host;
- char cb_name[256];
- struct timespec interval;
- user_data_t ud;
- host = cna_config_host (item);
- if (host == NULL)
+ host = cna_alloc_host ();
+ if (host == NULL) {
+ ERROR ("netapp plugin: Failed to allocate host object.");
continue;
+ }
- ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
-
- CDTIME_T_TO_TIMESPEC (host->interval, &interval);
-
- memset (&ud, 0, sizeof (ud));
- ud.data = host;
- ud.free_func = (void (*) (void *)) free_host_config;
+ if (cna_config_host (host, item) != 0) {
+ free_host_config (host);
+ continue;
+ }
- plugin_register_complex_read (/* group = */ NULL, cb_name,
- /* callback = */ cna_read,
- /* interval = */ (host->interval > 0) ? &interval : NULL,
- /* user data = */ &ud);
- continue;
+ cna_register_host (host);
}
else /* if (item->key != "Host") */
{