command_fs_meta_load.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package shell
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "os"
  7. "github.com/chrislusf/seaweedfs/weed/filer2"
  8. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  9. "github.com/chrislusf/seaweedfs/weed/util"
  10. "github.com/golang/protobuf/proto"
  11. )
  12. func init() {
  13. Commands = append(Commands, &commandFsMetaLoad{})
  14. }
  15. type commandFsMetaLoad struct {
  16. }
  17. func (c *commandFsMetaLoad) Name() string {
  18. return "fs.meta.load"
  19. }
  20. func (c *commandFsMetaLoad) Help() string {
  21. return `load saved filer meta data to restore the directory and file structure
  22. fs.meta.load <filer_host>-<port>-<time>.meta
  23. `
  24. }
  25. func (c *commandFsMetaLoad) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
  26. if len(args) == 0 {
  27. fmt.Fprintf(writer, "missing a metadata file\n")
  28. return nil
  29. }
  30. filerServer, filerPort, path, err := commandEnv.parseUrl(findInputDirectory(nil))
  31. if err != nil {
  32. return err
  33. }
  34. fileName := args[len(args)-1]
  35. dst, err := os.OpenFile(fileName, os.O_RDONLY, 0644)
  36. if err != nil {
  37. return nil
  38. }
  39. defer dst.Close()
  40. var dirCount, fileCount uint64
  41. ctx := context.Background()
  42. err = commandEnv.withFilerClient(ctx, filerServer, filerPort, func(ctx context.Context, client filer_pb.SeaweedFilerClient) error {
  43. sizeBuf := make([]byte, 4)
  44. for {
  45. if n, err := dst.Read(sizeBuf); n != 4 {
  46. if err == io.EOF {
  47. return nil
  48. }
  49. return err
  50. }
  51. size := util.BytesToUint32(sizeBuf)
  52. data := make([]byte, int(size))
  53. if n, err := dst.Read(data); n != len(data) {
  54. return err
  55. }
  56. fullEntry := &filer_pb.FullEntry{}
  57. if err = proto.Unmarshal(data, fullEntry); err != nil {
  58. return err
  59. }
  60. if err := filer_pb.CreateEntry(ctx, client, &filer_pb.CreateEntryRequest{
  61. Directory: fullEntry.Dir,
  62. Entry: fullEntry.Entry,
  63. }); err != nil {
  64. return err
  65. }
  66. fmt.Fprintf(writer, "load %s\n", filer2.FullPath(fullEntry.Dir).Child(fullEntry.Entry.Name))
  67. if fullEntry.Entry.IsDirectory {
  68. dirCount++
  69. } else {
  70. fileCount++
  71. }
  72. }
  73. })
  74. if err == nil {
  75. fmt.Fprintf(writer, "\ntotal %d directories, %d files", dirCount, fileCount)
  76. fmt.Fprintf(writer, "\n%s is loaded to http://%s:%d%s\n", fileName, filerServer, filerPort, path)
  77. }
  78. return err
  79. }