device_tool.go 3.7 KB

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