/**
* collectd - src/gmond.c
- * Copyright (C) 2009,2010 Florian octo Forster
+ * Copyright (C) 2009-2015 Florian octo Forster
*
- * 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.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
*
- * 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.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * 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
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
* Authors:
* Florian octo Forster <octo at collectd.org>
#if HAVE_PTHREAD_H
# include <pthread.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
struct metric_map_s
{
- char *ganglia_name;
- char *type;
- char *type_instance;
- char *ds_name;
- int ds_type;
- int ds_index;
+ char *ganglia_name;
+ char *type;
+ char *type_instance;
+ char *ds_name;
+ int ds_type;
+ size_t ds_index;
};
typedef struct metric_map_s metric_map_t;
return (NULL);
/* Look up the DS type and ds_index. */
- if ((map[i].ds_type < 0) || (map[i].ds_index < 0)) /* {{{ */
+ if (map[i].ds_type < 0) /* {{{ */
{
const data_set_t *ds;
}
else
{
- int j;
+ size_t j;
for (j = 0; j < ds->ds_num; j++)
if (strcasecmp (ds->ds[j].name, map[i].ds_name) == 0)
}
loop = 1;
- setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP,
(void *) &loop, sizeof (loop));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
memset (&mreq, 0, sizeof (mreq));
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_interface.s_addr = htonl (INADDR_ANY);
- setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(void *) &mreq, sizeof (mreq));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
} /* if (ai_ptr->ai_family == AF_INET) */
else if (ai_ptr->ai_family == AF_INET6)
{
}
loop = 1;
- setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
(void *) &loop, sizeof (loop));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
memset (&mreq, 0, sizeof (mreq));
memcpy (&mreq.ipv6mr_multiaddr,
&addr->sin6_addr, sizeof (addr->sin6_addr));
mreq.ipv6mr_interface = 0; /* any */
- setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(void *) &mreq, sizeof (mreq));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
} /* if (ai_ptr->ai_family == AF_INET6) */
sockets_num++;
pthread_mutex_lock (&mc_send_sockets_lock);
for (i = 0; i < mc_send_sockets_num; i++)
- sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
+ {
+ ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
/* flags = */ 0,
(struct sockaddr *) &mc_send_sockets[i].addr,
mc_send_sockets[i].addrlen);
+ if (status == -1)
+ {
+ char errbuf[1024];
+ ERROR ("gmond plugin: sendto(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ continue;
+ }
+ }
pthread_mutex_unlock (&mc_send_sockets_lock);
sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
return (se);
/* insert new entry */
- se = (staging_entry_t *) malloc (sizeof (*se));
+ se = calloc (1, sizeof (*se));
if (se == NULL)
return (NULL);
- memset (se, 0, sizeof (*se));
sstrncpy (se->key, key, sizeof (se->key));
se->flags = 0;
return (se);
} /* }}} staging_entry_t *staging_entry_get */
-static int staging_entry_submit (const char *host, const char *name, /* {{{ */
- staging_entry_t *se)
-{
- value_list_t vl;
- value_t values[se->vl.values_len];
-
- if (se->vl.interval == 0)
- {
- /* No meta data has been received for this metric yet. */
- se->flags = 0;
- pthread_mutex_unlock (&staging_lock);
- request_meta_data (host, name);
- return (0);
- }
-
- se->flags = 0;
-
- memcpy (values, se->vl.values, sizeof (values));
- memcpy (&vl, &se->vl, sizeof (vl));
-
- /* Unlock before calling `plugin_dispatch_values'.. */
- pthread_mutex_unlock (&staging_lock);
-
- vl.values = values;
-
- plugin_dispatch_values (&vl);
-
- return (0);
-} /* }}} int staging_entry_submit */
-
static int staging_entry_update (const char *host, const char *name, /* {{{ */
const char *type, const char *type_instance,
- int ds_index, int ds_type, value_t value)
+ size_t ds_index, int ds_type, value_t value)
{
const data_set_t *ds;
staging_entry_t *se;
if (ds->ds_num <= ds_index)
{
- ERROR ("gmond plugin: Invalid index %i: %s has only %i data source(s).",
+ ERROR ("gmond plugin: Invalid index %zu: %s has only %zu data source(s).",
ds_index, ds->type, ds->ds_num);
return (-1);
}
se->flags |= (0x01 << ds_index);
- /* Check if all values have been set and submit if so. */
- if (se->flags == ((0x01 << se->vl.values_len) - 1))
+ /* Check if all data sources have been set. If not, return here. */
+ if (se->flags != ((0x01 << se->vl.values_len) - 1))
{
- /* `staging_lock' is unlocked in `staging_entry_submit'. */
- staging_entry_submit (host, name, se);
+ pthread_mutex_unlock (&staging_lock);
+ return (0);
}
- else
+
+ /* Check if the interval of this metric is known. If not, request meta data
+ * and return. */
+ if (se->vl.interval == 0)
{
+ /* No meta data has been received for this metric yet. */
+ se->flags = 0;
pthread_mutex_unlock (&staging_lock);
+
+ request_meta_data (host, name);
+ return (0);
}
+ plugin_dispatch_values (&se->vl);
+
+ se->flags = 0;
+ pthread_mutex_unlock (&staging_lock);
+
return (0);
} /* }}} int staging_entry_update */
return (0);
} /* }}} int mc_receive_thread_stop */
-/*
+/*
* Config:
*
* <Plugin gmond>