示例#1
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  int r, default_memsize;

  /* What's the default memsize? */
  g = guestfs_create ();
  if (!g) error (EXIT_FAILURE, errno, "guestfs_create");
  default_memsize = guestfs_get_memsize (g);
  if (default_memsize == -1) exit (EXIT_FAILURE);
  guestfs_close (g);

  /* Check that guestfs_create parses the environment. */
  setenv ("LIBGUESTFS_MEMSIZE", "799", 1);
  g = guestfs_create ();
  if (!g) error (EXIT_FAILURE, errno, "guestfs_create");
  assert (guestfs_get_memsize (g) == 799);
  guestfs_close (g);

  /* Check that guestfs_create_flags with no flags parses the environment. */
  setenv ("LIBGUESTFS_MEMSIZE", "798", 1);
  g = guestfs_create_flags (0);
  if (!g) error (EXIT_FAILURE, errno, "guestfs_create_flags");
  assert (guestfs_get_memsize (g) == 798);
  guestfs_close (g);

  /* Check guestfs_create_flags + explicit guestfs_parse_environment. */
  setenv ("LIBGUESTFS_MEMSIZE", "797", 1);
  g = guestfs_create_flags (GUESTFS_CREATE_NO_ENVIRONMENT);
  assert (guestfs_get_memsize (g) == default_memsize);
  if (!g) error (EXIT_FAILURE, errno, "guestfs_create_flags");
  setenv ("LIBGUESTFS_MEMSIZE", "796", 1);
  r = guestfs_parse_environment (g);
  if (r == -1) exit (EXIT_FAILURE);
  assert (guestfs_get_memsize (g) == 796);
  guestfs_close (g);

  /* Check guestfs_parse_environment_list. */
  setenv ("LIBGUESTFS_MEMSIZE", "795", 1);
  g = guestfs_create_flags (GUESTFS_CREATE_NO_ENVIRONMENT);
  assert (guestfs_get_memsize (g) == default_memsize);
  if (!g) error (EXIT_FAILURE, errno, "guestfs_create_flags");
  setenv ("LIBGUESTFS_MEMSIZE", "794", 1);
  const char *local_environment[] = {
    "LIBGUESTFS_MEMSIZE=793",
    "LIBGUESTFS_MEMSIZE_NOT_REALLY_A_VARIABLE=1",
    "FOO=bar",
    "HOME=/homes",
    "BLAH",
    NULL
  };
  r = guestfs_parse_environment_list (g, (char **) local_environment);
  if (r == -1) exit (EXIT_FAILURE);
  assert (guestfs_get_memsize (g) == 793);
  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
