return (data);
}
-#ifdef HAVE_ZPL
static char *
safe_strdup(char *str)
{
return (dupstr);
}
-#endif /* HAVE_ZPL */
/*
* Callback routine that will print out information for each of
#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;
free(pt_header);
pt_header = NULL;
}
-#endif /* HAVE_ZPL */
/*
* zfs clone [-p] [-o prop=value] ... <snap> <fs | vol>
ret = zfs_clone(zhp, argv[1], props);
/* create the mountpoint if necessary */
-#ifdef HAVE_ZPL
if (ret == 0) {
zfs_handle_t *clone;
zfs_close(clone);
}
}
-#endif /* HAVE_ZPL */
zfs_close(zhp);
nvlist_free(props);
* 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 "
ret = 1;
}
}
-#endif /* HAVE_ZPL */
error:
if (zhp)
* '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)
{
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;
return (0);
else
return (1);
-#else
- return ENOSYS;
-#endif /*HAVE_ZPL*/
}
/*
#define SPINNER_TIME 3 /* seconds */
#define MOUNT_TIME 5 /* seconds */
-#ifdef HAVE_ZPL
static int
get_one_dataset(zfs_handle_t *zhp, void *data)
{
int flags = 0;
/* check options */
- while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:O" : "a"))
+ while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:" : "a"))
!= -1) {
switch (c) {
case 'a':
append_options(options, optarg);
break;
- case 'O':
- flags |= MS_OVERLAY;
- break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
"'%c' option\n"), optopt);
}
/*
- * When mount is given no arguments, go through /etc/mnttab and
+ * When mount is given no arguments, go through /etc/mtab and
* display any active ZFS mounts. We hide any snapshots, since
* they are controlled automatically.
*/
return (ret);
}
-#endif /* HAVE_ZPL */
/*
* zfs mount -a [nfs]
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 */
}
/*
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;
/*
* Convenience routine used by zfs_do_umount() and manual_unmount(). Given an
- * absolute path, find the entry /etc/mnttab, verify that its a ZFS filesystem,
+ * absolute path, find the entry /etc/mtab, verify that its a ZFS filesystem,
* and unmount it appropriately.
*/
static int
ino_t path_inode;
/*
- * Search for the path in /etc/mnttab. Rather than looking for the
+ * Search for the path in /etc/mtab. Rather than looking for the
* specific path, which can be fooled by non-standard paths (i.e. ".."
* or "//"), we stat() the path and search for the corresponding
* (major,minor) device pair.
"currently mounted\n"), cmdname, path);
return (1);
}
- (void) fprintf(stderr, gettext("warning: %s not in mnttab\n"),
+ (void) fprintf(stderr, gettext("warning: %s not in mtab\n"),
path);
if ((ret = umount2(path, flags)) != 0)
(void) fprintf(stderr, gettext("%s: %s\n"), path,
strcmp(smbshare_prop, "off") == 0) {
(void) fprintf(stderr, gettext("cannot unshare "
"'%s': legacy share\n"), path);
- (void) fprintf(stderr, gettext("use "
- "unshare(1M) to unshare this filesystem\n"));
+ (void) fprintf(stderr, gettext("use exportfs(8) "
+ "or smbcontrol(1) to unshare this filesystem\n"));
} else if (!zfs_is_shared(zhp)) {
(void) fprintf(stderr, gettext("cannot unshare '%s': "
"not currently shared\n"), path);
(void) fprintf(stderr, gettext("cannot unmount "
"'%s': legacy mountpoint\n"),
zfs_get_name(zhp));
- (void) fprintf(stderr, gettext("use umount(1M) "
+ (void) fprintf(stderr, gettext("use umount(8) "
"to unmount this filesystem\n"));
} else {
ret = zfs_unmountall(zhp, flags);
/*
* We could make use of zfs_for_each() to walk all datasets in
* the system, but this would be very inefficient, especially
- * since we would have to linearly search /etc/mnttab for each
- * one. Instead, do one pass through /etc/mnttab looking for
+ * since we would have to linearly search /etc/mtab for each
+ * one. Instead, do one pass through /etc/mtab looking for
* zfs entries and call zfs_unmount() for each one.
*
* Things get a little tricky if the administrator has created
return (ret);
}
-#endif /* HAVE_ZPL */
/*
* zfs unmount -a
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 */
}
/*
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 */
else
(void) fprintf(stderr, gettext("too many arguments\n"));
(void) fprintf(stderr, "usage: mount <dataset> <mountpoint>\n");
- return (2);
+ return (MOUNT_USAGE);
}
dataset = argv[0];
- path = argv[1];
+ mntpoint = argv[1];
- /* try to open the dataset */
- if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_FILESYSTEM)) == NULL)
- return (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, mountpoint,
- sizeof (mountpoint), NULL, NULL, 0, B_FALSE);
+ (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, legacy,
+ sizeof (legacy), NULL, NULL, 0, B_FALSE);
- /* check for legacy mountpoint and complain appropriately */
- ret = 0;
- if (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) {
- if (mount(dataset, path, MS_OPTIONSTR | flags, MNTTYPE_ZFS,
- NULL, 0, mntopts, sizeof (mntopts)) != 0) {
- (void) fprintf(stderr, gettext("mount failed: %s\n"),
- strerror(errno));
- ret = 1;
- }
- } else {
+ 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 -F zfs'\n"), dataset);
+ "mounted using 'mount -a -t zfs'\n"), dataset);
(void) fprintf(stderr, gettext("Use 'zfs set mountpoint=%s' "
- "instead.\n"), path);
- (void) fprintf(stderr, gettext("If you must use 'mount -F zfs' "
- "or /etc/vfstab, use 'zfs set mountpoint=legacy'.\n"));
- (void) fprintf(stderr, gettext("See zfs(1M) for more "
+ "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"));
- ret = 1;
+ 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);
+ }
}
- return (ret);
+ 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 /etc/fs/zfs/umount. Unlike a manual mount, we allow
- * unmounts of non-legacy filesystems, as this is the dominant administrative
- * interface.
+ * 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 flags = 0;
+ int verbose = 0, flags = 0;
int c;
/* check options */
- while ((c = getopt(argc, argv, "f")) != -1) {
+ 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"),
+ (void) fprintf(stderr, gettext("Invalid option '%c'\n"),
optopt);
- (void) fprintf(stderr, gettext("usage: unmount [-f] "
- "<path>\n"));
- return (2);
+ (void) fprintf(stderr, gettext("Usage: umount.zfs "
+ "[-nlfvr] <mountpoint>\n"));
+ return (MOUNT_USAGE);
}
}
argc -= optind;
argv += optind;
- /* check arguments */
+ /* check that we only have one argument */
if (argc != 1) {
if (argc == 0)
- (void) fprintf(stderr, gettext("missing path "
+ (void) fprintf(stderr, gettext("missing mountpoint "
"argument\n"));
else
(void) fprintf(stderr, gettext("too many arguments\n"));
- (void) fprintf(stderr, gettext("usage: unmount [-f] <path>\n"));
- return (2);
+
+ (void) fprintf(stderr, gettext("Usage: umount.zfs [-nlfvr] "
+ "<mountpoint>\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)
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.