autosnap: parallel snapshotting and bookmarking

refs #62
This commit is contained in:
Christian Schwarz
2018-02-26 22:18:09 +01:00
parent 61af396fdd
commit b34d0e1041

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/zrepl/zrepl/zfs" "github.com/zrepl/zrepl/zfs"
"sort" "sort"
"sync"
"time" "time"
) )
@ -165,33 +166,46 @@ func (a *IntervalAutosnap) doSnapshots(didSnaps chan struct{}) {
// don't cache the result from previous run in case the user added // don't cache the result from previous run in case the user added
// a new dataset in the meantime // a new dataset in the meantime
ds, stop := a.filterFilesystems() fss, stop := a.filterFilesystems()
if stop { if stop {
return return
} }
a.task.Log().Info("beginning parallel snapshots")
// TODO channel programs -> allow a little jitter? // TODO channel programs -> allow a little jitter?
for _, d := range ds { var wg sync.WaitGroup
for fsi := range fss {
wg.Add(1)
go func(fs *zfs.DatasetPath) {
defer wg.Done()
suffix := time.Now().In(time.UTC).Format("20060102_150405_000") suffix := time.Now().In(time.UTC).Format("20060102_150405_000")
snapname := fmt.Sprintf("%s%s", a.Prefix, suffix) snapname := fmt.Sprintf("%s%s", a.Prefix, suffix)
l := a.task.Log().WithField(logFSField, d.ToString()). l := a.task.Log().WithField(logFSField, fs.ToString()).
WithField("snapname", snapname) WithField("snapname", snapname)
l.Info("create snapshot") l.Info("create snapshot")
err := zfs.ZFSSnapshot(d, snapname, false) err := zfs.ZFSSnapshot(fs, snapname, false)
if err != nil { if err != nil {
a.task.Log().WithError(err).Error("cannot create snapshot") l.WithError(err).Error("cannot create snapshot")
return
} }
l.Info("create corresponding bookmark") l.Info("create corresponding bookmark")
err = zfs.ZFSBookmark(d, snapname, snapname) err = zfs.ZFSBookmark(fs, snapname, snapname)
if err != nil { if err != nil {
a.task.Log().WithError(err).Error("cannot create bookmark") l.WithError(err).Error("cannot create bookmark")
} }
}(fss[fsi])
} }
a.task.Log().Info("waiting for parallel snapshots to finish")
wg.Wait()
a.task.Log().Info("snapshots finished")
select { select {
case didSnaps <- struct{}{}: case didSnaps <- struct{}{}:
default: default: