summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-12-29 23:53:55 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-01-05 19:48:17 -0700
commit6ce1332d3cac5b74d2f049861f04cc2fa282d747 (patch)
tree198b1688b1329ee042175fd369b30b953f15accb
parent8efc82d0b1a167830970135c78d173667080b116 (diff)
cmd/btrfs-rec inspect rebuild-nodes: Optimize memory use
-rw-r--r--cmd/btrfs-rec/inspect_rebuildnodes.go25
-rw-r--r--lib/textui/log_memstats.go4
2 files changed, 20 insertions, 9 deletions
diff --git a/cmd/btrfs-rec/inspect_rebuildnodes.go b/cmd/btrfs-rec/inspect_rebuildnodes.go
index 9c86c3a..d813f36 100644
--- a/cmd/btrfs-rec/inspect_rebuildnodes.go
+++ b/cmd/btrfs-rec/inspect_rebuildnodes.go
@@ -5,7 +5,10 @@
package main
import (
+ "context"
"os"
+ "runtime"
+ "time"
"git.lukeshu.com/go/lowmemjson"
"github.com/datawire/dlib/dlog"
@@ -15,6 +18,7 @@ import (
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes"
+ "git.lukeshu.com/btrfs-progs-ng/lib/textui"
)
func init() {
@@ -26,18 +30,25 @@ func init() {
RunE: func(fs *btrfs.FS, cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
- dlog.Infof(ctx, "Reading %q...", args[0])
- nodeScanResults, err := readJSONFile[btrfsinspect.ScanDevicesResult](ctx, args[0])
- if err != nil {
- return err
- }
- dlog.Infof(ctx, "... done reading %q", args[0])
+ // This is wrapped in a func in order to *ensure* that `nodeScanResults` goes out of scope once
+ // `rebuilder` has been created.
+ rebuilder, err := func(ctx context.Context) (rebuildnodes.Rebuilder, error) {
+ dlog.Infof(ctx, "Reading %q...", args[0])
+ nodeScanResults, err := readJSONFile[btrfsinspect.ScanDevicesResult](ctx, args[0])
+ if err != nil {
+ return nil, err
+ }
+ dlog.Infof(ctx, "... done reading %q", args[0])
- rebuilder, err := rebuildnodes.NewRebuilder(ctx, fs, nodeScanResults)
+ return rebuildnodes.NewRebuilder(ctx, fs, nodeScanResults)
+ }(ctx)
if err != nil {
return err
}
+ runtime.GC()
+ time.Sleep(textui.LiveMemUseUpdateInterval) // let the logs reflect that GC right away
+
dlog.Info(ctx, "Rebuilding node tree...")
rebuildErr := rebuilder.Rebuild(ctx)
dst := os.Stdout
diff --git a/lib/textui/log_memstats.go b/lib/textui/log_memstats.go
index 6e3c3a1..7ef35da 100644
--- a/lib/textui/log_memstats.go
+++ b/lib/textui/log_memstats.go
@@ -19,14 +19,14 @@ type LiveMemUse struct {
var _ fmt.Stringer = (*LiveMemUse)(nil)
-var liveMemUseUpdateInterval = Tunable(1 * time.Second)
+var LiveMemUseUpdateInterval = Tunable(1 * time.Second)
func (o *LiveMemUse) String() string {
o.mu.Lock()
// runtime.ReadMemStats() calls stopTheWorld(), so we want to
// rate-limit how often we call it.
- if now := time.Now(); now.Sub(o.last) > liveMemUseUpdateInterval {
+ if now := time.Now(); now.Sub(o.last) > LiveMemUseUpdateInterval {
runtime.ReadMemStats(&o.stats)
o.last = now
}