]> git.proxmox.com Git - mirror_zfs.git/blame - contrib/pyzfs/libzfs_core/exceptions.py
ZVOLs should not be allowed to have children
[mirror_zfs.git] / contrib / pyzfs / libzfs_core / exceptions.py
CommitLineData
85ce3f4f 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#
6abf9225
AG
16
17"""
18Exceptions that can be raised by libzfs_core operations.
19"""
9de8c0cd 20from __future__ import absolute_import, division, print_function
6abf9225
AG
21
22import errno
c962fd6c 23from ._constants import (
24 ZFS_ERR_CHECKPOINT_EXISTS,
25 ZFS_ERR_DISCARDING_CHECKPOINT,
26 ZFS_ERR_NO_CHECKPOINT,
27 ZFS_ERR_DEVRM_IN_PROGRESS,
d8d418ff 28 ZFS_ERR_VDEV_TOO_BIG,
29 ZFS_ERR_WRONG_PARENT
c962fd6c 30)
6abf9225
AG
31
32
33class ZFSError(Exception):
34 errno = None
35 message = None
36 name = None
37
38 def __str__(self):
39 if self.name is not None:
85ce3f4f 40 return "[Errno %d] %s: '%s'" % (
41 self.errno, self.message, self.name)
6abf9225
AG
42 else:
43 return "[Errno %d] %s" % (self.errno, self.message)
44
45 def __repr__(self):
85ce3f4f 46 return "%s(%r, %r)" % (
47 self.__class__.__name__, self.errno, self.message)
6abf9225
AG
48
49
50class ZFSGenericError(ZFSError):
51
52 def __init__(self, errno, name, message):
53 self.errno = errno
54 self.message = message
55 self.name = name
56
57
58class ZFSInitializationFailed(ZFSError):
59 message = "Failed to initialize libzfs_core"
60
61 def __init__(self, errno):
62 self.errno = errno
63
64
65class 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
85ce3f4f 72 # this many errors were encountered but not placed on the `errors` list
6abf9225
AG
73 self.suppressed_count = suppressed_count
74
75 def __str__(self):
85ce3f4f 76 return "%s, %d errors included, %d suppressed" % (
77 ZFSError.__str__(self), len(self.errors), self.suppressed_count)
6abf9225
AG
78
79 def __repr__(self):
85ce3f4f 80 return "%s(%r, %r, errors=%r, supressed=%r)" % (
81 self.__class__.__name__, self.errno, self.message, self.errors,
82 self.suppressed_count)
6abf9225
AG
83
84
85class DatasetNotFound(ZFSError):
86
87 """
85ce3f4f 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.
6abf9225
AG
91 """
92 errno = errno.ENOENT
93 message = "Dataset not found"
94
95 def __init__(self, name):
96 self.name = name
97
98
99class DatasetExists(ZFSError):
100
101 """
85ce3f4f 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
6abf9225
AG
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
113class 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
121class FilesystemExists(DatasetExists):
122 message = "Filesystem already exists"
123
124 def __init__(self, name):
125 self.name = name
126
127
128class FilesystemNotFound(DatasetNotFound):
129 message = "Filesystem not found"
130
131 def __init__(self, name):
132 self.name = name
133
134
135class ParentNotFound(ZFSError):
136 errno = errno.ENOENT
137 message = "Parent not found"
138
139 def __init__(self, name):
140 self.name = name
141
142
143class WrongParent(ZFSError):
d8d418ff 144 errno = ZFS_ERR_WRONG_PARENT
6abf9225
AG
145 message = "Parent dataset is not a filesystem"
146
147 def __init__(self, name):
148 self.name = name
149
150
151class SnapshotExists(DatasetExists):
152 message = "Snapshot already exists"
153
154 def __init__(self, name):
155 self.name = name
156
157
158class SnapshotNotFound(DatasetNotFound):
159 message = "Snapshot not found"
160
161 def __init__(self, name):
162 self.name = name
163
85ce3f4f 164
6abf9225
AG
165class SnapshotNotLatest(ZFSError):
166 errno = errno.EEXIST
167 message = "Snapshot is not the latest"
168
169 def __init__(self, name):
170 self.name = name
171
85ce3f4f 172
6abf9225
AG
173class SnapshotIsCloned(ZFSError):
174 errno = errno.EEXIST
175 message = "Snapshot is cloned"
176
177 def __init__(self, name):
178 self.name = name
179
180
181class SnapshotIsHeld(ZFSError):
182 errno = errno.EBUSY
183 message = "Snapshot is held"
184
185 def __init__(self, name):
186 self.name = name
187
188
189class 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
197class 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
204class SnapshotDestructionFailure(MultipleOperationsFailure):
205 message = "Destruction of snapshot(s) failed for one or more reasons"
206
207 def __init__(self, errors, suppressed_count):
85ce3f4f 208 super(SnapshotDestructionFailure, self).__init__(
209 errors, suppressed_count)
6abf9225
AG
210
211
212class BookmarkExists(ZFSError):
213 errno = errno.EEXIST
214 message = "Bookmark already exists"
215
216 def __init__(self, name):
217 self.name = name
218
219
220class BookmarkNotFound(ZFSError):
221 errno = errno.ENOENT
222 message = "Bookmark not found"
223
224 def __init__(self, name):
225 self.name = name
226
227
228class 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
236class 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
244class 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
251class BookmarkDestructionFailure(MultipleOperationsFailure):
252 message = "Destruction of bookmark(s) failed for one or more reasons"
253
254 def __init__(self, errors, suppressed_count):
85ce3f4f 255 super(BookmarkDestructionFailure, self).__init__(
256 errors, suppressed_count)
6abf9225
AG
257
258
259class BadHoldCleanupFD(ZFSError):
260 errno = errno.EBADF
261 message = "Bad file descriptor as cleanup file descriptor"
262
263
264class 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
272class 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
280class 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
287class 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
294class 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
302class 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
310class 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
318class BadStream(ZFSError):
85ce3f4f 319 errno = errno.EBADE
6abf9225
AG
320 message = "Bad backup stream"
321
322
323class StreamFeatureNotSupported(ZFSError):
324 errno = errno.ENOTSUP
325 message = "Stream contains unsupported feature"
326
327
328class UnknownStreamFeature(ZFSError):
329 errno = errno.ENOTSUP
330 message = "Unknown feature requested for stream"
331
332
85ce3f4f 333class StreamFeatureInvalid(ZFSError):
334 errno = errno.EINVAL
335 message = "Kernel modules must be upgraded to receive this stream"
336
337
338class StreamFeatureIncompatible(ZFSError):
339 errno = errno.EINVAL
340 message = "Incompatible embedded feature with encrypted receive"
341
342
343class 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
6abf9225
AG
350class StreamIOError(ZFSError):
351 message = "I/O error while writing or reading stream"
352
353 def __init__(self, errno):
354 self.errno = errno
355
356
357class ZIOError(ZFSError):
358 errno = errno.EIO
359 message = "I/O error"
360
361 def __init__(self, name):
362 self.name = name
363
364
365class NoSpace(ZFSError):
366 errno = errno.ENOSPC
367 message = "No space left"
368
369 def __init__(self, name):
370 self.name = name
371
372
373class QuotaExceeded(ZFSError):
374 errno = errno.EDQUOT
375 message = "Quouta exceeded"
376
377 def __init__(self, name):
378 self.name = name
379
380
381class DatasetBusy(ZFSError):
382 errno = errno.EBUSY
383 message = "Dataset is busy"
384
385 def __init__(self, name):
386 self.name = name
387
388
389class 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
397class NameInvalid(ZFSError):
398 errno = errno.EINVAL
399 message = "Invalid name"
400
401 def __init__(self, name):
402 self.name = name
403
404
405class SnapshotNameInvalid(NameInvalid):
406 message = "Invalid name for snapshot"
407
408 def __init__(self, name):
409 self.name = name
410
411
412class FilesystemNameInvalid(NameInvalid):
413 message = "Invalid name for filesystem or volume"
414
415 def __init__(self, name):
416 self.name = name
417
418
419class BookmarkNameInvalid(NameInvalid):
420 message = "Invalid name for bookmark"
421
422 def __init__(self, name):
423 self.name = name
424
425
426class ReadOnlyPool(ZFSError):
427 errno = errno.EROFS
428 message = "Pool is read-only"
429
430 def __init__(self, name):
431 self.name = name
432
433
434class SuspendedPool(ZFSError):
435 errno = errno.EAGAIN
436 message = "Pool is suspended"
437
438 def __init__(self, name):
439 self.name = name
440
441
442class PoolNotFound(ZFSError):
443 errno = errno.EXDEV
444 message = "No such pool"
445
446 def __init__(self, name):
447 self.name = name
448
449
450class 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
458class 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
466class 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
474class 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
482class 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
85ce3f4f 490class 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
498class EncryptionKeyNotLoaded(ZFSError):
499 errno = errno.EACCES
500 message = "Encryption key is not currently loaded"
501
502
503class EncryptionKeyAlreadyLoaded(ZFSError):
504 errno = errno.EEXIST
505 message = "Encryption key is already loaded"
506
507
508class EncryptionKeyInvalid(ZFSError):
509 errno = errno.EACCES
510 message = "Incorrect encryption key provided"
511
512
513class ZCPError(ZFSError):
514 errno = None
515 message = None
516
517
518class 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
526class 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
534class ZCPLimitInvalid(ZCPError):
535 errno = errno.EINVAL
536 message = "Channel program called with invalid limits"
537
538
539class ZCPTimeout(ZCPError):
540 errno = errno.ETIME
541 message = "Channel program timed out"
542
543
544class ZCPSpaceError(ZCPError):
545 errno = errno.ENOSPC
546 message = "Channel program exhausted the memory limit"
547
548
549class ZCPMemoryError(ZCPError):
550 errno = errno.ENOMEM
551 message = "Channel program return value too large"
552
553
554class ZCPPermissionError(ZCPError):
555 errno = errno.EPERM
556 message = "Channel programs must be run as root"
557
558
c962fd6c 559class CheckpointExists(ZFSError):
560 errno = ZFS_ERR_CHECKPOINT_EXISTS
561 message = "Pool already has a checkpoint"
562
563
564class CheckpointNotFound(ZFSError):
565 errno = ZFS_ERR_NO_CHECKPOINT
566 message = "Pool does not have a checkpoint"
567
568
569class CheckpointDiscarding(ZFSError):
570 errno = ZFS_ERR_DISCARDING_CHECKPOINT
571 message = "Pool checkpoint is being discarded"
572
573
574class DeviceRemovalRunning(ZFSError):
575 errno = ZFS_ERR_DEVRM_IN_PROGRESS
576 message = "A vdev is currently being removed"
577
578
579class DeviceTooBig(ZFSError):
580 errno = ZFS_ERR_VDEV_TOO_BIG
581 message = "One or more top-level vdevs exceed the maximum vdev size"
582
583
6abf9225 584# vim: softtabstop=4 tabstop=4 expandtab shiftwidth=4