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.

105 lines
2.7 KiB

5 years ago
5 years ago
  1. package shell
  2. import (
  3. "fmt"
  4. "io"
  5. "github.com/chrislusf/seaweedfs/weed/filer2"
  6. "github.com/chrislusf/seaweedfs/weed/pb"
  7. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  8. )
  9. func init() {
  10. Commands = append(Commands, &commandFsDu{})
  11. }
  12. type commandFsDu struct {
  13. }
  14. func (c *commandFsDu) Name() string {
  15. return "fs.du"
  16. }
  17. func (c *commandFsDu) Help() string {
  18. return `show disk usage
  19. fs.du http://<filer_server>:<port>/dir
  20. fs.du http://<filer_server>:<port>/dir/file_name
  21. fs.du http://<filer_server>:<port>/dir/file_prefix
  22. `
  23. }
  24. func (c *commandFsDu) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
  25. filerServer, filerPort, path, err := commandEnv.parseUrl(findInputDirectory(args))
  26. if err != nil {
  27. return err
  28. }
  29. if commandEnv.isDirectory(filerServer, filerPort, path) {
  30. path = path + "/"
  31. }
  32. var blockCount, byteCount uint64
  33. dir, name := filer2.FullPath(path).DirAndName()
  34. blockCount, byteCount, err = duTraverseDirectory(writer, commandEnv.getFilerClient(filerServer, filerPort), dir, name)
  35. if name == "" && err == nil {
  36. fmt.Fprintf(writer, "block:%4d\tbyte:%10d\t%s\n", blockCount, byteCount, dir)
  37. }
  38. return
  39. }
  40. func duTraverseDirectory(writer io.Writer, filerClient filer2.FilerClient, dir, name string) (blockCount, byteCount uint64, err error) {
  41. err = filer2.ReadDirAllEntries(filerClient, filer2.FullPath(dir), name, func(entry *filer_pb.Entry, isLast bool) {
  42. if entry.IsDirectory {
  43. subDir := fmt.Sprintf("%s/%s", dir, entry.Name)
  44. if dir == "/" {
  45. subDir = "/" + entry.Name
  46. }
  47. numBlock, numByte, err := duTraverseDirectory(writer, filerClient, subDir, "")
  48. if err == nil {
  49. blockCount += numBlock
  50. byteCount += numByte
  51. }
  52. } else {
  53. blockCount += uint64(len(entry.Chunks))
  54. byteCount += filer2.TotalSize(entry.Chunks)
  55. }
  56. if name != "" && !entry.IsDirectory {
  57. fmt.Fprintf(writer, "block:%4d\tbyte:%10d\t%s/%s\n", blockCount, byteCount, dir, name)
  58. }
  59. })
  60. return
  61. }
  62. func (env *CommandEnv) withFilerClient(filerServer string, filerPort int64, fn func(filer_pb.SeaweedFilerClient) error) error {
  63. filerGrpcAddress := fmt.Sprintf("%s:%d", filerServer, filerPort+10000)
  64. return pb.WithGrpcFilerClient(filerGrpcAddress, env.option.GrpcDialOption, fn)
  65. }
  66. type commandFilerClient struct {
  67. env *CommandEnv
  68. filerServer string
  69. filerPort int64
  70. }
  71. func (env *CommandEnv) getFilerClient(filerServer string, filerPort int64) *commandFilerClient {
  72. return &commandFilerClient{
  73. env: env,
  74. filerServer: filerServer,
  75. filerPort: filerPort,
  76. }
  77. }
  78. func (c *commandFilerClient) WithFilerClient(fn func(filer_pb.SeaweedFilerClient) error) error {
  79. return c.env.withFilerClient(c.filerServer, c.filerPort, fn)
  80. }
  81. func (c *commandFilerClient) AdjustedUrl(hostAndPort string) string {
  82. return hostAndPort
  83. }