1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
51544Seschrock  * Common Development and Distribution License (the "License").
61544Seschrock  * You may not use this file except in compliance with the License.
7789Sahrens  *
8789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9789Sahrens  * or http://www.opensolaris.org/os/licensing.
10789Sahrens  * See the License for the specific language governing permissions
11789Sahrens  * and limitations under the License.
12789Sahrens  *
13789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18789Sahrens  *
19789Sahrens  * CDDL HEADER END
20789Sahrens  */
21789Sahrens /*
221544Seschrock  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23789Sahrens  * Use is subject to license terms.
24789Sahrens  */
25789Sahrens 
26789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
27789Sahrens 
28789Sahrens /*
29789Sahrens  * Internal utility routines for the ZFS library.
30789Sahrens  */
31789Sahrens 
32789Sahrens #include <errno.h>
33789Sahrens #include <fcntl.h>
34789Sahrens #include <libintl.h>
35789Sahrens #include <stdarg.h>
36789Sahrens #include <stdio.h>
37789Sahrens #include <stdlib.h>
38789Sahrens #include <strings.h>
39789Sahrens #include <unistd.h>
40789Sahrens #include <sys/mnttab.h>
41789Sahrens 
42789Sahrens #include <libzfs.h>
43789Sahrens 
44789Sahrens #include "libzfs_impl.h"
45789Sahrens 
46*2082Seschrock int
47*2082Seschrock libzfs_errno(libzfs_handle_t *hdl)
48*2082Seschrock {
49*2082Seschrock 	return (hdl->libzfs_error);
50*2082Seschrock }
51789Sahrens 
52*2082Seschrock const char *
53*2082Seschrock libzfs_error_action(libzfs_handle_t *hdl)
54*2082Seschrock {
55*2082Seschrock 	return (hdl->libzfs_action);
56*2082Seschrock }
57*2082Seschrock 
58*2082Seschrock const char *
59*2082Seschrock libzfs_error_description(libzfs_handle_t *hdl)
60*2082Seschrock {
61*2082Seschrock 	if (hdl->libzfs_desc[0] != '\0')
62*2082Seschrock 		return (hdl->libzfs_desc);
63789Sahrens 
64*2082Seschrock 	switch (hdl->libzfs_error) {
65*2082Seschrock 	case EZFS_NOMEM:
66*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "out of memory"));
67*2082Seschrock 	case EZFS_BADPROP:
68*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid property value"));
69*2082Seschrock 	case EZFS_PROPREADONLY:
70*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "read only property"));
71*2082Seschrock 	case EZFS_PROPTYPE:
72*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "property doesn't apply to "
73*2082Seschrock 		    "datasets of this type"));
74*2082Seschrock 	case EZFS_PROPNONINHERIT:
75*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "property cannot be inherited"));
76*2082Seschrock 	case EZFS_PROPSPACE:
77*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid quota or reservation"));
78*2082Seschrock 	case EZFS_BADTYPE:
79*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "operation not applicable to "
80*2082Seschrock 		    "datasets of this type"));
81*2082Seschrock 	case EZFS_BUSY:
82*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "pool or dataset is busy"));
83*2082Seschrock 	case EZFS_EXISTS:
84*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "pool or dataset exists"));
85*2082Seschrock 	case EZFS_NOENT:
86*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "no such pool or dataset"));
87*2082Seschrock 	case EZFS_BADSTREAM:
88*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid backup stream"));
89*2082Seschrock 	case EZFS_DSREADONLY:
90*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "dataset is read only"));
91*2082Seschrock 	case EZFS_VOLTOOBIG:
92*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
93*2082Seschrock 		    "this system"));
94*2082Seschrock 	case EZFS_VOLHASDATA:
95*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "volume has data"));
96*2082Seschrock 	case EZFS_INVALIDNAME:
97*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid name"));
98*2082Seschrock 	case EZFS_BADRESTORE:
99*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "unable to restore to "
100*2082Seschrock 		    "destination"));
101*2082Seschrock 	case EZFS_BADBACKUP:
102*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "backup failed"));
103*2082Seschrock 	case EZFS_BADTARGET:
104*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
105*2082Seschrock 	case EZFS_NODEVICE:
106*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "no such device in pool"));
107*2082Seschrock 	case EZFS_BADDEV:
108*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid device"));
109*2082Seschrock 	case EZFS_NOREPLICAS:
110*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "no valid replicas"));
111*2082Seschrock 	case EZFS_RESILVERING:
112*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "currently resilvering"));
113*2082Seschrock 	case EZFS_BADVERSION:
114*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "unsupported version"));
115*2082Seschrock 	case EZFS_POOLUNAVAIL:
116*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
117*2082Seschrock 	case EZFS_DEVOVERFLOW:
118*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
119*2082Seschrock 	case EZFS_BADPATH:
120*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
121*2082Seschrock 	case EZFS_CROSSTARGET:
122*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
123*2082Seschrock 		    "pools"));
124*2082Seschrock 	case EZFS_ZONED:
125*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
126*2082Seschrock 	case EZFS_MOUNTFAILED:
127*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "mount failed"));
128*2082Seschrock 	case EZFS_UMOUNTFAILED:
129*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "umount failed"));
130*2082Seschrock 	case EZFS_UNSHAREFAILED:
131*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
132*2082Seschrock 	case EZFS_SHAREFAILED:
133*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
134*2082Seschrock 	case EZFS_DEVLINKS:
135*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "failed to create /dev links"));
136*2082Seschrock 	case EZFS_PERM:
137*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "permission denied"));
138*2082Seschrock 	case EZFS_NOSPC:
139*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "out of space"));
140*2082Seschrock 	case EZFS_IO:
141*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "I/O error"));
142*2082Seschrock 	case EZFS_INTR:
143*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "signal received"));
144*2082Seschrock 	case EZFS_ISSPARE:
145*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "device is reserved as a hot "
146*2082Seschrock 		    "spare"));
147*2082Seschrock 	case EZFS_INVALCONFIG:
148*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "invalid vdev configuration"));
149*2082Seschrock 	case EZFS_UNKNOWN:
150*2082Seschrock 		return (dgettext(TEXT_DOMAIN, "unknown error"));
151*2082Seschrock 	default:
152*2082Seschrock 		abort();
153*2082Seschrock 	}
154*2082Seschrock 
155*2082Seschrock 	/* NOTREACHED */
156*2082Seschrock }
157*2082Seschrock 
158*2082Seschrock /*PRINTFLIKE2*/
159789Sahrens void
160*2082Seschrock zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...)
161789Sahrens {
162789Sahrens 	va_list ap;
163789Sahrens 
164789Sahrens 	va_start(ap, fmt);
165789Sahrens 
166*2082Seschrock 	(void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc),
167*2082Seschrock 	    fmt, ap);
168*2082Seschrock 	hdl->libzfs_desc_active = 1;
169789Sahrens 
170789Sahrens 	va_end(ap);
171789Sahrens }
172789Sahrens 
173*2082Seschrock static void
174*2082Seschrock zfs_verror(libzfs_handle_t *hdl, int error, const char *fmt, va_list ap)
175*2082Seschrock {
176*2082Seschrock 	(void) vsnprintf(hdl->libzfs_action, sizeof (hdl->libzfs_action),
177*2082Seschrock 	    fmt, ap);
178*2082Seschrock 	hdl->libzfs_error = error;
179*2082Seschrock 
180*2082Seschrock 	if (hdl->libzfs_desc_active)
181*2082Seschrock 		hdl->libzfs_desc_active = 0;
182*2082Seschrock 	else
183*2082Seschrock 		hdl->libzfs_desc[0] = '\0';
184*2082Seschrock 
185*2082Seschrock 	if (hdl->libzfs_printerr) {
186*2082Seschrock 		if (error == EZFS_UNKNOWN) {
187*2082Seschrock 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "internal "
188*2082Seschrock 			    "error: %s\n"), libzfs_error_description(hdl));
189*2082Seschrock 			abort();
190*2082Seschrock 		}
191*2082Seschrock 
192*2082Seschrock 		(void) fprintf(stderr, "%s: %s\n", hdl->libzfs_action,
193*2082Seschrock 		    libzfs_error_description(hdl));
194*2082Seschrock 		if (error == EZFS_NOMEM)
195*2082Seschrock 			exit(1);
196*2082Seschrock 	}
197*2082Seschrock }
198*2082Seschrock 
199*2082Seschrock /*PRINTFLIKE3*/
200*2082Seschrock int
201*2082Seschrock zfs_error(libzfs_handle_t *hdl, int error, const char *fmt, ...)
202*2082Seschrock {
203*2082Seschrock 	va_list ap;
204*2082Seschrock 
205*2082Seschrock 	va_start(ap, fmt);
206*2082Seschrock 
207*2082Seschrock 	zfs_verror(hdl, error, fmt, ap);
208*2082Seschrock 
209*2082Seschrock 	va_end(ap);
210*2082Seschrock 
211*2082Seschrock 	return (-1);
212*2082Seschrock }
213*2082Seschrock 
214*2082Seschrock static int
215*2082Seschrock zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
216*2082Seschrock     va_list ap)
217*2082Seschrock {
218*2082Seschrock 	switch (error) {
219*2082Seschrock 	case EPERM:
220*2082Seschrock 	case EACCES:
221*2082Seschrock 		zfs_verror(hdl, EZFS_PERM, fmt, ap);
222*2082Seschrock 		return (-1);
223*2082Seschrock 
224*2082Seschrock 	case EIO:
225*2082Seschrock 		zfs_verror(hdl, EZFS_IO, fmt, ap);
226*2082Seschrock 		return (-1);
227*2082Seschrock 
228*2082Seschrock 	case EINTR:
229*2082Seschrock 		zfs_verror(hdl, EZFS_INTR, fmt, ap);
230*2082Seschrock 		return (-1);
231*2082Seschrock 	}
232*2082Seschrock 
233*2082Seschrock 	return (0);
234*2082Seschrock }
235*2082Seschrock 
236*2082Seschrock /*PRINTFLIKE3*/
237*2082Seschrock int
238*2082Seschrock zfs_standard_error(libzfs_handle_t *hdl, int error, const char *fmt, ...)
239789Sahrens {
240789Sahrens 	va_list ap;
241789Sahrens 
242789Sahrens 	va_start(ap, fmt);
243789Sahrens 
244*2082Seschrock 	if (zfs_common_error(hdl, error, fmt, ap) != 0) {
245*2082Seschrock 		va_end(ap);
246*2082Seschrock 		return (-1);
247*2082Seschrock 	}
248*2082Seschrock 
249*2082Seschrock 
250*2082Seschrock 	switch (error) {
251*2082Seschrock 	case ENXIO:
252*2082Seschrock 		zfs_verror(hdl, EZFS_IO, fmt, ap);
253*2082Seschrock 		break;
254*2082Seschrock 
255*2082Seschrock 	case ENOENT:
256*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
257*2082Seschrock 		    "dataset does not exist"));
258*2082Seschrock 		zfs_verror(hdl, EZFS_NOENT, fmt, ap);
259*2082Seschrock 		break;
260*2082Seschrock 
261*2082Seschrock 	case ENOSPC:
262*2082Seschrock 	case EDQUOT:
263*2082Seschrock 		zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
264*2082Seschrock 		return (-1);
265*2082Seschrock 
266*2082Seschrock 	case EEXIST:
267*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
268*2082Seschrock 		    "dataset already exists"));
269*2082Seschrock 		zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
270*2082Seschrock 		break;
271*2082Seschrock 
272*2082Seschrock 	case EBUSY:
273*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
274*2082Seschrock 		    "dataset is busy"));
275*2082Seschrock 		zfs_verror(hdl, EZFS_BUSY, fmt, ap);
276*2082Seschrock 		break;
277*2082Seschrock 
278*2082Seschrock 	default:
279*2082Seschrock 		zfs_error_aux(hdl, strerror(errno));
280*2082Seschrock 		zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
281*2082Seschrock 		break;
282789Sahrens 	}
283789Sahrens 
284789Sahrens 	va_end(ap);
285*2082Seschrock 	return (-1);
286789Sahrens }
287789Sahrens 
288*2082Seschrock /*PRINTFLIKE3*/
289*2082Seschrock int
290*2082Seschrock zpool_standard_error(libzfs_handle_t *hdl, int error, const char *fmt, ...)
291789Sahrens {
292*2082Seschrock 	va_list ap;
293*2082Seschrock 
294*2082Seschrock 	va_start(ap, fmt);
295*2082Seschrock 
296*2082Seschrock 	if (zfs_common_error(hdl, error, fmt, ap) != 0) {
297*2082Seschrock 		va_end(ap);
298*2082Seschrock 		return (-1);
299*2082Seschrock 	}
300*2082Seschrock 
301*2082Seschrock 	switch (error) {
302*2082Seschrock 	case ENODEV:
303*2082Seschrock 		zfs_verror(hdl, EZFS_NODEVICE, fmt, ap);
304*2082Seschrock 		break;
305*2082Seschrock 
306*2082Seschrock 	case ENOENT:
307*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
308*2082Seschrock 		zfs_verror(hdl, EZFS_NOENT, fmt, ap);
309*2082Seschrock 		break;
310*2082Seschrock 
311*2082Seschrock 	case EEXIST:
312*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
313*2082Seschrock 		    "pool already exists"));
314*2082Seschrock 		zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
315*2082Seschrock 		break;
316*2082Seschrock 
317*2082Seschrock 	case EBUSY:
318*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
319*2082Seschrock 		zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
320*2082Seschrock 		break;
321*2082Seschrock 
322*2082Seschrock 	case ENXIO:
323*2082Seschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
324*2082Seschrock 		    "one or more devices is currently unavailable"));
325*2082Seschrock 		zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
326*2082Seschrock 		break;
327*2082Seschrock 
328*2082Seschrock 	case ENAMETOOLONG:
329*2082Seschrock 		zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap);
330*2082Seschrock 		break;
331*2082Seschrock 
332*2082Seschrock 	default:
333*2082Seschrock 		zfs_error_aux(hdl, strerror(error));
334*2082Seschrock 		zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
335*2082Seschrock 	}
336*2082Seschrock 
337*2082Seschrock 	va_end(ap);
338*2082Seschrock 	return (-1);
339789Sahrens }
340789Sahrens 
341789Sahrens /*
342789Sahrens  * Display an out of memory error message and abort the current program.
343789Sahrens  */
344*2082Seschrock int
345*2082Seschrock no_memory(libzfs_handle_t *hdl)
346789Sahrens {
347*2082Seschrock 	return (zfs_error(hdl, EZFS_NOMEM, "internal error"));
348789Sahrens }
349789Sahrens 
350789Sahrens /*
351789Sahrens  * A safe form of malloc() which will die if the allocation fails.
352789Sahrens  */
353789Sahrens void *
354*2082Seschrock zfs_alloc(libzfs_handle_t *hdl, size_t size)
355789Sahrens {
356789Sahrens 	void *data;
357789Sahrens 
358789Sahrens 	if ((data = calloc(1, size)) == NULL)
359*2082Seschrock 		(void) no_memory(hdl);
360789Sahrens 
361789Sahrens 	return (data);
362789Sahrens }
363789Sahrens 
364789Sahrens /*
365789Sahrens  * A safe form of strdup() which will die if the allocation fails.
366789Sahrens  */
367789Sahrens char *
368*2082Seschrock zfs_strdup(libzfs_handle_t *hdl, const char *str)
369789Sahrens {
370789Sahrens 	char *ret;
371789Sahrens 
372789Sahrens 	if ((ret = strdup(str)) == NULL)
373*2082Seschrock 		(void) no_memory(hdl);
374789Sahrens 
375789Sahrens 	return (ret);
376789Sahrens }
377789Sahrens 
378789Sahrens /*
379789Sahrens  * Convert a number to an appropriately human-readable output.
380789Sahrens  */
381789Sahrens void
382789Sahrens zfs_nicenum(uint64_t num, char *buf, size_t buflen)
383789Sahrens {
384789Sahrens 	uint64_t n = num;
385789Sahrens 	int index = 0;
386789Sahrens 	char u;
387789Sahrens 
388789Sahrens 	while (n >= 1024) {
3891162Seschrock 		n /= 1024;
390789Sahrens 		index++;
391789Sahrens 	}
392789Sahrens 
393789Sahrens 	u = " KMGTPE"[index];
394789Sahrens 
3951162Seschrock 	if (index == 0) {
396789Sahrens 		(void) snprintf(buf, buflen, "%llu", n);
3971162Seschrock 	} else if ((num & ((1ULL << 10 * index) - 1)) == 0) {
3981162Seschrock 		/*
3991162Seschrock 		 * If this is an even multiple of the base, always display
4001162Seschrock 		 * without any decimal precision.
4011162Seschrock 		 */
402789Sahrens 		(void) snprintf(buf, buflen, "%llu%c", n, u);
4031162Seschrock 	} else {
4041162Seschrock 		/*
4051162Seschrock 		 * We want to choose a precision that reflects the best choice
4061162Seschrock 		 * for fitting in 5 characters.  This can get rather tricky when
4071162Seschrock 		 * we have numbers that are very close to an order of magnitude.
4081162Seschrock 		 * For example, when displaying 10239 (which is really 9.999K),
4091162Seschrock 		 * we want only a single place of precision for 10.0K.  We could
4101162Seschrock 		 * develop some complex heuristics for this, but it's much
4111162Seschrock 		 * easier just to try each combination in turn.
4121162Seschrock 		 */
4131162Seschrock 		int i;
4141162Seschrock 		for (i = 2; i >= 0; i--) {
4151162Seschrock 			(void) snprintf(buf, buflen, "%.*f%c", i,
4161162Seschrock 			    (double)num / (1ULL << 10 * index), u);
4171162Seschrock 			if (strlen(buf) <= 5)
4181162Seschrock 				break;
4191162Seschrock 		}
4201162Seschrock 	}
421789Sahrens }
422*2082Seschrock 
423*2082Seschrock void
424*2082Seschrock libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr)
425*2082Seschrock {
426*2082Seschrock 	hdl->libzfs_printerr = printerr;
427*2082Seschrock }
428*2082Seschrock 
429*2082Seschrock libzfs_handle_t *
430*2082Seschrock libzfs_init(void)
431*2082Seschrock {
432*2082Seschrock 	libzfs_handle_t *hdl;
433*2082Seschrock 
434*2082Seschrock 	if ((hdl = calloc(sizeof (libzfs_handle_t), 1)) == NULL) {
435*2082Seschrock 		return (NULL);
436*2082Seschrock 	}
437*2082Seschrock 
438*2082Seschrock 	if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) == NULL) {
439*2082Seschrock 		free(hdl);
440*2082Seschrock 		return (NULL);
441*2082Seschrock 	}
442*2082Seschrock 
443*2082Seschrock 	if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
444*2082Seschrock 		(void) close(hdl->libzfs_fd);
445*2082Seschrock 		free(hdl);
446*2082Seschrock 		return (NULL);
447*2082Seschrock 	}
448*2082Seschrock 
449*2082Seschrock 	hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r");
450*2082Seschrock 
451*2082Seschrock 	return (hdl);
452*2082Seschrock }
453*2082Seschrock 
454*2082Seschrock void
455*2082Seschrock libzfs_fini(libzfs_handle_t *hdl)
456*2082Seschrock {
457*2082Seschrock 	(void) close(hdl->libzfs_fd);
458*2082Seschrock 	if (hdl->libzfs_mnttab)
459*2082Seschrock 		(void) fclose(hdl->libzfs_mnttab);
460*2082Seschrock 	if (hdl->libzfs_sharetab)
461*2082Seschrock 		(void) fclose(hdl->libzfs_sharetab);
462*2082Seschrock 	namespace_clear(hdl);
463*2082Seschrock 	free(hdl);
464*2082Seschrock }
465*2082Seschrock 
466*2082Seschrock libzfs_handle_t *
467*2082Seschrock zpool_get_handle(zpool_handle_t *zhp)
468*2082Seschrock {
469*2082Seschrock 	return (zhp->zpool_hdl);
470*2082Seschrock }
471*2082Seschrock 
472*2082Seschrock libzfs_handle_t *
473*2082Seschrock zfs_get_handle(zfs_handle_t *zhp)
474*2082Seschrock {
475*2082Seschrock 	return (zhp->zfs_hdl);
476*2082Seschrock }
477