From 8869adf1e811d894088dbb0f371edc23299005c8 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 21 Sep 2009 11:52:53 +0100 Subject: [PATCH] Remove guestfs_wait_ready (turn it into a no-op). 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. --- TODO | 3 +- cat/virt-cat.pl | 1 - df/virt-df.pl | 1 - examples/hello.c | 1 - examples/to-xml.c | 1 - fish/fish.c | 2 -- guestfs.pod | 24 ++++++---------- haskell/Guestfs010Launch.hs | 1 - haskell/Guestfs050LVCreate.hs | 1 - inspector/virt-inspector.pl | 1 - java/t/GuestFS010Launch.java | 1 - java/t/GuestFS050LVCreate.java | 1 - ocaml/examples/lvs.ml | 1 - ocaml/t/guestfs_010_launch.ml | 1 - ocaml/t/guestfs_050_lvcreate.ml | 1 - ocaml/t/guestfs_060_readdir.ml | 1 - perl/examples/lvs.pl | 1 - perl/lib/Sys/Guestfs/Lib.pm | 2 +- perl/t/050-lvcreate.t | 4 +-- perl/t/060-readdir.t | 4 +-- perl/t/510-lib-file-arch.t | 4 +-- python/t/010-launch.py | 1 - python/t/050-lvcreate.py | 1 - ruby/tests/tc_050_lvcreate.rb | 1 - ruby/tests/tc_rhbz507346.rb | 1 - src/generator.ml | 28 ++++++++----------- src/guestfs.c | 62 ++++++++++++++++++++--------------------- test-tool/test-tool.c | 10 ++----- 28 files changed, 56 insertions(+), 105 deletions(-) diff --git a/TODO b/TODO index bfcc477..12b1ce6 100644 --- 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: diff --git a/cat/virt-cat.pl b/cat/virt-cat.pl index 1017876..8db5348 100755 --- a/cat/virt-cat.pl +++ b/cat/virt-cat.pl @@ -140,7 +140,6 @@ if ($uri) { } $g->launch (); -$g->wait_ready (); # List of possible filesystems. my @partitions = get_partitions ($g); diff --git a/df/virt-df.pl b/df/virt-df.pl index a1b2228..21ba791 100755 --- a/df/virt-df.pl +++ b/df/virt-df.pl @@ -183,7 +183,6 @@ sub do_df } $g->launch (); - $g->wait_ready (); my @partitions = get_partitions ($g); diff --git a/examples/hello.c b/examples/hello.c index 1c12f8e..8b36ed4 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -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); diff --git a/examples/to-xml.c b/examples/to-xml.c index 2cf3de8..6d0a1df 100644 --- a/examples/to-xml.c +++ b/examples/to-xml.c @@ -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 ("\n"); diff --git a/fish/fish.c b/fish/fish.c index 9215f4e..f8c0483 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -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; } diff --git a/guestfs.pod b/guestfs.pod index c5b756e..33b84d7 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -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 and all of the actions including C +C and all of the actions including C 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 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 and -C. +After configuring the handle, you have to call C. You may also want to configure error handling for the handle. See L 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 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 is a non-blocking call that -starts up the child process, immediately moving from CONFIG to -LAUNCHING. C 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. +LAUNCHING to READY. C blocks until the child process +is READY to accept commands (or until some failure or timeout). +C internally moves the state from CONFIG to LAUNCHING +while it is running. High-level API actions such as C 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 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 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) which indicates that the guest -and daemon is alive. This is what C waits for. +and daemon is alive. This is what C waits for. =head1 QEMU WRAPPERS diff --git a/haskell/Guestfs010Launch.hs b/haskell/Guestfs010Launch.hs index 27e49f7..930d666 100644 --- a/haskell/Guestfs010Launch.hs +++ b/haskell/Guestfs010Launch.hs @@ -28,5 +28,4 @@ main = do hClose fd Guestfs.add_drive g "test.img" Guestfs.launch g - Guestfs.wait_ready g removeLink "test.img" diff --git a/haskell/Guestfs050LVCreate.hs b/haskell/Guestfs050LVCreate.hs index b82bf0d..502f6b2 100644 --- a/haskell/Guestfs050LVCreate.hs +++ b/haskell/Guestfs050LVCreate.hs @@ -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"] diff --git a/inspector/virt-inspector.pl b/inspector/virt-inspector.pl index 943f32e..86b1795 100755 --- a/inspector/virt-inspector.pl +++ b/inspector/virt-inspector.pl @@ -219,7 +219,6 @@ if ($uri) { } $g->launch (); -$g->wait_ready (); =head1 OUTPUT FORMAT diff --git a/java/t/GuestFS010Launch.java b/java/t/GuestFS010Launch.java index 198ea85..ad0665b 100644 --- a/java/t/GuestFS010Launch.java +++ b/java/t/GuestFS010Launch.java @@ -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 (); diff --git a/java/t/GuestFS050LVCreate.java b/java/t/GuestFS050LVCreate.java index 012d68b..940239a 100644 --- a/java/t/GuestFS050LVCreate.java +++ b/java/t/GuestFS050LVCreate.java @@ -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"}); diff --git a/ocaml/examples/lvs.ml b/ocaml/examples/lvs.ml index 12c7c15..74998b9 100644 --- a/ocaml/examples/lvs.ml +++ b/ocaml/examples/lvs.ml @@ -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)); diff --git a/ocaml/t/guestfs_010_launch.ml b/ocaml/t/guestfs_010_launch.ml index b253e0c..ae0f9f1 100644 --- a/ocaml/t/guestfs_010_launch.ml +++ b/ocaml/t/guestfs_010_launch.ml @@ -27,6 +27,5 @@ let () = Guestfs.add_drive g "test.img"; Guestfs.launch g; - Guestfs.wait_ready g; unlink "test.img" diff --git a/ocaml/t/guestfs_050_lvcreate.ml b/ocaml/t/guestfs_050_lvcreate.ml index 2d5bb1f..ad98c06 100644 --- a/ocaml/t/guestfs_050_lvcreate.ml +++ b/ocaml/t/guestfs_050_lvcreate.ml @@ -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"|]; diff --git a/ocaml/t/guestfs_060_readdir.ml b/ocaml/t/guestfs_060_readdir.ml index e9368a8..8035a09 100644 --- a/ocaml/t/guestfs_060_readdir.ml +++ b/ocaml/t/guestfs_060_readdir.ml @@ -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"; diff --git a/perl/examples/lvs.pl b/perl/examples/lvs.pl index 152db08..1a84017 100755 --- a/perl/examples/lvs.pl +++ b/perl/examples/lvs.pl @@ -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 (); diff --git a/perl/lib/Sys/Guestfs/Lib.pm b/perl/lib/Sys/Guestfs/Lib.pm index 96ada0d..a9868e2 100644 --- a/perl/lib/Sys/Guestfs/Lib.pm +++ b/perl/lib/Sys/Guestfs/Lib.pm @@ -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-Elaunch ()> and C<$g-Ewait_ready>. +have to call C<$g-Elaunch ()>. The optional C
parameter can be added to specify the libvirt URI. In addition, L lists other parameters which are diff --git a/perl/t/050-lvcreate.t b/perl/t/050-lvcreate.t index 1b3e313..a8f3e7b 100644 --- a/perl/t/050-lvcreate.t +++ b/perl/t/050-lvcreate.t @@ -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); diff --git a/perl/t/060-readdir.t b/perl/t/060-readdir.t index 17dfd24..898b44f 100644 --- a/perl/t/060-readdir.t +++ b/perl/t/060-readdir.t @@ -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); diff --git a/perl/t/510-lib-file-arch.t b/perl/t/510-lib-file-arch.t index 5c70449..dfe32bc 100644 --- a/perl/t/510-lib-file-arch.t +++ b/perl/t/510-lib-file-arch.t @@ -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); diff --git a/python/t/010-launch.py b/python/t/010-launch.py index c1316d2..93a8154 100644 --- a/python/t/010-launch.py +++ b/python/t/010-launch.py @@ -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") diff --git a/python/t/050-lvcreate.py b/python/t/050-lvcreate.py index 8503023..f98fe29 100644 --- a/python/t/050-lvcreate.py +++ b/python/t/050-lvcreate.py @@ -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) diff --git a/ruby/tests/tc_050_lvcreate.rb b/ruby/tests/tc_050_lvcreate.rb index ea87e39..37ae94d 100644 --- a/ruby/tests/tc_050_lvcreate.rb +++ b/ruby/tests/tc_050_lvcreate.rb @@ -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"]); diff --git a/ruby/tests/tc_rhbz507346.rb b/ruby/tests/tc_rhbz507346.rb index 3bd4bb6..8c5b34f 100644 --- a/ruby/tests/tc_rhbz507346.rb +++ b/ruby/tests/tc_rhbz507346.rb @@ -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) diff --git a/src/generator.ml b/src/generator.ml index 179665b..e5e2681 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -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. +This function is a no op. -You should call this after C to wait for the launch -to complete."); +In versions of the API E 1.0.71 you had to call this function +just after calling C to wait for the launch +to complete. However this is no longer necessary because +C 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 () diff --git a/src/guestfs.c b/src/guestfs.c index 17d812a..417d17f 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -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; } diff --git a/test-tool/test-tool.c b/test-tool/test-tool.c index 508c31a..c1a3de7 100644 --- a/test-tool/test-tool.c +++ b/test-tool/test-tool.c @@ -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); } -- 1.8.3.1