Skip to content

Instantly share code, notes, and snippets.

@freemed
Created June 21, 2011 15:40
Show Gist options
  • Save freemed/1038132 to your computer and use it in GitHub Desktop.
Save freemed/1038132 to your computer and use it in GitHub Desktop.
gmond+gmetric force spoof patch
Index: monitor-core/lib/libgmond.c
===================================================================
--- monitor-core/lib/libgmond.c (revision 2616)
+++ monitor-core/lib/libgmond.c (working copy)
@@ -66,6 +66,8 @@
CFG_BOOL("gexec", 0, CFGF_NONE),
CFG_INT("send_metadata_interval", 0, CFGF_NONE),
CFG_STR("module_dir", NULL, CFGF_NONE),
+ CFG_STR("override_hostname", NULL, CFGF_NONE),
+ CFG_STR("override_ip", NULL, CFGF_NONE),
CFG_END()
};
@@ -430,6 +432,12 @@
int
Ganglia_metadata_send( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels )
{
+ return Ganglia_metadata_send_real( gmetric, send_channels, NULL );
+}
+
+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];
@@ -444,9 +452,17 @@
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.host = apr_pstrdup (gm_pool, (char*)myhost);
msg.Ganglia_metadata_msg_u.gfull.metric_id.name = apr_pstrdup (gm_pool, gmetric->msg->name);
- msg.Ganglia_metadata_msg_u.gfull.metric_id.spoof = FALSE;
+ if ( override_string != NULL )
+ {
+ msg.Ganglia_metadata_msg_u.gfull.metric_id.host = apr_pstrdup (gm_pool, (char*)override_string);
+ 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);
+ msg.Ganglia_metadata_msg_u.gfull.metric_id.spoof = FALSE;
+ }
arr = apr_table_elts(gmetric->extra);
elts = (const apr_table_entry_t *)arr->elts;
@@ -492,6 +508,12 @@
int
Ganglia_value_send( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels )
{
+ return Ganglia_value_send_real( gmetric, send_channels, NULL );
+}
+
+int
+Ganglia_value_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];
@@ -505,9 +527,17 @@
apr_gethostname( (char*)myhost, APRMAXHOSTLEN+1, gm_pool);
msg.id = gmetric_string;
- msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrdup (gm_pool, (char*)myhost);
+ if (override_string != NULL)
+ {
+ msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrdup (gm_pool, (char*)override_string);
+ msg.Ganglia_value_msg_u.gstr.metric_id.spoof = TRUE;
+ }
+ else
+ {
+ msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrdup (gm_pool, (char*)myhost);
+ msg.Ganglia_value_msg_u.gstr.metric_id.spoof = FALSE;
+ }
msg.Ganglia_value_msg_u.gstr.metric_id.name = apr_pstrdup (gm_pool, gmetric->msg->name);
- msg.Ganglia_value_msg_u.gstr.metric_id.spoof = FALSE;
msg.Ganglia_value_msg_u.gstr.fmt = apr_pstrdup (gm_pool, "%s");
msg.Ganglia_value_msg_u.gstr.str = apr_pstrdup (gm_pool, gmetric->value);
Index: monitor-core/include/ganglia.h
===================================================================
--- monitor-core/include/ganglia.h (revision 2616)
+++ monitor-core/include/ganglia.h (working copy)
@@ -54,6 +54,7 @@
int Ganglia_metric_set( Ganglia_metric gmetric, char *name, char *value, char *type, char *units, unsigned int slope, unsigned int tmax, unsigned int dmax);
int Ganglia_metric_send( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels );
int Ganglia_metadata_send( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels );
+int Ganglia_metadata_send_real( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels, char *override_string );
void Ganglia_metadata_add( Ganglia_metric gmetric, char *name, char *value );
int Ganglia_value_send( Ganglia_metric gmetric, Ganglia_udp_send_channels send_channels );
Index: monitor-core/gmetric/Makefile.am
===================================================================
--- monitor-core/gmetric/Makefile.am (revision 2616)
+++ monitor-core/gmetric/Makefile.am (working copy)
@@ -10,6 +10,8 @@
GLDFLAGS =
endif
+INCLUDES = @APR_INCLUDES@
+
AM_CFLAGS = -I../lib -I../include $(GCFLAGS)
bin_PROGRAMS = gmetric
Index: monitor-core/gmetric/gmetric.c
===================================================================
--- monitor-core/gmetric/gmetric.c (revision 2616)
+++ monitor-core/gmetric/gmetric.c (working copy)
@@ -2,7 +2,12 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <confuse.h> /* header for libconfuse */
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_pools.h>
+
#include "ganglia.h"
#include "cmdline.h"
@@ -34,6 +39,10 @@
/* parse the configuration file */
gmond_config = Ganglia_gmond_config_create( args_info.conf_arg, !args_info.conf_given);
+ /* deal with spoof overrides */
+ cfg_t *globals = (cfg_t*) cfg_getsec( gmond_config, "globals" );
+ char *override_hostname = cfg_getstr( globals, "override_hostname" );
+ char *override_ip = cfg_getstr( globals, "override_ip" );
/* build the udp send channels */
send_channels = Ganglia_udp_send_channels_create(global_context, gmond_config);
@@ -50,6 +59,8 @@
fprintf(stderr,"Unable to allocate gmetric structure. Exiting.\n");
exit(1);
}
+ apr_pool_t *gm_pool = (apr_pool_t*)gmetric->pool;
+
if(args_info.spoof_given && args_info.heartbeat_given){
rval = Ganglia_metric_set(gmetric, "heartbeat", "0", "uint32", "", 0, 0, 0);
}else{
@@ -90,6 +101,11 @@
if(args_info.spoof_given)
Ganglia_metadata_add(gmetric, SPOOF_HOST, args_info.spoof_arg);
+ if(!args_info.spoof_given && override_hostname != NULL)
+ {
+ char *spoof_string = apr_pstrcat(gm_pool, override_ip != NULL ? override_ip : override_hostname, ":", override_hostname, NULL);
+ Ganglia_metadata_add(gmetric, SPOOF_HOST, spoof_string);
+ }
if(args_info.heartbeat_given)
Ganglia_metadata_add(gmetric, SPOOF_HEARTBEAT, "yes");
if(args_info.group_given)
Index: monitor-core/gmond/gmond.c
===================================================================
--- monitor-core/gmond/gmond.c (revision 2616)
+++ monitor-core/gmond/gmond.c (working copy)
@@ -80,6 +80,10 @@
int cluster_tag = 0;
/* This host's location */
char *host_location = NULL;
+/* This host name, spoofed */
+char *override_hostname = NULL;
+/* This host ip, spoofed */
+char *override_ip = NULL;
/* Boolean. Will this host received gexec requests? */
int gexec_on = 0;
/* This is tweakable by globals{max_udp_msg_len=...} */
@@ -292,6 +296,9 @@
send_metadata_interval = cfg_getint( tmp, "send_metadata_interval");
/* Get the DSO module dir */
module_dir = cfg_getstr(tmp, "module_dir");
+ /* Acquire spoof name/ip, if they are specified */
+ override_hostname = cfg_getstr(tmp, "override_hostname");
+ override_ip = cfg_getstr(tmp, "override_ip");
/* Commandline for debug_level trumps configuration file behaviour ... */
if (args_info.debug_given)
@@ -1166,7 +1173,7 @@
* since the xdr_free below will blast the value later (along with the other
* allocated structure elements). This is only performed once at gmetric creation */
metric->name = apr_pstrdup(host->pool, message->Ganglia_value_msg_u.gstr.metric_id.name );
- debug_msg("***Allocating value packet for host--%s-- and metric --%s-- ****\n", host->hostname, metric->name);
+ debug_msg("***Allocating value packet for host--%s-- and metric --%s-- ****\n", message->Ganglia_value_msg_u.gstr.metric_id.host, metric->name);
}
@@ -2536,8 +2543,13 @@
/* no memory */
return;
}
-
+
name = cb->msg.Ganglia_value_msg_u.gstr.metric_id.name;
+ if (override_hostname != NULL)
+ {
+ cb->msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrcat(gm_pool, override_ip != NULL ? override_ip : override_hostname, ":", override_hostname, NULL);
+ cb->msg.Ganglia_value_msg_u.gstr.metric_id.spoof = TRUE;
+ }
val = apr_pstrdup(gm_pool, host_metric_value(cb->info, &(cb->msg)));
type = apr_pstrdup(gm_pool, host_metric_type(cb->info->type));
@@ -2574,7 +2586,14 @@
debug_msg("\tsending metadata for metric: %s", cb->name);
ganglia_scoreboard_inc(PKTS_SENT_METADATA);
- errors = Ganglia_metadata_send(gmetric, udp_send_channels);
+ if (override_hostname != NULL)
+ {
+ errors = Ganglia_metadata_send_real(gmetric, udp_send_channels, cb->msg.Ganglia_value_msg_u.gstr.metric_id.host);
+ }
+ else
+ {
+ errors = Ganglia_metadata_send(gmetric, udp_send_channels);
+ }
if (errors)
{
err_msg("Error %d sending the modular data for %s\n", errors, cb->name);
Index: monitor-core/gmond/conf.pod
===================================================================
--- monitor-core/gmond/conf.pod (revision 2616)
+++ monitor-core/gmond/conf.pod (working copy)
@@ -152,6 +152,10 @@
However in unicast mode, a resend interval must be established. The interval
value is the minimum number of seconds between resends.
+The B<override_hostname> and B<override_ip> parameters allow an arbitrary
+hostname and/or IP (hostname can be optionally specified without IP) to
+use when identifying metrics coming from this host.
+
The B<module_dir> is an optional parameter indicating the directory where
the DSO modules are to be located. If absent, the value to use is set at
configure time with the --with-moduledir option which will default if omitted
@freemed
Copy link
Author

freemed commented Jun 24, 2011

README

This is a patch to allow gmond/gmetric to push a specific hostname/ip combination, rather than relying on ganglia's hostname/ip autodetection. The configuration is specified in your gmond.conf file.

This patch should be applied against a clean checkout of the ganglia svn repository.

Apply with:

$ svn co -q https://ganglia.svn.sourceforge.net/svnroot/ganglia/trunk ganglia
$ cd ganglia
$ patch -p0 < ~../patch.diff
patching file monitor-core/lib/libgmond.c
patching file monitor-core/include/ganglia.h
patching file monitor-core/gmetric/Makefile.am
patching file monitor-core/gmetric/gmetric.c
patching file monitor-core/gmond/gmond.c
patching file monitor-core/gmond/conf.pod
$

( @freemed / https://twitter.com/JBuchbinder & @vvuksan / https://twitter.com/vvuksan )

@sammarx
Copy link

sammarx commented Jun 29, 2011

I'm getting an error when trying to apply/compile this patch.
I'm on ubuntu 10.04
It's in the gmetric compilation section

gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I.. -I/usr/include/apr-1.0 -I../lib -I../include -g -O2 -fno-strict-aliasing -Wall -D_REENTRANT -MT gmetric.o -MD -MP -MF .deps/gmetric.Tpo -c -o gmetric.o gmetric.c
In file included from gmetric.c:7:
/usr/include/apr-1.0/apr.h:289: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘apr_off_t’
In file included from gmetric.c:8:
/usr/include/apr-1.0/apr_strings.h:299: error: expected declaration specifiers or ‘...’ before ‘apr_off_t’
/usr/include/apr-1.0/apr_strings.h:317: error: expected ‘)’ before ‘*’ token
/usr/include/apr-1.0/apr_strings.h:353: error: expected ‘)’ before ‘size’
gmetric.c: In function ‘main’:
gmetric.c:43: warning: passing argument 1 of ‘cfg_getsec’ from incompatible pointer type
/usr/include/confuse.h:770: note: expected ‘struct cfg_t *’ but argument is of type ‘Ganglia_gmond_config’

Any help would be appreciated

@freemed
Copy link
Author

freemed commented Jun 30, 2011

@smarxmoxie:

This has been merged back into upstream Subversion for ganglia as of rev 2618, so it no longer needs to be manually merged (you can just check it out).

This gist is being kept for historical purposes at the moment.

@umairpannu
Copy link

I have downloaded the latest version of ganglia but supplying host name in gmond.conf gives error and demon never starts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment