예제 #1
0
파일: gmond.c 프로젝트: beorn-/collectd
static int request_meta_data (const char *host, const char *name) /* {{{ */
{
  Ganglia_metadata_msg msg;
  char buffer[BUFF_SIZE];
  unsigned int buffer_size;
  XDR xdr;
  size_t i;

  memset (&msg, 0, sizeof (msg));

  msg.id = gmetadata_request;
  msg.Ganglia_metadata_msg_u.grequest.metric_id.host = strdup (host);
  msg.Ganglia_metadata_msg_u.grequest.metric_id.name = strdup (name);

  if ((msg.Ganglia_metadata_msg_u.grequest.metric_id.host == NULL)
      || (msg.Ganglia_metadata_msg_u.grequest.metric_id.name == NULL))
  {
    sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
    sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
    return (-1);
  }

  memset (buffer, 0, sizeof (buffer));
  xdrmem_create (&xdr, buffer, sizeof (buffer), XDR_ENCODE);

  if (!xdr_Ganglia_metadata_msg (&xdr, &msg))
  {
    sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
    sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
    return (-1);
  }

  buffer_size = xdr_getpos (&xdr);

  DEBUG ("gmond plugin: Requesting meta data for %s/%s.",
      host, name);

  pthread_mutex_lock (&mc_send_sockets_lock);
  for (i = 0; i < mc_send_sockets_num; i++)
  {
    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);
  sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
  return (0);
} /* }}} int request_meta_data */
예제 #2
0
파일: gmond.c 프로젝트: beorn-/collectd
static int mc_handle_metric (void *buffer, size_t buffer_size) /* {{{ */
{
  XDR xdr;
  Ganglia_msg_formats format;

  xdrmem_create (&xdr, buffer, buffer_size, XDR_DECODE);

  xdr_Ganglia_msg_formats (&xdr, &format);
  xdr_setpos (&xdr, 0);

  switch (format)
  {
    case gmetric_ushort:
    case gmetric_short:
    case gmetric_int:
    case gmetric_uint:
    case gmetric_string:
    case gmetric_float:
    case gmetric_double:
    {
      Ganglia_value_msg msg;

      memset (&msg, 0, sizeof (msg));
      if (xdr_Ganglia_value_msg (&xdr, &msg))
        mc_handle_value_msg (&msg);
      break;
    }

    case gmetadata_full:
    case gmetadata_request:
    {
      Ganglia_metadata_msg msg;
      memset (&msg, 0, sizeof (msg));
      if (xdr_Ganglia_metadata_msg (&xdr, &msg))
        mc_handle_metadata_msg (&msg);
      break;
    }

    default:
      DEBUG ("gmond plugin: Unknown format: %i", format);
      return (-1);
  } /* switch (format) */


  return (0);
} /* }}} int mc_handle_metric */
예제 #3
0
int
Ganglia_metadata_send_real( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels, char *override_string )
{
  int len, i;
  XDR x;
  char gmetricmsg[GANGLIA_MAX_MESSAGE_LEN];
  Ganglia_metadata_msg msg;
  const apr_array_header_t *arr;
  const apr_table_entry_t *elts;
  const char *spoof = SPOOF;
  apr_pool_t *gm_pool=(apr_pool_t*)gmetric->pool;

  if (myhost[0] == '\0') 
      apr_gethostname( (char*)myhost, APRMAXHOSTLEN+1, gm_pool);

  msg.id = gmetadata_full;
  memcpy( &(msg.Ganglia_metadata_msg_u.gfull.metric), gmetric->msg, sizeof(Ganglia_metadata_message));
  msg.Ganglia_metadata_msg_u.gfull.metric_id.name = apr_pstrdup (gm_pool, gmetric->msg->name);
  debug_msg("  msg.Ganglia_metadata_msg_u.gfull.metric_id.name: %s\n", msg.Ganglia_metadata_msg_u.gfull.metric_id.name);
  if ( override_string != NULL )
    {
      msg.Ganglia_metadata_msg_u.gfull.metric_id.host = apr_pstrdup (gm_pool, (char*)override_string);
      debug_msg("  msg.Ganglia_metadata_msg_u.gfull.metric_id.host: %s\n", msg.Ganglia_metadata_msg_u.gfull.metric_id.host);
      msg.Ganglia_metadata_msg_u.gfull.metric_id.spoof = TRUE;
    }
    else
    {
      msg.Ganglia_metadata_msg_u.gfull.metric_id.host = apr_pstrdup (gm_pool, (char*)myhost);
      debug_msg("  msg.Ganglia_metadata_msg_u.gfull.metric_id.host: %s\n", msg.Ganglia_metadata_msg_u.gfull.metric_id.host);
      msg.Ganglia_metadata_msg_u.gfull.metric_id.spoof = FALSE;
    }

  arr = apr_table_elts(gmetric->extra);
  elts = (const apr_table_entry_t *)arr->elts;
  msg.Ganglia_metadata_msg_u.gfull.metric.metadata.metadata_len = arr->nelts;
  msg.Ganglia_metadata_msg_u.gfull.metric.metadata.metadata_val = 
      (Ganglia_extra_data*)apr_pcalloc(gm_pool, sizeof(Ganglia_extra_data)*arr->nelts);

  /* add all of the metadata to the packet */
  for (i = 0; i < arr->nelts; ++i) {
      if (elts[i].key == NULL)
          continue;

      /* Replace the host name with the spoof host if it exists in the metadata */
      if ((apr_toupper(elts[i].key[0]) == spoof[0]) && strcasecmp(SPOOF_HOST, elts[i].key) == 0) 
        {
          msg.Ganglia_metadata_msg_u.gfull.metric_id.host = apr_pstrdup (gm_pool, elts[i].val);
          msg.Ganglia_metadata_msg_u.gfull.metric_id.spoof = TRUE;
        }
      if ((apr_toupper(elts[i].key[0]) == spoof[0]) && strcasecmp(SPOOF_HEARTBEAT, elts[i].key) == 0) 
        {
          msg.Ganglia_metadata_msg_u.gfull.metric_id.name = apr_pstrdup (gm_pool, "heartbeat");
          msg.Ganglia_metadata_msg_u.gfull.metric.name = msg.Ganglia_metadata_msg_u.gfull.metric_id.name;
          msg.Ganglia_metadata_msg_u.gfull.metric_id.spoof = TRUE;
        }

      msg.Ganglia_metadata_msg_u.gfull.metric.metadata.metadata_val[i].name = 
          apr_pstrdup(gm_pool, elts[i].key);
      msg.Ganglia_metadata_msg_u.gfull.metric.metadata.metadata_val[i].data = 
          apr_pstrdup(gm_pool, elts[i].val);
  }

  /* Send the message */
  xdrmem_create(&x, gmetricmsg, GANGLIA_MAX_MESSAGE_LEN, XDR_ENCODE);
  if(!xdr_Ganglia_metadata_msg(&x, &msg))
    {
      return 1;
    }
  len = xdr_getpos(&x); 
  /* Send the encoded data along...*/
  return Ganglia_udp_send_message( send_channels, gmetricmsg, len);
}
예제 #4
0
파일: gmond.c 프로젝트: hasso/collectd
static int create_sockets(socket_entry_t **ret_sockets, /* {{{ */
                          size_t *ret_sockets_num, const char *node,
                          const char *service, int listen) {
  struct addrinfo *ai_list;
  int ai_return;

  socket_entry_t *sockets = NULL;
  size_t sockets_num = 0;

  int status;

  if (*ret_sockets != NULL)
    return (EINVAL);

  struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
                              .ai_flags = AI_ADDRCONFIG | AI_PASSIVE,
                              .ai_protocol = IPPROTO_UDP,
                              .ai_socktype = SOCK_DGRAM};

  ai_return = getaddrinfo(node, service, &ai_hints, &ai_list);
  if (ai_return != 0) {
    char errbuf[1024];
    ERROR("gmond plugin: getaddrinfo (%s, %s) failed: %s",
          (node == NULL) ? "(null)" : node,
          (service == NULL) ? "(null)" : service,
          (ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
                                    : gai_strerror(ai_return));
    return (-1);
  }

  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
       ai_ptr = ai_ptr->ai_next) /* {{{ */
  {
    socket_entry_t *tmp;

    tmp = realloc(sockets, (sockets_num + 1) * sizeof(*sockets));
    if (tmp == NULL) {
      ERROR("gmond plugin: realloc failed.");
      continue;
    }
    sockets = tmp;

    sockets[sockets_num].fd =
        socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
    if (sockets[sockets_num].fd < 0) {
      char errbuf[1024];
      ERROR("gmond plugin: socket failed: %s",
            sstrerror(errno, errbuf, sizeof(errbuf)));
      continue;
    }

    assert(sizeof(sockets[sockets_num].addr) >= ai_ptr->ai_addrlen);
    memcpy(&sockets[sockets_num].addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
    sockets[sockets_num].addrlen = ai_ptr->ai_addrlen;

    /* Sending socket: Open only one socket and don't bind it. */
    if (listen == 0) {
      sockets_num++;
      break;
    } else {
      int yes = 1;

      status = setsockopt(sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
                          (void *)&yes, sizeof(yes));
      if (status != 0) {
        char errbuf[1024];
        WARNING("gmond plugin: setsockopt(2) failed: %s",
                sstrerror(errno, errbuf, sizeof(errbuf)));
      }
    }

    status = bind(sockets[sockets_num].fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
    if (status != 0) {
      char errbuf[1024];
      ERROR("gmond plugin: bind failed: %s",
            sstrerror(errno, errbuf, sizeof(errbuf)));
      close(sockets[sockets_num].fd);
      continue;
    }

    if (ai_ptr->ai_family == AF_INET) {
      struct sockaddr_in *addr;
      int loop;

      addr = (struct sockaddr_in *)ai_ptr->ai_addr;

      if (!IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) {
        sockets_num++;
        continue;
      }

      loop = 1;
      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)));
      }

      struct ip_mreq mreq = {.imr_multiaddr.s_addr = addr->sin_addr.s_addr,
                             .imr_interface.s_addr = htonl(INADDR_ANY)};

      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) {
      struct sockaddr_in6 *addr;
      int loop;

      addr = (struct sockaddr_in6 *)ai_ptr->ai_addr;

      if (!IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) {
        sockets_num++;
        continue;
      }

      loop = 1;
      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)));
      }

      struct ipv6_mreq mreq = {
          .ipv6mr_interface = 0 /* any */
      };

      memcpy(&mreq.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(addr->sin6_addr));
      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++;
  } /* }}} for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) */

  freeaddrinfo(ai_list);

  if (sockets_num == 0) {
    sfree(sockets);
    return (-1);
  }

  *ret_sockets = sockets;
  *ret_sockets_num = sockets_num;
  return (0);
} /* }}} int create_sockets */

static int request_meta_data(const char *host, const char *name) /* {{{ */
{
  Ganglia_metadata_msg msg = {0};
  char buffer[BUFF_SIZE] = {0};
  unsigned int buffer_size;
  XDR xdr;

  msg.id = gmetadata_request;
  msg.Ganglia_metadata_msg_u.grequest.metric_id.host = strdup(host);
  msg.Ganglia_metadata_msg_u.grequest.metric_id.name = strdup(name);

  if ((msg.Ganglia_metadata_msg_u.grequest.metric_id.host == NULL) ||
      (msg.Ganglia_metadata_msg_u.grequest.metric_id.name == NULL)) {
    sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
    sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
    return (-1);
  }

  xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_ENCODE);

  if (!xdr_Ganglia_metadata_msg(&xdr, &msg)) {
    sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
    sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
    return (-1);
  }

  buffer_size = xdr_getpos(&xdr);

  DEBUG("gmond plugin: Requesting meta data for %s/%s.", host, name);

  pthread_mutex_lock(&mc_send_sockets_lock);
  for (size_t i = 0; i < mc_send_sockets_num; i++) {
    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);
  sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
  return (0);
} /* }}} int request_meta_data */