示例#2
0
int
main (int argc, char *argv[])
{
    pthread_t thread[NR_THREADS];
    int data[NR_THREADS];
    int i, r, errors;
    guestfs_h *g;
    char *backend;

    /* Test is only meaningful if the backend "direct" is used. */
    g = guestfs_create ();
    if (!g)
        error (EXIT_FAILURE, errno, "guestfs_create");
    backend = guestfs_get_backend (g);
    if (backend == NULL) {
        guestfs_close (g);
        exit (EXIT_FAILURE);
    }
    if (STRNEQ (backend, "direct")) {
        fprintf (stderr, "%s: test skipped because backend isn't 'direct'.\n",
                 guestfs_int_program_name);
        free (backend);
        guestfs_close (g);
        exit (77);
    }
    free (backend);
    guestfs_close (g);

    /* Ensure error messages are not translated. */
    setenv ("LC_ALL", "C", 1);

    pthread_barrier_init (&barrier, NULL, NR_THREADS);

    /* Create the other threads which will set up their own libguestfs
     * handle then wait at a barrier before launching.
     */
    for (i = 0; i < NR_THREADS; ++i) {
        data[i] = i;
        r = pthread_create (&thread[i], NULL, start_thread, &data[i]);
        if (r != 0)
            error (EXIT_FAILURE, r, "pthread_create");
    }

    /* Wait for the threads to exit. */
    errors = 0;

    for (i = 0; i < NR_THREADS; ++i) {
        int *ret;

        r = pthread_join (thread[i], (void **) &ret);
        if (r != 0)
            error (EXIT_FAILURE, r, "pthread_join");
        if (*ret == -1)
            errors++;
    }

    exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
示例#3
0
static void
run_test (void)
{
  guestfs_h *g;
  size_t i;

  printf ("Warming up the libguestfs cache ...\n");
  for (i = 0; i < NR_WARMUP_PASSES; ++i) {
    g = create_handle ();
    add_drive (g);
    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);
    guestfs_close (g);
  }

  printf ("Running the tests in %d passes ...\n", NR_TEST_PASSES);
  for (i = 0; i < NR_TEST_PASSES; ++i) {
    g = create_handle ();
    set_up_event_handlers (g, i);
    start_libvirt_thread (i);
    add_drive (g);
    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);
    guestfs_close (g);
    stop_libvirt_thread ();

    printf ("    pass %zu: %zu events collected in %" PRIi64 " ns\n",
            i+1, pass_data[i].nr_events, pass_data[i].elapsed_ns);
  }

  if (verbose)
    dump_pass_data ();

  printf ("Analyzing the results ...\n");
  check_pass_data ();
  construct_timeline ();
  analyze_timeline ();

  if (verbose)
    dump_timeline ();

  printf ("\n");
  g = create_handle ();
  test_info (g, NR_TEST_PASSES);
  guestfs_close (g);
  printf ("\n");
  print_analysis ();
  printf ("\n");
  printf ("Longest activities:\n");
  printf ("\n");
  print_longest_to_shortest ();

  free_pass_data ();
  free_final_timeline ();
}
示例#4
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  int r;

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, errno, "guestfs_create");

  /* If these fail, the default error handler will print an error
   * message to stderr, so we don't need to print anything.  This code
   * is very pedantic, but after all we are testing the details of the
   * C API.
   */

  if (guestfs_set_verbose (g, 1) == -1)
    exit (EXIT_FAILURE);
  r = guestfs_get_verbose (g);
  if (r == -1)
    exit (EXIT_FAILURE);
  if (!r)
    error (EXIT_FAILURE, 0, "set_verbose not true");
  if (guestfs_set_verbose (g, 0) == -1)
    exit (EXIT_FAILURE);
  r = guestfs_get_verbose (g);
  if (r == -1)
    exit (EXIT_FAILURE);
  if (r)
    error (EXIT_FAILURE, 0, "set_verbose not false");

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
示例#5
0
JNIEXPORT void JNICALL
Java_com_redhat_et_libguestfs_GuestFS__1close
  (JNIEnv *env, jobject obj, jlong jg)
{
  guestfs_h *g = (guestfs_h *) (long) jg;
  size_t len;
  struct callback_data **data;

  /* There is a nasty, difficult to solve case here where the
   * user deletes events in one of the callbacks that we are
   * about to invoke, resulting in a double-free.  XXX
   */
  data = get_all_event_callbacks (env, g, &len);

  guestfs_close (g);

  if (len > 0) {
    size_t i;
    for (i = 0; i < len; ++i) {
      (*env)->DeleteGlobalRef (env, data[i]->callback);
      free (data[i]);
    }
    free (data);
  }
}
示例#6
0
static void
usage (int exitcode)
{
  guestfs_h *g;
  int default_memsize = -1;

  g = guestfs_create ();
  if (g) {
    default_memsize = guestfs_get_memsize (g);
    guestfs_close (g);
  }

  fprintf (stderr,
           "boot-analysis: Trace and analyze the appliance boot process.\n"
           "Usage:\n"
           "  boot-analysis [--options]\n"
           "Options:\n"
           "  --help         Display this usage text and exit.\n"
           "  --append OPTS  Append OPTS to kernel command line.\n"
           "  --colour       Output colours, even if not a terminal.\n"
           "  -m MB\n"
           "  --memsize MB   Set memory size in MB (default: %d).\n"
           "  --smp N        Enable N virtual CPUs (default: 1).\n"
           "  -v|--verbose   Verbose output, useful for debugging.\n",
           default_memsize);
  exit (exitcode);
}
示例#7
0
static void
test_stringsbuf (void)
{
  guestfs_h *g;
  DECLARE_STRINGSBUF (sb);

  g = guestfs_create ();
  assert (g);

  guestfs_int_add_string (g, &sb, "aaa");
  guestfs_int_add_string (g, &sb, "bbb");
  guestfs_int_add_string (g, &sb, "ccc");
  guestfs_int_add_string (g, &sb, "");
  guestfs_int_end_stringsbuf (g, &sb);

  assert (sb.size == 5 /* 4 strings + terminating NULL */);
  assert (STREQ (sb.argv[0], "aaa"));
  assert (STREQ (sb.argv[1], "bbb"));
  assert (STREQ (sb.argv[2], "ccc"));
  assert (STREQ (sb.argv[3], ""));
  assert (sb.argv[4] == NULL);

  assert (guestfs_int_count_strings (sb.argv) == 4);

  guestfs_int_free_stringsbuf (&sb);
  guestfs_close (g);
}
示例#8
0
static void
test_match (void)
{
  guestfs_h *g;
  char *ret, *ret2;

  g = guestfs_create ();
  assert (g);

  assert (match (g, "aaaaab", test_match_re));
  assert (! match (g, "aaaaacb", test_match_re));
  assert (! match (g, "", test_match_re));

  ret = match1 (g, "aaab", test_match1_re);
  assert (STREQ (ret, "aaa"));
  free (ret);

  assert (! match1 (g, "aaacb", test_match1_re));
  assert (! match1 (g, "", test_match1_re));

  assert (match2 (g, "aaabc", test_match2_re, &ret, &ret2));
  assert (STREQ (ret, "aaa"));
  assert (STREQ (ret2, "b"));
  free (ret);
  free (ret2);

  guestfs_close (g);
}
示例#9
0
PyObject *
py_guestfs_close (PyObject *self, PyObject *args)
{
  PyThreadState *py_save = NULL;
  PyObject *py_g;
  guestfs_h *g;
  size_t i, len;
  PyObject **callbacks;

  if (!PyArg_ParseTuple (args, (char *) "O:guestfs_close", &py_g))
    return NULL;
  g = get_handle (py_g);

  /* As in the OCaml bindings, there is a hard to solve case where the
   * caller can delete a callback from within the callback, resulting
   * in a double-free here.  XXX
   */
  callbacks = get_all_event_callbacks (g, &len);

  if (PyEval_ThreadsInitialized ())
    py_save = PyEval_SaveThread ();
  guestfs_close (g);
  if (PyEval_ThreadsInitialized ())
    PyEval_RestoreThread (py_save);

  for (i = 0; i < len; ++i)
    Py_XDECREF (callbacks[i]);
  free (callbacks);

  Py_INCREF (Py_None);
  return Py_None;
}
示例#10
0
/**
 * Test C<guestfs_int_new_command> etc.
 *
 * XXX These tests could be made much more thorough.  So far we simply
 * test that it's not obviously broken.
 */
