X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=cmd%2Fzfs%2Fzfs_main.c;h=b6dc6d49d3b7c47a0fa76f700dae812071e196b8;hb=e0f86c98620bbc085a7edddd8f6dbf82e4783a46;hp=8d75d2a457c0fbca334ca8bac973b613ff906ba4;hpb=9a616b5d17185c7fa5cd0d39ff8bc101cad8466d;p=zfs.git diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 8d75d2a..b6dc6d4 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -238,7 +238,7 @@ get_usage(zfs_help_t idx) case HELP_ROLLBACK: return (gettext("\trollback [-rRf] \n")); case HELP_SEND: - return (gettext("\tsend [-RDp] [-[iI] snapshot] \n")); + return (gettext("\tsend [-vRDp] [-[iI] snapshot] \n")); case HELP_SET: return (gettext("\tset " " ...\n")); @@ -318,7 +318,6 @@ safe_malloc(size_t size) return (data); } -#ifdef HAVE_ZPL static char * safe_strdup(char *str) { @@ -329,7 +328,6 @@ safe_strdup(char *str) return (dupstr); } -#endif /* HAVE_ZPL */ /* * Callback routine that will print out information for each of @@ -497,7 +495,6 @@ parse_depth(char *opt, int *flags) #define PROGRESS_DELAY 2 /* seconds */ -#ifdef HAVE_ZPL static char *pt_reverse = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; static time_t pt_begin; static char *pt_header = NULL; @@ -549,7 +546,6 @@ finish_progress(char *done) free(pt_header); pt_header = NULL; } -#endif /* HAVE_ZPL */ /* * zfs clone [-p] [-o prop=value] ... @@ -631,7 +627,6 @@ zfs_do_clone(int argc, char **argv) ret = zfs_clone(zhp, argv[1], props); /* create the mountpoint if necessary */ -#ifdef HAVE_ZPL if (ret == 0) { zfs_handle_t *clone; @@ -643,7 +638,6 @@ zfs_do_clone(int argc, char **argv) zfs_close(clone); } } -#endif /* HAVE_ZPL */ zfs_close(zhp); nvlist_free(props); @@ -831,7 +825,6 @@ zfs_do_create(int argc, char **argv) * verbose error message to let the user know that their filesystem was * in fact created, even if we failed to mount or share it. */ -#ifdef HAVE_ZPL if (canmount == ZFS_CANMOUNT_ON) { if (zfs_mount(zhp, NULL, 0) != 0) { (void) fprintf(stderr, gettext("filesystem " @@ -843,7 +836,6 @@ zfs_do_create(int argc, char **argv) ret = 1; } } -#endif /* HAVE_ZPL */ error: if (zhp) @@ -1887,16 +1879,6 @@ zfs_do_userspace(int argc, char **argv) zfs_userquota_prop_t p; int error; - /* - * Try the python version. If the execv fails, we'll continue - * and do a simplistic implementation. - */ - (void) execv(pypath, argv-1); - - (void) printf("internal error: %s not found\n" - "falling back on built-in implementation, " - "some features will not work\n", pypath); - if ((zhp = zfs_open(g_zfs, argv[argc-1], ZFS_TYPE_DATASET)) == NULL) return (1); @@ -2340,7 +2322,6 @@ typedef struct rollback_cbdata { * 'cb_dependent' is set, then this is a dependent and we should report it * without checking the transaction group. */ -#ifdef HAVE_ZPL static int rollback_check(zfs_handle_t *zhp, void *data) { @@ -2400,12 +2381,10 @@ rollback_check(zfs_handle_t *zhp, void *data) zfs_close(zhp); return (0); } -#endif /* HAVE_ZPL */ static int zfs_do_rollback(int argc, char **argv) { -#ifdef HAVE_ZPL int ret; int c; boolean_t force = B_FALSE; @@ -2487,9 +2466,6 @@ out: return (0); else return (1); -#else - return ENOSYS; -#endif /*HAVE_ZPL*/ } /* @@ -2955,7 +2931,6 @@ zfs_do_release(int argc, char **argv) #define SPINNER_TIME 3 /* seconds */ #define MOUNT_TIME 5 /* seconds */ -#ifdef HAVE_ZPL static int get_one_dataset(zfs_handle_t *zhp, void *data) { @@ -3400,7 +3375,6 @@ share_mount(int op, int argc, char **argv) return (ret); } -#endif /* HAVE_ZPL */ /* * zfs mount -a [nfs] @@ -3411,11 +3385,7 @@ share_mount(int op, int argc, char **argv) static int zfs_do_mount(int argc, char **argv) { -#ifdef HAVE_ZPL return (share_mount(OP_MOUNT, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } /* @@ -3427,14 +3397,9 @@ zfs_do_mount(int argc, char **argv) static int zfs_do_share(int argc, char **argv) { -#ifdef HAVE_ZPL return (share_mount(OP_SHARE, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } -#ifdef HAVE_ZPL typedef struct unshare_unmount_node { zfs_handle_t *un_zhp; char *un_mountp; @@ -3818,7 +3783,6 @@ unshare_unmount(int op, int argc, char **argv) return (ret); } -#endif /* HAVE_ZPL */ /* * zfs unmount -a @@ -3829,11 +3793,7 @@ unshare_unmount(int op, int argc, char **argv) static int zfs_do_unmount(int argc, char **argv) { -#ifdef HAVE_ZPL return (unshare_unmount(OP_MOUNT, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } /* @@ -3845,11 +3805,7 @@ zfs_do_unmount(int argc, char **argv) static int zfs_do_unshare(int argc, char **argv) { -#ifdef HAVE_ZPL return (unshare_unmount(OP_SHARE, argc, argv)); -#else - return ENOSYS; -#endif /* HAVE_ZPL */ } /* ARGSUSED */ @@ -3861,369 +3817,6 @@ zfs_do_python(int argc, char **argv) return (-1); } -typedef struct option_map { - const char *name; - int mask; -} option_map_t; - -static const option_map_t option_map[] = { - /* Canonicalized filesystem independent options from mount(8) */ - { MNTOPT_NOAUTO, MS_COMMENT }, - { MNTOPT_DEFAULTS, MS_COMMENT }, - { MNTOPT_NODEVICES, MS_NODEV }, - { MNTOPT_DIRSYNC, MS_DIRSYNC }, - { MNTOPT_NOEXEC, MS_NOEXEC }, - { MNTOPT_GROUP, MS_GROUP }, - { MNTOPT_NETDEV, MS_COMMENT }, - { MNTOPT_NOFAIL, MS_COMMENT }, - { MNTOPT_NOSUID, MS_NOSUID }, - { MNTOPT_OWNER, MS_OWNER }, - { MNTOPT_REMOUNT, MS_REMOUNT }, - { MNTOPT_RO, MS_RDONLY }, - { MNTOPT_SYNC, MS_SYNCHRONOUS }, - { MNTOPT_USER, MS_USERS }, - { MNTOPT_USERS, MS_USERS }, -#ifdef MS_NOATIME - { MNTOPT_NOATIME, MS_NOATIME }, -#endif -#ifdef MS_NODIRATIME - { MNTOPT_NODIRATIME, MS_NODIRATIME }, -#endif -#ifdef MS_RELATIME - { MNTOPT_RELATIME, MS_RELATIME }, -#endif -#ifdef MS_STRICTATIME - { MNTOPT_DFRATIME, MS_STRICTATIME }, -#endif -#ifdef HAVE_SELINUX - { MNTOPT_CONTEXT, MS_COMMENT }, - { MNTOPT_FSCONTEXT, MS_COMMENT }, - { MNTOPT_DEFCONTEXT, MS_COMMENT }, - { MNTOPT_ROOTCONTEXT, MS_COMMENT }, -#endif -#ifdef MS_I_VERSION - { MNTOPT_IVERSION, MS_I_VERSION }, -#endif -#ifdef MS_MANDLOCK - { MNTOPT_NBMAND, MS_MANDLOCK }, -#endif - /* Valid options not found in mount(8) */ - { MNTOPT_BIND, MS_BIND }, - { MNTOPT_RBIND, MS_BIND|MS_REC }, - { MNTOPT_COMMENT, MS_COMMENT }, - { MNTOPT_BOOTWAIT, MS_COMMENT }, - { MNTOPT_NOBOOTWAIT, MS_COMMENT }, - { MNTOPT_OPTIONAL, MS_COMMENT }, - { MNTOPT_SHOWTHROUGH, MS_COMMENT }, -#ifdef MS_NOSUB - { MNTOPT_NOSUB, MS_NOSUB }, -#endif -#ifdef MS_SILENT - { MNTOPT_QUIET, MS_SILENT }, -#endif - /* Custom zfs options */ - { MNTOPT_NOXATTR, MS_COMMENT }, - { NULL, 0 } }; - -/* - * Break the mount option in to a name/value pair. The name is - * validated against the option map and mount flags set accordingly. - */ -static int -parse_option(char *mntopt, unsigned long *mntflags, int sloppy) -{ - const option_map_t *opt; - char *ptr, *name, *value = NULL; - int rc; - - name = strdup(mntopt); - if (name == NULL) - return (ENOMEM); - - for (ptr = name; ptr && *ptr; ptr++) { - if (*ptr == '=') { - *ptr = '\0'; - value = ptr+1; - break; - } - } - - for (opt = option_map; opt->name != NULL; opt++) { - if (strncmp(name, opt->name, strlen(name)) == 0) { - *mntflags |= opt->mask; - - /* MS_USERS implies default user options */ - if (opt->mask & (MS_USERS)) - *mntflags |= (MS_NOEXEC|MS_NOSUID|MS_NODEV); - - /* MS_OWNER|MS_GROUP imply default owner options */ - if (opt->mask & (MS_OWNER | MS_GROUP)) - *mntflags |= (MS_NOSUID|MS_NODEV); - - rc = 0; - goto out; - } - } - - if (!sloppy) - rc = ENOENT; -out: - /* If required further process on the value may be done here */ - free(name); - return (rc); -} - -/* - * Translate the mount option string in to MS_* mount flags for the - * kernel vfs. When sloppy is non-zero unknown options will be ignored - * otherwise they are considered fatal are copied in to badopt. - */ -static int -parse_options(char *mntopts, unsigned long *mntflags, int sloppy, char *badopt) -{ - int rc = 0, quote = 0; - char *ptr, *opt, *opts; - - opts = strdup(mntopts); - if (opts == NULL) - return (ENOMEM); - - *mntflags = 0; - opt = NULL; - - /* - * Scan through all mount options which must be comma delimited. - * We must be careful to notice regions which are double quoted - * and skip commas in these regions. Each option is then checked - * to determine if it is a known option. - */ - for (ptr = opts; ptr && *ptr; ptr++) { - if (opt == NULL) - opt = ptr; - - if (*ptr == '"') - quote = !quote; - - if (quote) - continue; - - if ((*ptr == ',') || (*ptr == '\0')) { - *ptr = '\0'; - rc = parse_option(opt, mntflags, sloppy); - if (rc) { - strcpy(badopt, opt); - goto out; - } - - opt = NULL; - } - } -out: - free(opts); - return (rc); -} - -/* - * Called when invoked as /sbin/mount.zfs, mount helper for mount(8). - */ -static int -manual_mount(int argc, char **argv) -{ - zfs_handle_t *zhp; - char legacy[ZFS_MAXPROPLEN]; - char mntopts[MNT_LINE_MAX] = { '\0' }; - char badopt[MNT_LINE_MAX] = { '\0' }; - char *dataset, *mntpoint; - unsigned long mntflags; - int sloppy = 0, fake = 0, verbose = 0; - int rc, c; - - /* check options */ - while ((c = getopt(argc, argv, "sfnvo:h?")) != -1) { - switch (c) { - case 's': - sloppy = 1; - break; - case 'f': - fake = 1; - break; - case 'n': - /* Ignored, handled by mount(8) */ - break; - case 'v': - verbose++; - break; - case 'o': - (void) strlcpy(mntopts, optarg, sizeof (mntopts)); - break; - case 'h': - case '?': - (void) fprintf(stderr, gettext("Invalid option '%c'\n"), - optopt); - (void) fprintf(stderr, gettext("Usage: mount.zfs " - "[-sfnv] [-o options] \n")); - return (MOUNT_USAGE); - } - } - - argc -= optind; - argv += optind; - - /* check that we only have two arguments */ - if (argc != 2) { - if (argc == 0) - (void) fprintf(stderr, gettext("missing dataset " - "argument\n")); - else if (argc == 1) - (void) fprintf(stderr, - gettext("missing mountpoint argument\n")); - else - (void) fprintf(stderr, gettext("too many arguments\n")); - (void) fprintf(stderr, "usage: mount \n"); - return (MOUNT_USAGE); - } - - dataset = argv[0]; - mntpoint = argv[1]; - - /* try to open the dataset to access the mount point */ - if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) { - (void) fprintf(stderr, gettext("filesystem '%s' cannot be " - "mounted, unable to open the dataset\n"), dataset); - return (MOUNT_USAGE); - } - - (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, legacy, - sizeof (legacy), NULL, NULL, 0, B_FALSE); - - zfs_close(zhp); - - /* check for legacy mountpoint or util mount option */ - if ((!strcmp(legacy, ZFS_MOUNTPOINT_LEGACY) == 0) && - (strstr(mntopts, MNTOPT_ZFSUTIL) == NULL)) { - (void) fprintf(stderr, gettext("filesystem '%s' cannot be " - "mounted using 'mount -a -t zfs'\n"), dataset); - (void) fprintf(stderr, gettext("Use 'zfs set mountpoint=%s' " - "instead.\n"), mntpoint); - (void) fprintf(stderr, gettext("If you must use 'mount -a -t " - "zfs' or /etc/fstab, use 'zfs set mountpoint=legacy'.\n")); - (void) fprintf(stderr, gettext("See zfs(8) for more " - "information.\n")); - return (MOUNT_USAGE); - } - - /* validate mount options and set mntflags */ - rc = parse_options(mntopts, &mntflags, sloppy, badopt); - if (rc) { - switch (rc) { - case ENOMEM: - (void) fprintf(stderr, gettext("filesystem '%s' " - "cannot be mounted due to a memory allocation " - "failure\n"), dataset); - return (MOUNT_SYSERR); - case EINVAL: - (void) fprintf(stderr, gettext("filesystem '%s' " - "cannot be mounted of due to the invalid option " - "'%s'\n"), dataset, badopt); - (void) fprintf(stderr, gettext("Use the '-s' option " - "to ignore the bad mount option.\n")); - return (MOUNT_USAGE); - default: - (void) fprintf(stderr, gettext("filesystem '%s' " - "cannot be mounted due to internal error %d\n"), - dataset, rc); - return (MOUNT_SOFTWARE); - } - } - - if (verbose > 2) - printf("mount.zfs: dataset: \"%s\", mountpoint: \"%s\" " - "mountflags: 0x%lx, mountopts: \"%s\"\n", dataset, - mntpoint, mntflags, mntopts); - - /* load the zfs posix layer module (zpl) */ - if (libzfs_load_module("zpl")) { - (void) fprintf(stderr, gettext("filesystem '%s' cannot be " - "mounted without the zpl kernel module\n"), dataset); - (void) fprintf(stderr, gettext("Use 'dmesg' to determine why " - "the module could not be loaded.\n")); - return (MOUNT_SYSERR); - } - - if (!fake) { - rc = mount(dataset, mntpoint, MNTTYPE_ZFS, mntflags, mntopts); - if (rc) { - (void) fprintf(stderr, gettext("filesystem '%s' can" - "not be mounted due to error %d\n"), dataset, rc); - return (MOUNT_USAGE); - } - } - - return (MOUNT_SUCCESS); -} - -#ifdef HAVE_UNMOUNT_HELPER -/* - * Called when invoked as /sbin/umount.zfs, mount helper for mount(8). - * Unlike a manual mount, we allow unmounts of non-legacy filesystems, - * as this is the dominant administrative interface. - */ -static int -manual_unmount(int argc, char **argv) -{ - int verbose = 0, flags = 0; - int c; - - /* check options */ - while ((c = getopt(argc, argv, "nlfvrh?")) != -1) { - switch (c) { - case 'n': - /* Ignored, handled by mount(8) */ - break; - case 'l': - flags = MS_DETACH; - break; - case 'f': - flags = MS_FORCE; - break; - case 'v': - verbose++; - break; - case 'r': - /* Remount read-only on umount failure, unsupported */ - (void) fprintf(stderr, gettext("Unsupported option " - "'%c'\n"), optopt); - return (MOUNT_USAGE); - case 'h': - case '?': - (void) fprintf(stderr, gettext("Invalid option '%c'\n"), - optopt); - (void) fprintf(stderr, gettext("Usage: umount.zfs " - "[-nlfvr] \n")); - return (MOUNT_USAGE); - } - } - - argc -= optind; - argv += optind; - - /* check that we only have one argument */ - if (argc != 1) { - if (argc == 0) - (void) fprintf(stderr, gettext("missing mountpoint " - "argument\n")); - else - (void) fprintf(stderr, gettext("too many arguments\n")); - - (void) fprintf(stderr, gettext("Usage: umount.zfs [-nlfvr] " - "\n")); - return (MOUNT_USAGE); - } - - return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE)); -} -#endif /* HAVE_UNMOUNT_HELPER */ - static int find_command_idx(char *command, int *idx) { @@ -4321,7 +3914,6 @@ main(int argc, char **argv) { int ret; int i = 0; - char *progname; char *cmdname; (void) setlocale(LC_ALL, ""); @@ -4336,78 +3928,64 @@ main(int argc, char **argv) } /* - * This command also doubles as the /etc/fs mount and unmount program. - * Determine if we should take this behavior based on argv[0]. + * Make sure the user has specified some command. */ - progname = basename(argv[0]); - if (strcmp(progname, "mount.zfs") == 0) { - ret = manual_mount(argc, argv); -#ifdef HAVE_UNMOUNT_HELPER - } else if (strcmp(progname, "umount.zfs") == 0) { - ret = manual_unmount(argc, argv); -#endif /* HAVE_UNMOUNT_HELPER */ - } else { - /* - * Make sure the user has specified some command. - */ - if (argc < 2) { - (void) fprintf(stderr, gettext("missing command\n")); - usage(B_FALSE); - } + if (argc < 2) { + (void) fprintf(stderr, gettext("missing command\n")); + usage(B_FALSE); + } - cmdname = argv[1]; + cmdname = argv[1]; - /* - * The 'umount' command is an alias for 'unmount' - */ - if (strcmp(cmdname, "umount") == 0) - cmdname = "unmount"; + /* + * The 'umount' command is an alias for 'unmount' + */ + if (strcmp(cmdname, "umount") == 0) + cmdname = "unmount"; - /* - * The 'recv' command is an alias for 'receive' - */ - if (strcmp(cmdname, "recv") == 0) - cmdname = "receive"; + /* + * The 'recv' command is an alias for 'receive' + */ + if (strcmp(cmdname, "recv") == 0) + cmdname = "receive"; - /* - * Special case '-?' - */ - if ((strcmp(cmdname, "-?") == 0) || - (strcmp(cmdname, "--help") == 0)) - usage(B_TRUE); + /* + * Special case '-?' + */ + if ((strcmp(cmdname, "-?") == 0) || + (strcmp(cmdname, "--help") == 0)) + usage(B_TRUE); - if ((g_zfs = libzfs_init()) == NULL) - return (1); + if ((g_zfs = libzfs_init()) == NULL) + return (1); - zpool_set_history_str("zfs", argc, argv, history_str); - verify(zpool_stage_history(g_zfs, history_str) == 0); + zpool_set_history_str("zfs", argc, argv, history_str); + verify(zpool_stage_history(g_zfs, history_str) == 0); - libzfs_print_on_error(g_zfs, B_TRUE); + libzfs_print_on_error(g_zfs, B_TRUE); - /* - * Run the appropriate command. - */ - libzfs_mnttab_cache(g_zfs, B_TRUE); - if (find_command_idx(cmdname, &i) == 0) { - current_command = &command_table[i]; - ret = command_table[i].func(argc - 1, argv + 1); - } else if (strchr(cmdname, '=') != NULL) { - verify(find_command_idx("set", &i) == 0); - current_command = &command_table[i]; - ret = command_table[i].func(argc, argv); - } else { - (void) fprintf(stderr, gettext("unrecognized " - "command '%s'\n"), cmdname); - usage(B_FALSE); - ret = 1; - } - libzfs_mnttab_cache(g_zfs, B_FALSE); + /* + * Run the appropriate command. + */ + libzfs_mnttab_cache(g_zfs, B_TRUE); + if (find_command_idx(cmdname, &i) == 0) { + current_command = &command_table[i]; + ret = command_table[i].func(argc - 1, argv + 1); + } else if (strchr(cmdname, '=') != NULL) { + verify(find_command_idx("set", &i) == 0); + current_command = &command_table[i]; + ret = command_table[i].func(argc, argv); + } else { + (void) fprintf(stderr, gettext("unrecognized " + "command '%s'\n"), cmdname); + usage(B_FALSE); + ret = 1; } + libzfs_mnttab_cache(g_zfs, B_FALSE); + libzfs_fini(g_zfs); (void) fclose(mnttab_file); - libzfs_fini(g_zfs); - /* * The 'ZFS_ABORT' environment variable causes us to dump core on exit * for the purposes of running ::findleaks.