Because zfs send
and zfs
recv
use streams to exchange data, you can use them to
replicate information from one system to another by combining
zfs send
, ssh
, and
zfs recv
.
For example, if a snapshot of the scratchpool
filesystem has been created and this needs to be copied to a new
system or filesystem called slavepool
. You
would use the following command, combining the snapshot of
scratchpool
, the transmission to the slave
machine (using ssh), and the recovery of the
snapshot on the slave using zfs revc:
root-shell> zfs send scratchpool@snap1 |ssh mc@slave pfexec zfs recv -F slavepool
The first part, zfs send scratchpool@snap1
,
streams the snapshot, the second, ssh mc@slave
,
and the third, pfexec zfs recv -F slavepool
,
receives the streamed snapshot data and writes it to slavepool. In
this instance, I've specified the -F
option
which forces the snapshot data to be applied, and is therefore
destructive. This is fine, as I'm creating the first version of my
replicated filesystem.
On the slave machine, the replicated filesystem contains the exact same content:
root-shell> ls -al /slavepool/ total 23 drwxr-xr-x 6 root root 7 Nov 8 09:13 ./ drwxr-xr-x 29 root root 34 Nov 9 07:06 ../ drwxr-xr-x 31 root bin 50 Jul 21 07:32 DTT/ drwxr-xr-x 4 root bin 5 Jul 21 07:32 SUNWmlib/ drwxr-xr-x 14 root sys 16 Nov 5 09:56 SUNWspro/ drwxrwxrwx 19 1000 1000 40 Nov 6 19:16 emacs-22.1/
Once a snapshot has been created, to synchronize the filesystem
again, you need to create a new snapshot, and then use the
incremental snapshot feature of zfs send
to
send the changes between the two snapshots to the slave machine
again:
root-shell> zfs send -i scratchpool@snapshot1 scratchpool@snapshot2 |ssh mc@192.168.0.93 pfexec zfs recv slavepool
Without further modification, this operation fails, because the
filesystem on the slave machine can currently be modified, and you
can't apply the incremental changes to a destination filesystem
that has changed. It is the metadata that has changed. The
metadata about the filesystem, like the last time it was accessed
- in this case, it is our ls
that caused the
problem.
To prevent changes on the slave filesystem, you must set the filesystem on the slave to be read-only:
root-shell> zfs set readonly=on slavepool
Setting readonly
means that you cannot change
the filesystem on the slave by normal means, including the
filesystem metadata. Operations that would normally update
metadata (like our ls
) silently perform their
function without attempting to update the filesystem state.
In essence, the slave filesystem is nothing but a static copy of the original filesystem. However, even when configured to to be read-only, a filesystem can have snapshots applied to it. Now the filesystem is read only, re-run the initial copy:
root-shell> zfs send scratchpool@snap1 |ssh mc@slave pfexec zfs recv -F slavepool
Now you can make changes to the original filesystem and replicate them to the slave.