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