xref: /illumos-gate/usr/src/lib/libzfs/common/libzfs_util.c (revision f3861e1a2ceec23a5b699c24d814b7775a9e0b52)
1fa9e4066Sahrens /*
2fa9e4066Sahrens  * CDDL HEADER START
3fa9e4066Sahrens  *
4fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5ea8dc4b6Seschrock  * Common Development and Distribution License (the "License").
6ea8dc4b6Seschrock  * You may not use this file except in compliance with the License.
7fa9e4066Sahrens  *
8fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
10fa9e4066Sahrens  * See the License for the specific language governing permissions
11fa9e4066Sahrens  * and limitations under the License.
12fa9e4066Sahrens  *
13fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e4066Sahrens  *
19fa9e4066Sahrens  * CDDL HEADER END
20fa9e4066Sahrens  */
21fa9e4066Sahrens /*
22ea8dc4b6Seschrock  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23fa9e4066Sahrens  * Use is subject to license terms.
24fa9e4066Sahrens  */
25fa9e4066Sahrens 
26fa9e4066Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
27fa9e4066Sahrens 
28fa9e4066Sahrens /*
29fa9e4066Sahrens  * Internal utility routines for the ZFS library.
30fa9e4066Sahrens  */
31fa9e4066Sahrens 
32fa9e4066Sahrens #include <errno.h>
33fa9e4066Sahrens #include <fcntl.h>
34fa9e4066Sahrens #include <libintl.h>
35fa9e4066Sahrens #include <stdarg.h>
36fa9e4066Sahrens #include <stdio.h>
37fa9e4066Sahrens #include <stdlib.h>
38fa9e4066Sahrens #include <strings.h>
39fa9e4066Sahrens #include <unistd.h>
40fa9e4066Sahrens #include <sys/mnttab.h>
41fa9e4066Sahrens 
42fa9e4066Sahrens #include <libzfs.h>
43fa9e4066Sahrens 
44fa9e4066Sahrens #include "libzfs_impl.h"
45fa9e4066Sahrens 
4699653d4eSeschrock int
4799653d4eSeschrock libzfs_errno(libzfs_handle_t *hdl)
4899653d4eSeschrock {
4999653d4eSeschrock 	return (hdl->libzfs_error);
5099653d4eSeschrock }
51fa9e4066Sahrens 
5299653d4eSeschrock const char *
5399653d4eSeschrock libzfs_error_action(libzfs_handle_t *hdl)
5499653d4eSeschrock {
5599653d4eSeschrock 	return (hdl->libzfs_action);
5699653d4eSeschrock }
57fa9e4066Sahrens 
5899653d4eSeschrock const char *
5999653d4eSeschrock libzfs_error_description(libzfs_handle_t *hdl)
6099653d4eSeschrock {
6199653d4eSeschrock 	if (hdl->libzfs_desc[0] != '\0')
6299653d4eSeschrock 		return (hdl->libzfs_desc);
6399653d4eSeschrock 
6499653d4eSeschrock 	switch (hdl->libzfs_error) {
6599653d4eSeschrock 	case EZFS_NOMEM:
6699653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "out of memory"));
6799653d4eSeschrock 	case EZFS_BADPROP:
6899653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid property value"));
6999653d4eSeschrock 	case EZFS_PROPREADONLY:
7099653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "read only property"));
7199653d4eSeschrock 	case EZFS_PROPTYPE:
7299653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "property doesn't apply to "
7399653d4eSeschrock 		    "datasets of this type"));
7499653d4eSeschrock 	case EZFS_PROPNONINHERIT:
7599653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "property cannot be inherited"));
7699653d4eSeschrock 	case EZFS_PROPSPACE:
7799653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid quota or reservation"));
7899653d4eSeschrock 	case EZFS_BADTYPE:
7999653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "operation not applicable to "
8099653d4eSeschrock 		    "datasets of this type"));
8199653d4eSeschrock 	case EZFS_BUSY:
8299653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "pool or dataset is busy"));
8399653d4eSeschrock 	case EZFS_EXISTS:
8499653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "pool or dataset exists"));
8599653d4eSeschrock 	case EZFS_NOENT:
8699653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "no such pool or dataset"));
8799653d4eSeschrock 	case EZFS_BADSTREAM:
8899653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid backup stream"));
8999653d4eSeschrock 	case EZFS_DSREADONLY:
9099653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "dataset is read only"));
9199653d4eSeschrock 	case EZFS_VOLTOOBIG:
9299653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
9399653d4eSeschrock 		    "this system"));
9499653d4eSeschrock 	case EZFS_VOLHASDATA:
9599653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "volume has data"));
9699653d4eSeschrock 	case EZFS_INVALIDNAME:
9799653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid name"));
9899653d4eSeschrock 	case EZFS_BADRESTORE:
9999653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "unable to restore to "
10099653d4eSeschrock 		    "destination"));
10199653d4eSeschrock 	case EZFS_BADBACKUP:
10299653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "backup failed"));
10399653d4eSeschrock 	case EZFS_BADTARGET:
10499653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
10599653d4eSeschrock 	case EZFS_NODEVICE:
10699653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "no such device in pool"));
10799653d4eSeschrock 	case EZFS_BADDEV:
10899653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid device"));
10999653d4eSeschrock 	case EZFS_NOREPLICAS:
11099653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "no valid replicas"));
11199653d4eSeschrock 	case EZFS_RESILVERING:
11299653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "currently resilvering"));
11399653d4eSeschrock 	case EZFS_BADVERSION:
11499653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "unsupported version"));
11599653d4eSeschrock 	case EZFS_POOLUNAVAIL:
11699653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
11799653d4eSeschrock 	case EZFS_DEVOVERFLOW:
11899653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
11999653d4eSeschrock 	case EZFS_BADPATH:
12099653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
12199653d4eSeschrock 	case EZFS_CROSSTARGET:
12299653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
12399653d4eSeschrock 		    "pools"));
12499653d4eSeschrock 	case EZFS_ZONED:
12599653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
12699653d4eSeschrock 	case EZFS_MOUNTFAILED:
12799653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "mount failed"));
12899653d4eSeschrock 	case EZFS_UMOUNTFAILED:
12999653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "umount failed"));
130*f3861e1aSahl 	case EZFS_UNSHARENFSFAILED:
13199653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
132*f3861e1aSahl 	case EZFS_SHARENFSFAILED:
13399653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
13499653d4eSeschrock 	case EZFS_DEVLINKS:
13599653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "failed to create /dev links"));
13699653d4eSeschrock 	case EZFS_PERM:
13799653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "permission denied"));
13899653d4eSeschrock 	case EZFS_NOSPC:
13999653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "out of space"));
14099653d4eSeschrock 	case EZFS_IO:
14199653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "I/O error"));
14299653d4eSeschrock 	case EZFS_INTR:
14399653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "signal received"));
14499653d4eSeschrock 	case EZFS_ISSPARE:
14599653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "device is reserved as a hot "
14699653d4eSeschrock 		    "spare"));
14799653d4eSeschrock 	case EZFS_INVALCONFIG:
14899653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "invalid vdev configuration"));
1493bb79becSeschrock 	case EZFS_RECURSIVE:
1503bb79becSeschrock 		return (dgettext(TEXT_DOMAIN, "recursive dataset dependency"));
15106eeb2adSek 	case EZFS_NOHISTORY:
15206eeb2adSek 		return (dgettext(TEXT_DOMAIN, "no history available"));
153*f3861e1aSahl 	case EZFS_UNSHAREISCSIFAILED:
154*f3861e1aSahl 		return (dgettext(TEXT_DOMAIN,
155*f3861e1aSahl 		    "iscsitgtd failed request to unshare"));
156*f3861e1aSahl 	case EZFS_SHAREISCSIFAILED:
157*f3861e1aSahl 		return (dgettext(TEXT_DOMAIN,
158*f3861e1aSahl 		    "iscsitgtd failed request to share"));
15999653d4eSeschrock 	case EZFS_UNKNOWN:
16099653d4eSeschrock 		return (dgettext(TEXT_DOMAIN, "unknown error"));
16199653d4eSeschrock 	default:
162c08432ebSeschrock 		assert(hdl->libzfs_error == 0);
163c08432ebSeschrock 		return (dgettext(TEXT_DOMAIN, "no error"));
16499653d4eSeschrock 	}
16599653d4eSeschrock }
16699653d4eSeschrock 
16799653d4eSeschrock /*PRINTFLIKE2*/
168fa9e4066Sahrens void
16999653d4eSeschrock zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...)
170fa9e4066Sahrens {
171fa9e4066Sahrens 	va_list ap;
172fa9e4066Sahrens 
173fa9e4066Sahrens 	va_start(ap, fmt);
174fa9e4066Sahrens 
17599653d4eSeschrock 	(void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc),
17699653d4eSeschrock 	    fmt, ap);
17799653d4eSeschrock 	hdl->libzfs_desc_active = 1;
17899653d4eSeschrock 
17999653d4eSeschrock 	va_end(ap);
18099653d4eSeschrock }
18199653d4eSeschrock 
18299653d4eSeschrock static void
18399653d4eSeschrock zfs_verror(libzfs_handle_t *hdl, int error, const char *fmt, va_list ap)
18499653d4eSeschrock {
18599653d4eSeschrock 	(void) vsnprintf(hdl->libzfs_action, sizeof (hdl->libzfs_action),
18699653d4eSeschrock 	    fmt, ap);
18799653d4eSeschrock 	hdl->libzfs_error = error;
18899653d4eSeschrock 
18999653d4eSeschrock 	if (hdl->libzfs_desc_active)
19099653d4eSeschrock 		hdl->libzfs_desc_active = 0;
19199653d4eSeschrock 	else
19299653d4eSeschrock 		hdl->libzfs_desc[0] = '\0';
19399653d4eSeschrock 
19499653d4eSeschrock 	if (hdl->libzfs_printerr) {
19599653d4eSeschrock 		if (error == EZFS_UNKNOWN) {
19699653d4eSeschrock 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "internal "
19799653d4eSeschrock 			    "error: %s\n"), libzfs_error_description(hdl));
19899653d4eSeschrock 			abort();
19999653d4eSeschrock 		}
20099653d4eSeschrock 
20199653d4eSeschrock 		(void) fprintf(stderr, "%s: %s\n", hdl->libzfs_action,
20299653d4eSeschrock 		    libzfs_error_description(hdl));
20399653d4eSeschrock 		if (error == EZFS_NOMEM)
20499653d4eSeschrock 			exit(1);
205fa9e4066Sahrens 	}
20699653d4eSeschrock }
20799653d4eSeschrock 
20899653d4eSeschrock /*PRINTFLIKE3*/
20999653d4eSeschrock int
21099653d4eSeschrock zfs_error(libzfs_handle_t *hdl, int error, const char *fmt, ...)
21199653d4eSeschrock {
21299653d4eSeschrock 	va_list ap;
21399653d4eSeschrock 
21499653d4eSeschrock 	va_start(ap, fmt);
21599653d4eSeschrock 
21699653d4eSeschrock 	zfs_verror(hdl, error, fmt, ap);
217fa9e4066Sahrens 
218fa9e4066Sahrens 	va_end(ap);
21999653d4eSeschrock 
22099653d4eSeschrock 	return (-1);
221fa9e4066Sahrens }
222fa9e4066Sahrens 
22399653d4eSeschrock static int
22499653d4eSeschrock zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
22599653d4eSeschrock     va_list ap)
22699653d4eSeschrock {
22799653d4eSeschrock 	switch (error) {
22899653d4eSeschrock 	case EPERM:
22999653d4eSeschrock 	case EACCES:
23099653d4eSeschrock 		zfs_verror(hdl, EZFS_PERM, fmt, ap);
23199653d4eSeschrock 		return (-1);
23299653d4eSeschrock 
23399653d4eSeschrock 	case EIO:
23499653d4eSeschrock 		zfs_verror(hdl, EZFS_IO, fmt, ap);
23599653d4eSeschrock 		return (-1);
23699653d4eSeschrock 
23799653d4eSeschrock 	case EINTR:
23899653d4eSeschrock 		zfs_verror(hdl, EZFS_INTR, fmt, ap);
23999653d4eSeschrock 		return (-1);
24099653d4eSeschrock 	}
24199653d4eSeschrock 
24299653d4eSeschrock 	return (0);
24399653d4eSeschrock }
24499653d4eSeschrock 
24599653d4eSeschrock /*PRINTFLIKE3*/
24699653d4eSeschrock int
24799653d4eSeschrock zfs_standard_error(libzfs_handle_t *hdl, int error, const char *fmt, ...)
248fa9e4066Sahrens {
249fa9e4066Sahrens 	va_list ap;
250fa9e4066Sahrens 
251fa9e4066Sahrens 	va_start(ap, fmt);
252fa9e4066Sahrens 
25399653d4eSeschrock 	if (zfs_common_error(hdl, error, fmt, ap) != 0) {
25499653d4eSeschrock 		va_end(ap);
25599653d4eSeschrock 		return (-1);
256fa9e4066Sahrens 	}
257fa9e4066Sahrens 
258fa9e4066Sahrens 
25999653d4eSeschrock 	switch (error) {
26099653d4eSeschrock 	case ENXIO:
26199653d4eSeschrock 		zfs_verror(hdl, EZFS_IO, fmt, ap);
26299653d4eSeschrock 		break;
26399653d4eSeschrock 
26499653d4eSeschrock 	case ENOENT:
26599653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
26699653d4eSeschrock 		    "dataset does not exist"));
26799653d4eSeschrock 		zfs_verror(hdl, EZFS_NOENT, fmt, ap);
26899653d4eSeschrock 		break;
26999653d4eSeschrock 
27099653d4eSeschrock 	case ENOSPC:
27199653d4eSeschrock 	case EDQUOT:
27299653d4eSeschrock 		zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
27399653d4eSeschrock 		return (-1);
27499653d4eSeschrock 
27599653d4eSeschrock 	case EEXIST:
27699653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
27799653d4eSeschrock 		    "dataset already exists"));
27899653d4eSeschrock 		zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
27999653d4eSeschrock 		break;
28099653d4eSeschrock 
28199653d4eSeschrock 	case EBUSY:
28299653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
28399653d4eSeschrock 		    "dataset is busy"));
28499653d4eSeschrock 		zfs_verror(hdl, EZFS_BUSY, fmt, ap);
28599653d4eSeschrock 		break;
28699653d4eSeschrock 
28799653d4eSeschrock 	default:
28899653d4eSeschrock 		zfs_error_aux(hdl, strerror(errno));
28999653d4eSeschrock 		zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
29099653d4eSeschrock 		break;
29199653d4eSeschrock 	}
29299653d4eSeschrock 
29399653d4eSeschrock 	va_end(ap);
29499653d4eSeschrock 	return (-1);
295fa9e4066Sahrens }
296fa9e4066Sahrens 
29799653d4eSeschrock /*PRINTFLIKE3*/
29899653d4eSeschrock int
29999653d4eSeschrock zpool_standard_error(libzfs_handle_t *hdl, int error, const char *fmt, ...)
300fa9e4066Sahrens {
30199653d4eSeschrock 	va_list ap;
30299653d4eSeschrock 
30399653d4eSeschrock 	va_start(ap, fmt);
30499653d4eSeschrock 
30599653d4eSeschrock 	if (zfs_common_error(hdl, error, fmt, ap) != 0) {
30699653d4eSeschrock 		va_end(ap);
30799653d4eSeschrock 		return (-1);
30899653d4eSeschrock 	}
30999653d4eSeschrock 
31099653d4eSeschrock 	switch (error) {
31199653d4eSeschrock 	case ENODEV:
31299653d4eSeschrock 		zfs_verror(hdl, EZFS_NODEVICE, fmt, ap);
31399653d4eSeschrock 		break;
31499653d4eSeschrock 
31599653d4eSeschrock 	case ENOENT:
31699653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
31799653d4eSeschrock 		zfs_verror(hdl, EZFS_NOENT, fmt, ap);
31899653d4eSeschrock 		break;
31999653d4eSeschrock 
32099653d4eSeschrock 	case EEXIST:
32199653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
32299653d4eSeschrock 		    "pool already exists"));
32399653d4eSeschrock 		zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
32499653d4eSeschrock 		break;
32599653d4eSeschrock 
32699653d4eSeschrock 	case EBUSY:
32799653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
32899653d4eSeschrock 		zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
32999653d4eSeschrock 		break;
33099653d4eSeschrock 
33199653d4eSeschrock 	case ENXIO:
33299653d4eSeschrock 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
33399653d4eSeschrock 		    "one or more devices is currently unavailable"));
33499653d4eSeschrock 		zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
33599653d4eSeschrock 		break;
33699653d4eSeschrock 
33799653d4eSeschrock 	case ENAMETOOLONG:
33899653d4eSeschrock 		zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap);
33999653d4eSeschrock 		break;
34099653d4eSeschrock 
34199653d4eSeschrock 	default:
34299653d4eSeschrock 		zfs_error_aux(hdl, strerror(error));
34399653d4eSeschrock 		zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
34499653d4eSeschrock 	}
34599653d4eSeschrock 
34699653d4eSeschrock 	va_end(ap);
34799653d4eSeschrock 	return (-1);
348fa9e4066Sahrens }
349fa9e4066Sahrens 
350fa9e4066Sahrens /*
351fa9e4066Sahrens  * Display an out of memory error message and abort the current program.
352fa9e4066Sahrens  */
35399653d4eSeschrock int
35499653d4eSeschrock no_memory(libzfs_handle_t *hdl)
355fa9e4066Sahrens {
35699653d4eSeschrock 	return (zfs_error(hdl, EZFS_NOMEM, "internal error"));
357fa9e4066Sahrens }
358fa9e4066Sahrens 
359fa9e4066Sahrens /*
360fa9e4066Sahrens  * A safe form of malloc() which will die if the allocation fails.
361fa9e4066Sahrens  */
362fa9e4066Sahrens void *
36399653d4eSeschrock zfs_alloc(libzfs_handle_t *hdl, size_t size)
364fa9e4066Sahrens {
365fa9e4066Sahrens 	void *data;
366fa9e4066Sahrens 
367fa9e4066Sahrens 	if ((data = calloc(1, size)) == NULL)
36899653d4eSeschrock 		(void) no_memory(hdl);
369fa9e4066Sahrens 
370fa9e4066Sahrens 	return (data);
371fa9e4066Sahrens }
372fa9e4066Sahrens 
373e9dbad6fSeschrock /*
374e9dbad6fSeschrock  * A safe form of realloc(), which also zeroes newly allocated space.
375e9dbad6fSeschrock  */
376e9dbad6fSeschrock void *
377e9dbad6fSeschrock zfs_realloc(libzfs_handle_t *hdl, void *ptr, size_t oldsize, size_t newsize)
378e9dbad6fSeschrock {
379e9dbad6fSeschrock 	void *ret;
380e9dbad6fSeschrock 
381e9dbad6fSeschrock 	if ((ret = realloc(ptr, newsize)) == NULL) {
382e9dbad6fSeschrock 		(void) no_memory(hdl);
383e9dbad6fSeschrock 		free(ptr);
384e9dbad6fSeschrock 		return (NULL);
385e9dbad6fSeschrock 	}
386e9dbad6fSeschrock 
387e9dbad6fSeschrock 	bzero((char *)ret + oldsize, (newsize - oldsize));
388e9dbad6fSeschrock 	return (ret);
389e9dbad6fSeschrock }
390e9dbad6fSeschrock 
391fa9e4066Sahrens /*
392fa9e4066Sahrens  * A safe form of strdup() which will die if the allocation fails.
393fa9e4066Sahrens  */
394fa9e4066Sahrens char *
39599653d4eSeschrock zfs_strdup(libzfs_handle_t *hdl, const char *str)
396fa9e4066Sahrens {
397fa9e4066Sahrens 	char *ret;
398fa9e4066Sahrens 
399fa9e4066Sahrens 	if ((ret = strdup(str)) == NULL)
40099653d4eSeschrock 		(void) no_memory(hdl);
401fa9e4066Sahrens 
402fa9e4066Sahrens 	return (ret);
403fa9e4066Sahrens }
404fa9e4066Sahrens 
405fa9e4066Sahrens /*
406fa9e4066Sahrens  * Convert a number to an appropriately human-readable output.
407fa9e4066Sahrens  */
408fa9e4066Sahrens void
409fa9e4066Sahrens zfs_nicenum(uint64_t num, char *buf, size_t buflen)
410fa9e4066Sahrens {
411fa9e4066Sahrens 	uint64_t n = num;
412fa9e4066Sahrens 	int index = 0;
413fa9e4066Sahrens 	char u;
414fa9e4066Sahrens 
415fa9e4066Sahrens 	while (n >= 1024) {
4165c709891Seschrock 		n /= 1024;
417fa9e4066Sahrens 		index++;
418fa9e4066Sahrens 	}
419fa9e4066Sahrens 
420fa9e4066Sahrens 	u = " KMGTPE"[index];
421fa9e4066Sahrens 
4225c709891Seschrock 	if (index == 0) {
423fa9e4066Sahrens 		(void) snprintf(buf, buflen, "%llu", n);
4245c709891Seschrock 	} else if ((num & ((1ULL << 10 * index) - 1)) == 0) {
4255c709891Seschrock 		/*
4265c709891Seschrock 		 * If this is an even multiple of the base, always display
4275c709891Seschrock 		 * without any decimal precision.
4285c709891Seschrock 		 */
429fa9e4066Sahrens 		(void) snprintf(buf, buflen, "%llu%c", n, u);
4305c709891Seschrock 	} else {
4315c709891Seschrock 		/*
4325c709891Seschrock 		 * We want to choose a precision that reflects the best choice
4335c709891Seschrock 		 * for fitting in 5 characters.  This can get rather tricky when
4345c709891Seschrock 		 * we have numbers that are very close to an order of magnitude.
4355c709891Seschrock 		 * For example, when displaying 10239 (which is really 9.999K),
4365c709891Seschrock 		 * we want only a single place of precision for 10.0K.  We could
4375c709891Seschrock 		 * develop some complex heuristics for this, but it's much
4385c709891Seschrock 		 * easier just to try each combination in turn.
4395c709891Seschrock 		 */
4405c709891Seschrock 		int i;
4415c709891Seschrock 		for (i = 2; i >= 0; i--) {
4425c709891Seschrock 			(void) snprintf(buf, buflen, "%.*f%c", i,
4435c709891Seschrock 			    (double)num / (1ULL << 10 * index), u);
4445c709891Seschrock 			if (strlen(buf) <= 5)
4455c709891Seschrock 				break;
4465c709891Seschrock 		}
4475c709891Seschrock 	}
448fa9e4066Sahrens }
44999653d4eSeschrock 
45099653d4eSeschrock void
45199653d4eSeschrock libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr)
45299653d4eSeschrock {
45399653d4eSeschrock 	hdl->libzfs_printerr = printerr;
45499653d4eSeschrock }
45599653d4eSeschrock 
45699653d4eSeschrock libzfs_handle_t *
45799653d4eSeschrock libzfs_init(void)
45899653d4eSeschrock {
45999653d4eSeschrock 	libzfs_handle_t *hdl;
46099653d4eSeschrock 
46199653d4eSeschrock 	if ((hdl = calloc(sizeof (libzfs_handle_t), 1)) == NULL) {
46299653d4eSeschrock 		return (NULL);
46399653d4eSeschrock 	}
46499653d4eSeschrock 
465c08432ebSeschrock 	if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
46699653d4eSeschrock 		free(hdl);
46799653d4eSeschrock 		return (NULL);
46899653d4eSeschrock 	}
46999653d4eSeschrock 
47099653d4eSeschrock 	if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
47199653d4eSeschrock 		(void) close(hdl->libzfs_fd);
47299653d4eSeschrock 		free(hdl);
47399653d4eSeschrock 		return (NULL);
47499653d4eSeschrock 	}
47599653d4eSeschrock 
47699653d4eSeschrock 	hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r");
47799653d4eSeschrock 
47899653d4eSeschrock 	return (hdl);
47999653d4eSeschrock }
48099653d4eSeschrock 
48199653d4eSeschrock void
48299653d4eSeschrock libzfs_fini(libzfs_handle_t *hdl)
48399653d4eSeschrock {
48499653d4eSeschrock 	(void) close(hdl->libzfs_fd);
48599653d4eSeschrock 	if (hdl->libzfs_mnttab)
48699653d4eSeschrock 		(void) fclose(hdl->libzfs_mnttab);
48799653d4eSeschrock 	if (hdl->libzfs_sharetab)
48899653d4eSeschrock 		(void) fclose(hdl->libzfs_sharetab);
48999653d4eSeschrock 	namespace_clear(hdl);
49099653d4eSeschrock 	free(hdl);
49199653d4eSeschrock }
49299653d4eSeschrock 
49399653d4eSeschrock libzfs_handle_t *
49499653d4eSeschrock zpool_get_handle(zpool_handle_t *zhp)
49599653d4eSeschrock {
49699653d4eSeschrock 	return (zhp->zpool_hdl);
49799653d4eSeschrock }
49899653d4eSeschrock 
49999653d4eSeschrock libzfs_handle_t *
50099653d4eSeschrock zfs_get_handle(zfs_handle_t *zhp)
50199653d4eSeschrock {
50299653d4eSeschrock 	return (zhp->zfs_hdl);
50399653d4eSeschrock }
504e9dbad6fSeschrock 
505e9dbad6fSeschrock /*
506e9dbad6fSeschrock  * Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from
507e9dbad6fSeschrock  * an ioctl().
508e9dbad6fSeschrock  */
509e9dbad6fSeschrock int
510e9dbad6fSeschrock zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len)
511e9dbad6fSeschrock {
512e9dbad6fSeschrock 	if (len == 0)
513a2eea2e1Sahrens 		len = 2048;
514e9dbad6fSeschrock 	zc->zc_nvlist_dst_size = len;
515e9dbad6fSeschrock 	if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
516e9dbad6fSeschrock 	    zfs_alloc(hdl, zc->zc_nvlist_dst_size)) == NULL)
517e9dbad6fSeschrock 		return (-1);
518e9dbad6fSeschrock 
519e9dbad6fSeschrock 	return (0);
520e9dbad6fSeschrock }
521e9dbad6fSeschrock 
522e9dbad6fSeschrock /*
523e9dbad6fSeschrock  * Called when an ioctl() which returns an nvlist fails with ENOMEM.  This will
524e9dbad6fSeschrock  * expand the nvlist to the size specified in 'zc_nvlist_dst_size', which was
525e9dbad6fSeschrock  * filled in by the kernel to indicate the actual required size.
526e9dbad6fSeschrock  */
527e9dbad6fSeschrock int
528e9dbad6fSeschrock zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
529e9dbad6fSeschrock {
530e9dbad6fSeschrock 	free((void *)(uintptr_t)zc->zc_nvlist_dst);
531e9dbad6fSeschrock 	if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
532e9dbad6fSeschrock 	    zfs_alloc(hdl, zc->zc_nvlist_dst_size))
533e9dbad6fSeschrock 	    == NULL)
534e9dbad6fSeschrock 		return (-1);
535e9dbad6fSeschrock 
536e9dbad6fSeschrock 	return (0);
537e9dbad6fSeschrock }
538e9dbad6fSeschrock 
539e9dbad6fSeschrock /*
540a2eea2e1Sahrens  * Called to free the src and dst nvlists stored in the command structure.
541e9dbad6fSeschrock  */
542e9dbad6fSeschrock void
543e9dbad6fSeschrock zcmd_free_nvlists(zfs_cmd_t *zc)
544e9dbad6fSeschrock {
545e9dbad6fSeschrock 	free((void *)(uintptr_t)zc->zc_nvlist_src);
546e9dbad6fSeschrock 	free((void *)(uintptr_t)zc->zc_nvlist_dst);
547e9dbad6fSeschrock }
548e9dbad6fSeschrock 
549e9dbad6fSeschrock int
550e9dbad6fSeschrock zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl,
551e9dbad6fSeschrock     size_t *size)
552e9dbad6fSeschrock {
553e9dbad6fSeschrock 	char *packed;
554e9dbad6fSeschrock 	size_t len;
555e9dbad6fSeschrock 
556e9dbad6fSeschrock 	verify(nvlist_size(nvl, &len, NV_ENCODE_NATIVE) == 0);
557e9dbad6fSeschrock 
558e9dbad6fSeschrock 	if ((packed = zfs_alloc(hdl, len)) == NULL)
559e9dbad6fSeschrock 		return (-1);
560e9dbad6fSeschrock 
561e9dbad6fSeschrock 	verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
562e9dbad6fSeschrock 
563e9dbad6fSeschrock 	zc->zc_nvlist_src = (uint64_t)(uintptr_t)packed;
564e9dbad6fSeschrock 	zc->zc_nvlist_src_size = len;
565e9dbad6fSeschrock 
566e9dbad6fSeschrock 	if (size)
567e9dbad6fSeschrock 		*size = len;
568e9dbad6fSeschrock 	return (0);
569e9dbad6fSeschrock }
570e9dbad6fSeschrock 
571e9dbad6fSeschrock /*
572e9dbad6fSeschrock  * Unpacks an nvlist from the ZFS ioctl command structure.
573e9dbad6fSeschrock  */
574e9dbad6fSeschrock int
575e9dbad6fSeschrock zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
576e9dbad6fSeschrock {
577e9dbad6fSeschrock 	if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
578e9dbad6fSeschrock 	    zc->zc_nvlist_dst_size, nvlp, 0) != 0)
579e9dbad6fSeschrock 		return (no_memory(hdl));
580e9dbad6fSeschrock 
581e9dbad6fSeschrock 	return (0);
582e9dbad6fSeschrock }
583