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