xref: /illumos-gate/usr/src/lib/libzfs/common/libzfs_mount.c (revision f48205be61a214698b763ff550ab9e657525104c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Routines to manage ZFS mounts.  We separate all the nasty routines that have
31  * to deal with the OS.  The following functions are the main entry points --
32  * they are used by mount and unmount and when changing a filesystem's
33  * mountpoint.
34  *
35  * 	zfs_is_mounted()
36  * 	zfs_mount()
37  * 	zfs_unmount()
38  * 	zfs_unmountall()
39  *
40  * This file also contains the functions used to manage sharing filesystems via
41  * NFS and iSCSI:
42  *
43  * 	zfs_is_shared()
44  * 	zfs_share()
45  * 	zfs_unshare()
46  *
47  * 	zfs_is_shared_nfs()
48  * 	zfs_share_nfs()
49  * 	zfs_unshare_nfs()
50  * 	zfs_unshareall_nfs()
51  * 	zfs_is_shared_iscsi()
52  * 	zfs_share_iscsi()
53  * 	zfs_unshare_iscsi()
54  *
55  * The following functions are available for pool consumers, and will
56  * mount/unmount and share/unshare all datasets within pool:
57  *
58  * 	zpool_enable_datasets()
59  * 	zpool_disable_datasets()
60  */
61 
62 #include <dirent.h>
63 #include <dlfcn.h>
64 #include <errno.h>
65 #include <libgen.h>
66 #include <libintl.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <strings.h>
70 #include <unistd.h>
71 #include <zone.h>
72 #include <sys/mntent.h>
73 #include <sys/mnttab.h>
74 #include <sys/mount.h>
75 #include <sys/stat.h>
76 
77 #include <libzfs.h>
78 
79 #include "libzfs_impl.h"
80 
81 #include <libshare.h>
82 #include <sys/systeminfo.h>
83 #define	MAXISALEN	257	/* based on sysinfo(2) man page */
84 
85 static int (*iscsitgt_zfs_share)(const char *);
86 static int (*iscsitgt_zfs_unshare)(const char *);
87 static int (*iscsitgt_zfs_is_shared)(const char *);
88 
89 #pragma init(zfs_iscsi_init)
90 static void
91 zfs_iscsi_init(void)
92 {
93 	void *libiscsitgt;
94 
95 	if ((libiscsitgt = dlopen("/lib/libiscsitgt.so.1",
96 	    RTLD_LAZY | RTLD_GLOBAL)) == NULL ||
97 	    (iscsitgt_zfs_share = (int (*)(const char *))dlsym(libiscsitgt,
98 	    "iscsitgt_zfs_share")) == NULL ||
99 	    (iscsitgt_zfs_unshare = (int (*)(const char *))dlsym(libiscsitgt,
100 	    "iscsitgt_zfs_unshare")) == NULL ||
101 	    (iscsitgt_zfs_is_shared = (int (*)(const char *))dlsym(libiscsitgt,
102 	    "iscsitgt_zfs_is_shared")) == NULL) {
103 		iscsitgt_zfs_share = NULL;
104 		iscsitgt_zfs_unshare = NULL;
105 		iscsitgt_zfs_is_shared = NULL;
106 	}
107 }
108 
109 /*
110  * Search the sharetab for the given mountpoint, returning true if it is found.
111  */
112 static boolean_t
113 is_shared(libzfs_handle_t *hdl, const char *mountpoint)
114 {
115 	char buf[MAXPATHLEN], *tab;
116 
117 	if (hdl->libzfs_sharetab == NULL)
118 		return (0);
119 
120 	(void) fseek(hdl->libzfs_sharetab, 0, SEEK_SET);
121 
122 	while (fgets(buf, sizeof (buf), hdl->libzfs_sharetab) != NULL) {
123 
124 		/* the mountpoint is the first entry on each line */
125 		if ((tab = strchr(buf, '\t')) != NULL) {
126 			*tab = '\0';
127 			if (strcmp(buf, mountpoint) == 0)
128 				return (B_TRUE);
129 		}
130 	}
131 
132 	return (B_FALSE);
133 }
134 
135 /*
136  * Returns true if the specified directory is empty.  If we can't open the
137  * directory at all, return true so that the mount can fail with a more
138  * informative error message.
139  */
140 static boolean_t
141 dir_is_empty(const char *dirname)
142 {
143 	DIR *dirp;
144 	struct dirent64 *dp;
145 
146 	if ((dirp = opendir(dirname)) == NULL)
147 		return (B_TRUE);
148 
149 	while ((dp = readdir64(dirp)) != NULL) {
150 
151 		if (strcmp(dp->d_name, ".") == 0 ||
152 		    strcmp(dp->d_name, "..") == 0)
153 			continue;
154 
155 		(void) closedir(dirp);
156 		return (B_FALSE);
157 	}
158 
159 	(void) closedir(dirp);
160 	return (B_TRUE);
161 }
162 
163 /*
164  * Checks to see if the mount is active.  If the filesystem is mounted, we fill
165  * in 'where' with the current mountpoint, and return 1.  Otherwise, we return
166  * 0.
167  */
168 boolean_t
169 is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
170 {
171 	struct mnttab search = { 0 }, entry;
172 
173 	/*
174 	 * Search for the entry in /etc/mnttab.  We don't bother getting the
175 	 * mountpoint, as we can just search for the special device.  This will
176 	 * also let us find mounts when the mountpoint is 'legacy'.
177 	 */
178 	search.mnt_special = (char *)special;
179 	search.mnt_fstype = MNTTYPE_ZFS;
180 
181 	rewind(zfs_hdl->libzfs_mnttab);
182 	if (getmntany(zfs_hdl->libzfs_mnttab, &entry, &search) != 0)
183 		return (B_FALSE);
184 
185 	if (where != NULL)
186 		*where = zfs_strdup(zfs_hdl, entry.mnt_mountp);
187 
188 	return (B_TRUE);
189 }
190 
191 boolean_t
192 zfs_is_mounted(zfs_handle_t *zhp, char **where)
193 {
194 	return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
195 }
196 
197 /*
198  * Returns true if the given dataset is mountable, false otherwise.  Returns the
199  * mountpoint in 'buf'.
200  */
201 static boolean_t
202 zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
203     zfs_source_t *source)
204 {
205 	char sourceloc[ZFS_MAXNAMELEN];
206 	zfs_source_t sourcetype;
207 
208 	if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type))
209 		return (B_FALSE);
210 
211 	verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
212 	    &sourcetype, sourceloc, sizeof (sourceloc), B_FALSE) == 0);
213 
214 	if (strcmp(buf, ZFS_MOUNTPOINT_NONE) == 0 ||
215 	    strcmp(buf, ZFS_MOUNTPOINT_LEGACY) == 0)
216 		return (B_FALSE);
217 
218 	if (!zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT))
219 		return (B_FALSE);
220 
221 	if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
222 	    getzoneid() == GLOBAL_ZONEID)
223 		return (B_FALSE);
224 
225 	if (source)
226 		*source = sourcetype;
227 
228 	return (B_TRUE);
229 }
230 
231 /*
232  * Mount the given filesystem.
233  */
234 int
235 zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
236 {
237 	struct stat buf;
238 	char mountpoint[ZFS_MAXPROPLEN];
239 	char mntopts[MNT_LINE_MAX];
240 	libzfs_handle_t *hdl = zhp->zfs_hdl;
241 
242 	if (options == NULL)
243 		mntopts[0] = '\0';
244 	else
245 		(void) strlcpy(mntopts, options, sizeof (mntopts));
246 
247 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
248 		return (0);
249 
250 	/* Create the directory if it doesn't already exist */
251 	if (lstat(mountpoint, &buf) != 0) {
252 		if (mkdirp(mountpoint, 0755) != 0) {
253 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
254 			    "failed to create mountpoint"));
255 			return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
256 			    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
257 			    mountpoint));
258 		}
259 	}
260 
261 	/*
262 	 * Determine if the mountpoint is empty.  If so, refuse to perform the
263 	 * mount.  We don't perform this check if MS_OVERLAY is specified, which
264 	 * would defeat the point.  We also avoid this check if 'remount' is
265 	 * specified.
266 	 */
267 	if ((flags & MS_OVERLAY) == 0 &&
268 	    strstr(mntopts, MNTOPT_REMOUNT) == NULL &&
269 	    !dir_is_empty(mountpoint)) {
270 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
271 		    "directory is not empty"));
272 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
273 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
274 	}
275 
276 	/* perform the mount */
277 	if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags,
278 	    MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) {
279 		/*
280 		 * Generic errors are nasty, but there are just way too many
281 		 * from mount(), and they're well-understood.  We pick a few
282 		 * common ones to improve upon.
283 		 */
284 		if (errno == EBUSY) {
285 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
286 			    "mountpoint or dataset is busy"));
287 		} else {
288 			zfs_error_aux(hdl, strerror(errno));
289 		}
290 
291 		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
292 		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
293 		    zhp->zfs_name));
294 	}
295 
296 	return (0);
297 }
298 
299 /*
300  * Unmount a single filesystem.
301  */
302 static int
303 unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
304 {
305 	if (umount2(mountpoint, flags) != 0) {
306 		zfs_error_aux(hdl, strerror(errno));
307 		return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED,
308 		    dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
309 		    mountpoint));
310 	}
311 
312 	return (0);
313 }
314 
315 /*
316  * Unmount the given filesystem.
317  */
318 int
319 zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
320 {
321 	struct mnttab search = { 0 }, entry;
322 	char *mntpt = NULL;
323 
324 	/* check to see if need to unmount the filesystem */
325 	search.mnt_special = zhp->zfs_name;
326 	search.mnt_fstype = MNTTYPE_ZFS;
327 	rewind(zhp->zfs_hdl->libzfs_mnttab);
328 	if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
329 	    getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) {
330 
331 		/*
332 		 * mountpoint may have come from a call to
333 		 * getmnt/getmntany if it isn't NULL. If it is NULL,
334 		 * we know it comes from getmntany which can then get
335 		 * overwritten later. We strdup it to play it safe.
336 		 */
337 		if (mountpoint == NULL)
338 			mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp);
339 		else
340 			mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint);
341 
342 		/*
343 		 * Unshare and unmount the filesystem
344 		 */
345 		if (zfs_unshare_nfs(zhp, mntpt) != 0 ||
346 		    unmount_one(zhp->zfs_hdl, mntpt, flags) != 0) {
347 			free(mntpt);
348 			return (-1);
349 		}
350 		free(mntpt);
351 	}
352 
353 	return (0);
354 }
355 
356 /*
357  * Unmount this filesystem and any children inheriting the mountpoint property.
358  * To do this, just act like we're changing the mountpoint property, but don't
359  * remount the filesystems afterwards.
360  */
361 int
362 zfs_unmountall(zfs_handle_t *zhp, int flags)
363 {
364 	prop_changelist_t *clp;
365 	int ret;
366 
367 	clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, flags);
368 	if (clp == NULL)
369 		return (-1);
370 
371 	ret = changelist_prefix(clp);
372 	changelist_free(clp);
373 
374 	return (ret);
375 }
376 
377 boolean_t
378 zfs_is_shared(zfs_handle_t *zhp)
379 {
380 	if (ZFS_IS_VOLUME(zhp))
381 		return (zfs_is_shared_iscsi(zhp));
382 
383 	return (zfs_is_shared_nfs(zhp, NULL));
384 }
385 
386 int
387 zfs_share(zfs_handle_t *zhp)
388 {
389 	if (ZFS_IS_VOLUME(zhp))
390 		return (zfs_share_iscsi(zhp));
391 
392 	return (zfs_share_nfs(zhp));
393 }
394 
395 int
396 zfs_unshare(zfs_handle_t *zhp)
397 {
398 	if (ZFS_IS_VOLUME(zhp))
399 		return (zfs_unshare_iscsi(zhp));
400 
401 	return (zfs_unshare_nfs(zhp, NULL));
402 }
403 
404 /*
405  * Check to see if the filesystem is currently shared.
406  */
407 boolean_t
408 zfs_is_shared_nfs(zfs_handle_t *zhp, char **where)
409 {
410 	char *mountpoint;
411 
412 	if (!zfs_is_mounted(zhp, &mountpoint))
413 		return (B_FALSE);
414 
415 	if (is_shared(zhp->zfs_hdl, mountpoint)) {
416 		if (where != NULL)
417 			*where = mountpoint;
418 		else
419 			free(mountpoint);
420 		return (B_TRUE);
421 	} else {
422 		free(mountpoint);
423 		return (B_FALSE);
424 	}
425 }
426 
427 /*
428  * Make sure things will work if libshare isn't installed by using
429  * wrapper functions that check to see that the pointers to functions
430  * initialized in _zfs_init_libshare() are actually present.
431  */
432 
433 static sa_handle_t (*_sa_init)(int);
434 static void (*_sa_fini)(sa_handle_t);
435 static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
436 static int (*_sa_enable_share)(sa_share_t, char *);
437 static int (*_sa_disable_share)(sa_share_t, char *);
438 static char *(*_sa_errorstr)(int);
439 static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
440 
441 /*
442  * _zfs_init_libshare()
443  *
444  * Find the libshare.so.1 entry points that we use here and save the
445  * values to be used later. This is triggered by the runtime loader.
446  * Make sure the correct ISA version is loaded.
447  */
448 
449 #pragma init(_zfs_init_libshare)
450 static void
451 _zfs_init_libshare(void)
452 {
453 	void *libshare;
454 	char path[MAXPATHLEN];
455 	char isa[MAXISALEN];
456 
457 #if defined(_LP64)
458 	if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
459 		isa[0] = '\0';
460 #else
461 	isa[0] = '\0';
462 #endif
463 	(void) snprintf(path, MAXPATHLEN,
464 	    "/usr/lib/%s/libshare.so.1", isa);
465 
466 	if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
467 		_sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
468 		_sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
469 		_sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
470 		    dlsym(libshare, "sa_find_share");
471 		_sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
472 		    "sa_enable_share");
473 		_sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
474 		    "sa_disable_share");
475 		_sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
476 		_sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
477 		    dlsym(libshare, "sa_parse_legacy_options");
478 	}
479 }
480 
481 /*
482  * zfs_init_libshare(zhandle, service)
483  *
484  * Initialize the libshare API if it hasn't already been initialized.
485  * In all cases it returns 0 if it succeeded and an error if not. The
486  * service value is which part(s) of the API to initialize and is a
487  * direct map to the libshare sa_init(service) interface.
488  */
489 
490 int
491 zfs_init_libshare(libzfs_handle_t *zhandle, int service)
492 {
493 	int ret = SA_OK;
494 
495 	if (_sa_init == NULL)
496 		ret = SA_CONFIG_ERR;
497 
498 	if (ret == SA_OK && zhandle && zhandle->libzfs_sharehdl == NULL)
499 		zhandle->libzfs_sharehdl = _sa_init(service);
500 
501 	if (ret == SA_OK && zhandle->libzfs_sharehdl == NULL)
502 		ret = SA_NO_MEMORY;
503 
504 	return (ret);
505 }
506 
507 /*
508  * zfs_uninit_libshare(zhandle)
509  *
510  * Uninitialize the libshare API if it hasn't already been
511  * uninitialized. It is OK to call multiple times.
512  */
513 
514 void
515 zfs_uninit_libshare(libzfs_handle_t *zhandle)
516 {
517 
518 	if (zhandle != NULL && zhandle->libzfs_sharehdl != NULL) {
519 		if (_sa_fini != NULL)
520 			_sa_fini(zhandle->libzfs_sharehdl);
521 		zhandle->libzfs_sharehdl = NULL;
522 	}
523 }
524 
525 /*
526  * zfs_parse_options(options, proto)
527  *
528  * Call the legacy parse interface to get the protocol specific
529  * options using the NULL arg to indicate that this is a "parse" only.
530  */
531 
532 int
533 zfs_parse_options(char *options, char *proto)
534 {
535 	int ret;
536 
537 	if (_sa_parse_legacy_options != NULL)
538 		ret = _sa_parse_legacy_options(NULL, options, proto);
539 	else
540 		ret = SA_CONFIG_ERR;
541 	return (ret);
542 }
543 
544 /*
545  * zfs_sa_find_share(handle, path)
546  *
547  * wrapper around sa_find_share to find a share path in the
548  * configuration.
549  */
550 
551 static sa_share_t
552 zfs_sa_find_share(sa_handle_t handle, char *path)
553 {
554 	if (_sa_find_share != NULL)
555 		return (_sa_find_share(handle, path));
556 	return (NULL);
557 }
558 
559 /*
560  * zfs_sa_enable_share(share, proto)
561  *
562  * Wrapper for sa_enable_share which enables a share for a specified
563  * protocol.
564  */
565 
566 static int
567 zfs_sa_enable_share(sa_share_t share, char *proto)
568 {
569 	if (_sa_enable_share != NULL)
570 		return (_sa_enable_share(share, proto));
571 	return (SA_CONFIG_ERR);
572 }
573 
574 /*
575  * zfs_sa_disable_share(share, proto)
576  *
577  * Wrapper for sa_enable_share which disables a share for a specified
578  * protocol.
579  */
580 
581 static int
582 zfs_sa_disable_share(sa_share_t share, char *proto)
583 {
584 	if (_sa_disable_share != NULL)
585 		return (_sa_disable_share(share, proto));
586 	return (SA_CONFIG_ERR);
587 }
588 
589 /*
590  * Share the given filesystem according to the options in 'sharenfs'.  We rely
591  * on "libshare" to the dirty work for us.
592  */
593 
594 int
595 zfs_share_nfs(zfs_handle_t *zhp)
596 {
597 	char mountpoint[ZFS_MAXPROPLEN];
598 	char shareopts[ZFS_MAXPROPLEN];
599 	libzfs_handle_t *hdl = zhp->zfs_hdl;
600 	sa_share_t share;
601 	int ret;
602 
603 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
604 		return (0);
605 
606 	/*
607 	 * Return success if there are no share options.
608 	 */
609 	if (zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts, sizeof (shareopts),
610 	    NULL, NULL, 0, B_FALSE) != 0 ||
611 	    strcmp(shareopts, "off") == 0)
612 		return (0);
613 
614 	/*
615 	 * If the 'zoned' property is set, then zfs_is_mountable() will have
616 	 * already bailed out if we are in the global zone.  But local
617 	 * zones cannot be NFS servers, so we ignore it for local zones as well.
618 	 */
619 	if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
620 		return (0);
621 
622 	if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
623 		(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
624 		    dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
625 		    zfs_get_name(zhp), _sa_errorstr(ret));
626 		return (-1);
627 	}
628 	share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
629 	if (share != NULL) {
630 		int err;
631 		err = zfs_sa_enable_share(share, "nfs");
632 		if (err != SA_OK) {
633 			(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
634 			    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
635 			    zfs_get_name(zhp));
636 			return (-1);
637 		}
638 	} else {
639 		(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
640 		    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
641 		    zfs_get_name(zhp));
642 		return (-1);
643 	}
644 
645 	return (0);
646 }
647 
648 /*
649  * Unshare a filesystem by mountpoint.
650  */
651 static int
652 unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint)
653 {
654 	sa_share_t share;
655 	int err;
656 	char *mntpt;
657 
658 	/*
659 	 * Mountpoint could get trashed if libshare calls getmntany
660 	 * which id does during API initialization, so strdup the
661 	 * value.
662 	 */
663 	mntpt = zfs_strdup(hdl, mountpoint);
664 
665 	/* make sure libshare initialized */
666 	if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
667 		free(mntpt);	/* don't need the copy anymore */
668 		return (zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
669 		    dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
670 		    name, _sa_errorstr(err)));
671 	}
672 
673 	share = zfs_sa_find_share(hdl->libzfs_sharehdl, mntpt);
674 	free(mntpt);	/* don't need the copy anymore */
675 
676 	if (share != NULL) {
677 		err = zfs_sa_disable_share(share, "nfs");
678 		if (err != SA_OK) {
679 			return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
680 			    dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
681 			    name, _sa_errorstr(err)));
682 		}
683 	} else {
684 		return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
685 		    dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
686 		    name));
687 	}
688 	return (0);
689 }
690 
691 /*
692  * Unshare the given filesystem.
693  */
694 int
695 zfs_unshare_nfs(zfs_handle_t *zhp, const char *mountpoint)
696 {
697 	struct mnttab search = { 0 }, entry;
698 	char *mntpt = NULL;
699 
700 	/* check to see if need to unmount the filesystem */
701 	search.mnt_special = (char *)zfs_get_name(zhp);
702 	search.mnt_fstype = MNTTYPE_ZFS;
703 	rewind(zhp->zfs_hdl->libzfs_mnttab);
704 	if (mountpoint != NULL)
705 		mountpoint = mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint);
706 
707 	if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
708 	    getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) {
709 
710 		if (mountpoint == NULL)
711 			mountpoint = entry.mnt_mountp;
712 
713 		if (is_shared(zhp->zfs_hdl, mountpoint) &&
714 		    unshare_one(zhp->zfs_hdl, zhp->zfs_name, mountpoint) != 0) {
715 			if (mntpt != NULL)
716 				free(mntpt);
717 			return (-1);
718 		}
719 	}
720 	if (mntpt != NULL)
721 		free(mntpt);
722 
723 	return (0);
724 }
725 
726 /*
727  * Same as zfs_unmountall(), but for NFS unshares.
728  */
729 int
730 zfs_unshareall_nfs(zfs_handle_t *zhp)
731 {
732 	prop_changelist_t *clp;
733 	int ret;
734 
735 	clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0);
736 	if (clp == NULL)
737 		return (-1);
738 
739 	ret = changelist_unshare(clp);
740 	changelist_free(clp);
741 
742 	return (ret);
743 }
744 
745 /*
746  * Remove the mountpoint associated with the current dataset, if necessary.
747  * We only remove the underlying directory if:
748  *
749  *	- The mountpoint is not 'none' or 'legacy'
750  *	- The mountpoint is non-empty
751  *	- The mountpoint is the default or inherited
752  *	- The 'zoned' property is set, or we're in a local zone
753  *
754  * Any other directories we leave alone.
755  */
756 void
757 remove_mountpoint(zfs_handle_t *zhp)
758 {
759 	char mountpoint[ZFS_MAXPROPLEN];
760 	zfs_source_t source;
761 
762 	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint),
763 	    &source))
764 		return;
765 
766 	if (source == ZFS_SRC_DEFAULT ||
767 	    source == ZFS_SRC_INHERITED) {
768 		/*
769 		 * Try to remove the directory, silently ignoring any errors.
770 		 * The filesystem may have since been removed or moved around,
771 		 * and this error isn't really useful to the administrator in
772 		 * any way.
773 		 */
774 		(void) rmdir(mountpoint);
775 	}
776 }
777 
778 boolean_t
779 zfs_is_shared_iscsi(zfs_handle_t *zhp)
780 {
781 	return (iscsitgt_zfs_is_shared != NULL &&
782 	    iscsitgt_zfs_is_shared(zhp->zfs_name) != 0);
783 }
784 
785 int
786 zfs_share_iscsi(zfs_handle_t *zhp)
787 {
788 	char shareopts[ZFS_MAXPROPLEN];
789 	const char *dataset = zhp->zfs_name;
790 	libzfs_handle_t *hdl = zhp->zfs_hdl;
791 
792 	/*
793 	 * Return success if there are no share options.
794 	 */
795 	if (zfs_prop_get(zhp, ZFS_PROP_SHAREISCSI, shareopts,
796 	    sizeof (shareopts), NULL, NULL, 0, B_FALSE) != 0 ||
797 	    strcmp(shareopts, "off") == 0)
798 		return (0);
799 
800 	if (iscsitgt_zfs_share == NULL || iscsitgt_zfs_share(dataset) != 0)
801 		return (zfs_error_fmt(hdl, EZFS_SHAREISCSIFAILED,
802 		    dgettext(TEXT_DOMAIN, "cannot share '%s'"), dataset));
803 
804 	return (0);
805 }
806 
807 int
808 zfs_unshare_iscsi(zfs_handle_t *zhp)
809 {
810 	const char *dataset = zfs_get_name(zhp);
811 	libzfs_handle_t *hdl = zhp->zfs_hdl;
812 
813 	/*
814 	 * Return if the volume is not shared
815 	 */
816 	if (!zfs_is_shared_iscsi(zhp))
817 		return (0);
818 
819 	/*
820 	 * If this fails with ENODEV it indicates that zvol wasn't shared so
821 	 * we should return success in that case.
822 	 */
823 	if (iscsitgt_zfs_unshare == NULL ||
824 	    (iscsitgt_zfs_unshare(dataset) != 0 && errno != ENODEV))
825 		return (zfs_error_fmt(hdl, EZFS_UNSHAREISCSIFAILED,
826 		    dgettext(TEXT_DOMAIN, "cannot unshare '%s'"), dataset));
827 
828 	return (0);
829 }
830 
831 typedef struct mount_cbdata {
832 	zfs_handle_t	**cb_datasets;
833 	int 		cb_used;
834 	int		cb_alloc;
835 } mount_cbdata_t;
836 
837 static int
838 mount_cb(zfs_handle_t *zhp, void *data)
839 {
840 	mount_cbdata_t *cbp = data;
841 
842 	if (!(zfs_get_type(zhp) & (ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) {
843 		zfs_close(zhp);
844 		return (0);
845 	}
846 
847 	if (cbp->cb_alloc == cbp->cb_used) {
848 		void *ptr;
849 
850 		if ((ptr = zfs_realloc(zhp->zfs_hdl,
851 		    cbp->cb_datasets, cbp->cb_alloc * sizeof (void *),
852 		    cbp->cb_alloc * 2 * sizeof (void *))) == NULL)
853 			return (-1);
854 		cbp->cb_datasets = ptr;
855 
856 		cbp->cb_alloc *= 2;
857 	}
858 
859 	cbp->cb_datasets[cbp->cb_used++] = zhp;
860 
861 	return (zfs_iter_children(zhp, mount_cb, cbp));
862 }
863 
864 static int
865 dataset_cmp(const void *a, const void *b)
866 {
867 	zfs_handle_t **za = (zfs_handle_t **)a;
868 	zfs_handle_t **zb = (zfs_handle_t **)b;
869 	char mounta[MAXPATHLEN];
870 	char mountb[MAXPATHLEN];
871 	boolean_t gota, gotb;
872 
873 	if ((gota = (zfs_get_type(*za) == ZFS_TYPE_FILESYSTEM)) != 0)
874 		verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
875 		    sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
876 	if ((gotb = (zfs_get_type(*zb) == ZFS_TYPE_FILESYSTEM)) != 0)
877 		verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
878 		    sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
879 
880 	if (gota && gotb)
881 		return (strcmp(mounta, mountb));
882 
883 	if (gota)
884 		return (-1);
885 	if (gotb)
886 		return (1);
887 
888 	return (strcmp(zfs_get_name(a), zfs_get_name(b)));
889 }
890 
891 /*
892  * Mount and share all datasets within the given pool.  This assumes that no
893  * datasets within the pool are currently mounted.  Because users can create
894  * complicated nested hierarchies of mountpoints, we first gather all the
895  * datasets and mountpoints within the pool, and sort them by mountpoint.  Once
896  * we have the list of all filesystems, we iterate over them in order and mount
897  * and/or share each one.
898  */
899 #pragma weak zpool_mount_datasets = zpool_enable_datasets
900 int
901 zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
902 {
903 	mount_cbdata_t cb = { 0 };
904 	libzfs_handle_t *hdl = zhp->zpool_hdl;
905 	zfs_handle_t *zfsp;
906 	int i, ret = -1;
907 	int *good;
908 
909 	/*
910 	 * Gather all datasets within the pool.
911 	 */
912 	if ((cb.cb_datasets = zfs_alloc(hdl, 4 * sizeof (void *))) == NULL)
913 		return (-1);
914 	cb.cb_alloc = 4;
915 
916 	if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_ANY)) == NULL)
917 		goto out;
918 
919 	cb.cb_datasets[0] = zfsp;
920 	cb.cb_used = 1;
921 
922 	if (zfs_iter_children(zfsp, mount_cb, &cb) != 0)
923 		goto out;
924 
925 	/*
926 	 * Sort the datasets by mountpoint.
927 	 */
928 	qsort(cb.cb_datasets, cb.cb_used, sizeof (void *), dataset_cmp);
929 
930 	/*
931 	 * And mount all the datasets, keeping track of which ones
932 	 * succeeded or failed. By using zfs_alloc(), the good pointer
933 	 * will always be non-NULL.
934 	 */
935 	good = zfs_alloc(zhp->zpool_hdl, cb.cb_used * sizeof (int));
936 	ret = 0;
937 	for (i = 0; i < cb.cb_used; i++) {
938 		if (zfs_mount(cb.cb_datasets[i], mntopts, flags) != 0)
939 			ret = -1;
940 		else
941 			good[i] = 1;
942 	}
943 	/*
944 	 * Then share all the ones that need to be shared. This needs
945 	 * to be a separate pass in order to avoid excessive reloading
946 	 * of the configuration. Good should never be NULL since
947 	 * zfs_alloc is supposed to exit if memory isn't available.
948 	 */
949 	zfs_uninit_libshare(hdl);
950 	for (i = 0; i < cb.cb_used; i++) {
951 		if (good[i] && zfs_share(cb.cb_datasets[i]) != 0)
952 			ret = -1;
953 	}
954 
955 	free(good);
956 
957 out:
958 	for (i = 0; i < cb.cb_used; i++)
959 		zfs_close(cb.cb_datasets[i]);
960 	free(cb.cb_datasets);
961 
962 	return (ret);
963 }
964 
965 
966 static int
967 zvol_cb(const char *dataset, void *data)
968 {
969 	libzfs_handle_t *hdl = data;
970 	zfs_handle_t *zhp;
971 
972 	/*
973 	 * Ignore snapshots and ignore failures from non-existant datasets.
974 	 */
975 	if (strchr(dataset, '@') != NULL ||
976 	    (zhp = zfs_open(hdl, dataset, ZFS_TYPE_VOLUME)) == NULL)
977 		return (0);
978 
979 	(void) zfs_unshare_iscsi(zhp);
980 
981 	zfs_close(zhp);
982 
983 	return (0);
984 }
985 
986 static int
987 mountpoint_compare(const void *a, const void *b)
988 {
989 	const char *mounta = *((char **)a);
990 	const char *mountb = *((char **)b);
991 
992 	return (strcmp(mountb, mounta));
993 }
994 
995 /*
996  * Unshare and unmount all datasets within the given pool.  We don't want to
997  * rely on traversing the DSL to discover the filesystems within the pool,
998  * because this may be expensive (if not all of them are mounted), and can fail
999  * arbitrarily (on I/O error, for example).  Instead, we walk /etc/mnttab and
1000  * gather all the filesystems that are currently mounted.
1001  */
1002 #pragma weak zpool_unmount_datasets = zpool_disable_datasets
1003 int
1004 zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
1005 {
1006 	int used, alloc;
1007 	struct mnttab entry;
1008 	size_t namelen;
1009 	char **mountpoints = NULL;
1010 	zfs_handle_t **datasets = NULL;
1011 	libzfs_handle_t *hdl = zhp->zpool_hdl;
1012 	int i;
1013 	int ret = -1;
1014 	int flags = (force ? MS_FORCE : 0);
1015 
1016 	/*
1017 	 * First unshare all zvols.
1018 	 */
1019 	if (zpool_iter_zvol(zhp, zvol_cb, hdl) != 0)
1020 		return (-1);
1021 
1022 	namelen = strlen(zhp->zpool_name);
1023 
1024 	rewind(hdl->libzfs_mnttab);
1025 	used = alloc = 0;
1026 	while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
1027 		/*
1028 		 * Ignore non-ZFS entries.
1029 		 */
1030 		if (entry.mnt_fstype == NULL ||
1031 		    strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
1032 			continue;
1033 
1034 		/*
1035 		 * Ignore filesystems not within this pool.
1036 		 */
1037 		if (entry.mnt_mountp == NULL ||
1038 		    strncmp(entry.mnt_special, zhp->zpool_name, namelen) != 0 ||
1039 		    (entry.mnt_special[namelen] != '/' &&
1040 		    entry.mnt_special[namelen] != '\0'))
1041 			continue;
1042 
1043 		/*
1044 		 * At this point we've found a filesystem within our pool.  Add
1045 		 * it to our growing list.
1046 		 */
1047 		if (used == alloc) {
1048 			if (alloc == 0) {
1049 				if ((mountpoints = zfs_alloc(hdl,
1050 				    8 * sizeof (void *))) == NULL)
1051 					goto out;
1052 
1053 				if ((datasets = zfs_alloc(hdl,
1054 				    8 * sizeof (void *))) == NULL)
1055 					goto out;
1056 
1057 				alloc = 8;
1058 			} else {
1059 				void *ptr;
1060 
1061 				if ((ptr = zfs_realloc(hdl, mountpoints,
1062 				    alloc * sizeof (void *),
1063 				    alloc * 2 * sizeof (void *))) == NULL)
1064 					goto out;
1065 				mountpoints = ptr;
1066 
1067 				if ((ptr = zfs_realloc(hdl, datasets,
1068 				    alloc * sizeof (void *),
1069 				    alloc * 2 * sizeof (void *))) == NULL)
1070 					goto out;
1071 				datasets = ptr;
1072 
1073 				alloc *= 2;
1074 			}
1075 		}
1076 
1077 		if ((mountpoints[used] = zfs_strdup(hdl,
1078 		    entry.mnt_mountp)) == NULL)
1079 			goto out;
1080 
1081 		/*
1082 		 * This is allowed to fail, in case there is some I/O error.  It
1083 		 * is only used to determine if we need to remove the underlying
1084 		 * mountpoint, so failure is not fatal.
1085 		 */
1086 		datasets[used] = make_dataset_handle(hdl, entry.mnt_special);
1087 
1088 		used++;
1089 	}
1090 
1091 	/*
1092 	 * At this point, we have the entire list of filesystems, so sort it by
1093 	 * mountpoint.
1094 	 */
1095 	qsort(mountpoints, used, sizeof (char *), mountpoint_compare);
1096 
1097 	/*
1098 	 * Walk through and first unshare everything.
1099 	 */
1100 	for (i = 0; i < used; i++) {
1101 		if (is_shared(hdl, mountpoints[i]) &&
1102 		    unshare_one(hdl, mountpoints[i], mountpoints[i]) != 0)
1103 			goto out;
1104 	}
1105 
1106 	/*
1107 	 * Now unmount everything, removing the underlying directories as
1108 	 * appropriate.
1109 	 */
1110 	for (i = 0; i < used; i++) {
1111 		if (unmount_one(hdl, mountpoints[i], flags) != 0)
1112 			goto out;
1113 	}
1114 
1115 	for (i = 0; i < used; i++) {
1116 		if (datasets[i])
1117 			remove_mountpoint(datasets[i]);
1118 	}
1119 
1120 	ret = 0;
1121 out:
1122 	for (i = 0; i < used; i++) {
1123 		if (datasets[i])
1124 			zfs_close(datasets[i]);
1125 		free(mountpoints[i]);
1126 	}
1127 	free(datasets);
1128 	free(mountpoints);
1129 
1130 	return (ret);
1131 }
1132