diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-07-03 13:22:45 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-07-07 11:32:46 +0100 |
commit | dff126b7c5c322c942ec920fe9fb752137c2e25b (patch) | |
tree | b0f3c70599ba1fbf8e581d3c0b623eb1ecc9f6f6 | |
parent | b6ef5f47cf6355c860f659252a391293ae026a32 (diff) | |
download | libguestfs-dff126b7c5c322c942ec920fe9fb752137c2e25b.tar.gz libguestfs-dff126b7c5c322c942ec920fe9fb752137c2e25b.tar.xz libguestfs-dff126b7c5c322c942ec920fe9fb752137c2e25b.zip |
New API: guestfs_shutdown: Cleanly shutdown the backend.
The new API splits orderly close into a two-step process:
if (guestfs_shutdown (g) == -1) {
/* handle the error, eg. qemu error */
}
guestfs_close (g);
Note that the explicit shutdown step is only necessary in the case
where you have made changes to the disk image and want to handle write
errors. Read the documentation for further information.
This change also:
- deprecates guestfs_kill_subprocess
- turns guestfs_kill_subprocess into the same as guestfs_shutdown
- changes guestfish and other tools to call shutdown + close
where necessary (not for read-only tools)
- updates documentation
- updates examples
(cherry picked from commit ffbf1475f7ae7c462db289ad4834391469e72edd)
-rw-r--r-- | edit/virt-edit.c | 2 | ||||
-rwxr-xr-x | erlang/examples/create_disk.erl | 5 | ||||
-rw-r--r-- | examples/create_disk.c | 7 | ||||
-rw-r--r-- | fish/fish.c | 3 | ||||
-rw-r--r-- | fish/reopen.c | 3 | ||||
-rwxr-xr-x | fish/test-events.sh | 3 | ||||
-rw-r--r-- | format/format.c | 4 | ||||
-rw-r--r-- | fuse/guestmount.c | 2 | ||||
-rw-r--r-- | generator/generator_actions.ml | 26 | ||||
-rw-r--r-- | java/examples/CreateDisk.java | 5 | ||||
-rw-r--r-- | java/t/GuestFS010Basic.java | 1 | ||||
-rw-r--r-- | ocaml/examples/create_disk.ml | 6 | ||||
-rw-r--r-- | ocaml/t/guestfs_010_basic.ml | 1 | ||||
-rw-r--r-- | ocaml/t/guestfs_070_threads.ml | 3 | ||||
-rwxr-xr-x | perl/examples/create_disk.pl | 5 | ||||
-rw-r--r-- | python/examples/create_disk.py | 5 | ||||
-rw-r--r-- | python/t/010-basic.py | 1 | ||||
-rw-r--r-- | rescue/virt-rescue.c | 4 | ||||
-rw-r--r-- | resize/resize.ml | 8 | ||||
-rw-r--r-- | ruby/examples/create_disk.rb | 5 | ||||
-rw-r--r-- | sparsify/sparsify.ml | 1 | ||||
-rw-r--r-- | src/guestfs.c | 103 | ||||
-rw-r--r-- | src/guestfs.pod | 43 | ||||
-rw-r--r-- | src/launch.c | 12 | ||||
-rw-r--r-- | test-tool/test-tool.c | 5 | ||||
-rwxr-xr-x | tests/guests/guest-aux/make-fedora-img.pl | 3 | ||||
-rwxr-xr-x | tools/virt-make-fs | 5 | ||||
-rwxr-xr-x | tools/virt-tar | 6 | ||||
-rwxr-xr-x | tools/virt-win-reg | 6 |
29 files changed, 202 insertions, 81 deletions
diff --git a/edit/virt-edit.c b/edit/virt-edit.c index c0427451..3d23da86 100644 --- a/edit/virt-edit.c +++ b/edit/virt-edit.c @@ -298,7 +298,7 @@ main (int argc, char *argv[]) free (root); /* Cleanly unmount the disks after editing. */ - if (guestfs_umount_all (g) == -1 || guestfs_sync (g) == -1) + if (guestfs_shutdown (g) == -1) exit (EXIT_FAILURE); guestfs_close (g); diff --git a/erlang/examples/create_disk.erl b/erlang/examples/create_disk.erl index a0c90444..d192435a 100755 --- a/erlang/examples/create_disk.erl +++ b/erlang/examples/create_disk.erl @@ -51,6 +51,11 @@ main(_) -> % the disk image. ok = guestfs:upload(G, "/etc/resolv.conf", "/foo/resolv.conf"), + % Because we wrote to the disk and we want to detect write + % errors, call guestfs:shutdown. You don't need to do this: + % guestfs:close will do it implicitly. + ok = guestfs:shutdown(G), + % Note also that handles are automatically closed if they are % reaped by the garbage collector. You only need to call close % if you want to close the handle right away. diff --git a/examples/create_disk.c b/examples/create_disk.c index 5380888b..e314328f 100644 --- a/examples/create_disk.c +++ b/examples/create_disk.c @@ -99,6 +99,13 @@ main (int argc, char *argv[]) if (guestfs_upload (g, "/etc/resolv.conf", "/foo/resolv.conf") == -1) exit (EXIT_FAILURE); + /* Because we wrote to the disk and we want to detect write + * errors, call guestfs_shutdown. You don't need to do this: + * guestfs_close will do it implicitly. + */ + if (guestfs_shutdown (g) == -1) + exit (EXIT_FAILURE); + guestfs_close (g); /* Free up the lists. */ diff --git a/fish/fish.c b/fish/fish.c index 52d01850..41f61ca2 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -550,6 +550,9 @@ main (int argc, char *argv[]) if (progress_bars) progress_bar_free (bar); + if (guestfs_shutdown (g) == -1) + exit (EXIT_FAILURE); + guestfs_close (g); free_event_handlers (); diff --git a/fish/reopen.c b/fish/reopen.c index 585bbd23..602ff02a 100644 --- a/fish/reopen.c +++ b/fish/reopen.c @@ -39,6 +39,9 @@ run_reopen (const char *cmd, size_t argc, char *argv[]) return -1; } + if (guestfs_shutdown (g) == -1) + return -1; + /* Open the new handle first, so we can copy the settings from the * old one to the new one, and also so if it fails we still have an * open handle. diff --git a/fish/test-events.sh b/fish/test-events.sh index 76d3823f..b3684a83 100755 --- a/fish/test-events.sh +++ b/fish/test-events.sh @@ -53,6 +53,9 @@ if [ "$(cat test.out)" != '"ev1" (0): *: echo $EVENT $@ "ev1" (1): *: echo $EVENT $@ "ev2" (2): *: echo $EVENT $@ "ev2" (2): *: echo $EVENT $@ +enter shutdown +trace shutdown +trace shutdown = 0 enter get_autosync trace get_autosync trace get_autosync = 1 diff --git a/format/format.c b/format/format.c index 06428e88..45c9ab4b 100644 --- a/format/format.c +++ b/format/format.c @@ -255,6 +255,8 @@ main (int argc, char *argv[]) guestfs_set_verbose (g2, guestfs_get_verbose (g)); guestfs_set_trace (g2, guestfs_get_trace (g)); + if (guestfs_shutdown (g) == -1) + exit (EXIT_FAILURE); guestfs_close (g); g = g2; } @@ -273,6 +275,8 @@ main (int argc, char *argv[]) /* Free up data structures. */ free_drives (drvs); + if (guestfs_shutdown (g) == -1) + exit (EXIT_FAILURE); guestfs_close (g); exit (EXIT_SUCCESS); diff --git a/fuse/guestmount.c b/fuse/guestmount.c index 304d1ae8..c14a7f23 100644 --- a/fuse/guestmount.c +++ b/fuse/guestmount.c @@ -1255,6 +1255,8 @@ main (int argc, char *argv[]) r = fuse_main (fuse_argc, (char **) fuse_argv, &fg_operations, NULL); /* Cleanup. */ + if (guestfs_shutdown (g) == -1) + r = -1; guestfs_close (g); free_dir_caches (); diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 5cdd0764..c24e37d7 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -137,11 +137,13 @@ 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, [], + ("kill_subprocess", (RErr, [], []), -1, [DeprecatedBy "shutdown"], [], "kill the qemu subprocess", "\ -This kills the qemu subprocess. You should never need to call this."); +This kills the qemu subprocess. + +Do not call this. See: C<guestfs_shutdown> instead."); ("add_drive", (RErr, [String "filename"], []), -1, [], [], @@ -1655,6 +1657,26 @@ This function must be called before C<guestfs_launch>."); "\ This returns the number of virtual CPUs assigned to the appliance."); + ("shutdown", (RErr, [], []), -1, [], + [], + "shutdown the qemu subprocess", + "\ +This is the opposite of C<guestfs_launch>. It performs an orderly +shutdown of the backend process(es). If the autosync flag is set +(which is the default) then the disk image is synchronized. + +If the subprocess exits with an error then this function will return +an error, which should I<not> be ignored (it may indicate that the +disk image could not be written out properly). + +It is safe to call this multiple times. Extra calls are ignored. + +This call does I<not> close or free up the handle. You still +need to call C<guestfs_close> afterwards. + +C<guestfs_close> will call this if you don't do it explicitly, +but note that any errors are ignored in that case."); + ] (* daemon_functions are any functions which cause some action diff --git a/java/examples/CreateDisk.java b/java/examples/CreateDisk.java index 41f8739b..381fae1f 100644 --- a/java/examples/CreateDisk.java +++ b/java/examples/CreateDisk.java @@ -66,6 +66,11 @@ public class CreateDisk // the disk image. g.upload ("/etc/resolv.conf", "/foo/resolv.conf"); + // Because we wrote to the disk and we want to detect write + // errors, call g.shutdown. You don't need to do this: + // g.close will do it implicitly. + g.shutdown (); + // Note also that handles are automatically closed if they are // reaped by the garbage collector. You only need to call close // if you want to close the handle right away. diff --git a/java/t/GuestFS010Basic.java b/java/t/GuestFS010Basic.java index 21f88dd3..a44fde1f 100644 --- a/java/t/GuestFS010Basic.java +++ b/java/t/GuestFS010Basic.java @@ -55,6 +55,7 @@ public class GuestFS010Basic assert m.get ("/dev/VG/LV1").equals ("ext2"); assert m.get ("/dev/VG/LV2").equals ("unknown"); + g.shutdown (); g.close (); File f2 = new File ("test.img"); diff --git a/ocaml/examples/create_disk.ml b/ocaml/examples/create_disk.ml index 75dbdc35..4437b1c8 100644 --- a/ocaml/examples/create_disk.ml +++ b/ocaml/examples/create_disk.ml @@ -57,6 +57,12 @@ let () = *) g#upload "/etc/resolv.conf" "/foo/resolv.conf"; + (* Because we wrote to the disk and we want to detect write + * errors, call g#shutdown. You don't need to do this: + * g#close will do it implicitly. + *) + g#shutdown (); + (* Note also that handles are automatically closed if they are * reaped by the garbage collector. You only need to call close * if you want to close the handle right away. diff --git a/ocaml/t/guestfs_010_basic.ml b/ocaml/t/guestfs_010_basic.ml index b6750a1a..bb96737b 100644 --- a/ocaml/t/guestfs_010_basic.ml +++ b/ocaml/t/guestfs_010_basic.ml @@ -61,5 +61,6 @@ let () = "q", 'r' ] then failwith "Guestfs.readdir returned incorrect result"; + g#shutdown (); g#close (); unlink "test.img" diff --git a/ocaml/t/guestfs_070_threads.ml b/ocaml/t/guestfs_070_threads.ml index 8b22f938..419f853e 100644 --- a/ocaml/t/guestfs_070_threads.ml +++ b/ocaml/t/guestfs_070_threads.ml @@ -65,8 +65,7 @@ let () = let s = String.copy "/test" in Guestfs.touch g s; - Guestfs.umount_all g; - Guestfs.sync g; + Guestfs.shutdown g; Guestfs.close g; unlink "test.img"; Gc.compact (); diff --git a/perl/examples/create_disk.pl b/perl/examples/create_disk.pl index fa15bc7b..11b91469 100755 --- a/perl/examples/create_disk.pl +++ b/perl/examples/create_disk.pl @@ -57,6 +57,11 @@ $g->mkdir ("/foo"); # the disk image. $g->upload ("/etc/resolv.conf", "/foo/resolv.conf"); +# Because we wrote to the disk and we want to detect write +# errors, call $g->shutdown. You don't need to do this: +# $g->close will do it implicitly. +$g->shutdown (); + # Note also that handles are automatically closed if they are # reaped by reference counting. You only need to call close # if you want to close the handle right away. diff --git a/python/examples/create_disk.py b/python/examples/create_disk.py index 0885383e..86f50427 100644 --- a/python/examples/create_disk.py +++ b/python/examples/create_disk.py @@ -51,6 +51,11 @@ g.mkdir ("/foo") # the disk image. g.upload ("/etc/resolv.conf", "/foo/resolv.conf") +# Because we wrote to the disk and we want to detect write +# errors, call g.shutdown. You don't need to do this: +# g.close will do it implicitly. +g.shutdown () + # Note also that handles are automatically closed if they are # reaped by reference counting. You only need to call close # if you want to close the handle right away. diff --git a/python/t/010-basic.py b/python/t/010-basic.py index a97f3d24..779af484 100644 --- a/python/t/010-basic.py +++ b/python/t/010-basic.py @@ -31,6 +31,7 @@ g.lvcreate ("LV1", "VG", 200) g.lvcreate ("LV2", "VG", 200) if (g.lvs () != ["/dev/VG/LV1", "/dev/VG/LV2"]): raise "Error: g.lvs() returned incorrect result" +g.shutdown () g.close () os.unlink ("test.img") diff --git a/rescue/virt-rescue.c b/rescue/virt-rescue.c index bda40c1f..ded4f47e 100644 --- a/rescue/virt-rescue.c +++ b/rescue/virt-rescue.c @@ -319,7 +319,9 @@ main (int argc, char *argv[]) */ guestfs_set_error_handler (g, NULL, NULL); - /* We expect launch to fail, so ignore the return value. */ + /* We expect launch to fail, so ignore the return value, and don't + * bother with explicit guestfs_shutdown either. + */ ignore_value (guestfs_launch (g)); guestfs_close (g); diff --git a/resize/resize.ml b/resize/resize.ml index af673266..dd380e80 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -834,7 +834,7 @@ let g = if ok then g, true else if attempts > 0 then ( g#zero "/dev/sdb"; - g#sync (); + g#shutdown (); g#close (); let g = connect_both_disks () in @@ -1118,8 +1118,7 @@ let to_be_expanded = let g = if to_be_expanded then ( - g#umount_all (); - g#sync (); + g#shutdown (); g#close (); let g = new G.guestfs () in @@ -1192,8 +1191,7 @@ let () = (* Finished. Unmount disks and exit. *) let () = - g#umount_all (); - g#sync (); + g#shutdown (); g#close (); if not quiet then ( diff --git a/ruby/examples/create_disk.rb b/ruby/examples/create_disk.rb index 026ea2e7..32fb1171 100644 --- a/ruby/examples/create_disk.rb +++ b/ruby/examples/create_disk.rb @@ -54,6 +54,11 @@ g.mkdir("/foo") # the disk image. g.upload("/etc/resolv.conf", "/foo/resolv.conf") +# Because we wrote to the disk and we want to detect write +# errors, call g.shutdown. You don't need to do this: +# g.close will do it implicitly. +g.shutdown() + # Note also that handles are automatically closed if they are # reaped by the garbage collector. You only need to call close # if you want to close the handle right away. diff --git a/sparsify/sparsify.ml b/sparsify/sparsify.ml index e9db23af..76b118cb 100644 --- a/sparsify/sparsify.ml +++ b/sparsify/sparsify.ml @@ -270,6 +270,7 @@ let () = (* Don't need libguestfs now. *) let () = + g#shutdown (); g#close () (* What should the output format be? If the user specified an diff --git a/src/guestfs.c b/src/guestfs.c index d2c5b4eb..ef0ca167 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -172,8 +172,6 @@ guestfs_create (void) void guestfs_close (guestfs_h *g) { - int status, sig; - if (g->state == NO_HANDLE) { /* Not safe to call ANY callbacks here, so ... */ fprintf (stderr, _("guestfs_close: called twice on the same handle\n")); @@ -202,10 +200,6 @@ guestfs_close (guestfs_h *g) debug (g, "closing guestfs handle %p (state %d)", g, g->state); - /* Try to sync if autosync flag is set. */ - if (g->autosync && g->state == READY) - ignore_value (guestfs_internal_autosync (g)); - /* If we are valgrinding the daemon, then we *don't* want to kill * the subprocess because we want the final valgrind messages sent * when we close sockets below. However for normal production use, @@ -213,42 +207,10 @@ guestfs_close (guestfs_h *g) * daemon or qemu is not responding). */ #ifndef VALGRIND_DAEMON - /* Kill the qemu subprocess. */ if (g->state != CONFIG) - ignore_value (guestfs_kill_subprocess (g)); + ignore_value (guestfs_shutdown (g)); #endif - /* Close sockets. */ - if (g->fd[0] >= 0) - close (g->fd[0]); - if (g->fd[1] >= 0) - close (g->fd[1]); - if (g->sock >= 0) - close (g->sock); - g->fd[0] = -1; - g->fd[1] = -1; - g->sock = -1; - - /* Wait for subprocess(es) to exit. */ - if (g->pid > 0) { - if (waitpid (g->pid, &status, 0) == -1) - perror ("waitpid (qemu)"); - if (WIFEXITED (status) && WEXITSTATUS (status) != 0) - fprintf (stderr, "libguestfs: close: qemu failed (status %d)\n", - WEXITSTATUS (status)); - else if (WIFSIGNALED (status)) { - sig = WTERMSIG (status); - fprintf (stderr, "libguestfs: close: qemu terminated by signal %d (%s)\n", - sig, strsignal (sig)); - } - else if (WIFSTOPPED (status)) { - sig = WSTOPSIG (status); - fprintf (stderr, "libguestfs: close: qemu stopped by signal %d (%s)\n", - sig, strsignal (sig)); - } - } - if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0); - /* Run user close callbacks. */ guestfs___call_callbacks_void (g, GUESTFS_EVENT_CLOSE); @@ -285,6 +247,69 @@ guestfs_close (guestfs_h *g) free (g); } +/* Shutdown the backend. */ +int +guestfs__shutdown (guestfs_h *g) +{ + int ret = 0; + int status, sig; + + if (g->state == CONFIG) + return 0; + + /* Try to sync if autosync flag is set. */ + if (g->autosync && g->state == READY) { + if (guestfs_internal_autosync (g) == -1) + ret = -1; + } + + /* Signal qemu to shutdown cleanly, and kill the recovery process. */ + if (g->pid > 0) { + debug (g, "sending SIGTERM to process %d", g->pid); + kill (g->pid, SIGTERM); + } + if (g->recoverypid > 0) kill (g->recoverypid, 9); + + /* Close sockets. */ + if (g->fd[0] >= 0) + close (g->fd[0]); + if (g->fd[1] >= 0) + close (g->fd[1]); + if (g->sock >= 0) + close (g->sock); + g->fd[0] = -1; + g->fd[1] = -1; + g->sock = -1; + + /* Wait for subprocess(es) to exit. */ + if (g->pid > 0) { + if (waitpid (g->pid, &status, 0) == -1) { + perrorf (g, "waitpid (qemu)"); + ret = -1; + } + else if (WIFEXITED (status) && WEXITSTATUS (status) != 0) { + error (g, "qemu failed (status %d)", WEXITSTATUS (status)); + ret = -1; + } + else if (WIFSIGNALED (status)) { + sig = WTERMSIG (status); + error (g, "qemu terminated by signal %d (%s)", sig, strsignal (sig)); + ret = -1; + } + else if (WIFSTOPPED (status)) { + sig = WSTOPSIG (status); + error (g, "qemu stopped by signal %d (%s)", sig, strsignal (sig)); + ret = -1; + } + } + if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0); + + g->pid = g->recoverypid = 0; + g->state = CONFIG; + + return ret; +} + /* Close all open handles (called from atexit(3)). */ static void close_handles (void) diff --git a/src/guestfs.pod b/src/guestfs.pod index 95ff3409..b993abcd 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -14,6 +14,7 @@ guestfs - Library for accessing and modifying virtual machine images guestfs_mount (g, "/dev/sda1", "/"); guestfs_touch (g, "/hello"); guestfs_umount (g, "/"); + guestfs_shutdown (g); guestfs_close (g); cc prog.c -o prog -lguestfs @@ -81,13 +82,10 @@ this: */ guestfs_touch (g, "/hello"); - /* This is only needed for libguestfs < 1.5.24. Since then - * it is done automatically when you close the handle. See - * discussion of autosync in this page. - */ - guestfs_sync (g); + /* Synchronize the disk. This is the opposite of guestfs_launch. */ + guestfs_shutdown (g); - /* Close the handle 'g'. */ + /* Close and free the handle 'g'. */ guestfs_close (g); The code above doesn't include any error checking. In real code you @@ -1343,12 +1341,37 @@ L</ERROR HANDLING> section below. void guestfs_close (guestfs_h *g); This closes the connection handle and frees up all resources used. +If a close callback was set on the handle, then it is called. -If autosync was set on the handle and the handle was launched, then -this implicitly calls various functions to unmount filesystems and -sync the disk. See L</guestfs_set_autosync> for more details. +The correct way to close the handle is: -If a close callback was set on the handle, then it is called. + if (guestfs_shutdown (g) == -1) { + /* handle write errors here */ + } + guestfs_close (g); + +L</guestfs_shutdown> is only needed if B<all> of the following are true: + +=over 4 + +=item 1 + +one or more disks were added in read-write mode, I<and> + +=item 2 + +guestfs_launch was called, I<and> + +=item 3 + +you made some changes, I<and> + +=item 4 + +you have a way to handle write errors (eg. by exiting with an +error code or reporting something to the user). + +=back =head1 ERROR HANDLING diff --git a/src/launch.c b/src/launch.c index 466ec89c..a2c49458 100644 --- a/src/launch.c +++ b/src/launch.c @@ -1451,17 +1451,7 @@ guestfs__wait_ready (guestfs_h *g) int guestfs__kill_subprocess (guestfs_h *g) { - if (g->state == CONFIG) { - error (g, _("no subprocess to kill")); - return -1; - } - - debug (g, "sending SIGTERM to process %d", g->pid); - - if (g->pid > 0) kill (g->pid, SIGTERM); - if (g->recoverypid > 0) kill (g->recoverypid, 9); - - return 0; + return guestfs__shutdown (g); } /* Access current state. */ diff --git a/test-tool/test-tool.c b/test-tool/test-tool.c index 224fcb61..443d6f04 100644 --- a/test-tool/test-tool.c +++ b/test-tool/test-tool.c @@ -267,6 +267,11 @@ main (int argc, char *argv[]) } /* Close the handle. */ + if (guestfs_shutdown (g) == -1) { + fprintf (stderr, _("libguestfs-test-tool: shutdown failed\n")); + exit (EXIT_FAILURE); + } + guestfs_close (g); /* Booted and performed some simple operations -- success! */ diff --git a/tests/guests/guest-aux/make-fedora-img.pl b/tests/guests/guest-aux/make-fedora-img.pl index c26370c6..5c1f7cee 100755 --- a/tests/guests/guest-aux/make-fedora-img.pl +++ b/tests/guests/guest-aux/make-fedora-img.pl @@ -195,6 +195,9 @@ $g->mkfs_opts ('ext2', '/dev/VG/LV2', blocksize => 1024); $g->mkfs_opts ('ext2', '/dev/VG/LV3', blocksize => 2048); # Cleanup +$g->shutdown (); +$g->close (); + unlink ("fstab.tmp.$$") or die; foreach my $img (@images) { $img =~ /^(.*)\.tmp\.\d+$/ or die; diff --git a/tools/virt-make-fs b/tools/virt-make-fs index 1e34d0a4..5cb5101c 100755 --- a/tools/virt-make-fs +++ b/tools/virt-make-fs @@ -528,9 +528,8 @@ eval { } print STDERR "finishing off\n" if $debug; - $g->umount_all (); - $g->sync (); - undef $g; + $g->shutdown (); + $g->close () }; if ($@) { # Error: delete the output before exiting. diff --git a/tools/virt-tar b/tools/virt-tar index 777dbbdd..801104fe 100755 --- a/tools/virt-tar +++ b/tools/virt-tar @@ -279,10 +279,8 @@ if ($mode eq "x") { } } -$g->sync (); -$g->umount_all (); - -undef $g; +$g->shutdown (); +$g->close (); exit 0; diff --git a/tools/virt-win-reg b/tools/virt-win-reg index ab5daa71..2caa954c 100755 --- a/tools/virt-win-reg +++ b/tools/virt-win-reg @@ -337,9 +337,9 @@ else { # Import mode. upload_hive ($hiveshortname, $hives{$hiveshortname}->{hivefile}) } - # Sync everything. - $g->umount_all (); - $g->sync (); + # Close. + $g->shutdown (); + $g->close (); } exit 0; |