From 3b1d0fc8504365820d9dcbf389d6b80455d749ef Mon Sep 17 00:00:00 2001 From: shoopea Date: Tue, 22 Aug 2023 13:23:48 +0200 Subject: [PATCH] prepare indirect zfs transfer and multi-transfer --- addr.go | 8 ++++---- app.go | 13 ++++++------ box.go | 59 +++++++++++++++++++++++++++++++----------------------- version.go | 10 ++++----- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/addr.go b/addr.go index 37727ae..679c277 100644 --- a/addr.go +++ b/addr.go @@ -84,7 +84,7 @@ func (a Addr) ValidSnapshots() ([]*ZfsSnapshot, error) { } } -func (a Addr) SetManaged(val bool) error { +func (a Addr) SetManaged(managed bool) error { log.WithFields(log.Fields{"addr": a}).Debugf("starting") defer log.WithFields(log.Fields{"addr": a}).Debugf("done") @@ -99,9 +99,9 @@ func (a Addr) SetManaged(val bool) error { } else { fs.mx.Lock() defer fs.mx.Unlock() - if fs.managed != val { + if fs.managed != managed { var cmd string - if val { + if managed { cmd = fmt.Sprintf("zfs set %s=+ %s", zfsManagedPropertyName, a.Path()) } else { cmd = fmt.Sprintf("zfs set %s=- %s", zfsManagedPropertyName, a.Path()) @@ -111,7 +111,7 @@ func (a Addr) SetManaged(val bool) error { return err } } - fs.managed = val + fs.managed = managed return nil } } diff --git a/app.go b/app.go index 5a08c65..c04cdc7 100644 --- a/app.go +++ b/app.go @@ -478,7 +478,7 @@ func (a *App) Transfer() error { defer log.WithFields(log.Fields{"app": a.name}).Debugf("done") for _, src := range a.sources { - backedUp := false + dests := make([]Addr, 0) for _, dest := range a.destinations { dest2 := dest.Append("/" + src.Box() + "/" + src.Path()) if dest2.Online() { @@ -486,18 +486,17 @@ func (a *App) Transfer() error { log.WithFields(log.Fields{"app": a.name, "call": "Mkdir", "attr": dest, "error": err}).Errorf("") return err } - if err := TransferZfs(src, dest2); err != nil { - log.WithFields(log.Fields{"app": a.name, "call": "TransferZfs", "src": src, "dest": dest, "error": err}).Errorf("") - return err - } if err := dest2.SetManaged(true); err != nil { log.WithFields(log.Fields{"app": a.name, "call": "SetManaged", "src": src, "dest": dest, "error": err}).Errorf("") return err } - backedUp = true + dests = append(dests, dest2) } } - if backedUp { + if n, err := TransferZfs(src, dests); err != nil { + log.WithFields(log.Fields{"app": a.name, "call": "TransferZfs", "src": src, "dests": dests, "error": err}).Errorf("") + return err + } else if n > 0 { if err := src.SetBackedUp(true); err != nil { log.WithFields(log.Fields{"app": a.name, "call": "SetBackedUp", "src": src, "error": err}).Errorf("") return err diff --git a/box.go b/box.go index a9ff95d..c705f60 100644 --- a/box.go +++ b/box.go @@ -139,22 +139,39 @@ func (b *Box) Exec(cmd string) (r string, err error) { return s.Exec(cmd) } -func TransferZfs(from, to Addr) error { +func TransferZfs(from Addr, to []Addr) (int, error) { + log.WithFields(log.Fields{"from": from, "to": to}).Debugf("starting") + defer log.WithFields(log.Fields{"from": from, "to": to}).Debugf("done") + + count := 0 + + dests := make([]Addr, 0) + for _, dest := range to { + if cfg.box[from.Box()].allowDirectConnect && cfg.box[dest.Box()].allowDirectConnect { + if err := TransferDirectZfs(from, dest); err != nil { + log.WithFields(log.Fields{"from": from, "to": to, "call": "TransferDirectZfs", "attr": dest, "error": err}).Errorf("") + return count, err + } else { + count++ + } + } else { + dests = append(dests, dest) + } + } + + return count, nil + +} + +func TransferDirectZfs(from, to Addr) error { log.WithFields(log.Fields{"from": from, "to": to}).Debugf("starting") defer log.WithFields(log.Fields{"from": from, "to": to}).Debugf("done") var ( err error fromSnapshots, toSnapshots []*ZfsSnapshot - directTransfer bool ) - if cfg.box[from.Box()].allowDirectConnect && cfg.box[to.Box()].allowDirectConnect { - directTransfer = true - } else { - directTransfer = false - } - if fromSnapshots, err = from.ValidSnapshots(); err != nil { log.WithFields(log.Fields{"from": from, "to": to, "call": "ValidSnapshots", "attr": from, "error": err}).Errorf("") return err @@ -171,17 +188,13 @@ func TransferZfs(from, to Addr) error { if len(toSnapshots) == 0 { log.WithFields(log.Fields{"from": from, "to": to}).Debugf("initiating destination") - if directTransfer { - if _, err := to.BoxExec("ssh " + from.Box() + " zfs send " + fromSnapshots[0].String() + " | zfs recv -F " + to.Path()); err != nil { - log.WithFields(log.Fields{"from": from, "to": to, "call": "BoxExec", "error": err}).Errorf("") - return err - } - newToSnapshot := &ZfsSnapshot{name: fromSnapshots[0].name, fs: cfg.box[to.Box()].zfs.filesystems[to.Path()]} - toSnapshots = append(toSnapshots, newToSnapshot) - cfg.box[to.Box()].zfs.filesystems[to.Path()].AddSnapshot(newToSnapshot) - } else { - //handle indirect transfer + if _, err := to.BoxExec("ssh " + from.Box() + " zfs send " + fromSnapshots[0].String() + " | zfs recv -F " + to.Path()); err != nil { + log.WithFields(log.Fields{"from": from, "to": to, "call": "BoxExec", "error": err}).Errorf("") + return err } + newToSnapshot := &ZfsSnapshot{name: fromSnapshots[0].name, fs: cfg.box[to.Box()].zfs.filesystems[to.Path()]} + toSnapshots = append(toSnapshots, newToSnapshot) + cfg.box[to.Box()].zfs.filesystems[to.Path()].AddSnapshot(newToSnapshot) } @@ -204,13 +217,9 @@ func TransferZfs(from, to Addr) error { if fromFromSnapshotId < len(fromSnapshots)-1 { log.WithFields(log.Fields{"from": from, "to": to}).Debugf("transfering from %s to %s", fromSnapshots[fromFromSnapshotId].name, fromSnapshots[len(fromSnapshots)-1].name) - if directTransfer { - if _, err := to.BoxExec("ssh " + from.Box() + " zfs send -I " + fromSnapshots[fromFromSnapshotId].String() + " " + fromSnapshots[len(fromSnapshots)-1].String() + " | zfs recv -F " + to.Path()); err != nil { - log.WithFields(log.Fields{"from": from, "to": to, "call": "BoxExec", "error": err}).Errorf("") - return err - } - } else { - // handle indirect transfer + if _, err := to.BoxExec("ssh " + from.Box() + " zfs send -I " + fromSnapshots[fromFromSnapshotId].String() + " " + fromSnapshots[len(fromSnapshots)-1].String() + " | zfs recv -F " + to.Path()); err != nil { + log.WithFields(log.Fields{"from": from, "to": to, "call": "BoxExec", "error": err}).Errorf("") + return err } for _, v := range fromSnapshots[fromFromSnapshotId+1:] { diff --git a/version.go b/version.go index 071afc2..f79c30f 100644 --- a/version.go +++ b/version.go @@ -1,7 +1,7 @@ // Code generated by version.sh (@generated) DO NOT EDIT. package main -var githash = "1a1713e" -var branch = "v2" -var buildstamp = "2023-08-21_12:35:47" -var commits = "83" -var version = "1a1713e-b83 - 2023-08-21_12:35:47" +var githash = "e7ed6cb" +var branch = "master" +var buildstamp = "2023-08-22_11:08:53" +var commits = "85" +var version = "e7ed6cb-b85 - 2023-08-22_11:08:53"