diff options
Diffstat (limited to 'cmd/btrfs-rec')
-rw-r--r-- | cmd/btrfs-rec/inspect_rebuildmappings.go (renamed from cmd/btrfs-rec/inspect_recoverchunks.go) | 39 | ||||
-rw-r--r-- | cmd/btrfs-rec/inspect_scanfornodes.go | 5 | ||||
-rw-r--r-- | cmd/btrfs-rec/main.go | 6 |
3 files changed, 27 insertions, 23 deletions
diff --git a/cmd/btrfs-rec/inspect_recoverchunks.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index 4314b66..c32bf53 100644 --- a/cmd/btrfs-rec/inspect_recoverchunks.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -15,13 +15,15 @@ import ( "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" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" ) func init() { inspectors = append(inspectors, subcommand{ Command: cobra.Command{ - Use: "recover-chunks", + 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" + @@ -31,32 +33,35 @@ func init() { "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.NoArgs), + Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)), }, - RunE: func(fs *btrfs.FS, cmd *cobra.Command, _ []string) error { + RunE: func(fs *btrfs.FS, cmd *cobra.Command, args []string) error { ctx := cmd.Context() - dlog.Info(ctx, "Reading superblock...") - superblock, err := fs.Superblock() + scanResultsBytes, err := os.ReadFile(args[0]) if err != nil { return err } + var scanResults map[btrfsvol.DeviceID]btrfsinspect.ScanOneDevResult + if err := json.Unmarshal(scanResultsBytes, &scanResults); err != nil { + return err + } - for _, dev := range fs.LV.PhysicalVolumes() { - dlog.Infof(ctx, "dev[%q] Scanning for unreachable nodes...", dev.Name()) - devResult, err := btrfsinspect.ScanOneDev(ctx, dev, *superblock) - if err != nil { - return err + devices := fs.LV.PhysicalVolumes() + for _, devID := range maps.SortedKeys(scanResults) { + dev, ok := devices[devID] + if !ok { + return fmt.Errorf("device ID %v mentioned in %q is not part of the filesystem", + devID, args[0]) } - - dlog.Infof(ctx, "dev[%q] Re-inserting lost+found mappings...", dev.Name()) - devResult.AddToLV(ctx, fs, dev) + dlog.Infof(ctx, "Rebuilding mappings from results on device %v...", + dev.Name()) + scanResults[devID].AddToLV(ctx, fs, dev) } dlog.Infof(ctx, "Writing reconstructed mappings to stdout...") - mappings := fs.LV.Mappings() - _, _ = io.WriteString(os.Stdout, "{\n \"Mappings\": [\n") + _, _ = io.WriteString(os.Stdout, "[\n") for i, mapping := range mappings { suffix := "," if i == len(mappings)-1 { @@ -66,9 +71,9 @@ func init() { if err != nil { return err } - fmt.Printf(" %s%s\n", bs, suffix) + fmt.Printf(" %s%s\n", bs, suffix) } - _, _ = io.WriteString(os.Stdout, " ]\n}\n") + _, _ = io.WriteString(os.Stdout, "]\n") return nil }, }) diff --git a/cmd/btrfs-rec/inspect_scanfornodes.go b/cmd/btrfs-rec/inspect_scanfornodes.go index 3eee46c..9dbc3a5 100644 --- a/cmd/btrfs-rec/inspect_scanfornodes.go +++ b/cmd/btrfs-rec/inspect_scanfornodes.go @@ -26,7 +26,8 @@ func init() { Use: "scan-for-nodes", Short: "Scan devices for (potentially lost) nodes", Long: "" + - "The found information is printed as JSON on stdout.\n" + + "The found information is printed as JSON on stdout, and can\n" + + "be read by `btrfs-rec inspect rebuild-mappings`.\n" + "\n" + "This information is mostly useful for rebuilding a broken\n" + "chunk/dev-extent/blockgroup trees, but can also have some\n" + @@ -63,7 +64,7 @@ func init() { return err } - dlog.Info(ctx, "Serializing results...") + dlog.Info(ctx, "Writing scan results to stdout...") return json.NewEncoder(os.Stdout).Encode(results) }, }) diff --git a/cmd/btrfs-rec/main.go b/cmd/btrfs-rec/main.go index b17c8ec..c808237 100644 --- a/cmd/btrfs-rec/main.go +++ b/cmd/btrfs-rec/main.go @@ -141,13 +141,11 @@ func main() { if err != nil { return err } - var mappingsJSON struct { - Mappings []btrfsvol.Mapping - } + var mappingsJSON []btrfsvol.Mapping if err := json.Unmarshal(bs, &mappingsJSON); err != nil { return err } - for _, mapping := range mappingsJSON.Mappings { + for _, mapping := range mappingsJSON { if err := fs.LV.AddMapping(mapping); err != nil { return err } |