1*14843421SMatthew Ahrens#! /usr/bin/python2.4 2*14843421SMatthew Ahrens# 3*14843421SMatthew Ahrens# CDDL HEADER START 4*14843421SMatthew Ahrens# 5*14843421SMatthew Ahrens# The contents of this file are subject to the terms of the 6*14843421SMatthew Ahrens# Common Development and Distribution License (the "License"). 7*14843421SMatthew Ahrens# You may not use this file except in compliance with the License. 8*14843421SMatthew Ahrens# 9*14843421SMatthew Ahrens# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*14843421SMatthew Ahrens# or http://www.opensolaris.org/os/licensing. 11*14843421SMatthew Ahrens# See the License for the specific language governing permissions 12*14843421SMatthew Ahrens# and limitations under the License. 13*14843421SMatthew Ahrens# 14*14843421SMatthew Ahrens# When distributing Covered Code, include this CDDL HEADER in each 15*14843421SMatthew Ahrens# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*14843421SMatthew Ahrens# If applicable, add the following below this CDDL HEADER, with the 17*14843421SMatthew Ahrens# fields enclosed by brackets "[]" replaced with your own identifying 18*14843421SMatthew Ahrens# information: Portions Copyright [yyyy] [name of copyright owner] 19*14843421SMatthew Ahrens# 20*14843421SMatthew Ahrens# CDDL HEADER END 21*14843421SMatthew Ahrens# 22*14843421SMatthew Ahrens# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*14843421SMatthew Ahrens# Use is subject to license terms. 24*14843421SMatthew Ahrens# 25*14843421SMatthew Ahrens 26*14843421SMatthew Ahrens"""This module provides utility functions for ZFS. 27*14843421SMatthew Ahrenszfs.util.dev -- a file object of /dev/zfs """ 28*14843421SMatthew Ahrens 29*14843421SMatthew Ahrensimport gettext 30*14843421SMatthew Ahrensimport errno 31*14843421SMatthew Ahrensimport os 32*14843421SMatthew Ahrens# Note: this module (zfs.util) should not import zfs.ioctl, because that 33*14843421SMatthew Ahrens# would introduce a circular dependency 34*14843421SMatthew Ahrens 35*14843421SMatthew Ahrenserrno.ECANCELED = 47 36*14843421SMatthew Ahrenserrno.ENOTSUP = 48 37*14843421SMatthew Ahrens 38*14843421SMatthew Ahrensdev = open("/dev/zfs", "w") 39*14843421SMatthew Ahrens 40*14843421SMatthew Ahrens_ = gettext.translation("SUNW_OST_OSLIB", "/usr/lib/locale", 41*14843421SMatthew Ahrens fallback=True).gettext 42*14843421SMatthew Ahrens 43*14843421SMatthew Ahrensdef default_repr(self): 44*14843421SMatthew Ahrens """A simple __repr__ function.""" 45*14843421SMatthew Ahrens if self.__slots__: 46*14843421SMatthew Ahrens str = "<" + self.__class__.__name__ 47*14843421SMatthew Ahrens for v in self.__slots__: 48*14843421SMatthew Ahrens str += " %s: %r" % (v, getattr(self, v)) 49*14843421SMatthew Ahrens return str + ">" 50*14843421SMatthew Ahrens else: 51*14843421SMatthew Ahrens return "<%s %s>" % \ 52*14843421SMatthew Ahrens (self.__class__.__name__, repr(self.__dict__)) 53*14843421SMatthew Ahrens 54*14843421SMatthew Ahrensclass ZFSError(StandardError): 55*14843421SMatthew Ahrens """This exception class represents a potentially user-visible 56*14843421SMatthew Ahrens ZFS error. If uncaught, it will be printed and the process will 57*14843421SMatthew Ahrens exit with exit code 1. 58*14843421SMatthew Ahrens 59*14843421SMatthew Ahrens errno -- the error number (eg, from ioctl(2)).""" 60*14843421SMatthew Ahrens 61*14843421SMatthew Ahrens __slots__ = "why", "task", "errno" 62*14843421SMatthew Ahrens __repr__ = default_repr 63*14843421SMatthew Ahrens 64*14843421SMatthew Ahrens def __init__(self, eno, task=None, why=None): 65*14843421SMatthew Ahrens """Create a ZFS exception. 66*14843421SMatthew Ahrens eno -- the error number (errno) 67*14843421SMatthew Ahrens task -- a string describing the task that failed 68*14843421SMatthew Ahrens why -- a string describing why it failed (defaults to 69*14843421SMatthew Ahrens strerror(eno))""" 70*14843421SMatthew Ahrens 71*14843421SMatthew Ahrens self.errno = eno 72*14843421SMatthew Ahrens self.task = task 73*14843421SMatthew Ahrens self.why = why 74*14843421SMatthew Ahrens 75*14843421SMatthew Ahrens def __str__(self): 76*14843421SMatthew Ahrens s = "" 77*14843421SMatthew Ahrens if self.task: 78*14843421SMatthew Ahrens s += self.task + ": " 79*14843421SMatthew Ahrens if self.why: 80*14843421SMatthew Ahrens s += self.why 81*14843421SMatthew Ahrens else: 82*14843421SMatthew Ahrens s += self.strerror 83*14843421SMatthew Ahrens return s 84*14843421SMatthew Ahrens 85*14843421SMatthew Ahrens __strs = { 86*14843421SMatthew Ahrens errno.EPERM: _("permission denied"), 87*14843421SMatthew Ahrens errno.ECANCELED: 88*14843421SMatthew Ahrens _("delegated administration is disabled on pool"), 89*14843421SMatthew Ahrens errno.EINTR: _("signal received"), 90*14843421SMatthew Ahrens errno.EIO: _("I/O error"), 91*14843421SMatthew Ahrens errno.ENOENT: _("dataset does not exist"), 92*14843421SMatthew Ahrens errno.ENOSPC: _("out of space"), 93*14843421SMatthew Ahrens errno.EEXIST: _("dataset already exists"), 94*14843421SMatthew Ahrens errno.EBUSY: _("dataset is busy"), 95*14843421SMatthew Ahrens errno.EROFS: 96*14843421SMatthew Ahrens _("snapshot permissions cannot be modified"), 97*14843421SMatthew Ahrens errno.ENAMETOOLONG: _("dataset name is too long"), 98*14843421SMatthew Ahrens errno.ENOTSUP: _("unsupported version"), 99*14843421SMatthew Ahrens errno.EAGAIN: _("pool I/O is currently suspended"), 100*14843421SMatthew Ahrens } 101*14843421SMatthew Ahrens 102*14843421SMatthew Ahrens __strs[errno.EACCES] = __strs[errno.EPERM] 103*14843421SMatthew Ahrens __strs[errno.ENXIO] = __strs[errno.EIO] 104*14843421SMatthew Ahrens __strs[errno.ENODEV] = __strs[errno.EIO] 105*14843421SMatthew Ahrens __strs[errno.EDQUOT] = __strs[errno.ENOSPC] 106*14843421SMatthew Ahrens 107*14843421SMatthew Ahrens @property 108*14843421SMatthew Ahrens def strerror(self): 109*14843421SMatthew Ahrens return ZFSError.__strs.get(self.errno, os.strerror(self.errno)) 110*14843421SMatthew Ahrens 111*14843421SMatthew Ahrensdef nicenum(num): 112*14843421SMatthew Ahrens """Return a nice string (eg "1.23M") for this integer.""" 113*14843421SMatthew Ahrens index = 0; 114*14843421SMatthew Ahrens n = num; 115*14843421SMatthew Ahrens 116*14843421SMatthew Ahrens while n >= 1024: 117*14843421SMatthew Ahrens n /= 1024 118*14843421SMatthew Ahrens index += 1 119*14843421SMatthew Ahrens 120*14843421SMatthew Ahrens u = " KMGTPE"[index] 121*14843421SMatthew Ahrens if index == 0: 122*14843421SMatthew Ahrens return "%u" % n; 123*14843421SMatthew Ahrens elif n >= 100 or num & ((1024*index)-1) == 0: 124*14843421SMatthew Ahrens # it's an exact multiple of its index, or it wouldn't 125*14843421SMatthew Ahrens # fit as floating point, so print as an integer 126*14843421SMatthew Ahrens return "%u%c" % (n, u) 127*14843421SMatthew Ahrens else: 128*14843421SMatthew Ahrens # due to rounding, it's tricky to tell what precision to 129*14843421SMatthew Ahrens # use; try each precision and see which one fits 130*14843421SMatthew Ahrens for i in (2, 1, 0): 131*14843421SMatthew Ahrens s = "%.*f%c" % (i, float(num) / (1<<(10*index)), u) 132*14843421SMatthew Ahrens if len(s) <= 5: 133*14843421SMatthew Ahrens return s 134*14843421SMatthew Ahrens 135*14843421SMatthew Ahrensdef append_with_opt(option, opt, value, parser): 136*14843421SMatthew Ahrens """A function for OptionParser which appends a tuple (opt, value).""" 137*14843421SMatthew Ahrens getattr(parser.values, option.dest).append((opt, value)) 138*14843421SMatthew Ahrens 139