Remove guestfs_wait_ready (turn it into a no-op).
authorRichard Jones <rjones@trick.home.annexia.org>
Mon, 21 Sep 2009 10:52:53 +0000 (11:52 +0100)
committerRichard Jones <rjones@trick.home.annexia.org>
Mon, 21 Sep 2009 11:01:51 +0000 (12:01 +0100)
This commit changes guestfs_launch so that it both launches
the appliance and waits until it is ready (ie. the daemon communicates
back to us).

Since we removed the pretence that we could implement a low-level
asynchronous API, the need to call launch() followed by wait_ready()
has looked a bit silly.

Now guestfs_wait_ready() is basically a no-op.  It is left in the
API for backwards compatibility.  Any calls to guestfs_wait_ready()
can be removed from client code.

28 files changed:
TODO
cat/virt-cat.pl
df/virt-df.pl
examples/hello.c
examples/to-xml.c
fish/fish.c
guestfs.pod
haskell/Guestfs010Launch.hs
haskell/Guestfs050LVCreate.hs
inspector/virt-inspector.pl
java/t/GuestFS010Launch.java
java/t/GuestFS050LVCreate.java
ocaml/examples/lvs.ml
ocaml/t/guestfs_010_launch.ml
ocaml/t/guestfs_050_lvcreate.ml
ocaml/t/guestfs_060_readdir.ml
perl/examples/lvs.pl
perl/lib/Sys/Guestfs/Lib.pm
perl/t/050-lvcreate.t
perl/t/060-readdir.t
perl/t/510-lib-file-arch.t
python/t/010-launch.py
python/t/050-lvcreate.py
ruby/tests/tc_050_lvcreate.rb
ruby/tests/tc_rhbz507346.rb
src/generator.ml
src/guestfs.c
test-tool/test-tool.c

diff --git a/TODO b/TODO
index bfcc477..12b1ce6 100644 (file)
--- a/TODO
+++ b/TODO
@@ -214,7 +214,7 @@ Quick Perl scripts
 Currently we can't do Perl "one-liners".  ie. The current syntax for
 any short Perl one-liner would be:
 
-  perl -MSys::Guestfs -e '$g = Sys::Guestfs->new(); $g->add_drive ("foo"); $g->launch; $g->wait_ready; $g->mount ("/dev/sda1", "/"); ....'
+  perl -MSys::Guestfs -e '$g = Sys::Guestfs->new(); $g->add_drive ("foo"); $g->launch; $g->mount ("/dev/sda1", "/"); ....'
 
 You can see we're well beyond a single line just getting to the point
 of adding drives and mounting.
@@ -235,7 +235,6 @@ which is equivalent to the following sequence of calls:
  $h->set_autosync (1);
  $h->add_drive_ro ($filename);
  $h->launch ();
- $h->wait_ready ();
  $h->mount_ro (\"/dev/sda1\", \"/\");
 
 Command-line form would be:
index 1017876..8db5348 100755 (executable)
@@ -140,7 +140,6 @@ if ($uri) {
 }
 
 $g->launch ();
-$g->wait_ready ();
 
 # List of possible filesystems.
 my @partitions = get_partitions ($g);
index a1b2228..21ba791 100755 (executable)
@@ -183,7 +183,6 @@ sub do_df
     }
 
     $g->launch ();
-    $g->wait_ready ();
 
     my @partitions = get_partitions ($g);
 
index 1c12f8e..8b36ed4 100644 (file)
@@ -27,7 +27,6 @@ main (int argc, char *argv[])
   if (guestfs_add_drive (g, argv[1]) == -1) exit (1);
 
   if (guestfs_launch (g) == -1) exit (1);
-  if (guestfs_wait_ready (g) == -1) exit (1);
 
   if (guestfs_mount (g, argv[2], "/") == -1) exit (1);
 
index 2cf3de8..6d0a1df 100644 (file)
@@ -51,7 +51,6 @@ main (int argc, char *argv[])
     CALL (guestfs_add_drive (g, argv[i]), -1);
 
   CALL (guestfs_launch (g), -1);
-  CALL (guestfs_wait_ready (g), -1);
 
   printf ("<guestfs-system>\n");
 
