The readahead filter is a self-configuring filter that makes
sequential reads faster when the plugin is slow (and all of the
plugins we use here are always slow).
I observed the behaviour of the readahead filter with our qcow2
overlay when converting a guest from a vCenter source. Even when
doing random reads, qemu issues 64K reads which happen to also be the
minimum request size of the readahead filter, so there is no extra
overhead. When doing the sequential copy the readahead filter
performed better than qemu curl’s readahead because it scaled the
prefetched data appropriately on long contiguous stretches and then
shrunk it back to 64K around fragmented parts of the base image.
---
v2v/nbdkit.ml | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/v2v/nbdkit.ml b/v2v/nbdkit.ml
index 4bbb8f043..b2d77f963 100644
--- a/v2v/nbdkit.ml
+++ b/v2v/nbdkit.ml
@@ -49,6 +49,9 @@ type t = {
(* nbdkit plugin_name --dump-plugin output. *)
dump_plugin : (string * string) list;
+
+ (* nbdkit directory containing the filters. *)
+ filterdir : string;
}
(* Check that nbdkit is available and new enough. *)
@@ -105,6 +108,12 @@ let common_create plugin_name plugin_args plugin_env =
error_unless_nbdkit_min_version dump_config;
error_unless_nbdkit_compiled_with_selinux dump_config;
+ (* Get the filterdir. *)
+ let filterdir =
+ try List.assoc "filterdir" dump_config
+ with Not_found ->
+ error (f_"nbdkit --dump-config output did not contain filterdir") in
+
(* Get the nbdkit plugin_name --dump-plugin output, which also
* checks that the plugin is available and loadable.
*)
@@ -133,9 +142,17 @@ let common_create plugin_name plugin_args plugin_env =
if have_selinux then ( (* label the socket so qemu can open it *)
add_arg "--selinux-label"; add_arg
"system_u:object_r:svirt_socket_t:s0"
);
+
+ (* Adding the readahead filter is always a win for our access
+ * patterns. However if it doesn't exist don't worry.
+ *)
+ if Sys.file_exists (filterdir // "nbdkit-readahead-filter.so") then (
+ add_arg "--filter"; add_arg "readahead"
+ );
+
let args = get_args () @ [ plugin_name ] @ plugin_args in
- { plugin_name; args; env; dump_config; dump_plugin }
+ { plugin_name; args; env; dump_config; dump_plugin; filterdir }
(* VDDK libraries are located under lib32/ or lib64/ relative to the
* libdir. Note this is unrelated to Linux multilib or multiarch.
--
2.23.0