X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=fuse%2Fguestmount.c;h=1b3abf9788734572e2bf4e287a8890064cf23340;hp=e1cb2d89e2a45ca390f9d8d7ff6f4414fbcba6e5;hb=7509c91a71c729b3223eef4cde10d70daca66c72;hpb=9735484c3579e4e4705cd99dd2f6617186b069cc diff --git a/fuse/guestmount.c b/fuse/guestmount.c index e1cb2d8..1b3abf9 100644 --- a/fuse/guestmount.c +++ b/fuse/guestmount.c @@ -1,5 +1,5 @@ /* guestmount - mount guests using libguestfs and FUSE - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2010 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 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include "progname.h" #include "guestmount.h" +#include "options.h" #include "dircache.h" /* See */ @@ -55,45 +57,19 @@ #define ENOATTR ENODATA #endif -static guestfs_h *g = NULL; -static int read_only = 0; +guestfs_h *g = NULL; +int read_only = 0; int verbose = 0; +int inspector = 0; +int keys_from_stdin = 0; +int echo_keys = 0; +const char *libvirt_uri; int dir_cache_timeout = 60; -/* This is ugly: guestfs errors are strings, FUSE wants -errno. We - * have to do the conversion as best we can. - */ -#define MAX_ERRNO 256 - static int error (void) { - int i; - const char *err = guestfs_last_error (g); - - if (!err) - return -EINVAL; - - if (verbose) - fprintf (stderr, "%s\n", err); - - /* Add a few of our own ... */ - - /* This indicates guestfsd died. Translate into a hard EIO error. - * Arguably we could relaunch the guest if we hit this error. - */ - if (strstr (err, "call launch before using this function")) - return -EIO; - - /* See if it matches an errno string in the host. */ - for (i = 0; i < MAX_ERRNO; ++i) { - const char *e = strerror (i); - if (e && strstr (err, e) != NULL) - return -i; - } - - /* Too bad, return a generic error. */ - return -EINVAL; + return -guestfs_last_errno (g); } static struct guestfs_xattr_list * @@ -850,20 +826,6 @@ static struct fuse_operations fg_operations = { .removexattr = fg_removexattr, }; -struct drv { - struct drv *next; - char *filename; -}; - -struct mp { - struct mp *next; - char *device; - char *mountpoint; -}; - -static void add_drives (struct drv *); -static void mount_mps (struct mp *); - static void __attribute__((noreturn)) fuse_help (void) { @@ -882,22 +844,28 @@ usage (int status) fprintf (stdout, _("%s: FUSE module for libguestfs\n" "%s lets you mount a virtual machine filesystem\n" - "Copyright (C) 2009 Red Hat Inc.\n" + "Copyright (C) 2009-2010 Red Hat Inc.\n" "Usage:\n" " %s [--options] [-- [--FUSE-options]] mountpoint\n" "Options:\n" " -a|--add image Add image\n" + " -c|--connect uri Specify libvirt URI for -d option\n" " --dir-cache-timeout Set readdir cache timeout (default 5 sec)\n" + " -d|--domain guest Add disks from libvirt guest\n" + " --echo-keys Don't turn off echo for passphrases\n" + " --format[=raw|..] Force disk format for -a option\n" " --fuse-help Display extra FUSE options\n" + " -i|--inspector Automatically mount filesystems\n" " --help Display help message and exit\n" + " --keys-from-stdin Read passphrases from stdin\n" " -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n" " -n|--no-sync Don't autosync\n" " -o|--option opt Pass extra option to FUSE\n" " -r|--ro Mount read-only\n" " --selinux Enable SELinux support\n" - " --trace Trace guestfs API calls (to stderr)\n" " -v|--verbose Verbose messages\n" " -V|--version Display version and exit\n" + " -x|--trace Trace guestfs API calls\n" ), program_name, program_name, program_name); } @@ -916,18 +884,25 @@ main (int argc, char *argv[]) /* The command line arguments are broadly compatible with (a subset * of) guestfish. Thus we have to deal mainly with -a, -m and --ro. */ - static const char *options = "a:m:no:rv?V"; + static const char *options = "a:c:d:im:no:rv?Vwx"; static const struct option long_options[] = { { "add", 1, 0, 'a' }, + { "connect", 1, 0, 'c' }, { "dir-cache-timeout", 1, 0, 0 }, + { "domain", 1, 0, 'd' }, + { "echo-keys", 0, 0, 0 }, + { "format", 2, 0, 0 }, { "fuse-help", 0, 0, 0 }, { "help", 0, 0, HELP_OPTION }, + { "inspector", 0, 0, 'i' }, + { "keys-from-stdin", 0, 0, 0 }, { "mount", 1, 0, 'm' }, { "no-sync", 0, 0, 'n' }, { "option", 1, 0, 'o' }, { "ro", 0, 0, 'r' }, + { "rw", 0, 0, 'w' }, { "selinux", 0, 0, 0 }, - { "trace", 0, 0, 0 }, + { "trace", 0, 0, 'x' }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { 0, 0, 0, 0 } @@ -938,6 +913,7 @@ main (int argc, char *argv[]) struct mp *mps = NULL; struct mp *mp; char *p; + const char *format = NULL; int c, r; int option_index; struct sigaction sa; @@ -977,7 +953,6 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } - guestfs_set_autosync (g, 1); guestfs_set_recovery_proc (g, 0); ADD_FUSE_ARG (program_name); @@ -1012,12 +987,16 @@ main (int argc, char *argv[]) fuse_help (); else if (STREQ (long_options[option_index].name, "selinux")) guestfs_set_selinux (g, 1); - else if (STREQ (long_options[option_index].name, "trace")) { - ADD_FUSE_ARG ("-f"); - guestfs_set_trace (g, 1); - guestfs_set_recovery_proc (g, 1); - } - else { + 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, "keys-from-stdin")) { + keys_from_stdin = 1; + } else if (STREQ (long_options[option_index].name, "echo-keys")) { + echo_keys = 1; + } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); exit (EXIT_FAILURE); @@ -1025,39 +1004,27 @@ main (int argc, char *argv[]) break; case 'a': - if (access (optarg, R_OK) != 0) { - perror (optarg); - exit (EXIT_FAILURE); - } - drv = malloc (sizeof (struct drv)); - if (!drv) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - drv->filename = optarg; - drv->next = drvs; - drvs = drv; + OPTION_a; + break; + + case 'c': + OPTION_c; + break; + + case 'd': + OPTION_d; + break; + + case 'i': + OPTION_i; break; case 'm': - mp = malloc (sizeof (struct mp)); - if (!mp) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - p = strchr (optarg, ':'); - if (p) { - *p = '\0'; - mp->mountpoint = p+1; - } else - mp->mountpoint = bad_cast ("/"); - mp->device = optarg; - mp->next = mps; - mps = mp; + OPTION_m; break; case 'n': - guestfs_set_autosync (g, 0); + OPTION_n; break; case 'o': @@ -1066,17 +1033,26 @@ main (int argc, char *argv[]) break; case 'r': - read_only = 1; + OPTION_r; break; case 'v': - verbose++; - guestfs_set_verbose (g, verbose); + OPTION_v; break; case 'V': - printf ("%s %s\n", program_name, PACKAGE_VERSION); - exit (EXIT_SUCCESS); + OPTION_V; + break; + + case 'w': + OPTION_w; + break; + + case 'x': + OPTION_x; + ADD_FUSE_ARG ("-f"); + guestfs_set_recovery_proc (g, 1); + break; case HELP_OPTION: usage (EXIT_SUCCESS); @@ -1086,10 +1062,10 @@ main (int argc, char *argv[]) } } - /* We must have at least one -a and at least one -m. */ - if (!drvs || !mps) { + /* Check we have the right options. */ + if (!drvs || !(mps || inspector)) { fprintf (stderr, - _("%s: must have at least one -a and at least one -m option\n"), + _("%s: must have at least one -a/-d and at least one -m/-i option\n"), program_name); exit (EXIT_FAILURE); } @@ -1103,11 +1079,16 @@ main (int argc, char *argv[]) } /* Do the guest drives and mountpoints. */ - add_drives (drvs); + add_drives (drvs, 'a'); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); + if (inspector) + inspect_mount (); mount_mps (mps); + free_drives (drvs); + free_mps (mps); + /* FUSE example does this, not clear if it's necessary, but ... */ if (guestfs_umask (g, 0) == -1) exit (EXIT_FAILURE); @@ -1145,40 +1126,3 @@ main (int argc, char *argv[]) exit (r == -1 ? 1 : 0); } - -/* List is built in reverse order, so add them in reverse order. */ -static void -add_drives (struct drv *drv) -{ - int r; - - if (drv) { - add_drives (drv->next); - if (!read_only) - r = guestfs_add_drive (g, drv->filename); - else - r = guestfs_add_drive_ro (g, drv->filename); - if (r == -1) - exit (EXIT_FAILURE); - } -} - -/* List is built in reverse order, so mount them in reverse order. */ -static void -mount_mps (struct mp *mp) -{ - int r; - - if (mp) { - mount_mps (mp->next); - - /* Don't use guestfs_mount here because that will default to mount - * options -o sync,noatime. For more information, see guestfs(3) - * section "LIBGUESTFS GOTCHAS". - */ - const char *options = read_only ? "ro" : ""; - r = guestfs_mount_options (g, options, mp->device, mp->mountpoint); - if (r == -1) - exit (EXIT_FAILURE); - } -}