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