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
suffix := time.Now().In(time.UTC).Format("20060102_150405_000") for fsi := range fss {
snapname := fmt.Sprintf("%s%s", a.Prefix, suffix) wg.Add(1)
go func(fs *zfs.DatasetPath) {
defer wg.Done()
l := a.task.Log().WithField(logFSField, d.ToString()). suffix := time.Now().In(time.UTC).Format("20060102_150405_000")
WithField("snapname", snapname) snapname := fmt.Sprintf("%s%s", a.Prefix, suffix)
l.Info("create snapshot") l := a.task.Log().WithField(logFSField, fs.ToString()).
err := zfs.ZFSSnapshot(d, snapname, false) WithField("snapname", snapname)
if err != nil {
a.task.Log().WithError(err).Error("cannot create snapshot")
}
l.Info("create corresponding bookmark") l.Info("create snapshot")
err = zfs.ZFSBookmark(d, snapname, snapname) err := zfs.ZFSSnapshot(fs, snapname, false)
if err != nil { if err != nil {
a.task.Log().WithError(err).Error("cannot create bookmark") l.WithError(err).Error("cannot create snapshot")
} return
}
l.Info("create corresponding bookmark")
err = zfs.ZFSBookmark(fs, snapname, snapname)
if err != nil {
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: