fixes
diff --git a/configs/config_vm_scan.yaml b/configs/config_vm_scan.yaml
new file mode 100644
index 0000000..c9a91f7
--- /dev/null
+++ b/configs/config_vm_scan.yaml
@@ -0,0 +1,76 @@
+clouds:
+    fuel:
+        url: http://172.16.52.112:8000/
+        creds: admin:admin@admin
+        ssh_creds: root:test37
+        openstack_env: test
+
+    openstack:
+        OS_TENANT_NAME: admin
+        OS_USERNAME: admin
+        OS_PASSWORD: admin
+        OS_AUTH_URL: http://172.16.53.3:5000/v2.0/
+
+    ceph: local
+
+discover: fuel, ceph
+
+explicit_nodes:
+    "ssh://root@172.16.52.112:3022:/home/koder/.ssh/id_rsa": testnode
+
+
+internal:
+    var_dir_root: /tmp/perf_tests
+
+node_configs:
+    io_1024:
+        img_name: disk_io_perf
+        flavor_name: disk_io_perf.256
+        keypair_name: disk_io_perf
+        network_zone_name: novanetwork
+        flt_ip_pool: nova
+        creds: "ssh://ubuntu@{0}::disk_io_perf.pem"
+        name_templ: disk_io_perf-{0}
+
+tests:
+    - start_test_nodes:
+        openstack:
+            creds: clouds
+            vm_params:
+                count: x1
+                config: io_1024
+        tests:
+            - io:
+                cfg: tests/io_scenario_hdd.cfg
+                params:
+                    FILENAME: /opt/xxx.bin
+                    NUM_ROUNDS: 7
+
+    - start_test_nodes:
+        openstack:
+            creds: clouds
+            vm_params:
+                count: x2
+                config: io_1024
+        tests:
+            - io:
+                cfg: tests/io_scenario_hdd.cfg
+                params:
+                    FILENAME: /opt/xxx.bin
+                    NUM_ROUNDS: 7
+
+    - start_test_nodes:
+        openstack:
+            creds: clouds
+            vm_params:
+                count: x3
+                config: io_1024
+        tests:
+            - io:
+                cfg: tests/io_scenario_hdd.cfg
+                params:
+                    FILENAME: /opt/xxx.bin
+                    NUM_ROUNDS: 7
+
+logging:
+    extra_logs: 1
\ No newline at end of file
diff --git a/configs/local_ceph.yaml b/configs/local_ceph.yaml
index 7948093..996199c 100644
--- a/configs/local_ceph.yaml
+++ b/configs/local_ceph.yaml
@@ -16,7 +16,6 @@
 
 tests:
     - io:
-        # cfg: tests/io_scenario_hdd.cfg
         cfg: scripts/fio_tests_configs/io_task_test.cfg
         use_sudo: false
         params:
diff --git a/configs/perf1.yaml b/configs/perf1.yaml
index 05591fe..4405f34 100644
--- a/configs/perf1.yaml
+++ b/configs/perf1.yaml
@@ -46,6 +46,7 @@
 
         tests:
             - io:
+                name: ceph
                 # cfg: wally/suits/io/io_scenario_ceph.cfg
                 cfg: scripts/fio_tests_configs/io_task_test.cfg
                 prefill_files: true
diff --git a/configs/usb_hdd.yaml b/configs/usb_hdd.yaml
index 67b2d83..3ff2458 100644
--- a/configs/usb_hdd.yaml
+++ b/configs/usb_hdd.yaml
@@ -6,20 +6,22 @@
     var_dir_root: /tmp/perf_tests
 
 testnode_log_root: /tmp/perf_tests_rem
+# run_web_ui: true
 
-sensors:
-    roles_mapping:
-        testnode: system-cpu, block-io
+# sensors:
+#     roles_mapping:
+#         testnode: system-cpu, block-io
 
 tests:
     - io:
-        # cfg: wally/suits/io/io_scenario_hdd.cfg
-        cfg: scripts/fio_tests_configs/io_task_test.cfg
+        cfg: wally/suits/io/hdd.cfg
+        # cfg: scripts/fio_tests_configs/io_task_test.cfg
         prefill_files: false
         use_sudo: false
+        test_logging: true
         params:
             FILENAME: /media/koder/a5230078-4c27-4c3b-99aa-26148e78b2e7/xxx.bin
-            NUM_ROUNDS: 5
+            NUM_ROUNDS: 7
 
 logging:
     extra_logs: 1
\ No newline at end of file
diff --git a/wally/assumptions_check.py b/wally/assumptions_check.py
index 41ae2e0..94297c3 100644
--- a/wally/assumptions_check.py
+++ b/wally/assumptions_check.py
@@ -10,54 +10,6 @@
 from .statistic import approximate_line, difference
 
 
