forked from bicomsystems/go-libzfs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzpool_vdev.go
144 lines (131 loc) · 3.89 KB
/
zpool_vdev.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package zfs
// #include <stdlib.h>
// #include <libzfs.h>
// #include "common.h"
// #include "zpool.h"
// #include "zfs.h"
import "C"
import (
"fmt"
"unsafe"
)
// Online try to set dev online
// expand - expand storage
func (pool *Pool) Online(expand bool, devs ...string) (err error) {
cflags := C.int(0)
if expand {
cflags = C.ZFS_ONLINE_EXPAND
}
for _, dev := range devs {
csdev := C.CString(dev)
var newstate VDevState
if newstate = VDevState(C.set_zpool_vdev_online(pool.list, csdev, cflags)); newstate != VDevStateUnknown {
if newstate != VDevStateHealthy {
err = fmt.Errorf(
"Device '%s' onlined, but remains in faulted state",
dev)
}
} else {
err = LastError()
}
C.free(unsafe.Pointer(csdev))
}
return
}
// Offline Take the device/s in offline state
func (pool *Pool) Offline(force bool, devs ...string) (err error) {
return pool.offline(false, force, devs...)
}
// OfflineTemp Take the device/s in offline state temporary,
// upon reboot, the specified physical device reverts to its previous state.
// force - Force the device into a faulted state.
func (pool *Pool) OfflineTemp(force bool, devs ...string) (err error) {
return pool.offline(true, force, devs...)
}
// temp - Upon reboot, the specified physical device reverts to its previous state.
// force - Force the device into a faulted state.
func (pool *Pool) offline(temp, force bool, devs ...string) (err error) {
for _, dev := range devs {
csdev := C.CString(dev)
var newstate VDevState
if newstate = VDevState(C.set_zpool_vdev_offline(pool.list, csdev, booleanT(temp), booleanT(force))); newstate != VDevStateUnknown {
if newstate != VDevStateHealthy {
err = fmt.Errorf(
"Device '%s' offlined, but remains in faulted state",
dev)
}
} else {
err = LastError()
}
C.free(unsafe.Pointer(csdev))
}
return
}
// Clear - Clear all errors associated with a pool or a particular device.
func (pool *Pool) Clear(device string) (err error) {
csdev := C.CString(device)
if len(device) == 0 {
csdev = nil
}
if sc := C.do_zpool_clear(pool.list, csdev, C.ZPOOL_NO_REWIND); sc != 0 {
err = fmt.Errorf("Pool clear failed")
}
C.free(unsafe.Pointer(csdev))
return
}
// Attach test
// func (pool *Pool) attach(props PoolProperties, devs ...string) (err error) {
// cprops := toCPoolProperties(props)
// if cprops != nil {
// defer C.nvlist_free(cprops)
// } else {
// return fmt.Errorf("Out of memory [Pool Attach properties]")
// }
// cdevs := C.alloc_cstrings(C.int(len(devs)))
// if cdevs != nil {
// defer C.free(unsafe.Pointer(cdevs))
// } else {
// return fmt.Errorf("Out of memory [Pool Attach args]")
// }
// for i, dp := range devs {
// tmp := C.CString(dp)
// if tmp != nil {
// defer C.free(unsafe.Pointer(tmp))
// } else {
// return fmt.Errorf("Out of memory [Pool Attach dev]")
// }
// C.strings_setat(cdevs, C.int(i), tmp)
// }
// // vroot := C.make_root_vdev(pool.list.zph, cprops, 0, 0, 0, 0, len(devs), cdevs)
// var nvroot *C.struct_nvlist
// if r := C.nvlist_alloc(&nvroot, C.NV_UNIQUE_NAME, 0); r != 0 {
// err = errors.New("Failed to allocate root vdev")
// return
// }
// csTypeRoot := C.CString(string(VDevTypeRoot))
// r := C.nvlist_add_string(nvroot, C.sZPOOL_CONFIG_TYPE,
// csTypeRoot)
// C.free(unsafe.Pointer(csTypeRoot))
// if r != 0 {
// err = errors.New("Failed to allocate root vdev")
// return
// }
// defer C.nvlist_free(nvroot)
// // Now we need to build specs (vdev hierarchy)
// if err = buildVDevTree(nvroot, VDevTypeRoot, vdev.Devices, vdev.Spares, vdev.L2Cache, props); err != nil {
// return
// }
// return
// }
// func (pool *Pool) AttachForce(devs ...string) (err error) {
// return
// }
// func (pool *Pool) Detach(devs ...string) (err error) {
// return
// }
// func (pool *Pool) DetachForce(devs ...string) (err error) {
// return
// }
// func (pool *Pool) Replace(devs ...string) (err error) {
// return
// }