tests: Rename capitests -> tests/c-api.
[libguestfs.git] / generator / generator_actions.ml
index 56976dd..f7a6a6c 100644 (file)
@@ -743,6 +743,14 @@ Any Microsoft Windows operating system.
 
 FreeBSD.
 
 
 FreeBSD.
 
+=item \"netbsd\"
+
+NetBSD.
+
+=item \"hurd\"
+
+GNU/Hurd.
+
 =item \"unknown\"
 
 The operating system type could not be determined.
 =item \"unknown\"
 
 The operating system type could not be determined.
@@ -802,6 +810,10 @@ Gentoo.
 
 Linux Mint.
 
 
 Linux Mint.
 
+=item \"mageia\"
+
+Mageia.
+
 =item \"mandriva\"
 
 Mandriva.
 =item \"mandriva\"
 
 Mandriva.
@@ -810,6 +822,10 @@ Mandriva.
 
 MeeGo.
 
 
 MeeGo.
 
+=item \"opensuse\"
+
+OpenSUSE.
+
 =item \"pardus\"
 
 Pardus.
 =item \"pardus\"
 
 Pardus.
@@ -830,6 +846,10 @@ Scientific Linux.
 
 Slackware.
 
 
 Slackware.
 
+=item \"ttylinux\"
+
+ttylinux.
+
 =item \"ubuntu\"
 
 Ubuntu.
 =item \"ubuntu\"
 
 Ubuntu.
@@ -991,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).");
 
 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",
    "\
    [],
    "add an image to examine or modify",
    "\
@@ -1034,6 +1054,11 @@ this security hole.
 This rarely-used option lets you emulate the behaviour of the
 deprecated C<guestfs_add_drive_with_if> call (q.v.)
 
 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, [],
 =back");
 
   ("inspect_get_windows_systemroot", (RString "systemroot", [Device "root"], []), -1, [],
@@ -1069,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.");
 
 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"; Bool "live"; Bool "allowuuid"]), -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",
    "\
    [],
    "add the disk(s) from a named libvirt domain",
    "\
@@ -1108,12 +1140,58 @@ 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.
 
 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
 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"; Bool "live"]), -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",
    "\
    [],
    "add the disk(s) from a libvirt domain",
    "\
@@ -1143,6 +1221,10 @@ XML definition.  The default (if the flag is omitted) is never
 to try.  See L<guestfs(3)/ATTACHING TO RUNNING DAEMONS> for more
 information.
 
 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>.");
 *)
 The other optional parameters are passed directly through to
 C<guestfs_add_drive_opts>.");
 *)
@@ -1161,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).
 
 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.");
 Future versions of libguestfs may return other strings.
 
 Please read L<guestfs(3)/INSPECTION> for more details.");
@@ -1182,7 +1265,7 @@ a real packaging system (eg. Windows).
 
 Possible strings include: C<yum>, C<up2date>,
 C<apt> (for all Debian derivatives),
 
 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.");
 Future versions of libguestfs may return other strings.
 
 Please read L<guestfs(3)/INSPECTION> for more details.");
