The Flocker Volume Manager (FVM) provides snapshotting and replication of Flocker volumes. It has the ability to push volumes to remote nodes, track changes to those volumes, and roll them back to earlier states.
Although initially built on top of ZFS, FVM should eventually be capable of being backed on a number of filesystems. As such a generic data model is required.
We are therefore going to be using the following model for CLI examples below:
The names of volumes, branches and tags do not map directly onto the ZFS naming system.
Each Flocker instance has a UUID, with a matching (unique across a Flocker cluster) human readable name, typically the hostname. We can imagine having two Flocker instances on same machine (with different pools) for testing, so don’t want to require hostname. This is the first part of the <Flocker instance UUID>/<volume UUID>/<branch name> triplet of branch names - in human-exposed CLI we probably want to use human names though, not UUIDs. Branches are known to be local if branch’s specified Flocker instance matches the UUID of the Flocker process that is managing it.
Volumes have UUIDs, and a matching (cluster unique?) human readable name. Tags are indicated by having a snapshot with a user attributes indicating it is a tag, the tag name and the volume name. However, not all ZFS snapshots will be exposed as tags. E.g. the fact that a snapshot is necessary for cloning (and therefore branch creation) is an implementation detail; sometimes you want to branch off a tag, but if you want to branch off of latest version the fact that a snapshot is created needn’t be exposed.
A remote branch exists if there is a non-tag ZFS snapshot naming it, i.e. the snapshot has a user attribute indicating which branch it’s on (e.g. “thathost/somevolume/abranch”).
In either case the ZFS-level snapshot name is the Flocker instance UUID + the timestamp when it was generated.
A local branch exists due to local existence ZFS dataset, one of:
The branch name is stored as a user attribute on the ZFS dataset. Dataset names can be the branch human readable names, since only one Flocker instance will ever be setting them.
In cases where we can’t use attributes the data will be in a local database of some sort. E.g. ZFS properties are inherited automatically (not the behavior we want), which might lead to some corrupt state in crashes if the low-level APIs don’t allow bypassing this…
Btrfs does not have a concept of clones - it just has snapshots, and they are mounted and writable. As such the proposed model should also work with Btrfs. Btrfs appears to lack promotion, but that can be emulated via renames. It’s not clear if Btrfs has the “can’t delete parent if it has children” restriction, though it may just keep around extra disk storage in that case.