The general way to send ZFS data sets to remote nodes is normally achieved by sending the ZFS stream through ssh. Example:

zfs send  zones/UUID@snapshot  | ssh root@ zfs recv zones/UUID

The down side with this method is that ssh encryption is slow and has significant cpu overhead. You may find yourself in situations where you have very large datasets that you need to move from one ZFS host to another and you want it to be as fast as possible with as little cpu overhead as possible. The following method is good for local environments where you are not concerned about sending streams unencrypted. The tool that works very well for this is “netcat“.

The nc (or netcat) utility is used for a variety of tasks associated with TCP or UDP. nc can open TCP connections, send UDP packets and listen on arbitrary TCP and UDP ports.

The Steps Involved

On the Target SmartOS Node:

We start by running netcat on the target node where we want the ZFS dataset copied to. We run netcat in Listen mode on port 8023 with a timeout of 120 seconds. If we do not specify a timeout then netcat will listen forever and will not exit due to inactivity. This is a bad idea to leave this open on your server indefinitely and you want it to close automatically once the zfs receive is complete. In the last part of the command we pipe whatever data netcat receives into the zfs receive command and specify the target dataset.

nc -w 120 -l -p 8023 | zfs receive  zones/UUID

On the Source SmartOS Node:

On the source node we run a ZFS send and pipe it through netcat and  specify the target server and port.

zfs send zones/UUID@snapshot | nc -w 20 8023

That’s all there is to it!

I am sure you will be pleasantly surprised by the speeds you achieve as well as the significantly lower cpu overhead.