mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-22 16:34:32 +01:00
3ba3648f0f
The old approach with ZFSList would keep the two-dimensional array of lines and their fields in memory (for a short time), which could easily consume 100s of MiB with > 10000 snapshots / bookmarks (see #34) fixes #61
48 lines
863 B
Go
48 lines
863 B
Go
package zfs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
type DatasetFilter interface {
|
|
Filter(p *DatasetPath) (pass bool, err error)
|
|
}
|
|
|
|
func ZFSListMapping(filter DatasetFilter) (datasets []*DatasetPath, err error) {
|
|
|
|
if filter == nil {
|
|
panic("filter must not be nil")
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
rchan := make(chan ZFSListResult)
|
|
go ZFSListChan(ctx, rchan, []string{"name"}, "-r", "-t", "filesystem,volume")
|
|
|
|
datasets = make([]*DatasetPath, 0)
|
|
for r := range rchan {
|
|
|
|
if r.err != nil {
|
|
err = r.err
|
|
return
|
|
}
|
|
|
|
var path *DatasetPath
|
|
if path, err = NewDatasetPath(r.fields[0]); err != nil {
|
|
return
|
|
}
|
|
|
|
pass, filterErr := filter.Filter(path)
|
|
if filterErr != nil {
|
|
return nil, fmt.Errorf("error calling filter: %s", filterErr)
|
|
}
|
|
if pass {
|
|
datasets = append(datasets, path)
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
}
|