diff --git a/README.rst b/README.rst index f0666fd..f0d66fa 100644 --- a/README.rst +++ b/README.rst @@ -105,6 +105,7 @@ KloudBuster VM images contain multiple open source license components: * wrk2: Apache License 2.0 (https://raw.githubusercontent.com/giltene/wrk2/master/LICENSE) * redis: BSD License (http://redis.io/topics/license) +* fio: GPL v2 (https://raw.githubusercontent.com/axboe/fio/master/MORAL-LICENSE) Links diff --git a/kb_dib/elements/kloudbuster/post-install.d/01-kb-script b/kb_dib/elements/kloudbuster/post-install.d/01-kb-script index 6119d7f..479e7a5 100755 --- a/kb_dib/elements/kloudbuster/post-install.d/01-kb-script +++ b/kb_dib/elements/kloudbuster/post-install.d/01-kb-script @@ -79,7 +79,7 @@ mv /usr/local/lib/libhdr_histogram.so /usr/lib/ # Install fio cd /tmp -FIO='fio-2.3' +FIO='fio-2.5' wget http://brick.kernel.dk/snaps/$FIO.tar.gz tar xzf $FIO.tar.gz cd $FIO diff --git a/kloudbuster/fio_tool.py b/kloudbuster/fio_tool.py index 90cfb37..bfc958a 100644 --- a/kloudbuster/fio_tool.py +++ b/kloudbuster/fio_tool.py @@ -41,6 +41,8 @@ class FioTool(PerfTool): read_bw = result['jobs'][0]['read']['bw'] write_iops = result['jobs'][0]['write']['iops'] write_bw = result['jobs'][0]['write']['bw'] + read_clat = result['jobs'][0]['read']['clat']['bins'] + write_clat = result['jobs'][0]['write']['clat']['bins'] except Exception: return self.parse_error('Could not parse: "%s"' % (stdout)) @@ -53,6 +55,10 @@ class FioTool(PerfTool): parsed_output['write_iops'] = write_iops if write_bw: parsed_output['write_bw'] = write_bw + if read_bw and read_clat: + parsed_output['read_clat'] = read_clat + if write_bw and write_clat: + parsed_output['write_clat'] = write_clat return parsed_output @@ -69,6 +75,43 @@ class FioTool(PerfTool): all_res[key] += item['results'].get(key, 0) all_res[key] = int(all_res[key]) + clat_list = [] + # perc_list = [1, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99, 99.5, 99.9, 99.95, 99.99] + perc_list = [50, 75, 90, 99, 99.9, 99.99, 99.999] + if 'read_clat' in results[0]['results']: + clat_list.append('read_clat') + if 'write_clat' in results[0]['results']: + clat_list.append('write_clat') + + for clat in clat_list: + total_buckets = results[0]['results'][clat]['FIO_IO_U_PLAT_NR'] + grp_msb_bits = results[0]['results'][clat]['FIO_IO_U_PLAT_BITS'] + buckets_per_grp = results[0]['results'][clat]['FIO_IO_U_PLAT_VAL'] + + d_bins = {} + total_count = cur_count = cur_bucket = 0 + all_res[clat] = [] + for item in results: + for bucket in xrange(total_buckets): + d_bins[bucket] = d_bins.get(bucket, 0) + item['results'][clat][str(bucket)] + total_count += item['results'][clat][str(bucket)] + + for perc in perc_list: + count_at_perc = float(perc) * total_count / 100 + while cur_count < count_at_perc and cur_bucket < total_buckets: + cur_count += d_bins[cur_bucket] + cur_bucket += 1 + + grp = cur_bucket / buckets_per_grp + subbucket = cur_bucket % buckets_per_grp + if grp == 0: + val = subbucket - 1 + else: + base = 2 ** (grp_msb_bits + grp - 1) + val = int(base + (base / buckets_per_grp) * (subbucket - 0.5)) + + all_res[clat].append([perc, val]) + return all_res @staticmethod