You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.1 KiB

6 years ago
6 years ago
  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. filerServer, filerPort, path, err := commandEnv.parseUrl(findInputDirectory(nil))
  27. if err != nil {
  28. return err
  29. }
  30. fileName := args[len(args)-1]
  31. dst, err := os.OpenFile(fileName, os.O_RDONLY, 0644)
  32. if err != nil {
  33. return nil
  34. }
  35. defer dst.Close()
  36. var dirCount, fileCount uint64
  37. ctx := context.Background()
  38. err = commandEnv.withFilerClient(ctx, filerServer, filerPort, func(client filer_pb.SeaweedFilerClient) error {
  39. sizeBuf := make([]byte, 4)
  40. for {
  41. if n, err := dst.Read(sizeBuf); n != 4 {
  42. if err == io.EOF {
  43. return nil
  44. }
  45. return err
  46. }
  47. size := util.BytesToUint32(sizeBuf)
  48. data := make([]byte, int(size))
  49. if n, err := dst.Read(data); n != len(data) {
  50. return err
  51. }
  52. fullEntry := &filer_pb.FullEntry{}
  53. if err = proto.Unmarshal(data, fullEntry); err != nil {
  54. return err
  55. }
  56. if _, err = client.CreateEntry(ctx, &filer_pb.CreateEntryRequest{
  57. Directory: fullEntry.Dir,
  58. Entry: fullEntry.Entry,
  59. }); err != nil {
  60. return err
  61. }
  62. fmt.Fprintf(writer, "load %s\n", filer2.FullPath(fullEntry.Dir).Child(fullEntry.Entry.Name))
  63. if fullEntry.Entry.IsDirectory {
  64. dirCount++
  65. } else {
  66. fileCount++
  67. }
  68. }
  69. })
  70. if err == nil {
  71. fmt.Fprintf(writer, "\ntotal %d directories, %d files", dirCount, fileCount)
  72. fmt.Fprintf(writer, "\n%s is loaded to http://%s:%d%s\n", fileName, filerServer, filerPort, path)
  73. }
  74. return err
  75. }