60 static int zfs_do_clone(int argc, char **argv);
61 static int zfs_do_create(int argc, char **argv);
62 static int zfs_do_destroy(int argc, char **argv);
63 static int zfs_do_get(int argc, char **argv);
64 static int zfs_do_inherit(int argc, char **argv);
65 static int zfs_do_list(int argc, char **argv);
66 static int zfs_do_mount(int argc, char **argv);
67 static int zfs_do_rename(int argc, char **argv);
68 static int zfs_do_rollback(int argc, char **argv);
69 static int zfs_do_set(int argc, char **argv);
70 static int zfs_do_upgrade(int argc, char **argv);
71 static int zfs_do_snapshot(int argc, char **argv);
72 static int zfs_do_unmount(int argc, char **argv);
73 static int zfs_do_share(int argc, char **argv);
74 static int zfs_do_unshare(int argc, char **argv);
75 static int zfs_do_send(int argc, char **argv);
76 static int zfs_do_receive(int argc, char **argv);
77 static int zfs_do_promote(int argc, char **argv);
78 static int zfs_do_allow(int argc, char **argv);
79 static int zfs_do_unallow(int argc, char **argv);
80
81 /*
82 * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
83 */
84
85 #ifdef DEBUG
86 const char *
87 _umem_debug_init(void)
88 {
89 return ("default,verbose"); /* $UMEM_DEBUG setting */
90 }
91
92 const char *
93 _umem_logging_init(void)
94 {
95 return ("fail,contents"); /* $UMEM_LOGGING setting */
96 }
97 #endif
98
99 typedef enum {
100 HELP_CLONE,
101 HELP_CREATE,
102 HELP_DESTROY,
103 HELP_GET,
104 HELP_INHERIT,
105 HELP_UPGRADE,
106 HELP_LIST,
107 HELP_MOUNT,
108 HELP_PROMOTE,
109 HELP_RECEIVE,
110 HELP_RENAME,
111 HELP_ROLLBACK,
112 HELP_SEND,
113 HELP_SET,
114 HELP_SHARE,
115 HELP_SNAPSHOT,
116 HELP_UNMOUNT,
117 HELP_UNSHARE,
118 HELP_ALLOW,
119 HELP_UNALLOW
120 } zfs_help_t;
121
122 typedef struct zfs_command {
123 const char *name;
124 int (*func)(int argc, char **argv);
125 zfs_help_t usage;
126 } zfs_command_t;
127
128 /*
129 * Master command table. Each ZFS command has a name, associated function, and
130 * usage message. The usage messages need to be internationalized, so we have
131 * to have a function to return the usage message based on a command index.
132 *
133 * These commands are organized according to how they are displayed in the usage
134 * message. An empty command (one with a NULL name) indicates an empty line in
135 * the generic usage message.
136 */
137 static zfs_command_t command_table[] = {
138 { "create", zfs_do_create, HELP_CREATE },
139 { "destroy", zfs_do_destroy, HELP_DESTROY },
145 { "rename", zfs_do_rename, HELP_RENAME },
146 { NULL },
147 { "list", zfs_do_list, HELP_LIST },
148 { NULL },
149 { "set", zfs_do_set, HELP_SET },
150 { "get", zfs_do_get, HELP_GET },
151 { "inherit", zfs_do_inherit, HELP_INHERIT },
152 { "upgrade", zfs_do_upgrade, HELP_UPGRADE },
153 { NULL },
154 { "mount", zfs_do_mount, HELP_MOUNT },
155 { "unmount", zfs_do_unmount, HELP_UNMOUNT },
156 { "share", zfs_do_share, HELP_SHARE },
157 { "unshare", zfs_do_unshare, HELP_UNSHARE },
158 { NULL },
159 { "send", zfs_do_send, HELP_SEND },
160 { "receive", zfs_do_receive, HELP_RECEIVE },
161 { NULL },
162 { "allow", zfs_do_allow, HELP_ALLOW },
163 { NULL },
164 { "unallow", zfs_do_unallow, HELP_UNALLOW },
165 };
166
167 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
168
169 zfs_command_t *current_command;
170
171 static const char *
172 get_usage(zfs_help_t idx)
173 {
174 switch (idx) {
175 case HELP_CLONE:
176 return (gettext("\tclone [-p] [-o property=value] ... "
177 "<snapshot> <filesystem|volume>\n"));
178 case HELP_CREATE:
179 return (gettext("\tcreate [-p] [-o property=value] ... "
180 "<filesystem>\n"
181 "\tcreate [-ps] [-b blocksize] [-o property=value] ... "
182 "-V <size> <volume>\n"));
183 case HELP_DESTROY:
184 return (gettext("\tdestroy [-rRf] "
233 "<-a | filesystem|mountpoint>\n"));
234 case HELP_ALLOW:
235 return (gettext("\tallow [-ldug] "
236 "<\"everyone\"|user|group>[,...] <perm|@setname>[,...]\n"
237 "\t <filesystem|volume>\n"
238 "\tallow [-ld] -e <perm|@setname>[,...] "
239 "<filesystem|volume>\n"
240 "\tallow -c <perm|@setname>[,...] <filesystem|volume>\n"
241 "\tallow -s @setname <perm|@setname>[,...] "
242 "<filesystem|volume>\n"));
243 case HELP_UNALLOW:
244 return (gettext("\tunallow [-rldug] "
245 "<\"everyone\"|user|group>[,...]\n"
246 "\t [<perm|@setname>[,...]] <filesystem|volume>\n"
247 "\tunallow [-rld] -e [<perm|@setname>[,...]] "
248 "<filesystem|volume>\n"
249 "\tunallow [-r] -c [<perm|@setname>[,...]] "
250 "<filesystem|volume>\n"
251 "\tunallow [-r] -s @setname [<perm|@setname>[,...]] "
252 "<filesystem|volume>\n"));
253 }
254
255 abort();
256 /* NOTREACHED */
257 }
258
259 /*
260 * Utility function to guarantee malloc() success.
261 */
262 void *
263 safe_malloc(size_t size)
264 {
265 void *data;
266
267 if ((data = calloc(1, size)) == NULL) {
268 (void) fprintf(stderr, "internal error: out of memory\n");
269 exit(1);
270 }
271
272 return (data);
3044 return (0);
3045
3046 (void) fprintf(stderr, gettext("cannot %s '%s': "
3047 "dataset is exported to a local zone\n"), cmdname,
3048 zfs_get_name(zhp));
3049 return (1);
3050
3051 } else if (!zoned && getzoneid() != GLOBAL_ZONEID) {
3052 if (!explicit)
3053 return (0);
3054
3055 (void) fprintf(stderr, gettext("cannot %s '%s': "
3056 "permission denied\n"), cmdname,
3057 zfs_get_name(zhp));
3058 return (1);
3059 }
3060
3061 /*
3062 * Ignore any filesystems which don't apply to us. This
3063 * includes those with a legacy mountpoint, or those with
3064 * legacy share options.
3065 */
3066 verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
3067 sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
3068 verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
3069 sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
3070 verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
3071 sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
3072
3073 if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
3074 strcmp(smbshareopts, "off") == 0) {
3075 if (!explicit)
3076 return (0);
3077
3078 (void) fprintf(stderr, gettext("cannot share '%s': "
3079 "legacy share\n"), zfs_get_name(zhp));
3080 (void) fprintf(stderr, gettext("use share(1M) to "
3081 "share this filesystem, or set "
3082 "sharenfs property on\n"));
3083 return (1);
3084 }
3113 * on no pass through
3114 * on yes pass through
3115 * off no return 0
3116 * off yes display error, return 1
3117 * noauto no return 0
3118 * noauto yes pass through
3119 */
3120 canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
3121 if (canmount == ZFS_CANMOUNT_OFF) {
3122 if (!explicit)
3123 return (0);
3124
3125 (void) fprintf(stderr, gettext("cannot %s '%s': "
3126 "'canmount' property is set to 'off'\n"), cmdname,
3127 zfs_get_name(zhp));
3128 return (1);
3129 } else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) {
3130 return (0);
3131 }
3132
3133 /*
3134 * At this point, we have verified that the mountpoint and/or
3135 * shareopts are appropriate for auto management. If the
3136 * filesystem is already mounted or shared, return (failing
3137 * for explicit requests); otherwise mount or share the
3138 * filesystem.
3139 */
3140 switch (op) {
3141 case OP_SHARE:
3142
3143 shared_nfs = zfs_is_shared_nfs(zhp, NULL);
3144 shared_smb = zfs_is_shared_smb(zhp, NULL);
3145
3146 if (shared_nfs && shared_smb ||
3147 (shared_nfs && strcmp(shareopts, "on") == 0 &&
3148 strcmp(smbshareopts, "off") == 0) ||
3149 (shared_smb && strcmp(smbshareopts, "on") == 0 &&
3150 strcmp(shareopts, "off") == 0)) {
3151 if (!explicit)
3152 return (0);
3153
3333 case ':':
3334 (void) fprintf(stderr, gettext("missing argument for "
3335 "'%c' option\n"), optopt);
3336 usage(B_FALSE);
3337 break;
3338 case '?':
3339 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3340 optopt);
3341 usage(B_FALSE);
3342 }
3343 }
3344
3345 argc -= optind;
3346 argv += optind;
3347
3348 /* check number of arguments */
3349 if (do_all) {
3350 zfs_handle_t **dslist = NULL;
3351 size_t i, count = 0;
3352 char *protocol = NULL;
3353
3354 if (op == OP_MOUNT) {
3355 types = ZFS_TYPE_FILESYSTEM;
3356 } else if (argc > 0) {
3357 if (strcmp(argv[0], "nfs") == 0 ||
3358 strcmp(argv[0], "smb") == 0) {
3359 types = ZFS_TYPE_FILESYSTEM;
3360 } else if (strcmp(argv[0], "iscsi") == 0) {
3361 types = ZFS_TYPE_VOLUME;
3362 } else {
3363 (void) fprintf(stderr, gettext("share type "
3364 "must be 'nfs', 'smb' or 'iscsi'\n"));
3365 usage(B_FALSE);
3366 }
3367 protocol = argv[0];
3368 argc--;
3369 argv++;
3370 } else {
3371 types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
3372 }
3373
3374 if (argc != 0) {
3375 (void) fprintf(stderr, gettext("too many arguments\n"));
3376 usage(B_FALSE);
3377 }
3378
3379 get_all_datasets(types, &dslist, &count, verbose);
3380
3381 if (count == 0)
3382 return (0);
3383
3384 qsort(dslist, count, sizeof (void *), dataset_cmp);
3385
3386 for (i = 0; i < count; i++) {
3387 if (verbose)
3388 report_mount_progress(i, count);
3389
3390 if (share_mount_one(dslist[i], op, flags, protocol,
3391 B_FALSE, options) != 0)
3392 ret = 1;
3393 zfs_close(dslist[i]);
3394 }
3395
3396 free(dslist);
3397 } else if (argc == 0) {
3398 struct mnttab entry;
3399
3400 if ((op == OP_SHARE) || (options != NULL)) {
3401 (void) fprintf(stderr, gettext("missing filesystem "
3402 "argument (specify -a for all)\n"));
3403 usage(B_FALSE);
3404 }
3405
3406 /*
3407 * When mount is given no arguments, go through /etc/mnttab and
3408 * display any active ZFS mounts. We hide any snapshots, since
3409 * they are controlled automatically.
3410 */
3411 rewind(mnttab_file);
3412 while (getmntent(mnttab_file, &entry) == 0) {
4062 }
4063 }
4064
4065 argc -= optind;
4066 argv += optind;
4067
4068 /* check arguments */
4069 if (argc != 1) {
4070 if (argc == 0)
4071 (void) fprintf(stderr, gettext("missing path "
4072 "argument\n"));
4073 else
4074 (void) fprintf(stderr, gettext("too many arguments\n"));
4075 (void) fprintf(stderr, gettext("usage: unmount [-f] <path>\n"));
4076 return (2);
4077 }
4078
4079 return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE));
4080 }
4081
4082 static int
4083 volcheck(zpool_handle_t *zhp, void *data)
4084 {
4085 boolean_t isinit = *((boolean_t *)data);
4086
4087 if (isinit)
4088 return (zpool_create_zvol_links(zhp));
4089 else
4090 return (zpool_remove_zvol_links(zhp));
4091 }
4092
4093 /*
4094 * Iterate over all pools in the system and either create or destroy /dev/zvol
4095 * links, depending on the value of 'isinit'.
4096 */
4097 static int
4098 do_volcheck(boolean_t isinit)
4099 {
4100 return (zpool_iter(g_zfs, volcheck, &isinit) ? 1 : 0);
4101 }
|
60 static int zfs_do_clone(int argc, char **argv);
61 static int zfs_do_create(int argc, char **argv);
62 static int zfs_do_destroy(int argc, char **argv);
63 static int zfs_do_get(int argc, char **argv);
64 static int zfs_do_inherit(int argc, char **argv);
65 static int zfs_do_list(int argc, char **argv);
66 static int zfs_do_mount(int argc, char **argv);
67 static int zfs_do_rename(int argc, char **argv);
68 static int zfs_do_rollback(int argc, char **argv);
69 static int zfs_do_set(int argc, char **argv);
70 static int zfs_do_upgrade(int argc, char **argv);
71 static int zfs_do_snapshot(int argc, char **argv);
72 static int zfs_do_unmount(int argc, char **argv);
73 static int zfs_do_share(int argc, char **argv);
74 static int zfs_do_unshare(int argc, char **argv);
75 static int zfs_do_send(int argc, char **argv);
76 static int zfs_do_receive(int argc, char **argv);
77 static int zfs_do_promote(int argc, char **argv);
78 static int zfs_do_allow(int argc, char **argv);
79 static int zfs_do_unallow(int argc, char **argv);
80 static int zfs_do_key(int argc, char **argv);
81
82 /*
83 * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
84 */
85
86 #ifdef DEBUG
87 const char *
88 _umem_debug_init(void)
89 {
90 return ("default,verbose"); /* $UMEM_DEBUG setting */
91 }
92
93 const char *
94 _umem_logging_init(void)
95 {
96 return ("fail,contents"); /* $UMEM_LOGGING setting */
97 }
98 #endif
99
100 typedef enum {
101 HELP_CLONE,
102 HELP_CREATE,
103 HELP_DESTROY,
104 HELP_GET,
105 HELP_INHERIT,
106 HELP_UPGRADE,
107 HELP_LIST,
108 HELP_MOUNT,
109 HELP_PROMOTE,
110 HELP_RECEIVE,
111 HELP_RENAME,
112 HELP_ROLLBACK,
113 HELP_SEND,
114 HELP_SET,
115 HELP_SHARE,
116 HELP_SNAPSHOT,
117 HELP_UNMOUNT,
118 HELP_UNSHARE,
119 HELP_ALLOW,
120 HELP_UNALLOW,
121 HELP_KEY
122 } zfs_help_t;
123
124 typedef struct zfs_command {
125 const char *name;
126 int (*func)(int argc, char **argv);
127 zfs_help_t usage;
128 } zfs_command_t;
129
130 /*
131 * Master command table. Each ZFS command has a name, associated function, and
132 * usage message. The usage messages need to be internationalized, so we have
133 * to have a function to return the usage message based on a command index.
134 *
135 * These commands are organized according to how they are displayed in the usage
136 * message. An empty command (one with a NULL name) indicates an empty line in
137 * the generic usage message.
138 */
139 static zfs_command_t command_table[] = {
140 { "create", zfs_do_create, HELP_CREATE },
141 { "destroy", zfs_do_destroy, HELP_DESTROY },
147 { "rename", zfs_do_rename, HELP_RENAME },
148 { NULL },
149 { "list", zfs_do_list, HELP_LIST },
150 { NULL },
151 { "set", zfs_do_set, HELP_SET },
152 { "get", zfs_do_get, HELP_GET },
153 { "inherit", zfs_do_inherit, HELP_INHERIT },
154 { "upgrade", zfs_do_upgrade, HELP_UPGRADE },
155 { NULL },
156 { "mount", zfs_do_mount, HELP_MOUNT },
157 { "unmount", zfs_do_unmount, HELP_UNMOUNT },
158 { "share", zfs_do_share, HELP_SHARE },
159 { "unshare", zfs_do_unshare, HELP_UNSHARE },
160 { NULL },
161 { "send", zfs_do_send, HELP_SEND },
162 { "receive", zfs_do_receive, HELP_RECEIVE },
163 { NULL },
164 { "allow", zfs_do_allow, HELP_ALLOW },
165 { NULL },
166 { "unallow", zfs_do_unallow, HELP_UNALLOW },
167 { NULL },
168 { "key", zfs_do_key, HELP_KEY },
169 };
170
171 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
172
173 zfs_command_t *current_command;
174
175 static const char *
176 get_usage(zfs_help_t idx)
177 {
178 switch (idx) {
179 case HELP_CLONE:
180 return (gettext("\tclone [-p] [-o property=value] ... "
181 "<snapshot> <filesystem|volume>\n"));
182 case HELP_CREATE:
183 return (gettext("\tcreate [-p] [-o property=value] ... "
184 "<filesystem>\n"
185 "\tcreate [-ps] [-b blocksize] [-o property=value] ... "
186 "-V <size> <volume>\n"));
187 case HELP_DESTROY:
188 return (gettext("\tdestroy [-rRf] "
237 "<-a | filesystem|mountpoint>\n"));
238 case HELP_ALLOW:
239 return (gettext("\tallow [-ldug] "
240 "<\"everyone\"|user|group>[,...] <perm|@setname>[,...]\n"
241 "\t <filesystem|volume>\n"
242 "\tallow [-ld] -e <perm|@setname>[,...] "
243 "<filesystem|volume>\n"
244 "\tallow -c <perm|@setname>[,...] <filesystem|volume>\n"
245 "\tallow -s @setname <perm|@setname>[,...] "
246 "<filesystem|volume>\n"));
247 case HELP_UNALLOW:
248 return (gettext("\tunallow [-rldug] "
249 "<\"everyone\"|user|group>[,...]\n"
250 "\t [<perm|@setname>[,...]] <filesystem|volume>\n"
251 "\tunallow [-rld] -e [<perm|@setname>[,...]] "
252 "<filesystem|volume>\n"
253 "\tunallow [-r] -c [<perm|@setname>[,...]] "
254 "<filesystem|volume>\n"
255 "\tunallow [-r] -s @setname [<perm|@setname>[,...]] "
256 "<filesystem|volume>\n"));
257 case HELP_KEY:
258 return (gettext("\tkey <-l | -u | -c [ -o <property=value>]> "
259 "<-a | filesystem>\n"));
260 }
261
262 abort();
263 /* NOTREACHED */
264 }
265
266 /*
267 * Utility function to guarantee malloc() success.
268 */
269 void *
270 safe_malloc(size_t size)
271 {
272 void *data;
273
274 if ((data = calloc(1, size)) == NULL) {
275 (void) fprintf(stderr, "internal error: out of memory\n");
276 exit(1);
277 }
278
279 return (data);
3051 return (0);
3052
3053 (void) fprintf(stderr, gettext("cannot %s '%s': "
3054 "dataset is exported to a local zone\n"), cmdname,
3055 zfs_get_name(zhp));
3056 return (1);
3057
3058 } else if (!zoned && getzoneid() != GLOBAL_ZONEID) {
3059 if (!explicit)
3060 return (0);
3061
3062 (void) fprintf(stderr, gettext("cannot %s '%s': "
3063 "permission denied\n"), cmdname,
3064 zfs_get_name(zhp));
3065 return (1);
3066 }
3067
3068 /*
3069 * Ignore any filesystems which don't apply to us. This
3070 * includes those with a legacy mountpoint, or those with
3071 * legacy share options. We also have to ignore those
3072 * that are encrypted that don't currently have their
3073 * key available.
3074 */
3075 verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
3076 sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
3077 verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
3078 sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
3079 verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
3080 sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
3081
3082 if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
3083 strcmp(smbshareopts, "off") == 0) {
3084 if (!explicit)
3085 return (0);
3086
3087 (void) fprintf(stderr, gettext("cannot share '%s': "
3088 "legacy share\n"), zfs_get_name(zhp));
3089 (void) fprintf(stderr, gettext("use share(1M) to "
3090 "share this filesystem, or set "
3091 "sharenfs property on\n"));
3092 return (1);
3093 }
3122 * on no pass through
3123 * on yes pass through
3124 * off no return 0
3125 * off yes display error, return 1
3126 * noauto no return 0
3127 * noauto yes pass through
3128 */
3129 canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
3130 if (canmount == ZFS_CANMOUNT_OFF) {
3131 if (!explicit)
3132 return (0);
3133
3134 (void) fprintf(stderr, gettext("cannot %s '%s': "
3135 "'canmount' property is set to 'off'\n"), cmdname,
3136 zfs_get_name(zhp));
3137 return (1);
3138 } else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) {
3139 return (0);
3140 }
3141
3142
3143 /*
3144 * Only need to check for ZFS_CRYPT_KEY_UNAVAILABLE since
3145 * datasets that aren't encrypted have a keystatus of
3146 * ZFS_CRYPT_KEY_UNDEFINED.
3147 */
3148 if (zfs_mount_crypto_check(zhp) != 0) {
3149 if (!explicit)
3150 return (0);
3151
3152 (void) fprintf(stderr, gettext("cannot %s '%s': "
3153 "encryption key unavailable\n"), cmdname,
3154 zfs_get_name(zhp));
3155 return (1);
3156 }
3157
3158 /*
3159 * At this point, we have verified that the mountpoint and/or
3160 * shareopts are appropriate for auto management. If the
3161 * filesystem is already mounted or shared, return (failing
3162 * for explicit requests); otherwise mount or share the
3163 * filesystem.
3164 */
3165 switch (op) {
3166 case OP_SHARE:
3167
3168 shared_nfs = zfs_is_shared_nfs(zhp, NULL);
3169 shared_smb = zfs_is_shared_smb(zhp, NULL);
3170
3171 if (shared_nfs && shared_smb ||
3172 (shared_nfs && strcmp(shareopts, "on") == 0 &&
3173 strcmp(smbshareopts, "off") == 0) ||
3174 (shared_smb && strcmp(smbshareopts, "on") == 0 &&
3175 strcmp(shareopts, "off") == 0)) {
3176 if (!explicit)
3177 return (0);
3178
3358 case ':':
3359 (void) fprintf(stderr, gettext("missing argument for "
3360 "'%c' option\n"), optopt);
3361 usage(B_FALSE);
3362 break;
3363 case '?':
3364 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3365 optopt);
3366 usage(B_FALSE);
3367 }
3368 }
3369
3370 argc -= optind;
3371 argv += optind;
3372
3373 /* check number of arguments */
3374 if (do_all) {
3375 zfs_handle_t **dslist = NULL;
3376 size_t i, count = 0;
3377 char *protocol = NULL;
3378 char bypass[ZPOOL_MAXPROPLEN] = { 0 };
3379
3380
3381 if (op == OP_MOUNT) {
3382 types = ZFS_TYPE_FILESYSTEM;
3383 } else if (argc > 0) {
3384 if (strcmp(argv[0], "nfs") == 0 ||
3385 strcmp(argv[0], "smb") == 0) {
3386 types = ZFS_TYPE_FILESYSTEM;
3387 } else if (strcmp(argv[0], "iscsi") == 0) {
3388 types = ZFS_TYPE_VOLUME;
3389 } else {
3390 (void) fprintf(stderr, gettext("share type "
3391 "must be 'nfs', 'smb' or 'iscsi'\n"));
3392 usage(B_FALSE);
3393 }
3394 protocol = argv[0];
3395 argc--;
3396 argv++;
3397 } else {
3398 types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
3399 }
3400
3401 if (argc != 0) {
3402 (void) fprintf(stderr, gettext("too many arguments\n"));
3403 usage(B_FALSE);
3404 }
3405
3406 get_all_datasets(types, &dslist, &count, verbose);
3407
3408 if (count == 0)
3409 return (0);
3410
3411 qsort(dslist, count, sizeof (void *), dataset_cmp);
3412
3413 for (i = 0; i < count; i++) {
3414
3415 if (verbose)
3416 report_mount_progress(i, count);
3417
3418 /*
3419 * If bypass has a dataset value, then we need to skip
3420 * any datasets that are underneath it.
3421 */
3422 if (bypass[0] != NULL) {
3423 int len = strlen(bypass);
3424 char *ds_name = (char *)zfs_get_name(dslist[i]);
3425
3426 if (strncmp(bypass, ds_name, len) == 0 &&
3427 (strlen(ds_name) > len) &&
3428 ds_name[len] == '/') {
3429 zfs_close(dslist[i]);
3430 continue;
3431 } else
3432 bypass[0] = '\0';
3433 }
3434
3435 /*
3436 * Check if the dataset has a key before loading, if
3437 * no, then store it in 'bypass'.
3438 */
3439 if (zfs_mount_crypto_check(dslist[i])) {
3440 (void) strlcpy(bypass, zfs_get_name(dslist[i]),
3441 ZPOOL_MAXPROPLEN);
3442 } else {
3443 if (share_mount_one(dslist[i], op, flags,
3444 protocol, B_FALSE, options) != 0) {
3445 ret = 1;
3446 }
3447 }
3448
3449 zfs_close(dslist[i]);
3450 }
3451
3452 free(dslist);
3453 } else if (argc == 0) {
3454 struct mnttab entry;
3455
3456 if ((op == OP_SHARE) || (options != NULL)) {
3457 (void) fprintf(stderr, gettext("missing filesystem "
3458 "argument (specify -a for all)\n"));
3459 usage(B_FALSE);
3460 }
3461
3462 /*
3463 * When mount is given no arguments, go through /etc/mnttab and
3464 * display any active ZFS mounts. We hide any snapshots, since
3465 * they are controlled automatically.
3466 */
3467 rewind(mnttab_file);
3468 while (getmntent(mnttab_file, &entry) == 0) {
4118 }
4119 }
4120
4121 argc -= optind;
4122 argv += optind;
4123
4124 /* check arguments */
4125 if (argc != 1) {
4126 if (argc == 0)
4127 (void) fprintf(stderr, gettext("missing path "
4128 "argument\n"));
4129 else
4130 (void) fprintf(stderr, gettext("too many arguments\n"));
4131 (void) fprintf(stderr, gettext("usage: unmount [-f] <path>\n"));
4132 return (2);
4133 }
4134
4135 return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE));
4136 }
4137
4138 int
4139 zfs_do_key(int argc, char **argv)
4140 {
4141 int error = 1, options = 0;
4142 nvlist_t *props = NULL;
4143 char c, *propname, *propval = NULL;
4144 boolean_t load = B_FALSE, unload = B_FALSE, change = B_FALSE;
4145 boolean_t do_all = B_FALSE;
4146 char *strval;
4147 zfs_handle_t **dslist = NULL, *zhp = NULL;
4148 uint_t count;
4149 zfs_prop_t zprop;
4150
4151 while ((c = getopt(argc, argv, "aluco:")) != -1) {
4152 switch (c) {
4153 case 'a':
4154 do_all = B_TRUE;
4155 break;
4156
4157 case 'l':
4158 load = B_TRUE;
4159 break;
4160
4161 case 'u':
4162 unload = B_TRUE;
4163 break;
4164
4165 case 'c':
4166 change = B_TRUE;
4167 break;
4168
4169 case 'o':
4170 /* Key change is the only command that allows options */
4171 if (change != B_TRUE) {
4172 (void) fprintf(stderr, gettext("Property "
4173 "options only allowed during key "
4174 "change.\n"));
4175 usage(B_FALSE);
4176 goto error;
4177 }
4178
4179 propname = optarg;
4180 if ((propval = strchr(optarg, '=')) == NULL) {
4181 (void) fprintf(stderr, gettext("missing "
4182 "'=' for -o option\n"));
4183 goto error;
4184 }
4185
4186 *propval = '\0';
4187 propval++;
4188
4189 zprop = zfs_name_to_prop(propname);
4190 switch (zprop) {
4191 case ZFS_PROP_KEYSOURCE:
4192 case ZFS_PROP_KEYSCOPE:
4193 break;
4194
4195 default:
4196 (void) fprintf(stderr, gettext("Invalid "
4197 "property for key operation: '%s'\n"),
4198 propname);
4199 goto error;
4200 };
4201
4202 if (props == NULL &&
4203 nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
4204 (void) fprintf(stderr, gettext("internal "
4205 "error: out of memory\n"));
4206 goto error;
4207 }
4208
4209 if (nvlist_lookup_string(props, propname,
4210 &strval) == 0) {
4211 (void) fprintf(stderr, gettext("property '%s' "
4212 "specified multiple times\n"), propname);
4213 goto error;
4214 }
4215 if (nvlist_add_string(props, propname, propval) != 0) {
4216 (void) fprintf(stderr, gettext("internal "
4217 "error: out of memory\n"));
4218 goto error;
4219 }
4220
4221 options += 2;
4222 break;
4223
4224 case '?':
4225 default:
4226 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4227 optopt);
4228 usage(B_FALSE);
4229
4230 }
4231 }
4232
4233 if (!change && props != NULL)
4234 (void) fprintf(stderr, gettext("Properties are not allowed to "
4235 "be used in this command.\n"));
4236
4237 if (((load || unload) && (argc > 3)) ||
4238 (change && ((argc - options) > 3))) {
4239 (void) fprintf(stderr,
4240 gettext("too many arguments\n"));
4241 usage(B_FALSE);
4242 goto error;
4243 } else if ((load || unload) && (argc < 3)) {
4244 (void) fprintf(stderr, gettext("missing dataset "
4245 "argument (specify -a for all)\n"));
4246 usage(B_FALSE);
4247 goto error;
4248 } else if (change && ((argc - options) < 3)) {
4249 (void) fprintf(stderr, gettext("missing dataset "
4250 "argument\n"));
4251 usage(B_FALSE);
4252 goto error;
4253 }
4254
4255 if (do_all == B_FALSE) {
4256 zhp = zfs_open(g_zfs, argv[argc - 1],
4257 ZFS_TYPE_FILESYSTEM|ZFS_TYPE_VOLUME);
4258 if (zhp == NULL)
4259 goto error;
4260
4261 } else if (change) {
4262 /* We don't support do_all in a change operation */
4263
4264 (void) fprintf(stderr, gettext("cannot use '-a' with "
4265 "change operation.\n"));
4266 usage(B_FALSE);
4267 goto error;
4268
4269 } else {
4270 get_all_datasets(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
4271 &dslist, &count, B_FALSE);
4272 if (count == 0)
4273 return (0);
4274
4275 qsort(dslist, count, sizeof (void *), dataset_cmp);
4276 }
4277
4278 if (load) {
4279 if (do_all) {
4280 int i;
4281 zfs_crypt_t *cry = NULL;
4282
4283 cry = calloc(1, sizeof (zfs_crypt_t));
4284 for (i = 0; i < count; i++) {
4285 if (zfs_is_encrypted(dslist[i])) {
4286 zfs_set_libzfs_cry(dslist[i], cry);
4287 (void) zfs_load_key(dslist[i]);
4288 bzero(cry, sizeof (zfs_crypt_t));
4289 }
4290 zfs_close(dslist[i]);
4291 }
4292
4293 free(cry);
4294 free(dslist);
4295 error = 0;
4296
4297 } else
4298 error = zfs_cmd_key_load(zhp);
4299
4300 } else if (unload) {
4301 if (do_all) {
4302 int i;
4303
4304 /* Do in reverse order so we can unmount easily */
4305 for (i = count - 1; i > 0; i--) {
4306 if (zfs_is_encrypted(dslist[i]))
4307 (void) zfs_unload_key(dslist[i]);
4308
4309 zfs_close(dslist[i]);
4310 }
4311
4312 free(dslist);
4313 error = 0;
4314
4315 } else
4316 error = zfs_cmd_key_unload(zhp);
4317
4318 } else if (change) {
4319 error = zfs_cmd_key_change(zhp, props);
4320
4321 } else
4322 usage(B_FALSE);
4323
4324 if (zhp != NULL)
4325 zfs_close(zhp);
4326
4327 error:
4328 if (props != NULL) {
4329 nvlist_free(props);
4330 }
4331 return (error);
4332 }
4333
4334
4335 static int
4336 volcheck(zpool_handle_t *zhp, void *data)
4337 {
4338 boolean_t isinit = *((boolean_t *)data);
4339
4340 if (isinit)
4341 return (zpool_create_zvol_links(zhp));
4342 else
4343 return (zpool_remove_zvol_links(zhp));
4344 }
4345
4346 /*
4347 * Iterate over all pools in the system and either create or destroy /dev/zvol
4348 * links, depending on the value of 'isinit'.
4349 */
4350 static int
4351 do_volcheck(boolean_t isinit)
4352 {
4353 return (zpool_iter(g_zfs, volcheck, &isinit) ? 1 : 0);
4354 }
|