tests: Rename capitests -> tests/c-api.
[libguestfs.git] / generator / generator_actions.ml
index 0ae8790..f7a6a6c 100644 (file)
@@ -1,5 +1,5 @@
 (* libguestfs
- * Copyright (C) 2009-2010 Red Hat Inc.
+ * Copyright (C) 2009-2011 Red Hat Inc.
  *
  * 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
@@ -103,7 +103,7 @@ You probably don't want to call this function.")]
  *)
 
 let non_daemon_functions = test_functions @ [
-  ("launch", (RErr, [], []), -1, [FishAlias "run"],
+  ("launch", (RErr, [], []), -1, [FishAlias "run"; Progress],
    [],
    "launch the qemu subprocess",
    "\
@@ -113,7 +113,7 @@ using L<qemu(1)>.
 You should call this after configuring the handle
 (eg. adding drives) but before performing any actions.");
 
-  ("wait_ready", (RErr, [], []), -1, [NotInFish],
+  ("wait_ready", (RErr, [], []), -1, [NotInFish; DeprecatedBy "launch"],
    [],
    "wait until the qemu subprocess launches (no op)",
    "\
@@ -155,7 +155,7 @@ and specifying the format.");
    "\
 This function adds a virtual CD-ROM disk image to the guest.
 
-This is equivalent to the qemu parameter C<-cdrom filename>.
+This is equivalent to the qemu parameter I<-cdrom filename>.
 
 Notes:
 
@@ -190,7 +190,7 @@ automatically.");
    "add qemu parameters",
    "\
 This can be used to add arbitrary qemu command line parameters
-of the form C<-param value>.  Actually it's not quite arbitrary - we
+of the form I<-param value>.  Actually it's not quite arbitrary - we
 prevent you from setting some parameters which would interfere with
 parameters that we use.
 
@@ -300,10 +300,14 @@ Get the autosync flag.");
    [],
    "set verbose mode",
    "\
-If C<verbose> is true, this turns on verbose messages (to C<stderr>).
+If C<verbose> is true, this turns on verbose messages.
 
 Verbose messages are disabled unless the environment variable
-C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
+C<LIBGUESTFS_DEBUG> is defined and set to C<1>.
+
+Verbose messages are normally sent to C<stderr>, unless you
+register a callback to send them somewhere else (see
+C<guestfs_set_event_callback>).");
 
   ("get_verbose", (RBool "verbose", [], []), -1, [],
    [],
@@ -469,19 +473,19 @@ see L<guestfs(3)>.");
        ["get_trace"]])],
    "enable or disable command traces",
    "\
-If the command trace flag is set to 1, then commands are
-printed on stderr before they are executed in a format
-which is very similar to the one used by guestfish.  In
-other words, you can run a program with this enabled, and
-you will get out a script which you can feed to guestfish
-to perform the same set of actions.
+If the command trace flag is set to 1, then libguestfs
+calls, parameters and return values are traced.
 
 If you want to trace C API calls into libguestfs (and
 other libraries) then possibly a better way is to use
 the external ltrace(1) command.
 
 Command traces are disabled unless the environment variable
-C<LIBGUESTFS_TRACE> is defined and set to C<1>.");
+C<LIBGUESTFS_TRACE> is defined and set to C<1>.
+
+Trace messages are normally sent to C<stderr>, unless you
+register a callback to send them somewhere else (see
+C<guestfs_set_event_callback>).");
 
   ("get_trace", (RBool "trace", [], []), -1, [],
    [],
@@ -722,9 +726,6 @@ See also C<guestfs_list_filesystems>.");
    [],
    "get type of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the type of the inspected operating system.
 Currently defined types are:
 
@@ -742,6 +743,14 @@ Any Microsoft Windows operating system.
 
 FreeBSD.
 
+=item \"netbsd\"
+
+NetBSD.
+
+=item \"hurd\"
+
+GNU/Hurd.
+
 =item \"unknown\"
 
 The operating system type could not be determined.
@@ -757,9 +766,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get architecture of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the architecture of the inspected operating system.
 The possible return values are listed under
 C<guestfs_file_architecture>.
@@ -773,9 +779,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get distro of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the distro (distribution) of the inspected operating
 system.
 
@@ -787,6 +790,10 @@ Currently defined distros are:
 
 Arch Linux.
 
+=item \"centos\"
+
+CentOS.
+
 =item \"debian\"
 
 Debian.
@@ -803,6 +810,10 @@ Gentoo.
 
 Linux Mint.
 
+=item \"mageia\"
+
+Mageia.
+
 =item \"mandriva\"
 
 Mandriva.
@@ -811,6 +822,10 @@ Mandriva.
 
 MeeGo.
 
+=item \"opensuse\"
+
+OpenSUSE.
+
 =item \"pardus\"
 
 Pardus.
@@ -821,7 +836,19 @@ Some Red Hat-derived distro.
 
 =item \"rhel\"
 
-Red Hat Enterprise Linux and some derivatives.
+Red Hat Enterprise Linux.
+
+=item \"scientificlinux\"
+
+Scientific Linux.
+
+=item \"slackware\"
+
+Slackware.
+
+=item \"ttylinux\"
+
+ttylinux.
 
 =item \"ubuntu\"
 
@@ -847,9 +874,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get major version of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the major version number of the inspected operating
 system.
 
@@ -868,9 +892,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get minor version of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the minor version number of the inspected operating
 system.
 
@@ -883,9 +904,6 @@ See also C<guestfs_inspect_get_major_version>.");
    [],
    "get product name of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the product name of the inspected operating
 system.  The product name is generally some freeform string
 which can be displayed to the user, but should not be
@@ -900,9 +918,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get mountpoints of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns a hash of where we think the filesystems
 associated with this operating system should be mounted.
 Callers should note that this is at best an educated guess
@@ -920,6 +935,12 @@ which is the filesystem that would be mounted there
 Non-mounted devices such as swap devices are I<not>
 returned in this list.
 
+For operating systems like Windows which still use drive
+letters, this call will only return an entry for the first
+drive \"mounted on\" C</>.  For information about the
+mapping of drive letters to partitions, see
+C<guestfs_inspect_get_drive_mappings>.
+
 Please read L<guestfs(3)/INSPECTION> for more details.
 See also C<guestfs_inspect_get_filesystems>.");
 
@@ -927,9 +948,6 @@ See also C<guestfs_inspect_get_filesystems>.");
    [],
    "get filesystems associated with inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns a list of all the filesystems that we think
 are associated with this operating system.  This includes
 the root filesystem, other ordinary filesystems, and
@@ -993,7 +1011,7 @@ be mountable but require special options.  Filesystems may
 not all belong to a single logical operating system
 (use C<guestfs_inspect_os> to look for OSes).");
 
-  ("add_drive_opts", (RErr, [String "filename"], [Bool "readonly"; String "format"; String "iface"]), -1, [FishAlias "add"],
+  ("add_drive_opts", (RErr, [String "filename"], [Bool "readonly"; String "format"; String "iface"; String "name"]), -1, [FishAlias "add"],
    [],
    "add an image to examine or modify",
    "\
@@ -1036,15 +1054,17 @@ this security hole.
 This rarely-used option lets you emulate the behaviour of the
 deprecated C<guestfs_add_drive_with_if> call (q.v.)
 
+=item C<name>
+
+The name the drive had in the original guest, e.g. /dev/sdb. This is used as a
+hint to the guest inspection process if it is available.
+
 =back");
 
   ("inspect_get_windows_systemroot", (RString "systemroot", [Device "root"], []), -1, [],
    [],
    "get Windows systemroot of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the Windows systemroot of the inspected guest.
 The systemroot is a directory path such as C</WINDOWS>.
 
@@ -1074,7 +1094,14 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
 This returns the internal QEMU command line.  'debug' commands are
 not part of the formal API and can be removed or changed at any time.");
 
-  ("add_domain", (RInt "nrdisks", [String "dom"], [String "libvirturi"; Bool "readonly"; String "iface"]), -1, [FishAlias "domain"],
+  ("debug_drives", (RStringList "cmdline", [], []), -1, [NotInDocs],
+   [],
+   "debug the drives (internal use only)",
+   "\
+This returns the internal list of drives.  'debug' commands are
+not part of the formal API and can be removed or changed at any time.");
+
+  ("add_domain", (RInt "nrdisks", [String "dom"], [String "libvirturi"; Bool "readonly"; String "iface"; Bool "live"; Bool "allowuuid"; String "readonlydisk"]), -1, [FishAlias "domain"],
    [],
    "add the disk(s) from a named libvirt domain",
    "\
@@ -1101,12 +1128,70 @@ we connect to the default libvirt URI (or one set through an
 environment variable, see the libvirt documentation for full
 details).
 
+The optional C<live> flag controls whether this call will try
+to connect to a running virtual machine C<guestfsd> process if
+it sees a suitable E<lt>channelE<gt> element in the libvirt
+XML definition.  The default (if the flag is omitted) is never
+to try.  See L<guestfs(3)/ATTACHING TO RUNNING DAEMONS> for more
+information.
+
+If the C<allowuuid> flag is true (default is false) then a UUID
+I<may> be passed instead of the domain name.  The C<dom> string is
+treated as a UUID first and looked up, and if that lookup fails
+then we treat C<dom> as a name as usual.
+
+The optional C<readonlydisk> parameter controls what we do for
+disks which are marked E<lt>readonly/E<gt> in the libvirt XML.
+Possible values are:
+
+=over 4
+
+=item readonlydisk = \"error\"
+
+If C<readonly> is false:
+
+The whole call is aborted with an error if any disk with
+the E<lt>readonly/E<gt> flag is found.
+
+If C<readonly> is true:
+
+Disks with the E<lt>readonly/E<gt> flag are added read-only.
+
+=item readonlydisk = \"read\"
+
+If C<readonly> is false:
+
+Disks with the E<lt>readonly/E<gt> flag are added read-only.
+Other disks are added read/write.
+
+If C<readonly> is true:
+
+Disks with the E<lt>readonly/E<gt> flag are added read-only.
+
+=item readonlydisk = \"write\" (default)
+
+If C<readonly> is false:
+
+Disks with the E<lt>readonly/E<gt> flag are added read/write.
+
+If C<readonly> is true:
+
+Disks with the E<lt>readonly/E<gt> flag are added read-only.
+
+=item readonlydisk = \"ignore\"
+
+If C<readonly> is true or false:
+
+Disks with the E<lt>readonly/E<gt> flag are skipped.
+
+=back
+
 The other optional parameters are passed directly through to
 C<guestfs_add_drive_opts>.");
 
 (*
 This interface is not quite baked yet. -- RWMJ 2010-11-11
-  ("add_libvirt_dom", (RInt "nrdisks", [Pointer ("virDomainPtr", "dom")], [Bool "readonly"; String "iface"]), -1, [NotInFish],
+  ("add_libvirt_dom", (RInt "nrdisks", [Pointer ("virDomainPtr", "dom")], [Bool "readonly"; String "iface"; Bool "live"; String "readonlydisk"]), -1, [NotInFish],
    [],
    "add the disk(s) from a libvirt domain",
    "\
@@ -1129,7 +1214,18 @@ from a remote libvirt connection (see L<http://libvirt.org/remote.html>)
 will fail unless those disks are accessible via the same device path
 locally too.
 
-The optional parameters are passed directly through to
+The optional C<live> flag controls whether this call will try
+to connect to a running virtual machine C<guestfsd> process if
+it sees a suitable E<lt>channelE<gt> element in the libvirt
+XML definition.  The default (if the flag is omitted) is never
+to try.  See L<guestfs(3)/ATTACHING TO RUNNING DAEMONS> for more
+information.
+
+The optional C<readonlydisk> parameter controls what we do for
+disks which are marked E<lt>readonly/E<gt> in the libvirt XML.
+See C<guestfs_add_domain> for possible values.
+
+The other optional parameters are passed directly through to
 C<guestfs_add_drive_opts>.");
 *)
 
@@ -1137,9 +1233,6 @@ C<guestfs_add_drive_opts>.");
    [],
    "get package format used by the operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This function and C<guestfs_inspect_get_package_management> return
 the package format and package management tool used by the
 inspected operating system.  For example for Fedora these
@@ -1150,7 +1243,8 @@ This returns the string C<unknown> if we could not determine the
 package format I<or> if the operating system does not have
 a real packaging system (eg. Windows).
 
-Possible strings include: C<rpm>, C<deb>, C<ebuild>, C<pisi>, C<pacman>.
+Possible strings include:
+C<rpm>, C<deb>, C<ebuild>, C<pisi>, C<pacman>, C<pkgsrc>.
 Future versions of libguestfs may return other strings.
 
 Please read L<guestfs(3)/INSPECTION> for more details.");
@@ -1159,9 +1253,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get package management tool used by the operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 C<guestfs_inspect_get_package_format> and this function return
 the package format and package management tool used by the
 inspected operating system.  For example for Fedora these
@@ -1174,7 +1265,7 @@ a real packaging system (eg. Windows).
 
 Possible strings include: C<yum>, C<up2date>,
 C<apt> (for all Debian derivatives),
-C<portage>, C<pisi>, C<pacman>, C<urpmi>.
+C<portage>, C<pisi>, C<pacman>, C<urpmi>, C<zypper>.
 Future versions of libguestfs may return other strings.
 
 Please read L<guestfs(3)/INSPECTION> for more details.");
@@ -1183,9 +1274,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get list of applications installed in the operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 Return the list of applications installed in the operating system.
 
 I<Note:> This call works differently from other parts of the
@@ -1282,9 +1370,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get hostname of the operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This function returns the hostname of the operating system
 as found by inspection of the guest's configuration files.
 
@@ -1297,9 +1382,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get format of inspected operating system",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 This returns the format of the inspected operating system.  You
 can use it to detect install images, live CDs and similar.
 
@@ -1331,9 +1413,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get live flag for install disk",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 If C<guestfs_inspect_get_format> returns C<installer> (this
 is an install disk), then this returns true if a live image
 was detected on the disk.
@@ -1344,9 +1423,6 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get netinst (network installer) flag for install disk",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 If C<guestfs_inspect_get_format> returns C<installer> (this
 is an install disk), then this returns true if the disk is
 a network installer, ie. not a self-contained install CD but
@@ -1359,15 +1435,215 @@ Please read L<guestfs(3)/INSPECTION> for more details.");
    [],
    "get multipart flag for install disk",
    "\
-This function should only be called with a root device string
-as returned by C<guestfs_inspect_os>.
-
 If C<guestfs_inspect_get_format> returns C<installer> (this
 is an install disk), then this returns true if the disk is
 part of a set.
 
 Please read L<guestfs(3)/INSPECTION> for more details.");
 
+  ("set_attach_method", (RErr, [String "attachmethod"], []), -1, [FishAlias "attach-method"],
+   [],
+   "set the attach method",
+   "\
+Set the method that libguestfs uses to connect to the back end
+guestfsd daemon.  Possible methods are:
+
+=over 4
+
+=item C<appliance>
+
+Launch an appliance and connect to it.  This is the ordinary method
+and the default.
+
+=item C<unix:I<path>>
+
+Connect to the Unix domain socket I<path>.
+
+This method lets you connect to an existing daemon or (using
+virtio-serial) to a live guest.  For more information, see
+L<guestfs(3)/ATTACHING TO RUNNING DAEMONS>.
+
+=back");
+
+  ("get_attach_method", (RString "attachmethod", [], []), -1, [],
+   [InitNone, Always, TestOutput (
+      [["get_attach_method"]], "appliance")],
+   "get the attach method",
+   "\
+Return the current attach method.  See C<guestfs_set_attach_method>.");
+
+  ("inspect_get_product_variant", (RString "variant", [Device "root"], []), -1, [],
+   [],
+   "get product variant of inspected operating system",
+   "\
+This returns the product variant of the inspected operating
+system.
+
+For Windows guests, this returns the contents of the Registry key
+C<HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion>
+C<InstallationType> which is usually a string such as
+C<Client> or C<Server> (other values are possible).  This
+can be used to distinguish consumer and enterprise versions
+of Windows that have the same version number (for example,
+Windows 7 and Windows 2008 Server are both version 6.1,
+but the former is C<Client> and the latter is C<Server>).
+
+For enterprise Linux guests, in future we intend this to return
+the product variant such as C<Desktop>, C<Server> and so on.  But
+this is not implemented at present.
+
+If the product variant could not be determined, then the
+string C<unknown> is returned.
+
+Please read L<guestfs(3)/INSPECTION> for more details.
+See also C<guestfs_inspect_get_product_name>,
+C<guestfs_inspect_get_major_version>.");
+
+  ("inspect_get_windows_current_control_set", (RString "controlset", [Device "root"], []), -1, [],
+   [],
+   "get Windows CurrentControlSet of inspected operating system",
+   "\
+This returns the Windows CurrentControlSet of the inspected guest.
+The CurrentControlSet is a registry key name such as C<ControlSet001>.
+
+This call assumes that the guest is Windows and that the
+Registry could be examined by inspection.  If this is not
+the case then an error is returned.
+
+Please read L<guestfs(3)/INSPECTION> for more details.");
+
+  ("inspect_get_drive_mappings", (RHashtable "drives", [Device "root"], []), -1, [],
+   [],
+   "get drive letter mappings",
+   "\
+This call is useful for Windows which uses a primitive system
+of assigning drive letters (like \"C:\") to partitions.
+This inspection API examines the Windows Registry to find out
+how disks/partitions are mapped to drive letters, and returns
+a hash table as in the example below:
+
+ C      =>     /dev/vda2
+ E      =>     /dev/vdb1
+ F      =>     /dev/vdc1
+
+Note that keys are drive letters.  For Windows, the key is
+case insensitive and just contains the drive letter, without
+the customary colon separator character.
+
+In future we may support other operating systems that also used drive
+letters, but the keys for those might not be case insensitive
+and might be longer than 1 character.  For example in OS-9,
+hard drives were named C<h0>, C<h1> etc.
+
+For Windows guests, currently only hard drive mappings are
+returned.  Removable disks (eg. DVD-ROMs) are ignored.
+
+For guests that do not use drive mappings, or if the drive mappings
+could not be determined, this returns an empty hash table.
+
+Please read L<guestfs(3)/INSPECTION> for more details.
+See also C<guestfs_inspect_get_mountpoints>,
+C<guestfs_inspect_get_filesystems>.");
+
+  ("inspect_get_icon", (RBufferOut "icon", [Device "root"],  [Bool "favicon"; Bool "highquality"]), -1, [],
+   [],
+   "get the icon corresponding to this operating system",
+   "\
+This function returns an icon corresponding to the inspected
+operating system.  The icon is returned as a buffer containing a
+PNG image (re-encoded to PNG if necessary).
+
+If it was not possible to get an icon this function returns a
+zero-length (non-NULL) buffer.  I<Callers must check for this case>.
+
+Libguestfs will start by looking for a file called
+C</etc/favicon.png> or C<C:\\etc\\favicon.png>
+and if it has the correct format, the contents of this file will
+be returned.  You can disable favicons by passing the
+optional C<favicon> boolean as false (default is true).
+
+If finding the favicon fails, then we look in other places in the
+guest for a suitable icon.
+
+If the optional C<highquality> boolean is true then
+only high quality icons are returned, which means only icons of
+high resolution with an alpha channel.  The default (false) is
+to return any icon we can, even if it is of substandard quality.
+
+Notes:
+
+=over 4
+
+=item *
+
+Unlike most other inspection API calls, the guest's disks must be
+mounted up before you call this, since it needs to read information
+from the guest filesystem during the call.
+
+=item *
+
+B<Security:> The icon data comes from the untrusted guest,
+and should be treated with caution.  PNG files have been
+known to contain exploits.  Ensure that libpng (or other relevant
+libraries) are fully up to date before trying to process or
+display the icon.
+
+=item *
+
+The PNG image returned can be any size.  It might not be square.
+Libguestfs tries to return the largest, highest quality
+icon available.  The application must scale the icon to the
+required size.
+
+=item *
+
+Extracting icons from Windows guests requires the external
+C<wrestool> program from the C<icoutils> package, and
+several programs (C<bmptopnm>, C<pnmtopng>, C<pamcut>)
+from the C<netpbm> package.  These must be installed separately.
+
+=item *
+
+Operating system icons are usually trademarks.  Seek legal
+advice before using trademarks in applications.
+
+=back");
+
+  ("set_pgroup", (RErr, [Bool "pgroup"], []), -1, [FishAlias "pgroup"],
+   [],
+   "set process group flag",
+   "\
+If C<pgroup> is true, child processes are placed into
+their own process group.
+
+The practical upshot of this is that signals like C<SIGINT> (from
+users pressing C<^C>) won't be received by the child process.
+
+The default for this flag is false, because usually you want
+C<^C> to kill the subprocess.");
+
+  ("get_pgroup", (RBool "pgroup", [], []), -1, [],
+   [],
+   "get process group flag",
+   "\
+This returns the process group flag.");
+
+  ("set_smp", (RErr, [Int "smp"], []), -1, [FishAlias "smp"],
+   [],
+   "set number of virtual CPUs in appliance",
+   "\
+Change the number of virtual CPUs assigned to the appliance.  The
+default is C<1>.  Increasing this may improve performance, though
+often it has no effect.
+
+This function must be called before C<guestfs_launch>.");
+
+  ("get_smp", (RInt "smp", [], []), -1, [],
+   [],
+   "get number of virtual CPUs in appliance",
+   "\
+This returns the number of virtual CPUs assigned to the appliance.");
+
 ]
 
 (* daemon_functions are any functions which cause some action
@@ -1398,15 +1674,12 @@ exist.
 The mounted filesystem is writable, if we have sufficient permissions
 on the underlying device.
 
-B<Important note:>
-When you use this call, the filesystem options C<sync> and C<noatime>
-are set implicitly.  This was originally done because we thought it
-would improve reliability, but it turns out that I<-o sync> has a
-very large negative performance impact and negligible effect on
-reliability.  Therefore we recommend that you avoid using
-C<guestfs_mount> in any code that needs performance, and instead
-use C<guestfs_mount_options> (use an empty string for the first
-parameter if you don't want any options).");
+Before libguestfs 1.13.16, this call implicitly added the options
+C<sync> and C<noatime>.  The C<sync> option greatly slowed
+writes and caused many problems for users.  If your program
+might need to work with older versions of libguestfs, use
+C<guestfs_mount_options> instead (using an empty string for the
+first parameter if you don't want any options).");
 
   ("sync", (RErr, [], []), 2, [],
    [ InitEmpty, Always, TestRun [["sync"]]],
@@ -1644,7 +1917,12 @@ do not overwrite original.  Overrides C<AUG_SAVE_BACKUP>.
 
 =item C<AUG_TYPE_CHECK> = 4
 
-Typecheck lenses (can be expensive).
+Typecheck lenses.
+
+This option is only useful when debugging Augeas lenses.  Use
+of this option may require additional memory for the libguestfs
+appliance.  You may need to set the C<LIBGUESTFS_MEMSIZE>
+environment variable or call C<guestfs_set_memsize>.
 
 =item C<AUG_NO_STDINC> = 8
 
@@ -1983,7 +2261,7 @@ example C<ext3>.");
 
   ("sfdisk", (RErr, [Device "device";
                      Int "cyls"; Int "heads"; Int "sectors";
-                     StringList "lines"], []), 43, [DangerWillRobinson],
+                     StringList "lines"], []), 43, [DeprecatedBy "part_add"],
    [],
    "create partitions on a block device",
    "\
@@ -2084,7 +2362,7 @@ This unmounts all mounted filesystems.
 
 Some internal mounts are not unmounted by this call.");
 
-  ("lvm_remove_all", (RErr, [], []), 48, [DangerWillRobinson; Optional "lvm2"],
+  ("lvm_remove_all", (RErr, [], []), 48, [Optional "lvm2"],
    [],
    "remove all LVM LVs, VGs and PVs",
    "\
@@ -2112,17 +2390,14 @@ of compressed file.
 
 The exact command which runs is C<file -zb path>.  Note in
 particular that the filename is not prepended to the output
-(the C<-b> option).
+(the I<-b> option).
 
-This command can also be used on C</dev/> devices
-(and partitions, LV names).  You can for example use this
-to determine if a device contains a filesystem, although
-it's usually better to use C<guestfs_vfs_type>.
+The output depends on the output of the underlying L<file(1)>
+command and it can change in future in ways beyond our control.
+In other words, the output is not guaranteed by the ABI.
 
-If the C<path> does not begin with C</dev/> then
-this command only works for the content of regular files.
-For other file types (directory, symbolic link etc) it
-will just return the string C<directory> etc.");
+See also: L<file(1)>, C<guestfs_vfs_type>, C<guestfs_lstat>,
+C<guestfs_is_file>, C<guestfs_is_blockdev> (etc), C<guestfs_is_zero>.");
 
   ("command", (RString "output", [StringList "arguments"], []), 50, [ProtocolLimitWarning],
    [InitScratchFS, Always, TestOutput (
@@ -2314,7 +2589,10 @@ C<path> should be a file or directory in the mounted file system
 This is the same as the C<statvfs(2)> system call.");
 
   ("tune2fs_l", (RHashtable "superblock", [Device "device"], []), 55, [],
-   [], (* XXX test *)
+   [InitScratchFS, Always, TestOutputHashtable (
+      [["tune2fs_l"; "/dev/sdb1"]],
+      ["Filesystem magic number", "0xEF53";
+       "Filesystem OS type", "Linux"])],
    "get ext2/ext3/ext4 superblock details",
    "\
 This returns the contents of the ext2, ext3 or ext4 filesystem
@@ -2440,7 +2718,7 @@ This uses the L<blockdev(8)> command.");
    [InitScratchFS, Always, TestOutput (
       (* Pick a file from cwd which isn't likely to change. *)
       [["mkdir"; "/upload"];
-       ["upload"; "../COPYING.LIB"; "/upload/COPYING.LIB"];
+       ["upload"; "../../COPYING.LIB"; "/upload/COPYING.LIB"];
        ["checksum"; "md5"; "/upload/COPYING.LIB"]],
       Digest.to_hex (Digest.file "COPYING.LIB"))],
    "upload a file from the local machine",
@@ -2456,7 +2734,7 @@ See also C<guestfs_download>.");
    [InitScratchFS, Always, TestOutput (
       (* Pick a file from cwd which isn't likely to change. *)
       [["mkdir"; "/download"];
-       ["upload"; "../COPYING.LIB"; "/download/COPYING.LIB"];
+       ["upload"; "../../COPYING.LIB"; "/download/COPYING.LIB"];
        ["download"; "/download/COPYING.LIB"; "testdownload.tmp"];
        ["upload"; "testdownload.tmp"; "/download/upload"];
        ["checksum"; "md5"; "/download/upload"]],
@@ -2816,10 +3094,9 @@ Checking or repairing NTFS volumes is not supported
 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
 
   ("zero", (RErr, [Device "device"], []), 85, [Progress],
-   [InitBasicFS, Always, TestOutput (
+   [InitBasicFS, Always, TestRun (
       [["umount"; "/dev/sda1"];
-       ["zero"; "/dev/sda1"];
-       ["file"; "/dev/sda1"]], "data")],
+       ["zero"; "/dev/sda1"]])],
    "write zeroes to the device",
    "\
 This command writes zeroes over the first few blocks of C<device>.
@@ -2828,9 +3105,14 @@ How many blocks are zeroed isn't specified (but it's I<not> enough
 to securely wipe the device).  It should be sufficient to remove
 any partition tables, filesystem superblocks and so on.
 
-See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
+If blocks are already zero, then this command avoids writing
+zeroes.  This prevents the underlying device from becoming non-sparse
+or growing unnecessarily.
 
-  ("grub_install", (RErr, [Pathname "root"; Device "device"], []), 86, [],
+See also: C<guestfs_zero_device>, C<guestfs_scrub_device>,
+C<guestfs_is_zero_device>");
+
+  ("grub_install", (RErr, [Pathname "root"; Device "device"], []), 86, [Optional "grub"],
    (* See:
     * https://bugzilla.redhat.com/show_bug.cgi?id=484986
     * https://bugzilla.redhat.com/show_bug.cgi?id=479760
@@ -2840,12 +3122,32 @@ See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
        ["write"; "/boot/grub/device.map"; "(hd0) /dev/vda"];
        ["grub_install"; "/"; "/dev/vda"];
        ["is_dir"; "/boot"]])],
-   "install GRUB",
+   "install GRUB 1",
    "\
-This command installs GRUB (the Grand Unified Bootloader) on
+This command installs GRUB (the Grand Unified Bootloader) on
 C<device>, with the root directory being C<root>.
 
-Note: If grub-install reports the error
+Notes:
+
+=over 4
+
+=item *
+
+There is currently no way in the API to install grub2, which
+is used by most modern Linux guests.  It is possible to run
+the grub2 command from the guest, although see the
+caveats in L<guestfs(3)/RUNNING COMMANDS>.
+
+=item *
+
+This uses C<grub-install> from the host.  Unfortunately grub is
+not always compatible with itself, so this only works in rather
+narrow circumstances.  Careful testing with each guest version
+is advisable.
+
+=item *
+
+If grub-install reports the error
 \"No suitable drive was found in the generated device map.\"
 it may be that you need to create a C</boot/grub/device.map>
 file first that contains the mapping between grub device names
@@ -2854,7 +3156,9 @@ a file containing:
 
  (hd0) /dev/vda
 
-replacing C</dev/vda> with the name of the installation device.");
+replacing C</dev/vda> with the name of the installation device.
+
+=back");
 
   ("cp", (RErr, [Pathname "src"; Pathname "dest"], []), 87, [],
    [InitScratchFS, Always, TestOutput (
@@ -3074,7 +3378,7 @@ volume to match the new size of the underlying device.");
 
   ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
                        Int "cyls"; Int "heads"; Int "sectors";
-                       String "line"], []), 99, [DangerWillRobinson],
+                       String "line"], []), 99, [DeprecatedBy "part_add"],
    [],
    "modify a single partition on a block device",
    "\
@@ -3086,7 +3390,7 @@ pass C<0> for the cyls/heads/sectors parameters.
 
 See also: C<guestfs_part_add>");
 
-  ("sfdisk_l", (RString "partitions", [Device "device"], []), 100, [],
+  ("sfdisk_l", (RString "partitions", [Device "device"], []), 100, [DeprecatedBy "part_list"],
    [],
    "display the partition table",
    "\
@@ -3123,9 +3427,6 @@ be parsed.");
    "\
 This command activates or (if C<activate> is false) deactivates
 all logical volumes in all volume groups.
-If activated, then they are made known to the
-kernel, ie. they appear as C</dev/mapper> devices.  If deactivated,
-then those devices disappear.
 
 This command is the same as running C<vgchange -a y|n>");
 
@@ -3135,9 +3436,6 @@ This command is the same as running C<vgchange -a y|n>");
    "\
 This command activates or (if C<activate> is false) deactivates
 all logical volumes in the listed volume groups C<volgroups>.
-If activated, then they are made known to the
-kernel, ie. they appear as C</dev/mapper> devices.  If deactivated,
-then those devices disappear.
 
 This command is the same as running C<vgchange -a y|n volgroups...>
 
@@ -3231,8 +3529,8 @@ See also C<guestfs_find0>.");
    "check an ext2/ext3 filesystem",
    "\
 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
-filesystem checker on C<device>, noninteractively (C<-p>),
-even if the filesystem appears to be clean (C<-f>).
+filesystem checker on C<device>, noninteractively (I<-p>),
+even if the filesystem appears to be clean (I<-f>).
 
 This command is only needed because of C<guestfs_resize2fs>
 (q.v.).  Normally you should use C<guestfs_fsck>.");
@@ -3326,7 +3624,7 @@ It is just a wrapper around the C L<glob(3)> function
 with flags C<GLOB_MARK|GLOB_BRACE>.
 See that manual page for more details.");
 
-  ("scrub_device", (RErr, [Device "device"], []), 114, [DangerWillRobinson; Optional "scrub"],
+  ("scrub_device", (RErr, [Device "device"], []), 114, [Optional "scrub"],
    [InitNone, Always, TestRun (        (* use /dev/sdc because it's smaller *)
       [["scrub_device"; "/dev/sdc"]])],
    "scrub (securely wipe) a device",
@@ -3494,7 +3792,7 @@ This command is mostly useful for interactive sessions.  It
 is I<not> intended that you try to parse the output string.
 Use C<guestfs_statvfs> from programs.");
 
-  ("du", (RInt64 "sizekb", [Pathname "path"], []), 127, [],
+  ("du", (RInt64 "sizekb", [Pathname "path"], []), 127, [Progress],
    [InitISOFS, Always, TestOutputInt (
       [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
    "estimate file space usage",
@@ -3705,7 +4003,7 @@ This function is primarily intended for use by programs.  To
 get a simple list of names, use C<guestfs_ls>.  To get a printable
 directory for human consumption, use C<guestfs_ll>.");
 
-  ("sfdiskM", (RErr, [Device "device"; StringList "lines"], []), 139, [DangerWillRobinson],
+  ("sfdiskM", (RErr, [Device "device"; StringList "lines"], []), 139, [DeprecatedBy "part_add"],
    [],
    "create partitions on a block device",
    "\
@@ -4008,7 +4306,7 @@ This command creates a hard link using the C<ln> command.");
    "create a hard link",
    "\
 This command creates a hard link using the C<ln -f> command.
-The C<-f> option removes the link (C<linkname>) if it exists already.");
+The I<-f> option removes the link (C<linkname>) if it exists already.");
 
   ("ln_s", (RErr, [String "target"; Pathname "linkname"], []), 166, [],
    [InitScratchFS, Always, TestOutputStruct (
@@ -4029,7 +4327,7 @@ This command creates a symbolic link using the C<ln -s> command.");
    "create a symbolic link",
    "\
 This command creates a symbolic link using the C<ln -sf> command,
-The C<-f> option removes the link (C<linkname>) if it exists already.");
+The I<-f> option removes the link (C<linkname>) if it exists already.");
 
   ("readlink", (RString "link", [Pathname "path"], []), 168, [],
    [] (* XXX tested above *),
@@ -4521,10 +4819,31 @@ for the file until you write to it).  To create a non-sparse
 file of zeroes, use C<guestfs_fallocate64> instead.");
 
   ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"], []), 201, [],
+   (* Test directories, named pipes etc (RHBZ#761451, RHBZ#761460) *)
    [InitScratchFS, Always, TestOutputStruct (
-      [["touch"; "/utimens"];
-       ["utimens"; "/utimens"; "12345"; "67890"; "9876"; "5432"];
-       ["stat"; "/utimens"]], [CompareWithInt ("mtime", 9876)])],
+      [["touch"; "/utimens-file"];
+       ["utimens"; "/utimens-file"; "12345"; "67890"; "9876"; "5432"];
+       ["stat"; "/utimens-file"]], [CompareWithInt ("mtime", 9876)]);
+    InitScratchFS, Always, TestOutputStruct (
+      [["mkdir"; "/utimens-dir"];
+       ["utimens"; "/utimens-dir"; "12345"; "67890"; "9876"; "5432"];
+       ["stat"; "/utimens-dir"]], [CompareWithInt ("mtime", 9876)]);
+    InitScratchFS, Always, TestOutputStruct (
+      [["mkfifo"; "0o644"; "/utimens-fifo"];
+       ["utimens"; "/utimens-fifo"; "12345"; "67890"; "9876"; "5432"];
+       ["stat"; "/utimens-fifo"]], [CompareWithInt ("mtime", 9876)]);
+    InitScratchFS, Always, TestOutputStruct (
+      [["ln_sf"; "/utimens-file"; "/utimens-link"];
+       ["utimens"; "/utimens-link"; "12345"; "67890"; "9876"; "5432"];
+       ["stat"; "/utimens-link"]], [CompareWithInt ("mtime", 9876)]);
+    InitScratchFS, Always, TestOutputStruct (
+      [["mknod_b"; "0o644"; "8"; "0"; "/utimens-block"];
+       ["utimens"; "/utimens-block"; "12345"; "67890"; "9876"; "5432"];
+       ["stat"; "/utimens-block"]], [CompareWithInt ("mtime", 9876)]);
+    InitScratchFS, Always, TestOutputStruct (
+      [["mknod_c"; "0o644"; "1"; "3"; "/utimens-char"];
+       ["utimens"; "/utimens-char"; "12345"; "67890"; "9876"; "5432"];
+       ["stat"; "/utimens-char"]], [CompareWithInt ("mtime", 9876)])],
    "set timestamp of a file with nanosecond precision",
    "\
 This command sets the timestamps of a file with nanosecond
@@ -4675,7 +4994,9 @@ Possible values for C<parttype> are:
 
 =over 4
 
-=item B<efi> | B<gpt>
+=item B<efi>
+
+=item B<gpt>
 
 Intel EFI / GPT partition table.
 
@@ -4683,7 +5004,9 @@ This is recommended for >= 2 TB partitions that will be accessed
 from Linux and Intel-based Mac OS X.  It also has limited backwards
 compatibility with the C<mbr> format.
 
-=item B<mbr> | B<msdos>
+=item B<mbr>
+
+=item B<msdos>
 
 The standard PC \"Master Boot Record\" (MBR) format used
 by MS-DOS and Windows.  This partition type will B<only> work
@@ -4701,7 +5024,9 @@ supported include:
 
 AIX disk labels.
 
-=item B<amiga> | B<rdb>
+=item B<amiga>
+
+=item B<rdb>
 
 Amiga \"Rigid Disk Block\" format.
 
@@ -4762,7 +5087,7 @@ backwards from the end of the disk (C<-1> is the last sector).
 Creating a partition which covers the whole disk is not so easy.
 Use C<guestfs_part_disk> to do that.");
 
-  ("part_disk", (RErr, [Device "device"; String "parttype"], []), 210, [DangerWillRobinson],
+  ("part_disk", (RErr, [Device "device"; String "parttype"], []), 210, [],
    [InitEmpty, Always, TestRun (
       [["part_disk"; "/dev/sda"; "mbr"]]);
     InitEmpty, Always, TestRun (
@@ -4921,7 +5246,7 @@ See also C<guestfs_version>.
 
 =back");
 
-  ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"], []), 217, [],
+  ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"], []), 217, [DeprecatedBy "copy_device_to_device"],
    [InitScratchFS, Always, TestOutputBuffer (
       [["mkdir"; "/dd"];
        ["write"; "/dd/src"; "hello, world"];
@@ -4936,7 +5261,8 @@ example to duplicate a filesystem.
 
 If the destination is a device, it must be as large or larger
 than the source file or device, otherwise the copy will fail.
-This command cannot do partial copies (see C<guestfs_copy_size>).");
+This command cannot do partial copies
+(see C<guestfs_copy_device_to_device>).");
 
   ("filesize", (RInt64 "size", [Pathname "file"], []), 218, [],
    [InitScratchFS, Always, TestOutputInt (
@@ -5029,7 +5355,7 @@ calls to associate logical volumes and volume groups.
 
 See also C<guestfs_vgpvuuids>.");
 
-  ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"], []), 227, [Progress],
+  ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"], []), 227, [Progress; DeprecatedBy "copy_device_to_device"],
    [InitScratchFS, Always, TestOutputBuffer (
       [["mkdir"; "/copy_size"];
        ["write"; "/copy_size/src"; "hello, world"];
@@ -5043,14 +5369,18 @@ or file C<src> to another destination device or file C<dest>.
 Note this will fail if the source is too short or if the destination
 is not large enough.");
 
-  ("zero_device", (RErr, [Device "device"], []), 228, [DangerWillRobinson; Progress],
+  ("zero_device", (RErr, [Device "device"], []), 228, [Progress],
    [InitBasicFSonLVM, Always, TestRun (
       [["zero_device"; "/dev/VG/LV"]])],
    "write zeroes to an entire device",
    "\
 This command writes zeroes over the entire C<device>.  Compare
 with C<guestfs_zero> which just zeroes the first few blocks of
-a device.");
+a device.
+
+If blocks are already zero, then this command avoids writing
+zeroes.  This prevents the underlying device from becoming non-sparse
+or growing unnecessarily.");
 
   ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"], []), 229, [Optional "xz"],
    [InitScratchFS, Always, TestOutput (
@@ -5069,12 +5399,21 @@ I<xz compressed> tar file) into C<directory>.");
 This command packs the contents of C<directory> and downloads
 it to local file C<tarball> (as an xz compressed tar archive).");
 
-  ("ntfsresize", (RErr, [Device "device"], []), 231, [Optional "ntfsprogs"],
+  ("ntfsresize", (RErr, [Device "device"], []), 231, [Optional "ntfsprogs"; DeprecatedBy "ntfsresize_opts"],
    [],
    "resize an NTFS filesystem",
    "\
 This command resizes an NTFS filesystem, expanding or
 shrinking it to the size of the underlying device.
+
+I<Note:> After the resize operation, the filesystem is marked
+as requiring a consistency check (for safety).  You have to boot
+into Windows to perform this check and clear this condition.
+Furthermore, ntfsresize refuses to resize filesystems
+which have been marked in this way.  So in effect it is
+not possible to call ntfsresize multiple times on a single
+filesystem without booting into Windows between each resize.
+
 See also L<ntfsresize(8)>.");
 
   ("vgscan", (RErr, [], []), 232, [],
@@ -5256,7 +5595,9 @@ to ensure the length of the file is exactly C<len> bytes.");
    "create a new file",
    "\
 This call creates a file called C<path>.  The content of the
-file is the string C<content> (which can contain any 8 bit data).");
+file is the string C<content> (which can contain any 8 bit data).
+
+See also C<guestfs_write_append>.");
 
   ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"], []), 247, [ProtocolLimitWarning],
    [InitScratchFS, Always, TestOutput (
@@ -5298,7 +5639,7 @@ allows you to specify the new size (in bytes) explicitly.");
 This command is the same as C<guestfs_pvresize> except that it
 allows you to specify the new size (in bytes) explicitly.");
 
-  ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"], []), 250, [Optional "ntfsprogs"],
+  ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"], []), 250, [Optional "ntfsprogs"; DeprecatedBy "ntfsresize_opts"],
    [],
    "resize an NTFS filesystem (with size)",
    "\
@@ -5425,7 +5766,10 @@ encrypted to the underlying C<device> respectively.
 
 If this block device contains LVM volume groups, then
 calling C<guestfs_vgscan> followed by C<guestfs_vg_activate_all>
-will make them visible.");
+will make them visible.
+
+Use C<guestfs_list_dm_devices> to list all device mapper
+devices.");
 
   ("luks_open_ro", (RErr, [Device "device"; Key "key"; String "mapname"], []), 258, [Optional "luks"],
    [],
@@ -5444,7 +5788,7 @@ C<device> parameter must be the name of the LUKS mapping
 device (ie. C</dev/mapper/mapname>) and I<not> the name
 of the underlying block device.");
 
-  ("luks_format", (RErr, [Device "device"; Key "key"; Int "keyslot"], []), 260, [Optional "luks"; DangerWillRobinson],
+  ("luks_format", (RErr, [Device "device"; Key "key"; Int "keyslot"], []), 260, [Optional "luks"],
    [],
    "format a block device as a LUKS encrypted device",
    "\
@@ -5453,7 +5797,7 @@ the device as a LUKS encrypted device.  C<key> is the
 initial key, which is added to key slot C<slot>.  (LUKS
 supports 8 key slots, numbered 0-7).");
 
-  ("luks_format_cipher", (RErr, [Device "device"; Key "key"; Int "keyslot"; String "cipher"], []), 261, [Optional "luks"; DangerWillRobinson],
+  ("luks_format_cipher", (RErr, [Device "device"; Key "key"; Int "keyslot"; String "cipher"], []), 261, [Optional "luks"],
    [],
    "format a block device as a LUKS encrypted device",
    "\
@@ -5585,12 +5929,14 @@ removes the partition number, returning the device name
 (eg. \"/dev/sdb\").
 
 The named partition must exist, for example as a string returned
-from C<guestfs_list_partitions>.");
+from C<guestfs_list_partitions>.
+
+See also C<guestfs_part_to_partnum>.");
 
   ("upload_offset", (RErr, [FileIn "filename"; Dev_or_Path "remotefilename"; Int64 "offset"], []), 273, [Progress],
    (let md5 = Digest.to_hex (Digest.file "COPYING.LIB") in
     [InitScratchFS, Always, TestOutput (
-       [["upload_offset"; "../COPYING.LIB"; "/upload_offset"; "0"];
+       [["upload_offset"; "../../COPYING.LIB"; "/upload_offset"; "0"];
         ["checksum"; "md5"; "/upload_offset"]], md5)]),
    "upload a file from the local machine with offset",
    "\
@@ -5618,7 +5964,7 @@ See also C<guestfs_upload>, C<guestfs_pwrite>.");
     [InitScratchFS, Always, TestOutput (
        (* Pick a file from cwd which isn't likely to change. *)
        [["mkdir"; "/download_offset"];
-        ["upload"; "../COPYING.LIB"; "/download_offset/COPYING.LIB"];
+        ["upload"; "../../COPYING.LIB"; "/download_offset/COPYING.LIB"];
         ["download_offset"; "/download_offset/COPYING.LIB"; "testdownload.tmp"; offset; size];
         ["upload_offset"; "testdownload.tmp"; "/download_offset/COPYING.LIB"; offset];
         ["checksum"; "md5"; "/download_offset/COPYING.LIB"]], md5)]),
@@ -5683,10 +6029,10 @@ not refer to a logical volume.
 
 See also C<guestfs_is_lv>.");
 
-  ("mkfs_opts", (RErr, [String "fstype"; Device "device"], [Int "blocksize"; String "features"]), 278, [],
+  ("mkfs_opts", (RErr, [String "fstype"; Device "device"], [Int "blocksize"; String "features"; Int "inode"; Int "sectorsize"]), 278, [],
    [InitEmpty, Always, TestOutput (
       [["part_disk"; "/dev/sda"; "mbr"];
-       ["mkfs_opts"; "ext2"; "/dev/sda1"; "4096"; ""];
+       ["mkfs_opts"; "ext2"; "/dev/sda1"; ""; "NOARG"; ""; ""];
        ["mount_options"; ""; "/dev/sda1"; "/"];
        ["write"; "/new"; "new file contents"];
        ["cat"; "/new"]], "new file contents")],
@@ -5712,7 +6058,7 @@ For UFS block sizes, please see L<mkfs.ufs(8)>.
 
 =item C<features>
 
-This passes the C<-O> parameter to the external mkfs program.
+This passes the I<-O> parameter to the external mkfs program.
 
 For certain filesystem types, this allows extra filesystem
 features to be selected.  See L<mke2fs(8)> and L<mkfs.ufs(8)>
@@ -5721,6 +6067,16 @@ for more details.
 You cannot use this optional parameter with the C<gfs> or
 C<gfs2> filesystem type.
 
+=item C<inode>
+
+This passes the I<-I> parameter to the external L<mke2fs(8)> program
+which sets the inode size (only for ext2/3/4 filesystems at present).
+
+=item C<sectorsize>
+
+This passes the I<-S> parameter to external L<mkfs.ufs(8)> program,
+which sets sector size for ufs filesystem.
+
 =back");
 
   ("getxattr", (RBufferOut "xattr", [Pathname "path"; String "name"], []), 279, [Optional "linuxxattrs"],
@@ -5768,7 +6124,7 @@ See also: C<guestfs_lgetxattrs>, C<guestfs_getxattr>, L<attr(5)>.");
    "resize an ext2, ext3 or ext4 filesystem to the minimum size",
    "\
 This command is the same as C<guestfs_resize2fs>, but the filesystem
-is resized to its minimum size.  This works like the C<-M> option
+is resized to its minimum size.  This works like the I<-M> option
 to the C<resize2fs> command.
 
 To get the resulting size of the filesystem you should call
@@ -5786,6 +6142,461 @@ Instead, use the autosync flag (C<guestfs_set_autosync>) to
 control whether or not this operation is performed when the
 handle is closed.");
 
+  ("is_zero", (RBool "zeroflag", [Pathname "path"], []), 283, [],
+   [InitISOFS, Always, TestOutputTrue (
+      [["is_zero"; "/100kallzeroes"]]);
+    InitISOFS, Always, TestOutputFalse (
+      [["is_zero"; "/100kallspaces"]])],
+   "test if a file contains all zero bytes",
+   "\
+This returns true iff the file exists and the file is empty or
+it contains all zero bytes.");
+
+  ("is_zero_device", (RBool "zeroflag", [Device "device"], []), 284, [],
+   [InitBasicFS, Always, TestOutputTrue (
+      [["umount"; "/dev/sda1"];
+       ["zero_device"; "/dev/sda1"];
+       ["is_zero_device"; "/dev/sda1"]]);
+    InitBasicFS, Always, TestOutputFalse (
+      [["is_zero_device"; "/dev/sda1"]])],
+   "test if a device contains all zero bytes",
+   "\
+This returns true iff the device exists and contains all zero bytes.
+
+Note that for large devices this can take a long time to run.");
+
+  ("list_9p", (RStringList "mounttags", [], []), 285, [],
+   [],
+   "list 9p filesystems",
+   "\
+List all 9p filesystems attached to the guest.  A list of
+mount tags is returned.");
+
+  ("mount_9p", (RErr, [String "mounttag"; String "mountpoint"], [String "options"]), 286, [],
+   [],
+   "mount 9p filesystem",
+   "\
+Mount the virtio-9p filesystem with the tag C<mounttag> on the
+directory C<mountpoint>.
+
+If required, C<trans=virtio> will be automatically added to the options.
+Any other options required can be passed in the optional C<options>
+parameter.");
+
+  ("list_dm_devices", (RStringList "devices", [], []), 287, [],
+   [],
+   "list device mapper devices",
+   "\
+List all device mapper devices.
+
+The returned list contains C</dev/mapper/*> devices, eg. ones created
+by a previous call to C<guestfs_luks_open>.
+
+Device mapper devices which correspond to logical volumes are I<not>
+returned in this list.  Call C<guestfs_lvs> if you want to list logical
+volumes.");
+
+  ("ntfsresize_opts", (RErr, [Device "device"], [Int64 "size"; Bool "force"]), 288, [Optional "ntfsprogs"],
+   [],
+   "resize an NTFS filesystem",
+   "\
+This command resizes an NTFS filesystem, expanding or
+shrinking it to the size of the underlying device.
+
+The optional parameters are:
+
+=over 4
+
+=item C<size>
+
+The new size (in bytes) of the filesystem.  If omitted, the filesystem
+is resized to fit the container (eg. partition).
+
+=item C<force>
+
+If this option is true, then force the resize of the filesystem
+even if the filesystem is marked as requiring a consistency check.
+
+After the resize operation, the filesystem is always marked
+as requiring a consistency check (for safety).  You have to boot
+into Windows to perform this check and clear this condition.
+If you I<don't> set the C<force> option then it is not
+possible to call C<guestfs_ntfsresize_opts> multiple times on a
+single filesystem without booting into Windows between each resize.
+
+=back
+
+See also L<ntfsresize(8)>.");
+
+  ("btrfs_filesystem_resize", (RErr, [Pathname "mountpoint"], [Int64 "size"]), 289, [Optional "btrfs"],
+   [],
+   "resize a btrfs filesystem",
+   "\
+This command resizes a btrfs filesystem.
+
+Note that unlike other resize calls, the filesystem has to be
+mounted and the parameter is the mountpoint not the device
+(this is a requirement of btrfs itself).
+
+The optional parameters are:
+
+=over 4
+
+=item C<size>
+
+The new size (in bytes) of the filesystem.  If omitted, the filesystem
+is resized to the maximum size.
+
+=back
+
+See also L<btrfs(8)>.");
+
+  ("write_append", (RErr, [Pathname "path"; BufferIn "content"], []), 290, [ProtocolLimitWarning],
+   [InitScratchFS, Always, TestOutput (
+      [["write"; "/write_append"; "line1\n"];
+       ["write_append"; "/write_append"; "line2\n"];
+       ["write_append"; "/write_append"; "line3a"];
+       ["write_append"; "/write_append"; "line3b\n"];
+       ["cat"; "/write_append"]], "line1\nline2\nline3aline3b\n")],
+   "append content to end of file",
+   "\
+This call appends C<content> to the end of file C<path>.  If
+C<path> does not exist, then a new file is created.
+
+See also C<guestfs_write>.");
+
+  ("compress_out", (RErr, [String "ctype"; Pathname "file"; FileOut "zfile"], [Int "level"]), 291, [],
+   [],
+   "output compressed file",
+   "\
+This command compresses C<file> and writes it out to the local
+file C<zfile>.
+
+The compression program used is controlled by the C<ctype> parameter.
+Currently this includes: C<compress>, C<gzip>, C<bzip2>, C<xz> or C<lzop>.
+Some compression types may not be supported by particular builds of
+libguestfs, in which case you will get an error containing the
+substring \"not supported\".
+
+The optional C<level> parameter controls compression level.  The
+meaning and default for this parameter depends on the compression
+program being used.");
+
+  ("compress_device_out", (RErr, [String "ctype"; Device "device"; FileOut "zdevice"], [Int "level"]), 292, [],
+   [],
+   "output compressed device",
+   "\
+This command compresses C<device> and writes it out to the local
+file C<zdevice>.
+
+The C<ctype> and optional C<level> parameters have the same meaning
+as in C<guestfs_compress_out>.");
+
+  ("part_to_partnum", (RInt "partnum", [Device "partition"], []), 293, [],
+   [InitPartition, Always, TestOutputInt (
+      [["part_to_partnum"; "/dev/sda1"]], 1);
+    InitEmpty, Always, TestLastFail (
+      [["part_to_partnum"; "/dev/sda"]])],
+   "convert partition name to partition number",
+   "\
+This function takes a partition name (eg. \"/dev/sdb1\") and
+returns the partition number (eg. C<1>).
+
+The named partition must exist, for example as a string returned
+from C<guestfs_list_partitions>.
+
+See also C<guestfs_part_to_dev>.");
+
+  ("copy_device_to_device", (RErr, [Device "src"; Device "dest"], [Int64 "srcoffset"; Int64 "destoffset"; Int64 "size"]), 294, [Progress],
+   [],
+   "copy from source device to destination device",
+   "\
+The four calls C<guestfs_copy_device_to_device>,
+C<guestfs_copy_device_to_file>,
+C<guestfs_copy_file_to_device>, and
+C<guestfs_copy_file_to_file>
+let you copy from a source (device|file) to a destination
+(device|file).
+
+Partial copies can be made since you can specify optionally
+the source offset, destination offset and size to copy.  These
+values are all specified in bytes.  If not given, the offsets
+both default to zero, and the size defaults to copying as much
+as possible until we hit the end of the source.
+
+The source and destination may be the same object.  However
+overlapping regions may not be copied correctly.
+
+If the destination is a file, it is created if required.  If
+the destination file is not large enough, it is extended.");
+
+  ("copy_device_to_file", (RErr, [Device "src"; Pathname "dest"], [Int64 "srcoffset"; Int64 "destoffset"; Int64 "size"]), 295, [Progress],
+   [],
+   "copy from source device to destination file",
+   "\
+See C<guestfs_copy_device_to_device> for a general overview
+of this call.");
+
+  ("copy_file_to_device", (RErr, [Pathname "src"; Device "dest"], [Int64 "srcoffset"; Int64 "destoffset"; Int64 "size"]), 296, [Progress],
+   [],
+   "copy from source file to destination device",
+   "\
+See C<guestfs_copy_device_to_device> for a general overview
+of this call.");
+
+  ("copy_file_to_file", (RErr, [Pathname "src"; Pathname "dest"], [Int64 "srcoffset"; Int64 "destoffset"; Int64 "size"]), 297, [Progress],
+   [InitScratchFS, Always, TestOutputBuffer (
+      [["mkdir"; "/copyff"];
+       ["write"; "/copyff/src"; "hello, world"];
+       ["copy_file_to_file"; "/copyff/src"; "/copyff/dest"; ""; ""; ""];
+       ["read_file"; "/copyff/dest"]], "hello, world")],
+   "copy from source file to destination file",
+   "\
+See C<guestfs_copy_device_to_device> for a general overview
+of this call.
+
+This is B<not> the function you want for copying files.  This
+is for copying blocks within existing files.  See C<guestfs_cp>,
+C<guestfs_cp_a> and C<guestfs_mv> for general file copying and
+moving functions.");
+
+  ("tune2fs", (RErr, [Device "device"], [Bool "force"; Int "maxmountcount"; Int "mountcount"; String "errorbehavior"; Int64 "group"; Int "intervalbetweenchecks"; Int "reservedblockspercentage"; String "lastmounteddirectory"; Int64 "reservedblockscount"; Int64 "user"]), 298, [],
+   [InitScratchFS, Always, TestOutputHashtable (
+     [["tune2fs"; "/dev/sdb1"; "false"; "0"; ""; "NOARG"; ""; "0"; ""; "NOARG"; ""; ""];
+      ["tune2fs_l"; "/dev/sdb1"]],
+     ["Check interval", "0 (<none>)";
+      "Maximum mount count", "-1"]);
+    InitScratchFS, Always, TestOutputHashtable (
+      [["tune2fs"; "/dev/sdb1"; "false"; "0"; ""; "NOARG"; ""; "86400"; ""; "NOARG"; ""; ""];
+       ["tune2fs_l"; "/dev/sdb1"]],
+      ["Check interval", "86400 (1 day)";
+       "Maximum mount count", "-1"]);
+    InitScratchFS, Always, TestOutputHashtable (
+      [["tune2fs"; "/dev/sdb1"; "false"; ""; ""; "NOARG"; "1"; ""; ""; "NOARG"; ""; "1"];
+       ["tune2fs_l"; "/dev/sdb1"]],
+      ["Reserved blocks uid", "1 (user bin)";
+       "Reserved blocks gid", "1 (group bin)"]);
+    InitScratchFS, Always, TestOutputHashtable (
+      [["tune2fs"; "/dev/sdb1"; "false"; ""; ""; "NOARG"; "0"; ""; ""; "NOARG"; ""; "0"];
+       ["tune2fs_l"; "/dev/sdb1"]],
+      ["Reserved blocks uid", "0 (user root)";
+       "Reserved blocks gid", "0 (group root)"])
+   ],
+   "adjust ext2/ext3/ext4 filesystem parameters",
+   "\
+This call allows you to adjust various filesystem parameters of
+an ext2/ext3/ext4 filesystem called C<device>.
+
+The optional parameters are:
+
+=over 4
+
+=item C<force>
+
+Force tune2fs to complete the operation even in the face of errors.
+This is the same as the tune2fs C<-f> option.
+
+=item C<maxmountcount>
+
+Set the number of mounts after which the filesystem is checked
+by L<e2fsck(8)>.  If this is C<0> then the number of mounts is
+disregarded.  This is the same as the tune2fs C<-c> option.
+
+=item C<mountcount>
+
+Set the number of times the filesystem has been mounted.
+This is the same as the tune2fs C<-C> option.
+
+=item C<errorbehavior>
+
+Change the behavior of the kernel code when errors are detected.
+Possible values currently are: C<continue>, C<remount-ro>, C<panic>.
+In practice these options don't really make any difference,
+particularly for write errors.
+
+This is the same as the tune2fs C<-e> option.
+
+=item C<group>
+
+Set the group which can use reserved filesystem blocks.
+This is the same as the tune2fs C<-g> option except that it
+can only be specified as a number.
+
+=item C<intervalbetweenchecks>
+
+Adjust the maximal time between two filesystem checks
+(in seconds).  If the option is passed as C<0> then
+time-dependent checking is disabled.
+
+This is the same as the tune2fs C<-i> option.
+
+=item C<reservedblockspercentage>
+
+Set the percentage of the filesystem which may only be allocated
+by privileged processes.
+This is the same as the tune2fs C<-m> option.
+
+=item C<lastmounteddirectory>
+
+Set the last mounted directory.
+This is the same as the tune2fs C<-M> option.
+
+=item C<reservedblockscount>
+Set the number of reserved filesystem blocks.
+This is the same as the tune2fs C<-r> option.
+
+=item C<user>
+
+Set the user who can use the reserved filesystem blocks.
+This is the same as the tune2fs C<-u> option except that it
+can only be specified as a number.
+
+=back
+
+To get the current values of filesystem parameters, see
+C<guestfs_tune2fs_l>.  For precise details of how tune2fs
+works, see the L<tune2fs(8)> man page.");
+
+  ("md_create", (RErr, [String "name"; DeviceList "devices"], [Int64 "missingbitmap"; Int "nrdevices"; Int "spare"; Int64 "chunk"; String "level"]), 299, [Optional "mdadm"],
+   [],
+   "create a Linux md (RAID) device",
+   "\
+Create a Linux md (RAID) device named C<name> on the devices
+in the list C<devices>.
+
+The optional parameters are:
+
+=over 4
+
+=item C<missingbitmap>
+
+A bitmap of missing devices.  If a bit is set it means that a
+missing device is added to the array.  The least significant bit
+corresponds to the first device in the array.
+
+As examples:
+
+If C<devices = [\"/dev/sda\"]> and C<missingbitmap = 0x1> then
+the resulting array would be C<[E<lt>missingE<gt>, \"/dev/sda\"]>.
+
+If C<devices = [\"/dev/sda\"]> and C<missingbitmap = 0x2> then
+the resulting array would be C<[\"/dev/sda\", E<lt>missingE<gt>]>.
+
+This defaults to C<0> (no missing devices).
+
+The length of C<devices> + the number of bits set in
+C<missingbitmap> must equal C<nrdevices> + C<spare>.
+
+=item C<nrdevices>
+
+The number of active RAID devices.
+
+If not set, this defaults to the length of C<devices> plus
+the number of bits set in C<missingbitmap>.
+
+=item C<spare>
+
+The number of spare devices.
+
+If not set, this defaults to C<0>.
+
+=item C<chunk>
+
+The chunk size in bytes.
+
+=item C<level>
+
+The RAID level, which can be one of:
+I<linear>, I<raid0>, I<0>, I<stripe>, I<raid1>, I<1>, I<mirror>,
+I<raid4>, I<4>, I<raid5>, I<5>, I<raid6>, I<6>, I<raid10>, I<10>.
+Some of these are synonymous, and more levels may be added in future.
+
+If not set, this defaults to C<raid1>.
+
+=back");
+
+  ("list_md_devices", (RStringList "devices", [], []), 300, [],
+   [],
+   "list Linux md (RAID) devices",
+   "\
+List all Linux md devices.");
+
+  ("md_detail", (RHashtable "info", [Device "md"], []), 301,  [Optional "mdadm"],
+   [],
+   "obtain metadata for an MD device",
+   "\
+This command exposes the output of 'mdadm -DY <md>'. The following fields are
+usually present in the returned hash. Other fields may also be present.
+
+=over
+
+=item C<level>
+
+The raid level of the MD device.
+
+=item C<devices>
+
+The number of underlying devices in the MD device.
+
+=item C<metadata>
+
+The metadata version used.
+
+=item C<uuid>
+
+The UUID of the MD device.
+
+=item C<name>
+
+The name of the MD device.
+
+=back");
+
+  ("md_stop", (RErr, [Device "md"], []), 302, [Optional "mdadm"],
+   [],
+   "stop a Linux md (RAID) device",
+   "\
+This command deactivates the MD array named C<md>.  The
+device is stopped, but it is not destroyed or zeroed.");
+
+  ("blkid", (RHashtable "info", [Device "device"], []), 303, [],
+   [InitScratchFS, Always, TestOutputHashtable (
+      [["blkid"; "/dev/sdb1"]],
+      ["TYPE", "ext2";
+       "USAGE", "filesystem";
+       "PART_ENTRY_NUMBER", "1";
+       "PART_ENTRY_TYPE", "0x83";
+       "PART_ENTRY_OFFSET", "128";
+       "PART_ENTRY_SIZE", "102145"])],
+   "print block device attributes",
+   "\
+This command returns block device attributes for C<device>. The following fields are
+usually present in the returned hash. Other fields may also be present.
+
+=over
+
+=item C<UUID>
+
+The uuid of this device.
+
+=item C<LABEL>
+
+The label of this device.
+
+=item C<VERSION>
+
+The version of blkid command.
+
+=item C<TYPE>
+
+The filesystem type or RAID of this device.
+
+=item C<USAGE>
+
+The usage of this device, for example C<filesystem> or C<raid>.
+
+=back");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
@@ -5864,6 +6675,30 @@ them with the help of L</glob> like this:
 
  glob copy-out /home/* .");
 
+  ("delete_event", (RErr,[], []), -1, [], [],
+   "delete a previously registered event handler",
+   " delete-event name
+
+Delete the event handler which was previously registered as C<name>.
+If multiple event handlers were registered with the same name, they
+are all deleted.
+
+See also the guestfish commands C<event> and C<list-events>.");
+
+  ("display", (RErr,[], []), -1, [], [],
+   "display an image",
+   " display filename
+
+Use C<display> (a graphical display program) to display an image
+file.  It downloads the file, and runs C<display> on it.
+
+To use an alternative program, set the C<GUESTFISH_DISPLAY_IMAGE>
+environment variable.  For example to use the GNOME display program:
+
+ export GUESTFISH_DISPLAY_IMAGE=eog
+
+See also L<display(1)>.");
+
   ("echo", (RErr,[], []), -1, [], [],
    "display a line of text",
    " echo [params ...]
@@ -5881,6 +6716,39 @@ The editor is C<$EDITOR>.  However if you use the alternate
 commands C<vi> or C<emacs> you will get those corresponding
 editors.");
 
+  ("event", (RErr,[], []), -1, [], [],
+   "register a handler for an event or events",
+   " event name eventset \"shell script ...\"
+
+Register a shell script fragment which is executed when an
+event is raised.  See L<guestfs(3)/guestfs_set_event_callback>
+for a discussion of the event API in libguestfs.
+
+The C<name> parameter is a name that you give to this event
+handler.  It can be any string (even the empty string) and is
+simply there so you can delete the handler using the guestfish
+C<delete-event> command.
+
+The C<eventset> parameter is a comma-separated list of one
+or more events, for example C<close> or C<close,trace>.  The
+special value C<*> means all events.
+
+The third and final parameter is the shell script fragment
+(or any external command) that is executed when any of the
+events in the eventset occurs.  It is executed using
+C<$SHELL -c>, or if C<$SHELL> is not set then C</bin/sh -c>.
+
+The shell script fragment receives callback parameters as
+arguments C<$1>, C<$2> etc.  The actual event that was
+called is available in the environment variable C<$EVENT>.
+
+ event \"\" close \"echo closed\"
+ event messages appliance,library,trace \"echo $@\"
+ event \"\" progress \"echo progress: $3/$4\"
+ event \"\" * \"echo $EVENT $@\"
+
+See also the guestfish commands C<delete-event> and C<list-events>.");
+
   ("glob", (RErr,[], []), -1, [], [],
    "expand wildcards in command",
    " glob command args...
@@ -5935,6 +6803,13 @@ itself.
 
 Note that C<!cd> won't do what you might expect.");
 
+  ("list_events", (RErr,[], []), -1, [], [],
+   "list event handlers",
+   " list-events
+
+List the event handlers registered using the guestfish
+C<event> command.");
+
   ("man", (RErr,[], []), -1, [FishAlias "manual"], [],
    "open the manual",
    "  man
@@ -5960,6 +6835,17 @@ Close and reopen the libguestfs handle.  It is not necessary to use
 this normally, because the handle is closed properly when guestfish
 exits.  However this is occasionally useful for testing.");
 
+  ("setenv", (RErr,[], []), -1, [], [],
+   "set an environment variable",
+   "  setenv VAR value
+
+Set the environment variable C<VAR> to the string C<value>.
+
+To print the value of an environment variable use a shell command
+such as:
+
+ !echo $VAR");
+
   ("sparse", (RErr,[], []), -1, [], [],
    "create a sparse disk image and add",
    " sparse filename size
@@ -5994,4 +6880,10 @@ See also L<guestfs(3)/AVAILABILITY>.");
 Run the command as usual, but print the elapsed time afterwards.  This
 can be useful for benchmarking operations.");
 
+  ("unsetenv", (RErr,[], []), -1, [], [],
+   "unset an environment variable",
+   "  unsetenv VAR
+
+Remove C<VAR> from the environment.");
+
 ]