Beispiel #1
0
/* 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);
}
Beispiel #3
0
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);
}