@@ -1545,6 +1628,22 @@ C<^C> to kill the subprocess.");
    "\
 This returns the 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
 ]
 
 (* daemon_functions are any functions which cause some action
@@ -1552,7 +1651,7 @@ This returns the process group flag.");
  *)
 
 let daemon_functions = [
  *)
 
 let daemon_functions = [
-  ("mount", (RErr, [Device "device"; String "mountpoint"], []), 1, [DeprecatedBy "mount_options"],
+  ("mount", (RErr, [Device "device"; String "mountpoint"], []), 1, [],
    [InitEmpty, Always, TestOutput (
       [["part_disk"; "/dev/sda"; "mbr"];
        ["mkfs"; "ext2"; "/dev/sda1"];
    [InitEmpty, Always, TestOutput (
       [["part_disk"; "/dev/sda"; "mbr"];
        ["mkfs"; "ext2"; "/dev/sda1"];
@@ -1575,15 +1674,12 @@ exist.
 The mounted filesystem is writable, if we have sufficient permissions
 on the underlying device.
 
 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"]]],
 
   ("sync", (RErr, [], []), 2, [],
    [ InitEmpty, Always, TestRun [["sync"]]],
@@ -1821,7 +1917,12 @@ do not overwrite original.  Overrides C<AUG_SAVE_BACKUP>.
 
 =item C<AUG_TYPE_CHECK> = 4
 
 
 =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
 
 
 =item C<AUG_NO_STDINC> = 8
 
@@ -2160,7 +2261,7 @@ example C<ext3>.");
 
   ("sfdisk", (RErr, [Device "device";
                      Int "cyls"; Int "heads"; Int "sectors";
 
   ("sfdisk", (RErr, [Device "device";
                      Int "cyls"; Int "heads"; Int "sectors";
-                     StringList "lines"], []), 43, [DangerWillRobinson; DeprecatedBy "part_add"],
+                     StringList "lines"], []), 43, [DeprecatedBy "part_add"],
    [],
    "create partitions on a block device",
    "\
    [],
    "create partitions on a block device",
    "\
@@ -2261,7 +2362,7 @@ This unmounts all mounted filesystems.
 
 Some internal mounts are not unmounted by this call.");
 
 
 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",
    "\
    [],
    "remove all LVM LVs, VGs and PVs",
    "\
@@ -2488,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, [],
 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
    "get ext2/ext3/ext4 superblock details",
    "\
 This returns the contents of the ext2, ext3 or ext4 filesystem
@@ -2614,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"];
    [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",
        ["checksum"; "md5"; "/upload/COPYING.LIB"]],
       Digest.to_hex (Digest.file "COPYING.LIB"))],
    "upload a file from the local machine",
@@ -2630,7 +2734,7 @@ See also C<guestfs_download>.");
    [InitScratchFS, Always, TestOutput (
       (* Pick a file from cwd which isn't likely to change. *)
       [["mkdir"; "/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"]],
        ["download"; "/download/COPYING.LIB"; "testdownload.tmp"];
        ["upload"; "testdownload.tmp"; "/download/upload"];
        ["checksum"; "md5"; "/download/upload"]],
@@ -3001,10 +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.
 
 to securely wipe the device).  It should be sufficient to remove
 any partition tables, filesystem superblocks and so on.
 
+If blocks are already zero, then this command avoids writing
+zeroes.  This prevents the underlying device from becoming non-sparse
+or growing unnecessarily.
+
 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>,
 C<guestfs_is_zero_device>");
 
 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>,
 C<guestfs_is_zero_device>");
 
-  ("grub_install", (RErr, [Pathname "root"; Device "device"], []), 86, [],
+  ("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
    (* See:
     * https://bugzilla.redhat.com/show_bug.cgi?id=484986
     * https://bugzilla.redhat.com/show_bug.cgi?id=479760
@@ -3014,12 +3122,32 @@ C<guestfs_is_zero_device>");
        ["write"; "/boot/grub/device.map"; "(hd0) /dev/vda"];
        ["grub_install"; "/"; "/dev/vda"];
        ["is_dir"; "/boot"]])],
        ["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>.
 
 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
 \"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
@@ -3028,7 +3156,9 @@ a file containing:
 
  (hd0) /dev/vda
 
 
  (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 (
 
   ("cp", (RErr, [Pathname "src"; Pathname "dest"], []), 87, [],
    [InitScratchFS, Always, TestOutput (
@@ -3248,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";
 
   ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
                        Int "cyls"; Int "heads"; Int "sectors";
-                       String "line"], []), 99, [DangerWillRobinson; DeprecatedBy "part_add"],
+                       String "line"], []), 99, [DeprecatedBy "part_add"],
    [],
    "modify a single partition on a block device",
    "\
    [],
    "modify a single partition on a block device",
    "\
@@ -3494,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.");
 
 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",
    [InitNone, Always, TestRun (        (* use /dev/sdc because it's smaller *)
       [["scrub_device"; "/dev/sdc"]])],
    "scrub (securely wipe) a device",
@@ -3873,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>.");
 
 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; DeprecatedBy "part_add"],
+  ("sfdiskM", (RErr, [Device "device"; StringList "lines"], []), 139, [DeprecatedBy "part_add"],
    [],
    "create partitions on a block device",
    "\
    [],
    "create partitions on a block device",
    "\
@@ -4689,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, [],
 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 (
    [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
    "set timestamp of a file with nanosecond precision",
    "\
 This command sets the timestamps of a file with nanosecond
@@ -4936,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.");
 
 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 (
    [InitEmpty, Always, TestRun (
       [["part_disk"; "/dev/sda"; "mbr"]]);
     InitEmpty, Always, TestRun (
@@ -5095,7 +5246,7 @@ See also C<guestfs_version>.
 
 =back");
 
 
 =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"];
    [InitScratchFS, Always, TestOutputBuffer (
       [["mkdir"; "/dd"];
        ["write"; "/dd/src"; "hello, world"];
@@ -5110,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.
 
 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 (
 
   ("filesize", (RInt64 "size", [Pathname "file"], []), 218, [],
    [InitScratchFS, Always, TestOutputInt (
@@ -5203,7 +5355,7 @@ calls to associate logical volumes and volume groups.
 
 See also C<guestfs_vgpvuuids>.");
 
 
 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"];
    [InitScratchFS, Always, TestOutputBuffer (
       [["mkdir"; "/copy_size"];
        ["write"; "/copy_size/src"; "hello, world"];
@@ -5217,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.");
 
 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
    [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 (
 
   ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"], []), 229, [Optional "xz"],
    [InitScratchFS, Always, TestOutput (
@@ -5632,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.");
 
 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",
    "\
    [],
    "format a block device as a LUKS encrypted device",
    "\
@@ -5641,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).");
 
 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",
    "\
    [],
    "format a block device as a LUKS encrypted device",
    "\
@@ -5773,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
 (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", (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",
    "\
         ["checksum"; "md5"; "/upload_offset"]], md5)]),
    "upload a file from the local machine with offset",
    "\
@@ -5806,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"];
     [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)]),
         ["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)]),
@@ -6107,6 +6265,338 @@ C<path> does not exist, then a new file is created.
 
 See also C<guestfs_write>.");
 
 
 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
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
@@ -6185,6 +6675,16 @@ them with the help of L</glob> like this:
 
  glob copy-out /home/* .");
 
 
  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
   ("display", (RErr,[], []), -1, [], [],
    "display an image",
    " display filename
@@ -6216,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.");
 
 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...
   ("glob", (RErr,[], []), -1, [], [],
    "expand wildcards in command",
    " glob command args...
@@ -6270,6 +6803,13 @@ itself.
 
 Note that C<!cd> won't do what you might expect.");
 
 
 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
   ("man", (RErr,[], []), -1, [FishAlias "manual"], [],
    "open the manual",
    "  man
@@ -6295,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.");
 
 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
   ("sparse", (RErr,[], []), -1, [], [],
    "create a sparse disk image and add",
    " sparse filename size
@@ -6329,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.");
 
 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.");
+
 ]
 ]