From 058f8c36f6bf9ae2600bf7da33d680ced41eae9a Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 6 Mar 2023 10:42:51 -0700 Subject: cmd/btrfs-rec: Have each subcommand call runWithRawFS itself --- cmd/btrfs-rec/inspect_rebuildmappings.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'cmd/btrfs-rec/inspect_rebuildmappings.go') diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index 005fd5d..81660b0 100644 --- a/cmd/btrfs-rec/inspect_rebuildmappings.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -17,21 +17,19 @@ import ( ) func init() { - inspectors = append(inspectors, subcommand{ - Command: cobra.Command{ - Use: "rebuild-mappings SCAN_RESULT.json", - Short: "Rebuild broken chunk/dev-extent/blockgroup trees", - Long: "" + - "The rebuilt information is printed as JSON on stdout, and can\n" + - "be loaded by the --mappings flag.\n" + - "\n" + - "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)), - }, - RunE: func(fs *btrfs.FS, cmd *cobra.Command, args []string) error { + inspectors.AddCommand(&cobra.Command{ + Use: "rebuild-mappings SCAN_RESULT.json", + Short: "Rebuild broken chunk/dev-extent/blockgroup trees", + Long: "" + + "The rebuilt information is printed as JSON on stdout, and can\n" + + "be loaded by the --mappings flag.\n" + + "\n" + + "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)), + RunE: runWithRawFS(func(fs *btrfs.FS, cmd *cobra.Command, args []string) error { ctx := cmd.Context() dlog.Infof(ctx, "Reading %q...", args[0]) @@ -56,6 +54,6 @@ func init() { dlog.Info(ctx, "... done writing") return nil - }, + }), }) } -- cgit v1.2.3-2-g168b From 4278c185aafb0fb197e52cdb9eb9bd9d36b61c4d Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 7 Mar 2023 01:35:08 -0700 Subject: cmd/btrfs-rec: Smash scandevices and rebuild-mappings together --- cmd/btrfs-rec/inspect_rebuildmappings.go | 71 ++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) (limited to 'cmd/btrfs-rec/inspect_rebuildmappings.go') 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) } -- cgit v1.2.3-2-g168b From 9319e1788d0816dfd843de759f3b6553ce026ca5 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 7 Mar 2023 01:52:07 -0700 Subject: cmd/btrfs-rec: Fix newlines in `inspect rebuild-mappings --help` --- cmd/btrfs-rec/inspect_rebuildmappings.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd/btrfs-rec/inspect_rebuildmappings.go') diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index 55e3408..9c6b1cc 100644 --- a/cmd/btrfs-rec/inspect_rebuildmappings.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -21,12 +21,12 @@ func init() { Use: "rebuild-mappings", Short: "Rebuild broken chunk/dev-extent/blockgroup trees", Long: "" + - "The rebuilt information is printed as JSON on stdout, and can\n" + + "The rebuilt information is printed as JSON on stdout, and can " + "be loaded by the --mappings flag.\n" + "\n" + - "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" + + "This is very similar to `btrfs rescue chunk-recover`, but (1) " + + "does a better job, (2) is less buggy, and (3) doesn't actually " + + "write the info back to the filesystem; instead writing it " + "out-of-band to stdout.\n" + "\n" + "The I/O and the CPU parts of this can be split up as:\n" + -- cgit v1.2.3-2-g168b From 3949bd3ff240bc6d06dd08f6e3183e72571e0e1d Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 7 Mar 2023 12:10:42 -0700 Subject: Expose node-lists as a thing on the CLI --- cmd/btrfs-rec/inspect_rebuildmappings.go | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'cmd/btrfs-rec/inspect_rebuildmappings.go') diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index 9c6b1cc..b215e7a 100644 --- a/cmd/btrfs-rec/inspect_rebuildmappings.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -14,6 +14,9 @@ import ( "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() { @@ -118,5 +121,46 @@ func init() { }), }) + cmd.AddCommand(&cobra.Command{ + Use: "list-nodes", + Short: "Produce a listing of btree nodes from previously read data", + Long: "" + + "This is a variant of `btrfs-rec inspect list-nodes` that takes " + + "advantage of using previously read data from " + + "`btrfs-rec inspect rebuild-nodes scan`.", + Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + scanResults, err := readJSONFile[rebuildmappings.ScanDevicesResult](ctx, args[0]) + if err != nil { + return err + } + + var cnt int + for _, devResults := range scanResults { + cnt += len(devResults.FoundNodes) + } + set := make(containers.Set[btrfsvol.LogicalAddr], cnt) + for _, devResults := range scanResults { + for laddr := range devResults.FoundNodes { + set.Insert(laddr) + } + } + nodeList := maps.SortedKeys(set) + + dlog.Infof(ctx, "Writing nodes to stdout...") + if err := writeJSONFile(os.Stdout, nodeList, lowmemjson.ReEncoderConfig{ + Indent: "\t", + ForceTrailingNewlines: true, + }); err != nil { + return err + } + dlog.Info(ctx, "... done writing") + + return nil + }, + }) + inspectors.AddCommand(cmd) } -- cgit v1.2.3-2-g168b From afd2fe91ec604491bd8978b1880c6482e7394240 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 10 Mar 2023 22:02:23 -0700 Subject: cmd/btrfs-rec: inspect rebuild-mappings list-nodes: Set up logging and stuff --- cmd/btrfs-rec/inspect_rebuildmappings.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd/btrfs-rec/inspect_rebuildmappings.go') diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index b215e7a..43c45b1 100644 --- a/cmd/btrfs-rec/inspect_rebuildmappings.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -129,7 +129,7 @@ func init() { "advantage of using previously read data from " + "`btrfs-rec inspect rebuild-nodes scan`.", Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: run(func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() scanResults, err := readJSONFile[rebuildmappings.ScanDevicesResult](ctx, args[0]) @@ -159,7 +159,7 @@ func init() { dlog.Info(ctx, "... done writing") return nil - }, + }), }) inspectors.AddCommand(cmd) -- cgit v1.2.3-2-g168b