-def linearity_plot(data, types, vals=None):
-    fields = 'blocksize_b', 'iops_mediana', 'iops_stddev'
-
-    names = {}
-    for tp1 in ('rand', 'seq'):
-        for oper in ('read', 'write'):
-            for sync in ('sync', 'direct', 'async'):
-                sq = (tp1, oper, sync)
-                name = "{0} {1} {2}".format(*sq)
-                names["".join(word[0] for word in sq)] = name
-
-    colors = ['red', 'green', 'blue', 'cyan',
-              'magenta', 'black', 'yellow', 'burlywood']
-    markers = ['*', '^', 'x', 'o', '+', '.']
-    color = 0
-    marker = 0
-
-    for tp in types:
-        filtered_data = filter_data('linearity_test_' + tp, fields)
-        x = []
-        y = []
-        e = []
-        # values to make line
-        ax = []
-        ay = []
-
-        for sz, med, dev in sorted(filtered_data(data)):
-            iotime_ms = 1000. // med
-            iotime_max = 1000. // (med - dev * 3)
-
-            x.append(sz / 1024.0)
-            y.append(iotime_ms)
-            e.append(iotime_max - iotime_ms)
-            if vals is None or sz in vals:
-                ax.append(sz / 1024.0)
-                ay.append(iotime_ms)
-
-        plt.errorbar(x, y, e, linestyle='None', label=names[tp],
-                     color=colors[color], ecolor="black",
-                     marker=markers[marker])
-        ynew = approximate_line(ax, ay, ax, True)
-        plt.plot(ax, ynew, color=colors[color])
-        color += 1
-        marker += 1
-    plt.legend(loc=2)
-    plt.title("Linearity test by %i dots" % (len(vals)))
-
-
 def linearity_table(data, types, vals):
     """ create table by pyplot with diferences
         between original and approximated
diff --git a/wally/report.py b/wally/report.py
index e24e7b6..e435a6a 100644
--- a/wally/report.py
+++ b/wally/report.py
@@ -2,6 +2,11 @@
 import bisect
 import logging
 
+try:
+    import matplotlib.pyplot as plt
+except ImportError:
+    plt = None
+
 import wally
 from wally import charts
 from wally.statistic import round_3_digit
@@ -24,6 +29,71 @@
         self.bw_read_max = 0
 
 
+report_funcs = []
+
+
+def report(name, required_fields):
+    def closure(func):
+        report_funcs.append((required_fields.split(","), name, func))
+        return func
+    return closure
+
+
+# def linearity_report(processed_results, path, lab_info):
+#     names = {}
+#     for tp1 in ('rand', 'seq'):
+#         for oper in ('read', 'write'):
+#             for sync in ('sync', 'direct', 'async'):
+#                 sq = (tp1, oper, sync)
+#                 name = "{0} {1} {2}".format(*sq)
+#                 names["".join(word[0] for word in sq)] = name
+
+#     colors = ['red', 'green', 'blue', 'cyan',
+#               'magenta', 'black', 'yellow', 'burlywood']
+#     markers = ['*', '^', 'x', 'o', '+', '.']
+#     color = 0
+#     marker = 0
+
+#     name_pref = 'linearity_test_'
+#     plot_data = []
+
+#     x = []
+#     y = []
+#     e = []
+#     # values to make line
+#     ax = []
+#     ay = []
+
+#     for res in processed_results.values():
+#         if res.name.startswith(name_pref):
+#             res
+
+#     for sz, med, dev in sorted(filtered_data(data)):
+#         iotime_ms = 1000. // med
+#         iotime_max = 1000. // (med - dev * 3)
+
+#         x.append(sz / 1024.0)
+#         y.append(iotime_ms)
+#         e.append(iotime_max - iotime_ms)
+#         if vals is None or sz in vals:
+#             ax.append(sz / 1024.0)
+#             ay.append(iotime_ms)
+
+#     plt.errorbar(x, y, e, linestyle='None', label=names[tp],
+#                  color=colors[color], ecolor="black",
+#                  marker=markers[marker])
+#     ynew = approximate_line(ax, ay, ax, True)
+#     plt.plot(ax, ynew, color=colors[color])
+#     color += 1
+#     marker += 1
+#     plt.legend(loc=2)
+#     plt.title("Linearity test by %i dots" % (len(vals)))
+
+
+# if plt:
+#     linearity_report = report('linearity', 'linearity_test')(linearity_report)
+
+
 def render_hdd_html(dest, info, lab_description):
     very_root_dir = os.path.dirname(os.path.dirname(wally.__file__))
     templ_dir = os.path.join(very_root_dir, 'report_templates')
@@ -200,19 +270,9 @@
     return hdi
 
 
-report_funcs = []
-
-
-def report(name, required_fields):
-    def closure(func):
-        report_funcs.append((required_fields.split(","), name, func))
-        return func
-    return closure
-
-
 @report('HDD', 'hdd_test_rrd4k,hdd_test_rws4k')
 def make_hdd_report(processed_results, path, lab_info):
-    make_plots(processed_results, path)
+    make_hdd_plots(processed_results, path)
     di = get_disk_info(processed_results)
     render_hdd_html(path, di, lab_info)
 
@@ -250,7 +310,7 @@
                 if pos == len(res_fields):
                     break
 
-                if not res_fields[pos + 1].startswith(field):
+                if not res_fields[pos].startswith(field):
                     break
             else:
                 hpath = path.format(name)
diff --git a/wally/suits/io/ceph.cfg b/wally/suits/io/ceph.cfg
index 7a84872..9e98dd6 100644
--- a/wally/suits/io/ceph.cfg
+++ b/wally/suits/io/ceph.cfg
@@ -8,8 +8,7 @@
 filename={FILENAME}
 NUM_ROUNDS=7
 
-NUMJOBS_LARGE={% 1, 5, 10, 15, 20, 30, 40, 80, 120 %}
-NUMJOBS_NORM={% 1, 5, 10, 15, 20, 30, 40 %}
+NUMJOBS={% 1, 5, 10, 15, 20, 30, 40 %}
 NUMJOBS_SHORT={% 1, 5, 10 %}
 
 size=30G
@@ -23,7 +22,7 @@
 blocksize=4k
 rw=randwrite
 sync=1
-numjobs={NUMJOBS_NORM}
+numjobs={NUMJOBS}
 
 # ---------------------------------------------------------------------
 # direct write
@@ -42,23 +41,15 @@
 blocksize=4k
 rw=randread
 direct=1
-numjobs={NUMJOBS_NORM}
+numjobs={NUMJOBS}
 
 # ---------------------------------------------------------------------
-# this is essentially sequential read openration
-# we can't use seq read with numjobs > 1 on clouds due to caching
+# this is essentially sequential write/read operations
+# we can't use sequential with numjobs > 1 due to caching and block merging
 # ---------------------------------------------------------------------
 [ceph_test_{TEST_SUMM} * {NUM_ROUNDS}]
 blocksize=16m
-rw=randread
+rw={% randread, randwrite %}
 direct=1
 numjobs={NUMJOBS_SHORT}
 
-# ---------------------------------------------------------------------
-# sequential write
-# ---------------------------------------------------------------------
-[ceph_test_{TEST_SUMM} * {NUM_ROUNDS}]
-blocksize=1m
-rw=write
-direct=1
-numjobs={NUMJOBS_NORM}
diff --git a/wally/suits/io/check_distribution.cfg b/wally/suits/io/check_distribution.cfg
index 6ba3f9f..d08e52b 100644
--- a/wally/suits/io/check_distribution.cfg
+++ b/wally/suits/io/check_distribution.cfg
@@ -1,3 +1,6 @@
+[defaults]
+NUM_ROUNDS=301
+
 [distrubution_test_{TEST_SUMM} * {NUM_ROUNDS}]
 blocksize=4k
 rw=randwrite
@@ -7,7 +10,7 @@
 wait_for_previous
 filename={FILENAME}
 iodepth=1
-size=10Gb
+size=10G
 time_based
 runtime=30
 group_reporting
diff --git a/wally/suits/io/check_linearity.cfg b/wally/suits/io/check_linearity.cfg
index 4017cf3..a75d937 100644
--- a/wally/suits/io/check_linearity.cfg
+++ b/wally/suits/io/check_linearity.cfg
@@ -6,7 +6,7 @@
 wait_for_previous
 filename={FILENAME}
 iodepth=1
-size=10Gb
+size=10G
 time_based
 runtime=30
 
diff --git a/wally/suits/io/check_th_count.cfg b/wally/suits/io/check_th_count.cfg
index 3d57154..3f9dd19 100644
--- a/wally/suits/io/check_th_count.cfg
+++ b/wally/suits/io/check_th_count.cfg
@@ -5,7 +5,7 @@
 wait_for_previous
 filename={FILENAME}
 iodepth=1
-size=10Gb
+size=10G
 time_based
 runtime=30
 group_reporting
diff --git a/wally/suits/io/check_warmup.cfg b/wally/suits/io/check_warmup.cfg
index 6a9c622..37ee083 100644
--- a/wally/suits/io/check_warmup.cfg
+++ b/wally/suits/io/check_warmup.cfg
@@ -6,7 +6,7 @@
 wait_for_previous
 filename={FILENAME}
 iodepth=1
-size=10Gb
+size=10G
 time_based
 runtime=30
 
diff --git a/wally/suits/io/formatter.py b/wally/suits/io/formatter.py
index 63c9408..7fbe70b 100644
--- a/wally/suits/io/formatter.py
+++ b/wally/suits/io/formatter.py
@@ -19,13 +19,15 @@
     create a table with io performance report
     for console
     """
