Change to use virtio_blk (virtio block device) by default.
[libguestfs.git] / src / generator.ml
index 5885ff3..69fd706 100755 (executable)
@@ -133,7 +133,9 @@ can easily destroy all your data>."
  * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and
  * a fourth squashfs block device with some known files on it (/dev/sdd).
  *
- * Note for partitioning purposes, the 500MB device has 63 cylinders.
+ * Note for partitioning purposes, the 500MB device has 1015 cylinders.
+ * Number of cylinders was 63 for IDE emulated disks with precisely
+ * the same size.  How exactly this is calculated is a mystery.
  *
  * The squashfs block device (/dev/sdd) comes from images/test.sqsh.
  *
@@ -373,7 +375,8 @@ for whatever operations you want to perform (ie. read access if you
 just want to read the image or write access if you want to modify the
 image).
 
-This is equivalent to the qemu parameter C<-drive file=filename,cache=off>.
+This is equivalent to the qemu parameter
+C<-drive file=filename,cache=off,if=virtio>.
 
 Note that this call checks for the existence of C<filename>.  This
 stops you from specifying other types of drive which are supported
@@ -407,7 +410,7 @@ handle is closed.  We don't currently have any method to enable
 changes to be committed, although qemu can support this.
 
 This is equivalent to the qemu parameter
-C<-drive file=filename,snapshot=on>.
+C<-drive file=filename,snapshot=on,if=virtio>.
 
 Note that this call checks for the existence of C<filename>.  This
 stops you from specifying other types of drive which are supported
@@ -598,6 +601,35 @@ actions using the low-level API.
 
 For more information on states, see L<guestfs(3)>.");
 
