mirror of
https://github.com/zrepl/zrepl.git
synced 2025-08-14 00:58:24 +02:00
zfs: extract filesystem version code to separate file & add filtering support
This commit is contained in:
96
zfs/diff.go
96
zfs/diff.go
@ -1,55 +1,9 @@
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type VersionType string
|
||||
|
||||
const (
|
||||
Bookmark VersionType = "bookmark"
|
||||
Snapshot = "snapshot"
|
||||
)
|
||||
|
||||
func (t VersionType) DelimiterChar() string {
|
||||
switch t {
|
||||
case Bookmark:
|
||||
return "#"
|
||||
case Snapshot:
|
||||
return "@"
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected VersionType %#v", t))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type FilesystemVersion struct {
|
||||
Type VersionType
|
||||
|
||||
// Display name. Should not be used for identification, only for user output
|
||||
Name string
|
||||
|
||||
// GUID as exported by ZFS. Uniquely identifies a snapshot across pools
|
||||
Guid uint64
|
||||
|
||||
// The TXG in which the snapshot was created. For bookmarks,
|
||||
// this is the GUID of the snapshot it was initially tied to.
|
||||
CreateTXG uint64
|
||||
}
|
||||
|
||||
func (v FilesystemVersion) ToAbsPath(p DatasetPath) string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString(p.ToString())
|
||||
b.WriteString(v.Type.DelimiterChar())
|
||||
b.WriteString(v.Name)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
type fsbyCreateTXG []FilesystemVersion
|
||||
|
||||
func (l fsbyCreateTXG) Len() int { return len(l) }
|
||||
@ -105,56 +59,6 @@ type FilesystemDiff struct {
|
||||
MRCAPathRight []FilesystemVersion
|
||||
}
|
||||
|
||||
func ZFSListFilesystemVersions(fs DatasetPath) (res []FilesystemVersion, err error) {
|
||||
var fieldLines [][]string
|
||||
fieldLines, err = ZFSList(
|
||||
[]string{"name", "guid", "createtxg"},
|
||||
"-r", "-d", "1",
|
||||
"-t", "bookmark,snapshot",
|
||||
"-s", "createtxg", fs.ToString())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res = make([]FilesystemVersion, len(fieldLines))
|
||||
for i, line := range fieldLines {
|
||||
|
||||
if len(line[0]) < 3 {
|
||||
err = errors.New(fmt.Sprintf("snapshot or bookmark name implausibly short: %s", line[0]))
|
||||
return
|
||||
}
|
||||
|
||||
snapSplit := strings.SplitN(line[0], "@", 2)
|
||||
bookmarkSplit := strings.SplitN(line[0], "#", 2)
|
||||
if len(snapSplit)*len(bookmarkSplit) != 2 {
|
||||
err = errors.New(fmt.Sprintf("dataset cannot be snapshot and bookmark at the same time: %s", line[0]))
|
||||
return
|
||||
}
|
||||
|
||||
var v FilesystemVersion
|
||||
if len(snapSplit) == 2 {
|
||||
v.Name = snapSplit[1]
|
||||
v.Type = Snapshot
|
||||
} else {
|
||||
v.Name = bookmarkSplit[1]
|
||||
v.Type = Bookmark
|
||||
}
|
||||
|
||||
if v.Guid, err = strconv.ParseUint(line[1], 10, 64); err != nil {
|
||||
err = errors.New(fmt.Sprintf("cannot parse GUID: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if v.CreateTXG, err = strconv.ParseUint(line[2], 10, 64); err != nil {
|
||||
err = errors.New(fmt.Sprintf("cannot parse CreateTXG: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
res[i] = v
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// we must assume left and right are ordered ascendingly by ZFS_PROP_CREATETXG and that
|
||||
// names are unique (bas ZFS_PROP_GUID replacement)
|
||||
func MakeFilesystemDiff(left, right []FilesystemVersion) (diff FilesystemDiff) {
|
||||
|
Reference in New Issue
Block a user