#
# Copyright 2015 ClusterHQ
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
Python wrappers for libzfs_core interfaces.

As a rule, there is a Python function for each C function.
The signatures of the Python functions generally follow those of the
functions, but the argument types are natural to Python.
nvlists are wrapped as dictionaries or lists depending on their usage.
Some parameters have default values depending on typical use for
increased convenience.  Output parameters are not used and return values
are directly returned.  Error conditions are signalled by exceptions
rather than by integer error codes.
"""
from __future__ import absolute_import, division, print_function

import errno
import functools
import fcntl
import os
import struct
import threading
from . import exceptions
from . import _error_translation as errors
from .bindings import libzfs_core
from ._constants import (  # noqa: F401
    MAXNAMELEN,
    ZCP_DEFAULT_INSTRLIMIT,
    ZCP_DEFAULT_MEMLIMIT,
    WRAPPING_KEY_LEN,
    zfs_key_location,
    zfs_keyformat,
    zio_encrypt
)
from .ctypes import (
    int32_t,
    uint64_t
)
from ._nvlist import nvlist_in, nvlist_out


def _uncommitted(depends_on=None):
    '''
    Mark an API function as being an uncommitted extension that might not be
    available.

    :param function depends_on: the function that would be checked instead of
        a decorated function. For example, if the decorated function uses
        another uncommitted function.

    This decorator transforms a decorated function to raise
    :exc:`NotImplementedError` if the C libzfs_core library does not provide
    a function with the same name as the decorated function.

    The optional `depends_on` parameter can be provided if the decorated
    function does not directly call the C function but instead calls another
    Python function that follows the typical convention.
    One example is :func:`lzc_list_snaps` that calls :func:`lzc_list` that
    calls ``lzc_list`` in libzfs_core.

    This decorator is implemented using :func:`is_supported`.
    '''
    def _uncommitted_decorator(func, depends_on=depends_on):
        @functools.wraps(func)
        def _f(*args, **kwargs):
            if not is_supported(_f):
                raise NotImplementedError(func.__name__)
            return func(*args, **kwargs)
        if depends_on is not None:
            _f._check_func = depends_on
        return _f
    return _uncommitted_decorator


def lzc_create(name, ds_type='zfs', props=None, key=None):
    '''
    Create a ZFS filesystem or a ZFS volume ("zvol").

    :param bytes name: a name of the dataset to be created.
    :param str ds_type: the type of the dataset to be created,
        currently supported types are "zfs" (the default) for a filesystem and
        "zvol" for a volume.
    :param props: a `dict` of ZFS dataset property name-value pairs
        (empty by default).
    :type props: dict of bytes:Any
    :param key: dataset encryption key data (empty by default).
    :type key: bytes

    :raises FilesystemExists: if a dataset with the given name already exists.
    :raises ParentNotFound: if a parent dataset of the requested dataset does
        not exist.
    :raises PropertyInvalid: if one or more of the specified properties is
        invalid or has an invalid type or value.
    :raises NameInvalid: if the name is not a valid dataset name.
    :raises NameTooLong: if the name is too long.
    :raises WrongParent: if the parent dataset of the requested dataset is not
        a filesystem (e.g. ZVOL)
    '''
    if props is None:
        props = {}
    if key is None:
        key = b""
    else:
        key = bytes(key)
    if ds_type == 'zfs':
        ds_type = _lib.DMU_OST_ZFS
    elif ds_type == 'zvol':
        ds_type = _lib.DMU_OST_ZVOL
    else:
        raise exceptions.DatasetTypeInvalid(ds_type)
    nvlist = nvlist_in(props)
    ret = _lib.lzc_create(name, ds_type, nvlist, key, len(key))
    errors.lzc_create_translate_error(ret, name, ds_type, props)


def lzc_clone(name, origin, props=None):
    '''
    Clone a ZFS filesystem or a ZFS volume ("zvol") from a given snapshot.

    :param bytes name: a name of the dataset to be created.
    :param bytes origin: a name of the origin snapshot.
    :param props: a `dict` of ZFS dataset property name-value pairs
        (empty by default).
    :type props: dict of bytes:Any

    :raises FilesystemExists: if a dataset with the given name already exists.
    :raises DatasetNotFound: if either a parent dataset of the requested
        dataset or the origin snapshot does not exist.
    :raises PropertyInvalid: if one or more of the specified properties is
        invalid or has an invalid type or value.
    :raises FilesystemNameInvalid: if the name is not a valid dataset name.
    :raises SnapshotNameInvalid: if the origin is not a valid snapshot name.
    :raises NameTooLong: if the name or the origin name is too long.
    :raises PoolsDiffer: if the clone and the origin have different pool names.

    .. note::
        Because of a deficiency of the underlying C interface
        :exc:`.DatasetNotFound` can mean that either a parent filesystem of
        the target or the origin snapshot does not exist.
        It is currently impossible to distinguish between the cases.
        :func:`lzc_hold` can be used to check that the snapshot exists and
        ensure that it is not destroyed before cloning.
    '''
    if props is None:
        props = {}
    nvlist = nvlist_in(props)
    ret = _lib.lzc_clone(name, origin, nvlist)
    errors.lzc_clone_translate_error(ret, name, origin, props)


def lzc_rollback(name):
    '''
    Roll back a filesystem or volume to its most recent snapshot.

    Note that the latest snapshot may change if a new one is concurrently
    created or the current one is destroyed.  lzc_rollback_to can be used
    to roll back to a specific latest snapshot.

    :param bytes name: a name of the dataset to be rolled back.
    :return: a name of the most recent snapshot.
    :rtype: bytes

    :raises FilesystemNotFound: if the dataset does not exist.
    :raises SnapshotNotFound: if the dataset does not have any snapshots.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    '''
    # Account for terminating NUL in C strings.
    snapnamep = _ffi.new('char[]', MAXNAMELEN + 1)
    ret = _lib.lzc_rollback(name, snapnamep, MAXNAMELEN + 1)
    errors.lzc_rollback_translate_error(ret, name)
    return _ffi.string(snapnamep)


def lzc_rollback_to(name, snap):
    '''
    Roll back this filesystem or volume to the specified snapshot, if possible.

    :param bytes name: a name of the dataset to be rolled back.
    :param bytes snap: a name of the snapshot to be rolled back.

    :raises FilesystemNotFound: if the dataset does not exist.
    :raises SnapshotNotFound: if the dataset does not have any snapshots.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises SnapshotNotLatest: if the snapshot is not the latest.
    '''
    ret = _lib.lzc_rollback_to(name, snap)
    errors.lzc_rollback_to_translate_error(ret, name, snap)


def lzc_snapshot(snaps, props=None):
    '''
    Create snapshots.

    All snapshots must be in the same pool.

    Optionally snapshot properties can be set on all snapshots.
    Currently  only user properties (prefixed with "user:") are supported.

    Either all snapshots are successfully created or none are created if
    an exception is raised.

    :param snaps: a list of names of snapshots to be created.
    :type snaps: list of bytes
    :param props: a `dict` of ZFS dataset property name-value pairs
        (empty by default).
    :type props: dict of bytes:bytes

    :raises SnapshotFailure: if one or more snapshots could not be created.

    .. note::
        :exc:`.SnapshotFailure` is a compound exception that provides at least
        one detailed error object in :attr:`SnapshotFailure.errors` `list`.

    .. warning::
        The underlying implementation reports an individual, per-snapshot error
        only for :exc:`.SnapshotExists` condition and *sometimes* for
        :exc:`.NameTooLong`.
        In all other cases a single error is reported without connection to any
        specific snapshot name(s).

        This has the following implications:

        * if multiple error conditions are encountered only one of them is
          reported

        * unless only one snapshot is requested then it is impossible to tell
          how many snapshots are problematic and what they are

        * only if there are no other error conditions :exc:`.SnapshotExists`
          is reported for all affected snapshots

        * :exc:`.NameTooLong` can behave either in the same way as
          :exc:`.SnapshotExists` or as all other exceptions.
          The former is the case where the full snapshot name exceeds the
          maximum allowed length but the short snapshot name (after '@') is
          within the limit.
          The latter is the case when the short name alone exceeds the maximum
          allowed length.
    '''
    snaps_dict = {name: None for name in snaps}
    errlist = {}
    snaps_nvlist = nvlist_in(snaps_dict)
    if props is None:
        props = {}
    props_nvlist = nvlist_in(props)
    with nvlist_out(errlist) as errlist_nvlist:
        ret = _lib.lzc_snapshot(snaps_nvlist, props_nvlist, errlist_nvlist)
    errors.lzc_snapshot_translate_errors(ret, errlist, snaps, props)


lzc_snap = lzc_snapshot


def lzc_destroy_snaps(snaps, defer):
    '''
    Destroy snapshots.

    They must all be in the same pool.
    Snapshots that do not exist will be silently ignored.

    If 'defer' is not set, and a snapshot has user holds or clones, the
    destroy operation will fail and none of the snapshots will be
    destroyed.

    If 'defer' is set, and a snapshot has user holds or clones, it will be
    marked for deferred destruction, and will be destroyed when the last hold
    or clone is removed/destroyed.

    The operation succeeds if all snapshots were destroyed (or marked for
    later destruction if 'defer' is set) or didn't exist to begin with.

    :param snaps: a list of names of snapshots to be destroyed.
    :type snaps: list of bytes
    :param bool defer: whether to mark busy snapshots for deferred destruction
        rather than immediately failing.

    :raises SnapshotDestructionFailure: if one or more snapshots could not be
        created.

    .. note::
        :exc:`.SnapshotDestructionFailure` is a compound exception that
        provides at least one detailed error object in
        :attr:`SnapshotDestructionFailure.errors` `list`.

        Typical error is :exc:`SnapshotIsCloned` if `defer` is `False`.
        The snapshot names are validated quite loosely and invalid names are
        typically ignored as nonexisting snapshots.

        A snapshot name referring to a filesystem that doesn't exist is
        ignored.
        However, non-existent pool name causes :exc:`PoolNotFound`.
    '''
    snaps_dict = {name: None for name in snaps}
    errlist = {}
    snaps_nvlist = nvlist_in(snaps_dict)
    with nvlist_out(errlist) as errlist_nvlist:
        ret = _lib.lzc_destroy_snaps(snaps_nvlist, defer, errlist_nvlist)
    errors.lzc_destroy_snaps_translate_errors(ret, errlist, snaps, defer)


def lzc_bookmark(bookmarks):
    '''
    Create bookmarks.

    :param bookmarks: a dict that maps names of wanted bookmarks to names of
        existing snapshots.
    :type bookmarks: dict of bytes to bytes
    :raises BookmarkFailure: if any of the bookmarks can not be created for any
        reason.

    The bookmarks `dict` maps from name of the bookmark
    (e.g. :file:`{pool}/{fs}#{bmark}`) to the name of the snapshot
    (e.g. :file:`{pool}/{fs}@{snap}`).  All the bookmarks and snapshots must
    be in the same pool.
    '''
    errlist = {}
    nvlist = nvlist_in(bookmarks)
    with nvlist_out(errlist) as errlist_nvlist:
        ret = _lib.lzc_bookmark(nvlist, errlist_nvlist)
    errors.lzc_bookmark_translate_errors(ret, errlist, bookmarks)


def lzc_get_bookmarks(fsname, props=None):
    '''
    Retrieve a listing of bookmarks for the given file system.

    :param bytes fsname: a name of the filesystem.
    :param props: a `list` of properties that will be returned for each
        bookmark.
    :type props: list of bytes
    :return: a `dict` that maps the bookmarks' short names to their properties.
    :rtype: dict of bytes:dict

    :raises FilesystemNotFound: if the filesystem is not found.

    The following are valid properties on bookmarks:

    guid : integer
        globally unique identifier of the snapshot the bookmark refers to
    createtxg : integer
        txg when the snapshot the bookmark refers to was created
    creation : integer
        timestamp when the snapshot the bookmark refers to was created

    Any other properties passed in ``props`` are ignored without reporting
    any error.
    Values in the returned dictionary map the names of the requested properties
    to their respective values.
    '''
    bmarks = {}
    if props is None:
        props = []
    props_dict = {name: None for name in props}
    nvlist = nvlist_in(props_dict)
    with nvlist_out(bmarks) as bmarks_nvlist:
        ret = _lib.lzc_get_bookmarks(fsname, nvlist, bmarks_nvlist)
    errors.lzc_get_bookmarks_translate_error(ret, fsname, props)
    return bmarks


def lzc_destroy_bookmarks(bookmarks):
    '''
    Destroy bookmarks.

    :param bookmarks: a list of the bookmarks to be destroyed. The bookmarks
        are specified as :file:`{fs}#{bmark}`.
    :type bookmarks: list of bytes

    :raises BookmarkDestructionFailure: if any of the bookmarks may not be
        destroyed.

    The bookmarks must all be in the same pool.
    Bookmarks that do not exist will be silently ignored.
    This also includes the case where the filesystem component of the bookmark
    name does not exist.
    However, an invalid bookmark name will cause :exc:`.NameInvalid` error
    reported in :attr:`SnapshotDestructionFailure.errors`.

    Either all bookmarks that existed are destroyed or an exception is raised.
    '''
    errlist = {}
    bmarks_dict = {name: None for name in bookmarks}
    nvlist = nvlist_in(bmarks_dict)
    with nvlist_out(errlist) as errlist_nvlist:
        ret = _lib.lzc_destroy_bookmarks(nvlist, errlist_nvlist)
    errors.lzc_destroy_bookmarks_translate_errors(ret, errlist, bookmarks)


def lzc_snaprange_space(firstsnap, lastsnap):
    '''
    Calculate a size of data referenced by snapshots in the inclusive range
    between the ``firstsnap`` and the ``lastsnap`` and not shared with any
    other datasets.

    :param bytes firstsnap: the name of the first snapshot in the range.
    :param bytes lastsnap: the name of the last snapshot in the range.
    :return: the calculated stream size, in bytes.
    :rtype: `int` or `long`

    :raises SnapshotNotFound: if either of the snapshots does not exist.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    :raises SnapshotMismatch: if ``fromsnap`` is not an ancestor snapshot of
        ``snapname``.
    :raises PoolsDiffer: if the snapshots belong to different pools.

    ``lzc_snaprange_space`` calculates total size of blocks that exist
    because they are referenced only by one or more snapshots in the given
    range but no other dataset.
    In other words, this is the set of blocks that were born after the snap
    before firstsnap, and died before the snap after the last snap.
    Yet another interpretation is that the result of ``lzc_snaprange_space``
    is the size of the space that would be freed if the snapshots in the range
    are destroyed.

    If the same snapshot is given as both the ``firstsnap`` and the
    ``lastsnap``.
    In that case ``lzc_snaprange_space`` calculates space used by the snapshot.
    '''
    valp = _ffi.new('uint64_t *')
    ret = _lib.lzc_snaprange_space(firstsnap, lastsnap, valp)
    errors.lzc_snaprange_space_translate_error(ret, firstsnap, lastsnap)
    return int(valp[0])


def lzc_hold(holds, fd=None):
    '''
    Create *user holds* on snapshots.  If there is a hold on a snapshot,
    the snapshot can not be destroyed.  (However, it can be marked for
    deletion by :func:`lzc_destroy_snaps` ( ``defer`` = `True` ).)

    :param holds: the dictionary of names of the snapshots to hold mapped to
        the hold names.
    :type holds: dict of bytes : bytes
    :type fd: int or None
    :param fd: if not None then it must be the result of :func:`os.open`
        called as ``os.open("/dev/zfs", O_EXCL)``.
    :type fd: int or None
    :return: a list of the snapshots that do not exist.
    :rtype: list of bytes

    :raises HoldFailure: if a hold was impossible on one or more of the
        snapshots.
    :raises BadHoldCleanupFD: if ``fd`` is not a valid file descriptor
        associated with :file:`/dev/zfs`.

    The snapshots must all be in the same pool.

    If ``fd`` is not None, then when the ``fd`` is closed (including on process
    termination), the holds will be released.  If the system is shut down
    uncleanly, the holds will be released when the pool is next opened
    or imported.

    Holds for snapshots which don't exist will be skipped and have an entry
    added to the return value, but will not cause an overall failure.
    No exceptions is raised if all holds, for snapshots that existed, were
    successfully created.
    Otherwise :exc:`.HoldFailure` exception is raised and no holds will be
    created.
    :attr:`.HoldFailure.errors` may contain a single element for an error that
    is not specific to any hold / snapshot, or it may contain one or more
    elements detailing specific error per each affected hold.
    '''
    errlist = {}
    if fd is None:
        fd = -1
    nvlist = nvlist_in(holds)
    with nvlist_out(errlist) as errlist_nvlist:
        ret = _lib.lzc_hold(nvlist, fd, errlist_nvlist)
    errors.lzc_hold_translate_errors(ret, errlist, holds, fd)
    # If there is no error (no exception raised by _handleErrList), but errlist
    # is not empty, then it contains missing snapshots.
    assert all(errlist[x] == errno.ENOENT for x in errlist)
    return list(errlist.keys())


def lzc_release(holds):
    '''
    Release *user holds* on snapshots.

    If the snapshot has been marked for
    deferred destroy (by lzc_destroy_snaps(defer=B_TRUE)), it does not have
    any clones, and all the user holds are removed, then the snapshot will be
    destroyed.

    The snapshots must all be in the same pool.

    :param holds: a ``dict`` where keys are snapshot names and values are
        lists of hold tags to remove.
    :type holds: dict of bytes : list of bytes
    :return: a list of any snapshots that do not exist and of any tags that do
        not exist for existing snapshots.
        Such tags are qualified with a corresponding snapshot name using the
        following format :file:`{pool}/{fs}@{snap}#{tag}`
    :rtype: list of bytes

    :raises HoldReleaseFailure: if one or more existing holds could not be
        released.

    Holds which failed to release because they didn't exist will have an entry
    added to errlist, but will not cause an overall failure.

    This call is success if ``holds`` was empty or all holds that
    existed, were successfully removed.
    Otherwise an exception will be raised.
    '''
    errlist = {}
    holds_dict = {}
    for snap in holds:
        hold_list = holds[snap]
        if not isinstance(hold_list, list):
            raise TypeError('holds must be in a list')
        holds_dict[snap] = {hold: None for hold in hold_list}
    nvlist = nvlist_in(holds_dict)
    with nvlist_out(errlist) as errlist_nvlist:
        ret = _lib.lzc_release(nvlist, errlist_nvlist)
    errors.lzc_release_translate_errors(ret, errlist, holds)
    # If there is no error (no exception raised by _handleErrList), but errlist
    # is not empty, then it contains missing snapshots and tags.
    assert all(errlist[x] == errno.ENOENT for x in errlist)
    return list(errlist.keys())


def lzc_get_holds(snapname):
    '''
    Retrieve list of *user holds* on the specified snapshot.

    :param bytes snapname: the name of the snapshot.
    :return: holds on the snapshot along with their creation times
        in seconds since the epoch
    :rtype: dict of bytes : int
    '''
    holds = {}
    with nvlist_out(holds) as nvlist:
        ret = _lib.lzc_get_holds(snapname, nvlist)
    errors.lzc_get_holds_translate_error(ret, snapname)
    return holds


def lzc_send(snapname, fromsnap, fd, flags=None):
    '''
    Generate a zfs send stream for the specified snapshot and write it to
    the specified file descriptor.

    :param bytes snapname: the name of the snapshot to send.
    :param fromsnap: if not None the name of the starting snapshot
        for the incremental stream.
    :type fromsnap: bytes or None
    :param int fd: the file descriptor to write the send stream to.
    :param flags: the flags that control what enhanced features can be used in
        the stream.
    :type flags: list of bytes

    :raises SnapshotNotFound: if either the starting snapshot is not `None` and
        does not exist, or if the ending snapshot does not exist.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    :raises SnapshotMismatch: if ``fromsnap`` is not an ancestor snapshot of
        ``snapname``.
    :raises PoolsDiffer: if the snapshots belong to different pools.
    :raises IOError: if an input / output error occurs while writing to ``fd``.
    :raises UnknownStreamFeature: if the ``flags`` contain an unknown flag
        name.

    If ``fromsnap`` is None, a full (non-incremental) stream will be sent.
    If ``fromsnap`` is not None, it must be the full name of a snapshot or
    bookmark to send an incremental from, e.g.
    :file:`{pool}/{fs}@{earlier_snap}` or :file:`{pool}/{fs}#{earlier_bmark}`.

    The specified snapshot or bookmark must represent an earlier point in the
    history of ``snapname``.
    It can be an earlier snapshot in the same filesystem or zvol as
    ``snapname``, or it can be the origin of ``snapname``'s filesystem, or an
    earlier snapshot in the origin, etc.
    ``fromsnap`` must be strictly an earlier snapshot, specifying the same
    snapshot as both ``fromsnap`` and ``snapname`` is an error.

    If ``flags`` contains *"large_blocks"*, the stream is permitted
    to contain ``DRR_WRITE`` records with ``drr_length`` > 128K,
    and ``DRR_OBJECT`` records with ``drr_blksz`` > 128K.

    If ``flags`` contains *"embedded_data"*, the stream is permitted
    to contain ``DRR_WRITE_EMBEDDED`` records with
    ``drr_etype`` == ``BP_EMBEDDED_TYPE_DATA``,
    which the receiving system must support (as indicated by support
    for the *embedded_data* feature).

    If ``flags`` contains *"compress"*, the stream is generated by using
    compressed WRITE records for blocks which are compressed on disk and
    in memory.  If the *lz4_compress* feature is active on the sending
    system, then the receiving system must have that feature enabled as well.

    If ``flags`` contains *"raw"*, the stream is generated, for encrypted
    datasets, by sending data exactly as it exists on disk.  This allows
    backups to be taken even if encryption keys are not currently loaded.

    .. note::
        ``lzc_send`` can actually accept a filesystem name as the ``snapname``.
        In that case ``lzc_send`` acts as if a temporary snapshot was created
        after the start of the call and before the stream starts being
        produced.

    .. note::
        ``lzc_send`` does not return until all of the stream is written to
        ``fd``.

    .. note::
        ``lzc_send`` does *not* close ``fd`` upon returning.
    '''
    if fromsnap is not None:
        c_fromsnap = fromsnap
    else:
        c_fromsnap = _ffi.NULL
    c_flags = 0
    if flags is None:
        flags = []
    for flag in flags:
        c_flag = {
            'embedded_data': _lib.LZC_SEND_FLAG_EMBED_DATA,
            'large_blocks': _lib.LZC_SEND_FLAG_LARGE_BLOCK,
            'compress': _lib.LZC_SEND_FLAG_COMPRESS,
            'raw': _lib.LZC_SEND_FLAG_RAW,
        }.get(flag)
        if c_flag is None:
            raise exceptions.UnknownStreamFeature(flag)
        c_flags |= c_flag

    ret = _lib.lzc_send(snapname, c_fromsnap, fd, c_flags)
    errors.lzc_send_translate_error(ret, snapname, fromsnap, fd, flags)


def lzc_send_space(snapname, fromsnap=None, flags=None):
    '''
    Estimate size of a full or incremental backup stream
    given the optional starting snapshot and the ending snapshot.

    :param bytes snapname: the name of the snapshot for which the estimate
        should be done.
    :param fromsnap: the optional starting snapshot name.
        If not `None` then an incremental stream size is estimated, otherwise
        a full stream is estimated.
    :type fromsnap: `bytes` or `None`
    :param flags: the flags that control what enhanced features can be used
        in the stream.
    :type flags: list of bytes

    :return: the estimated stream size, in bytes.
    :rtype: `int` or `long`

    :raises SnapshotNotFound: if either the starting snapshot is not `None` and
        does not exist, or if the ending snapshot does not exist.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    :raises SnapshotMismatch: if ``fromsnap`` is not an ancestor snapshot of
        ``snapname``.
    :raises PoolsDiffer: if the snapshots belong to different pools.

    ``fromsnap``, if not ``None``,  must be strictly an earlier snapshot,
    specifying the same snapshot as both ``fromsnap`` and ``snapname`` is an
    error.
    '''
    if fromsnap is not None:
        c_fromsnap = fromsnap
    else:
        c_fromsnap = _ffi.NULL
    c_flags = 0
    if flags is None:
        flags = []
    for flag in flags:
        c_flag = {
            'embedded_data': _lib.LZC_SEND_FLAG_EMBED_DATA,
            'large_blocks': _lib.LZC_SEND_FLAG_LARGE_BLOCK,
            'compress': _lib.LZC_SEND_FLAG_COMPRESS,
            'raw': _lib.LZC_SEND_FLAG_RAW,
        }.get(flag)
        if c_flag is None:
            raise exceptions.UnknownStreamFeature(flag)
        c_flags |= c_flag
    valp = _ffi.new('uint64_t *')

    ret = _lib.lzc_send_space(snapname, c_fromsnap, c_flags, valp)
    errors.lzc_send_space_translate_error(ret, snapname, fromsnap)
    return int(valp[0])


def lzc_receive(snapname, fd, force=False, raw=False, origin=None, props=None):
    '''
    Receive from the specified ``fd``, creating the specified snapshot.

    :param bytes snapname: the name of the snapshot to create.
    :param int fd: the file descriptor from which to read the stream.
    :param bool force: whether to roll back or destroy the target filesystem
        if that is required to receive the stream.
    :param bool raw: whether this is a "raw" stream.
    :param origin: the optional origin snapshot name if the stream is for a
        clone.
    :type origin: bytes or None
    :param props: the properties to set on the snapshot as *received*
        properties.
    :type props: dict of bytes : Any

    :raises IOError: if an input / output error occurs while reading from the
        ``fd``.
    :raises DatasetExists: if the snapshot named ``snapname`` already exists.
    :raises DatasetExists: if the stream is a full stream and the destination
        filesystem already exists.
    :raises DatasetExists: if ``force`` is `True` but the destination
        filesystem could not be rolled back to a matching snapshot because a
        newer snapshot exists and it is an origin of a cloned filesystem.
    :raises StreamMismatch: if an incremental stream is received and the latest
        snapshot of the destination filesystem does not match the source
        snapshot of the stream.
    :raises StreamMismatch: if a full stream is received and the destination
        filesystem already exists and it has at least one snapshot, and
        ``force`` is `False`.
    :raises StreamMismatch: if an incremental clone stream is received but the
        specified ``origin`` is not the actual received origin.
    :raises DestinationModified: if an incremental stream is received and the
        destination filesystem has been modified since the last snapshot and
        ``force`` is `False`.
    :raises DestinationModified: if a full stream is received and the
        destination filesystem already exists and it does not have any
        snapshots, and ``force`` is `False`.
    :raises DatasetNotFound: if the destination filesystem and its parent do
        not exist.
    :raises DatasetNotFound: if the ``origin`` is not `None` and does not
        exist.
    :raises DatasetBusy: if ``force`` is `True` but the destination filesystem
        could not be rolled back to a matching snapshot because a newer
        snapshot is held and could not be destroyed.
    :raises DatasetBusy: if another receive operation is being performed on the
        destination filesystem.
    :raises BadStream: if the stream is corrupt or it is not recognized or it
        is a compound stream or it is a clone stream, but ``origin`` is `None`.
    :raises BadStream: if a clone stream is received and the destination
        filesystem already exists.
    :raises StreamFeatureNotSupported: if the stream has a feature that is not
        supported on this side.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    :raises WrongParent: if the parent dataset of the received destination is
        not a filesystem (e.g. ZVOL)

    .. note::
        The ``origin`` is ignored if the actual stream is an incremental stream
        that is not a clone stream and the destination filesystem exists.
        If the stream is a full stream and the destination filesystem does not
        exist then the ``origin`` is checked for existence: if it does not
        exist :exc:`.DatasetNotFound` is raised, otherwise
        :exc:`.StreamMismatch` is raised, because that snapshot can not have
        any relation to the stream.

    .. note::
        If ``force`` is `True` and the stream is incremental then the
        destination filesystem is rolled back to a matching source snapshot if
        necessary. Intermediate snapshots are destroyed in that case.

        However, none of the existing snapshots may have the same name as
        ``snapname`` even if such a snapshot were to be destroyed.
        The existing ``snapname`` snapshot always causes
        :exc:`.SnapshotExists` to be raised.

        If ``force`` is `True` and the stream is a full stream then the
        destination filesystem is replaced with the received filesystem unless
        the former has any snapshots.  This prevents the destination filesystem
        from being rolled back / replaced.

    .. note::
        This interface does not work on dedup'd streams
        (those with ``DMU_BACKUP_FEATURE_DEDUP``).

    .. note::
        ``lzc_receive`` does not return until all of the stream is read from
        ``fd`` and applied to the pool.

    .. note::
        ``lzc_receive`` does *not* close ``fd`` upon returning.
    '''

    if origin is not None:
        c_origin = origin
    else:
        c_origin = _ffi.NULL
    if props is None:
        props = {}
    nvlist = nvlist_in(props)
    ret = _lib.lzc_receive(snapname, nvlist, c_origin, force, raw, fd)
    errors.lzc_receive_translate_errors(
        ret, snapname, fd, force, raw, False, False, origin, None
    )


lzc_recv = lzc_receive


def lzc_exists(name):
    '''
    Check if a dataset (a filesystem, or a volume, or a snapshot)
    with the given name exists.

    :param bytes name: the dataset name to check.
    :return: `True` if the dataset exists, `False` otherwise.
    :rtype: bool

    .. note::
        ``lzc_exists`` can not be used to check for existence of bookmarks.
    '''
    ret = _lib.lzc_exists(name)
    return bool(ret)


@_uncommitted()
def lzc_change_key(fsname, crypt_cmd, props=None, key=None):
    '''
    Change encryption key on the specified dataset.

    :param bytes fsname: the name of the dataset.
    :param str crypt_cmd: the encryption "command" to be executed, currently
        supported values are "new_key", "inherit", "force_new_key" and
        "force_inherit".
    :param props: a `dict` of encryption-related property name-value pairs;
        only "keyformat", "keylocation" and "pbkdf2iters" are supported
        (empty by default).
    :type props: dict of bytes:Any
    :param key: dataset encryption key data (empty by default).
    :type key: bytes

    :raises PropertyInvalid: if ``props`` contains invalid values.
    :raises FilesystemNotFound: if the dataset does not exist.
    :raises UnknownCryptCommand: if ``crypt_cmd`` is invalid.
    :raises EncryptionKeyNotLoaded: if the encryption key is not currently
        loaded and therefore cannot be changed.
    '''
    if props is None:
        props = {}
    if key is None:
        key = b""
    else:
        key = bytes(key)
    cmd = {
        'new_key': _lib.DCP_CMD_NEW_KEY,
        'inherit': _lib.DCP_CMD_INHERIT,
        'force_new_key': _lib.DCP_CMD_FORCE_NEW_KEY,
        'force_inherit': _lib.DCP_CMD_FORCE_INHERIT,
    }.get(crypt_cmd)
    if cmd is None:
        raise exceptions.UnknownCryptCommand(crypt_cmd)
    nvlist = nvlist_in(props)
    ret = _lib.lzc_change_key(fsname, cmd, nvlist, key, len(key))
    errors.lzc_change_key_translate_error(ret, fsname)


@_uncommitted()
def lzc_load_key(fsname, noop, key):
    '''
    Load or verify encryption key on the specified dataset.

    :param bytes fsname: the name of the dataset.
    :param bool noop: if `True` the encryption key will only be verified,
        not loaded.
    :param key: dataset encryption key data.
    :type key: bytes

    :raises FilesystemNotFound: if the dataset does not exist.
    :raises EncryptionKeyAlreadyLoaded: if the encryption key is already
        loaded.
    :raises EncryptionKeyInvalid: if the encryption key provided is incorrect.
    '''
    ret = _lib.lzc_load_key(fsname, noop, key, len(key))
    errors.lzc_load_key_translate_error(ret, fsname, noop)


@_uncommitted()
def lzc_unload_key(fsname):
    '''
    Unload encryption key from the specified dataset.

    :param bytes fsname: the name of the dataset.

    :raises FilesystemNotFound: if the dataset does not exist.
    :raises DatasetBusy: if the encryption key is still being used. This
        usually occurs when the dataset is mounted.
    :raises EncryptionKeyNotLoaded: if the encryption key is not currently
        loaded.
    '''
    ret = _lib.lzc_unload_key(fsname)
    errors.lzc_unload_key_translate_error(ret, fsname)


def lzc_channel_program(
    poolname, program, instrlimit=ZCP_DEFAULT_INSTRLIMIT,
    memlimit=ZCP_DEFAULT_MEMLIMIT, params=None
):
    '''
    Executes a script as a ZFS channel program on pool ``poolname``.

    :param bytes poolname: the name of the pool.
    :param bytes program: channel program text.
    :param int instrlimit: execution time limit, in milliseconds.
    :param int memlimit: execution memory limit, in bytes.
    :param bytes params: a `list` of parameters passed to the channel program
        (empty by default).
    :type params: dict of bytes:Any
    :return: a dictionary of result values procuced by the channel program,
        if any.
    :rtype: dict

    :raises PoolNotFound: if the pool does not exist.
    :raises ZCPLimitInvalid: if either instruction or memory limit are invalid.
    :raises ZCPSyntaxError: if the channel program contains syntax errors.
    :raises ZCPTimeout: if the channel program took too long to execute.
    :raises ZCPSpaceError: if the channel program exhausted the memory limit.
    :raises ZCPMemoryError: if the channel program return value was too large.
    :raises ZCPPermissionError: if the user lacks the permission to run the
        channel program. Channel programs must be run as root.
    :raises ZCPRuntimeError: if the channel program encountered a runtime
        error.
    '''
    output = {}
    params_nv = nvlist_in({b"argv": params})
    with nvlist_out(output) as outnvl:
        ret = _lib.lzc_channel_program(
            poolname, program, instrlimit, memlimit, params_nv, outnvl)
    errors.lzc_channel_program_translate_error(
        ret, poolname, output.get(b"error"))
    return output.get(b"return")


def lzc_channel_program_nosync(
    poolname, program, instrlimit=ZCP_DEFAULT_INSTRLIMIT,
    memlimit=ZCP_DEFAULT_MEMLIMIT, params=None
):
    '''
    Executes a script as a read-only ZFS channel program on pool ``poolname``.
    A read-only channel program works programmatically the same way as a
    normal channel program executed with
    :func:`lzc_channel_program`. The only difference is it runs exclusively in
    open-context and therefore can return faster.
    The downside to that, is that the program cannot change on-disk state by
    calling functions from the zfs.sync submodule.

    :param bytes poolname: the name of the pool.
    :param bytes program: channel program text.
    :param int instrlimit: execution time limit, in milliseconds.
    :param int memlimit: execution memory limit, in bytes.
    :param bytes params: a `list` of parameters passed to the channel program
        (empty by default).
    :type params: dict of bytes:Any
    :return: a dictionary of result values procuced by the channel program,
        if any.
    :rtype: dict

    :raises PoolNotFound: if the pool does not exist.
    :raises ZCPLimitInvalid: if either instruction or memory limit are invalid.
    :raises ZCPSyntaxError: if the channel program contains syntax errors.
    :raises ZCPTimeout: if the channel program took too long to execute.
    :raises ZCPSpaceError: if the channel program exhausted the memory limit.
    :raises ZCPMemoryError: if the channel program return value was too large.
    :raises ZCPPermissionError: if the user lacks the permission to run the
        channel program. Channel programs must be run as root.
    :raises ZCPRuntimeError: if the channel program encountered a runtime
        error.
    '''
    output = {}
    params_nv = nvlist_in({b"argv": params})
    with nvlist_out(output) as outnvl:
        ret = _lib.lzc_channel_program_nosync(
            poolname, program, instrlimit, memlimit, params_nv, outnvl)
    errors.lzc_channel_program_translate_error(
        ret, poolname, output.get(b"error"))
    return output.get(b"return")


def lzc_receive_resumable(
    snapname, fd, force=False, raw=False, origin=None, props=None
):
    '''
    Like :func:`lzc_receive`, but if the receive fails due to premature stream
    termination, the intermediate state will be preserved on disk.  In this
    case, ECKSUM will be returned.  The receive may subsequently be resumed
    with a resuming send stream generated by lzc_send_resume().

    :param bytes snapname: the name of the snapshot to create.
    :param int fd: the file descriptor from which to read the stream.
    :param bool force: whether to roll back or destroy the target filesystem
        if that is required to receive the stream.
    :param bool raw: whether this is a "raw" stream.
    :param origin: the optional origin snapshot name if the stream is for a
        clone.
    :type origin: bytes or None
    :param props: the properties to set on the snapshot as *received*
        properties.
    :type props: dict of bytes : Any

    :raises IOError: if an input / output error occurs while reading from the
        ``fd``.
    :raises DatasetExists: if the snapshot named ``snapname`` already exists.
    :raises DatasetExists: if the stream is a full stream and the destination
        filesystem already exists.
    :raises DatasetExists: if ``force`` is `True` but the destination
        filesystem could not be rolled back to a matching snapshot because a
        newer snapshot exists and it is an origin of a cloned filesystem.
    :raises StreamMismatch: if an incremental stream is received and the latest
        snapshot of the destination filesystem does not match the source
        snapshot of the stream.
    :raises StreamMismatch: if a full stream is received and the destination
        filesystem already exists and it has at least one snapshot, and
        ``force`` is `False`.
    :raises StreamMismatch: if an incremental clone stream is received but the
        specified ``origin`` is not the actual received origin.
    :raises DestinationModified: if an incremental stream is received and the
        destination filesystem has been modified since the last snapshot and
        ``force`` is `False`.
    :raises DestinationModified: if a full stream is received and the
        destination filesystem already exists and it does not have any
        snapshots, and ``force`` is `False`.
    :raises DatasetNotFound: if the destination filesystem and its parent do
        not exist.
    :raises DatasetNotFound: if the ``origin`` is not `None` and does not
        exist.
    :raises DatasetBusy: if ``force`` is `True` but the destination filesystem
        could not be rolled back to a matching snapshot because a newer
        snapshot is held and could not be destroyed.
    :raises DatasetBusy: if another receive operation is being performed on the
        destination filesystem.
    :raises BadStream: if the stream is corrupt or it is not recognized or it
        is a compound stream or it is a clone stream, but ``origin`` is `None`.
    :raises BadStream: if a clone stream is received and the destination
        filesystem already exists.
    :raises StreamFeatureNotSupported: if the stream has a feature that is not
        supported on this side.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    '''

    if origin is not None:
        c_origin = origin
    else:
        c_origin = _ffi.NULL
    if props is None:
        props = {}
    nvlist = nvlist_in(props)
    ret = _lib.lzc_receive_resumable(
        snapname, nvlist, c_origin, force, raw, fd)
    errors.lzc_receive_translate_errors(
        ret, snapname, fd, force, raw, False, False, origin, None)


def lzc_receive_with_header(
    snapname, fd, begin_record, force=False, resumable=False, raw=False,
    origin=None, props=None
):
    '''
    Like :func:`lzc_receive`, but allows the caller to read the begin record
    and then to pass it in.

    That could be useful if the caller wants to derive, for example,
    the snapname or the origin parameters based on the information contained in
    the begin record.
    :func:`receive_header` can be used to receive the begin record from the
    file descriptor.

    :param bytes snapname: the name of the snapshot to create.
    :param int fd: the file descriptor from which to read the stream.
    :param begin_record: the stream's begin record.
    :type begin_record: ``cffi`` `CData` representing the dmu_replay_record_t
        structure.
    :param bool force: whether to roll back or destroy the target filesystem
        if that is required to receive the stream.
    :param bool resumable: whether this stream should be treated as resumable.
        If the receive fails due to premature stream termination, the
        intermediate state will be preserved on disk and may subsequently be
        resumed with :func:`lzc_send_resume`.
    :param bool raw: whether this is a "raw" stream.
    :param origin: the optional origin snapshot name if the stream is for a
        clone.
    :type origin: bytes or None
    :param props: the properties to set on the snapshot as *received*
        properties.
    :type props: dict of bytes : Any

    :raises IOError: if an input / output error occurs while reading from the
        ``fd``.
    :raises DatasetExists: if the snapshot named ``snapname`` already exists.
    :raises DatasetExists: if the stream is a full stream and the destination
        filesystem already exists.
    :raises DatasetExists: if ``force`` is `True` but the destination
        filesystem could not be rolled back to a matching snapshot because a
        newer snapshot exists and it is an origin of a cloned filesystem.
    :raises StreamMismatch: if an incremental stream is received and the latest
        snapshot of the destination filesystem does not match the source
        snapshot of the stream.
    :raises StreamMismatch: if a full stream is received and the destination
        filesystem already exists and it has at least one snapshot, and
        ``force`` is `False`.
    :raises StreamMismatch: if an incremental clone stream is received but the
        specified ``origin`` is not the actual received origin.
    :raises DestinationModified: if an incremental stream is received and the
        destination filesystem has been modified since the last snapshot and
        ``force`` is `False`.
    :raises DestinationModified: if a full stream is received and the
        destination filesystem already exists and it does not have any
        snapshots, and ``force`` is `False`.
    :raises DatasetNotFound: if the destination filesystem and its parent do
        not exist.
    :raises DatasetNotFound: if the ``origin`` is not `None` and does not
        exist.
    :raises DatasetBusy: if ``force`` is `True` but the destination filesystem
        could not be rolled back to a matching snapshot because a newer
        snapshot is held and could not be destroyed.
    :raises DatasetBusy: if another receive operation is being performed on the
        destination filesystem.
    :raises BadStream: if the stream is corrupt or it is not recognized or it
        is a compound stream or it is a clone stream, but ``origin`` is `None`.
    :raises BadStream: if a clone stream is received and the destination
        filesystem already exists.
    :raises StreamFeatureNotSupported: if the stream has a feature that is not
        supported on this side.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    '''

    if origin is not None:
        c_origin = origin
    else:
        c_origin = _ffi.NULL
    if props is None:
        props = {}
    nvlist = nvlist_in(props)
    ret = _lib.lzc_receive_with_header(
        snapname, nvlist, c_origin, force, resumable, raw, fd, begin_record)
    errors.lzc_receive_translate_errors(
        ret, snapname, fd, force, raw, False, False, origin, None)


def receive_header(fd):
    '''
    Read the begin record of the ZFS backup stream from the given file
    descriptor.

    This is a helper function for :func:`lzc_receive_with_header`.

    :param int fd: the file descriptor from which to read the stream.
    :return: a tuple with two elements where the first one is a Python `dict`
        representing the fields of the begin record and the second one is an
        opaque object suitable for passing to :func:`lzc_receive_with_header`.
    :raises IOError: if an input / output error occurs while reading from the
        ``fd``.

    At present the following fields can be of interest in the header:

    drr_toname : bytes
        the name of the snapshot for which the stream has been created
    drr_toguid : integer
        the GUID of the snapshot for which the stream has been created
    drr_fromguid : integer
        the GUID of the starting snapshot in the case the stream is
        incremental, zero otherwise
    drr_flags : integer
        the flags describing the stream's properties
    drr_type : integer
        the type of the dataset for which the stream has been created
        (volume, filesystem)
    '''
    # read sizeof(dmu_replay_record_t) bytes directly into the memory backing
    # 'record'
    record = _ffi.new("dmu_replay_record_t *")
    _ffi.buffer(record)[:] = os.read(fd, _ffi.sizeof(record[0]))
    # get drr_begin member and its representation as a Python dict
    drr_begin = record.drr_u.drr_begin
    header = {}
    for field, descr in _ffi.typeof(drr_begin).fields:
        if descr.type.kind == 'primitive':
            header[field] = getattr(drr_begin, field)
        elif descr.type.kind == 'enum':
            header[field] = getattr(drr_begin, field)
        elif descr.type.kind == 'array' and descr.type.item.cname == 'char':
            header[field] = _ffi.string(getattr(drr_begin, field))
        else:
            raise TypeError(
                'Unexpected field type in drr_begin: ' + str(descr.type))
    return (header, record)


@_uncommitted()
def lzc_receive_one(
    snapname, fd, begin_record, force=False, resumable=False, raw=False,
    origin=None, props=None, cleanup_fd=-1, action_handle=0
):
    '''
    Like :func:`lzc_receive`, but allows the caller to pass all supported
    arguments and retrieve all values returned.  The only additional input
    parameter is 'cleanup_fd' which is used to set a cleanup-on-exit file
    descriptor.

    :param bytes snapname: the name of the snapshot to create.
    :param int fd: the file descriptor from which to read the stream.
    :param begin_record: the stream's begin record.
    :type begin_record: ``cffi`` `CData` representing the dmu_replay_record_t
        structure.
    :param bool force: whether to roll back or destroy the target filesystem
        if that is required to receive the stream.
    :param bool resumable: whether this stream should be treated as resumable.
        If the receive fails due to premature stream termination, the
        intermediate state will be preserved on disk and may subsequently be
        resumed with :func:`lzc_send_resume`.
    :param bool raw: whether this is a "raw" stream.
    :param origin: the optional origin snapshot name if the stream is for a
        clone.
    :type origin: bytes or None
    :param props: the properties to set on the snapshot as *received*
        properties.
    :type props: dict of bytes : Any
    :param int cleanup_fd: file descriptor used to set a cleanup-on-exit file
        descriptor.
    :param int action_handle: variable used to pass the handle for guid/ds
        mapping: this should be set to zero on first call and will contain an
        updated handle on success, which should be passed in subsequent calls.

    :return: a tuple with two elements where the first one is the number of
        bytes read from the file descriptor and the second one is the
        action_handle return value.

    :raises IOError: if an input / output error occurs while reading from the
        ``fd``.
    :raises DatasetExists: if the snapshot named ``snapname`` already exists.
    :raises DatasetExists: if the stream is a full stream and the destination
        filesystem already exists.
    :raises DatasetExists: if ``force`` is `True` but the destination
        filesystem could not be rolled back to a matching snapshot because a
        newer snapshot exists and it is an origin of a cloned filesystem.
    :raises StreamMismatch: if an incremental stream is received and the latest
        snapshot of the destination filesystem does not match the source
        snapshot of the stream.
    :raises StreamMismatch: if a full stream is received and the destination
        filesystem already exists and it has at least one snapshot, and
        ``force`` is `False`.
    :raises StreamMismatch: if an incremental clone stream is received but the
        specified ``origin`` is not the actual received origin.
    :raises DestinationModified: if an incremental stream is received and the
        destination filesystem has been modified since the last snapshot and
        ``force`` is `False`.
    :raises DestinationModified: if a full stream is received and the
        destination filesystem already exists and it does not have any
        snapshots, and ``force`` is `False`.
    :raises DatasetNotFound: if the destination filesystem and its parent do
        not exist.
    :raises DatasetNotFound: if the ``origin`` is not `None` and does not
        exist.
    :raises DatasetBusy: if ``force`` is `True` but the destination filesystem
        could not be rolled back to a matching snapshot because a newer
        snapshot is held and could not be destroyed.
    :raises DatasetBusy: if another receive operation is being performed on the
        destination filesystem.
    :raises BadStream: if the stream is corrupt or it is not recognized or it
        is a compound stream or it is a clone stream, but ``origin`` is `None`.
    :raises BadStream: if a clone stream is received and the destination
        filesystem already exists.
    :raises StreamFeatureNotSupported: if the stream has a feature that is not
        supported on this side.
    :raises ReceivePropertyFailure: if one or more of the specified properties
        is invalid or has an invalid type or value.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    '''

    if origin is not None:
        c_origin = origin
    else:
        c_origin = _ffi.NULL
    if action_handle is not None:
        c_action_handle = _ffi.new("uint64_t *")
    else:
        c_action_handle = _ffi.NULL
    c_read_bytes = _ffi.new("uint64_t *")
    c_errflags = _ffi.new("uint64_t *")
    if props is None:
        props = {}
    nvlist = nvlist_in(props)
    properrs = {}
    with nvlist_out(properrs) as c_errors:
        ret = _lib.lzc_receive_one(
            snapname, nvlist, c_origin, force, resumable, raw, fd,
            begin_record, cleanup_fd, c_read_bytes, c_errflags,
            c_action_handle, c_errors)
    errors.lzc_receive_translate_errors(
        ret, snapname, fd, force, raw, False, False, origin, properrs)
    return (int(c_read_bytes[0]), action_handle)


@_uncommitted()
def lzc_receive_with_cmdprops(
    snapname, fd, begin_record, force=False, resumable=False, raw=False,
    origin=None, props=None, cmdprops=None, key=None, cleanup_fd=-1,
    action_handle=0
):
    '''
    Like :func:`lzc_receive_one`, but allows the caller to pass an additional
    'cmdprops' argument. The 'cmdprops' nvlist contains both override
    ('zfs receive -o') and exclude ('zfs receive -x') properties.

    :param bytes snapname: the name of the snapshot to create.
    :param int fd: the file descriptor from which to read the stream.
    :param begin_record: the stream's begin record.
    :type begin_record: ``cffi`` `CData` representing the dmu_replay_record_t
        structure.
    :param bool force: whether to roll back or destroy the target filesystem
        if that is required to receive the stream.
    :param bool resumable: whether this stream should be treated as resumable.
        If the receive fails due to premature stream termination, the
        intermediate state will be preserved on disk and may subsequently be
        resumed with :func:`lzc_send_resume`.
    :param bool raw: whether this is a "raw" stream.
    :param origin: the optional origin snapshot name if the stream is for a
        clone.
    :type origin: bytes or None
    :param props: the properties to set on the snapshot as *received*
        properties.
    :type props: dict of bytes : Any
    :param cmdprops: the properties to set on the snapshot as local overrides
        to *received* properties. `bool` values are forcefully inherited while
        every other value is set locally as if the command "zfs set" was
        invoked immediately before the receive.
    :type cmdprops: dict of bytes : Any
    :param key: raw bytes representing user's wrapping key
    :type key: bytes
    :param int cleanup_fd: file descriptor used to set a cleanup-on-exit file
        descriptor.
    :param int action_handle: variable used to pass the handle for guid/ds
        mapping: this should be set to zero on first call and will contain an
        updated handle on success, it should be passed in subsequent calls.

    :return: a tuple with two elements where the first one is the number of
        bytes read from the file descriptor and the second one is the
        action_handle return value.

    :raises IOError: if an input / output error occurs while reading from the
        ``fd``.
    :raises DatasetExists: if the snapshot named ``snapname`` already exists.
    :raises DatasetExists: if the stream is a full stream and the destination
        filesystem already exists.
    :raises DatasetExists: if ``force`` is `True` but the destination
        filesystem could not be rolled back to a matching snapshot because a
        newer snapshot exists and it is an origin of a cloned filesystem.
    :raises StreamMismatch: if an incremental stream is received and the latest
        snapshot of the destination filesystem does not match the source
        snapshot of the stream.
    :raises StreamMismatch: if a full stream is received and the destination
        filesystem already exists and it has at least one snapshot, and
        ``force`` is `False`.
    :raises StreamMismatch: if an incremental clone stream is received but the
        specified ``origin`` is not the actual received origin.
    :raises DestinationModified: if an incremental stream is received and the
        destination filesystem has been modified since the last snapshot and
        ``force`` is `False`.
    :raises DestinationModified: if a full stream is received and the
        destination filesystem already exists and it does not have any
        snapshots, and ``force`` is `False`.
    :raises DatasetNotFound: if the destination filesystem and its parent do
        not exist.
    :raises DatasetNotFound: if the ``origin`` is not `None` and does not
        exist.
    :raises DatasetBusy: if ``force`` is `True` but the destination filesystem
        could not be rolled back to a matching snapshot because a newer
        snapshot is held and could not be destroyed.
    :raises DatasetBusy: if another receive operation is being performed on the
        destination filesystem.
    :raises BadStream: if the stream is corrupt or it is not recognized or it
        is a compound stream or it is a clone stream, but ``origin`` is `None`.
    :raises BadStream: if a clone stream is received and the destination
        filesystem already exists.
    :raises StreamFeatureNotSupported: if the stream has a feature that is not
        supported on this side.
    :raises ReceivePropertyFailure: if one or more of the specified properties
        is invalid or has an invalid type or value.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    '''

    if origin is not None:
        c_origin = origin
    else:
        c_origin = _ffi.NULL
    if action_handle is not None:
        c_action_handle = _ffi.new("uint64_t *")
    else:
        c_action_handle = _ffi.NULL
    c_read_bytes = _ffi.new("uint64_t *")
    c_errflags = _ffi.new("uint64_t *")
    if props is None:
        props = {}
    if cmdprops is None:
        cmdprops = {}
    if key is None:
        key = b""
    else:
        key = bytes(key)

    nvlist = nvlist_in(props)
    cmdnvlist = nvlist_in(cmdprops)
    properrs = {}
    with nvlist_out(properrs) as c_errors:
        ret = _lib.lzc_receive_with_cmdprops(
            snapname, nvlist, cmdnvlist, key, len(key), c_origin,
            force, resumable, raw, fd, begin_record, cleanup_fd, c_read_bytes,
            c_errflags, c_action_handle, c_errors)
    errors.lzc_receive_translate_errors(
        ret, snapname, fd, force, raw, False, False, origin, properrs)
    return (int(c_read_bytes[0]), action_handle)


@_uncommitted()
def lzc_reopen(poolname, restart=True):
    '''
    Reopen a pool

    :param bytes poolname: the name of the pool.
    :param bool restart: whether to restart an in-progress scrub operation.

    :raises PoolNotFound: if the pool does not exist.
    '''
    ret = _lib.lzc_reopen(poolname, restart)
    errors.lzc_reopen_translate_error(ret, poolname)


def lzc_send_resume(
    snapname, fromsnap, fd, flags=None, resumeobj=0, resumeoff=0
):
    '''
    Resume a previously interrupted send operation generating a zfs send stream
    for the specified snapshot and writing it to the specified file descriptor.

    :param bytes snapname: the name of the snapshot to send.
    :param fromsnap: if not None the name of the starting snapshot
        for the incremental stream.
    :type fromsnap: bytes or None
    :param int fd: the file descriptor to write the send stream to.
    :param flags: the flags that control what enhanced features can be used in
        the stream.
    :type flags: list of bytes
    :param int resumeobj: the object number where this send stream should
        resume from.
    :param int resumeoff: the offset where this send stream should resume from.

    :raises SnapshotNotFound: if either the starting snapshot is not `None` and
        does not exist, or if the ending snapshot does not exist.
    :raises NameInvalid: if the name of either snapshot is invalid.
    :raises NameTooLong: if the name of either snapshot is too long.
    :raises SnapshotMismatch: if ``fromsnap`` is not an ancestor snapshot of
        ``snapname``.
    :raises PoolsDiffer: if the snapshots belong to different pools.
    :raises IOError: if an input / output error occurs while writing to ``fd``.
    :raises UnknownStreamFeature: if the ``flags`` contain an unknown flag
        name.

    .. note::
        See :func:`lzc_send` for more information.
    '''
    if fromsnap is not None:
        c_fromsnap = fromsnap
    else:
        c_fromsnap = _ffi.NULL
    c_flags = 0
    if flags is None:
        flags = []
    for flag in flags:
        c_flag = {
            'embedded_data': _lib.LZC_SEND_FLAG_EMBED_DATA,
            'large_blocks': _lib.LZC_SEND_FLAG_LARGE_BLOCK,
            'compress': _lib.LZC_SEND_FLAG_COMPRESS,
            'raw': _lib.LZC_SEND_FLAG_RAW,
        }.get(flag)
        if c_flag is None:
            raise exceptions.UnknownStreamFeature(flag)
        c_flags |= c_flag

    ret = _lib.lzc_send_resume(
        snapname, c_fromsnap, fd, c_flags, uint64_t(resumeobj),
        uint64_t(resumeoff))
    errors.lzc_send_translate_error(ret, snapname, fromsnap, fd, flags)


@_uncommitted()
def lzc_sync(poolname, force=False):
    '''
    Forces all in-core dirty data to be written to the primary pool storage
    and not the ZIL.

    :param bytes poolname: the name of the pool.
    :param bool force: whether to force uberblock update even if there is no
        dirty data.

    :raises PoolNotFound: if the pool does not exist.

    .. note::
        This method signature is different from its C libzfs_core counterpart:
        `innvl` has been replaced by the `force` boolean and `outnvl` has been
        conveniently removed since it's not used.
    '''
    innvl = nvlist_in({b"force": force})
    with nvlist_out({}) as outnvl:
        ret = _lib.lzc_sync(poolname, innvl, outnvl)
    errors.lzc_sync_translate_error(ret, poolname)


def is_supported(func):
    '''
    Check whether C *libzfs_core* provides implementation required
    for the given Python wrapper.

    If `is_supported` returns ``False`` for the function, then
    calling the function would result in :exc:`NotImplementedError`.

    :param function func: the function to check.
    :return bool: whether the function can be used.
    '''
    fname = func.__name__
    if fname not in globals():
        raise ValueError(fname + ' is not from libzfs_core')
    if not callable(func):
        raise ValueError(fname + ' is not a function')
    if not fname.startswith("lzc_"):
        raise ValueError(fname + ' is not a libzfs_core API function')
    check_func = getattr(func, "_check_func", None)
    if check_func is not None:
        return is_supported(check_func)
    return getattr(_lib, fname, None) is not None


@_uncommitted()
def lzc_promote(name):
    '''
    Promotes the ZFS dataset.

    :param bytes name: the name of the dataset to promote.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises NameTooLong: if the dataset's origin has a snapshot that, if
        transferred to the dataset, would get a too long name.
    :raises NotClone: if the dataset is not a clone.
    :raises FilesystemNotFound: if the dataset does not exist.
    :raises SnapshotExists: if the dataset already has a snapshot with the same
        name as one of the origin's snapshots.
    '''
    ret = _lib.lzc_promote(name, _ffi.NULL, _ffi.NULL)
    errors.lzc_promote_translate_error(ret, name)


@_uncommitted()
def lzc_remap(name):
    '''
    Remaps the ZFS dataset.

    :param bytes name: the name of the dataset to remap.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises DatasetNotFound: if the dataset does not exist.
    :raises FeatureNotSupported: if the pool containing the dataset does not
        have the *obsolete_counts* feature enabled.
    '''
    ret = _lib.lzc_remap(name)
    errors.lzc_remap_translate_error(ret, name)


@_uncommitted()
def lzc_pool_checkpoint(name):
    '''
    Creates a checkpoint for the specified pool.

    :param bytes name: the name of the pool to create a checkpoint for.
    :raises CheckpointExists: if the pool already has a checkpoint.
    :raises CheckpointDiscarding: if ZFS is in the middle of discarding a
        checkpoint for this pool.
    :raises DeviceRemovalRunning: if a vdev is currently being removed.
    :raises DeviceTooBig: if one or more top-level vdevs exceed the maximum
        vdev size.
    '''
    ret = _lib.lzc_pool_checkpoint(name)
    errors.lzc_pool_checkpoint_translate_error(ret, name)


@_uncommitted()
def lzc_pool_checkpoint_discard(name):
    '''
    Discard the checkpoint from the specified pool.

    :param bytes name: the name of the pool to discard the checkpoint from.
    :raises CheckpointNotFound: if pool does not have a checkpoint.
    :raises CheckpointDiscarding: if ZFS is in the middle of discarding a
        checkpoint for this pool.
    '''
    ret = _lib.lzc_pool_checkpoint_discard(name)
    errors.lzc_pool_checkpoint_discard_translate_error(ret, name)


def lzc_rename(source, target):
    '''
    Rename the ZFS dataset.

    :param source name: the current name of the dataset to rename.
    :param target name: the new name of the dataset.
    :raises NameInvalid: if either the source or target name is invalid.
    :raises NameTooLong: if either the source or target name is too long.
    :raises NameTooLong: if a snapshot of the source would get a too long name
        after renaming.
    :raises FilesystemNotFound: if the source does not exist.
    :raises FilesystemNotFound: if the target's parent does not exist.
    :raises FilesystemExists: if the target already exists.
    :raises PoolsDiffer: if the source and target belong to different pools.
    :raises WrongParent: if the "new" parent dataset is not a filesystem
        (e.g. ZVOL)
    '''
    ret = _lib.lzc_rename(source, target)
    errors.lzc_rename_translate_error(ret, source, target)


def lzc_destroy(name):
    '''
    Destroy the ZFS dataset.

    :param bytes name: the name of the dataset to destroy.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises FilesystemNotFound: if the dataset does not exist.
    '''
    ret = _lib.lzc_destroy(name)
    errors.lzc_destroy_translate_error(ret, name)


@_uncommitted()
def lzc_inherit(name, prop):
    '''
    Inherit properties from a parent dataset of the given ZFS dataset.

    :param bytes name: the name of the dataset.
    :param bytes prop: the name of the property to inherit.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises DatasetNotFound: if the dataset does not exist.
    :raises PropertyInvalid: if one or more of the specified properties is
        invalid or has an invalid type or value.

    Inheriting a property actually resets it to its default value
    or removes it if it's a user property, so that the property could be
    inherited if it's inheritable.  If the property is not inheritable
    then it would just have its default value.

    This function can be used on snapshots to inherit user defined properties.
    '''
    ret = _lib.lzc_inherit(name, prop, _ffi.NULL)
    errors.lzc_inherit_prop_translate_error(ret, name, prop)


# As the extended API is not committed yet, the names of the new interfaces
# are not settled down yet.
# lzc_inherit_prop makes it clearer what is to be inherited.
lzc_inherit_prop = lzc_inherit


@_uncommitted()
def lzc_set_props(name, prop, val):
    '''
    Set properties of the ZFS dataset.

    :param bytes name: the name of the dataset.
    :param bytes prop: the name of the property.
    :param Any val: the value of the property.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises DatasetNotFound: if the dataset does not exist.
    :raises NoSpace: if the property controls a quota and the values is too
        small for that quota.
    :raises PropertyInvalid: if one or more of the specified properties is
        invalid or has an invalid type or value.

    This function can be used on snapshots to set user defined properties.

    .. note::
        An attempt to set a readonly / statistic property is ignored
        without reporting any error.
    '''
    props = {prop: val}
    props_nv = nvlist_in(props)
    ret = _lib.lzc_set_props(name, props_nv, _ffi.NULL, _ffi.NULL)
    errors.lzc_set_prop_translate_error(ret, name, prop, val)


# As the extended API is not committed yet, the names of the new interfaces
# are not settled down yet.
# It's not clear if atomically setting multiple properties is an achievable
# goal and an interface acting on multiple entities must do so atomically
# by convention.
# Being able to set a single property at a time is sufficient for ClusterHQ.
lzc_set_prop = lzc_set_props


@_uncommitted()
def lzc_list(name, options):
    '''
    List subordinate elements of the given dataset.

    This function can be used to list child datasets and snapshots of the given
    dataset.  The listed elements can be filtered by their type and by their
    depth relative to the starting dataset.

    :param bytes name: the name of the dataset to be listed, could be a
        snapshot or a dataset.
    :param options: a `dict` of the options that control the listing behavior.
    :type options: dict of bytes:Any
    :return: a pair of file descriptors the first of which can be used to read
        the listing.
    :rtype: tuple of (int, int)
    :raises DatasetNotFound: if the dataset does not exist.

    Two options are currently available:

    recurse : integer or None
        specifies depth of the recursive listing. If ``None`` the depth is not
        limited.
        Absence of this option means that only the given dataset is listed.

    type : dict of bytes:None
        specifies dataset types to include into the listing.
        Currently allowed keys are "filesystem", "volume", "snapshot".
        Absence of this option implies all types.

    The first of the returned file descriptors can be used to
    read the listing in a binary encoded format.  The data is
    a series of variable sized records each starting with a fixed
    size header, the header is followed by a serialized ``nvlist``.
    Each record describes a single element and contains the element's
    name as well as its properties.
    The file descriptor must be closed after reading from it.

    The second file descriptor represents a pipe end to which the
    kernel driver is writing information.  It should not be closed
    until all interesting information has been read and it must
    be explicitly closed afterwards.
    '''
    (rfd, wfd) = os.pipe()
    fcntl.fcntl(rfd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
    fcntl.fcntl(wfd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
    options = options.copy()
    options['fd'] = int32_t(wfd)
    opts_nv = nvlist_in(options)
    ret = _lib.lzc_list(name, opts_nv)
    if ret == errno.ESRCH:
        return (None, None)
    errors.lzc_list_translate_error(ret, name, options)
    return (rfd, wfd)


# Description of the binary format used to pass data from the kernel.
_PIPE_RECORD_FORMAT = 'IBBBB'
_PIPE_RECORD_SIZE = struct.calcsize(_PIPE_RECORD_FORMAT)


def _list(name, recurse=None, types=None):
    '''
    A wrapper for :func:`lzc_list` that hides details of working
    with the file descriptors and provides data in an easy to
    consume format.

    :param bytes name: the name of the dataset to be listed, could be a
        snapshot, a volume or a filesystem.
    :param recurse: specifies depth of the recursive listing. If ``None`` the
        depth is not limited.
    :param types: specifies dataset types to include into the listing.
        Currently allowed keys are "filesystem", "volume", "snapshot". ``None``
        is equivalent to specifying the type of the dataset named by `name`.
    :type types: list of bytes or None
    :type recurse: integer or None
    :return: a list of dictionaries each describing a single listed element.
    :rtype: list of dict
    '''
    options = {}

    # Convert types to a dict suitable for mapping to an nvlist.
    if types is not None:
        types = {x: None for x in types}
        options['type'] = types
    if recurse is None or recurse > 0:
        options['recurse'] = recurse

    # Note that other_fd is used by the kernel side to write
    # the data, so we have to keep that descriptor open until
    # we are done.
    # Also, we have to explicitly close the descriptor as the
    # kernel doesn't do that.
    (fd, other_fd) = lzc_list(name, options)
    if fd is None:
        return

    try:
        while True:
            record_bytes = os.read(fd, _PIPE_RECORD_SIZE)
            if not record_bytes:
                break
            (size, _, err, _, _) = struct.unpack(
                _PIPE_RECORD_FORMAT, record_bytes)
            if err == errno.ESRCH:
                break
            errors.lzc_list_translate_error(err, name, options)
            if size == 0:
                break
            data_bytes = os.read(fd, size)
            result = {}
            with nvlist_out(result) as nvp:
                ret = _lib.nvlist_unpack(data_bytes, size, nvp, 0)
            if ret != 0:
                raise exceptions.ZFSGenericError(
                    ret, None, "Failed to unpack list data")
            yield result
    finally:
        os.close(other_fd)
        os.close(fd)


@_uncommitted(lzc_list)
def lzc_get_props(name):
    '''
    Get properties of the ZFS dataset.

    :param bytes name: the name of the dataset.
    :raises DatasetNotFound: if the dataset does not exist.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :return: a dictionary mapping the property names to their values.
    :rtype: dict of bytes:Any

    .. note::
        The value of ``clones`` property is a `list` of clone names as byte
        strings.

    .. warning::
        The returned dictionary does not contain entries for properties
        with default values.  One exception is the ``mountpoint`` property
        for which the default value is derived from the dataset name.
    '''
    result = next(_list(name, recurse=0))
    is_snapshot = result['dmu_objset_stats']['dds_is_snapshot']
    result = result['properties']
    # In most cases the source of the property is uninteresting and the
    # value alone is sufficient.  One exception is the 'mountpoint'
    # property the final value of which is not the same as the inherited
    # value.
    mountpoint = result.get('mountpoint')
    if mountpoint is not None:
        mountpoint_src = mountpoint['source']
        mountpoint_val = mountpoint['value']
        # 'source' is the name of the dataset that has 'mountpoint' set
        # to a non-default value and from which the current dataset inherits
        # the property.  'source' can be the current dataset if its
        # 'mountpoint' is explicitly set.
        # 'source' can also be a special value like '$recvd', that case
        # is equivalent to the property being set on the current dataset.
        # Note that a normal mountpoint value should start with '/'
        # unlike the special values "none" and "legacy".
        if (mountpoint_val.startswith('/') and
                not mountpoint_src.startswith('$')):
            mountpoint_val = mountpoint_val + name[len(mountpoint_src):]
    elif not is_snapshot:
        mountpoint_val = '/' + name
    else:
        mountpoint_val = None
    result = {k: result[k]['value'] for k in result}
    if 'clones' in result:
        result['clones'] = list(result['clones'].keys())
    if mountpoint_val is not None:
        result['mountpoint'] = mountpoint_val
    return result


@_uncommitted(lzc_list)
def lzc_list_children(name):
    '''
    List the children of the ZFS dataset.

    :param bytes name: the name of the dataset.
    :return: an iterator that produces the names of the children.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises DatasetNotFound: if the dataset does not exist.

    .. warning::
        If the dataset does not exist, then the returned iterator would produce
        no results and no error is reported.
        That case is indistinguishable from the dataset having no children.

        An attempt to list children of a snapshot is silently ignored as well.
    '''
    children = []
    for entry in _list(name, recurse=1, types=['filesystem', 'volume']):
        child = entry['name']
        if child != name:
            children.append(child)

    return iter(children)


@_uncommitted(lzc_list)
def lzc_list_snaps(name):
    '''
    List the snapshots of the ZFS dataset.

    :param bytes name: the name of the dataset.
    :return: an iterator that produces the names of the snapshots.
    :raises NameInvalid: if the dataset name is invalid.
    :raises NameTooLong: if the dataset name is too long.
    :raises DatasetNotFound: if the dataset does not exist.

    .. warning::
        If the dataset does not exist, then the returned iterator would produce
        no results and no error is reported.
        That case is indistinguishable from the dataset having no snapshots.

        An attempt to list snapshots of a snapshot is silently ignored as well.
    '''
    snaps = []
    for entry in _list(name, recurse=1, types=['snapshot']):
        snap = entry['name']
        if snap != name:
            snaps.append(snap)

    return iter(snaps)


# TODO: a better way to init and uninit the library
def _initialize():
    class LazyInit(object):

        def __init__(self, lib):
            self._lib = lib
            self._inited = False
            self._lock = threading.Lock()

        def __getattr__(self, name):
            if not self._inited:
                with self._lock:
                    if not self._inited:
                        ret = self._lib.libzfs_core_init()
                        if ret != 0:
                            raise exceptions.ZFSInitializationFailed(ret)
                        self._inited = True
            return getattr(self._lib, name)

    return LazyInit(libzfs_core.lib)


_ffi = libzfs_core.ffi
_lib = _initialize()


# vim: softtabstop=4 tabstop=4 expandtab shiftwidth=4
