device_tool.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // +build !windows
  2. package main
  3. import (
  4. "flag"
  5. "fmt"
  6. "os"
  7. "path"
  8. "sort"
  9. "strconv"
  10. "strings"
  11. "github.com/Sirupsen/logrus"
  12. "github.com/docker/docker/daemon/graphdriver/devmapper"
  13. "github.com/docker/docker/pkg/devicemapper"
  14. )
  15. func usage() {
  16. fmt.Fprintf(os.Stderr, "Usage: %s <flags> [status] | [list] | [device id] | [resize new-pool-size] | [snap new-id base-id] | [remove id] | [mount id mountpoint]\n", os.Args[0])
  17. flag.PrintDefaults()
  18. os.Exit(1)
  19. }
  20. func byteSizeFromString(arg string) (int64, error) {
  21. digits := ""
  22. rest := ""
  23. last := strings.LastIndexAny(arg, "0123456789")
  24. if last >= 0 {
  25. digits = arg[:last+1]
  26. rest = arg[last+1:]
  27. }
  28. val, err := strconv.ParseInt(digits, 10, 64)
  29. if err != nil {
  30. return val, err
  31. }
  32. rest = strings.ToLower(strings.TrimSpace(rest))
  33. var multiplier int64 = 1
  34. switch rest {
  35. case "":
  36. multiplier = 1
  37. case "k", "kb":
  38. multiplier = 1024
  39. case "m", "mb":
  40. multiplier = 1024 * 1024
  41. case "g", "gb":
  42. multiplier = 1024 * 1024 * 1024
  43. case "t", "tb":
  44. multiplier = 1024 * 1024 * 1024 * 1024
  45. default:
  46. return 0, fmt.Errorf("Unknown size unit: %s", rest)
  47. }
  48. return val * multiplier, nil
  49. }
  50. func main() {
  51. root := flag.String("r", "/var/lib/docker", "Docker root dir")
  52. flDebug := flag.Bool("D", false, "Debug mode")
  53. flag.Parse()
  54. if *flDebug {
  55. os.Setenv("DEBUG", "1")
  56. logrus.SetLevel(logrus.DebugLevel)
  57. }
  58. if flag.NArg() < 1 {
  59. usage()
  60. }
  61. args := flag.Args()
  62. home := path.Join(*root, "devicemapper")
  63. devices, err := devmapper.NewDeviceSet(home, false, nil, nil, nil)
  64. if err != nil {
  65. fmt.Println("Can't initialize device mapper: ", err)
  66. os.Exit(1)
  67. }
  68. switch args[0] {
  69. case "status":
  70. status := devices.Status()
  71. fmt.Printf("Pool name: %s\n", status.PoolName)
  72. fmt.Printf("Data Loopback file: %s\n", status.DataLoopback)
  73. fmt.Printf("Metadata Loopback file: %s\n", status.MetadataLoopback)
  74. fmt.Printf("Sector size: %d\n", status.SectorSize)
  75. fmt.Printf("Data use: %d of %d (%.1f %%)\n", status.Data.Used, status.Data.Total, 100.0*float64(status.Data.Used)/float64(status.Data.Total))
  76. fmt.Printf("Metadata use: %d of %d (%.1f %%)\n", status.Metadata.Used, status.Metadata.Total, 100.0*float64(status.Metadata.Used)/float64(status.Metadata.Total))
  77. break
  78. case "list":
  79. ids := devices.List()
  80. sort.Strings(ids)
  81. for _, id := range ids {
  82. fmt.Println(id)
  83. }
  84. break
  85. case "device":
  86. if flag.NArg() < 2 {
  87. usage()
  88. }
  89. status, err := devices.GetDeviceStatus(args[1])
  90. if err != nil {
  91. fmt.Println("Can't get device info: ", err)
  92. os.Exit(1)
  93. }
  94. fmt.Printf("Id: %d\n", status.DeviceID)
  95. fmt.Printf("Size: %d\n", status.Size)
  96. fmt.Printf("Transaction Id: %d\n", status.TransactionID)
  97. fmt.Printf("Size in Sectors: %d\n", status.SizeInSectors)
  98. fmt.Printf("Mapped Sectors: %d\n", status.MappedSectors)
  99. fmt.Printf("Highest Mapped Sector: %d\n", status.HighestMappedSector)
  100. break
  101. case "resize":
  102. if flag.NArg() < 2 {
  103. usage()
  104. }
  105. size, err := byteSizeFromString(args[1])
  106. if err != nil {
  107. fmt.Println("Invalid size: ", err)
  108. os.Exit(1)
  109. }
  110. err = devices.ResizePool(size)
  111. if err != nil {
  112. fmt.Println("Error resizing pool: ", err)
  113. os.Exit(1)
  114. }
  115. break
  116. case "snap":
  117. if flag.NArg() < 3 {
  118. usage()
  119. }
  120. err := devices.AddDevice(args[1], args[2], nil)
  121. if err != nil {
  122. fmt.Println("Can't create snap device: ", err)
  123. os.Exit(1)
  124. }
  125. break
  126. case "remove":
  127. if flag.NArg() < 2 {
  128. usage()
  129. }
  130. err := devicemapper.RemoveDevice(args[1])
  131. if err != nil {
  132. fmt.Println("Can't remove device: ", err)
  133. os.Exit(1)
  134. }
  135. break
  136. case "mount":
  137. if flag.NArg() < 3 {
  138. usage()
  139. }
  140. err := devices.MountDevice(args[1], args[2], "")
  141. if err != nil {
  142. fmt.Println("Can't create snap device: ", err)
  143. os.Exit(1)
  144. }
  145. break
  146. default:
  147. fmt.Printf("Unknown command %s\n", args[0])
  148. usage()
  149. os.Exit(1)
  150. }
  151. return
  152. }