contrib: More trace visualization.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 6 Oct 2010 10:30:02 +0000 (11:30 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 6 Oct 2010 11:12:34 +0000 (12:12 +0100)
contrib/visualize-alignment/README
contrib/visualize-alignment/guestfish-lv-ext4-4k-write-hello.qtr [new file with mode: 0644]
contrib/visualize-alignment/guestfish-lv-ext4-4k.qtr [new file with mode: 0644]
contrib/visualize-alignment/guestfish-write-hello.qtr
contrib/visualize-alignment/tracetops.ml

index 02f78ab..0009dcf 100644 (file)
@@ -1,5 +1,15 @@
+This directory contains some experimental work for capturing traces of
+block device operations while filesystem operations are performed.
+
+You can trace any operation that libguestfs supports, including
+partitioning, mkfs, LVM operations, and filesystem operations.  You
+can enable and disable tracing in order to capture single operations
+such as a single write, or groups of operations.  You can examine the
+traces by hand (as text files) or turn them into graphical
+visualizations.
+
 The *.qtr files are qemu trace files, produced using the unofficial
-patch in the current directory.
+qemu patch in the current directory.
 
 - guestfish-N-fs-10M.qtr
 
@@ -18,5 +28,37 @@ patch in the current directory.
 
 - guestfish-write-hello.qtr
 
-  $ guestfish -a test1.img -m /dev/sda1 write /hello "hello, world."
-  Note that the trace includes the adding and mounting operations.
+  $ guestfish -a test1.img -m /dev/sda1 \
+      debug qtrace "/dev/vda on" : \
+      write /hello "hello, world." : \
+      debug qtrace "/dev/vda off"
+  where test1.img was created by the command above.
+
+  This is just the creation of a new file with a small amount of content.
+
+  Within this trace file, the qtrace on/off commands appear as patterns
+  of reads.  For on: 2, 21, 15, 2.  For off: 2, 15, 21, 2.
+
+- guestfish-lv-ext4-4k.qtr
+
+  $ guestfish \
+      alloc test1.img 40M : \
+      run : \
+      part-disk /dev/vda mbr : \
+      pvcreate /dev/vda : \
+      vgcreate VG /dev/vda : \
+      lvcreate LV VG 32 : \
+      mkfs-b ext4 4096 /dev/VG/LV
+
+  Some points to note:
+    * an ext4 filesystem, so it has a journal and extents
+    * 4K block size, so we expect writes to be aligned
+    * located inside an LV, so more realistic
+
+- guestfish-lv-ext4-4k-write-hello.qtr
+
+  $ guestfish -a test1.img -m /dev/VG/LV \
+      debug qtrace "/dev/vda on" : \
+      write /hello "hello, world." : \
+      debug qtrace "/dev/vda off"
+  where test1.img was created by the previous command.
diff --git a/contrib/visualize-alignment/guestfish-lv-ext4-4k-write-hello.qtr b/contrib/visualize-alignment/guestfish-lv-ext4-4k-write-hello.qtr
new file mode 100644 (file)
index 0000000..4f856ed
--- /dev/null
@@ -0,0 +1,104 @@
+S 81920
+R 0 1
+R 0 8
+R 8 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 0 32
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 0 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 0 8
+R 8 8
+R 8 8
+R 8 8
+R 0 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 65792 8
+R 65904 8
+R 384 8
+R 392 8
+R 65912 8
+R 65656 8
+R 65856 8
+R 65664 8
+R 65520 8
+R 2432 8
+R 408 8
+R 440 8
+R 504 8
+R 400 8
+R 512 8
+R 448 8
+R 896 8
+R 416 8
+R 4480 8
+R 65792 8
+R 65904 8
+R 384 8
+R 392 8
+R 65912 8
+R 65656 8
+R 65856 8
+R 65664 8
+R 65520 8
+R 2432 8
+R 408 8
+R 440 8
+R 504 8
+R 400 8
+R 512 8
+R 448 8
+R 896 8
+R 416 8
+R 4480 8
+R 386 2
+R 384 8
+R 392 8
+R 664 8
+R 456 8
+W 384 8
+R 2 1
+R 21 1
+R 15 1
+R 2 1
+R 416 8
+R 536 8
+R 664 8
+R 408 8
+W 456 8
+W 464 8
+W 10712 8
+W 472 40
+W 512 8
+W 392 8
+W 408 16
+W 536 8
+W 664 8
+R 2 1
+R 15 1
+R 21 1
+R 2 1
+W 384 8
+W 456 8
+W 384 8
diff --git a/contrib/visualize-alignment/guestfish-lv-ext4-4k.qtr b/contrib/visualize-alignment/guestfish-lv-ext4-4k.qtr
new file mode 100644 (file)
index 0000000..c95d4b5
--- /dev/null
@@ -0,0 +1,450 @@
+S 81920
+R 0 1
+R 0 8
+R 8 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 2048 8
+R 24 8
+R 56 8
+R 120 8
+R 16 8
+R 128 8
+R 64 8
+R 512 8
+R 32 8
+R 4096 8
+R 0 32
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 0 8
+R 0 8
+R 0 32
+R 32 64
+R 128 8
+R 81896 8
+W 0 24
+W 81896 24
+R 81792 8
+R 81904 8
+R 0 32
+W 0 8
+R 32 8
+R 40 56
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 81904 8
+R 32 8
+R 0 32
+W 0 8
+R 2048 8
+R 120 8
+R 16 8
+R 128 8
+R 64 8
+R 0 8
+R 512 8
+R 32 8
+R 4096 8
+R 81728 8
+R 81840 8
+R 64 8
+R 72 8
+R 81856 1
+R 81600 8
+R 81848 8
+R 2112 8
+R 88 8
+R 120 8
+R 184 8
+R 80 8
+R 192 8
+R 128 8
+R 576 8
+R 96 8
+R 4160 8
+R 0 8
+R 0 8
+R 81792 8
+R 81904 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 2048 8
+R 24 8
+R 56 8
+R 120 8
+R 16 8
+R 128 8
+R 64 8
+R 512 8
+R 32 8
+R 4096 8
+R 0 8
+R 8 8
+R 0 8
+R 8 8
+R 24 8
+R 120 8
+R 8 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 2048 8
+R 24 8
+R 56 8
+R 120 8
+R 16 8
+R 128 8
+R 64 8
+R 512 8
+R 32 8
+R 4096 8
+W 8 8
+R 0 8
+R 0 8
+W 0 8
+R 8 8
+W 8 8
+R 0 8
+W 0 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 0 8
+R 8 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81728 1
+R 81840 1
+R 64 1
+R 72 1
+R 64 4
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 81728 8
+R 81840 8
+R 64 8
+R 72 8
+R 81856 1
+R 81600 8
+R 81848 1
+R 81849 1
+R 81850 1
+R 81851 1
+R 81852 4
+R 2112 1
+R 2113 1
+R 2114 1
+R 2115 1
+R 2116 1
+R 2117 1
+R 2118 1
+R 2119 1
+R 88 1
+R 89 1
+R 90 1
+R 91 1
+R 92 1
+R 93 1
+R 94 1
+R 95 1
+R 120 1
+R 121 1
+R 122 1
+R 123 1
+R 124 1
+R 125 1
+R 126 1
+R 127 1
+R 184 1
+R 185 1
+R 186 6
+R 80 1
+R 81 1
+R 82 1
+R 83 1
+R 84 1
+R 85 3
+R 192 1
+R 193 1
+R 194 1
+R 195 1
+R 196 1
+R 197 1
+R 198 1
+R 199 1
+R 128 1
+R 129 1
+R 130 1
+R 131 1
+R 132 1
+R 133 1
+R 134 1
+R 135 1
+R 576 1
+R 577 1
+R 578 1
+R 579 1
+R 580 1
+R 581 1
+R 582 1
+R 583 1
+R 96 1
+R 97 1
+R 98 1
+R 99 1
+R 100 1
+R 101 1
+R 102 1
+R 103 1
+R 4160 1
+R 4161 1
+R 4162 1
+R 4163 1
+R 4164 1
+R 4165 1
+R 4166 1
+R 4167 1
+R 0 32
+R 81792 8
+R 81904 8
+R 0 8
+R 56 8
+R 8 8
+R 81728 1
+R 81840 1
+R 64 1
+R 72 1
+R 64 4
+R 81728 8
+R 81840 8
+R 64 8
+R 72 8
+R 81856 1
+R 81600 8
+R 81848 8
+R 2112 8
+R 88 8
+R 120 8
+R 184 8
+R 80 8
+R 192 8
+R 128 8
+R 576 8
+R 96 8
+R 4160 8
+R 0 8
+R 0 8
+R 24 8
+R 56 8
+R 8 8
+R 0 8
+R 8 8
+R 81792 8
+R 81904 8
+R 8 8
+R 0 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 0 8
+R 8 8
+R 81728 1
+R 81840 1
+R 64 1
+R 72 1
+R 64 1
+R 65 3
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 81728 8
+R 81840 8
+R 64 8
+R 72 8
+R 81856 1
+R 81600 8
+R 81848 8
+R 2112 8
+R 88 8
+R 120 8
+R 184 8
+R 80 8
+R 192 8
+R 128 8
+R 576 8
+R 96 8
+R 4160 8
+R 8 8
+R 8 8
+W 8 8
+R 8 8
+R 8 8
+W 8 8
+R 8 8
+R 8 8
+W 8 8
+R 81728 8
+R 81840 8
+R 64 8
+R 72 8
+R 81856 1
+R 81600 8
+R 81848 8
+R 2112 8
+R 88 8
+R 120 8
+R 184 8
+R 80 8
+R 192 8
+R 128 8
+R 576 8
+R 96 8
+R 4160 8
+R 81792 8
+R 81904 8
+R 0 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 0 8
+R 8 8
+R 8 8
+R 8 8
+R 64 4
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+W 8 8
+R 8 8
+R 8 8
+R 8 8
+W 8 8
+R 8 8
+R 8 8
+R 8 8
+W 8 8
+R 0 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 8 8
+R 81728 8
+R 81840 8
+R 64 8
+R 72 8
+R 81856 1
+R 81600 8
+R 81848 8
+R 2112 8
+R 88 8
+R 120 8
+R 184 8
+R 80 8
+R 192 8
+R 128 8
+R 576 8
+R 96 8
+R 4160 8
+R 0 8
+R 24 8
+R 56 8
+R 65792 8
+R 65904 8
+R 384 8
+R 392 8
+R 65912 8
+R 65656 8
+R 65856 8
+R 65664 8
+R 65520 8
+R 2432 8
+R 408 8
+R 440 8
+R 504 8
+R 400 8
+R 512 8
+R 448 8
+R 896 8
+R 416 8
+R 4480 8
+R 384 8
+W 384 8
+R 81792 8
+R 81904 8
+R 8 8
+R 81912 8
+R 81656 8
+R 81856 8
+R 81664 8
+R 81520 8
+R 384 8
+W 384 3032
+W 3416 576
+W 3992 1448
+W 5440 1608
+W 7048 3032
+W 10080 632
+W 65792 128
+W 384 8
+W 384 8
index b561d6d..28f7bf1 100644 (file)
@@ -25,8 +25,7 @@ R 20400 8
 R 64 8
 R 72 8
 R 20416 1
-R 20160 1
-R 20161 7
+R 20160 8
 R 20408 8
 R 2112 8
 R 88 8
@@ -67,15 +66,36 @@ R 66 2
 R 68 2
 R 152 2
 W 66 2
+W 66 2
+W 66 2
+W 66 2
+R 2 1
+R 21 1
+R 15 1
+R 2 1
+W 66 2
+W 66 2
+W 66 2
 R 470 2
 R 150 2
 R 154 2
 R 148 2
-W 66 4
-W 148 2
 W 470 2
-W 13378 2
-W 150 6
+W 11330 2
+R 152 2
+W 66 2
+W 68 2
+W 148 8
+W 66 2
+W 66 2
+R 2 1
+R 15 1
+R 21 1
+R 2 1
+W 66 2
+W 66 2
+W 66 2
+W 66 2
 W 66 2
 W 66 2
 W 66 2
index 6600793..3ea2327 100755 (executable)
@@ -1,16 +1,33 @@
 #!/usr/bin/ocamlrun /usr/bin/ocaml
 
-#use "topfind";;
-#require "extlib";;
+(* Convert *.qtr (qemu block device trace) to Postscript.
+ * Copyright (C) 2009-2010 Red Hat Inc.
+ * By Richard W.M. Jones <rjones@redhat.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
 
-(* Convert *.qtr (qemu block device trace) to Postscript.  By Richard
- * W.M. Jones <rjones@redhat.com>.
- * 
- * Note that we use ordinary OCaml ints, which means this program is
+(* Note that we use ordinary OCaml ints, which means this program is
  * limited to: ~1TB disks for 32 bit machines, or effectively unlimited
- * for 64 bit machines.
+ * for 64 bit machines.  Also we make several 512 byte sector
+ * assumptions.
  *)
 
+#use "topfind";;
+#require "extlib";;
+
 open ExtList
 open Scanf
 open Printf
@@ -18,7 +35,7 @@ open Printf
 type op = Read | Write
 
 (* If 'true' then print debug messages. *)
-let debug = false
+let debug = true
 
 (* Width of each row (in sectors) in the output. *)
 let row_size = 64
@@ -88,6 +105,58 @@ let nb_sectors, accesses =
 
   nb_sectors, accesses
 
+(* If the accesses list contains any qtrace on/off patterns (in
+ * guestfish: debug "qtrace /dev/vda (on|off)") then filter out the
+ * things we want to display.  Otherwise leave the whole trace.
+ *)
+let accesses =
+  let contains_qtrace_patterns =
+    let rec loop = function
+      | [] -> false
+      | (Read, _, 2, 1) :: (Read, _, 21, 1) :: (Read, _, 15, 1) ::
+          (Read, _, 2, 1) :: _ -> true
+      | (Read, _, 2, 1) :: (Read, _, 15, 1) :: (Read, _, 21, 1) ::
+          (Read, _, 2, 1) :: _ -> true
+      | _ :: rest -> loop rest
+    in
+    loop accesses in
+
+  if contains_qtrace_patterns then (
+    if debug then eprintf "%s: contains qtrace on/off patterns\n%!" input;
+
+    let rec find_qtrace_on = function
+      | [] -> []
+      | (Read, _, 2, 1) :: (Read, _, 21, 1) :: (Read, _, 15, 1) ::
+          (Read, _, 2, 1) :: rest -> rest
+      | (Read, _, 2, 1) :: (Read, _, 15, 1) :: (Read, _, 21, 1) ::
+          (Read, _, 2, 1) :: rest ->
+          eprintf "ignored 'qtrace off' pattern when expecting 'qtrace on'\n";
+          find_qtrace_on rest
+      | _ :: rest -> find_qtrace_on rest
+    and split_until_qtrace_off = function
+      | [] -> [], []
+      | (Read, _, 2, 1) :: (Read, _, 15, 1) :: (Read, _, 21, 1) ::
+          (Read, _, 2, 1) :: rest -> [], rest
+      | (Read, _, 2, 1) :: (Read, _, 21, 1) :: (Read, _, 15, 1) ::
+          (Read, _, 2, 1) :: rest ->
+          eprintf "found 'qtrace on' pattern when expecting 'qtrace off'\n";
+          split_until_qtrace_off rest
+      | x :: ys ->
+          let xs, ys = split_until_qtrace_off ys in
+          x :: xs, ys
+    and filter_accesses xs =
+      let xs = find_qtrace_on xs in
+      if xs <> [] then (
+        let xs, ys = split_until_qtrace_off xs in
+        let ys = filter_accesses ys in
+        xs @ ys
+      ) else
+        []
+    in
+    filter_accesses accesses
+  ) else
+    accesses
+
 let ranges =
   (* Given the number of sectors, make the row array. *)
   let nr_rows = nb_sectors / row_size in