-    tab = texttable.Texttable()
+    tab = texttable.Texttable(max_width=120)
     tab.set_deco(tab.HEADER | tab.VLINES | tab.BORDER)
-    tab.set_cols_align(["l", "r", "r", "r", "r"])
+    tab.set_cols_align(["l", "r", "r", "r", "r", "r", "r"])
 
     prev_k = None
-
+    vm_count = test_set['__test_meta__']['testnodes_count']
     items = sorted(test_set['res'].items(), key=key_func)
+    header = ["Description", "iops\ncum", "KiBps\ncum",
+              "iops\nper vm", "KiBps\nper vm", "Cnf\n%", "lat\nms"]
 
     for test_name, data in items:
 
@@ -33,7 +35,9 @@
 
         if prev_k is not None:
             if prev_k != curr_k:
-                tab.add_row(["---"] * 5)
+                tab.add_row(
+                    ["--------", "-----", "------",
+                     "-----", "------", "---", "-----"])
 
         prev_k = curr_k
 
@@ -54,12 +58,14 @@
 
         iops = round_3_digit(iops)
         bw = round_3_digit(bw)
+        iops_cum = round_3_digit(iops * vm_count)
+        bw_cum = round_3_digit(bw * vm_count)
         med_lat = round_3_digit(med_lat)
 
