1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
5789Sahrens  * Common Development and Distribution License, Version 1.0 only
6789Sahrens  * (the "License").  You may not use this file except in compliance
7789Sahrens  * with the License.
8789Sahrens  *
9789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10789Sahrens  * or http://www.opensolaris.org/os/licensing.
11789Sahrens  * See the License for the specific language governing permissions
12789Sahrens  * and limitations under the License.
13789Sahrens  *
14789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
15789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
17789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
18789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
19789Sahrens  *
20789Sahrens  * CDDL HEADER END
21789Sahrens  */
22789Sahrens /*
23789Sahrens  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24789Sahrens  * Use is subject to license terms.
25789Sahrens  */
26789Sahrens 
27789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28789Sahrens 
29789Sahrens /*
30789Sahrens  * Internal utility routines for the ZFS library.
31789Sahrens  */
32789Sahrens 
33789Sahrens #include <errno.h>
34789Sahrens #include <fcntl.h>
35789Sahrens #include <libintl.h>
36789Sahrens #include <stdarg.h>
37789Sahrens #include <stdio.h>
38789Sahrens #include <stdlib.h>
39789Sahrens #include <strings.h>
40789Sahrens #include <unistd.h>
41789Sahrens #include <sys/mnttab.h>
42789Sahrens 
43789Sahrens #include <libzfs.h>
44789Sahrens 
45789Sahrens #include "libzfs_impl.h"
46789Sahrens 
47789Sahrens int zfs_fd;
48789Sahrens 
49789Sahrens void (*error_func)(const char *, va_list);
50789Sahrens 
51789Sahrens /*
52789Sahrens  * All error handling is kept within libzfs where we have the most information
53789Sahrens  * immediately available.  While this may not be suitable for a general purpose
54789Sahrens  * library, it greatly simplifies our commands.  This command name is used to
55789Sahrens  * prefix all error messages appropriately.
56789Sahrens  */
57789Sahrens void
58789Sahrens zfs_error(const char *fmt, ...)
59789Sahrens {
60789Sahrens 	va_list ap;
61789Sahrens 
62789Sahrens 	va_start(ap, fmt);
63789Sahrens 
64789Sahrens 	if (error_func != NULL) {
65789Sahrens 		error_func(fmt, ap);
66789Sahrens 	} else {
67789Sahrens 		(void) vfprintf(stderr, fmt, ap);
68789Sahrens 		(void) fprintf(stderr, "\n");
69789Sahrens 	}
70789Sahrens 
71789Sahrens 	va_end(ap);
72789Sahrens }
73789Sahrens 
74789Sahrens /*
75789Sahrens  * An internal error is something that we cannot recover from, and should never
76789Sahrens  * happen (such as running out of memory).  It should only be used in
77789Sahrens  * exceptional circumstances.
78789Sahrens  */
79789Sahrens void
80789Sahrens zfs_fatal(const char *fmt, ...)
81789Sahrens {
82789Sahrens 	va_list ap;
83789Sahrens 
84789Sahrens 	va_start(ap, fmt);
85789Sahrens 
86789Sahrens 	if (error_func != NULL) {
87789Sahrens 		error_func(fmt, ap);
88789Sahrens 	} else {
89789Sahrens 		(void) vfprintf(stderr, fmt, ap);
90789Sahrens 		(void) fprintf(stderr, "\n");
91789Sahrens 	}
92789Sahrens 
93789Sahrens 	va_end(ap);
94789Sahrens 
95789Sahrens 	exit(1);
96789Sahrens }
97789Sahrens 
98789Sahrens /*
99789Sahrens  * Consumers (such as the JNI interface) that need to capture error output can
100789Sahrens  * override the default error handler using this function.
101789Sahrens  */
102789Sahrens void
103789Sahrens zfs_set_error_handler(void (*func)(const char *, va_list))
104789Sahrens {
105789Sahrens 	error_func = func;
106789Sahrens }
107789Sahrens 
108789Sahrens /*
109789Sahrens  * Display an out of memory error message and abort the current program.
110789Sahrens  */
111789Sahrens void
112789Sahrens no_memory(void)
113789Sahrens {
114789Sahrens 	assert(errno == ENOMEM);
115789Sahrens 	zfs_fatal(dgettext(TEXT_DOMAIN, "internal error: out of memory\n"));
116789Sahrens }
117789Sahrens 
118789Sahrens /*
119789Sahrens  * A safe form of malloc() which will die if the allocation fails.
120789Sahrens  */
121789Sahrens void *
122789Sahrens zfs_malloc(size_t size)
123789Sahrens {
124789Sahrens 	void *data;
125789Sahrens 
126789Sahrens 	if ((data = calloc(1, size)) == NULL)
127789Sahrens 		no_memory();
128789Sahrens 
129789Sahrens 	return (data);
130789Sahrens }
131789Sahrens 
132789Sahrens /*
133789Sahrens  * A safe form of strdup() which will die if the allocation fails.
134789Sahrens  */
135789Sahrens char *
136789Sahrens zfs_strdup(const char *str)
137789Sahrens {
138789Sahrens 	char *ret;
139789Sahrens 
140789Sahrens 	if ((ret = strdup(str)) == NULL)
141789Sahrens 		no_memory();
142789Sahrens 
143789Sahrens 	return (ret);
144789Sahrens }
145789Sahrens 
146789Sahrens /*
147789Sahrens  * Initialize the library.  Sets the command name used when reporting errors.
148789Sahrens  * This command name is used to prefix all error messages appropriately.
149789Sahrens  * Also opens /dev/zfs and dies if it cannot be opened.
150789Sahrens  */
151789Sahrens #pragma init(zfs_init)
152789Sahrens void
153789Sahrens zfs_init(void)
154789Sahrens {
155789Sahrens 	if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0)
156789Sahrens 		zfs_fatal(dgettext(TEXT_DOMAIN,
157789Sahrens 		    "internal error: cannot open zfs device"));
158789Sahrens 
159789Sahrens 	if ((mnttab_file = fopen(MNTTAB, "r")) == NULL)
160789Sahrens 		zfs_fatal(dgettext(TEXT_DOMAIN, "internal error: unable to "
161789Sahrens 		    "open %s\n"), MNTTAB);
162789Sahrens 
163789Sahrens 	sharetab_file = fopen("/etc/dfs/sharetab", "r");
164789Sahrens }
165789Sahrens 
166789Sahrens /*
167789Sahrens  * Cleanup function for library.  Simply close the file descriptors that we
168789Sahrens  * opened as part of libzfs_init().
169789Sahrens  */
170789Sahrens #pragma fini(zfs_fini)
171789Sahrens void
172789Sahrens zfs_fini(void)
173789Sahrens {
174789Sahrens 	(void) close(zfs_fd);
175789Sahrens }
176789Sahrens 
177789Sahrens /*
178789Sahrens  * Convert a number to an appropriately human-readable output.
179789Sahrens  */
180789Sahrens void
181789Sahrens zfs_nicenum(uint64_t num, char *buf, size_t buflen)
182789Sahrens {
183789Sahrens 	uint64_t n = num;
184789Sahrens 	int index = 0;
185789Sahrens 	char u;
186789Sahrens 
187789Sahrens 	while (n >= 1024) {
188*1162Seschrock 		n /= 1024;
189789Sahrens 		index++;
190789Sahrens 	}
191789Sahrens 
192789Sahrens 	u = " KMGTPE"[index];
193789Sahrens 
194*1162Seschrock 	if (index == 0) {
195789Sahrens 		(void) snprintf(buf, buflen, "%llu", n);
196*1162Seschrock 	} else if ((num & ((1ULL << 10 * index) - 1)) == 0) {
197*1162Seschrock 		/*
198*1162Seschrock 		 * If this is an even multiple of the base, always display
199*1162Seschrock 		 * without any decimal precision.
200*1162Seschrock 		 */
201789Sahrens 		(void) snprintf(buf, buflen, "%llu%c", n, u);
202*1162Seschrock 	} else {
203*1162Seschrock 		/*
204*1162Seschrock 		 * We want to choose a precision that reflects the best choice
205*1162Seschrock 		 * for fitting in 5 characters.  This can get rather tricky when
206*1162Seschrock 		 * we have numbers that are very close to an order of magnitude.
207*1162Seschrock 		 * For example, when displaying 10239 (which is really 9.999K),
208*1162Seschrock 		 * we want only a single place of precision for 10.0K.  We could
209*1162Seschrock 		 * develop some complex heuristics for this, but it's much
210*1162Seschrock 		 * easier just to try each combination in turn.
211*1162Seschrock 		 */
212*1162Seschrock 		int i;
213*1162Seschrock 		for (i = 2; i >= 0; i--) {
214*1162Seschrock 			(void) snprintf(buf, buflen, "%.*f%c", i,
215*1162Seschrock 			    (double)num / (1ULL << 10 * index), u);
216*1162Seschrock 			if (strlen(buf) <= 5)
217*1162Seschrock 				break;
218*1162Seschrock 		}
219*1162Seschrock 	}
220789Sahrens }
221