index 9215f4e..f8c0483 100644 (file)
@@ -81,8 +81,6 @@ launch (guestfs_h *_g)
   if (guestfs_is_config (g)) {
     if (guestfs_launch (g) == -1)
       return -1;
-    if (guestfs_wait_ready (g) == -1)
-      return -1;
   }
   return 0;
 }
index c5b756e..33b84d7 100644 (file)
@@ -11,7 +11,6 @@ guestfs - Library for accessing and modifying virtual machine images
  guestfs_h *handle = guestfs_create ();
  guestfs_add_drive (handle, "guest.img");
  guestfs_launch (handle);
- guestfs_wait_ready (handle);
  guestfs_mount (handle, "/dev/sda1", "/");
  guestfs_touch (handle, "/hello");
  guestfs_sync (handle);
@@ -56,7 +55,6 @@ functions in the following order:
   */
 
  guestfs_launch (handle);
- guestfs_wait_ready (handle);
 
  /* now you can examine what partitions, LVs etc are available
   * you have to mount / at least
@@ -73,7 +71,7 @@ functions in the following order:
 
  guestfs_close (handle);
 
-C<guestfs_wait_ready> and all of the actions including C<guestfs_sync>
+C<guestfs_launch> and all of the actions including C<guestfs_sync>
 are blocking calls.  You can use the low-level event API to do
 non-blocking operations instead.
 
@@ -100,8 +98,7 @@ You have to call C<guestfs_add_drive> on the handle at least once.
 This function returns a non-NULL pointer to a handle on success or
 NULL on error.
 
-After configuring the handle, you have to call C<guestfs_launch> and
-C<guestfs_wait_ready>.
+After configuring the handle, you have to call C<guestfs_launch>.
 
 You may also want to configure error handling for the handle.  See
 L</ERROR HANDLING> section below.
@@ -443,7 +440,7 @@ libguestfs uses a state machine to model the child process:
                  /     |   | LAUNCHING |
                 /      |   \___________/
                /       |       /
-              /        |  guestfs_wait_ready
+              /        |  guestfs_launch
              /         |     /
     ______  /        __|____V
    /      \ ------> /        \
@@ -463,12 +460,10 @@ Configuration commands for qemu such as C<guestfs_add_drive> can only
 be issued when in the CONFIG state.
 
 The high-level API offers two calls that go from CONFIG through
-LAUNCHING to READY.  C<guestfs_launch> is a non-blocking call that
-starts up the child process, immediately moving from CONFIG to
-LAUNCHING.  C<guestfs_wait_ready> blocks until the child process is
-READY to accept commands (or until some failure or timeout).  The
-low-level event API described below provides a non-blocking way to
-replace C<guestfs_wait_ready>.
+LAUNCHING to READY.  C<guestfs_launch> blocks until the child process
+is READY to accept commands (or until some failure or timeout).
+C<guestfs_launch> internally moves the state from CONFIG to LAUNCHING
+while it is running.
 
 High-level API actions such as C<guestfs_mount> can only be issued
 when in the READY state.  These high-level API calls block waiting for
@@ -535,9 +530,6 @@ The callback function C<cb> will be called when the child process
 becomes ready first time after it has been launched.  (This
 corresponds to a transition from LAUNCHING to the READY state).
 
-You can use this instead of C<guestfs_wait_ready> to implement a
-non-blocking wait for the child process to finish booting up.
-
 =head1 BLOCK DEVICE NAMING
 
 In the kernel there is now quite a profusion of schemata for naming
@@ -780,7 +772,7 @@ parameters, but with the roles of daemon and library reversed.
 Because the underlying channel (QEmu -net channel) doesn't have any
 sort of connection control, when the daemon launches it sends an
 initial word (C<GUESTFS_LAUNCH_FLAG>) which indicates that the guest
-and daemon is alive.  This is what C<guestfs_wait_ready> waits for.
+and daemon is alive.  This is what C<guestfs_launch> waits for.
 
 =head1 QEMU WRAPPERS
 
index 27e49f7..930d666 100644 (file)
@@ -28,5 +28,4 @@ main = do
   hClose fd
   Guestfs.add_drive g "test.img"
   Guestfs.launch g
-  Guestfs.wait_ready g
   removeLink "test.img"
index b82bf0d..502f6b2 100644 (file)
@@ -28,7 +28,6 @@ main = do
   hClose fd
   Guestfs.add_drive g "test.img"
   Guestfs.launch g
-  Guestfs.wait_ready g
 
   Guestfs.pvcreate g "/dev/sda"
   Guestfs.vgcreate g "VG" ["/dev/sda"]
index 943f32e..86b1795 100755 (executable)
@@ -219,7 +219,6 @@ if ($uri) {
 }
 
 $g->launch ();
-$g->wait_ready ();
 
 =head1 OUTPUT FORMAT
 
index 198ea85..ad0665b 100644 (file)
@@ -29,7 +29,6 @@ public class GuestFS010Launch {
             f.close ();
             g.add_drive ("test.img");
             g.launch ();
-            g.wait_ready ();
             g.close ();
             File f2 = new File ("test.img");
             f2.delete ();
index 012d68b..940239a 100644 (file)
@@ -31,7 +31,6 @@ public class GuestFS050LVCreate {
 
             g.add_drive ("test.img");
             g.launch ();
-            g.wait_ready ();
 
             g.pvcreate ("/dev/sda");
             g.vgcreate ("VG", new String[] {"/dev/sda"});
index 12c7c15..74998b9 100644 (file)
@@ -11,7 +11,6 @@ let () =
   let h = Guestfs.create () in
   Guestfs.add_drive h Sys.argv.(1);
   Guestfs.launch h;
-  Guestfs.wait_ready h;
 
   let pvs = Guestfs.pvs h in
   printf "PVs found: [ %s ]\n" (String.concat "; " (Array.to_list pvs));
index b253e0c..ae0f9f1 100644 (file)
@@ -27,6 +27,5 @@ let () =
 
   Guestfs.add_drive g "test.img";
   Guestfs.launch g;
-  Guestfs.wait_ready g;
 
   unlink "test.img"
index 2d5bb1f..ad98c06 100644 (file)
@@ -27,7 +27,6 @@ let () =
 
   Guestfs.add_drive g "test.img";
   Guestfs.launch g;
-  Guestfs.wait_ready g;
 
   Guestfs.pvcreate g "/dev/sda";
   Guestfs.vgcreate g "VG" [|"/dev/sda"|];
index e9368a8..8035a09 100644 (file)
@@ -27,7 +27,6 @@ let () =
 
   Guestfs.add_drive g "test.img";
   Guestfs.launch g;
-  Guestfs.wait_ready g;
 
   Guestfs.sfdisk g "/dev/sda" 0 0 0 [|","|];
   Guestfs.mkfs g "ext2" "/dev/sda1";
index 152db08..1a84017 100755 (executable)
@@ -14,7 +14,6 @@ $h->add_drive ($ARGV[0]);
 
 print "Launching, this can take a few seconds\n";
 $h->launch ();
-$h->wait_ready ();
 
 print "Looking for PVs on the disk image\n";
 my @pvs = $h->pvs ();
index 96ada0d..a9868e2 100644 (file)
@@ -100,7 +100,7 @@ read-write handle, this function will refuse to use active libvirt
 domains.
 
 The handle is still in the config state when it is returned, so you
-have to call C<$g-E<gt>launch ()> and C<$g-E<gt>wait_ready>.
+have to call C<$g-E<gt>launch ()>.
 
 The optional C<address> parameter can be added to specify the libvirt
 URI.  In addition, L<Sys::Virt(3)> lists other parameters which are
index 1b3e313..a8f3e7b 100644 (file)
@@ -17,7 +17,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 12;
+use Test::More tests => 11;
 
 use Sys::Guestfs;
 
@@ -33,8 +33,6 @@ ok (1);
 
 $h->launch ();
 ok (1);
-$h->wait_ready ();
-ok (1);
 
 $h->pvcreate ("/dev/sda");
 ok (1);
index 17dfd24..898b44f 100644 (file)
@@ -17,7 +17,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 13;
+use Test::More tests => 12;
 
 use Sys::Guestfs;
 
@@ -33,8 +33,6 @@ ok (1);
 
 $h->launch ();
 ok (1);
-$h->wait_ready ();
-ok (1);
 
 $h->sfdisk ("/dev/sda", 0, 0, 0, [","]);
 ok (1);
index 5c70449..dfe32bc 100644 (file)
@@ -22,7 +22,7 @@ BEGIN {
     use Test::More;
     eval "use Locale::TextDomain";;
     if (exists $INC{"Locale/TextDomain.pm"}) {
-        plan tests => 17;
+        plan tests => 16;
     } else {
         plan skip_all => "no perl-libintl module";
         exit 0;
@@ -40,8 +40,6 @@ ok (1);
 
 $h->launch ();
 ok (1);
-$h->wait_ready ();
-ok (1);
 
 $h->mount_ro ("/dev/sda", "/");
 ok (1);
index c1316d2..93a8154 100644 (file)
@@ -24,6 +24,5 @@ f.truncate (500 * 1024 * 1024)
 f.close ()
 g.add_drive ("test.img")
 g.launch ()
-g.wait_ready ()
 
 os.unlink ("test.img")
index 8503023..f98fe29 100644 (file)
@@ -24,7 +24,6 @@ f.truncate (500 * 1024 * 1024)
 f.close ()
 g.add_drive ("test.img")
 g.launch ()
-g.wait_ready ()
 g.pvcreate ("/dev/sda")
 g.vgcreate ("VG", ["/dev/sda"])
 g.lvcreate ("LV1", "VG", 200)
index ea87e39..37ae94d 100644 (file)
@@ -30,7 +30,6 @@ class TestLoad < Test::Unit::TestCase
 
     g.add_drive("test.img")
     g.launch()
-    g.wait_ready()
 
     g.pvcreate("/dev/sda")
     g.vgcreate("VG", ["/dev/sda"]);
index 3bd4bb6..8c5b34f 100644 (file)
@@ -30,7 +30,6 @@ class TestLoad < Test::Unit::TestCase
 
     g.add_drive("test.img")
     g.launch()
-    g.wait_ready()
 
     exception = assert_raise TypeError do
         g.command(1)
index 179665b..e5e2681 100755 (executable)
@@ -440,13 +440,18 @@ You should call this after configuring the handle
 
   ("wait_ready", (RErr, []), -1, [NotInFish],
    [],
-   "wait until the qemu subprocess launches",
+   "wait until the qemu subprocess launches (no op)",
    "\
-Internally libguestfs is implemented by running a virtual machine
-using L<qemu(1)>.
+This function is a no op.
 
-You should call this after C<guestfs_launch> to wait for the launch
-to complete.");
+In versions of the API E<lt> 1.0.71 you had to call this function
+just after calling C<guestfs_launch> to wait for the launch
+to complete.  However this is no longer necessary because
+C<guestfs_launch> now does the waiting.
+
+If you see any calls to this function in code then you can just
+remove them, unless you want to retain compatibility with older
+versions of the API.");
 
   ("kill_subprocess", (RErr, []), -1, [],
    [],
@@ -4625,12 +4630,9 @@ static int
 check_state (guestfs_h *g, const char *caller)
 {
   if (!guestfs__is_ready (g)) {
-    if (guestfs__is_config (g))
+    if (guestfs__is_config (g) || guestfs__is_launching (g))
       error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
         caller);
-    else if (guestfs__is_launching (g))
-      error (g, \"%%s: call wait_ready() before using this function\",
-        caller);
     else
       error (g, \"%%s called from the wrong state, %%d != READY\",
         caller, guestfs__get_state (g));
@@ -5522,11 +5524,6 @@ int main (int argc, char *argv[])
   /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
   alarm (600);
 
-  if (guestfs_wait_ready (g) == -1) {
-    printf (\"guestfs_wait_ready FAILED\\n\");
-    exit (1);
-  }
-
   /* Cancel previous alarm. */
   alarm (0);
 
