diff options
Diffstat (limited to 'usr/src/cmd/zfs/zfs_main.c')
-rw-r--r-- | usr/src/cmd/zfs/zfs_main.c | 183 |
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)); |