Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Mar 2009 16:29:59 -0500
From:      "James R. Van Artsdalen" <james-freebsd-fs2@jrv.org>
To:        freebsd-fs@freebsd.org
Subject:   ZFS recv doesn't properly skip existing snapshots
Message-ID:  <49BAD057.6060602@jrv.org>

next in thread | raw e-mail | index | archive | help
/home/james# uname -a
FreeBSD bigtex.housenet.jrv 8.0-CURRENT FreeBSD 8.0-CURRENT #0 r189099:
Fri Feb 27 07:09:47 CST 2009    
james@bigtex.housenet.jrv:/usr/obj/usr/src/sys/GENERIC  amd64

"zfs recv" doesn't properly skip existing snapshots in a replication stream.

I'm working on a way to keep a remote pool in sync with a local pool
using zfs send/recv.  It appears that "zfs recv" may not be atomic
across the input stream but only within each individual filesystem. 
This means that the pool replication script must be prepared to handle
the situation where a parent filesystem may have received a snapshot
that a child did not.

It appears "zfs recv" is supposed to simply skip any snapshot it already
has, making me think that it should pick up at the next snapshot record
in the input stream.  But instead "zfs recv" appears to never get in
sync with the input stream again and simple exits.

Comments embedded with hashed below.

/home/james# zfs create bigtex/foo
/home/james# zfs create bigtex/foo/bar
/home/james# zfs snapshot -r bigtex/foo@a
/home/james# zfs snapshot -r bigtex/foo@b
/home/james# zfs snapshot -r bigtex/foo@c
/home/james# zfs snapshot -r bigtex/foo@d
/home/james# zfs list -t snapshot
...
bigtex/foo@a                                                                           
0      -    18K  -
bigtex/foo@b                                                                           
0      -    18K  -
bigtex/foo@c                                                                           
0      -    18K  -
bigtex/foo@d                                                                           
0      -    18K  -
bigtex/foo/bar@a                                                                       
0      -    18K  -
bigtex/foo/bar@b                                                                       
0      -    18K  -
bigtex/foo/bar@c                                                                       
0      -    18K  -
bigtex/foo/bar@d                                                                       
0      -    18K  -

# send initial data.  Works as expected.
/home/james# /root/zfs send -v -R bigtex/foo@b | /root/zfs recv -dv
bigtmptex
sending from @ to bigtex/foo@a
receiving full stream of bigtex/foo@a into bigtmptex/foo@a
sending from @a to bigtex/foo@b
sending from @ to bigtex/foo/bar@a
sending from @a to bigtex/foo/bar@b
received 13.6KB stream in 1 seconds (13.6KB/sec)
receiving incremental stream of bigtex/foo@b into bigtmptex/foo@b
received 312B stream in 1 seconds (312B/sec)
receiving full stream of bigtex/foo/bar@a into bigtmptex/foo/bar@a
received 13.6KB stream in 1 seconds (13.6KB/sec)
receiving incremental stream of bigtex/foo/bar@b into bigtmptex/foo/bar@b
received 312B stream in 1 seconds (312B/sec)

# send incremental update.  Works as expected.
/home/james# /root/zfs send -RvI @b bigtex/foo@d | /root/zfs recv -dvF
bigtmptex
sending from @b to bigtex/foo@c
sending from @c to bigtex/foo@d
sending from @b to bigtex/foo/bar@c
sending from @c to bigtex/foo/bar@d
receiving incremental stream of bigtex/foo@c into bigtmptex/foo@c
received 312B stream in 1 seconds (312B/sec)
receiving incremental stream of bigtex/foo@d into bigtmptex/foo@d
received 312B stream in 1 seconds (312B/sec)
receiving incremental stream of bigtex/foo/bar@c into bigtmptex/foo/bar@c
received 312B stream in 1 seconds (312B/sec)
receiving incremental stream of bigtex/foo/bar@d into bigtmptex/foo/bar@d
received 312B stream in 1 seconds (312B/sec)

# The results are correct.
/home/james# zfs list -t snapshot
...
bigtex/foo@a                                                                           
0      -    18K  -
bigtex/foo@b                                                                           
0      -    18K  -
bigtex/foo@c                                                                           
0      -    18K  -
bigtex/foo@d                                                                           
0      -    18K  -
bigtex/foo/bar@a                                                                       
0      -    18K  -
bigtex/foo/bar@b                                                                       
0      -    18K  -
bigtex/foo/bar@c                                                                       
0      -    18K  -
bigtex/foo/bar@d                                                                       
0      -    18K  -
bigtmptex/foo@a                                                                        
0      -    18K  -
bigtmptex/foo@b                                                                        
0      -    18K  -
bigtmptex/foo@c                                                                        
0      -    18K  -
bigtmptex/foo@d                                                                        
0      -    18K  -
bigtmptex/foo/bar@a                                                                    
0      -    18K  -
bigtmptex/foo/bar@b                                                                    
0      -    18K  -
bigtmptex/foo/bar@c                                                                    
0      -    18K  -
bigtmptex/foo/bar@d                                                                    
0      -    18K  -

# pretend that the incremental send/recv above was interrupted after
bigtex/foo@d was received but before bigtex/foo/bar@d
/home/james# zfs destroy bigtmptex/foo/bar@d

# a clever script might realize that we need to start at @c because @d
has not been received by some child filesystems.  But zfs recv doesn't
work right.
/home/james# /root/zfs send -RvI @c bigtex/foo@d | /root/zfs recv -dvF
bigtmptex
sending from @c to bigtex/foo@d
receiving incremental stream of bigtex/foo@d into bigtmptex/foo@d
snap bigtmptex/foo@d already exists; ignoring
sending from @c to bigtex/foo/bar@d
warning: cannot send 'bigtex/foo/bar@d': Broken pipe

/home/james# zfs list -t snapshot
...
bigtmptex/foo@a                                                                        
0      -    18K  -
bigtmptex/foo@b                                                                        
0      -    18K  -
bigtmptex/foo@c                                                                        
0      -    18K  -
bigtmptex/foo@d                                                                        
0      -    18K  -
bigtmptex/foo/bar@a                                                                    
0      -    18K  -
bigtmptex/foo/bar@b                                                                    
0      -    18K  -
bigtmptex/foo/bar@c                                                                    
0      -    18K  -




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?49BAD057.6060602>