mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-25 01:44:43 +01:00
[#289] zfs: workaround for OpenZFS 0.7 dry send info with zero estimated size
fixes #289
This commit is contained in:
parent
02db5994fe
commit
0ee7a49d31
30
zfs/zfs.go
30
zfs/zfs.go
@ -860,9 +860,9 @@ type DrySendInfo struct {
|
||||
var (
|
||||
// keep same number of capture groups for unmarshalInfoLine homogeneity
|
||||
|
||||
sendDryRunInfoLineRegexFull = regexp.MustCompile(`^(full)\t()([^\t]+@[^\t]+)\t([0-9]+)$`)
|
||||
sendDryRunInfoLineRegexFull = regexp.MustCompile(`^(?P<type>full)\t()(?P<to>[^\t]+@[^\t]+)(\t(?P<size>[0-9]+))?$`)
|
||||
// cannot enforce '[#@]' in incremental source, see test cases
|
||||
sendDryRunInfoLineRegexIncremental = regexp.MustCompile(`^(incremental)\t([^\t]+)\t([^\t]+@[^\t]+)\t([0-9]+)$`)
|
||||
sendDryRunInfoLineRegexIncremental = regexp.MustCompile(`^(?P<type>incremental)\t(?P<from>[^\t]+)\t(?P<to>[^\t]+@[^\t]+)(\t(?P<size>[0-9]+))?$`)
|
||||
)
|
||||
|
||||
// see test cases for example output
|
||||
@ -890,30 +890,44 @@ func (s *DrySendInfo) unmarshalInfoLine(l string) (regexMatched bool, err error)
|
||||
|
||||
mFull := sendDryRunInfoLineRegexFull.FindStringSubmatch(l)
|
||||
mInc := sendDryRunInfoLineRegexIncremental.FindStringSubmatch(l)
|
||||
var matchingExpr *regexp.Regexp
|
||||
var m []string
|
||||
if mFull == nil && mInc == nil {
|
||||
return false, nil
|
||||
} else if mFull != nil && mInc != nil {
|
||||
panic(fmt.Sprintf("ambiguous ZFS dry send output: %q", l))
|
||||
} else if mFull != nil {
|
||||
m = mFull
|
||||
matchingExpr, m = sendDryRunInfoLineRegexFull, mFull
|
||||
} else if mInc != nil {
|
||||
m = mInc
|
||||
matchingExpr, m = sendDryRunInfoLineRegexIncremental, mInc
|
||||
}
|
||||
s.Type, err = DrySendTypeFromString(m[1])
|
||||
|
||||
fields := make(map[string]string, matchingExpr.NumSubexp())
|
||||
for i, name := range matchingExpr.SubexpNames() {
|
||||
if i != 0 {
|
||||
fields[name] = m[i]
|
||||
}
|
||||
}
|
||||
|
||||
s.Type, err = DrySendTypeFromString(fields["type"])
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
s.From = m[2]
|
||||
s.To = m[3]
|
||||
s.From = fields["from"]
|
||||
s.To = fields["to"]
|
||||
toFS, _, _, err := DecomposeVersionString(s.To)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("'to' is not a valid filesystem version: %s", err)
|
||||
}
|
||||
s.Filesystem = toFS
|
||||
|
||||
s.SizeEstimate, err = strconv.ParseInt(m[4], 10, 64)
|
||||
if fields["size"] == "" {
|
||||
// workaround for OpenZFS 0.7 prior to https://github.com/openzfs/zfs/commit/835db58592d7d947e5818eb7281882e2a46073e0#diff-66bd524398bcd2ac70d90925ab6d8073L1245
|
||||
// see https://github.com/zrepl/zrepl/issues/289
|
||||
fields["size"] = "0"
|
||||
}
|
||||
s.SizeEstimate, err = strconv.ParseInt(fields["size"], 10, 64)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("cannot not parse size: %s", err)
|
||||
}
|
||||
|
@ -136,6 +136,18 @@ size 10511856
|
||||
fullNoToken := `
|
||||
full zroot/test/a@3 10518512
|
||||
size 10518512
|
||||
`
|
||||
|
||||
// zero-length incremental send on ZoL 0.7.12
|
||||
// (it omits the size field as well as the size line if size is 0)
|
||||
// see https://github.com/zrepl/zrepl/issues/289
|
||||
// fixed in https://github.com/openzfs/zfs/commit/835db58592d7d947e5818eb7281882e2a46073e0#diff-66bd524398bcd2ac70d90925ab6d8073L1245
|
||||
incZeroSized_0_7_12 := `
|
||||
incremental p1 with/ spaces d1@1 with space p1 with/ spaces d1@2 with space
|
||||
`
|
||||
|
||||
fullZeroSized_0_7_12 := `
|
||||
full p1 with/ spaces d1@2 with space
|
||||
`
|
||||
|
||||
fullWithSpaces := "\nfull\tpool1/otherjob/ds with spaces@blaffoo\t12912\nsize\t12912\n"
|
||||
@ -243,6 +255,25 @@ size 10518512
|
||||
SizeEstimate: 624,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "incrementalZeroSizedOpenZFS_pre0.7.12", in: incZeroSized_0_7_12,
|
||||
exp: &DrySendInfo{
|
||||
Type: DrySendTypeIncremental,
|
||||
Filesystem: "p1 with/ spaces d1",
|
||||
From: "p1 with/ spaces d1@1 with space",
|
||||
To: "p1 with/ spaces d1@2 with space",
|
||||
SizeEstimate: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fullZeroSizedOpenZFS_pre0.7.12", in: fullZeroSized_0_7_12,
|
||||
exp: &DrySendInfo{
|
||||
Type: DrySendTypeFull,
|
||||
Filesystem: "p1 with/ spaces d1",
|
||||
To: "p1 with/ spaces d1@2 with space",
|
||||
SizeEstimate: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
@ -251,10 +282,12 @@ size 10518512
|
||||
in := tc.in[1:] // strip first newline
|
||||
var si DrySendInfo
|
||||
err := si.unmarshalZFSOutput([]byte(in))
|
||||
t.Logf("%#v", &si)
|
||||
t.Logf("err=%T %s", err, err)
|
||||
|
||||
if tc.expErr {
|
||||
assert.Error(t, err)
|
||||
}
|
||||
t.Logf("%#v", &si)
|
||||
if tc.exp != nil {
|
||||
assert.Equal(t, tc.exp, &si)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user