xref: /freebsd-src/cddl/contrib/opensolaris/lib/pyzfs/common/util.py (revision 10b9d77bf1ccf2f3affafa6261692cb92cf7e992)
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