static void
test_command (void)
{
  guestfs_h *g;
  struct command *cmd;
  int r;

  g = guestfs_create ();
  assert (g);

  /* argv-style */
  cmd = guestfs_int_new_command (g);
  assert (cmd);
  guestfs_int_cmd_add_arg (cmd, "touch");
  guestfs_int_cmd_add_arg (cmd, "test-utils-test-command");
  r = guestfs_int_cmd_run (cmd);
  assert (r == 0);
  guestfs_int_cmd_close (cmd);

  /* system-style */
  cmd = guestfs_int_new_command (g);
  assert (cmd);
  guestfs_int_cmd_add_string_unquoted (cmd, "rm ");
  guestfs_int_cmd_add_string_quoted (cmd, "test-utils-test-command");
  r = guestfs_int_cmd_run (cmd);
  assert (r == 0);
  guestfs_int_cmd_close (cmd);

  guestfs_close (g);
}
示例#11
0
/* Allocate handles and deal with finalization. */
static void
guestfs_finalize (value gv)
{
  guestfs_h *g = Guestfs_val (gv);

  if (g) {
    /* There is a nasty, difficult to solve case here where the
     * user deletes events in one of the callbacks that we are
     * about to invoke, resulting in a double-free.  XXX
     */
    size_t len, i;
    value **roots = get_all_event_callbacks (g, &len);

    value *v = guestfs_get_private (g, "_ocaml_g");

    /* Close the handle: this could invoke callbacks from the list
     * above, which is why we don't want to delete them before
     * closing the handle.
     */
    guestfs_close (g);

    /* Now unregister the global roots. */
    for (i = 0; i < len; ++i) {
      caml_remove_global_root (roots[i]);
      free (roots[i]);
    }
    free (roots);

    caml_remove_global_root (v);
    free (v);
  }
}
示例#12
0
int
main (int argc, char *argv[])
{
  guestfs_h *g = guestfs_create ();

  /* Call some non-daemon functions that have a String parameter, but
   * setting that parameter to NULL.  Previously this would cause a
   * segfault inside libguestfs.  After this bug was fixed, this
   * turned into an error message.
   */

  assert (guestfs_add_drive (g, NULL) == -1);
  assert (guestfs_config (g, NULL, NULL) == -1);

  /* This optional argument must not be NULL. */

  assert (guestfs_add_drive_opts (g, "/dev/null",
                                  GUESTFS_ADD_DRIVE_OPTS_FORMAT, NULL,
                                  -1) == -1);

  /* These can be safely set to NULL, should be no error. */

  assert (guestfs_set_path (g, NULL) == 0);
  assert (guestfs_set_append (g, NULL) == 0);
  assert (guestfs_set_qemu (g, NULL) == 0);

  guestfs_close (g);
  exit (EXIT_SUCCESS);
}
示例#13
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  const char *key;
  void *data;
  size_t count;

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, errno, "guestfs_create");

  if (guestfs_set_event_callback (g, close_callback, GUESTFS_EVENT_CLOSE,
                                  0, NULL) == -1)
    exit (EXIT_FAILURE);

  guestfs_set_private (g, PREFIX "a", (void *) 1);
  guestfs_set_private (g, PREFIX "b", (void *) 2);
  guestfs_set_private (g, PREFIX "c", (void *) 3);
  guestfs_set_private (g, PREFIX "a", (void *) 4); /* overwrites previous */

  /* Check we can fetch keys. */
  assert (guestfs_get_private (g, PREFIX "a") == (void *) 4);
  assert (guestfs_get_private (g, PREFIX "b") == (void *) 2);
  assert (guestfs_get_private (g, PREFIX "c") == (void *) 3);
  assert (guestfs_get_private (g, PREFIX "d") == NULL);

  /* Check we can count keys by iterating. */
  count = 0;
  data = guestfs_first_private (g, &key);
  while (data != NULL) {
    if (strncmp (key, PREFIX, strlen (PREFIX)) == 0)
      count++;
    data = guestfs_next_private (g, &key);
  }
  assert (count == 3);

  /* Delete some keys. */
  guestfs_set_private (g, PREFIX "a", NULL);
  guestfs_set_private (g, PREFIX "b", NULL);

  /* Count them again. */
  count = 0;
  data = guestfs_first_private (g, &key);
  while (data != NULL) {
    if (strncmp (key, PREFIX, strlen (PREFIX)) == 0)
      count++;
    data = guestfs_next_private (g, &key);
  }
  assert (count == 1);

  /* Closing should implicitly call the close_callback function. */
  guestfs_close (g);

  assert (close_callback_called == 1);

  exit (EXIT_SUCCESS);
}
示例#14
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  int r;
  char *data;
  size_t i, size;

  if (test_start_nbdkit ("-n", NBDKIT_PLUGIN ("file"), "file=file-data",
                         NULL) == -1)
    exit (EXIT_FAILURE);

  g = guestfs_create ();
  if (g == NULL) {
    perror ("guestfs_create");
    exit (EXIT_FAILURE);
  }

  /* Using any exportname causes qemu to use the newstyle protocol. */
  r = guestfs_add_drive_opts (g, "/" /* exportname */,
                              GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                              GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd",
                              GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
                              -1);
  if (r == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  /* Check the data in the file is \x01-\x08 repeated 512 times. */
  data = guestfs_pread_device (g, "/dev/sda", 8 * 512, 0, &size);
  if (!data)
    exit (EXIT_FAILURE);
  if (size != 8 * 512) {
    fprintf (stderr, "%s FAILED: unexpected size (actual: %zu, expected: 512)\n",
             program_name, size);
    exit (EXIT_FAILURE);
  }

  for (i = 0; i < 512 * 8; i += 8) {
    if (data[i] != 1 || data[i+1] != 2 ||
        data[i+2] != 3 || data[i+3] != 4 ||
        data[i+4] != 5 || data[i+5] != 6 ||
        data[i+6] != 7 || data[i+7] != 8) {
      fprintf (stderr, "%s FAILED: unexpected data returned at offset %zu\n",
               program_name, i);
      exit (EXIT_FAILURE);
    }
  }

  free (data);

  guestfs_close (g);
  exit (EXIT_SUCCESS);
}
示例#15
0
int
main (int argc, char *argv[])
{
  char *str;
  guestfs_h *g;
  char tmp[] = "/tmp/charsetXXXXXX";
  int fd;
  size_t i;
  struct filesystem *fs;

  /* Allow this test to be skipped. */
  str = getenv ("SKIP_TEST_CHARSET_FIDELITY");
  if (str && STREQ (str, "1")) {
    printf ("%s: test skipped because environment variable is set.\n",
            argv[0]);
    exit (77);
  }

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, 0, "failed to create handle");

  fd = mkstemp (tmp);
  if (fd == -1)
    error (EXIT_FAILURE, errno, "mkstemp");

  if (ftruncate (fd, 1024 * 1024 * 1024) == -1)
    error (EXIT_FAILURE, errno, "ftruncate: %s", tmp);

  if (close (fd) == -1)
    error (EXIT_FAILURE, errno, "close: %s", tmp);

  if (guestfs_add_drive_opts (g, tmp, -1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1)
    exit (EXIT_FAILURE);

  for (i = 0; i < sizeof filesystems / sizeof filesystems[0]; ++i) {
    fs = &filesystems[i];
    test_filesystem (g, fs);
  }

  guestfs_close (g);
  unlink (tmp);

  exit (EXIT_SUCCESS);
}
示例#16
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  size_t i;
  int lengths[] = { 0, 1, 1024,
                    GUESTFS_ERROR_LEN-2, GUESTFS_ERROR_LEN-1,
                    GUESTFS_ERROR_LEN, GUESTFS_ERROR_LEN+1,
                    GUESTFS_ERROR_LEN+2,
                    GUESTFS_ERROR_LEN*2, -1 };
  char len_s[64];
  char *args[2];

  g = guestfs_create ();
  if (g == NULL) {
    perror ("guestfs_create");
    exit (EXIT_FAILURE);
  }

  if (guestfs_add_drive (g, "/dev/null") == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  guestfs_push_error_handler (g, NULL, NULL);

  for (i = 0; lengths[i] != -1; ++i) {
    snprintf (len_s, sizeof len_s, "%d", lengths[i]);
    args[0] = len_s;
    args[1] = NULL;

    if (guestfs_debug (g, "error", args) != NULL) {
      fprintf (stderr, "%s: unexpected return value from 'debug error'\n",
               argv[0]);
      exit (EXIT_FAILURE);
    }
    /* EROFS is a magic value returned by debug_error in the daemon. */
    if (guestfs_last_errno (g) != EROFS) {
      fprintf (stderr, "%s: unexpected error from 'debug error': %s\n",
               argv[0], guestfs_last_error (g));
      exit (EXIT_FAILURE);
    }
    /* else OK */
  }

  guestfs_pop_error_handler (g);
  guestfs_close (g);
  exit (EXIT_SUCCESS);
}
示例#17
0
int
main (int argc, char *argv[])
{
    guestfs_h *g;

    g = guestfs_create ();
    if (g == NULL) {
        fprintf (stderr, "failed to create handle\n");
        exit (EXIT_FAILURE);
    }

    guestfs_close (g);

    exit (EXIT_SUCCESS);
}
示例#18
0
static size_t
add_disks_to_handle_reverse (struct disk *disk, size_t *errors_r)
{
  size_t nr_disks_added;

  if (disk == NULL)
    return 0;

  nr_disks_added = add_disks_to_handle_reverse (disk->next, errors_r);

  struct guestfs_add_drive_opts_argv optargs = { .bitmask = 0 };

  optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK;
  optargs.readonly = 1;

  if (disk->format) {
    optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK;
    optargs.format = disk->format;
  }

  if (guestfs_add_drive_opts_argv (g, disk->filename, &optargs) == -1) {
    (*errors_r)++;
    disk->failed = 1;
    return nr_disks_added;
  }

  return nr_disks_added+1;
}

