In every dump (full or incremental) produces a file containing
the version vectors and
StoreIds
of every
vnode in the volume. These files have names of the form
/vice/backup/
groupid
.
volid
.newlist
. When the backup
coordinator is convinced that the backup of a volume has completed,
the
*.newlist
file is renamed to be
*.ancient
via the
volutil
ancient
call.
These files are stored in a human-readable format for
convenience.
When creating an incremental dump, the server looks for the .ancient file corresponding to the volume. If it doesnt exist, a full dump is created. If it does exist, it is used to determine which files have changed since the last successful backup. The server iterates through the vnode lists for the volume and the version vector lists from the *.ancient file comparing the version vectors and storeIds. A discrepancy between the two implies that the file has changed and should be included in the incremental dump. By comparing the sequence numbers in the vnodes lists, it can also be determined if a file or directory had been deleted (since the vnode is no longer in use). Vnodes that are freed and then reallocated between dumps look like vnodes which have been modified, and so are safely included in the incremental dump.
It is also important to maintain an ordering on the incremental dumps. To correctly restore to a particular day each incremental dump must be applied to the appropriate full dump. To ensure that this happens, each dump is labeled with a uniquifier, and each incremental is labeled with the uniquifier of the dump with respect to which it is taken. During merge, the full dumps uniquifier is compared with the uniquifier of the dump used to create the incremental. If they do not match, the incremental should not be applied to the full dump.