@@ -7390,7 +7387,6 @@ Sys::Guestfs - Perl bindings for libguestfs
  my $h = Sys::Guestfs->new ();
  $h->add_drive ('guest.img');
  $h->launch ();
- $h->wait_ready ();
  $h->mount ('/dev/sda1', '/');
  $h->touch ('/hello');
  $h->sync ();
@@ -7928,7 +7924,6 @@ import guestfs
 g = guestfs.GuestFS ()
 g.add_drive (\"guest.img\")
 g.launch ()
-g.wait_ready ()
 parts = g.list_partitions ()
 
 The guestfs module provides a Python binding to the libguestfs API
@@ -7963,7 +7958,6 @@ g.add_drive (\"guest.img\")
 
 # Launch the qemu subprocess and wait for it to become ready:
 g.launch ()
-g.wait_ready ()
 
 # Now you can issue commands, for example:
 logvols = g.lvs ()
index 17d812a..417d17f 100644 (file)
@@ -1208,6 +1208,32 @@ guestfs__launch (guestfs_h *g)
 
  connected:
   g->state = LAUNCHING;
+
+  /* Wait for qemu to start and to connect back to us via vmchannel and
+   * send the GUESTFS_LAUNCH_FLAG message.
+   */
+  uint32_t size;
+  void *buf = NULL;
+  r = recv_from_daemon (g, &size, &buf);
+  free (buf);
+
+  if (r == -1) return -1;
+
+  if (size != GUESTFS_LAUNCH_FLAG) {
+    error (g, _("guestfs_launch failed, see earlier error messages"));
+    goto cleanup2;
+  }
+
+  /* This is possible in some really strange situations, such as
+   * guestfsd starts up OK but then qemu immediately exits.  Check for
+   * it because the caller is probably expecting to be able to send
+   * commands after this function returns.
+   */
+  if (g->state != READY) {
+    error (g, _("qemu launched and contacted daemon, but state != READY"));
+    goto cleanup2;
+  }
+
   return 0;
 
  cleanup2:
@@ -1381,45 +1407,17 @@ qemu_supports (guestfs_h *g, const char *option)
   return g->qemu_help && strstr (g->qemu_help, option) != NULL;
 }
 
+/* You had to call this function after launch in versions <= 1.0.70,
+ * but it is now a no-op.
+ */
 int
 guestfs__wait_ready (guestfs_h *g)
 {
-  int r;
-  uint32_t size;
-  void *buf = NULL;
-
-  if (g->state == READY) return 0;
-
-  if (g->state == BUSY) {
-    error (g, _("qemu has finished launching already"));
-    return -1;
-  }
-
-  if (g->state != LAUNCHING) {
+  if (g->state != READY)  {
     error (g, _("qemu has not been launched yet"));
     return -1;
   }
 
-  r = recv_from_daemon (g, &size, &buf);
-  free (buf);
-
-  if (r == -1) return -1;
-
-  if (size != GUESTFS_LAUNCH_FLAG) {
-    error (g, _("guestfs_wait_ready failed, see earlier error messages"));
-    return -1;
-  }
-
-  /* This is possible in some really strange situations, such as
-   * guestfsd starts up OK but then qemu immediately exits.  Check for
-   * it because the caller is probably expecting to be able to send
-   * commands after this function returns.
-   */
-  if (g->state != READY) {
-    error (g, _("qemu launched and contacted daemon, but state != READY"));
-    return -1;
-  }
-
   return 0;
 }
 
index 508c31a..c1a3de7 100644 (file)
@@ -186,20 +186,14 @@ main (int argc, char *argv[])
   printf ("guestfs_get_verbose: %d\n", guestfs_get_verbose (g));
 
   /* Launch the guest handle. */
-  if (guestfs_launch (g) == -1) {
-    fprintf (stderr,
-             _("libguestfs-test-tool: failed to launch appliance\n"));
-    exit (1);
-  }
-
   printf ("Launching appliance, timeout set to %d seconds.\n", timeout);
   fflush (stdout);
 
   alarm (timeout);
 
-  if (guestfs_wait_ready (g) == -1) {
+  if (guestfs_launch (g) == -1) {
     fprintf (stderr,
-             _("libguestfs-test-tool: failed or timed out in 'wait_ready'\n"));
+             _("libguestfs-test-tool: failed to launch appliance\n"));
     exit (1);
   }