/* Close and reopen the libguestfs handle. */
static void
reset_guestfs_handle (void)
{
  /* Copy the settings from the old handle. */
  int verbose = guestfs_get_verbose (g);
  int trace = guestfs_get_trace (g);

  guestfs_close (g);

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  guestfs_set_verbose (g, verbose);
  guestfs_set_trace (g, trace);
}
示例#19
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  const char *filename = "test.log";
  FILE *debugfp;

  debugfp = fopen (filename, "w");
  if (debugfp == NULL) {
    perror (filename);
    exit (EXIT_FAILURE);
  }

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, "failed to create handle\n");
    exit (EXIT_FAILURE);
  }

  if (guestfs_set_event_callback
      (g, debug_to_file,
       GUESTFS_EVENT_LIBRARY | GUESTFS_EVENT_APPLIANCE |
       GUESTFS_EVENT_WARNING | GUESTFS_EVENT_TRACE,
       0, debugfp) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_set_verbose (g, 1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_set_trace (g, 1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_add_drive_opts (g, "/dev/null",
                              GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                              GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
                              -1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
示例#20
0
/**
 * Test C<guestfs_int_qemu_escape_param>
 *
 * XXX I wanted to make this test run qemu, passing some parameters
 * which need to be escaped, but I cannot think of a way to do that
 * without launching a VM.
 */
static void
test_qemu_escape_param (void)
{
  CLEANUP_FREE char *ret1 = NULL, *ret2 = NULL, *ret3 = NULL;
  guestfs_h *g;

  g = guestfs_create ();
  assert (g);

  ret1 = guestfs_int_qemu_escape_param (g, "name,with,commas");
  assert (STREQ (ret1, "name,,with,,commas"));

  ret2 = guestfs_int_qemu_escape_param (g, ",,,,");
  assert (STREQ (ret2, ",,,,,,,,"));

  ret3 = guestfs_int_qemu_escape_param (g, "");
  assert (STREQ (ret3, ""));

  guestfs_close (g);
}
示例#21
0
int
main (int argc, char *argv[])
{
  void *lib;
  guestfs_create_t guestfs_create;
  guestfs_get_program_t guestfs_get_program;
  guestfs_close_t guestfs_close;
  guestfs_h *g;

  if (access (LIBRARY, X_OK) == -1) {
    fprintf (stderr, "test skipped because %s cannot be accessed: %m\n",
             LIBRARY);
    exit (77);
  }

  lib = dlopen (LIBRARY, RTLD_LAZY);
  if (lib == NULL) {
    fprintf (stderr, "could not open %s: %s\n", LIBRARY, dlerror ());
    exit (EXIT_FAILURE);
  }

  guestfs_create = read_symbol (lib, "guestfs_create");
  guestfs_get_program = read_symbol (lib, "guestfs_get_program");
  guestfs_close = read_symbol (lib, "guestfs_close");

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, "failed to create handle\n");
    exit (EXIT_FAILURE);
  }
  printf ("program = %s\n", guestfs_get_program (g));

  guestfs_close (g);

  if (dlclose (lib) != 0) {
    fprintf (stderr, "could not close %s: %s\n", LIBRARY, dlerror ());
    exit (EXIT_FAILURE);
  }

  exit (EXIT_SUCCESS);
}
示例#22
0
/**
 * Test C<guestfs_int_getumask>.
 */
static void
test_getumask (void)
{
  guestfs_h *g;
  int orig_umask = umask (0777);

  g = guestfs_create ();
  assert (g);

  assert (guestfs_int_getumask (g) == 0777);
  umask (0022);
  assert (guestfs_int_getumask (g) == 0022);
  assert (guestfs_int_getumask (g) == 0022);
  umask (0222);
  assert (guestfs_int_getumask (g) == 0222);
  umask (0000);
  assert (guestfs_int_getumask (g) == 0000);

  umask (orig_umask);           /* Restore original umask. */
  guestfs_close (g);
}
示例#23
0
int
main (int argc, char *argv[])
{
  char *str;
  guestfs_h *g;
  size_t i;
  struct filesystem *fs;

  /* Allow this test to be skipped. */
  str = getenv (ourenvvar);
  if (str && STREQ (str, "1")) {
    printf ("%s: test skipped because environment variable is set.\n",
            program_name);
    exit (77);
  }

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, 0, "failed to create handle");

  if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1)
    exit (EXIT_FAILURE);

  for (i = 0; i < sizeof filesystems / sizeof filesystems[0]; ++i) {
    fs = &filesystems[i];
    test_filesystem (g, fs);
  }

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
示例#24
0
int
main (int argc, char *argv[])
{
  size_t nr_failed;
  guestfs_h *g;

  setbuf (stdout, NULL);

  no_test_warnings ();

  g = create_handle ();

  nr_failed = perform_tests (g);

  guestfs_close (g);

  if (nr_failed > 0) {
    printf ("***** %zu / %zu tests FAILED *****\n", nr_failed, nr_tests);
    exit (EXIT_FAILURE);
  }

  exit (EXIT_SUCCESS);
}
示例#25
0
static void *
start_srcthread (void *arg)
{
    struct threaddata *threaddata = arg;
    guestfs_h *srcg;
    char fdname[128];

    /* Open the source domain. */
    srcg = guestfs_create ();
    if (!srcg) {
        perror ("failed to create libguestfs handle");
        pthread_cancel (threaddata->mainthread);
        exit (EXIT_FAILURE);
    }
    if (open_guest (srcg, threaddata->src, 1) == -1) {
        pthread_cancel (threaddata->mainthread);
        exit (EXIT_FAILURE);
    }

    /* Begin the download. */
    snprintf (fdname, sizeof fdname, "/dev/fd/%d", threaddata->fd);
    if (guestfs_tar_out (srcg, threaddata->srcdir, fdname) == -1) {
        pthread_cancel (threaddata->mainthread);
        exit (EXIT_FAILURE);
    }

    /* Close the pipe; this will cause the receiver to finish the upload. */
    if (close (threaddata->fd) == -1) {
        pthread_cancel (threaddata->mainthread);
        exit (EXIT_FAILURE);
    }

    /* Clean up. */
    guestfs_close (srcg);

    return NULL;
}
示例#26
0
int
main (int argc, char *argv[])
{
  /* Current time for --time-days, --time-relative output. */
  time (&now);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:hlRvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "checksum", 2, 0, 0 },
    { "checksums", 2, 0, 0 },
    { "csv", 0, 0, 0 },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "extra-stat", 0, 0, 0 },
    { "extra-stats", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "human-readable", 0, 0, 'h' },
    { "keys-from-stdin", 0, 0, 0 },
    { "long", 0, 0, 'l' },
    { "long-options", 0, 0, 0 },
    { "recursive", 0, 0, 'R' },
    { "time", 0, 0, 0 },
    { "times", 0, 0, 0 },
    { "time-days", 0, 0, 0 },
    { "time-relative", 0, 0, 0 },
    { "time-t", 0, 0, 0 },
    { "uid", 0, 0, 0 },
    { "uids", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;
#define MODE_LS_L  1
#define MODE_LS_R  2
#define MODE_LS_LR (MODE_LS_L|MODE_LS_R)
  int mode = 0;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  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, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "checksum") ||
                 STREQ (long_options[option_index].name, "checksums")) {
        if (!optarg || STREQ (optarg, ""))
          checksum = "md5";
        else
          checksum = optarg;
      } else if (STREQ (long_options[option_index].name, "csv")) {
        csv = 1;
      } else if (STREQ (long_options[option_index].name, "extra-stat") ||
                 STREQ (long_options[option_index].name, "extra-stats")) {
        enable_extra_stats = 1;
      } else if (STREQ (long_options[option_index].name, "time") ||
                 STREQ (long_options[option_index].name, "times")) {
        enable_times = 1;
      } else if (STREQ (long_options[option_index].name, "time-t")) {
        enable_times = 1;
        time_t_output = 1;
      } else if (STREQ (long_options[option_index].name, "time-relative")) {
        enable_times = 1;
        time_t_output = 1;
        time_relative = 1;
      } else if (STREQ (long_options[option_index].name, "time-days")) {
        enable_times = 1;
        time_t_output = 1;
        time_relative = 2;
      } else if (STREQ (long_options[option_index].name, "uid") ||
                 STREQ (long_options[option_index].name, "uids")) {
        enable_uids = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'h':
      human = 1;
      break;

    case 'l':
      mode |= MODE_LS_L;
      break;

    case 'R':
      mode |= MODE_LS_R;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-ls which is how we detect this.
   */
  if (drvs == NULL) {
    /* argc - 1 because last parameter is the single directory name. */
    while (optind < argc - 1) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 1);
  assert (live == 0);

  /* Many flags only apply to -lR mode. */
  if (mode != MODE_LS_LR &&
      (csv || human || enable_uids || enable_times || enable_extra_stats ||
       checksum)) {
    fprintf (stderr, _("%s: used a flag which can only be combined with -lR mode\nFor more information, read the virt-ls(1) man page.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* CSV && human is unsafe because spreadsheets fail to parse these
   * fields correctly.  (RHBZ#600977).
   */
  if (human && csv) {
    fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* User must specify at least one directory name on the command line. */
  if (optind >= argc || argc - optind < 1)
    usage (EXIT_FAILURE);

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives, inspect and mount.  Note that inspector is always true,
   * and there is no -m option.
   */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  inspect_mount ();

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  unsigned errors = 0;

  while (optind < argc) {
    const char *dir = argv[optind];

    switch (mode) {
    case 0:                     /* no -l or -R option */
      if (do_ls (dir) == -1)
        errors++;
      break;

    case MODE_LS_L:             /* virt-ls -l */
      if (do_ls_l (dir) == -1)
        errors++;
      break;

    case MODE_LS_R:             /* virt-ls -R */
      if (do_ls_R (dir) == -1)
        errors++;
      break;

    case MODE_LS_LR:            /* virt-ls -lR */
      if (do_ls_lR (dir) == -1)
        errors++;
      break;

    default:
      abort ();                 /* can't happen */
    }

    optind++;
  }

  guestfs_close (g);

  exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
示例#27
0
/* Worker thread. */
static void *
start_thread (void *thread_data_vp)
{
  struct thread_data *thread_data = thread_data_vp;
  int quit = 0;
  int err;
  size_t i;
  guestfs_h *g;
  unsigned errors = 0;

  for (;;) {
    /* Take the next process. */
    err = pthread_mutex_lock (&mutex);
    if (err != 0) {
      fprintf (stderr, "%s: pthread_mutex_lock: %s",
               guestfs_int_program_name, strerror (err));
      goto error;
    }

    i = n;
    if (i > 0) {
      printf ("%zu to go ...          \r", n);
      fflush (stdout);

      n--;
    }
    else
      quit = 1;

    err = pthread_mutex_unlock (&mutex);
    if (err != 0) {
      fprintf (stderr, "%s: pthread_mutex_unlock: %s",
               guestfs_int_program_name, strerror (err));
      goto error;
    }

    if (quit)                   /* Work finished. */
      break;

    g = guestfs_create ();
    if (g == NULL) {
      perror ("guestfs_create");
      errors++;
      if (!ignore_errors)
        goto error;
    }

    guestfs_set_trace (g, trace);
    guestfs_set_verbose (g, verbose);

    if (guestfs_add_drive_ro (g, "/dev/null") == -1) {
      errors++;
      if (!ignore_errors)
        goto error;
    }

    if (guestfs_launch (g) == -1) {
      errors++;
      if (!ignore_errors)
        goto error;
    }

    if (guestfs_shutdown (g) == -1) {
      errors++;
      if (!ignore_errors)
        goto error;
    }

    guestfs_close (g);
  }

  if (errors > 0) {
    fprintf (stderr, "%s: thread %d: %u errors were ignored\n",
             guestfs_int_program_name, thread_data->thread_num, errors);
    goto error;
  }

  thread_data->r = 0;
  return &thread_data->r;

 error:
  thread_data->r = -1;
  return &thread_data->r;
}
示例#28
0
int
main (int argc, char *argv[])
{
  pthread_t thread[NR_THREADS];
  int data[NR_THREADS];
  int i, r, errors;
  guestfs_h *g;
  char *attach_method;

  /* Test is only meaningful if the attach-method "appliance" is used. */
  g = guestfs_create ();
  if (!g) {
    perror ("guestfs_create");
    exit (EXIT_FAILURE);
  }
  attach_method = guestfs_get_attach_method (g);
  if (attach_method == NULL) {
    guestfs_close (g);
    exit (EXIT_FAILURE);
  }
  if (STRNEQ (attach_method, "appliance")) {
    fprintf (stderr, "%s: test skipped because attach method isn't 'appliance'.\n",
             argv[0]);
    free (attach_method);
    guestfs_close (g);
    exit (77);
  }
  free (attach_method);
  guestfs_close (g);

  /* Ensure error messages are not translated. */
  setenv ("LC_ALL", "C", 1);

  pthread_barrier_init (&barrier, NULL, NR_THREADS);

  /* Create the other threads which will set up their own libguestfs
   * handle then wait at a barrier before launching.
   */
  for (i = 0; i < NR_THREADS; ++i) {
    data[i] = i;
    r = pthread_create (&thread[i], NULL, start_thread, &data[i]);
    if (r != 0) {
      fprintf (stderr, "pthread_create: %s\n", strerror (r));
      exit (EXIT_FAILURE);
    }
  }

  /* Wait for the threads to exit. */
  errors = 0;

  for (i = 0; i < NR_THREADS; ++i) {
    int *ret;

    r = pthread_join (thread[i], (void **) &ret);
    if (r != 0) {
      fprintf (stderr, "pthread_join: %s\n", strerror (r));
      exit (EXIT_FAILURE);
    }
    if (*ret == -1)
      errors++;
  }

  exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
示例#29
0
static void *
start_thread (void *vi)
{
  guestfs_h *g;
  int r, thread_id = *(int *)vi;
  const char *error;

  g = guestfs_create ();
  if (g == NULL) {
    perror ("guestfs_create");
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  if (guestfs_add_drive_opts (g, "/dev/null",
                              GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                              GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
                              -1) == -1) {
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  /* Fake out qemu. */
  if (guestfs_set_qemu (g, "/bin/true") == -1) {
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  /* Wait for the other threads to finish starting up. */
  r = pthread_barrier_wait (&barrier);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) {
    fprintf (stderr, "pthread_barrier_wait: [thread %d]: %s\n",
             thread_id, strerror (r));
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  /* Launch the handle.  Because of the faked out qemu, we expect this
   * will fail with "child process died unexpectedly".  We are
   * interested in other failures.
   */
  guestfs_push_error_handler (g, NULL, NULL);
  r = guestfs_launch (g);
  error = guestfs_last_error (g);

  if (r == 0) { /* This should NOT happen. */
    fprintf (stderr, "rhbz790721: [thread %d]: "
             "strangeness in test: expected launch to fail, but it didn't!\n",
             thread_id);
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  if (error == NULL) { /* This also should NOT happen. */
    fprintf (stderr, "rhbz790721: [thread %d]: "
             "strangeness in test: no error message!\n",
             thread_id);
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  /* If this happens, it indicates a bug/race in the appliance
   * building code which is what this regression test is designed to
   * spot.
   */
  if (STRNEQ (error, "child process died unexpectedly")) {
    fprintf (stderr, "rhbz790721: [thread %d]: error: %s\n", thread_id, error);
    *(int *)vi = -1;
    pthread_exit (vi);
  }

  guestfs_pop_error_handler (g);

  /* Close the handle. */
  guestfs_close (g);

  *(int *)vi = 0;
  pthread_exit (vi);
}
示例#30
0
文件: handle.c 项目: myyyy/libguestfs
/* Close all open handles (called from atexit(3)). */
static void
close_handles (void)
{
  while (handles) guestfs_close (handles);
}