Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd: add dump command to dump metadata to a file and load to load from a file #510

Merged
merged 12 commits into from
Jun 15, 2021
Merged
51 changes: 51 additions & 0 deletions cmd/dump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* JuiceFS, Copyright (C) 2021 Juicedata, Inc.
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package main

import (
"fmt"
"os"

"github.com/juicedata/juicefs/pkg/meta"
"github.com/urfave/cli/v2"
)

func dump(ctx *cli.Context) error {
setLoggerLevel(ctx)
if ctx.Args().Len() < 1 {
return fmt.Errorf("META-ADDR is needed")
}
m := meta.NewClient(ctx.Args().Get(0), &meta.Config{Retries: 10, Strict: true})
fname := "juicefs-metadata.dump"
if ctx.Args().Len() > 1 {
fname = ctx.Args().Get(1)
}
fp, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer fp.Close()
return m.DumpMeta(fp)
}

func dumpFlags() *cli.Command {
return &cli.Command{
Name: "dump",
Usage: "dump JuiceFS metadata into a standalone file",
ArgsUsage: "META-ADDR [FILE (default: juicefs-metadata.dump)]",
Action: dump,
}
}
50 changes: 50 additions & 0 deletions cmd/load.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* JuiceFS, Copyright (C) 2021 Juicedata, Inc.
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package main

import (
"fmt"
"io/ioutil"

"github.com/juicedata/juicefs/pkg/meta"
"github.com/urfave/cli/v2"
)

func load(ctx *cli.Context) error {
setLoggerLevel(ctx)
if ctx.Args().Len() < 1 {
return fmt.Errorf("META-ADDR is needed")
}
if ctx.Args().Len() < 2 {
return fmt.Errorf("FILE is needed")
}
m := meta.NewClient(ctx.Args().Get(0), &meta.Config{Retries: 10, Strict: true})
fname := ctx.Args().Get(1)
buf, err := ioutil.ReadFile(fname)
if err != nil {
return err
}
return m.LoadMeta(buf)
}

func loadFlags() *cli.Command {
return &cli.Command{
Name: "load",
Usage: "load JuiceFS metadata from a previously dumped file",
ArgsUsage: "META-ADDR FILE",
Action: load,
}
}
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ func main() {
profileFlags(),
statusFlags(),
warmupFlags(),
dumpFlags(),
loadFlags(),
},
}

Expand Down
46 changes: 46 additions & 0 deletions pkg/meta/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package meta

import (
"io"
"os"
"strings"
"syscall"
Expand Down Expand Up @@ -106,6 +107,48 @@ func typeToStatType(_type uint8) uint32 {
}
}

func typeToString(_type uint8) string {
switch _type {
case TypeFile:
return "regular"
case TypeDirectory:
return "directory"
case TypeSymlink:
return "symlink"
case TypeFIFO:
return "fifo"
case TypeBlockDev:
return "blockdev"
case TypeCharDev:
return "chardev"
case TypeSocket:
return "socket"
default:
return "unknown"
}
}

func typeFromString(s string) uint8 {
switch s {
case "regular":
return TypeFile
case "directory":
return TypeDirectory
case "symlink":
return TypeSymlink
case "fifo":
return TypeFIFO
case "blockdev":
return TypeBlockDev
case "chardev":
return TypeCharDev
case "socket":
return TypeSocket
default:
panic(s)
}
}

// SMode is the file mode including type and unix permission.
func (a Attr) SMode() uint32 {
return typeToStatType(a.Typ) | uint32(a.Mode)
Expand Down Expand Up @@ -254,6 +297,9 @@ type Meta interface {

// OnMsg add a callback for the given message type.
OnMsg(mtype uint32, cb MsgCallback)

DumpMeta(w io.Writer) error
LoadMeta(buf []byte) error
}

func removePassword(uri string) string {
Expand Down
Loading