handle DryRun send size estimate errors with bookmarks

This commit is contained in:
Christian Schwarz 2018-09-05 17:41:25 -07:00
parent 9eca269ad8
commit acd2418803
6 changed files with 39 additions and 15 deletions

View File

@ -235,12 +235,14 @@ func (t *tui) drawBar(name string, maxNameLength int, status string, bytes int64
t.write(rightPad(status, 14, " "))
t.write(" ")
if totalBytes > 0 {
length := 50
completedLength := int(int64(length) * bytes / totalBytes)
var completedLength int
if totalBytes > 0 {
completedLength = int(int64(length) * bytes / totalBytes)
if completedLength > length {
completedLength = length
}
}
t.write("[")
t.write(times("=", completedLength))
@ -249,8 +251,11 @@ func (t *tui) drawBar(name string, maxNameLength int, status string, bytes int64
t.write("]")
t.write(" ")
t.write(rightPad(ByteCountBinary(bytes) + "/" + ByteCountBinary(totalBytes), 20, " "))
totalBytesStr := ByteCountBinary(totalBytes)
if totalBytes == 0 {
totalBytesStr = "??? B"
}
t.write(rightPad(ByteCountBinary(bytes)+"/"+totalBytesStr, 20, " "))
t.newline()
}

View File

@ -77,6 +77,9 @@ func (p *Sender) Send(ctx context.Context, r *pdu.SendReq) (*pdu.SendRes, io.Rea
if r.DryRun {
size, err := zfs.ZFSSendDry(r.Filesystem, r.From, r.To)
if err == zfs.BookmarkSizeEstimationNotSupported {
return &pdu.SendRes{ExpectedSize: 0}, nil, nil
}
if err != nil {
return nil, nil, err
}

View File

@ -59,7 +59,7 @@ type StepReport struct {
Status StepState
Problem string
Bytes int64
ExpectedBytes int64
ExpectedBytes int64 // 0 means no size estimate possible
}
type Report struct {
@ -185,7 +185,7 @@ type ReplicationStep struct {
err error
byteCounter *util.ByteCounterReader
expectedSize int64
expectedSize int64 // 0 means no size estimate present / possible
}
func (f *Replication) TakeStep(ctx context.Context, sender Sender, receiver Receiver) (post State, nextStepDate time.Time) {
@ -457,6 +457,7 @@ func (s *ReplicationStep) updateSizeEstimate(ctx context.Context, sender Sender)
sres, _, err := sender.Send(ctx, sr)
if err != nil {
log.WithError(err).Error("dry run send request failed")
return err
}
s.expectedSize = sres.ExpectedSize
return nil

View File

@ -493,7 +493,8 @@ func (m *Property) GetValue() string {
type SendRes struct {
// Whether the resume token provided in the request has been used or not.
UsedResumeToken bool `protobuf:"varint,1,opt,name=UsedResumeToken,proto3" json:"UsedResumeToken,omitempty"`
// Expected stream size determined by dry run, not exact
// Expected stream size determined by dry run, not exact.
// 0 indicates that for the given SendReq, no size estimate could be made.
ExpectedSize int64 `protobuf:"varint,2,opt,name=ExpectedSize,proto3" json:"ExpectedSize,omitempty"`
Properties []*Property `protobuf:"bytes,3,rep,name=Properties,proto3" json:"Properties,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`

View File

@ -65,7 +65,8 @@ message SendRes {
// Whether the resume token provided in the request has been used or not.
bool UsedResumeToken = 1;
// Expected stream size determined by dry run, not exact
// Expected stream size determined by dry run, not exact.
// 0 indicates that for the given SendReq, no size estimate could be made.
int64 ExpectedSize = 2;
repeated Property Properties = 3;

View File

@ -309,6 +309,9 @@ func ZFSSend(fs string, from, to string) (stream io.ReadCloser, err error) {
return
}
var BookmarkSizeEstimationNotSupported error = fmt.Errorf("size estimation is not supported for bookmarks")
// May return BookmarkSizeEstimationNotSupported as err if from is a bookmark.
func ZFSSendDry(fs string, from, to string) (size int64, err error) {
fromV, err := absVersion(fs, from)
@ -324,6 +327,16 @@ func ZFSSendDry(fs string, from, to string) (size int64, err error) {
}
}
if strings.Contains(fromV, "#") {
/* TODO:
* ZFS at the time of writing does not support dry-run send because size-estimation
* uses fromSnap's deadlist. However, for a bookmark, that deadlist no longer exists.
* Redacted send & recv will bring this functionality, see
* https://github.com/openzfs/openzfs/pull/484
*/
return 0, BookmarkSizeEstimationNotSupported
}
args := make([]string, 0)
args = append(args, "send", "-n", "-v", "-P")