From: "Richard W.M. Jones" <rjones(a)redhat.com>
---
.gitignore | 4 +
fish/test-mount-local.sh | 8 +-
fuse/Makefile.am | 55 ++++++-
fuse/guestmount-cleanup.c | 297 ++++++++++++++++++++++++++++++++++++
fuse/guestmount-cleanup.pod | 103 +++++++++++++
fuse/guestmount.pod | 1 +
fuse/test-fuse-umount-race.sh | 11 +-
fuse/test-fuse.sh | 25 +--
ocaml/t/guestfs_500_mount_local.ml | 37 +----
po-docs/ja/Makefile.am | 1 +
po-docs/podfiles | 1 +
po-docs/uk/Makefile.am | 1 +
po/POTFILES | 1 +
sysprep/Makefile.am | 1 +
sysprep/sysprep_operation_script.ml | 14 +-
tests/selinux/run-test.pl | 23 +--
16 files changed, 486 insertions(+), 97 deletions(-)
create mode 100644 fuse/guestmount-cleanup.c
create mode 100644 fuse/guestmount-cleanup.pod
diff --git a/.gitignore b/.gitignore
index 0747430..2f46ba0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,7 +141,10 @@ Makefile.in
/format/virt-format.1
/fuse/guestmount
/fuse/guestmount.1
+/fuse/guestmount-cleanup
+/fuse/guestmount-cleanup.1
/fuse/stamp-guestmount.pod
+/fuse/stamp-guestmount-cleanup.pod
/generator/.depend
/generator/files-generated.txt
/generator/generator
@@ -181,6 +184,7 @@ Makefile.in
/html/guestfs-testing.1.html
/html/guestfsd.8.html
/html/guestmount.1.html
+/html/guestmount-cleanup.1.html
/html/libguestfs-make-fixed-appliance.1.html
/html/libguestfs-test-tool.1.html
/html/virt-alignment-scan.1.html
diff --git a/fish/test-mount-local.sh b/fish/test-mount-local.sh
index ad62a92..ca26088 100755
--- a/fish/test-mount-local.sh
+++ b/fish/test-mount-local.sh
@@ -1,6 +1,6 @@
#!/bin/bash -
# libguestfs
-# Copyright (C) 2012 Red Hat Inc.
+# Copyright (C) 2012-2013 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -51,11 +51,7 @@ if [ $# -gt 0 -a "$1" = "--run-test" ]; then
echo 'mount-local test successful' > mp/ok
# Unmount the mountpoint. Might need to retry this.
- count=10
- while ! fusermount -u mp && [ $count -gt 0 ]; do
- sleep 1
- ((count--))
- done
+ ../fuse/guestmount-cleanup mp
exit 0
fi
diff --git a/fuse/Makefile.am b/fuse/Makefile.am
index 12905a3..fc5f54e 100644
--- a/fuse/Makefile.am
+++ b/fuse/Makefile.am
@@ -17,13 +17,21 @@
include $(top_srcdir)/subdir-rules.mk
-EXTRA_DIST = guestmount.pod test-fuse.sh test-fuse-umount-race.sh
+EXTRA_DIST = \
+ guestmount.pod \
+ guestmount-cleanup.pod \
+ test-fuse.sh \
+ test-fuse-umount-race.sh
-CLEANFILES = stamp-guestmount.pod
+CLEANFILES = \
+ stamp-guestmount.pod \
+ stamp-guestmount-cleanup.pod
if HAVE_FUSE
-bin_PROGRAMS = guestmount
+bin_PROGRAMS = \
+ guestmount \
+ guestmount-cleanup
# These source files (all related to option parsing) are shared
# between guestfish and guestmount.
@@ -35,6 +43,8 @@ SHARED_SOURCE_FILES = \
../fish/options.h \
../fish/options.c
+# guestmount
+
guestmount_SOURCES = \
$(SHARED_SOURCE_FILES) \
guestmount.c
@@ -61,10 +71,35 @@ guestmount_LDADD = \
$(LIBVIRT_LIBS) \
../gnulib/lib/libgnu.la
+# guestmount-cleanup
+
+guestmount_cleanup_SOURCES = \
+ guestmount-cleanup.c
+
+guestmount_cleanup_CPPFLAGS = \
+ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+ -I$(top_srcdir)/src -I$(top_builddir)/src \
+ -I$(srcdir)/../gnulib/lib -I../gnulib/lib
+
+guestmount_cleanup_CFLAGS = \
+ $(WARN_CFLAGS) $(WERROR_CFLAGS) \
+ $(GPROF_CFLAGS) $(GCOV_CFLAGS)
+
+guestmount_cleanup_LDADD = \
+ $(top_builddir)/src/libutils.la \
+ $(top_builddir)/src/libguestfs.la \
+ $(LIBXML2_LIBS) \
+ $(LIBVIRT_LIBS) \
+ ../gnulib/lib/libgnu.la
+
# Documentation.
-man_MANS = guestmount.1
-noinst_DATA = $(top_builddir)/html/guestmount.1.html
+man_MANS = \
+ guestmount.1 \
+ guestmount-cleanup.1
+noinst_DATA = \
+ $(top_builddir)/html/guestmount.1.html \
+ $(top_builddir)/html/guestmount-cleanup.1.html
guestmount.1 $(top_builddir)/html/guestmount.1.html: stamp-guestmount.pod
@@ -76,6 +111,16 @@ stamp-guestmount.pod: guestmount.pod
$<
touch $@
+guestmount-cleanup.1 $(top_builddir)/html/guestmount-cleanup.1.html:
stamp-guestmount-cleanup.pod
+
+stamp-guestmount-cleanup.pod: guestmount-cleanup.pod
+ $(PODWRAPPER) \
+ --man guestmount-cleanup.1 \
+ --html $(top_builddir)/html/guestmount-cleanup.1.html \
+ --license GPLv2+ \
+ $<
+ touch $@
+
# Tests.
if ENABLE_APPLIANCE
diff --git a/fuse/guestmount-cleanup.c b/fuse/guestmount-cleanup.c
new file mode 100644
index 0000000..06f38d0
--- /dev/null
+++ b/fuse/guestmount-cleanup.c
@@ -0,0 +1,297 @@
+/* guestmount-cleanup
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+#include <locale.h>
+#include <libintl.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "guestfs.h"
+#include "guestfs-internal-frontend.h"
+
+#include "ignore-value.h"
+#include "progname.h"
+
+static int do_fusermount (const char *mountpoint, char **error_rtn);
+static void do_fuser (const char *mountpoint);
+
+static void __attribute__((noreturn))
+usage (int status)
+{
+ if (status != EXIT_SUCCESS)
+ fprintf (stderr, _("Try `%s --help' for more information.\n"),
+ program_name);
+ else {
+ fprintf (stdout,
+ _("%s: clean up a mounted filesystem\n"
+ "Copyright (C) 2013 Red Hat Inc.\n"
+ "Usage:\n"
+ " %s [--fd=FD] mountpoint\n"
+ "Options:\n"
+ " --fd=FD Pipe file descriptor to monitor\n"
+ " --help Display help message and exit\n"
+ " -v|--verbose Verbose messages\n"
+ " -V|--version Display version and exit\n"
+ ),
+ program_name, program_name);
+ }
+ exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+ enum { HELP_OPTION = CHAR_MAX + 1 };
+
+ static const char *options = "v?V";
+ static const struct option long_options[] = {
+ { "fd", 1, 0, 0 },
+ { "help", 0, 0, HELP_OPTION },
+ { "verbose", 0, 0, 'v' },
+ { "version", 0, 0, 'V' },
+ { 0, 0, 0, 0 }
+ };
+
+ int c, fd = -1;
+ int option_index;
+ const char *mountpoint;
+ struct sigaction sa;
+ struct pollfd pollfd;
+ char *error = NULL;
+ size_t i;
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEBASEDIR);
+ textdomain (PACKAGE);
+
+ /* Set global program name that is not polluted with libtool artifacts. */
+ set_program_name (argv[0]);
+
+ for (;;) {
+ c = getopt_long (argc, argv, options, long_options, &option_index);
+ if (c == -1) break;
+
+ switch (c) {
+ case 0: /* options which are long only */
+ if (STREQ (long_options[option_index].name, "fd")) {
+ if (sscanf (optarg, "%d", &fd) != 1 || fd < 0) {
+ fprintf (stderr, _("%s: cannot parse fd option '%s'\n"),
+ program_name, optarg);
+ exit (EXIT_FAILURE);
+ }
+ } else {
+ fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
+ program_name, long_options[option_index].name, option_index);
+ exit (EXIT_FAILURE);
+ }
+ break;
+
+ case 'V':
+ printf ("guestmount-cleanup %s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+ exit (EXIT_SUCCESS);
+
+ case HELP_OPTION:
+ usage (EXIT_SUCCESS);
+
+ default:
+ usage (EXIT_FAILURE);
+ }
+ }
+
+ /* We'd better have a mountpoint. */
+ if (optind+1 != argc) {
+ fprintf (stderr,
+ _("%s: you must specify a mountpoint in the host filesystem\n"),
+ program_name);
+ exit (EXIT_FAILURE);
+ }
+
+ mountpoint = argv[optind];
+
+ /* Monitor the pipe until we get POLLHUP. */
+ if (fd >= 0) {
+ ignore_value (chdir ("/"));
+
+ /* Ignore keyboard signals. */
+ memset (&sa, 0, sizeof sa);
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = SA_RESTART;
+ sigaction (SIGINT, &sa, NULL);
+ sigaction (SIGQUIT, &sa, NULL);
+
+ while (1) {
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
+ if (poll (&pollfd, 1, -1) == -1) {
+ if (errno != EAGAIN && errno != EINTR) {
+ perror ("poll");
+ exit (EXIT_FAILURE);
+ }
+ }
+ else {
+ if ((pollfd.revents & POLLHUP) != 0)
+ break;
+ }
+ }
+ }
+
+ /* Unmount the filesystem. We may have to try a few times. */
+ for (i = 0; i <= 5; ++i) {
+ if (i > 0)
+ sleep (1 << (i-1));
+
+ free (error);
+ error = NULL;
+
+ if (do_fusermount (mountpoint, &error) == 0)
+ goto done;
+ }
+
+ fprintf (stderr, _("%s: failed to unmount %s: %s\n"),
+ program_name, mountpoint, error);
+ free (error);
+
+ do_fuser (mountpoint);
+
+ exit (EXIT_FAILURE);
+
+ done:
+ exit (EXIT_SUCCESS);
+}
+
+static int
+do_fusermount (const char *mountpoint, char **error_rtn)
+{
+ int fd[2];
+ pid_t pid;
+ int r;
+ char *buf = NULL;
+ size_t allocsize = 0, len = 0;
+
+ if (pipe (fd) == -1) {
+ perror ("pipe");
+ exit (EXIT_FAILURE);
+ }
+
+ pid = fork ();
+ if (pid == -1) {
+ perror ("fork");
+ exit (EXIT_FAILURE);
+ }
+
+ if (pid == 0) { /* Child - run fusermount. */
+ close (fd[0]);
+ dup2 (fd[1], 1);
+ dup2 (fd[1], 2);
+ close (fd[1]);
+
+ execlp ("fusermount", "fusermount", "-u", mountpoint,
NULL);
+ perror ("exec");
+ _exit (EXIT_FAILURE);
+ }
+
+ /* Parent - read from the pipe any errors etc. */
+ close (fd[1]);
+
+ while (1) {
+ if (len >= allocsize) {
+ allocsize += 256;
+ buf = realloc (buf, allocsize);
+ if (buf == NULL) {
+ perror ("realloc");
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ /* Leave space in the buffer for a terminating \0 character. */
+ r = read (fd[0], &buf[len], allocsize - len - 1);
+ if (r == -1) {
+ perror ("read");
+ exit (EXIT_FAILURE);
+ }
+
+ if (r == 0)
+ break;
+
+ len += r;
+ }
+
+ if (close (fd[0]) == -1) {
+ perror ("close");
+ exit (EXIT_FAILURE);
+ }
+
+ if (buf) {
+ /* Remove any trailing \n from the error message. */
+ while (len > 0 && buf[len-1] == '\n') {
+ buf[len-1] = '\0';
+ len--;
+ }
+
+ /* Make sure the error message is \0 terminated. */
+ if (len < allocsize)
+ buf[len] = '\0';
+ }
+
+ if (waitpid (pid, &r, 0) == -1) {
+ perror ("waitpid");
+ exit (EXIT_FAILURE);
+ }
+
+ if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
+ *error_rtn = buf;
+ return 1; /* fusermount or exec failed */
+ }
+
+ free (buf);
+ return 0; /* fusermount successful */
+}
+
+/* Try running 'fuser' on the mountpoint. This is for information
+ * only so don't fail if we can't run it.
+ */
+static void
+do_fuser (const char *mountpoint)
+{
+ pid_t pid;
+
+ pid = fork ();
+ if (pid == -1) {
+ perror ("fork");
+ exit (EXIT_FAILURE);
+ }
+
+ if (pid == 0) { /* Child - run /sbin/fuser. */
+ execlp ("/sbin/fuser", "fuser", "-v", "-m",
mountpoint, NULL);
+ _exit (EXIT_FAILURE);
+ }
+
+ waitpid (pid, NULL, 0);
+}
diff --git a/fuse/guestmount-cleanup.pod b/fuse/guestmount-cleanup.pod
new file mode 100644
index 0000000..988b5f3
--- /dev/null
+++ b/fuse/guestmount-cleanup.pod
@@ -0,0 +1,103 @@
+=encoding utf8
+
+=head1 NAME
+
+guestmount-cleanup - Clean up a mounted filesystem
+
+=head1 SYNOPSIS
+
+ guestmount-cleanup mountpoint
+
+ guestmount-cleanup --fd=<FD> mountpoint
+
+=head1 DESCRIPTION
+
+guestmount-cleanup is a utility to clean up mounted filesystems
+automatically. This program is used alongside L<guestmount(1)> to
+unmount the filesystem when a program or script using that filesystem
+exits.
+
+There are two ways to use guestmount-cleanup. When called as:
+
+ guestmount-cleanup mountpoint
+
+it unmounts C<mountpoint> immediately.
+
+When called as:
+
+ guestmount-cleanup --fd=FD mountpoint
+
+it waits until the pipe C<FD> is closed. This can be used to monitor
+another process and clean up its mountpoint when that process exits,
+as described below.
+
+=head2 FROM PROGRAMS OR SCRIPTING LANGUAGES
+
+In the program, create a pipe (eg. by calling L<pipe(2)>). Let C<FD>
+be the file descriptor number of the read side of the pipe
+(ie. C<pipefd[0]>).
+
+After mounting the filesystem with L<guestmount(1)> (on
+C<mountpoint>), fork and run guestmount-cleanup like this:
+
+ guestmount-cleanup --fd=FD mountpoint
+
+Close the read side of the pipe in the parent process.
+
+Now, when the write side of the pipe (ie. C<pipefd[1]>) is closed for
+any reason, either explicitly or because the parent process
+exits, guestmount-cleanup notices and unmounts the mountpoint
+(by calling L<fusermount(1)>).
+
+If your operating system supports it, you should set the C<FD_CLOEXEC>
+flag on the write side of the pipe.
+
+=head2 FROM SHELL SCRIPTS
+
+Since bash doesn't provide a way to create an unnamed pipe, use a
+regular trap to call guestmount-cleanup like this:
+
+ trap "guestmount-cleanup mountpoint" INT TERM QUIT EXIT
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--fd=FD>
+
+Specify the pipe file descriptor to monitor, and delay cleanup until
+that pipe is closed.
+
+=item B<--help>
+
+Display brief help and exit.
+
+=item B<-V>
+
+=item B<--version>
+
+Display the program version and exit.
+
+=back
+
+=head1 EXIT STATUS
+
+This program returns 0 if successful, or non-zero if there was an
+error.
+
+=head1 SEE ALSO
+
+L<guestmount(1)>,
+L<fusermount(1)>,
+L<pipe(2)>,
+L<guestfs(3)/MOUNT LOCAL>,
+L<http://libguestfs.org/>,
+L<http://fuse.sf.net/>.
+
+=head1 AUTHORS
+
+Richard W.M. Jones (C<rjones at redhat dot com>)
+
+=head1 COPYRIGHT
+
+Copyright (C) 2013 Red Hat Inc.
diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod
index eb32684..77c97b4 100644
--- a/fuse/guestmount.pod
+++ b/fuse/guestmount.pod
@@ -397,6 +397,7 @@ error.
=head1 SEE ALSO
+L<guestmount-cleanup(1)>,
L<guestfish(1)>,
L<virt-inspector(1)>,
L<virt-cat(1)>,
diff --git a/fuse/test-fuse-umount-race.sh b/fuse/test-fuse-umount-race.sh
index 59186ab..8a7b1a4 100755
--- a/fuse/test-fuse-umount-race.sh
+++ b/fuse/test-fuse-umount-race.sh
@@ -48,15 +48,8 @@ pid="$(cat test.pid)"
timeout=10
-count=$timeout
-while ! fusermount -u mp && [ $count -gt 0 ]; do
- sleep 1
- ((count--))
-done
-if [ $count -eq 0 ]; then
- echo "$0: fusermount failed after $timeout seconds"
- exit 1
-fi
+# Unmount the mountpoint.
+./guestmount-cleanup mp
# Wait for guestmount to exit.
count=$timeout
diff --git a/fuse/test-fuse.sh b/fuse/test-fuse.sh
index bd0c096..e2fe71a 100755
--- a/fuse/test-fuse.sh
+++ b/fuse/test-fuse.sh
@@ -49,18 +49,24 @@ top_builddir=$(cd "$top_builddir" > /dev/null; pwd)
# Paths to the other programs and files. NB: Must be absolute paths.
guestfish="$top_builddir/fish/guestfish"
guestmount="$top_builddir/fuse/guestmount"
+guestmount_cleanup="$top_builddir/fuse/guestmount-cleanup"
image="$top_builddir/fuse/test.img"
mp="$top_builddir/fuse/test-mp"
-if [ ! -x "$guestfish" -o ! -x "$guestmount" ]; then
- echo "$0: error: guestfish or guestmount are not available"
+if [ ! -x "$guestfish" -o ! -x "$guestmount" -o ! -x
"$guestmount_cleanup" ]
+then
+ echo "$0: error: guestfish, guestmount or guestmount-cleanup are not
available"
exit 1
fi
-# Ensure everything is cleaned up on exit.
+# Ensure the mountpoint directory exists and is not being used.
rm -f "$image"
mkdir -p "$mp"
fusermount -u "$mp" >/dev/null 2>&1 ||:
+
+# Ensure everything is cleaned up on exit.
+mounted=
+
function cleanup ()
{
status=$?
@@ -75,15 +81,9 @@ function cleanup ()
# Who's using this? Should be no one, but see below.
if [ -x /sbin/fuser ]; then /sbin/fuser "$mp"; fi
- # If you run this and you have GNOME running at the same time,
- # then randomly /usr/libexec/gvfs-gdu-volume-monitor will decide
- # to do whatever it does in the mountpoint directory, preventing
- # you from unmounting it! Hence the need for this loop.
- count=10
- while ! fusermount -u "$mp" && [ $count -gt 0 ]; do
- sleep 1
- ((count--))
- done
+ if [ -n "$mounted" ]; then
+ $guestmount_cleanup "$mp"
+ fi
rm -f "$image"
rm -rf "$mp"
@@ -121,6 +121,7 @@ $guestmount \
-o uid="$(id -u)" -o gid="$(id -g)" "$mp"
# To debug guestmount, add this to the end of the preceding command:
# -v -x & sleep 60
+mounted=yes
stage Changing into mounted directory
cd "$mp"
diff --git a/ocaml/t/guestfs_500_mount_local.ml b/ocaml/t/guestfs_500_mount_local.ml
index 3047544..c1d7bdd 100644
--- a/ocaml/t/guestfs_500_mount_local.ml
+++ b/ocaml/t/guestfs_500_mount_local.ml
@@ -142,40 +142,9 @@ and test_mountpoint mp =
done;
if debug then eprintf "%s > unmounting filesystem\n%!" mp;
-
- unmount mp
-
-(* We may need to retry this a few times because of processes which
- * run in the background jumping into mountpoints. Only display
- * errors if it still fails after many retries.
- *)
-and unmount mp =
- let logfile = sprintf "%s.fusermount.log" mp in
- let unlink_logfile () =
- try unlink logfile with Unix_error _ -> ()
- in
- unlink_logfile ();
-
- let run_command () =
- Sys.command (sprintf "fusermount -u %s >> %s 2>&1"
- (Filename.quote mp) (Filename.quote logfile)) = 0
- in
-
- let rec loop tries =
- if tries <= 5 then (
- if not (run_command ()) then (
- sleep 1;
- loop (tries+1)
- )
- ) else (
- ignore (Sys.command (sprintf "cat %s" (Filename.quote logfile)));
- eprintf "fusermount: %s: failed, see earlier error messages\n" mp;
- exit 1
- )
- in
- loop 0;
-
- unlink_logfile ()
+ ignore (
+ Sys.command (sprintf "../fuse/guestmount-cleanup %s" (Filename.quote mp))
+ )
let () =
match Array.to_list Sys.argv with
diff --git a/po-docs/ja/Makefile.am b/po-docs/ja/Makefile.am
index d3413ec..b18189b 100644
--- a/po-docs/ja/Makefile.am
+++ b/po-docs/ja/Makefile.am
@@ -41,6 +41,7 @@ MANPAGES = \
guestfs-testing.1 \
guestfsd.8 \
guestmount.1 \
+ guestmount-cleanup.1 \
libguestfs-make-fixed-appliance.1 \
libguestfs-test-tool.1 \
virt-alignment-scan.1 \
diff --git a/po-docs/podfiles b/po-docs/podfiles
index 74f722d..47f5e78 100644
--- a/po-docs/podfiles
+++ b/po-docs/podfiles
@@ -20,6 +20,7 @@
../fish/virt-tar-in.pod
../fish/virt-tar-out.pod
../format/virt-format.pod
+../fuse/guestmount-cleanup.pod
../fuse/guestmount.pod
../guestfs-release-notes.pod
../inspector/virt-inspector.pod
diff --git a/po-docs/uk/Makefile.am b/po-docs/uk/Makefile.am
index d3413ec..b18189b 100644
--- a/po-docs/uk/Makefile.am
+++ b/po-docs/uk/Makefile.am
@@ -41,6 +41,7 @@ MANPAGES = \
guestfs-testing.1 \
guestfsd.8 \
guestmount.1 \
+ guestmount-cleanup.1 \
libguestfs-make-fixed-appliance.1 \
libguestfs-test-tool.1 \
virt-alignment-scan.1 \
diff --git a/po/POTFILES b/po/POTFILES
index d746354..0fde83d 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -143,6 +143,7 @@ fish/supported.c
fish/tilde.c
fish/time.c
format/format.c
+fuse/guestmount-cleanup.c
fuse/guestmount.c
gobject/src/optargs-add_domain.c
gobject/src/optargs-add_drive.c
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
index e16a19d..de49d86 100644
--- a/sysprep/Makefile.am
+++ b/sysprep/Makefile.am
@@ -155,6 +155,7 @@ sysprep-operations.pod: virt-sysprep
TESTS_ENVIRONMENT = \
abs_builddir=$(abs_builddir) \
abs_srcdir=$(abs_srcdir) \
+ PATH=$(abs_top_builddir)/fuse:$(PATH) \
$(top_builddir)/run --test
if ENABLE_APPLIANCE
diff --git a/sysprep/sysprep_operation_script.ml b/sysprep/sysprep_operation_script.ml
index a49bc3c..c11103d 100644
--- a/sysprep/sysprep_operation_script.ml
+++ b/sysprep/sysprep_operation_script.ml
@@ -77,7 +77,7 @@ let rec script_perform (g : Guestfs.guestfs) root =
[]
(* Run the scripts in the background and make sure they call
- * fusermount afterwards.
+ * guestmount-cleanup afterwards.
*)
and run_scripts mp scripts =
let sh = "/bin/bash" in
@@ -89,19 +89,11 @@ cleanup ()
{
status=$?
cd /
- count=10
- while ! fusermount -u %s >/dev/null 2>&1 && [ $count -gt 0 ]; do
- sleep 1
- ((count--))
- done
- if [ $count -eq 0 ]; then
- echo \"fusermount: failed to unmount directory\" %s >&2
- exit 1
- fi
+ guestmount-cleanup %s ||:
exit $status
}
trap cleanup INT TERM QUIT EXIT ERR\n"
- (Filename.quote mp) (Filename.quote mp) ^
+ (Filename.quote mp) ^
String.concat "\n" scripts in
let args = [| sh; "-c"; cmd |] in
diff --git a/tests/selinux/run-test.pl b/tests/selinux/run-test.pl
index 5258bb1..1cdeb05 100755
--- a/tests/selinux/run-test.pl
+++ b/tests/selinux/run-test.pl
@@ -175,28 +175,11 @@ sub run_fuse_tests
}
# Unmount the test directory.
- unmount ($mpdir);
-
- exit ($errors == 0 ? 0 : 1);
-}
-
-# Unmount the FUSE directory. We may need to retry this a few times.
-sub unmount
-{
- my $mpdir = shift;
- my $retries = 5;
-
- while ($retries > 0) {
- if (system ("fusermount", "-u", $mpdir) == 0) {
- last;
- }
- sleep 1;
- $retries--;
- }
-
- if ($retries == 0) {
+ if (system ("../../fuse/guestmount-cleanup", $mpdir) != 0) {
die "failed to unmount FUSE directory\n";
}
+
+ exit ($errors == 0 ? 0 : 1);
}
# Test extended attributes, using the libguestfs API directly.
--
1.8.1.2