diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-07 01:35:08 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-14 21:31:45 -0600 |
commit | 4278c185aafb0fb197e52cdb9eb9bd9d36b61c4d (patch) | |
tree | 865db7f28999b5ad71a9805b4b5bfa49f515957e | |
parent | 7c9ea276ac69130229f4ae35547288fe8429f6f1 (diff) |
cmd/btrfs-rec: Smash scandevices and rebuild-mappings together
-rw-r--r-- | cmd/btrfs-rec/inspect_lstrees.go | 2 | ||||
-rw-r--r-- | cmd/btrfs-rec/inspect_rebuildmappings.go | 71 | ||||
-rw-r--r-- | cmd/btrfs-rec/inspect_scandevices.go | 69 | ||||
-rw-r--r-- | cmd/btrfs-rec/util.go | 25 | ||||
-rwxr-xr-x | scripts/main.sh | 8 |
5 files changed, 97 insertions, 78 deletions
diff --git a/cmd/btrfs-rec/inspect_lstrees.go b/cmd/btrfs-rec/inspect_lstrees.go index be72860..1ff7671 100644 --- a/cmd/btrfs-rec/inspect_lstrees.go +++ b/cmd/btrfs-rec/inspect_lstrees.go @@ -114,7 +114,7 @@ func init() { return nil }), } - cmd.Flags().StringVar(&scandevicesFilename, "scandevices", "", "Output of 'scandevices' to use for a lost+found tree") + cmd.Flags().StringVar(&scandevicesFilename, "scandevices", "", "Output of 'btrfs-recs inspect rebuild-mappings scan' to use for a lost+found tree") noError(cmd.MarkFlagFilename("scandevices")) inspectors.AddCommand(cmd) diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index 81660b0..55e3408 100644 --- a/cmd/btrfs-rec/inspect_rebuildmappings.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -17,8 +17,8 @@ import ( ) func init() { - inspectors.AddCommand(&cobra.Command{ - Use: "rebuild-mappings SCAN_RESULT.json", + cmd := &cobra.Command{ + Use: "rebuild-mappings", Short: "Rebuild broken chunk/dev-extent/blockgroup trees", Long: "" + "The rebuilt information is printed as JSON on stdout, and can\n" + @@ -27,8 +27,69 @@ func init() { "This is very similar to `btrfs rescue chunk-recover`, but (1)\n" + "does a better job, (2) is less buggy, and (3) doesn't actually\n" + "write the info back to the filesystem; instead writing it\n" + - "out-of-band to stdout.", - Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)), + "out-of-band to stdout.\n" + + "\n" + + "The I/O and the CPU parts of this can be split up as:\n" + + "\n" + + "\tbtrfs-rec inspect rebuild-mappings scan > SCAN.json # read\n" + + "\tbtrfs-rec inspect rebuild-mappings process SCAN.json # CPU\n", + Args: cliutil.WrapPositionalArgs(cobra.NoArgs), + RunE: runWithRawFS(func(fs *btrfs.FS, cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + scanResults, err := rebuildmappings.ScanDevices(ctx, fs) + if err != nil { + return err + } + + if err := rebuildmappings.RebuildMappings(ctx, fs, scanResults); err != nil { + return err + } + + dlog.Infof(ctx, "Writing reconstructed mappings to stdout...") + if err := writeJSONFile(os.Stdout, fs.LV.Mappings(), lowmemjson.ReEncoderConfig{ + Indent: "\t", + ForceTrailingNewlines: true, + CompactIfUnder: 120, //nolint:gomnd // This is what looks nice. + }); err != nil { + return err + } + dlog.Info(ctx, "... done writing") + + return nil + }), + } + + cmd.AddCommand(&cobra.Command{ + Use: "scan", + Short: "Read from the filesystem all data nescessary to rebuild the mappings", + Args: cliutil.WrapPositionalArgs(cobra.NoArgs), + RunE: runWithRawFS(func(fs *btrfs.FS, cmd *cobra.Command, _ []string) (err error) { + ctx := cmd.Context() + + scanResults, err := rebuildmappings.ScanDevices(ctx, fs) + if err != nil { + return err + } + + dlog.Info(ctx, "Writing scan results to stdout...") + if err := writeJSONFile(os.Stdout, scanResults, lowmemjson.ReEncoderConfig{ + Indent: "\t", + ForceTrailingNewlines: true, + CompactIfUnder: 16, //nolint:gomnd // This is what looks nice. + }); err != nil { + return err + } + dlog.Info(ctx, "... done writing") + + return nil + }), + }) + + cmd.AddCommand(&cobra.Command{ + Use: "process", + Short: "Rebuild the mappings based on previously read data", + Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)), RunE: runWithRawFS(func(fs *btrfs.FS, cmd *cobra.Command, args []string) error { ctx := cmd.Context() @@ -56,4 +117,6 @@ func init() { return nil }), }) + + inspectors.AddCommand(cmd) } diff --git a/cmd/btrfs-rec/inspect_scandevices.go b/cmd/btrfs-rec/inspect_scandevices.go deleted file mode 100644 index 4172c7c..0000000 --- a/cmd/btrfs-rec/inspect_scandevices.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package main - -import ( - "context" - "os" - - "git.lukeshu.com/go/lowmemjson" - "github.com/datawire/dlib/dlog" - "github.com/datawire/ocibuild/pkg/cliutil" - "github.com/spf13/cobra" - - "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" - "git.lukeshu.com/btrfs-progs-ng/lib/containers" - "git.lukeshu.com/btrfs-progs-ng/lib/maps" -) - -func init() { - inspectors.AddCommand(&cobra.Command{ - Use: "scandevices", - Args: cliutil.WrapPositionalArgs(cobra.NoArgs), - RunE: runWithRawFS(func(fs *btrfs.FS, cmd *cobra.Command, _ []string) (err error) { - ctx := cmd.Context() - - results, err := rebuildmappings.ScanDevices(ctx, fs) - if err != nil { - return err - } - - dlog.Info(ctx, "Writing scan results to stdout...") - if err := writeJSONFile(os.Stdout, results, lowmemjson.ReEncoderConfig{ - Indent: "\t", - ForceTrailingNewlines: true, - CompactIfUnder: 16, //nolint:gomnd // This is what looks nice. - }); err != nil { - return err - } - dlog.Info(ctx, "... done writing") - - return nil - }), - }) -} - -func readNodeList(ctx context.Context, filename string) ([]btrfsvol.LogicalAddr, error) { - if filename == "" { - return nil, nil - } - results, err := readJSONFile[rebuildmappings.ScanDevicesResult](ctx, filename) - if err != nil { - return nil, err - } - var cnt int - for _, devResults := range results { - cnt += len(devResults.FoundNodes) - } - set := make(containers.Set[btrfsvol.LogicalAddr], cnt) - for _, devResults := range results { - for laddr := range devResults.FoundNodes { - set.Insert(laddr) - } - } - return maps.SortedKeys(set), nil -} diff --git a/cmd/btrfs-rec/util.go b/cmd/btrfs-rec/util.go index 3d751a6..2e4bb84 100644 --- a/cmd/btrfs-rec/util.go +++ b/cmd/btrfs-rec/util.go @@ -13,6 +13,10 @@ import ( "git.lukeshu.com/go/lowmemjson" "github.com/datawire/dlib/dlog" + "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/containers" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" "git.lukeshu.com/btrfs-progs-ng/lib/streamio" ) @@ -47,3 +51,24 @@ func writeJSONFile(w io.Writer, obj any, cfg lowmemjson.ReEncoderConfig) (err er }() return lowmemjson.NewEncoder(lowmemjson.NewReEncoder(buffer, cfg)).Encode(obj) } + +func readNodeList(ctx context.Context, filename string) ([]btrfsvol.LogicalAddr, error) { + if filename == "" { + return nil, nil + } + results, err := readJSONFile[rebuildmappings.ScanDevicesResult](ctx, filename) + if err != nil { + return nil, err + } + var cnt int + for _, devResults := range results { + cnt += len(devResults.FoundNodes) + } + set := make(containers.Set[btrfsvol.LogicalAddr], cnt) + for _, devResults := range results { + for laddr := range devResults.FoundNodes { + set.Insert(laddr) + } + } + return maps.SortedKeys(set), nil +} diff --git a/scripts/main.sh b/scripts/main.sh index 4aa96ea..67fb330 100755 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -32,9 +32,9 @@ export GOMEMLIMIT="$(awk '/^MemTotal:/{ print $2 "KiB" }' </proc/meminfo)" ###################################################################### run-btrfs-rec $gendir/0.scandevices.json \ - inspect scandevices + inspect rebuild-mappings scan run-btrfs-rec $gendir/1.mappings.json \ - inspect rebuild-mappings $gendir/0.scandevices.json + inspect rebuild-mappings process $gendir/0.scandevices.json # 1.mappings.log says: # @@ -52,13 +52,13 @@ run-btrfs-rec $gendir/1.mappings.json \ # matter which order we put the 2 block groups in within that physical # region. So just put them in laddr order. # -# And then run that through `rebuild-mappings` again to fill in the +# And then run that through `rebuild-mappings process` again to fill in the # flags and normalize it. run-btrfs-rec $gendir/2.mappings.json \ --mappings=<(sed <$gendir/1.mappings.json \ -e '2a{"LAddr":5242880,"PAddr":{"Dev":1,"Addr":5242880},"Size":1},' \ -e '2a{"LAddr":13631488,"PAddr":{"Dev":1,"Addr":13631488},"Size":1},') \ - inspect rebuild-mappings $gendir/0.scandevices.json + inspect rebuild-mappings process $gendir/0.scandevices.json run-btrfs-rec $gendir/3.nodes.json \ --mappings=$gendir/2.mappings.json \ |