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 2010 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 32import solaris.misc 33# Note: this module (zfs.util) should not import zfs.ioctl, because that 34# would introduce a circular dependency 35 36errno.ECANCELED = 47 37errno.ENOTSUP = 48 38 39dev = open("/dev/zfs", "w") 40 41try: 42 _ = gettext.translation("SUNW_OST_OSLIB", "/usr/lib/locale", 43 fallback=True).gettext 44except: 45 _ = solaris.misc.gettext 46 47def default_repr(self): 48 """A simple __repr__ function.""" 49 if self.__slots__: 50 str = "<" + self.__class__.__name__ 51 for v in self.__slots__: 52 str += " %s: %r" % (v, getattr(self, v)) 53 return str + ">" 54 else: 55 return "<%s %s>" % \ 56 (self.__class__.__name__, repr(self.__dict__)) 57 58class ZFSError(StandardError): 59 """This exception class represents a potentially user-visible 60 ZFS error. If uncaught, it will be printed and the process will 61 exit with exit code 1. 62 63 errno -- the error number (eg, from ioctl(2)).""" 64 65 __slots__ = "why", "task", "errno" 66 __repr__ = default_repr 67 68 def __init__(self, eno, task=None, why=None): 69 """Create a ZFS exception. 70 eno -- the error number (errno) 71 task -- a string describing the task that failed 72 why -- a string describing why it failed (defaults to 73 strerror(eno))""" 74 75 self.errno = eno 76 self.task = task 77 self.why = why 78 79 def __str__(self): 80 s = "" 81 if self.task: 82 s += self.task + ": " 83 if self.why: 84 s += self.why 85 else: 86 s += self.strerror 87 return s 88 89 __strs = { 90 errno.EPERM: _("permission denied"), 91 errno.ECANCELED: 92 _("delegated administration is disabled on pool"), 93 errno.EINTR: _("signal received"), 94 errno.EIO: _("I/O error"), 95 errno.ENOENT: _("dataset does not exist"), 96 errno.ENOSPC: _("out of space"), 97 errno.EEXIST: _("dataset already exists"), 98 errno.EBUSY: _("dataset is busy"), 99 errno.EROFS: 100 _("snapshot permissions cannot be modified"), 101 errno.ENAMETOOLONG: _("dataset name is too long"), 102 errno.ENOTSUP: _("unsupported version"), 103 errno.EAGAIN: _("pool I/O is currently suspended"), 104 } 105 106 __strs[errno.EACCES] = __strs[errno.EPERM] 107 __strs[errno.ENXIO] = __strs[errno.EIO] 108 __strs[errno.ENODEV] = __strs[errno.EIO] 109 __strs[errno.EDQUOT] = __strs[errno.ENOSPC] 110 111 @property 112 def strerror(self): 113 return ZFSError.__strs.get(self.errno, os.strerror(self.errno)) 114 115def nicenum(num): 116 """Return a nice string (eg "1.23M") for this integer.""" 117 index = 0; 118 n = num; 119 120 while n >= 1024: 121 n /= 1024 122 index += 1 123 124 u = " KMGTPE"[index] 125 if index == 0: 126 return "%u" % n; 127 elif n >= 100 or num & ((1024*index)-1) == 0: 128 # it's an exact multiple of its index, or it wouldn't 129 # fit as floating point, so print as an integer 130 return "%u%c" % (n, u) 131 else: 132 # due to rounding, it's tricky to tell what precision to 133 # use; try each precision and see which one fits 134 for i in (2, 1, 0): 135 s = "%.*f%c" % (i, float(num) / (1<<(10*index)), u) 136 if len(s) <= 5: 137 return s 138 139def append_with_opt(option, opt, value, parser): 140 """A function for OptionParser which appends a tuple (opt, value).""" 141 getattr(parser.values, option.dest).append((opt, value)) 142 143