diff --git a/0001-Fix-return-value-from-mod_python-init.patch b/0001-Fix-return-value-from-mod_python-init.patch new file mode 100644 index 0000000..db32809 --- /dev/null +++ b/0001-Fix-return-value-from-mod_python-init.patch @@ -0,0 +1,60 @@ +From 4ca52a1be8ef9b2ce1c62fdb4e5ba4db44132ad0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Tue, 15 Oct 2024 20:24:40 +0200 +Subject: [PATCH] Fix return value from mod_python init + +--- + gmond/modules/python/mod_python.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/gmond/modules/python/mod_python.c b/gmond/modules/python/mod_python.c +index 484429e..cdfeb7e 100644 +--- a/gmond/modules/python/mod_python.c ++++ b/gmond/modules/python/mod_python.c +@@ -601,11 +601,14 @@ static struct PyModuleDef moduledef = { + #define INITERROR return NULL + + PyMODINIT_FUNC PyInit_metric_init(apr_pool_t *p) ++ + #else ++ + #define INITERROR return + + static int pyth_metric_init (apr_pool_t *p) + #endif ++ + { + DIR *dp; + struct dirent *entry; +@@ -796,6 +799,16 @@ static int pyth_metric_init (apr_pool_t *p) + #endif + } + ++#if PY_MAJOR_VERSION >= 3 ++static int pyth_metric_init (apr_pool_t *p) { ++ if (PyInit_metric_init(p) == NULL) { ++ return 1; ++ } else { ++ return 0; ++ } ++} ++#endif ++ + static apr_status_t pyth_metric_cleanup ( void *data) + { + PyObject *pcleanup, *pobj; +@@ -913,11 +926,7 @@ static g_val_t pyth_metric_handler( int metric_index ) + mmodule python_module = + { + STD_MMODULE_STUFF, +-#if PY_MAJOR_VERSION >= 3 +- (int (*)(apr_pool_t *))PyInit_metric_init, +-#else + pyth_metric_init, +-#endif + NULL, + NULL, /* defined dynamically */ + pyth_metric_handler, +-- +2.47.0 + diff --git a/0002-2to3-pass.patch b/0002-2to3-pass.patch new file mode 100644 index 0000000..d4525ca --- /dev/null +++ b/0002-2to3-pass.patch @@ -0,0 +1,1080 @@ +From ca162aba2b52e50b29ef107eb60f54ecb9f0442d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 14 Oct 2024 20:25:28 +0200 +Subject: [PATCH 2/3] 2to3 pass + +--- + .../apache_status/apache_status.py | 38 +++++++++---------- + gmond/python_modules/cpu/cpu_stats.py | 12 +++--- + gmond/python_modules/db/DBUtil.py | 13 ++++--- + gmond/python_modules/db/mysql.py | 11 +++--- + gmond/python_modules/db/redis.py | 6 +-- + gmond/python_modules/db/riak.py | 18 ++++----- + gmond/python_modules/disk/diskfree.py | 2 +- + gmond/python_modules/disk/diskstat.py | 4 +- + gmond/python_modules/disk/multidisk.py | 4 +- + gmond/python_modules/example/example.py | 6 +-- + gmond/python_modules/example/spfexample.py | 4 +- + gmond/python_modules/memcached/memcached.py | 20 +++++----- + gmond/python_modules/memory/mem_stats.py | 4 +- + .../python_modules/network/multi_interface.py | 12 +++--- + gmond/python_modules/network/netstats.py | 16 ++++---- + gmond/python_modules/network/tcpconn.py | 8 ++-- + gmond/python_modules/network/traffic1.py | 18 ++++----- + gmond/python_modules/nfs/nfsstats.py | 6 +-- + gmond/python_modules/process/procstat.py | 34 ++++++++--------- + gmond/python_modules/ssl/entropy.py | 2 +- + gmond/python_modules/varnish/varnish.py | 12 +++--- + gmond/python_modules/vm_stats/vm_stats.py | 12 +++--- + gmond/python_modules/xen/xenstats.py | 2 +- + 23 files changed, 133 insertions(+), 131 deletions(-) + +diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py +index 580e893..fba14ee 100755 +--- a/gmond/python_modules/apache_status/apache_status.py ++++ b/gmond/python_modules/apache_status/apache_status.py +@@ -4,7 +4,7 @@ + import os + import threading + import time +-import urllib2 ++import urllib.request, urllib.error, urllib.parse + import traceback + import re + import copy +@@ -44,7 +44,7 @@ Scoreboard = { + NAME_PREFIX + 'idle' : {'key': 'I', 'desc': 'Idle cleanup of worker'}, + NAME_PREFIX + 'open_slot' : {'key': '.', 'desc': 'Open slot with no current process'}, + } +-Scoreboard_bykey = dict([(v["key"], k) for (k, v) in Scoreboard.iteritems()]) ++Scoreboard_bykey = dict([(v["key"], k) for (k, v) in Scoreboard.items()]) + + SSL_REGEX = re.compile('^(cache type:) (.*)()(?P[0-9]+)( bytes, current sessions: )(?P[0-9]+)(
subcaches: )(?P[0-9]+)(, indexes per subcache: )(?P[0-9]+)(
)(.*)(
index usage: )(?P[0-9]+)(%, cache usage: )(?P[0-9]+)(%
total sessions stored since starting: )(?P[0-9]+)(
total sessions expired since starting: )(?P[0-9]+)(
total \(pre-expiry\) sessions scrolled out of the cache: )(?P[0-9]+)(
total retrieves since starting: )(?P[0-9]+)( hit, )(?P[0-9]+)( miss
total removes since starting: )(?P[0-9]+)( hit, )(?P[0-9]+)') + # Good for Apache 2.2 +@@ -67,17 +67,17 @@ def get_metrics(): + + if (time.time() - METRICS['time']) > METRICS_CACHE_MAX: + +- metrics = dict([(k, 0) for k in Scoreboard.keys()]) ++ metrics = dict([(k, 0) for k in list(Scoreboard.keys())]) + + # This is the short server-status. Lacks SSL metrics + try: +- req = urllib2.Request(SERVER_STATUS_URL + "?auto") ++ req = urllib.request.Request(SERVER_STATUS_URL + "?auto") + + # Download the status file + if sys.version_info < (2, 6): +- res = urllib2.urlopen(req) ++ res = urllib.request.urlopen(req) + else: +- res = urllib2.urlopen(req, timeout=2) ++ res = urllib.request.urlopen(req, timeout=2) + + for line in res: + split_line = line.rstrip().split(": ") +@@ -96,20 +96,20 @@ def get_metrics(): + metric_name = long_metric_name + metrics[metric_name] = split_line[1] + +- except urllib2.URLError: ++ except urllib.error.URLError: + traceback.print_exc() + + # If we are collecting SSL metrics we'll do + if COLLECT_SSL: + + try: +- req2 = urllib2.Request(SERVER_STATUS_URL) ++ req2 = urllib.request.Request(SERVER_STATUS_URL) + + # Download the status file + if sys.version_info < (2, 6): +- res = urllib2.urlopen(req2) ++ res = urllib.request.urlopen(req2) + else: +- res = urllib2.urlopen(req2, timeout=2) ++ res = urllib.request.urlopen(req2, timeout=2) + + for line in res: + regMatch = SSL_REGEX.match(line) +@@ -119,7 +119,7 @@ def get_metrics(): + #print SSL_NAME_PREFIX + key + "=" + linebits[key] + metrics[SSL_NAME_PREFIX + key] = linebits[key] + +- except urllib2.URLError: ++ except urllib.error.URLError: + traceback.print_exc() + + LAST_METRICS = copy.deepcopy(METRICS) +@@ -138,7 +138,7 @@ def get_value(name): + + try: + result = metrics['data'][name] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -159,7 +159,7 @@ def get_delta(name): + try: + delta = multiplier * (float(curr_metrics['data'][name]) - float(last_metrics['data'][name])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -169,7 +169,7 @@ def get_delta(name): + + def create_desc(prop): + d = Desc_Skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -177,8 +177,8 @@ def create_desc(prop): + def metric_init(params): + global descriptors, Desc_Skel, SERVER_STATUS_URL, COLLECT_SSL + +- print '[apache_status] Received the following parameters' +- print params ++ print('[apache_status] Received the following parameters') ++ print(params) + + if "metric_group" not in params: + params["metric_group"] = "apache" +@@ -265,7 +265,7 @@ def metric_init(params): + "description": "Uptime", + })) + +- for k, v in Scoreboard.iteritems(): ++ for k, v in Scoreboard.items(): + descriptors.append(create_desc({ + "name" : k, + "call_back" : get_value, +@@ -404,9 +404,9 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if d['name'] == NAME_PREFIX + "rps": +- print 'value for %s is %.4f' % (d['name'], v) ++ print('value for %s is %.4f' % (d['name'], v)) + else: +- print 'value for %s is %s' % (d['name'], v) ++ print('value for %s is %s' % (d['name'], v)) + time.sleep(15) + except KeyboardInterrupt: + os._exit(1) +diff --git a/gmond/python_modules/cpu/cpu_stats.py b/gmond/python_modules/cpu/cpu_stats.py +index 5a8ebb8..16d6165 100644 +--- a/gmond/python_modules/cpu/cpu_stats.py ++++ b/gmond/python_modules/cpu/cpu_stats.py +@@ -75,7 +75,7 @@ def get_value(name): + + try: + result = metrics['data'][name][0] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -97,7 +97,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][name][0]) - float(last_metrics['data'][name][0])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -124,7 +124,7 @@ def get_softirq_delta(name): + try: + delta = (float(curr_metrics['data']['softirq'][index]) - float(last_metrics['data']['softirq'][index])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -134,7 +134,7 @@ def get_softirq_delta(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -279,6 +279,6 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) +- print 'Sleeping 15 seconds' ++ print('%s = %s' % (d['name'], v)) ++ print('Sleeping 15 seconds') + time.sleep(5) +diff --git a/gmond/python_modules/db/DBUtil.py b/gmond/python_modules/db/DBUtil.py +index 2504c24..66f8a78 100644 +--- a/gmond/python_modules/db/DBUtil.py ++++ b/gmond/python_modules/db/DBUtil.py +@@ -51,7 +51,7 @@ except: + args = tuple() + else: + args = self.default_factory, +- return type(self), args, None, None, self.items() ++ return type(self), args, None, None, list(self.items()) + def copy(self): + return self.__copy__() + def __copy__(self): +@@ -59,7 +59,7 @@ except: + def __deepcopy__(self, memo): + import copy + return type(self)(self.default_factory, +- copy.deepcopy(self.items())) ++ copy.deepcopy(list(self.items()))) + def __repr__(self): + return 'defaultdict(%s, %s)' % (self.default_factory, + dict.__repr__(self)) +@@ -77,7 +77,7 @@ def is_hex(s): + def longish(x): + if len(x): + try: +- return long(x) ++ return int(x) + except ValueError: + if(x.endswith(',')): + return longish(x[:-1]) +@@ -92,7 +92,7 @@ def longish(x): + def hexlongish(x): + if len(x): + try: +- return long(str(x), 16) ++ return int(str(x), 16) + except ValueError: + return longish(x[:-1]) + else: +@@ -101,7 +101,7 @@ def hexlongish(x): + def parse_innodb_status(innodb_status_raw, innodb_version="1.0"): + def sumof(status): + def new(*idxs): +- return sum(map(lambda x: longish(status[x]), idxs)) ++ return sum([longish(status[x]) for x in idxs]) + return new + + innodb_status = defaultdict(int) +@@ -280,5 +280,6 @@ if __name__ == '__main__': + cursor.close() + + conn.close() +- except MySQLdb.OperationalError, (errno, errmsg): ++ except MySQLdb.OperationalError as xxx_todo_changeme: ++ (errno, errmsg) = xxx_todo_changeme.args + raise +diff --git a/gmond/python_modules/db/mysql.py b/gmond/python_modules/db/mysql.py +index 7b5ab59..065a6cd 100644 +--- a/gmond/python_modules/db/mysql.py ++++ b/gmond/python_modules/db/mysql.py +@@ -154,7 +154,7 @@ def update_stats(get_innodb=True, get_master=True, get_slave=True): + cursor.execute("SHOW SLAVE STATUS") + res = cursor.fetchone() + if res: +- for (k,v) in res.items(): ++ for (k,v) in list(res.items()): + slave_status[k.lower()] = v + else: + get_slave = False +@@ -165,7 +165,8 @@ def update_stats(get_innodb=True, get_master=True, get_slave=True): + cursor.close() + + conn.close() +- except MySQLdb.OperationalError, (errno, errmsg): ++ except MySQLdb.OperationalError as xxx_todo_changeme: ++ (errno, errmsg) = xxx_todo_changeme.args + logging.error('error updating stats') + logging.error(errmsg) + return False +@@ -1097,9 +1098,9 @@ def metric_init(params): + + for stats_descriptions in (innodb_stats_descriptions, master_stats_descriptions, misc_stats_descriptions, slave_stats_descriptions): + for label in stats_descriptions: +- if mysql_stats.has_key(label): ++ if label in mysql_stats: + format = '%u' +- if stats_descriptions[label].has_key('value_type'): ++ if 'value_type' in stats_descriptions[label]: + if stats_descriptions[label]['value_type'] == "float": + format = '%f' + +@@ -1165,7 +1166,7 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: +- print ' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description']) ++ print(' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description'])) + + if options.gmetric: + if d['value_type'] == 'uint': +diff --git a/gmond/python_modules/db/redis.py b/gmond/python_modules/db/redis.py +index 4e682b7..9101b49 100755 +--- a/gmond/python_modules/db/redis.py ++++ b/gmond/python_modules/db/redis.py +@@ -83,7 +83,7 @@ def metric_handler(name): + v = cps + #logging.debug("submittincg metric %s is %s" % (n, int(v))) + metric_handler.info[n] = int(v) # TODO Use value_type. +- except Exception, e: ++ except Exception as e: + #logging.debug("caught exception %s" % e) + pass + s.close() +@@ -121,7 +121,7 @@ def metric_init(params={}): + "db0": {"units": "keys"}, + } + metric_handler.descriptors = {} +- for name, updates in metrics.iteritems(): ++ for name, updates in metrics.items(): + descriptor = { + "name": name, + "call_back": metric_handler, +@@ -135,7 +135,7 @@ def metric_init(params={}): + } + descriptor.update(updates) + metric_handler.descriptors[name] = descriptor +- return metric_handler.descriptors.values() ++ return list(metric_handler.descriptors.values()) + + + def metric_cleanup(): +diff --git a/gmond/python_modules/db/riak.py b/gmond/python_modules/db/riak.py +index 908b480..499a04f 100755 +--- a/gmond/python_modules/db/riak.py ++++ b/gmond/python_modules/db/riak.py +@@ -24,7 +24,7 @@ import os + import sys + import threading + import time +-import urllib2 ++import urllib.request, urllib.error, urllib.parse + import traceback + import json + +@@ -37,7 +37,7 @@ Debug = False + + def dprint(f, *v): + if Debug: +- print >>sys.stderr, "DEBUG: " + f % v ++ print("DEBUG: " + f % v, file=sys.stderr) + + + def floatable(str): +@@ -84,18 +84,18 @@ class UpdateMetricThread(threading.Thread): + + def update_metric(self): + try: +- req = urllib2.Request(url=self.url) +- res = urllib2.urlopen(req) ++ req = urllib.request.Request(url=self.url) ++ res = urllib.request.urlopen(req) + stats = res.read() + dprint("%s", stats) + json_stats = json.loads(stats) +- for (key, value) in json_stats.iteritems(): ++ for (key, value) in json_stats.items(): + dprint("%s = %s", key, value) + if value == 'undefined': + self.metric[self.mp + '_' + key] = 0 + else: + self.metric[self.mp + '_' + key] = value +- except urllib2.URLError: ++ except urllib.error.URLError: + traceback.print_exc() + else: + res.close() +@@ -116,7 +116,7 @@ def metric_init(params): + if "metrix_prefix" not in params: + params["metrix_prefix"] = "riak" + +- print params ++ print(params) + + # initialize skeleton of descriptors + Desc_Skel = { +@@ -1035,7 +1035,7 @@ def metric_init(params): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -1057,7 +1057,7 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + time.sleep(0.2) +diff --git a/gmond/python_modules/disk/diskfree.py b/gmond/python_modules/disk/diskfree.py +index 70d5d41..8f7442d 100644 +--- a/gmond/python_modules/disk/diskfree.py ++++ b/gmond/python_modules/disk/diskfree.py +@@ -152,4 +152,4 @@ if __name__ == '__main__': + } + descriptors = metric_init(PARAMS) + for d in descriptors: +- print (('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name'])) ++ print((('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name']))) +diff --git a/gmond/python_modules/disk/diskstat.py b/gmond/python_modules/disk/diskstat.py +index 4cde607..79962ca 100644 +--- a/gmond/python_modules/disk/diskstat.py ++++ b/gmond/python_modules/disk/diskstat.py +@@ -532,7 +532,7 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: +- print ' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description']) ++ print(' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description'])) + + if options.gmetric: + if d['value_type'] == 'uint': +@@ -544,5 +544,5 @@ if __name__ == '__main__': + (options.gmetric_bin, options.gmond_conf, v, d['units'], value_type, d['name'], d['slope']) + os.system(cmd) + +- print 'Sleeping 15 seconds' ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/disk/multidisk.py b/gmond/python_modules/disk/multidisk.py +index 5dff161..b26bf59 100644 +--- a/gmond/python_modules/disk/multidisk.py ++++ b/gmond/python_modules/disk/multidisk.py +@@ -118,7 +118,7 @@ def metric_init(params): + continue + + if ganglia.get_debug_msg_level() > 1: +- print 'Discovered device %s' % line[1] ++ print('Discovered device %s' % line[1]) + + descriptors.append(Init_Metric(line, 'disk_total', int(1200), + 'double', 'GB', 'both', '%.3f', +@@ -140,4 +140,4 @@ if __name__ == '__main__': + metric_init(None) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %f' % (d['name'], v) ++ print('value for %s is %f' % (d['name'], v)) +diff --git a/gmond/python_modules/example/example.py b/gmond/python_modules/example/example.py +index c35d40d..82faa30 100644 +--- a/gmond/python_modules/example/example.py ++++ b/gmond/python_modules/example/example.py +@@ -54,8 +54,8 @@ def metric_init(params): + global Constant_Value + random.seed() + +- print '[pyexample] Received the following parameters' +- print params ++ print('[pyexample] Received the following parameters') ++ print(params) + + if 'RandomMax' in params: + Random_Max = int(params['RandomMax']) +@@ -97,4 +97,4 @@ if __name__ == '__main__': + metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) +diff --git a/gmond/python_modules/example/spfexample.py b/gmond/python_modules/example/spfexample.py +index 0baf97e..31e0af4 100644 +--- a/gmond/python_modules/example/spfexample.py ++++ b/gmond/python_modules/example/spfexample.py +@@ -133,5 +133,5 @@ if __name__ == '__main__': + d = metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %s' % (d['name'], str(v)) +- print d ++ print('value for %s is %s' % (d['name'], str(v))) ++ print(d) +diff --git a/gmond/python_modules/memcached/memcached.py b/gmond/python_modules/memcached/memcached.py +index 7db7616..8bdb57c 100644 +--- a/gmond/python_modules/memcached/memcached.py ++++ b/gmond/python_modules/memcached/memcached.py +@@ -19,7 +19,7 @@ Debug = False + + def dprint(f, *v): + if Debug: +- print >>sys.stderr, "DEBUG: " + f % v ++ print("DEBUG: " + f % v, file=sys.stderr) + + + def floatable(str): +@@ -86,7 +86,7 @@ class UpdateMetricThread(threading.Thread): + rfd, wfd, xfd = select.select([sock], [], [], self.timeout) + + if not rfd: +- print >>sys.stderr, "ERROR: select timeout" ++ print("ERROR: select timeout", file=sys.stderr) + break + + for fd in rfd: +@@ -94,19 +94,19 @@ class UpdateMetricThread(threading.Thread): + try: + data = fd.recv(8192) + msg += data +- except (IOError, OSError), e: ++ except (IOError, OSError) as e: + if e.errno != errno.EINTR: + raise + + if msg.find("END"): + break +- except select.error, e: ++ except select.error as e: + if e[0] != errno.EINTR: + raise + + sock.close() +- except socket.error, e: +- print >>sys.stderr, "ERROR: %s" % e ++ except socket.error as e: ++ print("ERROR: %s" % e, file=sys.stderr) + + for m in msg.split("\r\n"): + d = m.split(" ") +@@ -140,7 +140,7 @@ class UpdateMetricThread(threading.Thread): + def metric_init(params): + global descriptors, Desc_Skel, _Worker_Thread, Debug + +- print '[memcached] memcached protocol "stats"' ++ print('[memcached] memcached protocol "stats"') + if "type" not in params: + params["type"] = "memcached" + +@@ -150,7 +150,7 @@ def metric_init(params): + elif params["type"] == "Tokyo Tyrant": + params["metrix_prefix"] = "tt" + +- print params ++ print(params) + + # initialize skeleton of descriptors + Desc_Skel = { +@@ -362,7 +362,7 @@ def metric_init(params): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -391,7 +391,7 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + time.sleep(0.2) +diff --git a/gmond/python_modules/memory/mem_stats.py b/gmond/python_modules/memory/mem_stats.py +index 932a85b..b0cdc16 100644 +--- a/gmond/python_modules/memory/mem_stats.py ++++ b/gmond/python_modules/memory/mem_stats.py +@@ -43,7 +43,7 @@ def metrics_handler(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -384,4 +384,4 @@ if __name__ == '__main__': + metric_init({}) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %f' % (d['name'], v) ++ print('value for %s is %f' % (d['name'], v)) +diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py +index 456704b..e4b1b04 100644 +--- a/gmond/python_modules/network/multi_interface.py ++++ b/gmond/python_modules/network/multi_interface.py +@@ -74,7 +74,7 @@ net_stats_file = "/proc/net/dev" + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -242,7 +242,7 @@ def get_aggregates(name): + try: + delta = (float(curr_metrics['data'][iface][index]) - float(last_metrics['data'][iface][index])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -300,7 +300,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][iface][index]) - float(last_metrics['data'][iface][index])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -320,8 +320,8 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) +- except StandardError: +- print sys.exc_info()[0] ++ except Exception: ++ print(sys.exc_info()[0]) + os._exit(1) +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index 66c378d..ba0c56f 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -82,7 +82,7 @@ def get_value(name): + + try: + result = float(curr_metrics['data'][group][metric]) +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -101,7 +101,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][group][metric]) - float(last_metrics['data'][group][metric])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print((name + " is less 0")) + delta = 0 + except KeyError: + delta = 0.0 +@@ -117,7 +117,7 @@ def get_tcploss_percentage(name): + try: + pct = 100 * (float(curr_metrics['data']['tcpext']["tcploss"]) - float(last_metrics["data"]['tcpext']["tcploss"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) + if pct < 0: +- print name + " is less 0" ++ print((name + " is less 0")) + pct = 0 + except KeyError: + pct = 0.0 +@@ -135,7 +135,7 @@ def get_tcpattemptfail_percentage(name): + try: + pct = 100 * (float(curr_metrics['data']['tcp']["attemptfails"]) - float(last_metrics["data"]['tcp']["attemptfails"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) + if pct < 0: +- print name + " is less 0" ++ print((name + " is less 0")) + pct = 0 + except Exception: + pct = 0.0 +@@ -151,7 +151,7 @@ def get_retrans_percentage(name): + try: + pct = 100 * (float(curr_metrics['data']['tcp']["retranssegs"]) - float(last_metrics['data']['tcp']["retranssegs"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) + if pct < 0: +- print name + " is less 0" ++ print((name + " is less 0")) + pct = 0 + except KeyError: + pct = 0.0 +@@ -163,7 +163,7 @@ def get_retrans_percentage(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in list(prop.items()): + d[k] = v + return d + +@@ -266,6 +266,6 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) +- print 'Sleeping 15 seconds' ++ print('%s = %s' % (d['name'], v)) ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/network/tcpconn.py b/gmond/python_modules/network/tcpconn.py +index 71bcc0f..b97d0ed 100644 +--- a/gmond/python_modules/network/tcpconn.py ++++ b/gmond/python_modules/network/tcpconn.py +@@ -68,7 +68,7 @@ def TCP_Connections(name): + global _WorkerThread + + if _WorkerThread is None: +- print 'Error: No netstat data gathering thread created for metric %s' % name ++ print('Error: No netstat data gathering thread created for metric %s' % name) + return 0 + + if not _WorkerThread.running and not _WorkerThread.shuttingdown: +@@ -233,7 +233,7 @@ class NetstatThread(threading.Thread): + if self.popenChild != None: + try: + self.popenChild.wait() +- except OSError, e: ++ except OSError as e: + if e.errno == 10: # No child processes + pass + +@@ -274,7 +274,7 @@ class NetstatThread(threading.Thread): + + try: + self.popenChild.wait() +- except OSError, e: ++ except OSError as e: + if e.errno == 10: # No child process + continue + +@@ -361,7 +361,7 @@ if __name__ == '__main__': + try: + for d in _descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + os._exit(1) +diff --git a/gmond/python_modules/network/traffic1.py b/gmond/python_modules/network/traffic1.py +index 9e2b252..9f1078f 100644 +--- a/gmond/python_modules/network/traffic1.py ++++ b/gmond/python_modules/network/traffic1.py +@@ -16,7 +16,7 @@ Debug = False + + def dprint(f, *v): + if Debug: +- print >> sys.stderr, "DEBUG: " + f % v ++ print("DEBUG: " + f % v, file=sys.stderr) + + + class UpdateTrafficThread(threading.Thread): +@@ -76,7 +76,7 @@ class UpdateTrafficThread(threading.Thread): + dprint("%s", ">>update_metric") + self.stats = {} + _stats = a[1].split() +- for name, index in self.stats_tab.iteritems(): ++ for name, index in self.stats_tab.items(): + self.stats[name + '_' + self.target_device] = int(_stats[index]) + self.stats["time"] = time.time() + dprint("%s", self.stats) +@@ -84,7 +84,7 @@ class UpdateTrafficThread(threading.Thread): + if "time" in self.stats_prev: + dprint("%s: %d = %d - %d", "DO DIFF", self.stats["time"] - self.stats_prev["time"], self.stats["time"], self.stats_prev["time"]) + d = self.stats["time"] - self.stats_prev["time"] +- for name, cur in self.stats.iteritems(): ++ for name, cur in self.stats.items(): + self.metric[name] = float(cur - self.stats_prev[name]) / d + + self.stats_prev = self.stats.copy() +@@ -104,8 +104,8 @@ class UpdateTrafficThread(threading.Thread): + def metric_init(params): + global Desc_Skel, _Worker_Thread, Debug + +- print '[traffic1] Received the following parameters' +- print params ++ print('[traffic1] Received the following parameters') ++ print(params) + + Desc_Skel = { + 'name' : 'XXX', +@@ -172,7 +172,7 @@ def metric_init(params): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -195,11 +195,11 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + time.sleep(0.2) + os._exit(1) +- except StandardError: +- print sys.exc_info()[0] ++ except Exception: ++ print(sys.exc_info()[0]) + os._exit(1) +diff --git a/gmond/python_modules/nfs/nfsstats.py b/gmond/python_modules/nfs/nfsstats.py +index a383101..618b1be 100644 +--- a/gmond/python_modules/nfs/nfsstats.py ++++ b/gmond/python_modules/nfs/nfsstats.py +@@ -273,11 +273,11 @@ def metric_init(params): + + # Parse our defined params list in order to ensure list will not exceed max_plimit + n = 0 +- names_keys = configtable[i]['names'].keys() ++ names_keys = list(configtable[i]['names'].keys()) + keys_to_remove = [] + for _tmpkey in names_keys: + _tmplist = names_keys +- param_pos = re.split("{(\d+)\}", configtable[i]['names'][_tmpkey].values()[0])[1] ++ param_pos = re.split("{(\d+)\}", list(configtable[i]['names'][_tmpkey].values())[0])[1] + if int(param_pos) > int(max_plimit): + keys_to_remove.append(_tmpkey) + n += 1 +@@ -388,7 +388,7 @@ def debug(level, text): + if level > verboselevel: + return + if sys.stderr.isatty(): +- print text ++ print(text) + else: + syslog.syslog(text) + +diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py +index 93ff9a9..aad5229 100644 +--- a/gmond/python_modules/process/procstat.py ++++ b/gmond/python_modules/process/procstat.py +@@ -144,7 +144,7 @@ def get_pgid(proc): + logging.debug('getting pgid for process: ' + proc) + ERROR = 0 + +- if pgid_list.has_key(proc) and os.path.exists('/proc/' + pgid_list[proc][0]): ++ if proc in pgid_list and os.path.exists('/proc/' + pgid_list[proc][0]): + return pgid_list[proc] + + val = PROCESSES[proc] +@@ -245,14 +245,14 @@ def test(params): + + PROCESSES = params + +- for proc, val in PROCESSES.items(): ++ for proc, val in list(PROCESSES.items()): + print('') +- print(' Testing ' + proc + ': ' + val) ++ print((' Testing ' + proc + ': ' + val)) + + try: + (ppid, pgid) = get_pgid(proc) +- except Exception, e: +- print(' failed getting pgid: ' + str(e)) ++ except Exception as e: ++ print((' failed getting pgid: ' + str(e))) + continue + + pids = get_pgroup(ppid, pgid) +@@ -262,7 +262,7 @@ def test(params): + for pid in pids: + # Read from binary file containing command line arguments + args = file('/proc/' + pid + '/cmdline', 'rt').readline().replace('\0', ' ') +- print(' ' + pid + ' ' + args) ++ print((' ' + pid + ' ' + args)) + + logging.debug('success testing') + +@@ -279,7 +279,7 @@ def update_stats(): + else: + last_update = cur_time + +- for proc, val in PROCESSES.items(): ++ for proc, val in list(PROCESSES.items()): + logging.debug(' updating for ' + proc) + + # setup storage lists +@@ -292,7 +292,7 @@ def update_stats(): + # Update CPU utilization + try: + (ppid, pgid) = get_pgid(proc) +- except Exception, e: ++ except Exception as e: + logging.warning(' failed getting pgid: ' + str(e)) + stats[proc]['cpu'] = 0.0 + stats[proc]['mem'] = 0 +@@ -391,7 +391,7 @@ def metric_init(params): + time_max = 60 + for label in descriptions: + for proc in PROCESSES: +- if stats[proc].has_key(label): ++ if label in stats[proc]: + + d = { + 'name': 'procstat_' + proc + '_' + label, +@@ -435,12 +435,12 @@ def display_proc_stat(pid): + # Display them + i = 0 + for f in fields: +- print '%15s: %s' % (f, stat[i]) ++ print('%15s: %s' % (f, stat[i])) + i += 1 + + except: +- print('failed to get /proc/' + pid + '/stat') +- print(traceback.print_exc(file=sys.stdout)) ++ print(('failed to get /proc/' + pid + '/stat')) ++ print((traceback.print_exc(file=sys.stdout))) + + + def display_proc_statm(pid): +@@ -454,12 +454,12 @@ def display_proc_statm(pid): + # Display them + i = 0 + for f in fields: +- print '%15s: %s' % (f, statm[i]) ++ print('%15s: %s' % (f, statm[i])) + i += 1 + + except: +- print('failed to get /proc/' + pid + '/statm') +- print(traceback.print_exc(file=sys.stdout)) ++ print(('failed to get /proc/' + pid + '/statm')) ++ print((traceback.print_exc(file=sys.stdout))) + + + def metric_cleanup(): +@@ -504,7 +504,7 @@ if __name__ == '__main__': + update_stats() + + print('') +- print(' waiting ' + str(MAX_UPDATE_TIME) + ' seconds') ++ print((' waiting ' + str(MAX_UPDATE_TIME) + ' seconds')) + time.sleep(MAX_UPDATE_TIME) + + metric_init(params) +@@ -512,7 +512,7 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: +- print ' %s: %s %s [%s]' % (d['name'], d['format'] % v, d['units'], d['description']) ++ print(' %s: %s %s [%s]' % (d['name'], d['format'] % v, d['units'], d['description'])) + + if options.gmetric: + if d['value_type'] == 'uint': +diff --git a/gmond/python_modules/ssl/entropy.py b/gmond/python_modules/ssl/entropy.py +index 8337981..71193c6 100644 +--- a/gmond/python_modules/ssl/entropy.py ++++ b/gmond/python_modules/ssl/entropy.py +@@ -53,4 +53,4 @@ if __name__ == '__main__': + metric_init({}) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) +diff --git a/gmond/python_modules/varnish/varnish.py b/gmond/python_modules/varnish/varnish.py +index f8c0723..b1a8573 100755 +--- a/gmond/python_modules/varnish/varnish.py ++++ b/gmond/python_modules/varnish/varnish.py +@@ -51,7 +51,7 @@ METRICS_CACHE_MAX = 5 + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -92,7 +92,7 @@ def get_value(name): + name = name[len(NAME_PREFIX):] # remove prefix from name + try: + result = metrics['data'][name] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -109,9 +109,9 @@ def get_delta(name): + try: + delta = float(curr_metrics['data'][name] - last_metrics['data'][name]) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print "Less than 0" ++ print("Less than 0") + delta = 0 +- except StandardError: ++ except Exception: + delta = 0 + + return delta +@@ -1038,6 +1038,6 @@ if __name__ == '__main__': + descriptors = metric_init(PARAMS) + while True: + for d in descriptors: +- print (('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name'])) +- print 'Sleeping 15 seconds' ++ print((('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name']))) ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/vm_stats/vm_stats.py b/gmond/python_modules/vm_stats/vm_stats.py +index ed663de..2e1e8b8 100644 +--- a/gmond/python_modules/vm_stats/vm_stats.py ++++ b/gmond/python_modules/vm_stats/vm_stats.py +@@ -69,7 +69,7 @@ def get_value(name): + + try: + result = metrics['data'][name] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -86,7 +86,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][name]) - float(last_metrics['data'][name])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -112,7 +112,7 @@ def get_vmeff(name): + + delta = 100 * (float(curr_metrics['data']['pgsteal_normal']) - float(last_metrics['data']['pgsteal_normal'])) / pgscan_diff + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -122,7 +122,7 @@ def get_vmeff(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -734,6 +734,6 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) +- print 'Sleeping 15 seconds' ++ print('%s = %s' % (d['name'], v)) ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/xen/xenstats.py b/gmond/python_modules/xen/xenstats.py +index 67a6c21..bdb3750 100755 +--- a/gmond/python_modules/xen/xenstats.py ++++ b/gmond/python_modules/xen/xenstats.py +@@ -128,4 +128,4 @@ if __name__ == '__main__': + metric_init('init') + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) +-- +2.47.0 + diff --git a/0003-Ruff-pass.patch b/0003-Ruff-pass.patch new file mode 100644 index 0000000..409375c --- /dev/null +++ b/0003-Ruff-pass.patch @@ -0,0 +1,534 @@ +From 0be29755dcea7e19bc347b273fa38787ecb57252 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 14 Oct 2024 20:27:57 +0200 +Subject: [PATCH 3/3] Ruff pass + +--- + .../apache_status/apache_status.py | 5 +-- + gmond/python_modules/cpu/cpu_stats.py | 3 -- + gmond/python_modules/db/DBUtil.py | 6 ++-- + gmond/python_modules/db/mysql.py | 2 +- + gmond/python_modules/db/redis.py | 4 +-- + gmond/python_modules/db/riak.py | 9 +++--- + gmond/python_modules/disk/diskstat.py | 4 +-- + gmond/python_modules/disk/multidisk.py | 4 +-- + gmond/python_modules/memcached/memcached.py | 6 ++-- + gmond/python_modules/memory/mem_stats.py | 3 -- + .../python_modules/network/multi_interface.py | 2 +- + gmond/python_modules/network/netstats.py | 4 +-- + gmond/python_modules/network/tcpconn.py | 6 ++-- + gmond/python_modules/network/traffic1.py | 4 +-- + gmond/python_modules/nfs/nfsstats.py | 6 ++-- + gmond/python_modules/process/procstat.py | 32 +++++++++---------- + gmond/python_modules/ssl/entropy.py | 5 ++- + gmond/python_modules/varnish/varnish.py | 2 +- + gmond/python_modules/vm_stats/vm_stats.py | 1 - + gmond/python_modules/xen/xenstats.py | 2 -- + 20 files changed, 50 insertions(+), 60 deletions(-) + +diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py +index fba14ee..d375d74 100755 +--- a/gmond/python_modules/apache_status/apache_status.py ++++ b/gmond/python_modules/apache_status/apache_status.py +@@ -2,9 +2,10 @@ + # -*- coding: utf-8 -*- + + import os +-import threading + import time +-import urllib.request, urllib.error, urllib.parse ++import urllib.request ++import urllib.error ++import urllib.parse + import traceback + import re + import copy +diff --git a/gmond/python_modules/cpu/cpu_stats.py b/gmond/python_modules/cpu/cpu_stats.py +index 16d6165..ab518cc 100644 +--- a/gmond/python_modules/cpu/cpu_stats.py ++++ b/gmond/python_modules/cpu/cpu_stats.py +@@ -1,6 +1,3 @@ +-import sys +-import traceback +-import os + import re + import time + import copy +diff --git a/gmond/python_modules/db/DBUtil.py b/gmond/python_modules/db/DBUtil.py +index 66f8a78..c7e7473 100644 +--- a/gmond/python_modules/db/DBUtil.py ++++ b/gmond/python_modules/db/DBUtil.py +@@ -28,7 +28,7 @@ pure python collections.defaultdict substitute + #from collections import defaultdict + try: + from collections import defaultdict +-except: ++except ImportError: + class defaultdict(dict): + def __init__(self, default_factory=None, *a, **kw): + if (default_factory is not None and +@@ -79,9 +79,9 @@ def longish(x): + try: + return int(x) + except ValueError: +- if(x.endswith(',')): ++ if x.endswith(','): + return longish(x[:-1]) +- if(is_hex(x.lower()) == True): ++ if is_hex(x.lower()): + return hexlongish(x) + #print "X==(%s)(%s)(%s)" %(x, x[:-1],hexlongish(x)), sys.exc_info()[0] + return longish(x[:-1]) +diff --git a/gmond/python_modules/db/mysql.py b/gmond/python_modules/db/mysql.py +index 065a6cd..5aae1cf 100644 +--- a/gmond/python_modules/db/mysql.py ++++ b/gmond/python_modules/db/mysql.py +@@ -354,7 +354,7 @@ def get_stat(name): + logging.debug("fetching %s" % name) + try: + return mysql_stats[label] +- except: ++ except KeyError: + logging.error("failed to fetch %s" % name) + return 0 + else: +diff --git a/gmond/python_modules/db/redis.py b/gmond/python_modules/db/redis.py +index 9101b49..285a625 100755 +--- a/gmond/python_modules/db/redis.py ++++ b/gmond/python_modules/db/redis.py +@@ -34,7 +34,7 @@ def metric_handler(name): + if metric_handler.auth is not None: + s.send("*2\r\n$4\r\nAUTH\r\n$%d\r\n%s\r\n" % (len(metric_handler.auth), metric_handler.auth)) + result = s.recv(100) +- if not 'OK' in result: ++ if 'OK' not in result: + return 0 + s.send("*1\r\n$4\r\nINFO\r\n") + #logging.debug("sent INFO") +@@ -83,7 +83,7 @@ def metric_handler(name): + v = cps + #logging.debug("submittincg metric %s is %s" % (n, int(v))) + metric_handler.info[n] = int(v) # TODO Use value_type. +- except Exception as e: ++ except Exception: + #logging.debug("caught exception %s" % e) + pass + s.close() +diff --git a/gmond/python_modules/db/riak.py b/gmond/python_modules/db/riak.py +index 499a04f..a399931 100755 +--- a/gmond/python_modules/db/riak.py ++++ b/gmond/python_modules/db/riak.py +@@ -24,7 +24,9 @@ import os + import sys + import threading + import time +-import urllib.request, urllib.error, urllib.parse ++import urllib.request ++import urllib.error ++import urllib.parse + import traceback + import json + +@@ -44,7 +46,7 @@ def floatable(str): + try: + float(str) + return True +- except: ++ except ValueError: + return False + + +@@ -102,7 +104,6 @@ class UpdateMetricThread(threading.Thread): + + def metric_of(self, name): + val = 0 +- mp = name.split("_")[0] + if name in self.metric: + _Lock.acquire() + val = self.metric[name] +@@ -1062,6 +1063,6 @@ if __name__ == '__main__': + except KeyboardInterrupt: + time.sleep(0.2) + os._exit(1) +- except: ++ except Exception: + traceback.print_exc() + os._exit(1) +diff --git a/gmond/python_modules/disk/diskstat.py b/gmond/python_modules/disk/diskstat.py +index 79962ca..aea335f 100644 +--- a/gmond/python_modules/disk/diskstat.py ++++ b/gmond/python_modules/disk/diskstat.py +@@ -386,7 +386,7 @@ def get_stat(name): + + try: + return stats[dev][label] +- except: ++ except Exception: + logging.warning('failed to fetch [' + dev + '] ' + name) + return 0 + else: +@@ -394,7 +394,7 @@ def get_stat(name): + + try: + return stats[label] +- except: ++ except Exception: + logging.warning('failed to fetch ' + name) + return 0 + +diff --git a/gmond/python_modules/disk/multidisk.py b/gmond/python_modules/disk/multidisk.py +index b26bf59..5ad59b5 100644 +--- a/gmond/python_modules/disk/multidisk.py ++++ b/gmond/python_modules/disk/multidisk.py +@@ -108,8 +108,8 @@ def metric_init(params): + global descriptors + f = open('/proc/mounts', 'r') + +- for l in f: +- line = l.split() ++ for buff in f: ++ line = buff.split() + if line[3].startswith('ro'): + continue + elif Remote_Mount(line[0], line[2]): +diff --git a/gmond/python_modules/memcached/memcached.py b/gmond/python_modules/memcached/memcached.py +index 8bdb57c..b5c3df4 100644 +--- a/gmond/python_modules/memcached/memcached.py ++++ b/gmond/python_modules/memcached/memcached.py +@@ -26,7 +26,7 @@ def floatable(str): + try: + float(str) + return True +- except: ++ except ValueError: + return False + + +@@ -58,7 +58,7 @@ class UpdateMetricThread(threading.Thread): + return + try: + self.join() +- except: ++ except Exception: + pass + + def run(self): +@@ -396,6 +396,6 @@ if __name__ == '__main__': + except KeyboardInterrupt: + time.sleep(0.2) + os._exit(1) +- except: ++ except Exception: + traceback.print_exc() + os._exit(1) +diff --git a/gmond/python_modules/memory/mem_stats.py b/gmond/python_modules/memory/mem_stats.py +index b0cdc16..0a6dd6a 100644 +--- a/gmond/python_modules/memory/mem_stats.py ++++ b/gmond/python_modules/memory/mem_stats.py +@@ -1,6 +1,3 @@ +-import sys +-import traceback +-import os + import re + + +diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py +index e4b1b04..c9f898f 100644 +--- a/gmond/python_modules/network/multi_interface.py ++++ b/gmond/python_modules/network/multi_interface.py +@@ -94,7 +94,7 @@ def metric_init(params): + Desc_Skel = { + 'name' : 'XXX', + 'call_back' : get_delta, +- 'time_max' : 60, ++ 'time_max' : time_max, + 'value_type' : 'float', + 'format' : '%.0f', + 'units' : '/s', +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index ba0c56f..ec65d1e 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -2,11 +2,11 @@ + # + # /proc/net/netstat + +-import sys + import re + import time + import copy +-import string ++ ++NAME_PREFIX = 'netstat_' + + PARAMS = {} + +diff --git a/gmond/python_modules/network/tcpconn.py b/gmond/python_modules/network/tcpconn.py +index b97d0ed..cf55a6d 100644 +--- a/gmond/python_modules/network/tcpconn.py ++++ b/gmond/python_modules/network/tcpconn.py +@@ -31,6 +31,8 @@ + #******************************************************************************/ + + import os ++import threading ++import time + + OBSOLETE_POPEN = False + try: +@@ -39,8 +41,6 @@ except ImportError: + import popen2 + OBSOLETE_POPEN = True + +-import threading +-import time + + _WorkerThread = None # Worker thread object + _glock = threading.Lock() # Synchronization lock +@@ -230,7 +230,7 @@ class NetstatThread(threading.Thread): + + def shutdown(self): + self.shuttingdown = True +- if self.popenChild != None: ++ if self.popenChild is not None: + try: + self.popenChild.wait() + except OSError as e: +diff --git a/gmond/python_modules/network/traffic1.py b/gmond/python_modules/network/traffic1.py +index 9f1078f..c5fdcba 100644 +--- a/gmond/python_modules/network/traffic1.py ++++ b/gmond/python_modules/network/traffic1.py +@@ -67,8 +67,8 @@ class UpdateTrafficThread(threading.Thread): + + def update_metric(self): + f = open(self.proc_file, "r") +- for l in f: +- a = l.split(":") ++ for buff in f: ++ a = buff.split(":") + dev = a[0].lstrip() + if dev != self.target_device: + continue +diff --git a/gmond/python_modules/nfs/nfsstats.py b/gmond/python_modules/nfs/nfsstats.py +index 618b1be..2d3d279 100644 +--- a/gmond/python_modules/nfs/nfsstats.py ++++ b/gmond/python_modules/nfs/nfsstats.py +@@ -10,8 +10,6 @@ + # 2) the code is structured in a way intended to make it easy to repurpose + # the code for extracting other information out of /proc + +-import os +-import stat + import re + import time + import syslog +@@ -262,7 +260,7 @@ def metric_init(params): + else: + tests_passed = False + break +- except: ++ except Exception: + tests_passed = False + break + if not tests_passed: +@@ -362,7 +360,7 @@ def get_value(name): + for i in range(0, len(descriptors)): + if descriptors[i]['name'] == name: + break +- contents = file(descriptors[i]['file']).read() ++ contents = open(descriptors[i]['file']).read() + m = re.search(descriptors[i]['re'], contents, flags=re.MULTILINE) + + m_value = m.group(1) +diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py +index aad5229..e5c3f9a 100644 +--- a/gmond/python_modules/process/procstat.py ++++ b/gmond/python_modules/process/procstat.py +@@ -128,14 +128,14 @@ PROCESSES = {} + + def readCpu(pid): + try: +- stat = file('/proc/' + pid + '/stat', 'rt').readline().split() ++ stat = open('/proc/' + pid + '/stat', 'rt').readline().split() + #logging.debug(' stat (' + pid + '): ' + str(stat)) + utime = int(stat[13]) + stime = int(stat[14]) + cutime = int(stat[15]) + cstime = int(stat[16]) + return (utime + stime + cutime + cstime) +- except: ++ except Exception: + logging.warning('failed to get (' + str(pid) + ') stats') + return 0 + +@@ -152,8 +152,8 @@ def get_pgid(proc): + if '.pid' in val[-4:]: + if os.path.exists(val): + logging.debug(' pidfile found') +- ppid = file(val, 'rt').readline().strip() +- pgid = file('/proc/' + ppid + '/stat', 'rt').readline().split()[4] ++ ppid = open(val, 'rt').readline().strip() ++ pgid = open('/proc/' + ppid + '/stat', 'rt').readline().split()[4] + else: + raise Exception('pidfile (' + val + ') does not exist') + +@@ -195,10 +195,10 @@ def get_pgroup(ppid, pgid): + p_list = [] + for stat_file in glob.glob('/proc/[1-9]*/stat'): + try: +- stat = file(stat_file, 'rt').readline().split() ++ stat = open(stat_file, 'rt').readline().split() + if stat[4] == pgid: + p_list.append(stat[0]) +- except: ++ except Exception: + # likely the pid has exited. this is normal. + pass + +@@ -225,7 +225,7 @@ def get_rss(pids): + try: + statm = open('/proc/' + p + '/statm', 'rt').readline().split() + #logging.debug(' statm (' + p + '): ' + str(statm)) +- except: ++ except Exception: + # Process finished, ignore this mem usage + logging.warning(' failed getting statm for pid: ' + p) + continue +@@ -261,7 +261,7 @@ def test(params): + print(' PID, ARGS') + for pid in pids: + # Read from binary file containing command line arguments +- args = file('/proc/' + pid + '/cmdline', 'rt').readline().replace('\0', ' ') ++ args = open('/proc/' + pid + '/cmdline', 'rt').readline().replace('\0', ' ') + print((' ' + pid + ' ' + args)) + + logging.debug('success testing') +@@ -283,9 +283,9 @@ def update_stats(): + logging.debug(' updating for ' + proc) + + # setup storage lists +- if not proc in stats: ++ if proc not in stats: + stats[proc] = {} +- if not proc in last_val: ++ if proc not in last_val: + last_val[proc] = {} + + ##### +@@ -347,7 +347,7 @@ def get_stat(name): + + try: + return stats[proc][label] +- except: ++ except Exception: + logging.warning('failed to fetch [' + proc + '] ' + name) + return 0 + else: +@@ -355,7 +355,7 @@ def get_stat(name): + + try: + return stats[label] +- except: ++ except Exception: + logging.warning('failed to fetch ' + name) + return 0 + else: +@@ -420,7 +420,7 @@ def metric_init(params): + + def display_proc_stat(pid): + try: +- stat = file('/proc/' + pid + '/stat', 'rt').readline().split() ++ stat = open('/proc/' + pid + '/stat', 'rt').readline().split() + + fields = [ + 'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', +@@ -438,14 +438,14 @@ def display_proc_stat(pid): + print('%15s: %s' % (f, stat[i])) + i += 1 + +- except: ++ except Exception: + print(('failed to get /proc/' + pid + '/stat')) + print((traceback.print_exc(file=sys.stdout))) + + + def display_proc_statm(pid): + try: +- statm = file('/proc/' + pid + '/statm', 'rt').readline().split() ++ statm = open('/proc/' + pid + '/statm', 'rt').readline().split() + + fields = [ + 'size', 'rss', 'share', 'trs', 'drs', 'lrs', 'dt' +@@ -457,7 +457,7 @@ def display_proc_statm(pid): + print('%15s: %s' % (f, statm[i])) + i += 1 + +- except: ++ except Exception: + print(('failed to get /proc/' + pid + '/statm')) + print((traceback.print_exc(file=sys.stdout))) + +diff --git a/gmond/python_modules/ssl/entropy.py b/gmond/python_modules/ssl/entropy.py +index 71193c6..bb9f67c 100644 +--- a/gmond/python_modules/ssl/entropy.py ++++ b/gmond/python_modules/ssl/entropy.py +@@ -7,7 +7,6 @@ + # (it can reuse the pool of bits). + # Therefore if you are running SSL on the box you want to know this. + +-import sys + + + entropy_file = "/proc/sys/kernel/random/entropy_avail" +@@ -20,8 +19,8 @@ def metrics_handler(name): + except IOError: + return 0 + +- for l in f: +- line = l ++ for buff in f: ++ line = buff + + return int(line) + +diff --git a/gmond/python_modules/varnish/varnish.py b/gmond/python_modules/varnish/varnish.py +index b1a8573..e5c1b75 100755 +--- a/gmond/python_modules/varnish/varnish.py ++++ b/gmond/python_modules/varnish/varnish.py +@@ -143,7 +143,7 @@ def metric_init(lparams): + Desc_Skel = { + 'name' : 'XXX', + 'call_back' : 'XXX', +- 'time_max' : 60, ++ 'time_max' : time_max, + 'value_type' : 'float', + 'format' : '%f', + 'units' : 'XXX', +diff --git a/gmond/python_modules/vm_stats/vm_stats.py b/gmond/python_modules/vm_stats/vm_stats.py +index 2e1e8b8..8eb9c11 100644 +--- a/gmond/python_modules/vm_stats/vm_stats.py ++++ b/gmond/python_modules/vm_stats/vm_stats.py +@@ -3,7 +3,6 @@ + # + # /proc/vmstat + +-import sys + import re + import time + import copy +diff --git a/gmond/python_modules/xen/xenstats.py b/gmond/python_modules/xen/xenstats.py +index bdb3750..1c328e4 100755 +--- a/gmond/python_modules/xen/xenstats.py ++++ b/gmond/python_modules/xen/xenstats.py +@@ -18,8 +18,6 @@ + # MA 02110-1301, USA. + + import libvirt +-import os +-import time + + descriptors = list() + conn = libvirt.openReadOnly("xen:///") +-- +2.47.0 + diff --git a/0004-Use-raw-strings.patch b/0004-Use-raw-strings.patch new file mode 100644 index 0000000..722e6aa --- /dev/null +++ b/0004-Use-raw-strings.patch @@ -0,0 +1,62 @@ +From 21656da69738482cca947cb70ad9ef25ac95cbfa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 14 Oct 2024 20:36:13 +0200 +Subject: [PATCH 4/4] Use raw strings + +--- + gmond/python_modules/memory/mem_stats.py | 2 +- + gmond/python_modules/network/netstats.py | 4 ++-- + gmond/python_modules/vm_stats/vm_stats.py | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gmond/python_modules/memory/mem_stats.py b/gmond/python_modules/memory/mem_stats.py +index 0a6dd6a..522268e 100644 +--- a/gmond/python_modules/memory/mem_stats.py ++++ b/gmond/python_modules/memory/mem_stats.py +@@ -26,7 +26,7 @@ def metrics_handler(name): + if name == 'mem_swap_used': + return metrics_handler('mem_swap_total') - metrics_handler('mem_swap_free') + for line in file: +- parts = re.split("\s+", line) ++ parts = re.split(r"\s+", line) + if parts[0] == metric_map[name]['name'] + ":": + # All of the measurements are in kBytes. We want to change them over + # to Bytes +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index ec65d1e..3805f4b 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -46,7 +46,7 @@ def get_metrics(): + for line in file: + if re.match("(.*): [0-9]", line): + count = 0 +- metrics = re.split("\s+", line) ++ metrics = re.split(r"\s+", line) + metric_group = metrics[0].replace(":", "").lower() + if metric_group not in stats_pos: + continue +@@ -202,7 +202,7 @@ def metric_init(params): + # Lines with + if not re.match("(.*): [0-9]", line): + count = 0 +- mapping = re.split("\s+", line) ++ mapping = re.split(r"\s+", line) + metric_group = mapping[0].replace(":", "").lower() + stats_pos[metric_group] = dict() + for metric in mapping: +diff --git a/gmond/python_modules/vm_stats/vm_stats.py b/gmond/python_modules/vm_stats/vm_stats.py +index 8eb9c11..fc5a241 100644 +--- a/gmond/python_modules/vm_stats/vm_stats.py ++++ b/gmond/python_modules/vm_stats/vm_stats.py +@@ -46,7 +46,7 @@ def get_metrics(): + # convert to dict + metrics = {} + for line in file: +- parts = re.split("\s+", line) ++ parts = re.split(r"\s+", line) + metrics[parts[0]] = parts[1] + + # update cache +-- +2.47.0 + diff --git a/0005-First-loop-might-contain-non-integer-input.patch b/0005-First-loop-might-contain-non-integer-input.patch new file mode 100644 index 0000000..4077272 --- /dev/null +++ b/0005-First-loop-might-contain-non-integer-input.patch @@ -0,0 +1,27 @@ +From 1d9688e7059d0a93c27bf4e74f26ad3cf1120837 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 4 Nov 2024 20:06:47 +0100 +Subject: [PATCH 5/5] First loop might contain non integer input + +--- + gmond/python_modules/network/netstats.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index 3805f4b..76f6b68 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -52,6 +52,10 @@ def get_metrics(): + continue + new_metrics[metric_group] = dict() + for value in metrics: ++ try: ++ value = int(value) ++ except ValueError: ++ value = -1 + # Skip first + if count > 0 and value >= 0 and count in stats_pos[metric_group]: + metric_name = stats_pos[metric_group][count] +-- +2.47.0 + diff --git a/CVE-2019-20378_CVE-2019-20379.patch b/CVE-2019-20378_CVE-2019-20379.patch deleted file mode 100644 index e9c414b..0000000 --- a/CVE-2019-20378_CVE-2019-20379.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ab909037aa30bc200d467eecb1c189565604ba6a Mon Sep 17 00:00:00 2001 -From: Adam Tygart -Date: Fri, 28 Feb 2020 10:17:20 -0600 -Subject: [PATCH] Fix XSS from OBB-1005024 - ---- - graph_all_periods.php | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/graph_all_periods.php b/graph_all_periods.php -index 4e90ccba..9185d646 100644 ---- a/graph_all_periods.php -+++ b/graph_all_periods.php -@@ -10,12 +10,12 @@ - $data->assign("refresh", $conf['default_refresh']); - $data->assign("conf", $conf); - $data->assign("embed", -- isset($_REQUEST['embed']) ? $_REQUEST['embed'] : NULL); -+ isset($_REQUEST['embed']) ? sanitize($_REQUEST['embed']) : NULL); - $data->assign("mobile", -- isset($_REQUEST['mobile']) ? $_REQUEST['mobile'] : NULL); --$data->assign("h", isset($_GET['h']) ? $_GET['h'] : NULL); --$data->assign("g", isset($_GET['g']) ? $_GET['g'] : NULL); --$data->assign("m", isset($_GET['m']) ? $_GET['m'] : NULL); -+ isset($_REQUEST['mobile']) ? sanitize($_REQUEST['mobile']) : NULL); -+$data->assign("h", isset($_GET['h']) ? sanitize($_GET['h']) : NULL); -+$data->assign("g", isset($_GET['g']) ? sanitize($_GET['g']) : NULL); -+$data->assign("m", isset($_GET['m']) ? sanitize($_GET['m']) : NULL); - $data->assign("html_g", - isset($_GET['g']) ? htmlspecialchars($_GET['g']) : NULL); - $data->assign("html_m", diff --git a/conf.php b/conf.php index d6f87a5..ab08134 100644 --- a/conf.php +++ b/conf.php @@ -1,11 +1,11 @@ +?> \ No newline at end of file diff --git a/ganglia-3.7.2-185ab6.patch b/ganglia-3.7.2-185ab6.patch new file mode 100644 index 0000000..3a41200 --- /dev/null +++ b/ganglia-3.7.2-185ab6.patch @@ -0,0 +1,1413 @@ +diff --git a/contrib/removespikes.pl b/contrib/removespikes.pl +index e52908d3..7061cea8 100755 +--- a/contrib/removespikes.pl ++++ b/contrib/removespikes.pl +@@ -97,10 +97,10 @@ while () { + $cdo=0; + if ($linea=~/^(.*)/) { $tstamp=$1; } + if ($linea=~/(.*)$/) { $tresto=$1; } +- if (/\s\d\.\d+e.(\d+)\s<\/v>/) { ++ if (/\s?\d\.\d+e.(\d+)\s?<\/v>/) { + @dump = split(/<\/v>/, $tresto); + for ($lino=0; $lino<=$#dump-1; $lino++) { # scans DS's within each row +- if ( $dump[$lino]=~/\d\.\d+e.(\d+)\s/ ) { # make sure it is a number (and not NaN) ++ if ( $dump[$lino]=~/\d\.\d+e.(\d+)\s?/ ) { # make sure it is a number (and not NaN) + $a=substr("0$lino",-2).":".$1; + $exp{$a}++; # store exponents + $tot{substr("0$lino",-2)}++; # and keep a per DS total +@@ -146,11 +146,11 @@ while () { + $cdo=0; + if ($linea=~/^(.*)/) { $tstamp=$1; } # Grab timestamp + if ($linea=~/(.*)$/) { $tresto=$1; } # grab rest-of-line :-) +- if (/\s\d\.\d+e.(\d+)\s<\/v>/) { # are there DS's? ++ if (/\s?\d\.\d+e.(\d+)\s?<\/v>/) { # are there DS's? + @dump=split(/<\/v>/, $tresto); # split them + if ($linbak ne '') { + for ($lino=0;$lino<=$#dump-1;$lino++) { # for each DS: +- if ($dump[$lino]=~/\d\.\d+e.(\d+)\s/) { # grab number (and not a NaN) ++ if ($dump[$lino]=~/\d\.\d+e.(\d+)\s?/) { # grab number (and not a NaN) + $c=$&; + $a=$1*1; # and exponent + $b=substr("0$lino",-2).":$1"; # calculate the max percentage of this DS +diff --git a/ganglia.inc b/ganglia.inc +index 733196a0..df8634a6 100644 +--- a/ganglia.inc ++++ b/ganglia.inc +@@ -1,11 +1,11 @@ + + +-FIXCONFIG = $(top_srcdir)/scripts/fixconfig ++FIXCONFIG = $(top_builddir)/scripts/fixconfig + + # Unfortunately, we can't do this here with a pattern rule because + # that is a GNU make feature and is not fully portable + #%: %.in $(FIXCONFIG) +-# $(FIXCONFIG) $< ++# $(FIXCONFIG) $< $@ + + # For the moment, it is necessary to provide a rule for each file + # we want to generate - see the rule for ganglia-config in Makefile.am +diff --git a/ganglia.pod b/ganglia.pod +index 42c3a507..de709cbc 100644 +--- a/ganglia.pod ++++ b/ganglia.pod +@@ -1,5 +1,7 @@ + =pod + ++=encoding UTF-8 ++ + =for comment The ganglia documentation is written in POD (Plain Old Documentation) + format. If you want to edit this file but don't know the POD format, it is very + easy to learn. Visit http://www.linuxgazette.com/issue73/spiel.html for a nice intro +@@ -605,10 +607,12 @@ is only partially complete). + machine_type + mem_buffers Amount of buffered memory l,f + mem_cached Amount of cached memory l,f +- mem_free Amount of available memory l,f ++ mem_free Amount of free memory available l,f + mem_shared Amount of shared memory l,f ++ mem_slab Amount of in-kernel data struct cache l + mem_sreclaimable Amount of slab reclaimable memory l (kernel >= 2.6.19) +- mem_total Amount of available memory l,f ++ mem_available Amount of application memory available l (kernel >= 3.14) ++ mem_total Amount of total memory available l,f + mtu Network maximum transmission unit l,f + os_name Operating system name l,f + os_release Operating system release (version) l,f +diff --git a/gmetad-python/gmetad-python.service.in b/gmetad-python/gmetad-python.service.in +index 16918db7..11243979 100644 +--- a/gmetad-python/gmetad-python.service.in ++++ b/gmetad-python/gmetad-python.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Ganglia Meta Daemon in Python +-After=network.target ++After=network-online.target + + [Service] + ExecStart=@bindir@/gmetad.py -f +diff --git a/gmetad/export_helpers.c b/gmetad/export_helpers.c +index 2c126e2e..8ee3b6c8 100644 +--- a/gmetad/export_helpers.c ++++ b/gmetad/export_helpers.c +@@ -349,10 +349,11 @@ path_macro_replace(char *path, graphite_path_macro *patrn) + char *prefix; + char *suffix; + char *offset; ++ int i; + + strncpy(final, path, PATHSIZE); + strncpy(path_cp, path, PATHSIZE); +- for(int i=0; patrn[i].torepl != 0; i++){ ++ for(i=0; patrn[i].torepl != 0; i++){ + while((offset = strstr(path_cp, patrn[i].torepl))) + { + prefix=path_cp; //pointer to the beginning of path_cp (for clarity) +diff --git a/gmetad/gmetad.c b/gmetad/gmetad.c +index 60ade92c..21d5b2f3 100644 +--- a/gmetad/gmetad.c ++++ b/gmetad/gmetad.c +@@ -323,7 +323,7 @@ write_root_summary(datum_t *key, datum_t *val, void *arg) + return 0; + + /* Don't write a summary for metris that appears to be sFlow VM metrics */ +- if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strchr(name, '.')) != NULL && *(p+1) == 'v') ++ if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strrchr(name, '.')) != NULL && *(p+1) == 'v') + return 0; + + ganglia_scoreboard_inc(METS_SUMRZ_ROOT); +@@ -341,7 +341,8 @@ write_root_summary(datum_t *key, datum_t *val, void *arg) + + debug_msg("Writing Root Summary data for metric %s", name); + +- rc = write_data_to_rrd( NULL, NULL, name, sum, num, 15, 0, metric->slope); ++ rc = write_data_to_rrd( NULL, NULL, name, sum, num, 15, 0, ++ cstr_to_slope(getfield(metric->strings, metric->slope))); + if (rc) + { + err_msg("Unable to write meta data for metric %s to RRD", name); +@@ -610,12 +611,12 @@ main ( int argc, char *argv[] ) + /* Sum the new values */ + hash_foreach(root.authority, do_root_summary, NULL ); + +- /* summary completed */ +- pthread_mutex_unlock(root.sum_finished); +- + /* Save them to RRD */ + hash_foreach(root.metric_summary, write_root_summary, NULL); + ++ /* summary completed */ ++ pthread_mutex_unlock(root.sum_finished); ++ + /* Remember our last run */ + now = apr_time_now(); + last_metadata = now; //Updating global variable +diff --git a/gmetad/gmetad.service.in b/gmetad/gmetad.service.in +index 8234e90e..d7800655 100644 +--- a/gmetad/gmetad.service.in ++++ b/gmetad/gmetad.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Ganglia Meta Daemon +-After=network.target ++After=network-online.target + + [Service] + Type=forking +diff --git a/gmetad/process_xml.c b/gmetad/process_xml.c +index 15abc75c..fc28701e 100644 +--- a/gmetad/process_xml.c ++++ b/gmetad/process_xml.c +@@ -1172,7 +1172,7 @@ finish_processing_source(datum_t *key, datum_t *val, void *arg) + return 0; + + /* Don't save to RRD if this metrics appears to be an sFlow VM metrics */ +- if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strchr(name, '.')) != NULL && *(p+1) == 'v') ++ if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strrchr(name, '.')) != NULL && *(p+1) == 'v') + return 0; + + switch (tt->type) +diff --git a/gmetad/rrd_helpers.c b/gmetad/rrd_helpers.c +index 740799a5..e38c6514 100644 +--- a/gmetad/rrd_helpers.c ++++ b/gmetad/rrd_helpers.c +@@ -276,8 +276,8 @@ RRD_create( char *rrd, int summary, unsigned int step, + heartbeat); + argv[argc++] = sum; + if (summary) { +- sprintf(num,"DS:num:%s:%d:U:U", +- data_source_type, ++ sprintf(num,"DS:num:%s:%d:U:U", ++ "GAUGE", + heartbeat); + argv[argc++] = num; + } +diff --git a/gmetad/server.c b/gmetad/server.c +index 28188e75..24083122 100644 +--- a/gmetad/server.c ++++ b/gmetad/server.c +@@ -68,7 +68,11 @@ static const struct metricinfo + { + "cpu_sintr", cpu_sintr_func, g_float}, + { +- "cpu_steal", cpu_steal_func, g_uint16}, ++ "cpu_steal", cpu_steal_func, g_float}, ++ { ++ "cpu_guest", cpu_guest_func, g_float}, ++ { ++ "cpu_gnice", cpu_gnice_func, g_float}, + { + "load_one", load_one_func, g_float}, + { +@@ -115,6 +119,10 @@ static const struct metricinfo + #ifdef LINUX + "mem_sreclaimable", mem_sreclaimable_func, g_float}, + { ++ "mem_slab", mem_slab_func, g_float}, ++ { ++ "mem_available", mem_available_func, g_float}, ++ { + #endif + #ifdef SOLARIS + "bread_sec", bread_sec_func, g_float}, +diff --git a/gmetric/gmetric.c b/gmetric/gmetric.c +index 8e8da980..3328b08a 100644 +--- a/gmetric/gmetric.c ++++ b/gmetric/gmetric.c +@@ -113,7 +113,8 @@ main( int argc, char *argv[] ) + if(args_info.group_given) + { + char *last; +- for (char *group = apr_strtok(args_info.group_arg, ", ", &last); group != NULL; group = apr_strtok(NULL, ", ", &last)) { ++ char *group; ++ for (group = apr_strtok(args_info.group_arg, ", ", &last); group != NULL; group = apr_strtok(NULL, ", ", &last)) { + Ganglia_metadata_add(gmetric, "GROUP", group); + } + } +diff --git a/gmond/conf.pod b/gmond/conf.pod +index 96531574..a4971631 100644 +--- a/gmond/conf.pod ++++ b/gmond/conf.pod +@@ -166,6 +166,10 @@ For example, in a 32-bit Intel compatible Linux host that is usually: + + /usr/lib/ganglia + ++The B parameter is optional, and may be used to include arbitrary ++information in various output produced by Gmond, including the XML. ++It will be included as the I attribute of the XML tab. ++ + =head2 udp_send_channel + + You can define as many B sections as you like within +diff --git a/gmond/g25_config.c b/gmond/g25_config.c +index d295ab64..98721817 100644 +--- a/gmond/g25_config.c ++++ b/gmond/g25_config.c +@@ -373,5 +373,6 @@ print_ganglia_25_config( char *path ) + dotconf_cleanup(configfile); + + print_config(path, &gmond_config); ++ fclose(fp); + return 0; + } +diff --git a/gmond/gmond.c b/gmond/gmond.c +index 7790e981..04a4b024 100644 +--- a/gmond/gmond.c ++++ b/gmond/gmond.c +@@ -775,16 +775,15 @@ setup_listen_channels_pollset( void ) + + if(buffer) + { +- /* RB: getsockopt() returns double SO_RCVBUF since kernel reserves overhead space */ ++ /* NOTE: getsockopt() returns double SO_RCVBUF on Linux for reserved overhead space */ + if(rx_buf_sz!=(buffer*2)) + { +- err_msg("Error setting UDP receive buffer for port %d bind=%s to size: %d.\n", ++ err_msg("WARNING When setting UDP receive buffer for port %d bind=%s to size: %d.\n", + port, bindaddr? bindaddr: "unspecified", (apr_int32_t) buffer); +- err_msg("Reported buffer size by OS: %d : does not match config setting %d.\n", +- (int) (rx_buf_sz/2), (int) buffer); +- err_msg("NOTE: only supported on systems that have Apache Portable Runtime library version 0.9.4 or higher.\n"); +- err_msg("Check Operating System (kernel) limits, change or disable buffer size. Exiting.\n"); +- exit(EXIT_FAILURE); ++ err_msg("Reported raw buffer size by OS: %d : config setting %d. Unable to verify\n", ++ (int) rx_buf_sz, (int) buffer); ++ err_msg("NOTE: Linux will report twice the configured value. See socket(7).\n"); ++ err_msg("Check Operating System (kernel) limits, change or disable buffer size.\n"); + } + else + { /* RB: Eureka */ +@@ -1013,34 +1012,49 @@ Ganglia_host_get( char *remIP, apr_sockaddr_t *sa, Ganglia_metric_id *metric_id) + + /* split out the spoofed host name and ip address so that it can + * be used to get the spoofed host. */ +- if(metric_id && metric_id->spoof) ++ if(metric_id && metric_id->spoof && metric_id->host) + { +- char *spoofName; +- char *spoofIP; + int spoof_info_len; + + spoof_info_len = strlen(metric_id->host); +- buff = malloc(spoof_info_len+1); +- strncpy(buff, metric_id->host, spoof_info_len + 1); +- spoofIP = buff; +- if( !(spoofName = strchr(buff+1,':')) ){ +- err_msg("Incorrect format for spoof argument. exiting.\n"); +- if (spoofIP) debug_msg("spoofIP: %s \n",spoofIP); +- if (buff) debug_msg("buff: %s \n",buff); +- if (buff) free(buff); ++ /* don't bother if the host string is empty */ ++ if(spoof_info_len > 0) ++ { ++ char *spoofName; ++ char *spoofIP; ++ ++ buff = malloc(spoof_info_len+1); ++ if(buff == NULL) ++ { ++ err_msg("Unable to allocate spoof argument parse buffer. exiting.\n"); ++ return NULL; ++ } ++ strncpy(buff, metric_id->host, spoof_info_len + 1); ++ spoofIP = buff; ++ if( !(spoofName = strchr(buff+1,':')) ){ ++ err_msg("Incorrect format for spoof argument (no colon delimiter). exiting.\n"); ++ if (spoofIP) debug_msg("spoofIP: %s \n",spoofIP); ++ if (buff) debug_msg("buff: %s \n",buff); ++ if (buff) free(buff); ++ return NULL; ++ } ++ *spoofName = 0; ++ spoofName++; ++ if(!(*spoofName)){ ++ err_msg("Incorrect format for spoof argument (empty hostname). exiting.\n"); ++ if (buff) free(buff); ++ return NULL; ++ } ++ debug_msg(" spoofName: %s spoofIP: %s \n",spoofName,spoofIP); ++ ++ hostname = spoofName; ++ remoteip = spoofIP; ++ } ++ else ++ { ++ err_msg("Incorrect format for spoof argument (host string empty). exiting.\n"); + return NULL; +- } +- *spoofName = 0; +- spoofName++; +- if(!(*spoofName)){ +- err_msg("Incorrect format for spoof argument. exiting.\n"); +- if (buff) free(buff); +- return NULL; +- } +- debug_msg(" spoofName: %s spoofIP: %s \n",spoofName,spoofIP); +- +- hostname = spoofName; +- remoteip = spoofIP; ++ } + } + + apr_thread_mutex_lock(hosts_mutex); +@@ -2030,13 +2044,20 @@ process_tcp_accept_channel(const apr_pollfd_t *desc, apr_time_t now) + channel = desc->client_data; + + /* Create a context for the client connection */ +- apr_pool_create(&client_context, global_context); ++ status = apr_pool_create(&client_context, global_context); ++ if(status != APR_SUCCESS) ++ { ++ return; ++ } + + /* Accept the connection */ + status = apr_socket_accept(&client, server, client_context); + if(status != APR_SUCCESS) + { +- goto close_accept_socket; ++ debug_msg("failed to accept"); ++ /* Failed to accept, socket was not created ++ * Clear a prepared client context */ ++ goto clear_client_context; + } + + /* Set the timeout for writing to the client */ +@@ -2144,6 +2165,7 @@ process_tcp_accept_channel(const apr_pollfd_t *desc, apr_time_t now) + close_accept_socket: + apr_socket_shutdown(client, APR_SHUTDOWN_READ); + apr_socket_close(client); ++clear_client_context: + apr_pool_destroy(client_context); + } + +@@ -2298,6 +2320,7 @@ load_metric_modules( void ) + { + cfg_t *tmp; + int j; ++ apr_hash_t *modules_loaded = apr_hash_make(global_context); + + tmp = cfg_getsec( config_file, "modules"); + for (j = 0; j < cfg_size(tmp, "module"); j++) +@@ -2309,6 +2332,7 @@ load_metric_modules( void ) + apr_array_header_t *modParams_list = NULL; + int k, modEnabled; + apr_status_t merge_ret; ++ char *module_key = NULL; + + cfg_t *module = cfg_getnsec(tmp, "module", j); + +@@ -2345,6 +2369,17 @@ load_metric_modules( void ) + } + modName = cfg_getstr(module, "name"); + modparams = cfg_getstr(module, "params"); ++ ++ ++ /* Check that we haven't loaded this module already, now ++ * that we've pulled the module name and path */ ++ module_key = apr_pstrcat(global_context, modName, ":", modPath, NULL); ++ debug_msg("loading %s @ %s", modName, modPath); ++ if (NULL != apr_hash_get(modules_loaded, module_key, APR_HASH_KEY_STRING)) { ++ err_quit("Attempt to load module %s @ %s more than once.", modName, modPath); ++ continue; ++ } ++ + modParams_list = apr_array_make(global_context, 2, sizeof(mmparam)); + + for (k = 0; k < cfg_size(module, "param"); k++) +@@ -2372,6 +2407,7 @@ load_metric_modules( void ) + continue; + } + debug_msg("loaded module: %s", modName); ++ apr_hash_set(modules_loaded, module_key, APR_HASH_KEY_STRING, apr_pstrdup(global_context, "true")); + + /* + * Retrieve the pointer to the module structure through the module name. +@@ -2976,7 +3012,13 @@ Ganglia_collection_group_send( Ganglia_collection_group *group, apr_time_t now) + 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, (char *)( override_ip != NULL ? override_ip : override_hostname ), ":", (char *) override_hostname, NULL); ++ /* Since cb will live beyond this function call, we need to ++ * allocate the host field from the global pool and NOT the ++ * temporary gm_pool from the metric object. (Note that ++ * Ganglia_metric_callback objects are allocated from ++ * global_context elsewhere in this file.) ++ */ ++ cb->msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrcat(global_context, (char *)( override_ip != NULL ? override_ip : override_hostname ), ":", (char *) 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))); +@@ -3294,6 +3336,7 @@ main ( int argc, char *argv[] ) + { + apr_time_t now, next_collection, last_cleanup; + apr_pool_t *cleanup_context; ++ apr_thread_t *tcp_listener_thread = NULL; + + gmond_argv = argv; + +@@ -3415,8 +3458,7 @@ main ( int argc, char *argv[] ) + /* Create TCP listener thread */ + if(!deaf) + { +- apr_thread_t *thread; +- if (apr_thread_create(&thread, NULL, tcp_listener, NULL, global_context) != APR_SUCCESS) ++ if (apr_thread_create(&tcp_listener_thread, NULL, tcp_listener, NULL, global_context) != APR_SUCCESS) + { + err_msg("Failed to create TCP listener thread. Exiting.\n"); + exit(EXIT_FAILURE); +@@ -3477,6 +3519,16 @@ main ( int argc, char *argv[] ) + } + } + ++ if(tcp_listener_thread) ++ { ++ apr_status_t status = SUCCESS; ++ if((status = apr_thread_join(&status, tcp_listener_thread)) != APR_SUCCESS) ++ { ++ char buff[512]; ++ debug_msg("apr_thread_join returned unexpected status %d = %s\n", status, apr_strerror(status, buff, 511)); ++ } ++ } ++ + apr_pool_destroy(global_context); + + if(reload_required == 1) +diff --git a/gmond/gmond.service.in b/gmond/gmond.service.in +index 3fd136b4..13774e80 100644 +--- a/gmond/gmond.service.in ++++ b/gmond/gmond.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Ganglia Monitor Daemon +-After=network.target ++After=network-online.target + + [Service] + Type=forking +diff --git a/gmond/modules/cpu/mod_cpu.c b/gmond/modules/cpu/mod_cpu.c +index c5323a7b..f510dabb 100644 +--- a/gmond/modules/cpu/mod_cpu.c ++++ b/gmond/modules/cpu/mod_cpu.c +@@ -58,6 +58,10 @@ static g_val_t cpu_metric_handler ( int metric_index ) + return cpu_sintr_func(); + case 10: + return cpu_steal_func(); ++ case 11: ++ return cpu_guest_func(); ++ case 12: ++ return cpu_gnice_func(); + } + + /* default case */ +@@ -78,6 +82,8 @@ static Ganglia_25metric cpu_metric_info[] = + {0, "cpu_intr", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_intr"}, + {0, "cpu_sintr", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_sintr"}, + {0, "cpu_steal", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_steal"}, ++ {0, "cpu_guest", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_guest"}, ++ {0, "cpu_gnice", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_gnice"}, + {0, NULL} + + }; +diff --git a/gmond/modules/cpu/mod_multicpu.c b/gmond/modules/cpu/mod_multicpu.c +index 253e0969..f57bad76 100644 +--- a/gmond/modules/cpu/mod_multicpu.c ++++ b/gmond/modules/cpu/mod_multicpu.c +@@ -76,6 +76,8 @@ static cpu_util *cpu_wio = NULL; + static cpu_util *cpu_intr = NULL; + static cpu_util *cpu_sintr = NULL; + static cpu_util *cpu_steal = NULL; ++static cpu_util *cpu_guest = NULL; ++static cpu_util *cpu_gnice = NULL; + + /* + * A helper function to determine the number of cpustates in /proc/stat (MKN) +@@ -102,6 +104,10 @@ static void init_cpu_info (void) + ** Loop over file until next "cpu" token is found. + ** i=4 : Linux 2.4.x + ** i=7 : Linux 2.6.x ++ ** ++ ** i=8 : Linux 2.6.11+ ++ ** i=9 : Linux 2.6.24+ ++ ** i=10: Linux 2.6.33+ + */ + while (strncmp(p,"cpu",3)) { + p = skip_token(p); +@@ -190,7 +196,8 @@ static char *find_cpu (char *p, int cpu_index, double *total_jiffies) + static double total_jiffies_func (char *p) + { + unsigned long user_jiffies, nice_jiffies, system_jiffies, idle_jiffies, +- wio_jiffies, irq_jiffies, sirq_jiffies, steal_jiffies; ++ wio_jiffies, irq_jiffies, sirq_jiffies, steal_jiffies, ++ guest_jiffies, gnice_jiffies; + + user_jiffies = strtod( p, &p ); + p = skip_whitespace(p); +@@ -216,6 +223,10 @@ static double total_jiffies_func (char *p) + + p = skip_whitespace(p); + steal_jiffies = strtod( p , &p ); ++ p = skip_whitespace(p); ++ guest_jiffies = strtod( p , &p ); /* "guest" included in user already */ ++ p = skip_whitespace(p); ++ gnice_jiffies = strtod( p , &p ); /* "gnice" included in nice already */ + return user_jiffies + nice_jiffies + system_jiffies + idle_jiffies + + wio_jiffies + irq_jiffies + sirq_jiffies + steal_jiffies; + } +@@ -457,7 +468,7 @@ static cpu_util *init_metric (apr_pool_t *p, apr_array_header_t *ar, int cpu_cou + static g_val_t multi_cpu_steal_func (int cpu_index) + { + char *p; +- cpu_util *cpu = &(cpu_user[cpu_index]); ++ cpu_util *cpu = &(cpu_steal[cpu_index]); + + p = update_file(&proc_stat); + if((proc_stat.last_read.tv_sec != cpu->stamp.tv_sec) && +@@ -479,6 +490,59 @@ static g_val_t multi_cpu_steal_func (int cpu_index) + return cpu->val; + } + ++static g_val_t multi_cpu_guest_func (int cpu_index) ++{ ++ char *p; ++ cpu_util *cpu = &(cpu_guest[cpu_index]); ++ ++ p = update_file(&proc_stat); ++ if((proc_stat.last_read.tv_sec != cpu->stamp.tv_sec) && ++ (proc_stat.last_read.tv_usec != cpu->stamp.tv_usec)) { ++ cpu->stamp = proc_stat.last_read; ++ ++ p = find_cpu (p, cpu_index, &cpu->curr_total_jiffies); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_whitespace(p); ++ calculate_utilization (p, cpu); ++ } ++ ++ return cpu->val; ++} ++ ++static g_val_t multi_cpu_gnice_func (int cpu_index) ++{ ++ char *p; ++ cpu_util *cpu = &(cpu_gnice[cpu_index]); ++ ++ p = update_file(&proc_stat); ++ if((proc_stat.last_read.tv_sec != cpu->stamp.tv_sec) && ++ (proc_stat.last_read.tv_usec != cpu->stamp.tv_usec)) { ++ cpu->stamp = proc_stat.last_read; ++ ++ p = find_cpu (p, cpu_index, &cpu->curr_total_jiffies); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_whitespace(p); ++ calculate_utilization (p, cpu); ++ } ++ ++ return cpu->val; ++} ++ + static int ex_metric_init (apr_pool_t *p) + { + int i; +@@ -515,6 +579,10 @@ static int ex_metric_init (apr_pool_t *p) + "executing at the sintr level"); + cpu_steal = init_metric (pool, metric_info, cpu_count, "multicpu_steal", + "Percentage of CPU preempted by the hypervisor"); ++ cpu_guest = init_metric (pool, metric_info, cpu_count, "multicpu_guest", ++ "Percentage of CPU running a virtual CPU"); ++ cpu_gnice = init_metric (pool, metric_info, cpu_count, "multicpu_gnice", ++ "Percentage of CPU running a niced guest"); + + /* Add a terminator to the array and replace the empty static metric definition + array with the dynamic array that we just created +@@ -574,6 +642,12 @@ static g_val_t ex_metric_handler ( int metric_index ) + if (strcmp(name, "multicpu_steal") == 0) + return multi_cpu_steal_func(index); + ++ if (strcmp(name, "multicpu_guest") == 0) ++ return multi_cpu_guest_func(index); ++ ++ if (strcmp(name, "multicpu_gnice") == 0) ++ return multi_cpu_gnice_func(index); ++ + /* default case */ + val.f = 0; + return val; +diff --git a/gmond/modules/memory/mod_mem.c b/gmond/modules/memory/mod_mem.c +index feb8d99c..98c0812c 100644 +--- a/gmond/modules/memory/mod_mem.c ++++ b/gmond/modules/memory/mod_mem.c +@@ -50,6 +50,10 @@ static g_val_t mem_metric_handler ( int metric_index ) + #ifdef LINUX + case 7: + return mem_sreclaimable_func(); ++ case 8: ++ return mem_slab_func(); ++ case 9: ++ return mem_available_func(); + #endif + #if HPUX + case 7: +@@ -79,6 +83,8 @@ static Ganglia_25metric mem_metric_info[] = + {0, "swap_total", 1200, GANGLIA_VALUE_FLOAT, "KB", "zero", "%.0f", UDP_HEADER_SIZE+8, "Total amount of swap space displayed in KBs"}, + #ifdef LINUX + {0, "mem_sreclaimable", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "Amount of reclaimable slab memory"}, ++ {0, "mem_slab", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "Amount of in-kernel data structures cache"}, ++ {0, "mem_available", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "Estimate of how much memory is available"}, + #endif + #if HPUX + {0, "mem_arm", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "mem_arm"}, +diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py +index e33e5ea9..580e8931 100755 +--- a/gmond/python_modules/apache_status/apache_status.py ++++ b/gmond/python_modules/apache_status/apache_status.py +@@ -86,6 +86,10 @@ def get_metrics(): + for sck in split_line[1]: + metrics[ Scoreboard_bykey[sck] ] += 1 + else: ++ # Apache > 2.4.16 inserts the hostname as the first line, so ignore ++ if len(split_line) == 1: ++ continue ++ + if long_metric_name in Metric_Map: + metric_name = Metric_Map[long_metric_name] + else: +diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py +index 3f9b45d0..456704b8 100644 +--- a/gmond/python_modules/network/multi_interface.py ++++ b/gmond/python_modules/network/multi_interface.py +@@ -247,7 +247,7 @@ def get_aggregates(name): + except KeyError: + delta = 0.0 + +- sum += delta ++ sum += delta + + return sum + +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index f9c6795f..66c378d2 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -19,6 +19,8 @@ stats_files = ["/proc/net/netstat", "/proc/net/snmp"] + + LAST_METRICS = copy.deepcopy(METRICS) + METRICS_CACHE_MAX = 5 ++# Metrics that are not counters but absolute values ++ABSOLUTE_VALUES = ["currestab"] + + stats_pos = {} + +@@ -46,6 +48,8 @@ def get_metrics(): + count = 0 + metrics = re.split("\s+", line) + metric_group = metrics[0].replace(":", "").lower() ++ if metric_group not in stats_pos: ++ continue + new_metrics[metric_group] = dict() + for value in metrics: + # Skip first +@@ -69,12 +73,15 @@ def get_metrics(): + def get_value(name): + """Return a value for the requested metric""" + +- metrics = get_metrics()[0] ++ # get metrics ++ [curr_metrics, last_metrics] = get_metrics() + +- name = name[len(NAME_PREFIX):] # remove prefix from name ++ parts = name.split("_") ++ group = parts[0] ++ metric = "_".join(parts[1:]) + + try: +- result = metrics['data'][name] ++ result = float(curr_metrics['data'][group][metric]) + except StandardError: + result = 0 + +@@ -209,11 +216,17 @@ def metric_init(params): + + for group in stats_pos: + for item in stats_pos[group]: +- descriptors.append(create_desc(Desc_Skel, { ++ if stats_pos[group][item] in ABSOLUTE_VALUES: ++ descriptors.append(create_desc(Desc_Skel, { + "name" : group + "_" + stats_pos[group][item], +- "description": stats_pos[group][item], +- 'groups' : group +- })) ++ "call_back" : get_value, ++ "groups" : group ++ })) ++ else: ++ descriptors.append(create_desc(Desc_Skel, { ++ "name" : group + "_" + stats_pos[group][item], ++ "groups" : group ++ })) + + descriptors.append(create_desc(Desc_Skel, { + "name" : "tcpext_tcploss_percentage", +@@ -221,7 +234,7 @@ def metric_init(params): + "description": "TCP percentage loss, tcploss / insegs + outsegs", + "units" : "pct", + 'groups' : 'tcpext' +- })) ++ })) + + descriptors.append(create_desc(Desc_Skel, { + "name" : "tcp_attemptfails_percentage", +@@ -229,7 +242,7 @@ def metric_init(params): + "description": "TCP attemptfail percentage, tcpattemptfail / insegs + outsegs", + "units" : "pct", + 'groups' : 'tcp' +- })) ++ })) + + descriptors.append(create_desc(Desc_Skel, { + "name" : "tcp_retrans_percentage", +@@ -237,7 +250,7 @@ def metric_init(params): + "description": "TCP retrans percentage, retranssegs / insegs + outsegs", + "units" : "pct", + 'groups' : 'tcp' +- })) ++ })) + + return descriptors + +@@ -247,12 +260,12 @@ def metric_cleanup(): + pass + + +-#This code is for debugging and unit testing ++# This code is for debugging and unit testing + if __name__ == '__main__': + descriptors = metric_init(PARAMS) + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) ++ print '%s = %s' % (d['name'], v) + print 'Sleeping 15 seconds' + time.sleep(15) +diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py +index b26849b2..93ff9a9c 100644 +--- a/gmond/python_modules/process/procstat.py ++++ b/gmond/python_modules/process/procstat.py +@@ -383,6 +383,8 @@ def metric_init(params): + + mem = { + 'units': 'B', ++ 'value_type': 'float', ++ 'format': '%.0f', + 'description': 'The total memory utilization'} + ) + +diff --git a/gmond/sflow.c b/gmond/sflow.c +index 80154ed7..5e633634 100644 +--- a/gmond/sflow.c ++++ b/gmond/sflow.c +@@ -303,7 +303,8 @@ submit_sflow_string(Ganglia_host *hostdata, char *metric_prefix, EnumSFLOWGMetri + char mtitle_buf[SFLOW_MAX_METRIC_NAME_LEN]; + if(ok || sflowCFG.submit_null_str) { + set_metric_name_and_title(&mname, &mtitle, mname_buf, mtitle_buf, metric_prefix, tag); +- fmsg.id = vmsg.id = gmetric_uint; ++ //fmsg.id = vmsg.id = gmetric_uint; ++ fmsg.id = vmsg.id = gmetric_string; + fmsg.Ganglia_metadata_msg_u.gfull.metric.type = "string"; + vmsg.Ganglia_value_msg_u.gstr.metric_id.name = mname; + vmsg.Ganglia_value_msg_u.gstr.str = (ok ? (char *)val : sflowCFG.null_str); +@@ -400,7 +401,7 @@ process_struct_CPU(SFlowXDR *x, SFlowDataSource *dataSource, Ganglia_host *hostd + + if(steal_and_guest) { + cpu_total += delta_cpu_steal; +- /* Note: cpu_guest is included in cpu_idle ++ /* Note: cpu_guest is included in cpu_user + * and cpu_guest_nice is included in cpu_nice + * so they do not contribute to cpu_total. + */ +@@ -1188,6 +1189,7 @@ processCounterSample(SFlowXDR *x, char **errorMsg) + SFLOWXDR_skip(x,4); + + machine_type = SFLOWXDR_next(x); ++ + os_name = SFLOWXDR_next(x); + osrelease_len = SFLOWXDR_next(x); + if(osrelease_len > 0 && osrelease_len <= SFLOW_MAX_OSRELEASE_LEN) { +diff --git a/gmond/sflow_gmetric.h b/gmond/sflow_gmetric.h +index d85c36e7..f8811da2 100644 +--- a/gmond/sflow_gmetric.h ++++ b/gmond/sflow_gmetric.h +@@ -20,7 +20,7 @@ SFLOW_GMETRIC(SFLOW_M_cpu_intr, "cpu_intr", "", GANGLIA_SLOPE_BOTH, "%.2f", "cpu + SFLOW_GMETRIC(SFLOW_M_cpu_sintr, "cpu_sintr", "", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Soft Interrupts" ) + SFLOW_GMETRIC(SFLOW_M_cpu_steal, "cpu_steal", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Steal" ) + SFLOW_GMETRIC(SFLOW_M_cpu_guest, "cpu_guest", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Guest" ) +-SFLOW_GMETRIC(SFLOW_M_cpu_guest_nice, "cpu_guest_nice", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Guest Nice" ) ++SFLOW_GMETRIC(SFLOW_M_cpu_guest_nice, "cpu_gnice", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Guest Nice" ) + SFLOW_GMETRIC(SFLOW_M_interrupts, "interrupts", "", GANGLIA_SLOPE_BOTH, "%.0f", "cpu", NULL, "Interrupts" ) + SFLOW_GMETRIC(SFLOW_M_contexts, "contexts", "", GANGLIA_SLOPE_BOTH, "%.0f", "cpu", NULL, "Context Switches" ) + SFLOW_GMETRIC(SFLOW_M_mem_total, "mem_total", "KB", GANGLIA_SLOPE_ZERO, "%.0f", "memory", NULL, "Memory Total" ) +diff --git a/lib/default_conf.h.in b/lib/default_conf.h.in +index 142115f6..3f9e5b9f 100644 +--- a/lib/default_conf.h.in ++++ b/lib/default_conf.h.in +@@ -71,7 +71,7 @@ udp_recv_channel {\n\ + bind = 239.2.11.71\n\ + retry_bind = true\n\ + # Size of the UDP buffer. If you are handling lots of metrics you really\n\ +- # should bump it up to e.g. 10MB or even higher.\n\ ++ # should bump it up to e.g. 10MB or even higher.\n\ + # buffer = 10485760\n\ + }\n\ + \n\ +@@ -270,6 +270,19 @@ collection_group {\n\ + title = \"CPU sintr\"\n\ + }\n\ + */\n\ ++ /* The next two metrics are optional if you want more detail...\n\ ++ ... since they are accounted for in cpu_user and cpu_nice.\n\ ++ metric {\n\ ++ name = \"cpu_guest\"\n\ ++ value_threshold = \"1.0\"\n\ ++ title = \"CPU guest\"\n\ ++ }\n\ ++ metric {\n\ ++ name = \"cpu_gnice\"\n\ ++ value_threshold = \"1.0\"\n\ ++ title = \"CPU gnice\"\n\ ++ }\n\ ++ */\n\ + }\n\ + \n\ + collection_group {\n\ +@@ -397,6 +410,24 @@ include (\"" SYSCONFDIR "/conf.d/*.conf\")\n\ + \n\ + " + ++#define LINUX_SPECIFIC_CONFIGURATION "\ ++collection_group {\n\ ++ collect_every = 40\n\ ++ time_threshold = 180\n\ ++ metric {\n\ ++ name = \"mem_available\"\n\ ++ value_threshold = \"1024.0\"\n\ ++ title = \"Available Memory\"\n\ ++ }\n\ ++ metric {\n\ ++ name = \"mem_sreclaimable\"\n\ ++ value_threshold = \"1024.0\"\n\ ++ title = \"Slab Memory Reclaimable\"\n\ ++ }\n\ ++}\n\ ++\n\ ++" ++ + #define SOLARIS_SPECIFIC_CONFIGURATION "\ + /* solaris specific metrics begin */\n\ + collection_group {\n\ +diff --git a/lib/hash.c b/lib/hash.c +index a1d41e76..de922533 100644 +--- a/lib/hash.c ++++ b/lib/hash.c +@@ -346,6 +346,10 @@ hash_delete (datum_t *key, hash_t * hash) + for (; bucket != NULL; last = bucket, bucket = bucket->next) + { + node_t tmp; ++ if (bucket->key && !hash_keycmp(hash, key, bucket->key)) ++ { ++ continue; ++ } + if (bucket == &hash->node[i]) + { + tmp.key = bucket->key; +diff --git a/lib/libgmond.c b/lib/libgmond.c +index f5eb32f1..d378d8e9 100644 +--- a/lib/libgmond.c ++++ b/lib/libgmond.c +@@ -26,7 +26,11 @@ + #include + #include + +-static char myhost[APRMAXHOSTLEN+1]; ++/* functions throughout this file will initialize this ++ * variable if myhost[0] == '\0', so ensure the compiler ++ * initializes it as an empty string: ++ */ ++static char myhost[APRMAXHOSTLEN+1] = ""; + + /***** IMPORTANT ************ + Any changes that you make to this file need to be reconciled in ./conf.pod +@@ -210,6 +214,9 @@ build_default_gmond_configuration(Ganglia_pool p) + default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, SFLOW_CONFIGURATION, NULL); + #endif + default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, COLLECTION_GROUP_LIST, NULL); ++#if LINUX ++ default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, LINUX_SPECIFIC_CONFIGURATION, NULL); ++#endif + #if SOLARIS + default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, SOLARIS_SPECIFIC_CONFIGURATION, NULL); + #endif +diff --git a/libmetrics/darwin/metrics.c b/libmetrics/darwin/metrics.c +index 690e88ed..c9940eba 100644 +--- a/libmetrics/darwin/metrics.c ++++ b/libmetrics/darwin/metrics.c +@@ -37,7 +37,7 @@ + #include + #include + +-/* Added for disk statstics */ ++/* Added for disk statistics */ + #include + #include + #include +@@ -467,6 +467,28 @@ cpu_sintr_func ( void ) + return val; + } + ++/* ++** FIXME ++*/ ++g_val_t ++cpu_guest_func ( void ) ++{ ++ g_val_t val; ++ val.f = 0.0; ++ return val; ++} ++ ++/* ++** FIXME ++*/ ++g_val_t ++cpu_gnice_func ( void ) ++{ ++ g_val_t val; ++ val.f = 0.0; ++ return val; ++} ++ + + g_val_t + bytes_in_func ( void ) +diff --git a/libmetrics/libmetrics.h b/libmetrics/libmetrics.h +index fab9a092..947a387f 100644 +--- a/libmetrics/libmetrics.h ++++ b/libmetrics/libmetrics.h +@@ -55,6 +55,8 @@ void libmetrics_init( void ); + g_val_t cpu_intr_func(void); + g_val_t cpu_sintr_func(void); + g_val_t cpu_steal_func(void); ++ g_val_t cpu_guest_func(void); ++ g_val_t cpu_gnice_func(void); + g_val_t bytes_in_func(void); + g_val_t bytes_out_func(void); + g_val_t pkts_in_func(void); +@@ -77,7 +79,10 @@ void libmetrics_init( void ); + g_val_t location_func(void); + + #ifdef LINUX ++ g_val_t mem_available_func (void); ++ g_val_t mem_slab_func (void); + g_val_t mem_sreclaimable_func (void); ++ g_val_t mem_sunreclaim_func (void); + #endif + + /* the following are additional internal metrics added by swagner +diff --git a/libmetrics/linux/metrics.c b/libmetrics/linux/metrics.c +index 62e7314b..456abe33 100644 +--- a/libmetrics/linux/metrics.c ++++ b/libmetrics/linux/metrics.c +@@ -104,6 +104,8 @@ num_cpustates_func ( void ) + ** i=4 : Linux 2.4.x + ** i=7 : Linux 2.6.x + ** i=8 : Linux 2.6.11 ++** i=9 : Linux 2.6.24 ++** i=10 : Linux 2.6.33 + */ + while (strncmp(p, "cpu", 3)) { + p = skip_token(p); +@@ -262,7 +264,11 @@ void update_ifdata ( char *caller ) + l_bytes_in += rbi - ns->rbi; + } else { + debug_msg("update_ifdata(%s) - Overflow in rbi: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rbi,rbi); +- l_bytes_in += STAT_MAX - ns->rbi + rbi; ++ if ( ns->rbi <= ULONG_MAX ) { /* assume it's more reasonable that the counter rolled over at ULONG_MAX than ULLONG_MAX */ ++ l_bytes_in += ULONG_MAX - ns->rbi + rbi; ++ } else { ++ l_bytes_in += STAT_MAX - ns->rbi + rbi; ++ } + } + ns->rbi = rbi; + +@@ -271,7 +277,11 @@ void update_ifdata ( char *caller ) + l_pkts_in += rpi - ns->rpi; + } else { + debug_msg("updata_ifdata(%s) - Overflow in rpi: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rpi,rpi); +- l_pkts_in += STAT_MAX - ns->rpi + rpi; ++ if ( ns->rpi <= ULONG_MAX ) { ++ l_pkts_in += ULONG_MAX - ns->rpi + rpi; ++ } else { ++ l_pkts_in += STAT_MAX - ns->rpi + rpi; ++ } + } + ns->rpi = rpi; + +@@ -284,7 +294,11 @@ void update_ifdata ( char *caller ) + l_bytes_out += rbo - ns->rbo; + } else { + debug_msg("update_ifdata(%s) - Overflow in rbo: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rbo,rbo); +- l_bytes_out += STAT_MAX - ns->rbo + rbo; ++ if ( ns->rbo <= ULONG_MAX ) { ++ l_bytes_out += ULONG_MAX - ns->rbo + rbo; ++ } else { ++ l_bytes_out += STAT_MAX - ns->rbo + rbo; ++ } + } + ns->rbo = rbo; + +@@ -293,7 +307,11 @@ void update_ifdata ( char *caller ) + l_pkts_out += rpo - ns->rpo; + } else { + debug_msg("update_ifdata(%s) - Overflow in rpo: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rpo,rpo); +- l_pkts_out += STAT_MAX - ns->rpo + rpo; ++ if ( ns->rpo <= ULONG_MAX ) { ++ l_pkts_out += ULONG_MAX - ns->rpo + rpo; ++ } else { ++ l_pkts_out += STAT_MAX - ns->rpo + rpo; ++ } + } + ns->rpo = rpo; + } +@@ -593,36 +611,30 @@ machine_type_func ( void ) + + #ifdef __i386__ + snprintf(val.str, MAX_G_STRING_SIZE, "x86"); +-#endif +-#ifdef __x86_64__ ++#elif __x86_64__ + snprintf(val.str, MAX_G_STRING_SIZE, "x86_64"); +-#endif +-#ifdef __ia64__ ++#elif __ia64__ + snprintf(val.str, MAX_G_STRING_SIZE, "ia64"); +-#endif +-#ifdef __sparc__ ++#elif __sparc__ + snprintf(val.str, MAX_G_STRING_SIZE, "sparc"); +-#endif +-#ifdef __alpha__ ++#elif __alpha__ + snprintf(val.str, MAX_G_STRING_SIZE, "alpha"); +-#endif +-#ifdef __powerpc__ ++#elif __powerpc__ + snprintf(val.str, MAX_G_STRING_SIZE, "powerpc"); +-#endif +-#ifdef __m68k__ ++#elif __m68k__ + snprintf(val.str, MAX_G_STRING_SIZE, "m68k"); +-#endif +-#ifdef __mips__ ++#elif __mips__ + snprintf(val.str, MAX_G_STRING_SIZE, "mips"); +-#endif +-#ifdef __arm__ ++#elif __arm__ + snprintf(val.str, MAX_G_STRING_SIZE, "arm"); +-#endif +-#ifdef __hppa__ ++#elif __aarch64__ ++ snprintf(val.str, MAX_G_STRING_SIZE, "aarch64"); ++#elif __hppa__ + snprintf(val.str, MAX_G_STRING_SIZE, "hppa"); +-#endif +-#ifdef __s390__ ++#elif __s390__ + snprintf(val.str, MAX_G_STRING_SIZE, "s390"); ++#else ++ snprintf(val.str, MAX_G_STRING_SIZE, "unknown"); + #endif + + return val; +@@ -691,6 +703,8 @@ total_jiffies_func ( void ) + p = skip_whitespace(p); + steal_jiffies = strtod( p, &p ); + ++ /* guest is included in user already, and gnice is included in nice */ ++ + return user_jiffies + nice_jiffies + system_jiffies + idle_jiffies + + wio_jiffies + irq_jiffies + sirq_jiffies + steal_jiffies; + } +@@ -1056,6 +1070,89 @@ cpu_steal_func ( void ) + return val; + } + ++g_val_t ++cpu_guest_func ( void ) ++{ ++ char *p; ++ static g_val_t val; ++ static struct timeval stamp={0,0}; ++ static double last_guest_jiffies, guest_jiffies, ++ last_total_jiffies, total_jiffies, diff; ++ ++ p = update_file(&proc_stat); ++ if((proc_stat.last_read.tv_sec != stamp.tv_sec) && ++ (proc_stat.last_read.tv_usec != stamp.tv_usec)) { ++ stamp = proc_stat.last_read; ++ ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ guest_jiffies = strtod( p , (char **)NULL ); ++ total_jiffies = total_jiffies_func(); ++ ++ diff = guest_jiffies - last_guest_jiffies; ++ ++ if ( diff ) ++ val.f = (diff/(total_jiffies - last_total_jiffies))*100; ++ else ++ val.f = 0.0; ++ ++ last_guest_jiffies = guest_jiffies; ++ last_total_jiffies = total_jiffies; ++ ++ } ++ ++ return val; ++} ++ ++g_val_t ++cpu_gnice_func ( void ) ++{ ++ char *p; ++ static g_val_t val; ++ static struct timeval stamp={0,0}; ++ static double last_gnice_jiffies, gnice_jiffies, ++ last_total_jiffies, total_jiffies, diff; ++ ++ p = update_file(&proc_stat); ++ if((proc_stat.last_read.tv_sec != stamp.tv_sec) && ++ (proc_stat.last_read.tv_usec != stamp.tv_usec)) { ++ stamp = proc_stat.last_read; ++ ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ p = skip_token(p); ++ gnice_jiffies = strtod( p , (char **)NULL ); ++ total_jiffies = total_jiffies_func(); ++ ++ diff = gnice_jiffies - last_gnice_jiffies; ++ ++ if ( diff ) ++ val.f = (diff/(total_jiffies - last_total_jiffies))*100; ++ else ++ val.f = 0.0; ++ ++ last_gnice_jiffies = gnice_jiffies; ++ last_total_jiffies = total_jiffies; ++ ++ } ++ ++ return val; ++} ++ + g_val_t + load_one_func ( void ) + { +@@ -1150,6 +1247,23 @@ mem_free_func ( void ) + return val; + } + ++g_val_t ++mem_available_func ( void ) ++{ ++ char *p; ++ g_val_t val; ++ ++ p = strstr( update_file(&proc_meminfo), "MemAvailable:" ); ++ if (p) { ++ p = skip_token(p); ++ val.f = atof( p ); ++ } else { ++ val.f = 0.0; ++ } ++ ++ return val; ++} ++ + g_val_t + mem_shared_func ( void ) + { +@@ -1187,6 +1301,23 @@ mem_buffers_func ( void ) + return val; + } + ++g_val_t ++mem_slab_func ( void ) ++{ ++ char *p; ++ g_val_t val; ++ ++ p = strstr( update_file(&proc_meminfo), "Slab:" ); ++ if(p) { ++ p = skip_token(p); ++ val.f = atof( p ); ++ } else { ++ val.f = 0; ++ } ++ ++ return val; ++} ++ + g_val_t + mem_sreclaimable_func ( void ) + { +@@ -1204,6 +1335,23 @@ mem_sreclaimable_func ( void ) + return val; + } + ++g_val_t ++mem_sunreclaim_func ( void ) ++{ ++ char *p; ++ g_val_t val; ++ ++ p = strstr( update_file(&proc_meminfo), "SUnreclaim:" ); ++ if(p) { ++ p = skip_token(p); ++ val.f = atof( p ); ++ } else { ++ val.f = 0; ++ } ++ ++ return val; ++} ++ + g_val_t + mem_cached_func ( void ) + { +@@ -1388,7 +1536,8 @@ float find_disk_space(double *total_size, double *total_free) + if (!strncmp(mode, "ro", 2)) continue; + if (remote_mount(device, type)) continue; + if (strncmp(device, "/dev/", 5) != 0 && +- strncmp(device, "/dev2/", 6) != 0) continue; ++ strncmp(device, "/dev2/", 6) != 0 && ++ strncmp(type, "zfs", 3) != 0) continue; + thispct = device_space(mount, device, total_size, total_free); + debug_msg("Counting device %s (%.2f %%)", device, thispct); + if (!max || max + #include + #include ++#include + + #include + #include +@@ -485,6 +486,28 @@ cpu_steal_func ( void ) + return val; + } + ++/* ++** FIXME ++*/ ++g_val_t ++cpu_guest_func ( void ) ++{ ++ g_val_t val; ++ val.f = 0.0; ++ return val; ++} ++ ++/* ++** FIXME ++*/ ++g_val_t ++cpu_gnice_func ( void ) ++{ ++ g_val_t val; ++ val.f = 0.0; ++ return val; ++} ++ + g_val_t + mem_free_func ( void ) + { +diff --git a/libmetrics/solaris/metrics.c b/libmetrics/solaris/metrics.c +index 93ca213b..b7000171 100644 +--- a/libmetrics/solaris/metrics.c ++++ b/libmetrics/solaris/metrics.c +@@ -1366,3 +1366,26 @@ cpu_steal_func ( void ) + return val; + } + ++ ++/* ++** FIXME ++*/ ++g_val_t ++cpu_guest_func ( void ) ++{ ++ g_val_t val; ++ val.f = 0.0; ++ return val; ++} ++ ++/* ++** FIXME ++*/ ++g_val_t ++cpu_gnice_func ( void ) ++{ ++ g_val_t val; ++ val.f = 0.0; ++ return val; ++} ++ +diff --git a/libmetrics/tests/test-metrics.c b/libmetrics/tests/test-metrics.c +index e87717f4..b3ae3bac 100644 +--- a/libmetrics/tests/test-metrics.c ++++ b/libmetrics/tests/test-metrics.c +@@ -41,6 +41,10 @@ static const struct metricinfo + { + "cpu_nice", cpu_nice_func, g_float}, + { ++ "cpu_guest", cpu_guest_func, g_float}, ++ { ++ "cpu_gnice", cpu_gnice_func, g_float}, ++ { + "cpu_system", cpu_system_func, g_float}, + { + "cpu_idle", cpu_idle_func, g_float}, diff --git a/ganglia-3.7.2-apache.patch b/ganglia-3.7.2-apache.patch deleted file mode 100644 index 2f11ee4..0000000 --- a/ganglia-3.7.2-apache.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- gmond/python_modules/apache_status/apache_status.py.orig 2015-08-19 09:34:42.310000000 +1200 -+++ gmond/python_modules/apache_status/apache_status.py 2015-08-19 09:35:33.989000000 +1200 -@@ -86,6 +86,8 @@ - for sck in split_line[1]: - metrics[ Scoreboard_bykey[sck] ] += 1 - else: -+ if len(split_line) == 1: -+ continue - if long_metric_name in Metric_Map: - metric_name = Metric_Map[long_metric_name] - else: diff --git a/ganglia-3.7.2-autoconf-python3.patch b/ganglia-3.7.2-autoconf-python3.patch new file mode 100644 index 0000000..8fd84f4 --- /dev/null +++ b/ganglia-3.7.2-autoconf-python3.patch @@ -0,0 +1,32 @@ +diff --git a/configure.ac b/configure.ac +index fe7983b..d0a6d18 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -319,22 +319,17 @@ if test x"$enable_python" = xyes; then + if test -n "$PYTHON_BIN"; then + # find out python version + AC_MSG_CHECKING(Python version) +- PyVERSION=`$PYTHON_BIN -c ['import sys; print sys.version[:3]'`] +- PyMAJVERSION=`$PYTHON_BIN -c ['import sys; print sys.version[:1]'`] ++ PyVERSION=`$PYTHON_BIN -c ['import sys; print("%s.%s%s" % (sys.version_info.major, sys.version_info.minor, sys.abiflags))'`] ++ PyMAJVERSION=`$PYTHON_BIN -c ['import sys; print(sys.version_info.major)'`] + AC_MSG_RESULT($PyVERSION) + PYTHON_VERSION=$PyVERSION + AC_SUBST(PYTHON_VERSION) +- +- PyEXEC_INSTALLDIR=`$PYTHON_BIN -c "import sys; print sys.exec_prefix"` +- if test -f "$PyEXEC_INSTALLDIR/include/python/Python.h"; then +- PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python" ++ PyINC_DIR=`$PYTHON_BIN -c ['import sysconfig; print(sysconfig.get_paths()["include"])'`] ++ if test -f "$PyINC_DIR/Python.h"; then ++ PYTHON_INCLUDES="-I$PyINC_DIR" + else +- if test -f "$PyEXEC_INSTALLDIR/include/python$PyVERSION/Python.h"; then +- PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python$PyVERSION" +- else + PYTHON_INCLUDES="" + enable_python="no" +- fi + fi + AC_SUBST(PYTHON_INCLUDES) + else diff --git a/ganglia-3.7.2-gcc14-cast.patch b/ganglia-3.7.2-gcc14-cast.patch new file mode 100644 index 0000000..9cbac25 --- /dev/null +++ b/ganglia-3.7.2-gcc14-cast.patch @@ -0,0 +1,33 @@ +--- ganglia-3.7.2/gmond/gmond.c~ 2015-07-01 21:49:35.000000000 +0200 ++++ ganglia-3.7.2/gmond/gmond.c 2024-02-05 19:54:03.584404224 +0100 +@@ -2060,7 +2060,7 @@ + debug_msg("failed to allocate gzip stream"); + goto close_accept_socket; + } +- apr_status_t r = apr_socket_data_set(client, strm, GZIP_KEY, &zstream_destroy); ++ apr_status_t r = apr_socket_data_set(client, strm, GZIP_KEY, (int (*)(void *))&zstream_destroy); + if (r != APR_SUCCESS) + { + debug_msg("failed to set socket user data"); +diff --git a/gmetad/rrd_helpers.c b/gmetad/rrd_helpers.c +index 740799a..3f39071 100644 +--- a/gmetad/rrd_helpers.c ++++ b/gmetad/rrd_helpers.c +@@ -199,7 +199,7 @@ reconnect: + static int + RRD_update( char *rrd, const char *sum, const char *num, unsigned int process_time ) + { +- char *argv[3]; ++ const char *argv[3]; + int argc = 3; + char val[128]; + +@@ -235,7 +235,7 @@ RRD_create( char *rrd, int summary, unsigned int step, + unsigned int process_time, ganglia_slope_t slope) + { + const char *data_source_type = "GAUGE"; +- char *argv[128]; ++ const char *argv[128]; + int argc=0; + int heartbeat; + char s[16], start[64]; diff --git a/ganglia-3.7.2-pcre2.patch b/ganglia-3.7.2-pcre2.patch new file mode 100644 index 0000000..64260fc --- /dev/null +++ b/ganglia-3.7.2-pcre2.patch @@ -0,0 +1,126 @@ +From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1000041 + +--- ganglia.orig/configure.ac ++++ ganglia/configure.ac +@@ -520,14 +520,20 @@ + echo "Added -L$libpcrepath/${LIB_SUFFIX} to LDFLAGS" + fi + if test x"$libpcre" == xyes ; then +- AC_CHECK_HEADERS([pcre/pcre.h pcre.h]) +- AC_CHECK_LIB(pcre, pcre_compile) +- if test x"$ac_cv_lib_pcre_pcre_compile" = xyes; then +- echo "Found a suitable pcre library" +- else +- echo "libpcre not found, specify --with-libpcre=no to build without PCRE support" +- exit 1; +- fi ++ AC_CHECK_HEADERS([pcre2.h], [], [], [[#define PCRE2_CODE_UNIT_WIDTH 8]]) ++ LIBS="$LIBS -lpcre2-8" ++ AC_MSG_CHECKING([for pcre2_match_data_create in -lpcre2-8]) ++ AC_LINK_IFELSE( ++ [AC_LANG_PROGRAM([[#define PCRE2_CODE_UNIT_WIDTH 8 ++ #include ++ ]], ++ [[pcre2_match_data *md; ++ md = pcre2_match_data_create (16, NULL);]])], ++ [AC_DEFINE([HAVE_LIBPCRE], [1], [Define if the PCRE2 library is available]) ++ AC_MSG_RESULT([yes]) ++ AC_MSG_RESULT([Found a suitable pcre library])], ++ [AC_MSG_RESULT([no]) ++ AC_MSG_FAILURE([libpcre not found, specify --with-libpcre=no to build without PCRE support], [1])]) + else + echo "building without PCRE support" + fi +--- ganglia.orig/gmond/gmond.c ++++ ganglia/gmond/gmond.c +@@ -38,11 +38,8 @@ + #include + + #ifdef HAVE_LIBPCRE +-#if defined (HAVE_PCRE_PCRE_H) +-#include +-#else +-#include +-#endif ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + #endif + + #include "cmdline.h" /* generated by cmdline.sh which runs gengetopt */ +@@ -2650,10 +2647,11 @@ + + if(name_match != NULL) + { +- pcre *pcre_re; +- const char *pcre_err_ptr; +- int pcre_err_offset; +- int pcre_ovector[PCRE_OVECCOUNT]; ++ pcre2_code *pcre_re; ++ pcre2_match_data *pcre_md; ++ int pcre_err_ptr; ++ size_t pcre_err_offset; ++ size_t *pcre_ovector; + int pcre_rc; + + apr_hash_index_t *hi; +@@ -2662,9 +2660,9 @@ + const char *key; + int found = 0; + +- if((pcre_re = pcre_compile(name_match, 0, &pcre_err_ptr, &pcre_err_offset, NULL)) == NULL) ++ if((pcre_re = pcre2_compile((PCRE2_SPTR)name_match, PCRE2_ZERO_TERMINATED, 0, &pcre_err_ptr, &pcre_err_offset, NULL)) == NULL) + { +- err_msg ("pcre_compile failed on %s\n", name_match); ++ err_msg ("pcre2_compile failed on %s\n", name_match); + exit (1); + } + +@@ -2676,6 +2674,8 @@ + exit(EXIT_FAILURE); + } + ++ pcre_md = pcre2_match_data_create(PCRE_OVECCOUNT, NULL); ++ + for(hi = apr_hash_first(p, metric_callbacks); + hi; + hi = apr_hash_next(hi)) +@@ -2683,17 +2683,17 @@ + Ganglia_metric_callback *cb; + + apr_hash_this(hi, (const void**)&key, NULL, &val); +- if((pcre_rc = pcre_exec(pcre_re, NULL, key, strlen(key), 0, 0, pcre_ovector, PCRE_OVECCOUNT)) < 1) ++ if((pcre_rc = pcre2_match(pcre_re, (PCRE2_SPTR)key, strlen(key), 0, 0, pcre_md, NULL)) < 1) + { + switch(pcre_rc) + { +- case PCRE_ERROR_NOMATCH: ++ case PCRE2_ERROR_NOMATCH: + break; + case 0: + /* output vector not big enough */ + default: + /* unexpected error */ +- err_msg ("unexpected pcre_exec error\n"); ++ err_msg ("unexpected pcre2_match error\n"); + exit (1); + } + } +@@ -2703,6 +2703,8 @@ + char *title_tmpl = cfg_getstr ( metric, "title"); + float value_threshold = cfg_getfloat( metric, "value_threshold"); + ++ pcre_ovector = pcre2_get_ovector_pointer(pcre_md); ++ + if(title_tmpl != NULL) + { + struct iovec *ptrs; +@@ -2772,6 +2774,8 @@ + if (!found) + err_msg("Unable to find any metric information for '%s'. Possible that a module has not been loaded.\n", name_match); + ++ pcre2_match_data_free(pcre_md); ++ pcre2_code_free(pcre_re); + } + else + #endif + diff --git a/ganglia-3.7.2-sflow.patch b/ganglia-3.7.2-sflow.patch deleted file mode 100644 index bb8132f..0000000 --- a/ganglia-3.7.2-sflow.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- gmond/sflow.c.orig 2016-12-02 09:56:38.744353600 +0000 -+++ gmond/sflow.c 2016-12-02 09:47:45.666353600 +0000 -@@ -303,7 +303,8 @@ - char mtitle_buf[SFLOW_MAX_METRIC_NAME_LEN]; - if(ok || sflowCFG.submit_null_str) { - set_metric_name_and_title(&mname, &mtitle, mname_buf, mtitle_buf, metric_prefix, tag); -- fmsg.id = vmsg.id = gmetric_uint; -+ //fmsg.id = vmsg.id = gmetric_uint; -+ fmsg.id = vmsg.id = gmetric_string; - fmsg.Ganglia_metadata_msg_u.gfull.metric.type = "string"; - vmsg.Ganglia_value_msg_u.gstr.metric_id.name = mname; - vmsg.Ganglia_value_msg_u.gstr.str = (ok ? (char *)val : sflowCFG.null_str); - diff --git a/ganglia-gmond-python2to3.patch b/ganglia-gmond-python2to3.patch new file mode 100644 index 0000000..fc1b9cc --- /dev/null +++ b/ganglia-gmond-python2to3.patch @@ -0,0 +1,176 @@ +diff --git a/gmond/modules/python/mod_python.c b/gmond/modules/python/mod_python.c +index ed5a401..484429e 100644 +--- a/gmond/modules/python/mod_python.c ++++ b/gmond/modules/python/mod_python.c +@@ -29,6 +29,10 @@ + * + * Author: Brad Nicholes (bnicholes novell.com) + * Jon Carey (jcarey novell.com) ++* ++* Modified for Python3 support, based on code at https://docs.python.org/3.5/howto/cporting.html ++* Tom Crane (T.Crane@rhul.ac.uk), June 2024. ++* + ******************************************************************************/ + + #include +@@ -51,12 +55,23 @@ + /* + * Backward compatibility for 2.1 to 2.4 + */ ++#if PY_MAJOR_VERSION < 3 + #if PY_MINOR_VERSION < 5 + #define Py_ssize_t int + #if PY_MINOR_VERSION < 3 + #define PyInt_AsUnsignedLongMask PyInt_AsLong + #endif + #endif ++#endif ++ ++#if PY_MAJOR_VERSION >= 3 ++# define PyInt_AsLong(x) (PyLong_AsLong((x))) ++# define PyInt_Check(x) (PyLong_Check((x))) ++# define PyString_Check(x) (PyUnicode_Check((x))) ++# define PyString_AsString(x) (PyUnicode_AsUTF8((x))) ++# define PyInt_AsUnsignedLongMask(x) (PyLong_AsUnsignedLongMask((x))) ++# define PyString_FromString(x) (PyUnicode_FromString((x))) ++#endif + + /* + * Declare ourselves so the configuration routines can find and know us. +@@ -540,7 +555,57 @@ static PyMethodDef GangliaMethods[] = { + {NULL, NULL, 0, NULL} + }; + ++struct module_state { ++ PyObject *error; ++}; ++ ++#if PY_MAJOR_VERSION >= 3 ++#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) ++#else ++#define GETSTATE(m) (&_state) ++static struct module_state _state; ++#endif ++ ++static PyObject * ++error_out(PyObject *m) { ++ struct module_state *st = GETSTATE(m); ++ PyErr_SetString(st->error, "something bad happened"); ++ return NULL; ++} ++ ++#if PY_MAJOR_VERSION >= 3 ++ ++static int ganglia_traverse(PyObject *m, visitproc visit, void *arg) { ++ Py_VISIT(GETSTATE(m)->error); ++ return 0; ++} ++ ++static int ganglia_clear(PyObject *m) { ++ Py_CLEAR(GETSTATE(m)->error); ++ return 0; ++} ++ ++ ++static struct PyModuleDef moduledef = { ++ PyModuleDef_HEAD_INIT, ++ "ganglia", ++ NULL, ++ sizeof(struct module_state), ++ GangliaMethods, ++ NULL, ++ ganglia_traverse, ++ ganglia_clear, ++ NULL ++}; ++ ++#define INITERROR return NULL ++ ++PyMODINIT_FUNC PyInit_metric_init(apr_pool_t *p) ++#else ++#define INITERROR return ++ + static int pyth_metric_init (apr_pool_t *p) ++#endif + { + DIR *dp; + struct dirent *entry; +@@ -563,29 +628,41 @@ static int pyth_metric_init (apr_pool_t *p) + + if (!path) { + err_msg("[PYTHON] Missing python module path.\n"); +- return -1; ++ INITERROR; + } + + if (access(path, F_OK)) + { + /* 'path' does not exist */ + err_msg("[PYTHON] Can't open the python module path %s.\n", path); +- return -1; ++ INITERROR; + } + + if (access(path, R_OK)) + { + /* Don't have read access to 'path' */ + err_msg("[PYTHON] Can't read from the python module path %s.\n", path); +- return -1; ++ INITERROR; + } + + /* Init Python environment */ + + /* Set up the python path to be able to load module from our module path */ + Py_Initialize(); +- Py_InitModule("ganglia", GangliaMethods); ++#if PY_MAJOR_VERSION >= 3 ++ PyObject *module = PyModule_Create(&moduledef); ++#else ++ PyObject *module = Py_InitModule("ganglia", GangliaMethods); ++#endif ++ if (module == NULL) ++ INITERROR; ++ struct module_state *st = GETSTATE(module); + ++ st->error = PyErr_NewException("ganglia.Error", NULL, NULL); ++ if (st->error == NULL) { ++ Py_DECREF(module); ++ INITERROR; ++ } + PyObject *sys_path = PySys_GetObject("path"); + PyObject *addpath = PyString_FromString(path); + PyList_Append(sys_path, addpath); +@@ -598,7 +675,7 @@ static int pyth_metric_init (apr_pool_t *p) + /* Error: Cannot open the directory - Shouldn't happen */ + /* Log? */ + err_msg("[PYTHON] Can't open the python module path %s.\n", path); +- return -1; ++ INITERROR; + } + + i = 0; +@@ -712,7 +789,11 @@ static int pyth_metric_init (apr_pool_t *p) + memset (mi, 0, sizeof(*mi)); + + python_module.metrics_info = (Ganglia_25metric *)metric_info->elts; ++#if PY_MAJOR_VERSION >= 3 ++ return module; ++#else + return 0; ++#endif + } + + static apr_status_t pyth_metric_cleanup ( void *data) +@@ -832,7 +913,11 @@ static g_val_t pyth_metric_handler( int metric_index ) + mmodule python_module = + { + STD_MMODULE_STUFF, ++#if PY_MAJOR_VERSION >= 3 ++ (int (*)(apr_pool_t *))PyInit_metric_init, ++#else + pyth_metric_init, ++#endif + NULL, + NULL, /* defined dynamically */ + pyth_metric_handler, diff --git a/ganglia-web-3.7.5.tar.gz b/ganglia-web-3.7.5.tar.gz deleted file mode 100644 index 9fde405..0000000 Binary files a/ganglia-web-3.7.5.tar.gz and /dev/null differ diff --git a/ganglia-web-3.7.6-php8.patch b/ganglia-web-3.7.6-php8.patch new file mode 100644 index 0000000..9fcadb0 --- /dev/null +++ b/ganglia-web-3.7.6-php8.patch @@ -0,0 +1,169 @@ +From: + https://bugzilla.redhat.com/show_bug.cgi?id=2180500 + +diff --git a/api/host.php b/api/host.php +index 5eb026c..5cee9ec 100644 +--- a/api/host.php ++++ b/api/host.php +@@ -87,7 +87,7 @@ switch ( $_GET['action'] ) { + $reports["excluded_reports"] = array_unique($reports["excluded_reports"]); + $additional_cluster_img_html_args = array(); + $additional_cluster_img_html_args['h'] = $hostname; +- $additional_cluster_img_html_args['st'] = $cluster[LOCALTIME]; ++ $additional_cluster_img_html_args['st'] = $cluster['LOCALTIME']; + $additional_cluster_img_html_args['m'] = $metricname; + $additional_cluster_img_html_args['r'] = $range; + $additional_cluster_img_html_args['s'] = $sort; +@@ -152,7 +152,7 @@ switch ( $_GET['action'] ) { + $graph_arguments['z'] = $size; + $graph_arguments['jr'] = $jobrange; + $graph_arguments['js'] = $jobstart; +- $graph_arguments['st'] = $cluster[LOCALTIME]; ++ $graph_arguments['st'] = $cluster['LOCALTIME']; + # Adding units to graph 2003 by Jason Smith . + if ($v['UNITS']) { + $graph_arguments['vl'] = $metrics[$cluster_url]['UNITS']; +diff --git a/dwoo/Dwoo/Core.php b/dwoo/Dwoo/Core.php +index 8ec104b..fc62cde 100644 +--- a/dwoo/Dwoo/Core.php ++++ b/dwoo/Dwoo/Core.php +@@ -1250,7 +1250,7 @@ class Dwoo_Core + } + unset($varstr); + +- while (list($k, $sep) = each($m[1])) { ++ foreach($m[1] as $k => $sep){ + if ($sep === '.' || $sep === '[' || $sep === '') { + // strip enclosing quotes if present + $m[2][$k] = preg_replace('#^(["\']?)(.*?)\1$#', '$2', $m[2][$k]); +@@ -1425,7 +1425,7 @@ class Dwoo_Core + $cur = $this->scope; + } + +- while (list($k, $sep) = each($m[1])) { ++ foreach($m[1] as $k => $sep){ + if ($sep === '.' || $sep === '[' || $sep === '') { + if ((is_array($cur) || $cur instanceof ArrayAccess) && isset($cur[$m[2][$k]])) { + $cur = $cur[$m[2][$k]]; +@@ -1470,7 +1470,7 @@ class Dwoo_Core + $cur =& $this->scope; + $last = array(array_pop($m[1]), array_pop($m[2])); + +- while (list($k, $sep) = each($m[1])) { ++ foreach($m[1] as $k => $sep){ + if ($sep === '.' || $sep === '[' || $sep === '') { + if (is_array($cur) === false) { + $cur = array(); +diff --git a/dwoo/Dwoo/Data.php b/dwoo/Dwoo/Data.php +index c5f292e..d841546 100644 +--- a/dwoo/Dwoo/Data.php ++++ b/dwoo/Dwoo/Data.php +@@ -71,7 +71,7 @@ class Dwoo_Data implements Dwoo_IDataProvider + public function mergeData(array $data) + { + $args = func_get_args(); +- while (list(,$v) = each($args)) { ++ foreach($args as $v){ + if (is_array($v)) { + $this->data = array_merge($this->data, $v); + } +@@ -90,7 +90,7 @@ class Dwoo_Data implements Dwoo_IDataProvider + { + if (is_array($name)) { + reset($name); +- while (list($k,$v) = each($name)) ++ foreach($name as $k => $v) + $this->data[$k] = $v; + } else { + $this->data[$name] = $val; +diff --git a/dwoo/plugins/builtin/blocks/textformat.php b/dwoo/plugins/builtin/blocks/textformat.php +index fb0f422..61ec1d6 100644 +--- a/dwoo/plugins/builtin/blocks/textformat.php ++++ b/dwoo/plugins/builtin/blocks/textformat.php +@@ -67,7 +67,7 @@ class Dwoo_Plugin_textformat extends Dwoo_Block_Plugin + // gets paragraphs + $pgs = explode("\n", str_replace(array("\r\n", "\r"), "\n", $this->buffer)); + +- while (list($i,) = each($pgs)) { ++ foreach($pgs as $i){ + if (empty($pgs[$i])) { + continue; + } +diff --git a/dwoo/plugins/builtin/functions/capitalize.php b/dwoo/plugins/builtin/functions/capitalize.php +index d04f39b..de57c20 100644 +--- a/dwoo/plugins/builtin/functions/capitalize.php ++++ b/dwoo/plugins/builtin/functions/capitalize.php +@@ -25,7 +25,7 @@ function Dwoo_Plugin_capitalize(Dwoo_Core $dwoo, $value, $numwords=false) + } else { + $bits = explode(' ', (string) $value); + $out = ''; +- while (list(,$v) = each($bits)) { ++ foreach($bits as $v){ + if (preg_match('#^[^0-9]+$#', $v)) { + $out .= ' '.mb_convert_case($v, MB_CASE_TITLE, $dwoo->getCharset()); + } else { +diff --git a/host_view.php b/host_view.php +index ca05c8d..3b54b35 100644 +--- a/host_view.php ++++ b/host_view.php +@@ -329,7 +329,7 @@ $cluster_url = rawurlencode($clustername); + + $baseGraphArgs = "c=$cluster_url&h=" . $user['hostname'] + . "&r=" . $user['range'] . "&z=$size&jr=$jobrange" +- . "&js=$jobstart&st=$cluster[LOCALTIME]"; ++ . "&js=$jobstart&st=" . $cluster['LOCALTIME']; + if ($user['cs']) + $baseGraphArgs .= "&cs=" . rawurlencode($user['cs']); + if ($user['ce']) +diff --git a/lib/GangliaAuth.php b/lib/GangliaAuth.php +index 01ca10d..bda8f84 100644 +--- a/lib/GangliaAuth.php ++++ b/lib/GangliaAuth.php +@@ -94,7 +94,7 @@ class GangliaAuth { + } + + protected function getMagicQuotesGpc() { +- return get_magic_quotes_gpc(); ++ return false; + } + } + ?> +diff --git a/metric_group_view.php b/metric_group_view.php +index 13dc0a1..f526545 100644 +--- a/metric_group_view.php ++++ b/metric_group_view.php +@@ -105,7 +105,7 @@ $cluster_url = rawurlencode($clustername); + + $baseGraphArgs = "c=$cluster_url&h=$hostname" + . "&r=$range&z=$size&jr=$jobrange" +- . "&js=$jobstart&st=$cluster[LOCALTIME]"; ++ . "&js=$jobstart&st=$cluster['LOCALTIME']"; + if ($cs) + $baseGraphArgs .= "&cs=" . rawurlencode($cs); + if ($ce) +diff --git a/mobile_helper.php b/mobile_helper.php +index d9e20cb..2b384ad 100644 +--- a/mobile_helper.php ++++ b/mobile_helper.php +@@ -268,7 +268,7 @@ foreach ($metrics as $metric_name => $metric_attributes) { + else { + $metric_graphargs = "c=".rawurlencode($clustername)."&h=".rawurlencode($hostname)."&v=".rawurlencode($metric_attributes['VAL']) + ."&m=$metric_name&r=".rawurlencode($range)."&z=$size&jr=$jobrange" +- ."&js=$jobstart&st=$cluster[LOCALTIME]"; ++ ."&js=$jobstart&st=$cluster['LOCALTIME']"; + if ($cs) + $metric_graphargs .= "&cs=" . rawurlencode($cs); + if ($ce) +diff --git a/physical_view.php b/physical_view.php +index 8d5c3bc..a0d4111 100644 +--- a/physical_view.php ++++ b/physical_view.php +@@ -99,7 +99,7 @@ function physical_racks() { + else { + ksort($racks); + reset($racks); +- while (list($rack,) = each($racks)) { ++ foreach($racks as $rack){ + # In our convention, y=0 is close to the floor. (Easier to wire up) + krsort($racks[$rack]); + } diff --git a/ganglia-web-3.7.6-pr-379.patch b/ganglia-web-3.7.6-pr-379.patch new file mode 100644 index 0000000..e33404a --- /dev/null +++ b/ganglia-web-3.7.6-pr-379.patch @@ -0,0 +1,121 @@ +diff --git a/Makefile b/Makefile +index 6d2dd1b..a3ab48a 100644 +--- a/Makefile ++++ b/Makefile +@@ -30,7 +30,7 @@ PHPCBF = phpcbf + ########################################################## + + # Gweb version +-GWEB_VERSION = 3.7.5 ++GWEB_VERSION = 3.7.7 + + DIST_NAME = ganglia-web + DIST_DIR = $(DIST_NAME)-$(GWEB_VERSION) +diff --git a/cluster_view.php b/cluster_view.php +index 998ad65..fed4ed8 100644 +--- a/cluster_view.php ++++ b/cluster_view.php +@@ -372,7 +372,7 @@ function get_cluster_overview($showhosts, + $overview["cluster_load"] = join(", ", $cluster_load); + + $avg_cpu_num = find_avg($clustername, "", "cpu_num"); +- if ($avg_cpu_num == 0) ++ if ((float)$avg_cpu_num == 0) + $avg_cpu_num = 1; + $cluster_util = + sprintf("%.0f%%", +diff --git a/ganglia.php b/ganglia.php +index 262b88e..3d1b325 100644 +--- a/ganglia.php ++++ b/ganglia.php +@@ -350,7 +350,7 @@ function Gmetad () { + } + + if ($debug) print "
DEBUG: Creating parser\n"; +- if ( isset($context) && is_array($context) && isset($SKIP_GMETAD_CONTEXTS) && is_array($SKIP_GMETAD_CONTEXTS) && in_array($context, $SKIP_GMETAD_CONTEXTS) ) { ++ if ( is_array($SKIP_GMETAD_CONTEXTS) && in_array($context, $SKIP_GMETAD_CONTEXTS) ) { + return TRUE; + } + $parser = xml_parser_create(); +diff --git a/get_ganglia.php b/get_ganglia.php +index 50e5fe8..d9c4f2e 100644 +--- a/get_ganglia.php ++++ b/get_ganglia.php +@@ -7,7 +7,7 @@ + + # If we are in compare_hosts, views and decompose_graph context we shouldn't attempt + # any connections to the gmetad +-if (! in_array($context, $SKIP_GMETAD_CONTEXTS) ) { ++if (! ( is_array($SKIP_GMETAD_CONTEXTS) && in_array($context, $SKIP_GMETAD_CONTEXTS) ) ) { + if (! Gmetad($conf['ganglia_ip'], $conf['ganglia_port']) ) + { + print "

