9f9230833b50b8271840dc2c12bd1e94d9df7d12Alexander Pyhalov#!@PYTHON@
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# CDDL HEADER START
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# The contents of this file are subject to the terms of the
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# Common Development and Distribution License (the "License").
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# You may not use this file except in compliance with the License.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# or http://www.opensolaris.org/os/licensing.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# See the License for the specific language governing permissions
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# and limitations under the License.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# When distributing Covered Code, include this CDDL HEADER in each
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# If applicable, add the following below this CDDL HEADER, with the
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# fields enclosed by brackets "[]" replaced with your own identifying
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# information: Portions Copyright [yyyy] [name of copyright owner]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# CDDL HEADER END
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
6d52f363e3b2c0c5da672c5b8c8adec99d345f38Lori Alt# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens#
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens"""This module provides utility functions for ZFS.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenszfs.util.dev -- a file object of /dev/zfs """
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensimport gettext
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensimport errno
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensimport os
e4d060fb4c00d44cd578713eb9a921f594b733b8Sam Falknerimport solaris.misc
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# Note: this module (zfs.util) should not import zfs.ioctl, because that
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens# would introduce a circular dependency
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenserrno.ECANCELED = 47
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenserrno.ENOTSUP = 48
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensdev = open("/dev/zfs", "w")
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
e4d060fb4c00d44cd578713eb9a921f594b733b8Sam Falknertry:
e4d060fb4c00d44cd578713eb9a921f594b733b8Sam Falkner _ = gettext.translation("SUNW_OST_OSLIB", "/usr/lib/locale",
e4d060fb4c00d44cd578713eb9a921f594b733b8Sam Falkner fallback=True).gettext
e4d060fb4c00d44cd578713eb9a921f594b733b8Sam Falknerexcept:
e4d060fb4c00d44cd578713eb9a921f594b733b8Sam Falkner _ = solaris.misc.gettext
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensdef default_repr(self):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens """A simple __repr__ function."""
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if self.__slots__:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens str = "<" + self.__class__.__name__
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens for v in self.__slots__:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens str += " %s: %r" % (v, getattr(self, v))
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return str + ">"
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens else:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return "<%s %s>" % \
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens (self.__class__.__name__, repr(self.__dict__))
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensclass ZFSError(StandardError):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens """This exception class represents a potentially user-visible
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens ZFS error. If uncaught, it will be printed and the process will
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens exit with exit code 1.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno -- the error number (eg, from ioctl(2))."""
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __slots__ = "why", "task", "errno"
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __repr__ = default_repr
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens def __init__(self, eno, task=None, why=None):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens """Create a ZFS exception.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens eno -- the error number (errno)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens task -- a string describing the task that failed
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens why -- a string describing why it failed (defaults to
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens strerror(eno))"""
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens self.errno = eno
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens self.task = task
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens self.why = why
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens def __str__(self):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s = ""
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if self.task:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s += self.task + ": "
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if self.why:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s += self.why
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens else:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s += self.strerror
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return s
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __strs = {
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EPERM: _("permission denied"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.ECANCELED:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens _("delegated administration is disabled on pool"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EINTR: _("signal received"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EIO: _("I/O error"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.ENOENT: _("dataset does not exist"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.ENOSPC: _("out of space"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EEXIST: _("dataset already exists"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EBUSY: _("dataset is busy"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EROFS:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens _("snapshot permissions cannot be modified"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.ENAMETOOLONG: _("dataset name is too long"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.ENOTSUP: _("unsupported version"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens errno.EAGAIN: _("pool I/O is currently suspended"),
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens }
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __strs[errno.EACCES] = __strs[errno.EPERM]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __strs[errno.ENXIO] = __strs[errno.EIO]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __strs[errno.ENODEV] = __strs[errno.EIO]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens __strs[errno.EDQUOT] = __strs[errno.ENOSPC]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens @property
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens def strerror(self):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return ZFSError.__strs.get(self.errno, os.strerror(self.errno))
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensdef nicenum(num):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens """Return a nice string (eg "1.23M") for this integer."""
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens index = 0;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens n = num;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens while n >= 1024:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens n /= 1024
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens index += 1
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens u = " KMGTPE"[index]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if index == 0:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return "%u" % n;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens elif n >= 100 or num & ((1024*index)-1) == 0:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens # it's an exact multiple of its index, or it wouldn't
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens # fit as floating point, so print as an integer
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return "%u%c" % (n, u)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens else:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens # due to rounding, it's tricky to tell what precision to
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens # use; try each precision and see which one fits
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens for i in (2, 1, 0):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s = "%.*f%c" % (i, float(num) / (1<<(10*index)), u)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if len(s) <= 5:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens return s
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensdef append_with_opt(option, opt, value, parser):
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens """A function for OptionParser which appends a tuple (opt, value)."""
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens getattr(parser.values, option.dest).append((opt, value))
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens