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