-        params = (descr, int(iops), int(bw), dev_perc, med_lat)
+        params = (descr, int(iops_cum), int(bw_cum),
+                  int(iops), int(bw), dev_perc, med_lat)
         tab.add_row(params)
 
-    header = ["Description", "IOPS", "BW KiBps", "Dev * 3 %", "clat ms"]
     tab.header(header)
 
     return tab.draw()
diff --git a/wally/suits/io/hdd.cfg b/wally/suits/io/hdd.cfg
index 519fb0f..07e45e9 100644
--- a/wally/suits/io/hdd.cfg
+++ b/wally/suits/io/hdd.cfg
@@ -7,7 +7,7 @@
 softrandommap=1
 filename={FILENAME}
 NUM_ROUNDS=7
-NUMJOBS={% 1, 5, 10, 15, 20, 30, 40, 80, 120 %}
+NUMJOBS={% 1, 5, 10, 15, 20, 30, 40, 80 %}
 
 size=10G
 ramp_time=5
diff --git a/wally/suits/io/long_test.cfg b/wally/suits/io/long_test.cfg
index 4b0a79d..a59c360 100644
--- a/wally/suits/io/long_test.cfg
+++ b/wally/suits/io/long_test.cfg
@@ -8,7 +8,7 @@
 wait_for_previous
 filename={FILENAME}
 iodepth=1
-size=50Gb
+size=50G
 time_based
 runtime=300
 
diff --git a/wally/suits/io/vm_count_ec2.cfg b/wally/suits/io/vm_count_ec2.cfg
index 19c9e50..c132039 100644
--- a/wally/suits/io/vm_count_ec2.cfg
+++ b/wally/suits/io/vm_count_ec2.cfg
@@ -5,12 +5,13 @@
 wait_for_previous
 filename={FILENAME}
 iodepth=1
-size=10Gb
+size=10G
 time_based
 runtime=30
 group_reporting
 rate={BW_LIMIT}
 rate_iops={IOPS_LIMIT}
+NUMJOBS={% 1, 2, 5, 10, 15, 20, 25, 30, 35, 40 %}
 
 # ---------------------------------------------------------------------
 # check different thread count. (latency, bw) = func(th_count)
@@ -19,11 +20,11 @@
 blocksize={% 4k, 1m %}
 rw={% randwrite, randread %}
 direct=1
-numjobs={% 1, 2, 5, 10, 15, 20, 25, 30, 35, 40 %}
+numjobs={NUMJOBS}
 
 [vm_count_{TEST_SUMM} * {NUM_ROUNDS}]
 blocksize={% 4k, 1m %}
 rw=randwrite
 direct=0
 sync=1
-numjobs={% 1, 2, 5, 10, 15, 20, 25, 30, 35, 40 %}
+numjobs={NUMJOBS}