diff --git a/.gitignore b/.gitignore index 16eae54ea..1b9ce8977 100644 --- a/.gitignore +++ b/.gitignore @@ -181,6 +181,7 @@ Makefile.in /fuse/guestunmount.1 /fuse/stamp-guestmount.pod /fuse/stamp-guestunmount.pod +/fuse/test-guestmount-fd /fuse/test-guestunmount-fd /generator/.depend /generator/files-generated.txt diff --git a/fuse/Makefile.am b/fuse/Makefile.am index 3fd64a2ba..028633879 100644 --- a/fuse/Makefile.am +++ b/fuse/Makefile.am @@ -132,14 +132,32 @@ TESTS = \ if ENABLE_APPLIANCE TESTS += \ test-fuse.sh \ - test-fuse-umount-race.sh + test-fuse-umount-race.sh \ + test-guestmount-fd endif ENABLE_APPLIANCE TESTS_ENVIRONMENT = \ top_builddir=.. \ $(top_builddir)/run --test -check_PROGRAMS = test-guestunmount-fd +check_PROGRAMS = test-guestmount-fd test-guestunmount-fd + +test_guestmount_fd_SOURCES = \ + test-guestmount-fd.c + +test_guestmount_fd_CPPFLAGS = \ + -I$(top_srcdir)/src -I$(top_builddir)/src \ + -I$(srcdir)/../gnulib/lib -I../gnulib/lib + +test_guestmount_fd_CFLAGS = \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) + +test_guestmount_fd_LDADD = \ + $(top_builddir)/src/libutils.la \ + $(top_builddir)/src/libguestfs.la \ + $(LIBXML2_LIBS) \ + $(LIBVIRT_LIBS) \ + ../gnulib/lib/libgnu.la test_guestunmount_fd_SOURCES = \ test-guestunmount-fd.c diff --git a/fuse/test-guestmount-fd.c b/fuse/test-guestmount-fd.c new file mode 100644 index 000000000..c14309328 --- /dev/null +++ b/fuse/test-guestmount-fd.c @@ -0,0 +1,162 @@ +/* Test guestmount --fd option. + * Copyright (C) 2014 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ignore-value.h" + +#include "guestfs.h" +#include "guestfs-internal-frontend.h" + +#define GUESTMOUNT_BINARY "./guestmount" +#define GUESTUNMOUNT_BINARY "./guestunmount" +#define TEST_IMAGE "../tests/guests/fedora.img" +#define MOUNTPOINT "test-guestmount-fd.d" +#define TEST_FILE MOUNTPOINT "/etc/fstab" + +int +main (int argc, char *argv[]) +{ + char *skip; + int pipefd[2]; + pid_t pid; + char c; + int r, status; + + /* Allow the test to be skipped. */ + skip = getenv ("SKIP_TEST_GUESTMOUNT_FD"); + if (skip && STREQ (skip, "1")) { + fprintf (stderr, "%s: test skipped because environment variable set.\n", + program_name); + exit (77); + } + + /* Skip the test if the test image can't be found. */ + if (access (TEST_IMAGE, R_OK) == -1) { + perror (TEST_IMAGE); + exit (77); + } + + /* Create the pipe. */ + if (pipe (pipefd) == -1) { + perror ("pipe"); + exit (EXIT_FAILURE); + } + + /* Create the mount point. */ + ignore_value (rmdir (MOUNTPOINT)); + if (mkdir (MOUNTPOINT, 0700) == -1) { + perror ("mkdir: " MOUNTPOINT); + exit (EXIT_FAILURE); + } + + /* Create the guestmount subprocess. */ + pid = fork (); + if (pid == -1) { + perror ("fork"); + exit (EXIT_FAILURE); + } + + if (pid == 0) { /* child - guestmount */ + char fd_str[64]; + + close (pipefd[0]); + + snprintf (fd_str, sizeof fd_str, "%d", pipefd[1]); + + execlp (GUESTMOUNT_BINARY, + "guestmount", + "--fd", fd_str, "--no-fork", + "--ro", "-a", TEST_IMAGE, "-i", MOUNTPOINT, NULL); + perror ("execlp"); + _exit (EXIT_FAILURE); + } + + /* Parent continues. */ + close (pipefd[1]); + + /* Wait for guestmount to start up. */ + r = read (pipefd[0], &c, 1); + if (r == -1) { + perror ("read (pipefd)"); + ignore_value (rmdir (MOUNTPOINT)); + exit (EXIT_FAILURE); + } + if (r == 0) { + fprintf (stderr, "%s: unexpected end of file on pipe fd.\n", + program_name); + ignore_value (rmdir (MOUNTPOINT)); + exit (EXIT_FAILURE); + } + + /* Check that the test image was mounted. */ + if (access (TEST_FILE, R_OK) == -1) { + fprintf (stderr, "%s: test failed because test image is not mounted and ready.", + program_name); + ignore_value (rmdir (MOUNTPOINT)); + exit (EXIT_FAILURE); + } + + /* Unmount it. */ + r = system (GUESTUNMOUNT_BINARY " " MOUNTPOINT); + if (r != 0) { + char status_string[80]; + + fprintf (stderr, "%s: test failed: %s\n", program_name, + guestfs___exit_status_to_string (r, GUESTUNMOUNT_BINARY, + status_string, + sizeof status_string)); + ignore_value (rmdir (MOUNTPOINT)); + exit (EXIT_FAILURE); + } + + close (pipefd[0]); + + /* Wait for guestmount to exit, and check it exits cleanly. */ + r = waitpid (pid, &status, 0); + if (r == -1) { + perror ("waitpid"); + ignore_value (rmdir (MOUNTPOINT)); + exit (EXIT_FAILURE); + } + if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { + char status_string[80]; + + fprintf (stderr, "%s: test failed: %s\n", + program_name, + guestfs___exit_status_to_string (status, GUESTMOUNT_BINARY, + status_string, + sizeof status_string)); + ignore_value (rmdir (MOUNTPOINT)); + exit (EXIT_FAILURE); + } + + ignore_value (rmdir (MOUNTPOINT)); + + exit (EXIT_SUCCESS); +} diff --git a/po/POTFILES b/po/POTFILES index 7d4a0c88d..33d2a947a 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -162,6 +162,7 @@ fish/uri.c format/format.c fuse/guestmount.c fuse/guestunmount.c +fuse/test-guestmount-fd.c fuse/test-guestunmount-fd.c gobject/src/optargs-add_domain.c gobject/src/optargs-add_drive.c