mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
This commit adds an optional 'cachemode' parameter to the 'add_drive'
API to control caching. This corresponds approximately to the
'-drive ...,cache=' parameter in qemu, but the choices are much more
restrictive, just 'writeback' or 'unsafe', for reasons outlined below.
The caching modes supported by recent QEMU are:
writeback:
- Reports data writes completed when data is present in the host
page cache.
Only safe provided guest correctly issues flush operations.
writethrough:
- Reports data writes completed only when each write has been
flushed to disk. Performance is reported as not good.
none:
- Uses O_DIRECT (avoids all interaction with host cache), but does
not ensure every write is flushed to disk.
Only safe provided guest correctly issues flush operations.
directsync:
- Uses O_DIRECT (avoids all interaction with host cache), and
ensures every write has been flushed to disk.
unsafe:
- No special handling.
Since the libguestfs appliance kernel always issues flush operations
(eg. for filesystem journalling and for sync) the following modes can
be ignored: 'directsync', 'writethrough'.
That leaves 'writeback', 'none' and 'unsafe'. However 'none' is both
a constant source of pain (RHBZ#994517), is inefficient because it
doesn't use the host cache, and does not give us any safety guarantees
over and above 'writeback'. Therefore we should ignore 'none'.
This leaves 'writeback' (safe) and 'unsafe' (fast, useful for scratch
disks), which is what we implement in this patch.
Note that the previous behaviour was to use 'none' if possible, else
to use 'writeback'. The new behaviour is to use 'writeback' only
which is (in safety terms) equivalent to 'none', and also faster and
less painful (RHBZ#994517).
This patch also allows you to specify a cache mode for network drives
which also previously defaulted to 'writeback'.
There is a considerable performance benefit to using unsafe (for
scratch disks only, of course). The C API tests only use scratch
disks (since they are just tests, the final state of the disk doesn't
matter), and this decreases total run time from 202 seconds to 163
seconds, about 25% faster.
This program generates a large amount of code and documentation for all the daemon actions. To add a new action there are only two files you need to change, 'actions.ml' to describe the interface, and daemon/<somefile>.c to write the implementation. After editing these files, build it (make -C generator) to regenerate all the output files. 'make' will rerun this automatically when necessary. IMPORTANT: This program should NOT print any warnings at compile time or run time. If it prints warnings, you should treat them as errors. OCaml tips: (1) In emacs, install tuareg-mode to display and format OCaml code correctly. 'vim' comes with a good OCaml editing mode by default. (2) Read the resources at http://ocaml-tutorial.org/ (3) A module called 'Foo' is defined in one or two files called 'foo.mli' and 'foo.ml' (NB: lowercase first letter). The *.mli file, if present, defines the public interface for the module. The *.ml file is the implementation. If the *.mli file is missing then everything is exported. Some notable files in this directory: actions.ml The libguestfs API. structs.ml Structures returned by the API. c.ml Generate C API. <lang>.ml Generate bindings for <lang>. main.ml The main generator program. Note about long descriptions: When referring to another action, use the format C<guestfs_other> (ie. the full name of the C function). This will be replaced as appropriate in other language bindings. Apart from that, long descriptions are just perldoc paragraphs. Note about extending functions: In general you cannot change the name, number of required arguments or type of required arguments of a function, since this would break backwards compatibility. You may add another optional argument, *if* the function has >= 1 optional arguments already. Add it at the end of the list. You may add optional arguments to a function that doesn't have any. However you *must* set the once_had_no_optargs flag to true, so that the relevant backwards compatibility bindings can be added.