1*789Sahrens /* 2*789Sahrens * CDDL HEADER START 3*789Sahrens * 4*789Sahrens * The contents of this file are subject to the terms of the 5*789Sahrens * Common Development and Distribution License, Version 1.0 only 6*789Sahrens * (the "License"). You may not use this file except in compliance 7*789Sahrens * with the License. 8*789Sahrens * 9*789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*789Sahrens * or http://www.opensolaris.org/os/licensing. 11*789Sahrens * See the License for the specific language governing permissions 12*789Sahrens * and limitations under the License. 13*789Sahrens * 14*789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 15*789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*789Sahrens * If applicable, add the following below this CDDL HEADER, with the 17*789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 18*789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 19*789Sahrens * 20*789Sahrens * CDDL HEADER END 21*789Sahrens */ 22*789Sahrens /* 23*789Sahrens * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*789Sahrens * Use is subject to license terms. 25*789Sahrens */ 26*789Sahrens 27*789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 28*789Sahrens 29*789Sahrens /* 30*789Sahrens * Internal utility routines for the ZFS library. 31*789Sahrens */ 32*789Sahrens 33*789Sahrens #include <errno.h> 34*789Sahrens #include <fcntl.h> 35*789Sahrens #include <libintl.h> 36*789Sahrens #include <stdarg.h> 37*789Sahrens #include <stdio.h> 38*789Sahrens #include <stdlib.h> 39*789Sahrens #include <strings.h> 40*789Sahrens #include <unistd.h> 41*789Sahrens #include <sys/mnttab.h> 42*789Sahrens 43*789Sahrens #include <libzfs.h> 44*789Sahrens 45*789Sahrens #include "libzfs_impl.h" 46*789Sahrens 47*789Sahrens int zfs_fd; 48*789Sahrens 49*789Sahrens void (*error_func)(const char *, va_list); 50*789Sahrens 51*789Sahrens /* 52*789Sahrens * All error handling is kept within libzfs where we have the most information 53*789Sahrens * immediately available. While this may not be suitable for a general purpose 54*789Sahrens * library, it greatly simplifies our commands. This command name is used to 55*789Sahrens * prefix all error messages appropriately. 56*789Sahrens */ 57*789Sahrens void 58*789Sahrens zfs_error(const char *fmt, ...) 59*789Sahrens { 60*789Sahrens va_list ap; 61*789Sahrens 62*789Sahrens va_start(ap, fmt); 63*789Sahrens 64*789Sahrens if (error_func != NULL) { 65*789Sahrens error_func(fmt, ap); 66*789Sahrens } else { 67*789Sahrens (void) vfprintf(stderr, fmt, ap); 68*789Sahrens (void) fprintf(stderr, "\n"); 69*789Sahrens } 70*789Sahrens 71*789Sahrens va_end(ap); 72*789Sahrens } 73*789Sahrens 74*789Sahrens /* 75*789Sahrens * An internal error is something that we cannot recover from, and should never 76*789Sahrens * happen (such as running out of memory). It should only be used in 77*789Sahrens * exceptional circumstances. 78*789Sahrens */ 79*789Sahrens void 80*789Sahrens zfs_fatal(const char *fmt, ...) 81*789Sahrens { 82*789Sahrens va_list ap; 83*789Sahrens 84*789Sahrens va_start(ap, fmt); 85*789Sahrens 86*789Sahrens if (error_func != NULL) { 87*789Sahrens error_func(fmt, ap); 88*789Sahrens } else { 89*789Sahrens (void) vfprintf(stderr, fmt, ap); 90*789Sahrens (void) fprintf(stderr, "\n"); 91*789Sahrens } 92*789Sahrens 93*789Sahrens va_end(ap); 94*789Sahrens 95*789Sahrens exit(1); 96*789Sahrens } 97*789Sahrens 98*789Sahrens /* 99*789Sahrens * Consumers (such as the JNI interface) that need to capture error output can 100*789Sahrens * override the default error handler using this function. 101*789Sahrens */ 102*789Sahrens void 103*789Sahrens zfs_set_error_handler(void (*func)(const char *, va_list)) 104*789Sahrens { 105*789Sahrens error_func = func; 106*789Sahrens } 107*789Sahrens 108*789Sahrens /* 109*789Sahrens * Display an out of memory error message and abort the current program. 110*789Sahrens */ 111*789Sahrens void 112*789Sahrens no_memory(void) 113*789Sahrens { 114*789Sahrens assert(errno == ENOMEM); 115*789Sahrens zfs_fatal(dgettext(TEXT_DOMAIN, "internal error: out of memory\n")); 116*789Sahrens } 117*789Sahrens 118*789Sahrens /* 119*789Sahrens * A safe form of malloc() which will die if the allocation fails. 120*789Sahrens */ 121*789Sahrens void * 122*789Sahrens zfs_malloc(size_t size) 123*789Sahrens { 124*789Sahrens void *data; 125*789Sahrens 126*789Sahrens if ((data = calloc(1, size)) == NULL) 127*789Sahrens no_memory(); 128*789Sahrens 129*789Sahrens return (data); 130*789Sahrens } 131*789Sahrens 132*789Sahrens /* 133*789Sahrens * A safe form of strdup() which will die if the allocation fails. 134*789Sahrens */ 135*789Sahrens char * 136*789Sahrens zfs_strdup(const char *str) 137*789Sahrens { 138*789Sahrens char *ret; 139*789Sahrens 140*789Sahrens if ((ret = strdup(str)) == NULL) 141*789Sahrens no_memory(); 142*789Sahrens 143*789Sahrens return (ret); 144*789Sahrens } 145*789Sahrens 146*789Sahrens /* 147*789Sahrens * Initialize the library. Sets the command name used when reporting errors. 148*789Sahrens * This command name is used to prefix all error messages appropriately. 149*789Sahrens * Also opens /dev/zfs and dies if it cannot be opened. 150*789Sahrens */ 151*789Sahrens #pragma init(zfs_init) 152*789Sahrens void 153*789Sahrens zfs_init(void) 154*789Sahrens { 155*789Sahrens if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) 156*789Sahrens zfs_fatal(dgettext(TEXT_DOMAIN, 157*789Sahrens "internal error: cannot open zfs device")); 158*789Sahrens 159*789Sahrens if ((mnttab_file = fopen(MNTTAB, "r")) == NULL) 160*789Sahrens zfs_fatal(dgettext(TEXT_DOMAIN, "internal error: unable to " 161*789Sahrens "open %s\n"), MNTTAB); 162*789Sahrens 163*789Sahrens sharetab_file = fopen("/etc/dfs/sharetab", "r"); 164*789Sahrens } 165*789Sahrens 166*789Sahrens /* 167*789Sahrens * Cleanup function for library. Simply close the file descriptors that we 168*789Sahrens * opened as part of libzfs_init(). 169*789Sahrens */ 170*789Sahrens #pragma fini(zfs_fini) 171*789Sahrens void 172*789Sahrens zfs_fini(void) 173*789Sahrens { 174*789Sahrens (void) close(zfs_fd); 175*789Sahrens } 176*789Sahrens 177*789Sahrens /* 178*789Sahrens * Convert a number to an appropriately human-readable output. 179*789Sahrens */ 180*789Sahrens void 181*789Sahrens zfs_nicenum(uint64_t num, char *buf, size_t buflen) 182*789Sahrens { 183*789Sahrens uint64_t n = num; 184*789Sahrens int index = 0; 185*789Sahrens char u; 186*789Sahrens 187*789Sahrens while (n >= 1024) { 188*789Sahrens n = (n + (1024 / 2)) / 1024; /* Round up or down */ 189*789Sahrens index++; 190*789Sahrens } 191*789Sahrens 192*789Sahrens u = " KMGTPE"[index]; 193*789Sahrens 194*789Sahrens if (index == 0) 195*789Sahrens (void) snprintf(buf, buflen, "%llu", n); 196*789Sahrens else if (n < 10 && (num & (num - 1)) != 0) 197*789Sahrens (void) snprintf(buf, buflen, "%.2f%c", 198*789Sahrens (double)num / (1ULL << 10 * index), u); 199*789Sahrens else if (n < 100 && (num & (num - 1)) != 0) 200*789Sahrens (void) snprintf(buf, buflen, "%.1f%c", 201*789Sahrens (double)num / (1ULL << 10 * index), u); 202*789Sahrens else 203*789Sahrens (void) snprintf(buf, buflen, "%llu%c", n, u); 204*789Sahrens } 205