There was an error collecting ganglia data ". +diff --git a/graph.php b/graph.php +index e8a7a9c..bf34014 100644 +--- a/graph.php ++++ b/graph.php +@@ -1552,7 +1552,7 @@ if ($sourcetime) { + + // Fix from Phil Radden, but step is not always 15 anymore. + if ($range == "month") +- $rrdtool_graph['end'] = floor($rrdtool_graph['end'] / 672) * 672; ++ $rrdtool_graph['end'] = floor((int)$rrdtool_graph['end'] / 672) * 672; + + /////////////////////////////////////////////////////////////////////////////// + // Are we generating aggregate graphs +diff --git a/meta_view.php b/meta_view.php +index aa79e15..e6490af 100644 +--- a/meta_view.php ++++ b/meta_view.php +@@ -119,7 +119,7 @@ foreach ( $sorted_sources as $source => $val ) + + $clusname = $source == $self ? '' : $source; + $avg_cpu_num = find_avg($clusname, "", "cpu_num"); +- if ($avg_cpu_num == 0) $avg_cpu_num = 1; ++ if ((float)$avg_cpu_num == 0) $avg_cpu_num = 1; + $cluster_util = sprintf("%.0f", ((double) find_avg($clusname, "", "load_one") / $avg_cpu_num ) * 100); + + $sources[$source]["name"] = $name; +diff --git a/mobile_helper.php b/mobile_helper.php +index db45bb7..d9e20cb 100644 +--- a/mobile_helper.php ++++ b/mobile_helper.php +@@ -266,7 +266,7 @@ foreach ($metrics as $metric_name => $metric_attributes) { + } else if (isset($reports[$metric_name]) and $reports[$metric]) + continue; + else { +- $metric_graphargs = "c=".rawurlencode($clustername)."&h=".rawurlencode($hostname)."&v=".rawurlencode($metric_attributes[VAL]) ++ $metric_graphargs = "c=".rawurlencode($clustername)."&h=".rawurlencode($hostname)."&v=".rawurlencode($metric_attributes['VAL']) + ."&m=$metric_name&r=".rawurlencode($range)."&z=$size&jr=$jobrange" + ."&js=$jobstart&st=$cluster[LOCALTIME]"; + if ($cs) +diff --git a/pie.php b/pie.php +index 0e94bbe..24afad9 100644 +--- a/pie.php ++++ b/pie.php +@@ -276,7 +276,11 @@ $to = 0; + + $x; //PHPCS + $y; //PHPCS +- $pie_count = count( $angles ); ++ if is_null( $angles ) { ++ $pie_count = 0; ++ } else { ++ $pie_count = count( $angles ); ++ } + $PIE_THICKNESS = ($this->diameter * 0.075); + + for( $j = ($this->center_y+$PIE_THICKNESS); $j > $this->center_y; $j-- ) { +diff --git a/templates/default/footer.tpl b/templates/default/footer.tpl +index af9fb5e..548a8e4 100644 +--- a/templates/default/footer.tpl ++++ b/templates/default/footer.tpl +@@ -92,7 +92,7 @@ Loading view, please wait... +