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
,
32 class ZFSError(Exception):
38 if self
.name
is not None:
39 return "[Errno %d] %s: '%s'" % (
40 self
.errno
, self
.message
, self
.name
)
42 return "[Errno %d] %s" % (self
.errno
, self
.message
)
45 return "%s(%r, %r)" % (
46 self
.__class
__.__name
__, self
.errno
, self
.message
)
49 class ZFSGenericError(ZFSError
):
51 def __init__(self
, errno
, name
, message
):
53 self
.message
= message
57 class ZFSInitializationFailed(ZFSError
):
58 message
= "Failed to initialize libzfs_core"
60 def __init__(self
, errno
):
64 class MultipleOperationsFailure(ZFSError
):
66 def __init__(self
, errors
, suppressed_count
):
67 # Use first of the individual error codes
68 # as an overall error code. This is more consistent.
69 self
.errno
= errors
[0].errno
71 # this many errors were encountered but not placed on the `errors` list
72 self
.suppressed_count
= suppressed_count
75 return "%s, %d errors included, %d suppressed" % (
76 ZFSError
.__str
__(self
), len(self
.errors
), self
.suppressed_count
)
79 return "%s(%r, %r, errors=%r, supressed=%r)" % (
80 self
.__class
__.__name
__, self
.errno
, self
.message
, self
.errors
,
81 self
.suppressed_count
)
84 class DatasetNotFound(ZFSError
):
87 This exception is raised when an operation failure can be caused by a
88 missing snapshot or a missing filesystem and it is impossible to
89 distinguish between the causes.
92 message
= "Dataset not found"
94 def __init__(self
, name
):
98 class DatasetExists(ZFSError
):
101 This exception is raised when an operation failure can be caused by an
102 existing snapshot or filesystem and it is impossible to distinguish between
106 message
= "Dataset already exists"
108 def __init__(self
, name
):
112 class NotClone(ZFSError
):
114 message
= "Filesystem is not a clone, can not promote"
116 def __init__(self
, name
):
120 class FilesystemExists(DatasetExists
):
121 message
= "Filesystem already exists"
123 def __init__(self
, name
):
127 class FilesystemNotFound(DatasetNotFound
):
128 message
= "Filesystem not found"
130 def __init__(self
, name
):
134 class ParentNotFound(ZFSError
):
136 message
= "Parent not found"
138 def __init__(self
, name
):
142 class WrongParent(ZFSError
):
144 message
= "Parent dataset is not a filesystem"
146 def __init__(self
, name
):
150 class SnapshotExists(DatasetExists
):
151 message
= "Snapshot already exists"
153 def __init__(self
, name
):
157 class SnapshotNotFound(DatasetNotFound
):
158 message
= "Snapshot not found"
160 def __init__(self
, name
):
164 class SnapshotNotLatest(ZFSError
):
166 message
= "Snapshot is not the latest"
168 def __init__(self
, name
):
172 class SnapshotIsCloned(ZFSError
):
174 message
= "Snapshot is cloned"
176 def __init__(self
, name
):
180 class SnapshotIsHeld(ZFSError
):
182 message
= "Snapshot is held"
184 def __init__(self
, name
):
188 class DuplicateSnapshots(ZFSError
):
190 message
= "Requested multiple snapshots of the same filesystem"
192 def __init__(self
, name
):
196 class SnapshotFailure(MultipleOperationsFailure
):
197 message
= "Creation of snapshot(s) failed for one or more reasons"
199 def __init__(self
, errors
, suppressed_count
):
200 super(SnapshotFailure
, self
).__init
__(errors
, suppressed_count
)
203 class SnapshotDestructionFailure(MultipleOperationsFailure
):
204 message
= "Destruction of snapshot(s) failed for one or more reasons"
206 def __init__(self
, errors
, suppressed_count
):
207 super(SnapshotDestructionFailure
, self
).__init
__(
208 errors
, suppressed_count
)
211 class BookmarkExists(ZFSError
):
213 message
= "Bookmark already exists"
215 def __init__(self
, name
):
219 class BookmarkNotFound(ZFSError
):
221 message
= "Bookmark not found"
223 def __init__(self
, name
):
227 class BookmarkMismatch(ZFSError
):
229 message
= "Bookmark is not in snapshot's filesystem"
231 def __init__(self
, name
):
235 class BookmarkNotSupported(ZFSError
):
236 errno
= errno
.ENOTSUP
237 message
= "Bookmark feature is not supported"
239 def __init__(self
, name
):
243 class BookmarkFailure(MultipleOperationsFailure
):
244 message
= "Creation of bookmark(s) failed for one or more reasons"
246 def __init__(self
, errors
, suppressed_count
):
247 super(BookmarkFailure
, self
).__init
__(errors
, suppressed_count
)
250 class BookmarkDestructionFailure(MultipleOperationsFailure
):
251 message
= "Destruction of bookmark(s) failed for one or more reasons"
253 def __init__(self
, errors
, suppressed_count
):
254 super(BookmarkDestructionFailure
, self
).__init
__(
255 errors
, suppressed_count
)
258 class BadHoldCleanupFD(ZFSError
):
260 message
= "Bad file descriptor as cleanup file descriptor"
263 class HoldExists(ZFSError
):
265 message
= "Hold with a given tag already exists on snapshot"
267 def __init__(self
, name
):
271 class HoldNotFound(ZFSError
):
273 message
= "Hold with a given tag does not exist on snapshot"
275 def __init__(self
, name
):
279 class HoldFailure(MultipleOperationsFailure
):
280 message
= "Placement of hold(s) failed for one or more reasons"
282 def __init__(self
, errors
, suppressed_count
):
283 super(HoldFailure
, self
).__init
__(errors
, suppressed_count
)
286 class HoldReleaseFailure(MultipleOperationsFailure
):
287 message
= "Release of hold(s) failed for one or more reasons"
289 def __init__(self
, errors
, suppressed_count
):
290 super(HoldReleaseFailure
, self
).__init
__(errors
, suppressed_count
)
293 class SnapshotMismatch(ZFSError
):
295 message
= "Snapshot is not descendant of source snapshot"
297 def __init__(self
, name
):
301 class StreamMismatch(ZFSError
):
303 message
= "Stream is not applicable to destination dataset"
305 def __init__(self
, name
):
309 class DestinationModified(ZFSError
):
310 errno
= errno
.ETXTBSY
311 message
= "Destination dataset has modifications that can not be undone"
313 def __init__(self
, name
):
317 class BadStream(ZFSError
):
319 message
= "Bad backup stream"
322 class StreamFeatureNotSupported(ZFSError
):
323 errno
= errno
.ENOTSUP
324 message
= "Stream contains unsupported feature"
327 class UnknownStreamFeature(ZFSError
):
328 errno
= errno
.ENOTSUP
329 message
= "Unknown feature requested for stream"
332 class StreamFeatureInvalid(ZFSError
):
334 message
= "Kernel modules must be upgraded to receive this stream"
337 class StreamFeatureIncompatible(ZFSError
):
339 message
= "Incompatible embedded feature with encrypted receive"
342 class ReceivePropertyFailure(MultipleOperationsFailure
):
343 message
= "Receiving of properties failed for one or more reasons"
345 def __init__(self
, errors
, suppressed_count
):
346 super(ReceivePropertyFailure
, self
).__init
__(errors
, suppressed_count
)
349 class StreamIOError(ZFSError
):
350 message
= "I/O error while writing or reading stream"
352 def __init__(self
, errno
):
356 class ZIOError(ZFSError
):
358 message
= "I/O error"
360 def __init__(self
, name
):
364 class NoSpace(ZFSError
):
366 message
= "No space left"
368 def __init__(self
, name
):
372 class QuotaExceeded(ZFSError
):
374 message
= "Quouta exceeded"
376 def __init__(self
, name
):
380 class DatasetBusy(ZFSError
):
382 message
= "Dataset is busy"
384 def __init__(self
, name
):
388 class NameTooLong(ZFSError
):
389 errno
= errno
.ENAMETOOLONG
390 message
= "Dataset name is too long"
392 def __init__(self
, name
):
396 class NameInvalid(ZFSError
):
398 message
= "Invalid name"
400 def __init__(self
, name
):
404 class SnapshotNameInvalid(NameInvalid
):
405 message
= "Invalid name for snapshot"
407 def __init__(self
, name
):
411 class FilesystemNameInvalid(NameInvalid
):
412 message
= "Invalid name for filesystem or volume"
414 def __init__(self
, name
):
418 class BookmarkNameInvalid(NameInvalid
):
419 message
= "Invalid name for bookmark"
421 def __init__(self
, name
):
425 class ReadOnlyPool(ZFSError
):
427 message
= "Pool is read-only"
429 def __init__(self
, name
):
433 class SuspendedPool(ZFSError
):
435 message
= "Pool is suspended"
437 def __init__(self
, name
):
441 class PoolNotFound(ZFSError
):
443 message
= "No such pool"
445 def __init__(self
, name
):
449 class PoolsDiffer(ZFSError
):
451 message
= "Source and target belong to different pools"
453 def __init__(self
, name
):
457 class FeatureNotSupported(ZFSError
):
458 errno
= errno
.ENOTSUP
459 message
= "Feature is not supported in this version"
461 def __init__(self
, name
):
465 class PropertyNotSupported(ZFSError
):
466 errno
= errno
.ENOTSUP
467 message
= "Property is not supported in this version"
469 def __init__(self
, name
):
473 class PropertyInvalid(ZFSError
):
475 message
= "Invalid property or property value"
477 def __init__(self
, name
):
481 class DatasetTypeInvalid(ZFSError
):
483 message
= "Specified dataset type is unknown"
485 def __init__(self
, name
):
489 class UnknownCryptCommand(ZFSError
):
491 message
= "Specified crypt command is invalid"
493 def __init__(self
, name
):
497 class EncryptionKeyNotLoaded(ZFSError
):
499 message
= "Encryption key is not currently loaded"
502 class EncryptionKeyAlreadyLoaded(ZFSError
):
504 message
= "Encryption key is already loaded"
507 class EncryptionKeyInvalid(ZFSError
):
509 message
= "Incorrect encryption key provided"
512 class ZCPError(ZFSError
):
517 class ZCPSyntaxError(ZCPError
):
519 message
= "Channel program contains syntax errors"
521 def __init__(self
, details
):
522 self
.details
= details
525 class ZCPRuntimeError(ZCPError
):
527 message
= "Channel programs encountered a runtime error"
529 def __init__(self
, details
):
530 self
.details
= details
533 class ZCPLimitInvalid(ZCPError
):
535 message
= "Channel program called with invalid limits"
538 class ZCPTimeout(ZCPError
):
540 message
= "Channel program timed out"
543 class ZCPSpaceError(ZCPError
):
545 message
= "Channel program exhausted the memory limit"
548 class ZCPMemoryError(ZCPError
):
550 message
= "Channel program return value too large"
553 class ZCPPermissionError(ZCPError
):
555 message
= "Channel programs must be run as root"
558 class CheckpointExists(ZFSError
):
559 errno
= ZFS_ERR_CHECKPOINT_EXISTS
560 message
= "Pool already has a checkpoint"
563 class CheckpointNotFound(ZFSError
):
564 errno
= ZFS_ERR_NO_CHECKPOINT
565 message
= "Pool does not have a checkpoint"
568 class CheckpointDiscarding(ZFSError
):
569 errno
= ZFS_ERR_DISCARDING_CHECKPOINT
570 message
= "Pool checkpoint is being discarded"
573 class DeviceRemovalRunning(ZFSError
):
574 errno
= ZFS_ERR_DEVRM_IN_PROGRESS
575 message
= "A vdev is currently being removed"
578 class DeviceTooBig(ZFSError
):
579 errno
= ZFS_ERR_VDEV_TOO_BIG
580 message
= "One or more top-level vdevs exceed the maximum vdev size"
583 # vim: softtabstop=4 tabstop=4 expandtab shiftwidth=4