mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-28 19:34:58 +01:00
handle DryRun send size estimate errors with bookmarks
This commit is contained in:
parent
9eca269ad8
commit
acd2418803
@ -235,23 +235,28 @@ func (t *tui) drawBar(name string, maxNameLength int, status string, bytes int64
|
|||||||
t.write(rightPad(status, 14, " "))
|
t.write(rightPad(status, 14, " "))
|
||||||
t.write(" ")
|
t.write(" ")
|
||||||
|
|
||||||
|
length := 50
|
||||||
|
var completedLength int
|
||||||
if totalBytes > 0 {
|
if totalBytes > 0 {
|
||||||
length := 50
|
completedLength = int(int64(length) * bytes / totalBytes)
|
||||||
completedLength := int(int64(length) * bytes / totalBytes)
|
|
||||||
if completedLength > length {
|
if completedLength > length {
|
||||||
completedLength = length
|
completedLength = length
|
||||||
}
|
}
|
||||||
|
|
||||||
t.write("[")
|
|
||||||
t.write(times("=", completedLength))
|
|
||||||
t.write(">")
|
|
||||||
t.write(times("-", length-completedLength))
|
|
||||||
t.write("]")
|
|
||||||
|
|
||||||
t.write(" ")
|
|
||||||
t.write(rightPad(ByteCountBinary(bytes) + "/" + ByteCountBinary(totalBytes), 20, " "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.write("[")
|
||||||
|
t.write(times("=", completedLength))
|
||||||
|
t.write(">")
|
||||||
|
t.write(times("-", length-completedLength))
|
||||||
|
t.write("]")
|
||||||
|
|
||||||
|
t.write(" ")
|
||||||
|
totalBytesStr := ByteCountBinary(totalBytes)
|
||||||
|
if totalBytes == 0 {
|
||||||
|
totalBytesStr = "??? B"
|
||||||
|
}
|
||||||
|
t.write(rightPad(ByteCountBinary(bytes)+"/"+totalBytesStr, 20, " "))
|
||||||
|
|
||||||
t.newline()
|
t.newline()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@ func (p *Sender) Send(ctx context.Context, r *pdu.SendReq) (*pdu.SendRes, io.Rea
|
|||||||
|
|
||||||
if r.DryRun {
|
if r.DryRun {
|
||||||
size, err := zfs.ZFSSendDry(r.Filesystem, r.From, r.To)
|
size, err := zfs.ZFSSendDry(r.Filesystem, r.From, r.To)
|
||||||
|
if err == zfs.BookmarkSizeEstimationNotSupported {
|
||||||
|
return &pdu.SendRes{ExpectedSize: 0}, nil, nil
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ type StepReport struct {
|
|||||||
Status StepState
|
Status StepState
|
||||||
Problem string
|
Problem string
|
||||||
Bytes int64
|
Bytes int64
|
||||||
ExpectedBytes int64
|
ExpectedBytes int64 // 0 means no size estimate possible
|
||||||
}
|
}
|
||||||
|
|
||||||
type Report struct {
|
type Report struct {
|
||||||
@ -185,7 +185,7 @@ type ReplicationStep struct {
|
|||||||
err error
|
err error
|
||||||
|
|
||||||
byteCounter *util.ByteCounterReader
|
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) {
|
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)
|
sres, _, err := sender.Send(ctx, sr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("dry run send request failed")
|
log.WithError(err).Error("dry run send request failed")
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
s.expectedSize = sres.ExpectedSize
|
s.expectedSize = sres.ExpectedSize
|
||||||
return nil
|
return nil
|
||||||
|
@ -493,7 +493,8 @@ func (m *Property) GetValue() string {
|
|||||||
type SendRes struct {
|
type SendRes struct {
|
||||||
// Whether the resume token provided in the request has been used or not.
|
// 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"`
|
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"`
|
ExpectedSize int64 `protobuf:"varint,2,opt,name=ExpectedSize,proto3" json:"ExpectedSize,omitempty"`
|
||||||
Properties []*Property `protobuf:"bytes,3,rep,name=Properties,proto3" json:"Properties,omitempty"`
|
Properties []*Property `protobuf:"bytes,3,rep,name=Properties,proto3" json:"Properties,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
@ -65,7 +65,8 @@ message SendRes {
|
|||||||
// Whether the resume token provided in the request has been used or not.
|
// Whether the resume token provided in the request has been used or not.
|
||||||
bool UsedResumeToken = 1;
|
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;
|
int64 ExpectedSize = 2;
|
||||||
|
|
||||||
repeated Property Properties = 3;
|
repeated Property Properties = 3;
|
||||||
|
13
zfs/zfs.go
13
zfs/zfs.go
@ -309,6 +309,9 @@ func ZFSSend(fs string, from, to string) (stream io.ReadCloser, err error) {
|
|||||||
return
|
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) {
|
func ZFSSendDry(fs string, from, to string) (size int64, err error) {
|
||||||
|
|
||||||
fromV, err := absVersion(fs, from)
|
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 := make([]string, 0)
|
||||||
args = append(args, "send", "-n", "-v", "-P")
|
args = append(args, "send", "-n", "-v", "-P")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user