From ce781a183272fe835c318dc5affb8d64558a4e2b Mon Sep 17 00:00:00 2001 From: cody burkard <cody@onlab.us> Date: Thu, 21 Aug 2014 17:39:59 -0700 Subject: [PATCH] use cgroups to calculate percentage of cpu used --- mininet/net.py | 53 +++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/mininet/net.py b/mininet/net.py index 8a6acdcc..0ef0a043 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -94,6 +94,7 @@ import copy from time import sleep from itertools import chain, groupby +from math import ceil from mininet.cli import CLI from mininet.log import info, error, debug, output, warn @@ -726,33 +727,41 @@ def runCpuLimitTest( self, cpu, duration=5 ): duration: test duration in seconds returns a single list of measured CPU fractions as floats. """ + cores = int( quietRun( 'nproc' ) ) pct = cpu * 100 - info('*** Testing CPU %.0f%% bandwidth limit\n' % pct) + info( '*** Testing CPU %.0f%% bandwidth limit\n' % pct ) hosts = self.hosts + cores = int( quietRun( 'nproc' ) ) + # number of processes to run a while loop on per host + num_procs = int( ceil( cores * cpu ) ) + pids = {} for h in hosts: - h.cmd( 'while true; do a=1; done &' ) - pids = [h.cmd( 'echo $!' ).strip() for h in hosts] - pids_str = ",".join(["%s" % pid for pid in pids]) - cmd = 'ps -p %s -o pid,%%cpu,args' % pids_str - # It's a shame that this is what pylint prefers - outputs = [] - for _ in range( duration ): + pids[ h ] = [] + for _core in range( num_procs ): + h.cmd( 'while true; do a=1; done &' ) + pids[ h ].append( h.cmd( 'echo $!' ).strip() ) + outputs = {} + time = {} + # get the initial cpu time for each host + for host in hosts: + outputs[ host ] = [] + with open( '/sys/fs/cgroup/cpuacct/%s/cpuacct.usage' % host, 'r' ) as f: + time[ host ] = float( f.read() ) + for _ in range( 5 ): sleep( 1 ) - outputs.append( quietRun( cmd ).strip() ) - for h in hosts: - h.cmd( 'kill $!' ) + for host in hosts: + with open( '/sys/fs/cgroup/cpuacct/%s/cpuacct.usage' % host, 'r' ) as f: + readTime = float( f.read() ) + outputs[ host ].append( ( ( readTime - time[ host ] ) + / 1000000000 ) / cores * 100 ) + time[ host ] = readTime + for h, pids in pids.items(): + for pid in pids: + h.cmd( 'kill -9 %s' % pid ) cpu_fractions = [] - for test_output in outputs: - # Split by line. Ignore first line, which looks like this: - # PID %CPU COMMAND\n - for line in test_output.split('\n')[1:]: - r = r'\d+\s*(\d+\.\d+)' - m = re.search( r, line ) - if m is None: - error( '*** Error: could not extract CPU fraction: %s\n' % - line ) - return None - cpu_fractions.append( float( m.group( 1 ) ) ) + for _host, outputs in outputs.items(): + for pct in outputs: + cpu_fractions.append( pct ) output( '*** Results: %s\n' % cpu_fractions ) return cpu_fractions -- GitLab