From 211f828987934b8799d7971a731cd971f5eaa2dd Mon Sep 17 00:00:00 2001 From: Sandy Xu Date: Wed, 24 Apr 2024 15:56:43 +0800 Subject: [PATCH 1/2] cmd/dump: use a temp file during dumping --- cmd/dump.go | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/cmd/dump.go b/cmd/dump.go index 2b810cb189ba..63dfcfac6af6 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -72,25 +72,26 @@ Details: https://juicefs.com/docs/community/metadata_dump_load`, } } -func dump(ctx *cli.Context) (err error) { - setup(ctx, 1) - metaUri := ctx.Args().Get(0) - dst := ctx.Args().Get(1) - removePassword(metaUri) +func dumpMeta(m meta.Meta, dst string, threads int, keepSecret, fast, skipTrash bool) (err error) { var w io.WriteCloser - if ctx.Args().Len() == 1 { + if dst == "" { w = os.Stdout - dst = "STDOUT" } else { - fp, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) - if err != nil { - return err + tmp := dst + ".tmp" + fp, e := os.OpenFile(tmp, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + if e != nil { + return e } defer func() { e := fp.Close() if err == nil { err = e } + if err == nil { + err = os.Rename(tmp, dst) + } else { + _ = os.Remove(tmp) + } }() if strings.HasSuffix(dst, ".gz") { zw := gzip.NewWriter(fp) @@ -105,6 +106,17 @@ func dump(ctx *cli.Context) (err error) { w = fp } } + return m.DumpMeta(w, 1, threads, keepSecret, fast, skipTrash) +} + +func dump(ctx *cli.Context) error { + setup(ctx, 1) + metaUri := ctx.Args().Get(0) + var dst string + if ctx.Args().Len() > 1 { + dst = ctx.Args().Get(1) + } + removePassword(metaUri) metaConf := meta.DefaultConf() metaConf.Subdir = ctx.String("subdir") m := meta.NewClient(metaUri, metaConf) @@ -119,9 +131,12 @@ func dump(ctx *cli.Context) (err error) { logger.Warnf("Invalid threads number %d, reset to 1", threads) threads = 1 } - if err := m.DumpMeta(w, 1, threads, ctx.Bool("keep-secret-key"), ctx.Bool("fast"), ctx.Bool("skip-trash")); err != nil { - return err + err := dumpMeta(m, dst, threads, ctx.Bool("keep-secret-key"), ctx.Bool("fast"), ctx.Bool("skip-trash")) + if err == nil { + if dst == "" { + dst = "STDOUT" + } + logger.Infof("Dump metadata into %s succeed", dst) } - logger.Infof("Dump metadata into %s succeed", dst) - return nil + return err } From c2144331ec390b74fd5819cb3d66d862a03e562a Mon Sep 17 00:00:00 2001 From: Sandy Xu Date: Wed, 24 Apr 2024 16:03:32 +0800 Subject: [PATCH 2/2] fix --- cmd/dump.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/dump.go b/cmd/dump.go index 63dfcfac6af6..4518b03ea6a5 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -93,6 +93,7 @@ func dumpMeta(m meta.Meta, dst string, threads int, keepSecret, fast, skipTrash _ = os.Remove(tmp) } }() + if strings.HasSuffix(dst, ".gz") { zw := gzip.NewWriter(fp) defer func() { @@ -117,6 +118,7 @@ func dump(ctx *cli.Context) error { dst = ctx.Args().Get(1) } removePassword(metaUri) + metaConf := meta.DefaultConf() metaConf.Subdir = ctx.String("subdir") m := meta.NewClient(metaUri, metaConf) @@ -126,6 +128,7 @@ func dump(ctx *cli.Context) error { if st := m.Chroot(meta.Background, metaConf.Subdir); st != 0 { return st } + threads := ctx.Int("threads") if threads <= 0 { logger.Warnf("Invalid threads number %d, reset to 1", threads)