#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <inttypes.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <locale.h>
#include <fuse.h>
#include <guestfs.h>
dir_cache_invalidate (path);
- return -ENOSYS; /* XXX */
+ /* See fg_read. */
+ const size_t limit = 2 * 1024 * 1024;
+ if (size > limit)
+ size = limit;
+
+ int r;
+ r = guestfs_pwrite (g, path, buf, size, offset);
+ if (r == -1)
+ return error ();
+
+ return r;
}
static int
struct drv {
struct drv *next;
char *filename;
+ const char *format;
};
struct mp {
"Options:\n"
" -a|--add image Add image\n"
" --dir-cache-timeout Set readdir cache timeout (default 5 sec)\n"
+ " --format[=raw|..] Force disk format for -a option\n"
" --fuse-help Display extra FUSE options\n"
" --help Display help message and exit\n"
" -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n"
static const struct option long_options[] = {
{ "add", 1, 0, 'a' },
{ "dir-cache-timeout", 1, 0, 0 },
+ { "format", 2, 0, 0 },
{ "fuse-help", 0, 0, 0 },
{ "help", 0, 0, HELP_OPTION },
{ "mount", 1, 0, 'm' },
struct mp *mps = NULL;
struct mp *mp;
char *p;
- int c, i, r;
+ const char *format = NULL;
+ int c, r;
int option_index;
struct sigaction sa;
guestfs_set_trace (g, 1);
guestfs_set_recovery_proc (g, 1);
}
+ else if (STREQ (long_options[option_index].name, "format")) {
+ if (!optarg || STREQ (optarg, ""))
+ format = NULL;
+ else
+ format = optarg;
+ }
else {
fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
program_name, long_options[option_index].name, option_index);
exit (EXIT_FAILURE);
}
drv->filename = optarg;
+ drv->format = format;
drv->next = drvs;
drvs = drv;
break;
guestfs_set_verbose (g, verbose);
break;
- case 'V':
- printf ("%s %s\n", program_name, PACKAGE_VERSION);
+ case 'V': {
+ struct guestfs_version *v = guestfs_version (g);
+ printf ("%s %"PRIi64".%"PRIi64".%"PRIi64"%s\n", program_name,
+ v->major, v->minor, v->release, v->extra);
exit (EXIT_SUCCESS);
+ }
case HELP_OPTION:
usage (EXIT_SUCCESS);
add_drives (struct drv *drv)
{
int r;
+ struct guestfs_add_drive_opts_argv ad_optargs;
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);
+
+ ad_optargs.bitmask = 0;
+ if (read_only) {
+ ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK;
+ ad_optargs.readonly = 1;
+ }
+ if (drv->format) {
+ ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK;
+ ad_optargs.format = drv->format;
+ }
+ r = guestfs_add_drive_opts_argv (g, drv->filename, &ad_optargs);
if (r == -1)
exit (EXIT_FAILURE);
}
if (mp) {
mount_mps (mp->next);
- if (!read_only)
- r = guestfs_mount (g, mp->device, mp->mountpoint);
- else
- r = guestfs_mount_ro (g, mp->device, mp->mountpoint);
+
+ /* 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);
}