/* This is a convenience function, but we might consider exporting * it as an API in future. */ int guestfs_int_get_backend_setting_bool (guestfs_h *g, const char *name) { CLEANUP_FREE char *value = NULL; int b; guestfs_push_error_handler (g, NULL, NULL); value = guestfs_get_backend_setting (g, name); guestfs_pop_error_handler (g); if (value == NULL && guestfs_last_errno (g) == ESRCH) return 0; if (value == NULL) return -1; b = guestfs_int_is_true (value); if (b == -1) return -1; return b; }
int main (int argc, char *argv[]) { char *skip; int pipefd[2]; pid_t pid; int r, status; /* Allow the test to be skipped. */ skip = getenv ("SKIP_TEST_FUSE_SH"); if (skip && guestfs_int_is_true (skip) > 0) error (77, 0, "test skipped because environment variable set"); skip = getenv ("SKIP_TEST_GUESTUNMOUNT_FD"); if (skip && guestfs_int_is_true (skip) > 0) error (77, 0, "test skipped because environment variable set"); /* Create the pipe. */ if (pipe (pipefd) == -1) error (EXIT_FAILURE, errno, "pipe"); /* Create the guestunmount subprocess. */ pid = fork (); if (pid == -1) error (EXIT_FAILURE, errno, "fork"); if (pid == 0) { /* child - guestunmount */ char fd_str[64]; close (pipefd[1]); snprintf (fd_str, sizeof fd_str, "%d", pipefd[0]); execlp ("guestunmount", "guestunmount", "--fd", fd_str, "/", NULL); perror ("execlp"); _exit (EXIT_FAILURE); } /* Parent continues. */ close (pipefd[0]); ignore_value (fcntl (pipefd[1], F_SETFD, FD_CLOEXEC)); /* Sleep a bit and test that the guestunmount process is still running. */ sleep (2); r = waitpid (pid, &status, WNOHANG); if (r == -1) error (EXIT_FAILURE, errno, "waitpid"); if (r != 0) { char status_string[80]; error (EXIT_FAILURE, 0, "test failed: %s", guestfs_int_exit_status_to_string (r, "guestunmount", status_string, sizeof status_string)); } /* Close the write side of the pipe. This should cause guestunmount * to exit. It should exit with status code _3_ because we gave it * a directory which isn't a FUSE mountpoint. */ close (pipefd[1]); r = waitpid (pid, &status, 0); if (r == -1) error (EXIT_FAILURE, errno, "waitpid"); if (!WIFEXITED (status) || WEXITSTATUS (status) != 3) { char status_string[80]; error (EXIT_FAILURE, 0, "test failed: guestunmount didn't return status code 3; %s", guestfs_int_exit_status_to_string (status, "guestunmount", status_string, sizeof status_string)); } exit (EXIT_SUCCESS); }
static int parse_environment (guestfs_h *g, char *(*do_getenv) (const void *data, const char *), const void *data) { int memsize, b; char *str; /* Don't bother checking the return values of functions * that cannot return errors. */ str = do_getenv (data, "LIBGUESTFS_TRACE"); if (str) { b = guestfs_int_is_true (str); if (b == -1) { error (g, _("%s=%s: non-boolean value"), "LIBGUESTFS_TRACE", str); return -1; } guestfs_set_trace (g, b); } str = do_getenv (data, "LIBGUESTFS_DEBUG"); if (str) { b = guestfs_int_is_true (str); if (b == -1) { error (g, _("%s=%s: non-boolean value"), "LIBGUESTFS_TRACE", str); return -1; } guestfs_set_verbose (g, b); } str = do_getenv (data, "LIBGUESTFS_TMPDIR"); if (str && STRNEQ (str, "")) { if (guestfs_set_tmpdir (g, str) == -1) return -1; } str = do_getenv (data, "LIBGUESTFS_CACHEDIR"); if (str && STRNEQ (str, "")) { if (guestfs_set_cachedir (g, str) == -1) return -1; } str = do_getenv (data, "TMPDIR"); if (guestfs_int_set_env_tmpdir (g, str) == -1) return -1; str = do_getenv (data, "LIBGUESTFS_PATH"); if (str && STRNEQ (str, "")) guestfs_set_path (g, str); str = do_getenv (data, "LIBGUESTFS_HV"); if (str && STRNEQ (str, "")) guestfs_set_hv (g, str); else { str = do_getenv (data, "LIBGUESTFS_QEMU"); if (str && STRNEQ (str, "")) guestfs_set_hv (g, str); } str = do_getenv (data, "LIBGUESTFS_APPEND"); if (str) guestfs_set_append (g, str); str = do_getenv (data, "LIBGUESTFS_MEMSIZE"); if (str && STRNEQ (str, "")) { if (sscanf (str, "%d", &memsize) != 1) { error (g, _("non-numeric value for LIBGUESTFS_MEMSIZE")); return -1; } if (guestfs_set_memsize (g, memsize) == -1) { /* set_memsize produces an error message already. */ return -1; } } str = do_getenv (data, "LIBGUESTFS_BACKEND"); if (str && STRNEQ (str, "")) { if (guestfs_set_backend (g, str) == -1) return -1; } else { str = do_getenv (data, "LIBGUESTFS_ATTACH_METHOD"); if (str && STRNEQ (str, "")) { if (guestfs_set_backend (g, str) == -1) return -1; } } str = do_getenv (data, "LIBGUESTFS_BACKEND_SETTINGS"); if (str) { CLEANUP_FREE_STRING_LIST char **settings = guestfs_int_split_string (':', str); if (settings == NULL) { perrorf (g, "split_string: malloc"); return -1; } if (guestfs_set_backend_settings (g, settings) == -1) return -1; } return 0; }
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_FUSE_SH"); if (skip && guestfs_int_is_true (skip) > 0) error (77, 0, "test skipped because environment variable set"); skip = getenv ("SKIP_TEST_GUESTMOUNT_FD"); if (skip && guestfs_int_is_true (skip) > 0) error (77, 0, "test skipped because environment variable set"); /* Skip the test if the test image can't be found. */ if (access (TEST_IMAGE, R_OK) == -1) error (77, errno, "access: %s", TEST_IMAGE); /* Skip the test if /dev/fuse is not writable, because guestmount * will fail. */ if (access ("/dev/fuse", W_OK) == -1) error (77, errno, "access: %s", "/dev/fuse"); /* Create the pipe. */ if (pipe (pipefd) == -1) error (EXIT_FAILURE, errno, "pipe"); /* Create the mount point. */ ignore_value (rmdir (MOUNTPOINT)); if (mkdir (MOUNTPOINT, 0700) == -1) error (EXIT_FAILURE, errno, "mkdir: %s", MOUNTPOINT); /* Create the guestmount subprocess. */ pid = fork (); if (pid == -1) error (EXIT_FAILURE, errno, "fork"); 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", getprogname ()); 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.", getprogname ()); 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", getprogname (), guestfs_int_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", getprogname (), guestfs_int_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); }