blob: f8a775433b3c205c947be504d96bdf4b8ef8073c [file] [log] [blame]
#
# Copyright 2015 ClusterHQ
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
Exceptions that can be raised by libzfs_core operations.
"""
from __future__ import absolute_import, division, print_function
import errno
from ._constants import (
ZFS_ERR_CHECKPOINT_EXISTS,
ZFS_ERR_DISCARDING_CHECKPOINT,
ZFS_ERR_NO_CHECKPOINT,
ZFS_ERR_DEVRM_IN_PROGRESS,
ZFS_ERR_VDEV_TOO_BIG,
ZFS_ERR_WRONG_PARENT
)
class ZFSError(Exception):
errno = None
message = None
name = None
def __str__(self):
if self.name is not None:
return "[Errno %d] %s: '%s'" % (
self.errno, self.message, self.name)
else:
return "[Errno %d] %s" % (self.errno, self.message)
def __repr__(self):
return "%s(%r, %r)" % (
self.__class__.__name__, self.errno, self.message)
class ZFSGenericError(ZFSError):
def __init__(self, errno, name, message):
self.errno = errno
self.message = message
self.name = name
class ZFSInitializationFailed(ZFSError):
message = "Failed to initialize libzfs_core"
def __init__(self, errno):
self.errno = errno
class MultipleOperationsFailure(ZFSError):
def __init__(self, errors, suppressed_count):
# Use first of the individual error codes
# as an overall error code. This is more consistent.
self.errno = errors[0].errno
self.errors = errors
# this many errors were encountered but not placed on the `errors` list
self.suppressed_count = suppressed_count
def __str__(self):
return "%s, %d errors included, %d suppressed" % (
ZFSError.__str__(self), len(self.errors), self.suppressed_count)
def __repr__(self):
return "%s(%r, %r, errors=%r, suppressed=%r)" % (
self.__class__.__name__, self.errno, self.message, self.errors,
self.suppressed_count)
class DatasetNotFound(ZFSError):
"""
This exception is raised when an operation failure can be caused by a
missing snapshot or a missing filesystem and it is impossible to
distinguish between the causes.
"""
errno = errno.ENOENT
message = "Dataset not found"
def __init__(self, name):
self.name = name
class DatasetExists(ZFSError):
"""
This exception is raised when an operation failure can be caused by an
existing snapshot or filesystem and it is impossible to distinguish between
the causes.
"""
errno = errno.EEXIST
message = "Dataset already exists"
def __init__(self, name):
self.name = name
class NotClone(ZFSError):
errno = errno.EINVAL
message = "Filesystem is not a clone, can not promote"
def __init__(self, name):
self.name = name
class FilesystemExists(DatasetExists):
message = "Filesystem already exists"
def __init__(self, name):
self.name = name
class FilesystemNotFound(DatasetNotFound):
message = "Filesystem not found"
def __init__(self, name):
self.name = name
class ParentNotFound(ZFSError):
errno = errno.ENOENT
message = "Parent not found"
def __init__(self, name):
self.name = name
class WrongParent(ZFSError):
errno = ZFS_ERR_WRONG_PARENT
message = "Parent dataset is not a filesystem"
def __init__(self, name):
self.name = name
class SnapshotExists(DatasetExists):
message = "Snapshot already exists"
def __init__(self, name):
self.name = name
class SnapshotNotFound(DatasetNotFound):
message = "Snapshot not found"
def __init__(self, name):
self.name = name
class SnapshotNotLatest(ZFSError):
errno = errno.EEXIST
message = "Snapshot is not the latest"
def __init__(self, name):
self.name = name
class SnapshotIsCloned(ZFSError):
errno = errno.EEXIST
message = "Snapshot is cloned"
def __init__(self, name):
self.name = name
class SnapshotIsHeld(ZFSError):
errno = errno.EBUSY
message = "Snapshot is held"
def __init__(self, name):
self.name = name
class DuplicateSnapshots(ZFSError):
errno = errno.EXDEV
message = "Requested multiple snapshots of the same filesystem"
def __init__(self, name):
self.name = name
class SnapshotFailure(MultipleOperationsFailure):
message = "Creation of snapshot(s) failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(SnapshotFailure, self).__init__(errors, suppressed_count)
class SnapshotDestructionFailure(MultipleOperationsFailure):
message = "Destruction of snapshot(s) failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(SnapshotDestructionFailure, self).__init__(
errors, suppressed_count)
class BookmarkExists(ZFSError):
errno = errno.EEXIST
message = "Bookmark already exists"
def __init__(self, name):
self.name = name
class BookmarkNotFound(ZFSError):
errno = errno.ENOENT
message = "Bookmark not found"
def __init__(self, name):
self.name = name
class BookmarkMismatch(ZFSError):
errno = errno.EINVAL
message = "Bookmark is not in snapshot's filesystem"
def __init__(self, name):
self.name = name
class BookmarkNotSupported(ZFSError):
errno = errno.ENOTSUP
message = "Bookmark feature is not supported"
def __init__(self, name):
self.name = name
class BookmarkFailure(MultipleOperationsFailure):
message = "Creation of bookmark(s) failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(BookmarkFailure, self).__init__(errors, suppressed_count)
class BookmarkDestructionFailure(MultipleOperationsFailure):
message = "Destruction of bookmark(s) failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(BookmarkDestructionFailure, self).__init__(
errors, suppressed_count)
class BadHoldCleanupFD(ZFSError):
errno = errno.EBADF
message = "Bad file descriptor as cleanup file descriptor"
class HoldExists(ZFSError):
errno = errno.EEXIST
message = "Hold with a given tag already exists on snapshot"
def __init__(self, name):
self.name = name
class HoldNotFound(ZFSError):
errno = errno.ENOENT
message = "Hold with a given tag does not exist on snapshot"
def __init__(self, name):
self.name = name
class HoldFailure(MultipleOperationsFailure):
message = "Placement of hold(s) failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(HoldFailure, self).__init__(errors, suppressed_count)
class HoldReleaseFailure(MultipleOperationsFailure):
message = "Release of hold(s) failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(HoldReleaseFailure, self).__init__(errors, suppressed_count)
class SnapshotMismatch(ZFSError):
errno = errno.ENODEV
message = "Snapshot is not descendant of source snapshot"
def __init__(self, name):
self.name = name
class StreamMismatch(ZFSError):
errno = errno.ENODEV
message = "Stream is not applicable to destination dataset"
def __init__(self, name):
self.name = name
class DestinationModified(ZFSError):
errno = errno.ETXTBSY
message = "Destination dataset has modifications that can not be undone"
def __init__(self, name):
self.name = name
class BadStream(ZFSError):
errno = errno.EBADE
message = "Bad backup stream"
class StreamFeatureNotSupported(ZFSError):
errno = errno.ENOTSUP
message = "Stream contains unsupported feature"
class UnknownStreamFeature(ZFSError):
errno = errno.ENOTSUP
message = "Unknown feature requested for stream"
class StreamFeatureInvalid(ZFSError):
errno = errno.EINVAL
message = "Kernel modules must be upgraded to receive this stream"
class StreamFeatureIncompatible(ZFSError):
errno = errno.EINVAL
message = "Incompatible embedded feature with encrypted receive"
class ReceivePropertyFailure(MultipleOperationsFailure):
message = "Receiving of properties failed for one or more reasons"
def __init__(self, errors, suppressed_count):
super(ReceivePropertyFailure, self).__init__(errors, suppressed_count)
class StreamIOError(ZFSError):
message = "I/O error while writing or reading stream"
def __init__(self, errno):
self.errno = errno
class ZIOError(ZFSError):
errno = errno.EIO
message = "I/O error"
def __init__(self, name):
self.name = name
class NoSpace(ZFSError):
errno = errno.ENOSPC
message = "No space left"
def __init__(self, name):
self.name = name
class QuotaExceeded(ZFSError):
errno = errno.EDQUOT
message = "Quota exceeded"
def __init__(self, name):
self.name = name
class DatasetBusy(ZFSError):
errno = errno.EBUSY
message = "Dataset is busy"
def __init__(self, name):
self.name = name
class NameTooLong(ZFSError):
errno = errno.ENAMETOOLONG
message = "Dataset name is too long"
def __init__(self, name):
self.name = name
class NameInvalid(ZFSError):
errno = errno.EINVAL
message = "Invalid name"
def __init__(self, name):
self.name = name
class SnapshotNameInvalid(NameInvalid):
message = "Invalid name for snapshot"
def __init__(self, name):
self.name = name
class FilesystemNameInvalid(NameInvalid):
message = "Invalid name for filesystem or volume"
def __init__(self, name):
self.name = name
class BookmarkNameInvalid(NameInvalid):
message = "Invalid name for bookmark"
def __init__(self, name):
self.name = name
class ReadOnlyPool(ZFSError):
errno = errno.EROFS
message = "Pool is read-only"
def __init__(self, name):
self.name = name
class SuspendedPool(ZFSError):
errno = errno.EAGAIN
message = "Pool is suspended"
def __init__(self, name):
self.name = name
class PoolNotFound(ZFSError):
errno = errno.EXDEV
message = "No such pool"
def __init__(self, name):
self.name = name
class PoolsDiffer(ZFSError):
errno = errno.EXDEV
message = "Source and target belong to different pools"
def __init__(self, name):
self.name = name
class FeatureNotSupported(ZFSError):
errno = errno.ENOTSUP
message = "Feature is not supported in this version"
def __init__(self, name):
self.name = name
class PropertyNotSupported(ZFSError):
errno = errno.ENOTSUP
message = "Property is not supported in this version"
def __init__(self, name):
self.name = name
class PropertyInvalid(ZFSError):
errno = errno.EINVAL
message = "Invalid property or property value"
def __init__(self, name):
self.name = name
class DatasetTypeInvalid(ZFSError):
errno = errno.EINVAL
message = "Specified dataset type is unknown"
def __init__(self, name):
self.name = name
class UnknownCryptCommand(ZFSError):
errno = errno.EINVAL
message = "Specified crypt command is invalid"
def __init__(self, name):
self.name = name
class EncryptionKeyNotLoaded(ZFSError):
errno = errno.EACCES
message = "Encryption key is not currently loaded"
class EncryptionKeyAlreadyLoaded(ZFSError):
errno = errno.EEXIST
message = "Encryption key is already loaded"
class EncryptionKeyInvalid(ZFSError):
errno = errno.EACCES
message = "Incorrect encryption key provided"
class ZCPError(ZFSError):
errno = None
message = None
class ZCPSyntaxError(ZCPError):
errno = errno.EINVAL
message = "Channel program contains syntax errors"
def __init__(self, details):
self.details = details
class ZCPRuntimeError(ZCPError):
errno = errno.ECHRNG
message = "Channel programs encountered a runtime error"
def __init__(self, details):
self.details = details
class ZCPLimitInvalid(ZCPError):
errno = errno.EINVAL
message = "Channel program called with invalid limits"
class ZCPTimeout(ZCPError):
errno = errno.ETIME
message = "Channel program timed out"
class ZCPSpaceError(ZCPError):
errno = errno.ENOSPC
message = "Channel program exhausted the memory limit"
class ZCPMemoryError(ZCPError):
errno = errno.ENOMEM
message = "Channel program return value too large"
class ZCPPermissionError(ZCPError):
errno = errno.EPERM
message = "Channel programs must be run as root"
class CheckpointExists(ZFSError):
errno = ZFS_ERR_CHECKPOINT_EXISTS
message = "Pool already has a checkpoint"
class CheckpointNotFound(ZFSError):
errno = ZFS_ERR_NO_CHECKPOINT
message = "Pool does not have a checkpoint"
class CheckpointDiscarding(ZFSError):
errno = ZFS_ERR_DISCARDING_CHECKPOINT
message = "Pool checkpoint is being discarded"
class DeviceRemovalRunning(ZFSError):
errno = ZFS_ERR_DEVRM_IN_PROGRESS
message = "A vdev is currently being removed"
class DeviceTooBig(ZFSError):
errno = ZFS_ERR_VDEV_TOO_BIG
message = "One or more top-level vdevs exceed the maximum vdev size"
# vim: softtabstop=4 tabstop=4 expandtab shiftwidth=4