+  ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"],
+   [],
+   "set memory allocated to the qemu subprocess",
+   "\
+This sets the memory size in megabytes allocated to the
+qemu subprocess.  This only has any effect if called before
+C<guestfs_launch>.
+
+You can also change this by setting the environment
+variable C<LIBGUESTFS_MEMSIZE> before the handle is
+created.
+
+For more information on the architecture of libguestfs,
+see L<guestfs(3)>.");
+
+  ("get_memsize", (RInt "memsize", []), -1, [],
+   [],
+   "get memory allocated to the qemu subprocess",
+   "\
+This gets the memory size in megabytes allocated to the
+qemu subprocess.
+
+If C<guestfs_set_memsize> was not called
+on this handle, and if C<LIBGUESTFS_MEMSIZE> was not set,
+then this returns the compiled-in default value for memsize.
+
+For more information on the architecture of libguestfs,
+see L<guestfs(3)>.");
+
 ]
 
 (* daemon_functions are any functions which cause some action
@@ -704,7 +736,7 @@ The full block device names are returned, eg. C</dev/sda>");
    [InitBasicFS, Always, TestOutputListOfDevices (
       [["list_partitions"]], ["/dev/sda1"]);
     InitEmpty, Always, TestOutputListOfDevices (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
    "list the partitions",
    "\
@@ -719,7 +751,7 @@ call C<guestfs_lvs>.");
    [InitBasicFSonLVM, Always, TestOutputListOfDevices (
       [["pvs"]], ["/dev/sda1"]);
     InitEmpty, Always, TestOutputListOfDevices (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["pvcreate"; "/dev/sda1"];
        ["pvcreate"; "/dev/sda2"];
        ["pvcreate"; "/dev/sda3"];
@@ -738,7 +770,7 @@ See also C<guestfs_pvs_full>.");
    [InitBasicFSonLVM, Always, TestOutputList (
       [["vgs"]], ["VG"]);
     InitEmpty, Always, TestOutputList (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["pvcreate"; "/dev/sda1"];
        ["pvcreate"; "/dev/sda2"];
        ["pvcreate"; "/dev/sda3"];
@@ -759,7 +791,7 @@ See also C<guestfs_vgs_full>.");
    [InitBasicFSonLVM, Always, TestOutputList (
       [["lvs"]], ["/dev/VG/LV"]);
     InitEmpty, Always, TestOutputList (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["pvcreate"; "/dev/sda1"];
        ["pvcreate"; "/dev/sda2"];
        ["pvcreate"; "/dev/sda3"];
@@ -1112,7 +1144,7 @@ See also C<guestfs_stat>.");
 
   ("pvcreate", (RErr, [String "device"]), 39, [],
    [InitEmpty, Always, TestOutputListOfDevices (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["pvcreate"; "/dev/sda1"];
        ["pvcreate"; "/dev/sda2"];
        ["pvcreate"; "/dev/sda3"];
@@ -1125,7 +1157,7 @@ as C</dev/sda1>.");
 
   ("vgcreate", (RErr, [String "volgroup"; StringList "physvols"]), 40, [],
    [InitEmpty, Always, TestOutputList (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["pvcreate"; "/dev/sda1"];
        ["pvcreate"; "/dev/sda2"];
        ["pvcreate"; "/dev/sda3"];
@@ -1139,7 +1171,7 @@ from the non-empty list of physical volumes C<physvols>.");
 
   ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [],
    [InitEmpty, Always, TestOutputList (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["pvcreate"; "/dev/sda1"];
        ["pvcreate"; "/dev/sda2"];
        ["pvcreate"; "/dev/sda3"];
@@ -1267,7 +1299,7 @@ Some internal mounts are not shown.");
        ["mounts"]], []);
     (* check that umount_all can unmount nested mounts correctly: *)
     InitEmpty, Always, TestOutputList (
-      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",200 ,400 ,"];
        ["mkfs"; "ext2"; "/dev/sda1"];
        ["mkfs"; "ext2"; "/dev/sda2"];
        ["mkfs"; "ext2"; "/dev/sda3"];
@@ -1314,51 +1346,51 @@ particular that the filename is not prepended to the output
   ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
    [InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 1"]], "Result1");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 2"]], "Result2\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 3"]], "\nResult3");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 4"]], "\nResult4\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 5"]], "\nResult5\n\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 6"]], "\n\nResult6\n\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 7"]], "");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 8"]], "\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 9"]], "\n\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
     InitBasicFS, Always, TestOutput (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
     InitBasicFS, Always, TestLastFail (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command"; "/test-command"]])],
    "run a command from the guest filesystem",
    "\
@@ -1395,47 +1427,47 @@ locations.");
   ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
    [InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 1"]], ["Result1"]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 2"]], ["Result2"]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 3"]], ["";"Result3"]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 4"]], ["";"Result4"]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 7"]], []);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 8"]], [""]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 9"]], ["";""]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
     InitBasicFS, Always, TestOutputList (
       [["upload"; "test-command"; "/test-command"];
-       ["chmod"; "493"; "/test-command"];
+       ["chmod"; "0o755"; "/test-command"];
        ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
    "run a command, returning lines",
    "\
@@ -1470,8 +1502,7 @@ This is the same as the C<lstat(2)> system call.");
 
   ("statvfs", (RStatVFS "statbuf", [String "path"]), 54, [],
    [InitBasicFS, Always, TestOutputStruct (
-      [["statvfs"; "/"]], [CompareWithInt ("bfree", 487702);
-                          CompareWithInt ("blocks", 490020);
+      [["statvfs"; "/"]], [CompareWithInt ("namemax", 255);
                           CompareWithInt ("bsize", 1024)])],
    "get file system statistics",
    "\
@@ -1987,7 +2018,10 @@ any partition tables, filesystem superblocks and so on.
 See also: C<guestfs_scrub_device>.");
 
   ("grub_install", (RErr, [String "root"; String "device"]), 86, [],
-   [InitBasicFS, Always, TestOutputTrue (
+   (* Test disabled because grub-install incompatible with virtio-blk driver.
+    * See also: https://bugzilla.redhat.com/show_bug.cgi?id=479760
+    *)
+   [InitBasicFS, Disabled, TestOutputTrue (
       [["grub_install"; "/"; "/dev/sda1"];
        ["is_dir"; "/boot"]])],
    "install GRUB",
@@ -2599,6 +2633,124 @@ subdirectories (recursively).
 The result is the estimated size in I<kilobytes>
 (ie. units of 1024 bytes).");
 
+  ("initrd_list", (RStringList "filenames", [String "path"]), 128, [],
+   [InitBasicFS, Always, TestOutputList (
+      [["mount_vfs"; "ro"; "squashfs"; "/dev/sdd"; "/"];
+       ["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3"])],
+   "list files in an initrd",
+   "\
+This command lists out files contained in an initrd.
+
+The files are listed without any initial C</> character.  The
+files are listed in the order they appear (not necessarily
+alphabetical).  Directory names are listed as separate items.
+
+Old Linux kernels (2.4 and earlier) used a compressed ext2
+filesystem as initrd.  We I<only> support the newer initramfs
+format (compressed cpio files).");
+
+  ("mount_loop", (RErr, [String "file"; String "mountpoint"]), 129, [],
+   [],
+   "mount a file using the loop device",
+   "\
+This command lets you mount C<file> (a filesystem image
+in a file) on a mount point.  It is entirely equivalent to
+the command C<mount -o loop file mountpoint>.");
+
+  ("mkswap", (RErr, [String "device"]), 130, [],
+   [InitEmpty, Always, TestRun (
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+       ["mkswap"; "/dev/sda1"]])],
+   "create a swap partition",
+   "\
+Create a swap partition on C<device>.");
+
+  ("mkswap_L", (RErr, [String "label"; String "device"]), 131, [],
+   [InitEmpty, Always, TestRun (
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+       ["mkswap_L"; "hello"; "/dev/sda1"]])],
+   "create a swap partition with a label",
+   "\
+Create a swap partition on C<device> with label C<label>.");
+
+  ("mkswap_U", (RErr, [String "uuid"; String "device"]), 132, [],
+   [InitEmpty, Always, TestRun (
+      [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+       ["mkswap_U"; "a3a61220-882b-4f61-89f4-cf24dcc7297d"; "/dev/sda1"]])],
+   "create a swap partition with an explicit UUID",
+   "\
+Create a swap partition on C<device> with UUID C<uuid>.");
+
+  ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; String "path"]), 133, [],
+   [InitBasicFS, Always, TestOutputStruct (
+      [["mknod"; "0o10777"; "0"; "0"; "/node"];
+       (* NB: default umask 022 means 0777 -> 0755 in these tests *)
+       ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
+    InitBasicFS, Always, TestOutputStruct (
+      [["mknod"; "0o60777"; "66"; "99"; "/node"];
+       ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
+   "make block, character or FIFO devices",
+   "\
+This call creates block or character special devices, or
+named pipes (FIFOs).
+
+The C<mode> parameter should be the mode, using the standard
+constants.  C<devmajor> and C<devminor> are the
+device major and minor numbers, only used when creating block
+and character special devices.");
+
+  ("mkfifo", (RErr, [Int "mode"; String "path"]), 134, [],
+   [InitBasicFS, Always, TestOutputStruct (
+      [["mkfifo"; "0o777"; "/node"];
+       ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
+   "make FIFO (named pipe)",
+   "\
+This call creates a FIFO (named pipe) called C<path> with
+mode C<mode>.  It is just a convenient wrapper around
+C<guestfs_mknod>.");
+
+  ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; String "path"]), 135, [],
+   [InitBasicFS, Always, TestOutputStruct (
+      [["mknod_b"; "0o777"; "99"; "66"; "/node"];
+       ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
+   "make block device node",
+   "\
+This call creates a block device node called C<path> with
+mode C<mode> and device major/minor C<devmajor> and C<devminor>.
+It is just a convenient wrapper around C<guestfs_mknod>.");
+
+  ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; String "path"]), 136, [],
+   [InitBasicFS, Always, TestOutputStruct (
+      [["mknod_c"; "0o777"; "99"; "66"; "/node"];
+       ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
+   "make char device node",
+   "\
+This call creates a char device node called C<path> with
+mode C<mode> and device major/minor C<devmajor> and C<devminor>.
+It is just a convenient wrapper around C<guestfs_mknod>.");
+
+  ("umask", (RInt "oldmask", [Int "mask"]), 137, [],
+   [], (* XXX umask is one of those stateful things that we should
+       * reset between each test.
+       *)
+   "set file mode creation mask (umask)",
+   "\
+This function sets the mask used for creating new files and
+device nodes to C<mask & 0777>.
+
+Typical umask values would be C<022> which creates new files
+with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
+C<002> which creates new files with permissions like
+\"-rw-rw-r--\" or \"-rwxrwxr-x\".
+
+The default umask is C<022>.  This is important because it
+means that directories and device nodes will be created with
+C<0644> or C<0755> mode even if you specify C<0777>.
+
+See also L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
+
+This call returns the previous umask.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
@@ -4131,6 +4283,8 @@ int main (int argc, char *argv[])
   int fd;
   int nr_tests, test_num = 0;
 
+  setbuf (stdout, NULL);
+
   no_test_warnings ();
 
   g = guestfs_create ();
@@ -4312,7 +4466,7 @@ static int %s_skip (void)
 static int %s (void)
 {
   if (%s_skip ()) {
-    printf (\"%%s skipped (reason: environment variable set)\\n\", \"%s\");
+    printf (\"        %%s skipped (reason: environment variable set)\\n\", \"%s\");
     return 0;
   }
 
@@ -4320,17 +4474,17 @@ static int %s (void)
 
   (match prereq with
    | Disabled ->
-       pr "  printf (\"%%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
+       pr "  printf (\"        %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
    | If _ ->
        pr "  if (! %s_prereq ()) {\n" test_name;
-       pr "    printf (\"%%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
+       pr "    printf (\"        %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
        pr "    return 0;\n";
        pr "  }\n";
        pr "\n";
        generate_one_test_body name i test_name init test;
    | Unless _ ->
        pr "  if (%s_prereq ()) {\n" test_name;
-       pr "    printf (\"%%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
+       pr "    printf (\"        %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
        pr "    return 0;\n";
        pr "  }\n";
        pr "\n";