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); }
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); }
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); }
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); }
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); }
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); }
/* Guestfs.create */ CAMLprim value ocaml_guestfs_create (void) { CAMLparam0 (); CAMLlocal1 (gv); guestfs_h *g; value *v; g = guestfs_create (); if (g == NULL) caml_failwith ("failed to create guestfs handle"); guestfs_set_error_handler (g, NULL, NULL); gv = Val_guestfs (g); /* Store the OCaml handle into the C handle. This is only so we can * map the C handle to the OCaml handle in event_callback_wrapper. */ v = guestfs_safe_malloc (g, sizeof *v); *v = gv; /* XXX This global root is generational, but we cannot rely on every * user having the OCaml 3.11 version which supports this. */ caml_register_global_root (v); guestfs_set_private (g, "_ocaml_g", v); CAMLreturn (gv); }
/** * 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); }
/* Common function to create the handle and set various defaults. */ static guestfs_h * create_handle (void) { guestfs_h *g; CLEANUP_FREE char *full_append = NULL; g = guestfs_create (); if (!g) error (EXIT_FAILURE, errno, "guestfs_create"); if (memsize != 0) if (guestfs_set_memsize (g, memsize) == -1) exit (EXIT_FAILURE); if (smp >= 2) if (guestfs_set_smp (g, smp) == -1) exit (EXIT_FAILURE); /* This changes some details in appliance/init and enables a * detailed trace of calls to initcall functions in the kernel. */ if (asprintf (&full_append, "guestfs_boot_analysis=1 " "ignore_loglevel initcall_debug " "%s", append != NULL ? append : "") == -1) error (EXIT_FAILURE, errno, "asprintf"); if (guestfs_set_append (g, full_append) == -1) exit (EXIT_FAILURE); return g; }
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); }
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); }
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); }
/* Create the handle, with attached disks. */ static guestfs_h * create_handle (void) { guestfs_h *g; g = guestfs_create (); if (g == NULL) { printf ("FAIL: guestfs_create\n"); exit (EXIT_FAILURE); } if (guestfs_add_drive_scratch (g, 524288000, -1) == -1) { printf ("FAIL: guestfs_add_drive_scratch\n"); exit (EXIT_FAILURE); } if (guestfs_add_drive_scratch (g, 52428800, -1) == -1) { printf ("FAIL: guestfs_add_drive_scratch\n"); exit (EXIT_FAILURE); } if (guestfs_add_drive_scratch (g, 10485760, -1) == -1) { printf ("FAIL: guestfs_add_drive_scratch\n"); exit (EXIT_FAILURE); } if (guestfs_add_drive_ro (g, "../data/test.iso") == -1) { printf ("FAIL: guestfs_add_drive_ro ../data/test.iso\n"); exit (EXIT_FAILURE); } /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */ alarm (600); if (guestfs_launch (g) == -1) { printf ("FAIL: guestfs_launch\n"); exit (EXIT_FAILURE); } /* Cancel previous alarm. */ alarm (0); /* Create ext2 filesystem on /dev/sdb1 partition. */ if (guestfs_part_disk (g, "/dev/sdb", "mbr") == -1) { printf ("FAIL: guestfs_part_disk\n"); exit (EXIT_FAILURE); } if (guestfs_mkfs (g, "ext2", "/dev/sdb1") == -1) { printf ("FAIL: guestfs_mkfs (/dev/sdb1)\n"); exit (EXIT_FAILURE); } return g; }
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); }
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); }
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); }
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); }
PyObject * py_guestfs_create (PyObject *self, PyObject *args) { guestfs_h *g; g = guestfs_create (); if (g == NULL) { PyErr_SetString (PyExc_RuntimeError, "guestfs.create: failed to allocate handle"); return NULL; } guestfs_set_error_handler (g, NULL, NULL); /* This can return NULL, but in that case put_handle will have * set the Python error string. */ return put_handle (g); }
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); }
/** * 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); }
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); }
/** * 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); }
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); }
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; }
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); }
/* 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; }
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); }
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); }
int main (int argc, char *argv[]) { guestfs_h *g; struct guestfs_internal_mountable *mountable; const char *devices[] = { "/dev/VG/LV", NULL }; const char *feature[] = { "btrfs", NULL }; g = guestfs_create (); if (g == NULL) { perror ("could not create handle"); exit (EXIT_FAILURE); } if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1) { error: guestfs_close (g); exit (EXIT_FAILURE); } if (guestfs_launch (g) == -1) goto error; if (!guestfs_feature_available (g, (char **) feature)) { printf ("skipping test because btrfs is not available\n"); guestfs_close (g); exit (77); } if (!guestfs_filesystem_available (g, "btrfs")) { printf ("skipping test because btrfs filesystem is not available\n"); guestfs_close (g); exit (77); } if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1) goto error; if (guestfs_pvcreate (g, "/dev/sda1") == -1) goto error; const char *pvs[] = { "/dev/sda1", NULL }; if (guestfs_vgcreate (g, "VG", (char **) pvs) == -1) goto error; if (guestfs_lvcreate (g, "LV", "VG", 900) == -1) goto error; if (guestfs_mkfs_btrfs (g, (char * const *)devices, -1) == -1) goto error; if (guestfs_mount (g, "/dev/VG/LV", "/") == -1) goto error; if (guestfs_btrfs_subvolume_create (g, "/sv") == -1) goto error; mountable = guestfs_internal_parse_mountable (g, "/dev/VG/LV"); if (mountable == NULL) goto error; if (mountable->im_type != MOUNTABLE_DEVICE || STRNEQ ("/dev/VG/LV", mountable->im_device)) { fprintf (stderr, "incorrectly parsed /dev/VG/LV: im_device=%s\n", mountable->im_device); goto error; } guestfs_free_internal_mountable (mountable); mountable = guestfs_internal_parse_mountable (g, "btrfsvol:/dev/VG/LV/sv"); if (mountable == NULL) goto error; if (mountable->im_type != MOUNTABLE_BTRFSVOL || STRNEQ ("/dev/VG/LV", mountable->im_device) || STRNEQ ("sv", mountable->im_volume)) { fprintf (stderr, "incorrectly parsed /dev/VG/LV/sv: im_device=%s, im_volume=%s\n", mountable->im_device, mountable->im_volume); goto error; } guestfs_free_internal_mountable (mountable); guestfs_close (g); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { guestfs_h *g; int fd, r; char tempdir[] = "/tmp/mlXXXXXX"; pid_t pid; char *shell, *p; if (argc != 2) { usage (); exit (EXIT_FAILURE); } printf ("\n" "This is the 'mount-local' demonstration program. Follow the\n" "instructions on screen.\n" "\n" "Creating and formatting the disk image, please wait a moment ...\n"); fflush (stdout); /* Create the output disk image: raw sparse. */ fd = open (argv[1], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644); if (fd == -1) { perror (argv[1]); exit (EXIT_FAILURE); } if (ftruncate (fd, SIZE_MB * 1024 * 1024) == -1) { perror ("truncate"); close (fd); exit (EXIT_FAILURE); } if (close (fd) == -1) { perror ("close"); exit (EXIT_FAILURE); } /* Guestfs handle. */ g = guestfs_create (); if (g == NULL) { perror ("could not create libguestfs handle"); exit (EXIT_FAILURE); } /* Create the disk image and format it with a partition and a filesystem. */ if (guestfs_add_drive_opts (g, argv[1], GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", -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); if (guestfs_mkfs (g, "ext2", "/dev/sda1") == -1) exit (EXIT_FAILURE); /* Mount the empty filesystem. */ if (guestfs_mount_options (g, MOUNT_OPTIONS, "/dev/sda1", "/") == -1) exit (EXIT_FAILURE); /* Create a file in the new filesystem. */ if (guestfs_touch (g, "/PUT_FILES_AND_DIRECTORIES_HERE") == -1) exit (EXIT_FAILURE); /* Create a temporary mount directory. */ if (mkdtemp (tempdir) == NULL) { perror ("mkdtemp"); exit (EXIT_FAILURE); } /* Mount the filesystem. */ if (guestfs_mount_local (g, tempdir, -1) == -1) exit (EXIT_FAILURE); /* Fork the shell for the user. */ pid = fork (); if (pid == -1) { perror ("fork"); exit (EXIT_FAILURE); } if (pid == 0) { /* Child. */ if (chdir (tempdir) == -1) { perror (tempdir); _exit (EXIT_FAILURE); } printf ("\n" "The *current directory* is a FUSE filesystem backed by the disk\n" "image which is managed by libguestfs. Any files or directories\n" "you copy into here (up to %d MB) will be saved into the disk\n" "image. You can also delete files, create certain special files\n" "and so on.\n" "\n" "When you have finished adding files, hit ^D or type 'exit' to\n" "exit the shell and return to the mount-local program.\n" "\n", SIZE_MB); shell = getenv ("SHELL"); if (!shell) r = system ("/bin/sh"); else { /* Set a magic prompt. We only know how to do this for bash. */ p = strrchr (shell, '/'); if (p && strcmp (p+1, "bash") == 0) { size_t len = 64 + strlen (shell); char buf[len]; snprintf (buf, len, "PS1='mount-local-shell> ' %s --norc -i", shell); r = system (buf); } else r = system (shell); } if (r == -1) { fprintf (stderr, "error: failed to run sub-shell (%s) " "(is $SHELL set correctly?)\n", shell); //FALLTHROUGH } chdir ("/"); guestfs_umount_local (g, GUESTFS_UMOUNT_LOCAL_RETRY, 1, -1); _exit (EXIT_SUCCESS); } /* Note that we are *not* waiting for the child yet. We want to * run the FUSE code in parallel with the subshell. */ /* We're going to hide libguestfs errors here, but in a real program * you would probably want to log them somewhere. */ guestfs_push_error_handler (g, NULL, NULL); /* Now run the FUSE thread. */ if (guestfs_mount_local_run (g) == -1) exit (EXIT_FAILURE); guestfs_pop_error_handler (g); waitpid (pid, NULL, 0); /* Shutdown the handle explicitly so write errors can be detected. */ if (guestfs_shutdown (g) == -1) exit (EXIT_FAILURE); guestfs_close (g); printf ("\n" "Any files or directories that you copied in have been saved into\n" "the disk image called '%s'.\n" "\n" "Try opening the disk image with guestfish to see those files:\n" "\n" " guestfish -a %s -m /dev/sda1\n" "\n", argv[1], argv[1]); exit (EXIT_SUCCESS); }