summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zfs/zfs_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/zfs/zfs_main.c')
-rw-r--r--usr/src/cmd/zfs/zfs_main.c183
1 files changed, 138 insertions, 45 deletions
diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c
index 3fe2cd1705..e7ea903595 100644
--- a/usr/src/cmd/zfs/zfs_main.c
+++ b/usr/src/cmd/zfs/zfs_main.c
@@ -283,7 +283,9 @@ usage_prop_cb(int prop, void *cb)
(void) fprintf(fp, "\t%-13s ", zfs_prop_to_name(prop));
- if (zfs_prop_readonly(prop))
+ if (prop == ZFS_PROP_CASE)
+ (void) fprintf(fp, "NO ");
+ else if (zfs_prop_readonly(prop))
(void) fprintf(fp, " NO ");
else
(void) fprintf(fp, " YES ");
@@ -1348,6 +1350,35 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data)
upgrade_cbdata_t *cb = data;
int version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
+ if (cb->cb_version >= ZPL_VERSION_FUID) {
+ char pool_name[MAXPATHLEN];
+ zpool_handle_t *zpool_handle;
+ int spa_version;
+ char *p;
+
+ if (zfs_prop_get(zhp, ZFS_PROP_NAME, pool_name,
+ sizeof (pool_name), NULL, NULL, 0, B_FALSE) != 0)
+ return (-1);
+
+ if (p = strchr(pool_name, '/'))
+ *p = '\0';
+ if ((zpool_handle = zpool_open(g_zfs, pool_name)) == NULL)
+ return (-1);
+
+ spa_version = zpool_get_prop_int(zpool_handle,
+ ZPOOL_PROP_VERSION, NULL);
+ zpool_close(zpool_handle);
+ if (spa_version < SPA_VERSION_FUID) {
+ /* can't upgrade */
+ (void) printf(gettext("%s: can not be upgraded; "
+ "the pool version needs to first be upgraded\nto "
+ "version %d\n\n"),
+ zfs_get_name(zhp), SPA_VERSION_FUID);
+ cb->cb_numfailed++;
+ return (0);
+ }
+ }
+
/* upgrade */
if (version < cb->cb_version) {
char verstr[16];
@@ -1442,6 +1473,8 @@ zfs_do_upgrade(int argc, char **argv)
"---------------\n");
(void) printf(gettext(" 1 Initial ZFS filesystem version\n"));
(void) printf(gettext(" 2 Enhanced directory entries\n"));
+ (void) printf(gettext(" 3 Case insensitive and File system "
+ "unique identifer (FUID)\n"));
(void) printf(gettext("\nFor more information on a particular "
"version, including supported releases, see:\n\n"));
(void) printf("http://www.opensolaris.org/os/community/zfs/"
@@ -1494,7 +1527,7 @@ zfs_do_upgrade(int argc, char **argv)
* <dataset> ...
*
* -r Recurse over all children
- * -H Scripted mode; elide headers and separate colums by tabs
+ * -H Scripted mode; elide headers and separate columns by tabs
* -o Control which fields to display.
* -t Control which object types to display.
* -s Specify sort columns, descending order.
@@ -2121,7 +2154,7 @@ zfs_do_set(int argc, char **argv)
* zfs snapshot [-r] <fs@snap>
*
* Creates a snapshot with the given name. While functionally equivalent to
- * 'zfs create', it is a separate command to diffferentiate intent.
+ * 'zfs create', it is a separate command to differentiate intent.
*/
static int
zfs_do_snapshot(int argc, char **argv)
@@ -2828,15 +2861,17 @@ dataset_cmp(const void *a, const void *b)
* Share or mount a dataset.
*/
static int
-share_mount_one(zfs_handle_t *zhp, int op, int flags, boolean_t explicit,
- const char *options)
+share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
+ boolean_t explicit, const char *options)
{
char mountpoint[ZFS_MAXPROPLEN];
char shareopts[ZFS_MAXPROPLEN];
+ char smbshareopts[ZFS_MAXPROPLEN];
const char *cmdname = op == OP_SHARE ? "share" : "mount";
struct mnttab mnt;
uint64_t zoned, canmount;
zfs_type_t type = zfs_get_type(zhp);
+ boolean_t shared_nfs, shared_smb;
assert(type & (ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME));
@@ -2877,9 +2912,12 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, boolean_t explicit,
sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
+ sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
- if (op == OP_SHARE && strcmp(shareopts, "off") == 0) {
+ if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
+ strcmp(smbshareopts, "off") == 0) {
if (!explicit)
return (0);
@@ -2935,7 +2973,15 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, boolean_t explicit,
*/
switch (op) {
case OP_SHARE:
- if (zfs_is_shared_nfs(zhp, NULL)) {
+
+ shared_nfs = zfs_is_shared_nfs(zhp, NULL);
+ shared_smb = zfs_is_shared_smb(zhp, NULL);
+
+ if (shared_nfs && shared_smb ||
+ (shared_nfs && strcmp(shareopts, "on") == 0 &&
+ strcmp(smbshareopts, "off") == 0) ||
+ (shared_smb && strcmp(smbshareopts, "on") == 0 &&
+ strcmp(shareopts, "off") == 0)) {
if (!explicit)
return (0);
@@ -2949,8 +2995,23 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, boolean_t explicit,
zfs_mount(zhp, NULL, 0) != 0)
return (1);
- if (zfs_share_nfs(zhp) != 0)
+ if (protocol == NULL) {
+ if (zfs_shareall(zhp) != 0)
+ return (1);
+ } else if (strcmp(protocol, "nfs") == 0) {
+ if (zfs_share_nfs(zhp))
+ return (1);
+ } else if (strcmp(protocol, "smb") == 0) {
+ if (zfs_share_smb(zhp))
+ return (1);
+ } else {
+ (void) fprintf(stderr, gettext("cannot share "
+ "'%s': invalid share type '%s' "
+ "specified\n"),
+ zfs_get_name(zhp), protocol);
return (1);
+ }
+
break;
case OP_MOUNT:
@@ -3098,20 +3159,22 @@ share_mount(int op, int argc, char **argv)
if (do_all) {
zfs_handle_t **dslist = NULL;
size_t i, count = 0;
+ char *protocol = NULL;
if (op == OP_MOUNT) {
types = ZFS_TYPE_FILESYSTEM;
} else if (argc > 0) {
- if (strcmp(argv[0], "nfs") == 0) {
+ if (strcmp(argv[0], "nfs") == 0 ||
+ strcmp(argv[0], "smb") == 0) {
types = ZFS_TYPE_FILESYSTEM;
} else if (strcmp(argv[0], "iscsi") == 0) {
types = ZFS_TYPE_VOLUME;
} else {
(void) fprintf(stderr, gettext("share type "
- "must be 'nfs' or 'iscsi'\n"));
+ "must be 'nfs', 'smb' or 'iscsi'\n"));
usage(B_FALSE);
}
-
+ protocol = argv[0];
argc--;
argv++;
} else {
@@ -3134,8 +3197,8 @@ share_mount(int op, int argc, char **argv)
if (verbose)
report_mount_progress(i, count);
- if (share_mount_one(dslist[i], op, flags, B_FALSE,
- options) != 0)
+ if (share_mount_one(dslist[i], op, flags, protocol,
+ B_FALSE, options) != 0)
ret = 1;
zfs_close(dslist[i]);
}
@@ -3181,7 +3244,7 @@ share_mount(int op, int argc, char **argv)
if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL) {
ret = 1;
} else {
- ret = share_mount_one(zhp, op, flags, B_TRUE,
+ ret = share_mount_one(zhp, op, flags, NULL, B_TRUE,
options);
zfs_close(zhp);
}
@@ -3203,7 +3266,7 @@ zfs_do_mount(int argc, char **argv)
}
/*
- * zfs share -a [nfs | iscsi]
+ * zfs share -a [nfs | iscsi | smb]
* zfs share filesystem
*
* Share all filesystems, or share the given filesystem.
@@ -3243,7 +3306,8 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
struct stat64 statbuf;
struct extmnttab entry;
const char *cmdname = (op == OP_SHARE) ? "unshare" : "unmount";
- char property[ZFS_MAXPROPLEN];
+ char nfs_mnt_prop[ZFS_MAXPROPLEN];
+ char smbshare_prop[ZFS_MAXPROPLEN];
/*
* Search for the path in /etc/mnttab. Rather than looking for the
@@ -3283,27 +3347,31 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
return (1);
verify(zfs_prop_get(zhp, op == OP_SHARE ?
- ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, property,
- sizeof (property), NULL, NULL, 0, B_FALSE) == 0);
+ ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, nfs_mnt_prop,
+ sizeof (nfs_mnt_prop), NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, op == OP_SHARE ?
+ ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, smbshare_prop,
+ sizeof (smbshare_prop), NULL, NULL, 0, B_FALSE) == 0);
if (op == OP_SHARE) {
- if (strcmp(property, "off") == 0) {
+ if (strcmp(nfs_mnt_prop, "off") == 0 &&
+ 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"));
ret = 1;
- } else if (!zfs_is_shared_nfs(zhp, NULL)) {
+ } else if (!zfs_is_shared(zhp)) {
(void) fprintf(stderr, gettext("cannot unshare '%s': "
"not currently shared\n"), path);
ret = 1;
} else {
- ret = zfs_unshareall_nfs(zhp);
+ ret = zfs_unshareall_bypath(zhp, path);
}
} else {
if (is_manual) {
ret = zfs_unmount(zhp, NULL, flags);
- } else if (strcmp(property, "legacy") == 0) {
+ } else if (strcmp(nfs_mnt_prop, "legacy") == 0) {
(void) fprintf(stderr, gettext("cannot unmount "
"'%s': legacy mountpoint\n"),
zfs_get_name(zhp));
@@ -3331,7 +3399,8 @@ unshare_unmount(int op, int argc, char **argv)
int ret = 0;
int types, c;
zfs_handle_t *zhp;
- char property[ZFS_MAXPROPLEN];
+ char nfsiscsi_mnt_prop[ZFS_MAXPROPLEN];
+ char sharesmb[ZFS_MAXPROPLEN];
/* check options */
while ((c = getopt(argc, argv, op == OP_SHARE ? "a" : "af")) != -1) {
@@ -3412,18 +3481,31 @@ unshare_unmount(int op, int argc, char **argv)
continue;
}
- verify(zfs_prop_get(zhp, op == OP_SHARE ?
- ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT,
- property, sizeof (property), NULL, NULL,
- 0, B_FALSE) == 0);
-
- /* Ignore legacy mounts and shares */
- if ((op == OP_SHARE &&
- strcmp(property, "off") == 0) ||
- (op == OP_MOUNT &&
- strcmp(property, "legacy") == 0)) {
- zfs_close(zhp);
- continue;
+ switch (op) {
+ case OP_SHARE:
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
+ nfsiscsi_mnt_prop,
+ sizeof (nfsiscsi_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ if (strcmp(nfsiscsi_mnt_prop, "off") != 0)
+ break;
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB,
+ nfsiscsi_mnt_prop,
+ sizeof (nfsiscsi_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ if (strcmp(nfsiscsi_mnt_prop, "off") == 0)
+ continue;
+ break;
+ case OP_MOUNT:
+ /* Ignore legacy mounts */
+ verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
+ nfsiscsi_mnt_prop,
+ sizeof (nfsiscsi_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ if (strcmp(nfsiscsi_mnt_prop, "legacy") == 0)
+ continue;
+ default:
+ break;
}
node = safe_malloc(sizeof (unshare_unmount_node_t));
@@ -3463,7 +3545,7 @@ unshare_unmount(int op, int argc, char **argv)
switch (op) {
case OP_SHARE:
- if (zfs_unshare_nfs(node->un_zhp,
+ if (zfs_unshareall_bypath(node->un_zhp,
node->un_mountp) != 0)
ret = 1;
break;
@@ -3537,12 +3619,22 @@ unshare_unmount(int op, int argc, char **argv)
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
verify(zfs_prop_get(zhp, op == OP_SHARE ?
- ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT, property,
- sizeof (property), NULL, NULL, 0, B_FALSE) == 0);
+ ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT,
+ nfsiscsi_mnt_prop, sizeof (nfsiscsi_mnt_prop), NULL,
+ NULL, 0, B_FALSE) == 0);
switch (op) {
case OP_SHARE:
- if (strcmp(property, "off") == 0) {
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
+ nfsiscsi_mnt_prop,
+ sizeof (nfsiscsi_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB,
+ sharesmb, sizeof (sharesmb), NULL, NULL,
+ 0, B_FALSE) == 0);
+
+ if (strcmp(nfsiscsi_mnt_prop, "off") == 0 &&
+ strcmp(sharesmb, "off") == 0) {
(void) fprintf(stderr, gettext("cannot "
"unshare '%s': legacy share\n"),
zfs_get_name(zhp));
@@ -3550,18 +3642,18 @@ unshare_unmount(int op, int argc, char **argv)
"unshare(1M) to unshare this "
"filesystem\n"));
ret = 1;
- } else if (!zfs_is_shared_nfs(zhp, NULL)) {
+ } else if (!zfs_is_shared(zhp)) {
(void) fprintf(stderr, gettext("cannot "
"unshare '%s': not currently "
"shared\n"), zfs_get_name(zhp));
ret = 1;
- } else if (zfs_unshareall_nfs(zhp) != 0) {
+ } else if (zfs_unshareall(zhp) != 0) {
ret = 1;
}
break;
case OP_MOUNT:
- if (strcmp(property, "legacy") == 0) {
+ if (strcmp(nfsiscsi_mnt_prop, "legacy") == 0) {
(void) fprintf(stderr, gettext("cannot "
"unmount '%s': legacy "
"mountpoint\n"), zfs_get_name(zhp));
@@ -3583,10 +3675,11 @@ unshare_unmount(int op, int argc, char **argv)
} else {
assert(op == OP_SHARE);
- verify(zfs_prop_get(zhp, ZFS_PROP_SHAREISCSI, property,
- sizeof (property), NULL, NULL, 0, B_FALSE) == 0);
+ verify(zfs_prop_get(zhp, ZFS_PROP_SHAREISCSI,
+ nfsiscsi_mnt_prop, sizeof (nfsiscsi_mnt_prop),
+ NULL, NULL, 0, B_FALSE) == 0);
- if (strcmp(property, "off") == 0) {
+ if (strcmp(nfsiscsi_mnt_prop, "off") == 0) {
(void) fprintf(stderr, gettext("cannot unshare "
"'%s': 'shareiscsi' property not set\n"),
zfs_get_name(zhp));