1*10b9d77bSPawel Jakub Dawidek#! /usr/bin/python2.6 28fc25799SMartin Matuska# 38fc25799SMartin Matuska# CDDL HEADER START 48fc25799SMartin Matuska# 58fc25799SMartin Matuska# The contents of this file are subject to the terms of the 68fc25799SMartin Matuska# Common Development and Distribution License (the "License"). 78fc25799SMartin Matuska# You may not use this file except in compliance with the License. 88fc25799SMartin Matuska# 98fc25799SMartin Matuska# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 108fc25799SMartin Matuska# or http://www.opensolaris.org/os/licensing. 118fc25799SMartin Matuska# See the License for the specific language governing permissions 128fc25799SMartin Matuska# and limitations under the License. 138fc25799SMartin Matuska# 148fc25799SMartin Matuska# When distributing Covered Code, include this CDDL HEADER in each 158fc25799SMartin Matuska# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 168fc25799SMartin Matuska# If applicable, add the following below this CDDL HEADER, with the 178fc25799SMartin Matuska# fields enclosed by brackets "[]" replaced with your own identifying 188fc25799SMartin Matuska# information: Portions Copyright [yyyy] [name of copyright owner] 198fc25799SMartin Matuska# 208fc25799SMartin Matuska# CDDL HEADER END 218fc25799SMartin Matuska# 22*10b9d77bSPawel Jakub Dawidek# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 238fc25799SMartin Matuska# 248fc25799SMartin Matuska 258fc25799SMartin Matuska"""This module provides utility functions for ZFS. 268fc25799SMartin Matuskazfs.util.dev -- a file object of /dev/zfs """ 278fc25799SMartin Matuska 288fc25799SMartin Matuskaimport gettext 298fc25799SMartin Matuskaimport errno 308fc25799SMartin Matuskaimport os 31*10b9d77bSPawel Jakub Dawidekimport solaris.misc 328fc25799SMartin Matuska# Note: this module (zfs.util) should not import zfs.ioctl, because that 338fc25799SMartin Matuska# would introduce a circular dependency 348fc25799SMartin Matuska 358fc25799SMartin Matuskaerrno.ECANCELED = 47 368fc25799SMartin Matuskaerrno.ENOTSUP = 48 378fc25799SMartin Matuska 388fc25799SMartin Matuskadev = open("/dev/zfs", "w") 398fc25799SMartin Matuska 40*10b9d77bSPawel Jakub Dawidektry: 418fc25799SMartin Matuska _ = gettext.translation("SUNW_OST_OSLIB", "/usr/lib/locale", 428fc25799SMartin Matuska fallback=True).gettext 43*10b9d77bSPawel Jakub Dawidekexcept: 44*10b9d77bSPawel Jakub Dawidek _ = solaris.misc.gettext 458fc25799SMartin Matuska 468fc25799SMartin Matuskadef default_repr(self): 478fc25799SMartin Matuska """A simple __repr__ function.""" 488fc25799SMartin Matuska if self.__slots__: 498fc25799SMartin Matuska str = "<" + self.__class__.__name__ 508fc25799SMartin Matuska for v in self.__slots__: 518fc25799SMartin Matuska str += " %s: %r" % (v, getattr(self, v)) 528fc25799SMartin Matuska return str + ">" 538fc25799SMartin Matuska else: 548fc25799SMartin Matuska return "<%s %s>" % \ 558fc25799SMartin Matuska (self.__class__.__name__, repr(self.__dict__)) 568fc25799SMartin Matuska 578fc25799SMartin Matuskaclass ZFSError(StandardError): 588fc25799SMartin Matuska """This exception class represents a potentially user-visible 598fc25799SMartin Matuska ZFS error. If uncaught, it will be printed and the process will 608fc25799SMartin Matuska exit with exit code 1. 618fc25799SMartin Matuska 628fc25799SMartin Matuska errno -- the error number (eg, from ioctl(2)).""" 638fc25799SMartin Matuska 648fc25799SMartin Matuska __slots__ = "why", "task", "errno" 658fc25799SMartin Matuska __repr__ = default_repr 668fc25799SMartin Matuska 678fc25799SMartin Matuska def __init__(self, eno, task=None, why=None): 688fc25799SMartin Matuska """Create a ZFS exception. 698fc25799SMartin Matuska eno -- the error number (errno) 708fc25799SMartin Matuska task -- a string describing the task that failed 718fc25799SMartin Matuska why -- a string describing why it failed (defaults to 728fc25799SMartin Matuska strerror(eno))""" 738fc25799SMartin Matuska 748fc25799SMartin Matuska self.errno = eno 758fc25799SMartin Matuska self.task = task 768fc25799SMartin Matuska self.why = why 778fc25799SMartin Matuska 788fc25799SMartin Matuska def __str__(self): 798fc25799SMartin Matuska s = "" 808fc25799SMartin Matuska if self.task: 818fc25799SMartin Matuska s += self.task + ": " 828fc25799SMartin Matuska if self.why: 838fc25799SMartin Matuska s += self.why 848fc25799SMartin Matuska else: 858fc25799SMartin Matuska s += self.strerror 868fc25799SMartin Matuska return s 878fc25799SMartin Matuska 888fc25799SMartin Matuska __strs = { 898fc25799SMartin Matuska errno.EPERM: _("permission denied"), 908fc25799SMartin Matuska errno.ECANCELED: 918fc25799SMartin Matuska _("delegated administration is disabled on pool"), 928fc25799SMartin Matuska errno.EINTR: _("signal received"), 938fc25799SMartin Matuska errno.EIO: _("I/O error"), 948fc25799SMartin Matuska errno.ENOENT: _("dataset does not exist"), 958fc25799SMartin Matuska errno.ENOSPC: _("out of space"), 968fc25799SMartin Matuska errno.EEXIST: _("dataset already exists"), 978fc25799SMartin Matuska errno.EBUSY: _("dataset is busy"), 988fc25799SMartin Matuska errno.EROFS: 998fc25799SMartin Matuska _("snapshot permissions cannot be modified"), 1008fc25799SMartin Matuska errno.ENAMETOOLONG: _("dataset name is too long"), 1018fc25799SMartin Matuska errno.ENOTSUP: _("unsupported version"), 1028fc25799SMartin Matuska errno.EAGAIN: _("pool I/O is currently suspended"), 1038fc25799SMartin Matuska } 1048fc25799SMartin Matuska 1058fc25799SMartin Matuska __strs[errno.EACCES] = __strs[errno.EPERM] 1068fc25799SMartin Matuska __strs[errno.ENXIO] = __strs[errno.EIO] 1078fc25799SMartin Matuska __strs[errno.ENODEV] = __strs[errno.EIO] 1088fc25799SMartin Matuska __strs[errno.EDQUOT] = __strs[errno.ENOSPC] 1098fc25799SMartin Matuska 1108fc25799SMartin Matuska @property 1118fc25799SMartin Matuska def strerror(self): 1128fc25799SMartin Matuska return ZFSError.__strs.get(self.errno, os.strerror(self.errno)) 1138fc25799SMartin Matuska 1148fc25799SMartin Matuskadef nicenum(num): 1158fc25799SMartin Matuska """Return a nice string (eg "1.23M") for this integer.""" 1168fc25799SMartin Matuska index = 0; 1178fc25799SMartin Matuska n = num; 1188fc25799SMartin Matuska 1198fc25799SMartin Matuska while n >= 1024: 1208fc25799SMartin Matuska n /= 1024 1218fc25799SMartin Matuska index += 1 1228fc25799SMartin Matuska 1238fc25799SMartin Matuska u = " KMGTPE"[index] 1248fc25799SMartin Matuska if index == 0: 1258fc25799SMartin Matuska return "%u" % n; 1268fc25799SMartin Matuska elif n >= 100 or num & ((1024*index)-1) == 0: 1278fc25799SMartin Matuska # it's an exact multiple of its index, or it wouldn't 1288fc25799SMartin Matuska # fit as floating point, so print as an integer 1298fc25799SMartin Matuska return "%u%c" % (n, u) 1308fc25799SMartin Matuska else: 1318fc25799SMartin Matuska # due to rounding, it's tricky to tell what precision to 1328fc25799SMartin Matuska # use; try each precision and see which one fits 1338fc25799SMartin Matuska for i in (2, 1, 0): 1348fc25799SMartin Matuska s = "%.*f%c" % (i, float(num) / (1<<(10*index)), u) 1358fc25799SMartin Matuska if len(s) <= 5: 1368fc25799SMartin Matuska return s 1378fc25799SMartin Matuska 1388fc25799SMartin Matuskadef append_with_opt(option, opt, value, parser): 1398fc25799SMartin Matuska """A function for OptionParser which appends a tuple (opt, value).""" 1408fc25799SMartin Matuska getattr(parser.values, option.dest).append((opt, value)) 1418fc25799SMartin Matuska 142