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. 27zfs.util.dev -- a file object of /dev/zfs """ 28 29import gettext 30import errno 31import os 32# Note: this module (zfs.util) should not import zfs.ioctl, because that 33# would introduce a circular dependency 34 35errno.ECANCELED = 47 36errno.ENOTSUP = 48 37 38dev = open("/dev/zfs", "w") 39 40_ = gettext.translation("SUNW_OST_OSLIB", "/usr/lib/locale", 41 fallback=True).gettext 42 43def 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 54class 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 111def 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 135def 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 139