summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/1mbs_clients.pngbin0 -> 121336 bytes
-rw-r--r--examples/aio-read.pngbin0 -> 76819 bytes
-rw-r--r--examples/backwards-read.pngbin0 -> 31100 bytes
-rw-r--r--examples/basic-verify.pngbin0 -> 35952 bytes
-rw-r--r--examples/butterfly.pngbin0 -> 35393 bytes
-rw-r--r--examples/cpp_null.pngbin0 -> 34346 bytes
-rw-r--r--examples/cpuio.pngbin0 -> 52593 bytes
-rw-r--r--examples/cross-stripe-verify.pngbin0 -> 54366 bytes
-rw-r--r--examples/dev-dax.pngbin0 -> 93539 bytes
-rw-r--r--examples/dfs.pngbin0 -> 187461 bytes
-rw-r--r--examples/disk-zone-profile.pngbin0 -> 37313 bytes
-rw-r--r--examples/e4defrag.pngbin0 -> 97107 bytes
-rw-r--r--examples/e4defrag2.pngbin0 -> 222226 bytes
-rw-r--r--examples/enospc-pressure.pngbin0 -> 150373 bytes
-rw-r--r--examples/exitwhat.pngbin0 -> 111627 bytes
-rw-r--r--examples/falloc.pngbin0 -> 129273 bytes
-rw-r--r--examples/filecreate-ioengine.pngbin0 -> 59636 bytes
-rw-r--r--examples/filedelete-ioengine.pngbin0 -> 33042 bytes
-rw-r--r--examples/filestat-ioengine.pngbin0 -> 52330 bytes
-rw-r--r--examples/fio-rand-RW.pngbin0 -> 47406 bytes
-rw-r--r--examples/fio-rand-read.pngbin0 -> 36614 bytes
-rw-r--r--examples/fio-rand-write.pngbin0 -> 38608 bytes
-rw-r--r--examples/fio-seq-RW.pngbin0 -> 48279 bytes
-rw-r--r--examples/fio-seq-read.pngbin0 -> 37851 bytes
-rw-r--r--examples/fio-seq-write.pngbin0 -> 42756 bytes
-rw-r--r--examples/fixed-rate-submission.pngbin0 -> 41703 bytes
-rw-r--r--examples/flow.pngbin0 -> 63860 bytes
-rw-r--r--examples/fsx.pngbin0 -> 37310 bytes
-rw-r--r--examples/ftruncate.pngbin0 -> 56594 bytes
-rw-r--r--examples/gfapi.pngbin0 -> 46875 bytes
-rw-r--r--examples/gpudirect-rdmaio-client.pngbin0 -> 50659 bytes
-rw-r--r--examples/gpudirect-rdmaio-server.pngbin0 -> 37805 bytes
-rw-r--r--examples/http-s3.pngbin0 -> 108929 bytes
-rw-r--r--examples/http-swift.pngbin0 -> 113698 bytes
-rw-r--r--examples/http-webdav.pngbin0 -> 86857 bytes
-rw-r--r--examples/ime.pngbin0 -> 193722 bytes
-rw-r--r--examples/iometer-file-access-server.pngbin0 -> 44797 bytes
-rw-r--r--examples/jesd219.pngbin0 -> 64846 bytes
-rw-r--r--examples/latency-profile.pngbin0 -> 44487 bytes
-rw-r--r--examples/libcufile-cufile.pngbin0 -> 160611 bytes
-rw-r--r--examples/libcufile-posix.pngbin0 -> 164649 bytes
-rw-r--r--examples/libhdfs.pngbin0 -> 32812 bytes
-rw-r--r--examples/libiscsi.pngbin0 -> 31649 bytes
-rw-r--r--examples/libpmem.pngbin0 -> 119668 bytes
-rw-r--r--examples/librpma_apm-client.pngbin0 -> 53792 bytes
-rw-r--r--examples/librpma_apm-server.pngbin0 -> 42611 bytes
-rw-r--r--examples/librpma_gpspm-client.pngbin0 -> 56398 bytes
-rw-r--r--examples/librpma_gpspm-server.pngbin0 -> 53793 bytes
-rw-r--r--examples/libzbc-rand-write.pngbin0 -> 48503 bytes
-rw-r--r--examples/libzbc-seq-read.pngbin0 -> 47229 bytes
-rw-r--r--examples/mtd.pngbin0 -> 79866 bytes
-rw-r--r--examples/nbd.pngbin0 -> 88667 bytes
-rw-r--r--examples/netio.pngbin0 -> 50944 bytes
-rw-r--r--examples/netio_multicast.pngbin0 -> 74921 bytes
-rw-r--r--examples/nfs.pngbin0 -> 84808 bytes
-rw-r--r--examples/null.pngbin0 -> 30223 bytes
-rw-r--r--examples/numa.pngbin0 -> 66068 bytes
-rw-r--r--examples/pmemblk.pngbin0 -> 107529 bytes
-rw-r--r--examples/poisson-rate-submission.pngbin0 -> 41057 bytes
-rw-r--r--examples/rados.pngbin0 -> 39665 bytes
-rw-r--r--examples/rand-zones.pngbin0 -> 38297 bytes
-rw-r--r--examples/rbd.pngbin0 -> 37191 bytes
-rw-r--r--examples/rdmaio-client.pngbin0 -> 44671 bytes
-rw-r--r--examples/rdmaio-server.pngbin0 -> 31860 bytes
-rw-r--r--examples/ssd-steadystate.pngbin0 -> 71772 bytes
-rw-r--r--examples/ssd-test.pngbin0 -> 99835 bytes
-rw-r--r--examples/steadystate.pngbin0 -> 64580 bytes
-rw-r--r--examples/surface-scan.pngbin0 -> 72042 bytes
-rw-r--r--examples/test.pngbin0 -> 30141 bytes
-rw-r--r--examples/tiobench-example.pngbin0 -> 71939 bytes
-rw-r--r--examples/waitfor.pngbin0 -> 94577 bytes
-rw-r--r--examples/zbd-rand-write.pngbin0 -> 53018 bytes
-rw-r--r--examples/zbd-seq-read.pngbin0 -> 50185 bytes
-rw-r--r--examples/zipf.pngbin0 -> 33276 bytes
-rw-r--r--tools/fiograph/fiograph.conf102
-rwxr-xr-xtools/fiograph/fiograph.py305
76 files changed, 407 insertions, 0 deletions
diff --git a/examples/1mbs_clients.png b/examples/1mbs_clients.png
new file mode 100644
index 00000000..3f972dc6
--- /dev/null
+++ b/examples/1mbs_clients.png
Binary files differ
diff --git a/examples/aio-read.png b/examples/aio-read.png
new file mode 100644
index 00000000..e0c020a5
--- /dev/null
+++ b/examples/aio-read.png
Binary files differ
diff --git a/examples/backwards-read.png b/examples/backwards-read.png
new file mode 100644
index 00000000..81dc9208
--- /dev/null
+++ b/examples/backwards-read.png
Binary files differ
diff --git a/examples/basic-verify.png b/examples/basic-verify.png
new file mode 100644
index 00000000..98f73020
--- /dev/null
+++ b/examples/basic-verify.png
Binary files differ
diff --git a/examples/butterfly.png b/examples/butterfly.png
new file mode 100644
index 00000000..2c566512
--- /dev/null
+++ b/examples/butterfly.png
Binary files differ
diff --git a/examples/cpp_null.png b/examples/cpp_null.png
new file mode 100644
index 00000000..5303ac2a
--- /dev/null
+++ b/examples/cpp_null.png
Binary files differ
diff --git a/examples/cpuio.png b/examples/cpuio.png
new file mode 100644
index 00000000..02938dbb
--- /dev/null
+++ b/examples/cpuio.png
Binary files differ
diff --git a/examples/cross-stripe-verify.png b/examples/cross-stripe-verify.png
new file mode 100644
index 00000000..90aa630f
--- /dev/null
+++ b/examples/cross-stripe-verify.png
Binary files differ
diff --git a/examples/dev-dax.png b/examples/dev-dax.png
new file mode 100644
index 00000000..2463bca3
--- /dev/null
+++ b/examples/dev-dax.png
Binary files differ
diff --git a/examples/dfs.png b/examples/dfs.png
new file mode 100644
index 00000000..049ccaec
--- /dev/null
+++ b/examples/dfs.png
Binary files differ
diff --git a/examples/disk-zone-profile.png b/examples/disk-zone-profile.png
new file mode 100644
index 00000000..5f7b24c9
--- /dev/null
+++ b/examples/disk-zone-profile.png
Binary files differ
diff --git a/examples/e4defrag.png b/examples/e4defrag.png
new file mode 100644
index 00000000..00a7fefd
--- /dev/null
+++ b/examples/e4defrag.png
Binary files differ
diff --git a/examples/e4defrag2.png b/examples/e4defrag2.png
new file mode 100644
index 00000000..8a128e95
--- /dev/null
+++ b/examples/e4defrag2.png
Binary files differ
diff --git a/examples/enospc-pressure.png b/examples/enospc-pressure.png
new file mode 100644
index 00000000..da28b7c0
--- /dev/null
+++ b/examples/enospc-pressure.png
Binary files differ
diff --git a/examples/exitwhat.png b/examples/exitwhat.png
new file mode 100644
index 00000000..9fc1883f
--- /dev/null
+++ b/examples/exitwhat.png
Binary files differ
diff --git a/examples/falloc.png b/examples/falloc.png
new file mode 100644
index 00000000..886be22e
--- /dev/null
+++ b/examples/falloc.png
Binary files differ
diff --git a/examples/filecreate-ioengine.png b/examples/filecreate-ioengine.png
new file mode 100644
index 00000000..45d11da3
--- /dev/null
+++ b/examples/filecreate-ioengine.png
Binary files differ
diff --git a/examples/filedelete-ioengine.png b/examples/filedelete-ioengine.png
new file mode 100644
index 00000000..3512ab71
--- /dev/null
+++ b/examples/filedelete-ioengine.png
Binary files differ
diff --git a/examples/filestat-ioengine.png b/examples/filestat-ioengine.png
new file mode 100644
index 00000000..bed59ab9
--- /dev/null
+++ b/examples/filestat-ioengine.png
Binary files differ
diff --git a/examples/fio-rand-RW.png b/examples/fio-rand-RW.png
new file mode 100644
index 00000000..aa4b0998
--- /dev/null
+++ b/examples/fio-rand-RW.png
Binary files differ
diff --git a/examples/fio-rand-read.png b/examples/fio-rand-read.png
new file mode 100644
index 00000000..d45664a4
--- /dev/null
+++ b/examples/fio-rand-read.png
Binary files differ
diff --git a/examples/fio-rand-write.png b/examples/fio-rand-write.png
new file mode 100644
index 00000000..10e068bc
--- /dev/null
+++ b/examples/fio-rand-write.png
Binary files differ
diff --git a/examples/fio-seq-RW.png b/examples/fio-seq-RW.png
new file mode 100644
index 00000000..a2be35ec
--- /dev/null
+++ b/examples/fio-seq-RW.png
Binary files differ
diff --git a/examples/fio-seq-read.png b/examples/fio-seq-read.png
new file mode 100644
index 00000000..cf8f2978
--- /dev/null
+++ b/examples/fio-seq-read.png
Binary files differ
diff --git a/examples/fio-seq-write.png b/examples/fio-seq-write.png
new file mode 100644
index 00000000..8db12092
--- /dev/null
+++ b/examples/fio-seq-write.png
Binary files differ
diff --git a/examples/fixed-rate-submission.png b/examples/fixed-rate-submission.png
new file mode 100644
index 00000000..86ca9b3e
--- /dev/null
+++ b/examples/fixed-rate-submission.png
Binary files differ
diff --git a/examples/flow.png b/examples/flow.png
new file mode 100644
index 00000000..26a3d34c
--- /dev/null
+++ b/examples/flow.png
Binary files differ
diff --git a/examples/fsx.png b/examples/fsx.png
new file mode 100644
index 00000000..b4e13c80
--- /dev/null
+++ b/examples/fsx.png
Binary files differ
diff --git a/examples/ftruncate.png b/examples/ftruncate.png
new file mode 100644
index 00000000..b98895f6
--- /dev/null
+++ b/examples/ftruncate.png
Binary files differ
diff --git a/examples/gfapi.png b/examples/gfapi.png
new file mode 100644
index 00000000..acc6a6ae
--- /dev/null
+++ b/examples/gfapi.png
Binary files differ
diff --git a/examples/gpudirect-rdmaio-client.png b/examples/gpudirect-rdmaio-client.png
new file mode 100644
index 00000000..eac79858
--- /dev/null
+++ b/examples/gpudirect-rdmaio-client.png
Binary files differ
diff --git a/examples/gpudirect-rdmaio-server.png b/examples/gpudirect-rdmaio-server.png
new file mode 100644
index 00000000..e043d7c0
--- /dev/null
+++ b/examples/gpudirect-rdmaio-server.png
Binary files differ
diff --git a/examples/http-s3.png b/examples/http-s3.png
new file mode 100644
index 00000000..2021e85e
--- /dev/null
+++ b/examples/http-s3.png
Binary files differ
diff --git a/examples/http-swift.png b/examples/http-swift.png
new file mode 100644
index 00000000..9928fb16
--- /dev/null
+++ b/examples/http-swift.png
Binary files differ
diff --git a/examples/http-webdav.png b/examples/http-webdav.png
new file mode 100644
index 00000000..c37c3de5
--- /dev/null
+++ b/examples/http-webdav.png
Binary files differ
diff --git a/examples/ime.png b/examples/ime.png
new file mode 100644
index 00000000..f636f5e7
--- /dev/null
+++ b/examples/ime.png
Binary files differ
diff --git a/examples/iometer-file-access-server.png b/examples/iometer-file-access-server.png
new file mode 100644
index 00000000..e3124554
--- /dev/null
+++ b/examples/iometer-file-access-server.png
Binary files differ
diff --git a/examples/jesd219.png b/examples/jesd219.png
new file mode 100644
index 00000000..73b5a124
--- /dev/null
+++ b/examples/jesd219.png
Binary files differ
diff --git a/examples/latency-profile.png b/examples/latency-profile.png
new file mode 100644
index 00000000..50650df8
--- /dev/null
+++ b/examples/latency-profile.png
Binary files differ
diff --git a/examples/libcufile-cufile.png b/examples/libcufile-cufile.png
new file mode 100644
index 00000000..f3758e5d
--- /dev/null
+++ b/examples/libcufile-cufile.png
Binary files differ
diff --git a/examples/libcufile-posix.png b/examples/libcufile-posix.png
new file mode 100644
index 00000000..7818feb4
--- /dev/null
+++ b/examples/libcufile-posix.png
Binary files differ
diff --git a/examples/libhdfs.png b/examples/libhdfs.png
new file mode 100644
index 00000000..e774c911
--- /dev/null
+++ b/examples/libhdfs.png
Binary files differ
diff --git a/examples/libiscsi.png b/examples/libiscsi.png
new file mode 100644
index 00000000..d0006cc0
--- /dev/null
+++ b/examples/libiscsi.png
Binary files differ
diff --git a/examples/libpmem.png b/examples/libpmem.png
new file mode 100644
index 00000000..8a9a1432
--- /dev/null
+++ b/examples/libpmem.png
Binary files differ
diff --git a/examples/librpma_apm-client.png b/examples/librpma_apm-client.png
new file mode 100644
index 00000000..2fe02cdf
--- /dev/null
+++ b/examples/librpma_apm-client.png
Binary files differ
diff --git a/examples/librpma_apm-server.png b/examples/librpma_apm-server.png
new file mode 100644
index 00000000..f78ae02e
--- /dev/null
+++ b/examples/librpma_apm-server.png
Binary files differ
diff --git a/examples/librpma_gpspm-client.png b/examples/librpma_gpspm-client.png
new file mode 100644
index 00000000..0c975a27
--- /dev/null
+++ b/examples/librpma_gpspm-client.png
Binary files differ
diff --git a/examples/librpma_gpspm-server.png b/examples/librpma_gpspm-server.png
new file mode 100644
index 00000000..56124533
--- /dev/null
+++ b/examples/librpma_gpspm-server.png
Binary files differ
diff --git a/examples/libzbc-rand-write.png b/examples/libzbc-rand-write.png
new file mode 100644
index 00000000..1d277412
--- /dev/null
+++ b/examples/libzbc-rand-write.png
Binary files differ
diff --git a/examples/libzbc-seq-read.png b/examples/libzbc-seq-read.png
new file mode 100644
index 00000000..5a532228
--- /dev/null
+++ b/examples/libzbc-seq-read.png
Binary files differ
diff --git a/examples/mtd.png b/examples/mtd.png
new file mode 100644
index 00000000..8cb3692e
--- /dev/null
+++ b/examples/mtd.png
Binary files differ
diff --git a/examples/nbd.png b/examples/nbd.png
new file mode 100644
index 00000000..e3bcf610
--- /dev/null
+++ b/examples/nbd.png
Binary files differ
diff --git a/examples/netio.png b/examples/netio.png
new file mode 100644
index 00000000..81afd41d
--- /dev/null
+++ b/examples/netio.png
Binary files differ
diff --git a/examples/netio_multicast.png b/examples/netio_multicast.png
new file mode 100644
index 00000000..f07ab4b7
--- /dev/null
+++ b/examples/netio_multicast.png
Binary files differ
diff --git a/examples/nfs.png b/examples/nfs.png
new file mode 100644
index 00000000..29dbca0d
--- /dev/null
+++ b/examples/nfs.png
Binary files differ
diff --git a/examples/null.png b/examples/null.png
new file mode 100644
index 00000000..052671db
--- /dev/null
+++ b/examples/null.png
Binary files differ
diff --git a/examples/numa.png b/examples/numa.png
new file mode 100644
index 00000000..1ef45759
--- /dev/null
+++ b/examples/numa.png
Binary files differ
diff --git a/examples/pmemblk.png b/examples/pmemblk.png
new file mode 100644
index 00000000..250e254b
--- /dev/null
+++ b/examples/pmemblk.png
Binary files differ
diff --git a/examples/poisson-rate-submission.png b/examples/poisson-rate-submission.png
new file mode 100644
index 00000000..739c2560
--- /dev/null
+++ b/examples/poisson-rate-submission.png
Binary files differ
diff --git a/examples/rados.png b/examples/rados.png
new file mode 100644
index 00000000..91bd61a0
--- /dev/null
+++ b/examples/rados.png
Binary files differ
diff --git a/examples/rand-zones.png b/examples/rand-zones.png
new file mode 100644
index 00000000..13cbfb47
--- /dev/null
+++ b/examples/rand-zones.png
Binary files differ
diff --git a/examples/rbd.png b/examples/rbd.png
new file mode 100644
index 00000000..f1186139
--- /dev/null
+++ b/examples/rbd.png
Binary files differ
diff --git a/examples/rdmaio-client.png b/examples/rdmaio-client.png
new file mode 100644
index 00000000..4e4bc289
--- /dev/null
+++ b/examples/rdmaio-client.png
Binary files differ
diff --git a/examples/rdmaio-server.png b/examples/rdmaio-server.png
new file mode 100644
index 00000000..fc344725
--- /dev/null
+++ b/examples/rdmaio-server.png
Binary files differ
diff --git a/examples/ssd-steadystate.png b/examples/ssd-steadystate.png
new file mode 100644
index 00000000..eb27f8a4
--- /dev/null
+++ b/examples/ssd-steadystate.png
Binary files differ
diff --git a/examples/ssd-test.png b/examples/ssd-test.png
new file mode 100644
index 00000000..a92ed153
--- /dev/null
+++ b/examples/ssd-test.png
Binary files differ
diff --git a/examples/steadystate.png b/examples/steadystate.png
new file mode 100644
index 00000000..4bb90484
--- /dev/null
+++ b/examples/steadystate.png
Binary files differ
diff --git a/examples/surface-scan.png b/examples/surface-scan.png
new file mode 100644
index 00000000..00573808
--- /dev/null
+++ b/examples/surface-scan.png
Binary files differ
diff --git a/examples/test.png b/examples/test.png
new file mode 100644
index 00000000..6be50029
--- /dev/null
+++ b/examples/test.png
Binary files differ
diff --git a/examples/tiobench-example.png b/examples/tiobench-example.png
new file mode 100644
index 00000000..14410326
--- /dev/null
+++ b/examples/tiobench-example.png
Binary files differ
diff --git a/examples/waitfor.png b/examples/waitfor.png
new file mode 100644
index 00000000..64e4bf94
--- /dev/null
+++ b/examples/waitfor.png
Binary files differ
diff --git a/examples/zbd-rand-write.png b/examples/zbd-rand-write.png
new file mode 100644
index 00000000..d58721be
--- /dev/null
+++ b/examples/zbd-rand-write.png
Binary files differ
diff --git a/examples/zbd-seq-read.png b/examples/zbd-seq-read.png
new file mode 100644
index 00000000..b81a08c4
--- /dev/null
+++ b/examples/zbd-seq-read.png
Binary files differ
diff --git a/examples/zipf.png b/examples/zipf.png
new file mode 100644
index 00000000..cb2a9816
--- /dev/null
+++ b/examples/zipf.png
Binary files differ
diff --git a/tools/fiograph/fiograph.conf b/tools/fiograph/fiograph.conf
new file mode 100644
index 00000000..7b851e19
--- /dev/null
+++ b/tools/fiograph/fiograph.conf
@@ -0,0 +1,102 @@
+[fio_jobs]
+header=<<B><font color="{}"> {} </font></B> >
+header_color=black
+text_color=darkgreen
+shape=box
+shape_color=blue
+style=rounded
+title_style=<<table border='0' cellborder='0' cellspacing='1'> <tr> <td align='center'> <b> {} </b> </td> </tr>
+item_style=<tr> <td align = "left"> <font color="{}" > {} </font> </td> </tr>
+cluster_style=filled
+cluster_color=gainsboro
+
+[exec_prerun]
+text_color=red
+
+[exec_postrun]
+text_color=red
+
+[numjobs]
+text_color=red
+style=<font color="{}" > x {} </font>
+
+[ioengine]
+text_color=darkblue
+specific_options_color=darkblue
+
+# definitions of engine's specific options
+
+[ioengine_cpuio]
+specific_options=cpuload cpumode cpuchunks exit_on_io_done
+
+[ioengine_dfs]
+specific_options=pool cont chunk_size object_class svcl
+
+[ioengine_e4defrag]
+specific_options=donorname inplace
+
+[ioengine_filestat]
+specific_options=stat_type
+
+[ioengine_single-instance]
+specific_options=volume brick
+
+[ioengine_http]
+specific_options=https http_host http_user http_pass http_s3_key http_s3_keyid http_swift_auth_token http_s3_region http_mode http_verbose
+
+[ioengine_ime_aio]
+specific_options=ime_psync ime_psyncv
+
+[ioengine_io_uring]
+specific_options=hipri cmdprio_percentage cmdprio_percentage fixedbufs registerfiles sqthread_poll sqthread_poll_cpu nonvectored uncached nowait force_async
+
+[ioengine_libaio]
+specific_options=userspace_reap cmdprio_percentage cmdprio_percentage nowait
+
+[ioengine_libcufile]
+specific_options=gpu_dev_ids cuda_io
+
+[ioengine_libhdfs]
+specific_options=namenode hostname port hdfsdirectory chunk_size single_instance hdfs_use_direct
+
+[ioengine_libiscsi]
+specific_options=initiator
+
+[ioengine_librpma_apm_server]
+specific_options=librpma_apm_client
+
+[ioengine_busy_wait_polling]
+specific_options=serverip port direct_write_to_pmem
+
+[ioengine_librpma_gpspm_server]
+specific_options=librpma_gpspm_client
+
+[ioengine_mmap]
+specific_options=thp
+
+[ioengine_mtd]
+specific_options=skip_bad
+
+[ioengine_nbd]
+specific_options=uri
+
+[ioengine_net]
+specific_options=hostname port protocol nodelay listen pingpong interface ttl window_size mss netsplice
+
+[ioengine_nfs]
+specific_options=nfs_url
+
+[ioengine_rados]
+specific_options=clustername pool clientname busy_poll touch_objects
+
+[ioengine_rbd]
+specific_options=clustername rbdname pool clientname busy_poll
+
+[ioengine_rdma]
+specific_options=hostname bindname port verb
+
+[ioengine_sg]
+specific_options=hipri readfua writefua sg_write_mode sg
+
+[ioengine_pvsync2]
+specific_options=hipri hipri_percentage uncached nowait sync psync vsync pvsync
diff --git a/tools/fiograph/fiograph.py b/tools/fiograph/fiograph.py
new file mode 100755
index 00000000..7695c964
--- /dev/null
+++ b/tools/fiograph/fiograph.py
@@ -0,0 +1,305 @@
+#!/usr/bin/env python3
+from graphviz import Digraph
+import argparse
+import configparser
+import os
+
+config_file = None
+fio_file = None
+
+
+def get_section_option(section_name, option_name, default=None):
+ global fio_file
+ if fio_file.has_option(section_name, option_name):
+ return fio_file[section_name][option_name]
+ return default
+
+
+def get_config_option(section_name, option_name, default=None):
+ global config_file
+ if config_file.has_option(section_name, option_name):
+ return config_file[section_name][option_name]
+ return default
+
+
+def get_header_color(keyword='fio_jobs', default_color='black'):
+ return get_config_option(keyword, 'header_color', default_color)
+
+
+def get_shape_color(keyword='fio_jobs', default_color='black'):
+ return get_config_option(keyword, 'shape_color', default_color)
+
+
+def get_text_color(keyword='fio_jobs', default_color='black'):
+ return get_config_option(keyword, 'text_color', default_color)
+
+
+def get_cluster_color(keyword='fio_jobs', default_color='gray92'):
+ return get_config_option(keyword, 'cluster_color', default_color)
+
+
+def get_header(keyword='fio_jobs'):
+ return get_config_option(keyword, 'header')
+
+
+def get_shape(keyword='fio_jobs'):
+ return get_config_option(keyword, 'shape', 'box')
+
+
+def get_style(keyword='fio_jobs'):
+ return get_config_option(keyword, 'style', 'rounded')
+
+
+def get_cluster_style(keyword='fio_jobs'):
+ return get_config_option(keyword, 'cluster_style', 'filled')
+
+
+def get_specific_options(engine):
+ if not engine:
+ return ''
+ return get_config_option('ioengine_{}'.format(engine), 'specific_options', '').split(' ')
+
+
+def render_option(section, label, display, option, color_override=None):
+ # These options are already shown with graphical helpers, no need to report them directly
+ skip_list = ['size', 'stonewall', 'runtime', 'time_based',
+ 'numjobs', 'wait_for', 'wait_for_previous']
+ # If the option doesn't exist or if a special handling is already done
+ # don't render it, just return the current state
+ if option in skip_list or option not in section:
+ return label, display
+ display = option
+ if section[option]:
+ display = '{} = {}'.format(display, section[option])
+
+ # Adding jobs's options into the box, darkgreen is the default color
+ if color_override:
+ color = color_override
+ else:
+ color = get_text_color(option, get_text_color('fio_jobs', 'darkgreen'))
+ label += get_config_option('fio_jobs',
+ 'item_style').format(color, display)
+ return label, display
+
+
+def render_options(fio_file, section_name):
+ """Render all options of a section."""
+ display = section_name
+ section = fio_file[section_name]
+
+ # Add a multiplier to the section_name if numjobs is set
+ numjobs = int(get_section_option(section_name, 'numjobs', '1'))
+ if numjobs > 1:
+ display = display + \
+ get_style('numjobs').format(
+ get_text_color('numjobs'), numjobs)
+
+ # Header of the box
+ label = get_config_option('fio_jobs', 'title_style').format(display)
+
+ # Let's parse all the options of the current fio thread
+ # Some needs to be printed on top or bottom of the job to ease the read
+ to_early_print = ['exec_prerun', 'ioengine']
+ to_late_print = ['exec_postrun']
+
+ # Let's print the options on top of the box
+ for early_print in to_early_print:
+ label, display = render_option(
+ section, label, display, early_print)
+
+ current_io_engine = get_section_option(
+ section_name, 'ioengine', None)
+ if current_io_engine:
+ # Let's print all specifics options for this engine
+ for specific_option in sorted(get_specific_options(current_io_engine)):
+ label, display = render_option(
+ section, label, display, specific_option, get_config_option('ioengine', 'specific_options_color'))
+
+ # Let's print generic options sorted by name
+ for option in sorted(section):
+ if option in to_early_print or option in to_late_print or option in get_specific_options(current_io_engine):
+ continue
+ label, display = render_option(section, label, display, option)
+
+ # let's print options on the bottom of the box
+ for late_print in to_late_print:
+ label, display = render_option(
+ section, label, display, late_print)
+
+ # End of the box content
+ label += '</table>>'
+ return label
+
+
+def render_section(current_graph, fio_file, section_name, label):
+ """Render the section."""
+ attr = None
+ section = fio_file[section_name]
+
+ # Let's render the box associated to a job
+ current_graph.node(section_name, label,
+ shape=get_shape(),
+ color=get_shape_color(),
+ style=get_style())
+
+ # Let's report the duration of the jobs with a self-loop arrow
+ if 'runtime' in section and 'time_based' in section:
+ attr = 'runtime={}'.format(section['runtime'])
+ elif 'size' in section:
+ attr = 'size={}'.format(section['size'])
+ if attr:
+ current_graph.edge(section_name, section_name, attr)
+
+
+def create_sub_graph(name):
+ """Return a new graph."""
+ # We need to put 'cluster' in the name to ensure graphviz consider it as a cluster
+ cluster_name = 'cluster_' + name
+ # Unset the main graph labels to avoid a recopy in each subgraph
+ attr = {}
+ attr['label'] = ''
+ new_graph = Digraph(name=cluster_name, graph_attr=attr)
+ new_graph.attr(style=get_cluster_style(),
+ color=get_cluster_color())
+ return new_graph
+
+
+def create_legend():
+ """Return a legend."""
+ html_table = "<<table border='0' cellborder='1' cellspacing='0' cellpadding='4'>"
+ html_table += '<tr><td COLSPAN="2"><b>Legend</b></td></tr>'
+ legend_item = '<tr> <td>{}</td> <td><font color="{}">{}</font></td></tr>"'
+ legend_bgcolor_item = '<tr><td>{}</td><td BGCOLOR="{}"></td></tr>'
+ html_table += legend_item.format('numjobs',
+ get_text_color('numjobs'), 'x numjobs')
+ html_table += legend_item.format('generic option',
+ get_text_color(), 'generic option')
+ html_table += legend_item.format('ioengine option',
+ get_text_color('ioengine'), 'ioengine option')
+ html_table += legend_bgcolor_item.format('job', get_shape_color())
+ html_table += legend_bgcolor_item.format(
+ 'execution group', get_cluster_color())
+ html_table += '</table>>'
+ legend = Digraph('html_table')
+ legend.node('legend', shape='none', label=html_table)
+ return legend
+
+
+def fio_to_graphviz(filename, format):
+ """Compute the graphviz graph from the fio file."""
+
+ # Let's read the fio file
+ global fio_file
+ fio_file = configparser.RawConfigParser(
+ allow_no_value=True,
+ default_section="global",
+ inline_comment_prefixes="'#', ';'")
+ fio_file.read(filename)
+
+ # Prepare the main graph object
+ # Let's define the header of the document
+ attrs = {}
+ attrs['labelloc'] = 't'
+ attrs['label'] = get_header().format(
+ get_header_color(), os.path.basename(filename))
+ main_graph = Digraph(engine='dot', graph_attr=attrs, format=format)
+
+ # Let's add a legend
+ main_graph.subgraph(create_legend())
+
+ # By default all jobs are run in parallel and depends on "global"
+ depends_on = fio_file.default_section
+
+ # The previous section is by default the global section
+ previous_section = fio_file.default_section
+
+ current_graph = main_graph
+
+ # The first job will be a new execution group
+ new_execution_group = True
+
+ # Let's interate on all sections to create links between them
+ for section_name in fio_file.sections():
+ # The current section
+ section = fio_file[section_name]
+
+ # If the current section is waiting the previous job
+ if ('stonewall' or 'wait_for_previous') in section:
+ # let's remember what was the previous job we depend on
+ depends_on = previous_section
+ new_execution_group = True
+ elif 'wait_for' in section:
+ # This sections depends on a named section pointed by wait_for
+ depends_on = section['wait_for']
+ new_execution_group = True
+
+ if new_execution_group:
+ # Let's link the current graph with the main one
+ main_graph.subgraph(current_graph)
+ # Let's create a new graph to represent all the incoming jobs running at the same time
+ current_graph = create_sub_graph(section_name)
+
+ # Let's render the current section in its execution group
+ render_section(current_graph, fio_file, section_name,
+ render_options(fio_file, section_name))
+
+ # Let's trace the link between this job and the one it depends on
+ # If we depend on 'global', we can avoid doing adding an arrow as we don't want to see 'global'
+ if depends_on != fio_file.default_section:
+ current_graph.edge(depends_on, section_name)
+
+ # The current section become the parent of the next one
+ previous_section = section_name
+
+ # We are by default in the same execution group
+ new_execution_group = False
+
+ # The last subgraph isn't rendered yet
+ main_graph.subgraph(current_graph)
+
+ # Let's return the main graphviz object
+ return main_graph
+
+
+def setup_commandline():
+ "Prepare the command line."
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--file', action='store',
+ type=str,
+ required=True,
+ help='the fio file to graph')
+ parser.add_argument('--output', action='store',
+ type=str,
+ help='the output filename')
+ parser.add_argument('--format', action='store',
+ type=str,
+ default='png',
+ help='the output format')
+ parser.add_argument('--view', action='store_true',
+ default=False,
+ help='view the graph')
+ parser.add_argument('--keep', action='store_true',
+ default=False,
+ help='keep the graphviz script file')
+ parser.add_argument('--config', action='store',
+ type=str,
+ default='fiograph.conf',
+ help='the configuration filename')
+ args = parser.parse_args()
+ return args
+
+
+def main():
+ global config_file
+ args = setup_commandline()
+ output_file = args.file
+ if args.output is None:
+ output_file = output_file.replace('.fio', '')
+ config_file = configparser.RawConfigParser(allow_no_value=True)
+ config_file.read(args.config)
+ fio_to_graphviz(args.file, args.format).render(output_file, view=args.view)
+ if not args.keep:
+ os.remove(output_file)
+
+
+main()