@contextmanager
    def reader(self, remote_snapshots=None):
        # The existing snapshot code uses Twisted, so we're not using it
        # in this iteration.  What's worse, though, is that it's not clear
        # if the current snapshot naming scheme makes any sense, and
        # moreover it violates abstraction boundaries. So as first pass
        # I'm just using UUIDs, and hopefully requirements will become
        # clearer as we iterate.
        snapshot = b"%s@%s" % (self.name, uuid4())
        check_call([b"zfs", b"snapshot", snapshot])

        # Determine whether there is a shared snapshot which can be used as the
        # basis for an incremental send.
        local_snapshots = list(
            Snapshot(name=name) for name in
            _parse_snapshots(
                check_output([b"zfs"] + _list_snapshots_command(self)),
                self
            ))

        if remote_snapshots is None:
            remote_snapshots = []

        latest_common_snapshot = _latest_common_snapshot(
            remote_snapshots, local_snapshots)

        if latest_common_snapshot is None:
            identifier = [snapshot]
        else:
            identifier = [
                b"-i",
                u"{}@{}".format(
                    self.name, latest_common_snapshot.name).encode("ascii"),
                snapshot,
            ]

        process = Popen([b"zfs", b"send"] + identifier, stdout=PIPE)
        try:
            yield process.stdout
        finally:
            process.stdout.close()
            process.wait()
Send zfs stream of contents.
dataset/ETHPy150Open ClusterHQ/flocker/flocker/volume/filesystems/zfs.py/Filesystem.reader