summaryrefslogtreecommitdiff
path: root/cmd/btrfs-rec/inspect_scandevices.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/btrfs-rec/inspect_scandevices.go')
-rw-r--r--cmd/btrfs-rec/inspect_scandevices.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/cmd/btrfs-rec/inspect_scandevices.go b/cmd/btrfs-rec/inspect_scandevices.go
new file mode 100644
index 0000000..f5caadb
--- /dev/null
+++ b/cmd/btrfs-rec/inspect_scandevices.go
@@ -0,0 +1,72 @@
+// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package main
+
+import (
+ "bufio"
+ "context"
+ "os"
+ "sync"
+
+ "git.lukeshu.com/go/lowmemjson"
+ "github.com/datawire/dlib/dgroup"
+ "github.com/datawire/dlib/dlog"
+ "github.com/datawire/ocibuild/pkg/cliutil"
+ "github.com/spf13/cobra"
+
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect"
+)
+
+func init() {
+ inspectors = append(inspectors, subcommand{
+ Command: cobra.Command{
+ Use: "scandevices",
+ Args: cliutil.WrapPositionalArgs(cobra.NoArgs),
+ },
+ RunE: func(fs *btrfs.FS, cmd *cobra.Command, _ []string) (err error) {
+ maybeSetErr := func(_err error) {
+ if err == nil && _err != nil {
+ err = _err
+ }
+ }
+ ctx := cmd.Context()
+
+ var resultsMu sync.Mutex
+ results := make(map[btrfsvol.DeviceID]btrfsinspect.ScanOneDeviceResult)
+ grp := dgroup.NewGroup(ctx, dgroup.GroupConfig{})
+ for _, dev := range fs.LV.PhysicalVolumes() {
+ dev := dev
+ grp.Go(dev.Name(), func(ctx context.Context) error {
+ superblock, err := dev.Superblock()
+ if err != nil {
+ return err
+ }
+ dlog.Infof(ctx, "dev[%q] Scanning for unreachable nodes...", dev.Name())
+ devResult, err := btrfsinspect.ScanOneDevice(ctx, dev, *superblock)
+ dlog.Infof(ctx, "dev[%q] Finished scanning", dev.Name())
+ resultsMu.Lock()
+ results[superblock.DevItem.DevID] = devResult
+ resultsMu.Unlock()
+ return err
+ })
+ }
+ if err := grp.Wait(); err != nil {
+ return err
+ }
+
+ dlog.Info(ctx, "Writing scan results to stdout...")
+ buffer := bufio.NewWriter(os.Stdout)
+ defer func() {
+ maybeSetErr(buffer.Flush())
+ }()
+ return lowmemjson.Encode(&lowmemjson.ReEncoder{
+ Out: buffer,
+ Indent: "\t",
+ }, results)
+ },
+ })
+}