]> git.proxmox.com Git - mirror_zfs.git/blob - contrib/pyzfs/libzfs_core/exceptions.py
c54459ec8b4745413fe79ad0e34d7b653495b618
[mirror_zfs.git] / contrib / pyzfs / libzfs_core / exceptions.py
1 #
2 # Copyright 2015 ClusterHQ
3 #
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
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15 #
16
17 """
18 Exceptions that can be raised by libzfs_core operations.
19 """
20 from __future__ import absolute_import, division, print_function
21
22 import errno
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,
28 ZFS_ERR_VDEV_TOO_BIG
29 )
30
31
32 class ZFSError(Exception):
33 errno = None
34 message = None
35 name = None
36
37 def __str__(self):
38 if self.name is not None:
39 return "[Errno %d] %s: '%s'" % (
40 self.errno, self.message, self.name)
41 else:
42 return "[Errno %d] %s" % (self.errno, self.message)
43
44 def __repr__(self):
45 return "%s(%r, %r)" % (
46 self.__class__.__name__, self.errno, self.message)
47
48
49 class ZFSGenericError(ZFSError):
50
51 def __init__(self, errno, name, message):
52 self.errno = errno
53 self.message = message
54 self.name = name
55
56
57 class ZFSInitializationFailed(ZFSError):
58 message = "Failed to initialize libzfs_core"
59
60 def __init__(self, errno):
61 self.errno = errno
62
63
64 class MultipleOperationsFailure(ZFSError):
65
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
70 self.errors = errors
71 # this many errors were encountered but not placed on the `errors` list
72 self.suppressed_count = suppressed_count
73
74 def __str__(self):
75 return "%s, %d errors included, %d suppressed" % (
76 ZFSError.__str__(self), len(self.errors), self.suppressed_count)
77
78 def __repr__(self):
79 return "%s(%r, %r, errors=%r, supressed=%r)" % (
80 self.__class__.__name__, self.errno, self.message, self.errors,
81 self.suppressed_count)
82
83
84 class DatasetNotFound(ZFSError):
85
86 """
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.
90 """
91 errno = errno.ENOENT
92 message = "Dataset not found"
93
94 def __init__(self, name):
95 self.name = name
96
97
98 class DatasetExists(ZFSError):
99
100 """
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
103 the causes.
104 """
105 errno = errno.EEXIST
106 message = "Dataset already exists"
107
108 def __init__(self, name):
109 self.name = name
110
111
112 class NotClone(ZFSError):
113 errno = errno.EINVAL
114 message = "Filesystem is not a clone, can not promote"
115
116 def __init__(self, name):
117 self.name = name
118
119
120 class FilesystemExists(DatasetExists):
121 message = "Filesystem already exists"
122
123 def __init__(self, name):
124 self.name = name
125
126
127 class FilesystemNotFound(DatasetNotFound):
128 message = "Filesystem not found"
129
130 def __init__(self, name):
131 self.name = name
132
133
134 class ParentNotFound(ZFSError):
135 errno = errno.ENOENT
136 message = "Parent not found"
137
138 def __init__(self, name):
139 self.name = name
140
141
142 class WrongParent(ZFSError):
143 errno = errno.EINVAL
144 message = "Parent dataset is not a filesystem"
145
146 def __init__(self, name):
147 self.name = name
148
149
150 class SnapshotExists(DatasetExists):
151 message = "Snapshot already exists"
152
153 def __init__(self, name):
154 self.name = name
155
156
157 class SnapshotNotFound(DatasetNotFound):
158 message = "Snapshot not found"
159
160 def __init__(self, name):
161 self.name = name
162
163
164 class SnapshotNotLatest(ZFSError):
165 errno = errno.EEXIST
166 message = "Snapshot is not the latest"
167
168 def __init__(self, name):
169 self.name = name
170
171
172 class SnapshotIsCloned(ZFSError):
173 errno = errno.EEXIST
174 message = "Snapshot is cloned"
175
176 def __init__(self, name):
177 self.name = name
178
179
180 class SnapshotIsHeld(ZFSError):
181 errno = errno.EBUSY
182 message = "Snapshot is held"
183
184 def __init__(self, name):
185 self.name = name
186
187
188 class DuplicateSnapshots(ZFSError):
189 errno = errno.EXDEV
190 message = "Requested multiple snapshots of the same filesystem"
191
192 def __init__(self, name):
193 self.name = name
194
195
196 class SnapshotFailure(MultipleOperationsFailure):
197 message = "Creation of snapshot(s) failed for one or more reasons"
198
199 def __init__(self, errors, suppressed_count):
200 super(SnapshotFailure, self).__init__(errors, suppressed_count)
201
202
203 class SnapshotDestructionFailure(MultipleOperationsFailure):
204 message = "Destruction of snapshot(s) failed for one or more reasons"
205
206 def __init__(self, errors, suppressed_count):
207 super(SnapshotDestructionFailure, self).__init__(
208 errors, suppressed_count)
209
210
211 class BookmarkExists(ZFSError):
212 errno = errno.EEXIST
213 message = "Bookmark already exists"
214
215 def __init__(self, name):
216 self.name = name
217
218
219 class BookmarkNotFound(ZFSError):
220 errno = errno.ENOENT
221 message = "Bookmark not found"
222
223 def __init__(self, name):
224 self.name = name
225
226
227 class BookmarkMismatch(ZFSError):
228 errno = errno.EINVAL
229 message = "Bookmark is not in snapshot's filesystem"
230
231 def __init__(self, name):
232 self.name = name
233
234
235 class BookmarkNotSupported(ZFSError):
236 errno = errno.ENOTSUP
237 message = "Bookmark feature is not supported"
238
239 def __init__(self, name):
240 self.name = name
241
242
243 class BookmarkFailure(MultipleOperationsFailure):
244 message = "Creation of bookmark(s) failed for one or more reasons"
245
246 def __init__(self, errors, suppressed_count):
247 super(BookmarkFailure, self).__init__(errors, suppressed_count)
248
249
250 class BookmarkDestructionFailure(MultipleOperationsFailure):
251 message = "Destruction of bookmark(s) failed for one or more reasons"
252
253 def __init__(self, errors, suppressed_count):
254 super(BookmarkDestructionFailure, self).__init__(
255 errors, suppressed_count)
256
257
258 class BadHoldCleanupFD(ZFSError):
259 errno = errno.EBADF
260 message = "Bad file descriptor as cleanup file descriptor"
261
262
263 class HoldExists(ZFSError):
264 errno = errno.EEXIST
265 message = "Hold with a given tag already exists on snapshot"
266
267 def __init__(self, name):
268 self.name = name
269
270
271 class HoldNotFound(ZFSError):
272 errno = errno.ENOENT
273 message = "Hold with a given tag does not exist on snapshot"
274
275 def __init__(self, name):
276 self.name = name
277
278
279 class HoldFailure(MultipleOperationsFailure):
280 message = "Placement of hold(s) failed for one or more reasons"
281
282 def __init__(self, errors, suppressed_count):
283 super(HoldFailure, self).__init__(errors, suppressed_count)
284
285
286 class HoldReleaseFailure(MultipleOperationsFailure):
287 message = "Release of hold(s) failed for one or more reasons"
288
289 def __init__(self, errors, suppressed_count):
290 super(HoldReleaseFailure, self).__init__(errors, suppressed_count)
291
292
293 class SnapshotMismatch(ZFSError):
294 errno = errno.ENODEV
295 message = "Snapshot is not descendant of source snapshot"
296
297 def __init__(self, name):
298 self.name = name
299
300
301 class StreamMismatch(ZFSError):
302 errno = errno.ENODEV
303 message = "Stream is not applicable to destination dataset"
304
305 def __init__(self, name):
306 self.name = name
307
308
309 class DestinationModified(ZFSError):
310 errno = errno.ETXTBSY
311 message = "Destination dataset has modifications that can not be undone"
312
313 def __init__(self, name):
314 self.name = name
315
316
317 class BadStream(ZFSError):
318 errno = errno.EBADE
319 message = "Bad backup stream"
320
321
322 class StreamFeatureNotSupported(ZFSError):
323 errno = errno.ENOTSUP
324 message = "Stream contains unsupported feature"
325
326
327 class UnknownStreamFeature(ZFSError):
328 errno = errno.ENOTSUP
329 message = "Unknown feature requested for stream"
330
331
332 class StreamFeatureInvalid(ZFSError):
333 errno = errno.EINVAL
334 message = "Kernel modules must be upgraded to receive this stream"
335
336
337 class StreamFeatureIncompatible(ZFSError):
338 errno = errno.EINVAL
339 message = "Incompatible embedded feature with encrypted receive"
340
341
342 class ReceivePropertyFailure(MultipleOperationsFailure):
343 message = "Receiving of properties failed for one or more reasons"
344
345 def __init__(self, errors, suppressed_count):
346 super(ReceivePropertyFailure, self).__init__(errors, suppressed_count)
347
348
349 class StreamIOError(ZFSError):
350 message = "I/O error while writing or reading stream"
351
352 def __init__(self, errno):
353 self.errno = errno
354
355
356 class ZIOError(ZFSError):
357 errno = errno.EIO
358 message = "I/O error"
359
360 def __init__(self, name):
361 self.name = name
362
363
364 class NoSpace(ZFSError):
365 errno = errno.ENOSPC
366 message = "No space left"
367
368 def __init__(self, name):
369 self.name = name
370
371
372 class QuotaExceeded(ZFSError):
373 errno = errno.EDQUOT
374 message = "Quouta exceeded"
375
376 def __init__(self, name):
377 self.name = name
378
379
380 class DatasetBusy(ZFSError):
381 errno = errno.EBUSY
382 message = "Dataset is busy"
383
384 def __init__(self, name):
385 self.name = name
386
387
388 class NameTooLong(ZFSError):
389 errno = errno.ENAMETOOLONG
390 message = "Dataset name is too long"
391
392 def __init__(self, name):
393 self.name = name
394
395
396 class NameInvalid(ZFSError):
397 errno = errno.EINVAL
398 message = "Invalid name"
399
400 def __init__(self, name):
401 self.name = name
402
403
404 class SnapshotNameInvalid(NameInvalid):
405 message = "Invalid name for snapshot"
406
407 def __init__(self, name):
408 self.name = name
409
410
411 class FilesystemNameInvalid(NameInvalid):
412 message = "Invalid name for filesystem or volume"
413
414 def __init__(self, name):
415 self.name = name
416
417
418 class BookmarkNameInvalid(NameInvalid):
419 message = "Invalid name for bookmark"
420
421 def __init__(self, name):
422 self.name = name
423
424
425 class ReadOnlyPool(ZFSError):
426 errno = errno.EROFS
427 message = "Pool is read-only"
428
429 def __init__(self, name):
430 self.name = name
431
432
433 class SuspendedPool(ZFSError):
434 errno = errno.EAGAIN
435 message = "Pool is suspended"
436
437 def __init__(self, name):
438 self.name = name
439
440
441 class PoolNotFound(ZFSError):
442 errno = errno.EXDEV
443 message = "No such pool"
444
445 def __init__(self, name):
446 self.name = name
447
448
449 class PoolsDiffer(ZFSError):
450 errno = errno.EXDEV
451 message = "Source and target belong to different pools"
452
453 def __init__(self, name):
454 self.name = name
455
456
457 class FeatureNotSupported(ZFSError):
458 errno = errno.ENOTSUP
459 message = "Feature is not supported in this version"
460
461 def __init__(self, name):
462 self.name = name
463
464
465 class PropertyNotSupported(ZFSError):
466 errno = errno.ENOTSUP
467 message = "Property is not supported in this version"
468
469 def __init__(self, name):
470 self.name = name
471
472
473 class PropertyInvalid(ZFSError):
474 errno = errno.EINVAL
475 message = "Invalid property or property value"
476
477 def __init__(self, name):
478 self.name = name
479
480
481 class DatasetTypeInvalid(ZFSError):
482 errno = errno.EINVAL
483 message = "Specified dataset type is unknown"
484
485 def __init__(self, name):
486 self.name = name
487
488
489 class UnknownCryptCommand(ZFSError):
490 errno = errno.EINVAL
491 message = "Specified crypt command is invalid"
492
493 def __init__(self, name):
494 self.name = name
495
496
497 class EncryptionKeyNotLoaded(ZFSError):
498 errno = errno.EACCES
499 message = "Encryption key is not currently loaded"
500
501
502 class EncryptionKeyAlreadyLoaded(ZFSError):
503 errno = errno.EEXIST
504 message = "Encryption key is already loaded"
505
506
507 class EncryptionKeyInvalid(ZFSError):
508 errno = errno.EACCES
509 message = "Incorrect encryption key provided"
510
511
512 class ZCPError(ZFSError):
513 errno = None
514 message = None
515
516
517 class ZCPSyntaxError(ZCPError):
518 errno = errno.EINVAL
519 message = "Channel program contains syntax errors"
520
521 def __init__(self, details):
522 self.details = details
523
524
525 class ZCPRuntimeError(ZCPError):
526 errno = errno.ECHRNG
527 message = "Channel programs encountered a runtime error"
528
529 def __init__(self, details):
530 self.details = details
531
532
533 class ZCPLimitInvalid(ZCPError):
534 errno = errno.EINVAL
535 message = "Channel program called with invalid limits"
536
537
538 class ZCPTimeout(ZCPError):
539 errno = errno.ETIME
540 message = "Channel program timed out"
541
542
543 class ZCPSpaceError(ZCPError):
544 errno = errno.ENOSPC
545 message = "Channel program exhausted the memory limit"
546
547
548 class ZCPMemoryError(ZCPError):
549 errno = errno.ENOMEM
550 message = "Channel program return value too large"
551
552
553 class ZCPPermissionError(ZCPError):
554 errno = errno.EPERM
555 message = "Channel programs must be run as root"
556
557
558 class CheckpointExists(ZFSError):
559 errno = ZFS_ERR_CHECKPOINT_EXISTS
560 message = "Pool already has a checkpoint"
561
562
563 class CheckpointNotFound(ZFSError):
564 errno = ZFS_ERR_NO_CHECKPOINT
565 message = "Pool does not have a checkpoint"
566
567
568 class CheckpointDiscarding(ZFSError):
569 errno = ZFS_ERR_DISCARDING_CHECKPOINT
570 message = "Pool checkpoint is being discarded"
571
572
573 class DeviceRemovalRunning(ZFSError):
574 errno = ZFS_ERR_DEVRM_IN_PROGRESS
575 message = "A vdev is currently being removed"
576
577
578 class DeviceTooBig(ZFSError):
579 errno = ZFS_ERR_VDEV_TOO_BIG
580 message = "One or more top-level vdevs exceed the maximum vdev size"
581
582
583 # vim: softtabstop=4 tabstop=4 expandtab shiftwidth=4