zpool.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package zfs
  2. // ZFS zpool states, which can indicate if a pool is online, offline, degraded, etc.
  3. //
  4. // More information regarding zpool states can be found in the ZFS manual:
  5. // https://openzfs.github.io/openzfs-docs/man/7/zpoolconcepts.7.html#Device_Failure_and_Recovery
  6. const (
  7. ZpoolOnline = "ONLINE"
  8. ZpoolDegraded = "DEGRADED"
  9. ZpoolFaulted = "FAULTED"
  10. ZpoolOffline = "OFFLINE"
  11. ZpoolUnavail = "UNAVAIL"
  12. ZpoolRemoved = "REMOVED"
  13. )
  14. // Zpool is a ZFS zpool.
  15. // A pool is a top-level structure in ZFS, and can contain many descendent datasets.
  16. type Zpool struct {
  17. Name string
  18. Health string
  19. Allocated uint64
  20. Size uint64
  21. Free uint64
  22. Fragmentation uint64
  23. ReadOnly bool
  24. Freeing uint64
  25. Leaked uint64
  26. DedupRatio float64
  27. }
  28. // zpool is a helper function to wrap typical calls to zpool and ignores stdout.
  29. func zpool(arg ...string) error {
  30. _, err := zpoolOutput(arg...)
  31. return err
  32. }
  33. // zpool is a helper function to wrap typical calls to zpool.
  34. func zpoolOutput(arg ...string) ([][]string, error) {
  35. c := command{Command: "zpool"}
  36. return c.Run(arg...)
  37. }
  38. // GetZpool retrieves a single ZFS zpool by name.
  39. func GetZpool(name string) (*Zpool, error) {
  40. args := zpoolArgs
  41. args = append(args, name)
  42. out, err := zpoolOutput(args...)
  43. if err != nil {
  44. return nil, err
  45. }
  46. z := &Zpool{Name: name}
  47. for _, line := range out {
  48. if err := z.parseLine(line); err != nil {
  49. return nil, err
  50. }
  51. }
  52. return z, nil
  53. }
  54. // Datasets returns a slice of all ZFS datasets in a zpool.
  55. func (z *Zpool) Datasets() ([]*Dataset, error) {
  56. return Datasets(z.Name)
  57. }
  58. // Snapshots returns a slice of all ZFS snapshots in a zpool.
  59. func (z *Zpool) Snapshots() ([]*Dataset, error) {
  60. return Snapshots(z.Name)
  61. }
  62. // CreateZpool creates a new ZFS zpool with the specified name, properties, and optional arguments.
  63. //
  64. // A full list of available ZFS properties and command-line arguments may be found in the ZFS manual:
  65. // https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
  66. // https://openzfs.github.io/openzfs-docs/man/8/zpool-create.8.html
  67. func CreateZpool(name string, properties map[string]string, args ...string) (*Zpool, error) {
  68. cli := make([]string, 1, 4)
  69. cli[0] = "create"
  70. if properties != nil {
  71. cli = append(cli, propsSlice(properties)...)
  72. }
  73. cli = append(cli, name)
  74. cli = append(cli, args...)
  75. if err := zpool(cli...); err != nil {
  76. return nil, err
  77. }
  78. return &Zpool{Name: name}, nil
  79. }
  80. // Destroy destroys a ZFS zpool by name.
  81. func (z *Zpool) Destroy() error {
  82. err := zpool("destroy", z.Name)
  83. return err
  84. }
  85. // ListZpools list all ZFS zpools accessible on the current system.
  86. func ListZpools() ([]*Zpool, error) {
  87. args := []string{"list", "-Ho", "name"}
  88. out, err := zpoolOutput(args...)
  89. if err != nil {
  90. return nil, err
  91. }
  92. var pools []*Zpool
  93. for _, line := range out {
  94. z, err := GetZpool(line[0])
  95. if err != nil {
  96. return nil, err
  97. }
  98. pools = append(pools, z)
  99. }
  100. return pools, nil
  101. }