Skip to content

Commit efef769

Browse files
committed
Added rudimentary import support
1 parent d17124d commit efef769

File tree

3 files changed

+59
-19
lines changed

3 files changed

+59
-19
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ cannot be distributed since it contains compiled CDDL and GPLv2 code.
4545
The decoder side of nvlist has a fuzzing harness based on go-fuzz.
4646

4747
## Not yet implemented
48-
* Import (missing proper XDR support in nvlist)
48+
* Import from on-disk labels (missing proper XDR support in nvlist)
4949
* VDev management (needs reverse-engineered config structures)
5050
* Feature management (upgrade, enabling, disabling)
5151
* Diff

ioctl/wrappers.go

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,30 +107,32 @@ func Init(nodePath string) error {
107107
}
108108

109109
type VDev struct {
110-
IsLog uint64 `nvlist:"is_log"`
111-
SpaceMapObjectNumber uint64 `nvlist:"DTL,omitempty"`
112-
AlignmentShift uint64 `nvlist:"ashift,omitempty"`
113-
AllocatableCapacity uint64 `nvlist:"asize,omitempty"`
114-
GUID uint64 `nvlist:"guid,omitempty"`
115-
ID uint64 `nvlist:"id,omitempty"`
116-
Path string `nvlist:"path"`
117-
Type string `nvlist:"type"`
118-
Children []VDev `nvlist:"children,omitempty"`
119-
L2CacheChildren []VDev `nvlist:"l2cache,omitempty"`
120-
SparesChildren []VDev `nvlist:"spares,omitempty"`
110+
IsLog uint64 `nvlist:"is_log"`
111+
DTL uint64 `nvlist:"DTL,omitempty"`
112+
AlignmentShift uint64 `nvlist:"ashift,omitempty"`
113+
AllocatableCapacity uint64 `nvlist:"asize,omitempty"`
114+
GUID uint64 `nvlist:"guid,omitempty"`
115+
ID uint64 `nvlist:"id,omitempty"`
116+
Path string `nvlist:"path"`
117+
Type string `nvlist:"type"`
118+
Children []VDev `nvlist:"children,omitempty"`
119+
L2CacheChildren []VDev `nvlist:"l2cache,omitempty"`
120+
SparesChildren []VDev `nvlist:"spares,omitempty"`
121121
}
122122

123123
type PoolConfig struct {
124-
NumberOfChildren uint64 `nvlist:"vdev_children"`
125-
VDevTree *VDev `nvlist:"vdev_tree"`
126-
Errata uint64 `nvlist:"errata,omitempty"`
127-
HostID uint64 `nvlist:"hostid,omitempty"`
128-
Hostname string `nvlist:"hostname,omitempty"`
124+
Version uint64 `nvlist:"version,omitempty"`
129125
Name string `nvlist:"name,omitempty"`
130-
GUID uint64 `nvlist:"pool_guid,omitempty"`
131126
State uint64 `nvlist:"state,omitempty"`
132127
TXG uint64 `nvlist:"txg,omitempty"`
133-
Version uint64 `nvlist:"version,omitempty"`
128+
GUID uint64 `nvlist:"pool_guid,omitempty"`
129+
Errata uint64 `nvlist:"errata,omitempty"`
130+
Hostname string `nvlist:"hostname,omitempty"`
131+
NumberOfChildren uint64 `nvlist:"vdev_children"`
132+
VDevTree *VDev `nvlist:"vdev_tree"`
133+
HostID uint64 `nvlist:"hostid,omitempty"`
134+
// Delta: -hostid, +top_guid, +guid, +features_for_read
135+
FeaturesForRead map[string]bool `nvlist:"features_for_read"`
134136
}
135137

136138
func delimitedBufToString(buf []byte) string {
@@ -200,6 +202,30 @@ func PoolConfigs() (map[string]interface{}, error) {
200202
return res, err
201203
}
202204

205+
// PoolImport imports a pool
206+
func PoolImport(name string, config map[string]interface{}, props map[string]interface{}) (map[string]interface{}, error) {
207+
cmd := &Cmd{}
208+
cmd.Guid = config["pool_guid"].(uint64)
209+
outConfig := make(map[string]interface{})
210+
err := NvlistIoctl(zfsHandle.Fd(), ZFS_IOC_POOL_IMPORT, name, cmd, props, outConfig, config)
211+
if cmd.Cookie != 0 {
212+
return nil, unix.Errno(cmd.Cookie)
213+
}
214+
return outConfig, err
215+
}
216+
217+
// PoolExport exports a pool
218+
func PoolExport(name string, force, hardForce bool) error {
219+
cmd := &Cmd{}
220+
if force {
221+
cmd.Cookie = 1
222+
}
223+
if hardForce {
224+
cmd.Guid = 1
225+
}
226+
return NvlistIoctl(zfsHandle.Fd(), ZFS_IOC_POOL_EXPORT, name, cmd, nil, nil, nil)
227+
}
228+
203229
// Promote replaces a ZFS filesystem with a clone of itself.
204230
func Promote(name string) (conflictingSnapshot string, err error) {
205231
cmd := &Cmd{}

ioctl/wrappers_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ func TestSequence(t *testing.T) {
179179
t.Error(err)
180180
}
181181

182+
configs, err := PoolConfigs()
183+
if err != nil {
184+
t.Fatal(err)
185+
}
186+
187+
if err := PoolExport("tp1", false, false); err != nil {
188+
t.Fatal(err)
189+
}
190+
importConfig := configs["tp1"].(map[string]interface{})
191+
192+
if _, err := PoolImport("tp1", importConfig, nil); err != nil {
193+
t.Fatal(err)
194+
}
195+
182196
// TODO: Validate that GUID has changed
183197

184198
if err := Destroy("tp1/test9", ObjectTypeAny, false); err != nil {

0 commit comments

Comments
 (0)