2 # Copyright 2015 ClusterHQ
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 Exceptions that can be raised by libzfs_core operations.
20 from __future__
import absolute_import
, division
, print_function
23 from ._constants
import (
24 ZFS_ERR_CHECKPOINT_EXISTS
,
25 ZFS_ERR_DISCARDING_CHECKPOINT
,
26 ZFS_ERR_NO_CHECKPOINT
,
27 ZFS_ERR_DEVRM_IN_PROGRESS
,
33 class ZFSError(Exception):
39 if self
.name
is not None:
40 return "[Errno %d] %s: '%s'" % (
41 self
.errno
, self
.message
, self
.name
)
43 return "[Errno %d] %s" % (self
.errno
, self
.message
)
46 return "%s(%r, %r)" % (
47 self
.__class
__.__name
__, self
.errno
, self
.message
)
50 class ZFSGenericError(ZFSError
):
52 def __init__(self
, errno
, name
, message
):
54 self
.message
= message
58 class ZFSInitializationFailed(ZFSError
):
59 message
= "Failed to initialize libzfs_core"
61 def __init__(self
, errno
):
65 class MultipleOperationsFailure(ZFSError
):
67 def __init__(self
, errors
, suppressed_count
):
68 # Use first of the individual error codes
69 # as an overall error code. This is more consistent.
70 self
.errno
= errors
[0].errno
72 # this many errors were encountered but not placed on the `errors` list
73 self
.suppressed_count
= suppressed_count
76 return "%s, %d errors included, %d suppressed" % (
77 ZFSError
.__str
__(self
), len(self
.errors
), self
.suppressed_count
)
80 return "%s(%r, %r, errors=%r, supressed=%r)" % (
81 self
.__class
__.__name
__, self
.errno
, self
.message
, self
.errors
,
82 self
.suppressed_count
)
85 class DatasetNotFound(ZFSError
):
88 This exception is raised when an operation failure can be caused by a
89 missing snapshot or a missing filesystem and it is impossible to
90 distinguish between the causes.
93 message
= "Dataset not found"
95 def __init__(self
, name
):
99 class DatasetExists(ZFSError
):
102 This exception is raised when an operation failure can be caused by an
103 existing snapshot or filesystem and it is impossible to distinguish between
107 message
= "Dataset already exists"
109 def __init__(self
, name
):
113 class NotClone(ZFSError
):
115 message
= "Filesystem is not a clone, can not promote"
117 def __init__(self
, name
):
121 class FilesystemExists(DatasetExists
):
122 message
= "Filesystem already exists"
124 def __init__(self
, name
):
128 class FilesystemNotFound(DatasetNotFound
):
129 message
= "Filesystem not found"
131 def __init__(self
, name
):
135 class ParentNotFound(ZFSError
):
137 message
= "Parent not found"
139 def __init__(self
, name
):
143 class WrongParent(ZFSError
):
144 errno
= ZFS_ERR_WRONG_PARENT
145 message
= "Parent dataset is not a filesystem"
147 def __init__(self
, name
):
151 class SnapshotExists(DatasetExists
):
152 message
= "Snapshot already exists"
154 def __init__(self
, name
):
158 class SnapshotNotFound(DatasetNotFound
):
159 message
= "Snapshot not found"
161 def __init__(self
, name
):
165 class SnapshotNotLatest(ZFSError
):
167 message
= "Snapshot is not the latest"
169 def __init__(self
, name
):
173 class SnapshotIsCloned(ZFSError
):
175 message
= "Snapshot is cloned"
177 def __init__(self
, name
):
181 class SnapshotIsHeld(ZFSError
):
183 message
= "Snapshot is held"
185 def __init__(self
, name
):
189 class DuplicateSnapshots(ZFSError
):
191 message
= "Requested multiple snapshots of the same filesystem"
193 def __init__(self
, name
):
197 class SnapshotFailure(MultipleOperationsFailure
):
198 message
= "Creation of snapshot(s) failed for one or more reasons"
200 def __init__(self
, errors
, suppressed_count
):
201 super(SnapshotFailure
, self
).__init
__(errors
, suppressed_count
)
204 class SnapshotDestructionFailure(MultipleOperationsFailure
):
205 message
= "Destruction of snapshot(s) failed for one or more reasons"
207 def __init__(self
, errors
, suppressed_count
):
208 super(SnapshotDestructionFailure
, self
).__init
__(
209 errors
, suppressed_count
)
212 class BookmarkExists(ZFSError
):
214 message
= "Bookmark already exists"
216 def __init__(self
, name
):
220 class BookmarkNotFound(ZFSError
):
222 message
= "Bookmark not found"
224 def __init__(self
, name
):
228 class BookmarkMismatch(ZFSError
):
230 message
= "Bookmark is not in snapshot's filesystem"
232 def __init__(self
, name
):
236 class BookmarkNotSupported(ZFSError
):
237 errno
= errno
.ENOTSUP
238 message
= "Bookmark feature is not supported"
240 def __init__(self
, name
):
244 class BookmarkFailure(MultipleOperationsFailure
):
245 message
= "Creation of bookmark(s) failed for one or more reasons"
247 def __init__(self
, errors
, suppressed_count
):
248 super(BookmarkFailure
, self
).__init
__(errors
, suppressed_count
)
251 class BookmarkDestructionFailure(MultipleOperationsFailure
):
252 message
= "Destruction of bookmark(s) failed for one or more reasons"
254 def __init__(self
, errors
, suppressed_count
):
255 super(BookmarkDestructionFailure
, self
).__init
__(
256 errors
, suppressed_count
)
259 class BadHoldCleanupFD(ZFSError
):
261 message
= "Bad file descriptor as cleanup file descriptor"
264 class HoldExists(ZFSError
):
266 message
= "Hold with a given tag already exists on snapshot"
268 def __init__(self
, name
):
272 class HoldNotFound(ZFSError
):
274 message
= "Hold with a given tag does not exist on snapshot"
276 def __init__(self
, name
):
280 class HoldFailure(MultipleOperationsFailure
):
281 message
= "Placement of hold(s) failed for one or more reasons"
283 def __init__(self
, errors
, suppressed_count
):
284 super(HoldFailure
, self
).__init
__(errors
, suppressed_count
)
287 class HoldReleaseFailure(MultipleOperationsFailure
):
288 message
= "Release of hold(s) failed for one or more reasons"
290 def __init__(self
, errors
, suppressed_count
):
291 super(HoldReleaseFailure
, self
).__init
__(errors
, suppressed_count
)
294 class SnapshotMismatch(ZFSError
):
296 message
= "Snapshot is not descendant of source snapshot"
298 def __init__(self
, name
):
302 class StreamMismatch(ZFSError
):
304 message
= "Stream is not applicable to destination dataset"
306 def __init__(self
, name
):
310 class DestinationModified(ZFSError
):
311 errno
= errno
.ETXTBSY
312 message
= "Destination dataset has modifications that can not be undone"
314 def __init__(self
, name
):
318 class BadStream(ZFSError
):
320 message
= "Bad backup stream"
323 class StreamFeatureNotSupported(ZFSError
):
324 errno
= errno
.ENOTSUP
325 message
= "Stream contains unsupported feature"
328 class UnknownStreamFeature(ZFSError
):
329 errno
= errno
.ENOTSUP
330 message
= "Unknown feature requested for stream"
333 class StreamFeatureInvalid(ZFSError
):
335 message
= "Kernel modules must be upgraded to receive this stream"
338 class StreamFeatureIncompatible(ZFSError
):
340 message
= "Incompatible embedded feature with encrypted receive"
343 class ReceivePropertyFailure(MultipleOperationsFailure
):
344 message
= "Receiving of properties failed for one or more reasons"
346 def __init__(self
, errors
, suppressed_count
):
347 super(ReceivePropertyFailure
, self
).__init
__(errors
, suppressed_count
)
350 class StreamIOError(ZFSError
):
351 message
= "I/O error while writing or reading stream"
353 def __init__(self
, errno
):
357 class ZIOError(ZFSError
):
359 message
= "I/O error"
361 def __init__(self
, name
):
365 class NoSpace(ZFSError
):
367 message
= "No space left"
369 def __init__(self
, name
):
373 class QuotaExceeded(ZFSError
):
375 message
= "Quouta exceeded"
377 def __init__(self
, name
):
381 class DatasetBusy(ZFSError
):
383 message
= "Dataset is busy"
385 def __init__(self
, name
):
389 class NameTooLong(ZFSError
):
390 errno
= errno
.ENAMETOOLONG
391 message
= "Dataset name is too long"
393 def __init__(self
, name
):
397 class NameInvalid(ZFSError
):
399 message
= "Invalid name"
401 def __init__(self
, name
):
405 class SnapshotNameInvalid(NameInvalid
):
406 message
= "Invalid name for snapshot"
408 def __init__(self
, name
):
412 class FilesystemNameInvalid(NameInvalid
):
413 message
= "Invalid name for filesystem or volume"
415 def __init__(self
, name
):
419 class BookmarkNameInvalid(NameInvalid
):
420 message
= "Invalid name for bookmark"
422 def __init__(self
, name
):
426 class ReadOnlyPool(ZFSError
):
428 message
= "Pool is read-only"
430 def __init__(self
, name
):
434 class SuspendedPool(ZFSError
):
436 message
= "Pool is suspended"
438 def __init__(self
, name
):
442 class PoolNotFound(ZFSError
):
444 message
= "No such pool"
446 def __init__(self
, name
):
450 class PoolsDiffer(ZFSError
):
452 message
= "Source and target belong to different pools"
454 def __init__(self
, name
):
458 class FeatureNotSupported(ZFSError
):
459 errno
= errno
.ENOTSUP
460 message
= "Feature is not supported in this version"
462 def __init__(self
, name
):
466 class PropertyNotSupported(ZFSError
):
467 errno
= errno
.ENOTSUP
468 message
= "Property is not supported in this version"
470 def __init__(self
, name
):
474 class PropertyInvalid(ZFSError
):
476 message
= "Invalid property or property value"
478 def __init__(self
, name
):
482 class DatasetTypeInvalid(ZFSError
):
484 message
= "Specified dataset type is unknown"
486 def __init__(self
, name
):
490 class UnknownCryptCommand(ZFSError
):
492 message
= "Specified crypt command is invalid"
494 def __init__(self
, name
):
498 class EncryptionKeyNotLoaded(ZFSError
):
500 message
= "Encryption key is not currently loaded"
503 class EncryptionKeyAlreadyLoaded(ZFSError
):
505 message
= "Encryption key is already loaded"
508 class EncryptionKeyInvalid(ZFSError
):
510 message
= "Incorrect encryption key provided"
513 class ZCPError(ZFSError
):
518 class ZCPSyntaxError(ZCPError
):
520 message
= "Channel program contains syntax errors"
522 def __init__(self
, details
):
523 self
.details
= details
526 class ZCPRuntimeError(ZCPError
):
528 message
= "Channel programs encountered a runtime error"
530 def __init__(self
, details
):
531 self
.details
= details
534 class ZCPLimitInvalid(ZCPError
):
536 message
= "Channel program called with invalid limits"
539 class ZCPTimeout(ZCPError
):
541 message
= "Channel program timed out"
544 class ZCPSpaceError(ZCPError
):
546 message
= "Channel program exhausted the memory limit"
549 class ZCPMemoryError(ZCPError
):
551 message
= "Channel program return value too large"
554 class ZCPPermissionError(ZCPError
):
556 message
= "Channel programs must be run as root"
559 class CheckpointExists(ZFSError
):
560 errno
= ZFS_ERR_CHECKPOINT_EXISTS
561 message
= "Pool already has a checkpoint"
564 class CheckpointNotFound(ZFSError
):
565 errno
= ZFS_ERR_NO_CHECKPOINT
566 message
= "Pool does not have a checkpoint"
569 class CheckpointDiscarding(ZFSError
):
570 errno
= ZFS_ERR_DISCARDING_CHECKPOINT
571 message
= "Pool checkpoint is being discarded"
574 class DeviceRemovalRunning(ZFSError
):
575 errno
= ZFS_ERR_DEVRM_IN_PROGRESS
576 message
= "A vdev is currently being removed"
579 class DeviceTooBig(ZFSError
):
580 errno
= ZFS_ERR_VDEV_TOO_BIG
581 message
= "One or more top-level vdevs exceed the maximum vdev size"
584 # vim: softtabstop=4 tabstop=4 expandtab shiftwidth=4