- Implemented PoolImportByGUID and renamed VDevSpec to VDevTree
This commit is contained in:
		
							parent
							
								
									bc19737222
								
							
						
					
					
						commit
						4f32480fa0
					
				| 
						 | 
					@ -12,7 +12,7 @@ func Test(t *testing.T) {
 | 
				
			||||||
	zpoolTestExport(t)
 | 
						zpoolTestExport(t)
 | 
				
			||||||
	zpoolTestImport(t)
 | 
						zpoolTestImport(t)
 | 
				
			||||||
	zpoolTestExportForce(t)
 | 
						zpoolTestExportForce(t)
 | 
				
			||||||
	zpoolTestImport(t)
 | 
						zpoolTestImportByGUID(t)
 | 
				
			||||||
	zpoolTestPoolProp(t)
 | 
						zpoolTestPoolProp(t)
 | 
				
			||||||
	zpoolTestPoolStatusAndState(t)
 | 
						zpoolTestPoolStatusAndState(t)
 | 
				
			||||||
	zpoolTestPoolOpenAll(t)
 | 
						zpoolTestPoolOpenAll(t)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										129
									
								
								zpool.go
								
								
								
								
							
							
						
						
									
										129
									
								
								zpool.go
								
								
								
								
							| 
						 | 
					@ -20,6 +20,14 @@ const (
 | 
				
			||||||
// PoolProperties type is map of pool properties name -> value
 | 
					// PoolProperties type is map of pool properties name -> value
 | 
				
			||||||
type PoolProperties map[Prop]string
 | 
					type PoolProperties map[Prop]string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDevTree ZFS virtual device tree
 | 
				
			||||||
 | 
					type VDevTree struct {
 | 
				
			||||||
 | 
						Type    VDevType
 | 
				
			||||||
 | 
						Devices []VDevTree // groups other devices (e.g. mirror)
 | 
				
			||||||
 | 
						Parity  uint
 | 
				
			||||||
 | 
						Path    string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Pool object represents handler to single ZFS pool
 | 
					// Pool object represents handler to single ZFS pool
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
/* Pool.Properties map[string]Property
 | 
					/* Pool.Properties map[string]Property
 | 
				
			||||||
| 
						 | 
					@ -48,12 +56,13 @@ func PoolOpen(name string) (pool Pool, err error) {
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PoolImport given a list of directories to search, find and import pool with matching
 | 
					func poolSearchImport(q string, searchpaths []string, guid bool) (name string,
 | 
				
			||||||
// name stored on disk.
 | 
						err error) {
 | 
				
			||||||
func PoolImport(name string, searchpaths []string) (pool Pool, err error) {
 | 
						var config *C.nvlist_t
 | 
				
			||||||
 | 
						var cname *C.char
 | 
				
			||||||
 | 
						config = nil
 | 
				
			||||||
	errPoolList := errors.New("Failed to list pools")
 | 
						errPoolList := errors.New("Failed to list pools")
 | 
				
			||||||
	var elem *C.nvpair_t
 | 
						var elem *C.nvpair_t
 | 
				
			||||||
	var config *C.nvlist_t
 | 
					 | 
				
			||||||
	numofp := len(searchpaths)
 | 
						numofp := len(searchpaths)
 | 
				
			||||||
	cpaths := C.alloc_strings(C.int(numofp))
 | 
						cpaths := C.alloc_strings(C.int(numofp))
 | 
				
			||||||
	for i, path := range searchpaths {
 | 
						for i, path := range searchpaths {
 | 
				
			||||||
| 
						 | 
					@ -65,39 +74,87 @@ func PoolImport(name string, searchpaths []string) (pool Pool, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	elem = C.nvlist_next_nvpair(pools, elem)
 | 
						elem = C.nvlist_next_nvpair(pools, elem)
 | 
				
			||||||
	for ; elem != nil; elem = C.nvlist_next_nvpair(pools, elem) {
 | 
						for ; elem != nil; elem = C.nvlist_next_nvpair(pools, elem) {
 | 
				
			||||||
		var cname *C.char
 | 
							var cq *C.char
 | 
				
			||||||
		var tconfig *C.nvlist_t
 | 
							var tconfig *C.nvlist_t
 | 
				
			||||||
		retcode := C.nvpair_value_nvlist(elem, &tconfig)
 | 
							retcode := C.nvpair_value_nvlist(elem, &tconfig)
 | 
				
			||||||
		if retcode != 0 {
 | 
							if retcode != 0 {
 | 
				
			||||||
			err = errPoolList
 | 
								err = errPoolList
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		retcode = C.nvlist_lookup_string(tconfig,
 | 
							if guid {
 | 
				
			||||||
			C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cname)
 | 
								var iguid C.uint64_t
 | 
				
			||||||
		if retcode != 0 {
 | 
								if retcode = C.nvlist_lookup_uint64(tconfig,
 | 
				
			||||||
			err = errPoolList
 | 
									C.CString(C.ZPOOL_CONFIG_POOL_GUID), &iguid); retcode != 0 {
 | 
				
			||||||
			return
 | 
									err = errPoolList
 | 
				
			||||||
		}
 | 
									return
 | 
				
			||||||
		oname := C.GoString(cname)
 | 
								}
 | 
				
			||||||
		if name == oname {
 | 
								sguid := fmt.Sprint(iguid)
 | 
				
			||||||
			config = tconfig
 | 
								if q == sguid {
 | 
				
			||||||
			break
 | 
									config = tconfig
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if retcode = C.nvlist_lookup_string(tconfig,
 | 
				
			||||||
 | 
									C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cq); retcode != 0 {
 | 
				
			||||||
 | 
									err = errPoolList
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								cname = cq
 | 
				
			||||||
 | 
								name = C.GoString(cq)
 | 
				
			||||||
 | 
								if q == name {
 | 
				
			||||||
 | 
									config = tconfig
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if config == nil {
 | 
						if config == nil {
 | 
				
			||||||
		err = errors.New("No pools to import found with name " + name)
 | 
							err = fmt.Errorf("No pool found %s", q)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if guid {
 | 
				
			||||||
	retcode := C.zpool_import(libzfsHandle, config, C.CString(name), nil)
 | 
							// We need to get name so we can open pool by name
 | 
				
			||||||
	if retcode != 0 {
 | 
							if retcode := C.nvlist_lookup_string(config,
 | 
				
			||||||
 | 
								C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cname); retcode != 0 {
 | 
				
			||||||
 | 
								err = errPoolList
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							name = C.GoString(cname)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if retcode := C.zpool_import(libzfsHandle, config, cname,
 | 
				
			||||||
 | 
							nil); retcode != 0 {
 | 
				
			||||||
		err = LastError()
 | 
							err = LastError()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PoolImport given a list of directories to search, find and import pool with matching
 | 
				
			||||||
 | 
					// name stored on disk.
 | 
				
			||||||
 | 
					func PoolImport(name string, searchpaths []string) (pool Pool, err error) {
 | 
				
			||||||
 | 
						_, err = poolSearchImport(name, searchpaths, false)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	pool, err = PoolOpen(name)
 | 
						pool, err = PoolOpen(name)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PoolImportByGUID given a list of directories to search, find and import pool
 | 
				
			||||||
 | 
					// with matching GUID stored on disk.
 | 
				
			||||||
 | 
					func PoolImportByGUID(guid string, searchpaths []string) (pool Pool, err error) {
 | 
				
			||||||
 | 
						var name string
 | 
				
			||||||
 | 
						name, err = poolSearchImport(guid, searchpaths, true)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pool, err = PoolOpen(name)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// func PoolList(paths []string, cache string) (pools []Pool, err error) {
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PoolOpenAll open all active ZFS pools on current system.
 | 
					// PoolOpenAll open all active ZFS pools on current system.
 | 
				
			||||||
// Returns array of Pool handlers, each have to be closed after not needed
 | 
					// Returns array of Pool handlers, each have to be closed after not needed
 | 
				
			||||||
// anymore. Call Pool.Close() method.
 | 
					// anymore. Call Pool.Close() method.
 | 
				
			||||||
| 
						 | 
					@ -164,9 +221,17 @@ func (pool *Pool) ReloadProperties() (err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// read features
 | 
						// read features
 | 
				
			||||||
	pool.Features = map[string]string{
 | 
						pool.Features = map[string]string{
 | 
				
			||||||
		"async_destroy": "disabled",
 | 
							"async_destroy":      "disabled",
 | 
				
			||||||
		"empty_bpobj":   "disabled",
 | 
							"empty_bpobj":        "disabled",
 | 
				
			||||||
		"lz4_compress":  "disabled"}
 | 
							"lz4_compress":       "disabled",
 | 
				
			||||||
 | 
							"spacemap_histogram": "disabled",
 | 
				
			||||||
 | 
							"enabled_txg":        "disabled",
 | 
				
			||||||
 | 
							"hole_birth":         "disabled",
 | 
				
			||||||
 | 
							"extensible_dataset": "disabled",
 | 
				
			||||||
 | 
							"embedded_data":      "disabled",
 | 
				
			||||||
 | 
							"bookmarks":          "disabled",
 | 
				
			||||||
 | 
							"filesystem_limits":  "disabled",
 | 
				
			||||||
 | 
							"large_blocks":       "disabled"}
 | 
				
			||||||
	for name := range pool.Features {
 | 
						for name := range pool.Features {
 | 
				
			||||||
		pool.GetFeature(name)
 | 
							pool.GetFeature(name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -265,15 +330,7 @@ func (pool *Pool) State() (state PoolState, err error) {
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VDevSpec ZFS virtual device specification
 | 
					func (vdev *VDevTree) isGrouping() (grouping bool, mindevs, maxdevs int) {
 | 
				
			||||||
type VDevSpec struct {
 | 
					 | 
				
			||||||
	Type    VDevType
 | 
					 | 
				
			||||||
	Devices []VDevSpec // groups other devices (e.g. mirror)
 | 
					 | 
				
			||||||
	Parity  uint
 | 
					 | 
				
			||||||
	Path    string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (vdev *VDevSpec) isGrouping() (grouping bool, mindevs, maxdevs int) {
 | 
					 | 
				
			||||||
	maxdevs = int(^uint(0) >> 1)
 | 
						maxdevs = int(^uint(0) >> 1)
 | 
				
			||||||
	if vdev.Type == VDevTypeRaidz {
 | 
						if vdev.Type == VDevTypeRaidz {
 | 
				
			||||||
		grouping = true
 | 
							grouping = true
 | 
				
			||||||
| 
						 | 
					@ -295,7 +352,7 @@ func (vdev *VDevSpec) isGrouping() (grouping bool, mindevs, maxdevs int) {
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (vdev *VDevSpec) isLog() (r C.uint64_t) {
 | 
					func (vdev *VDevTree) isLog() (r C.uint64_t) {
 | 
				
			||||||
	r = 0
 | 
						r = 0
 | 
				
			||||||
	if vdev.Type == VDevTypeLog {
 | 
						if vdev.Type == VDevTypeLog {
 | 
				
			||||||
		r = 1
 | 
							r = 1
 | 
				
			||||||
| 
						 | 
					@ -335,7 +392,7 @@ func toCDatasetProperties(props DatasetProperties) (cprops *C.nvlist_t) {
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func buildVDevSpec(root *C.nvlist_t, rtype VDevType, vdevs []VDevSpec,
 | 
					func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
				
			||||||
	props PoolProperties) (err error) {
 | 
						props PoolProperties) (err error) {
 | 
				
			||||||
	count := len(vdevs)
 | 
						count := len(vdevs)
 | 
				
			||||||
	if count == 0 {
 | 
						if count == 0 {
 | 
				
			||||||
| 
						 | 
					@ -396,7 +453,7 @@ func buildVDevSpec(root *C.nvlist_t, rtype VDevType, vdevs []VDevSpec,
 | 
				
			||||||
					return
 | 
										return
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err = buildVDevSpec(child, vdev.Type, vdev.Devices,
 | 
								if err = buildVDevTree(child, vdev.Type, vdev.Devices,
 | 
				
			||||||
				props); err != nil {
 | 
									props); err != nil {
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -470,7 +527,7 @@ func buildVDevSpec(root *C.nvlist_t, rtype VDevType, vdevs []VDevSpec,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PoolCreate create ZFS pool per specs, features and properties of pool and root dataset
 | 
					// PoolCreate create ZFS pool per specs, features and properties of pool and root dataset
 | 
				
			||||||
func PoolCreate(name string, vdevs []VDevSpec, features map[string]string,
 | 
					func PoolCreate(name string, vdevs []VDevTree, features map[string]string,
 | 
				
			||||||
	props PoolProperties, fsprops DatasetProperties) (pool Pool, err error) {
 | 
						props PoolProperties, fsprops DatasetProperties) (pool Pool, err error) {
 | 
				
			||||||
	// create root vdev nvroot
 | 
						// create root vdev nvroot
 | 
				
			||||||
	var nvroot *C.nvlist_t
 | 
						var nvroot *C.nvlist_t
 | 
				
			||||||
| 
						 | 
					@ -486,7 +543,7 @@ func PoolCreate(name string, vdevs []VDevSpec, features map[string]string,
 | 
				
			||||||
	defer C.nvlist_free(nvroot)
 | 
						defer C.nvlist_free(nvroot)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Now we need to build specs (vdev hierarchy)
 | 
						// Now we need to build specs (vdev hierarchy)
 | 
				
			||||||
	if err = buildVDevSpec(nvroot, VDevTypeRoot, vdevs, props); err != nil {
 | 
						if err = buildVDevTree(nvroot, VDevTypeRoot, vdevs, props); err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ import (
 | 
				
			||||||
// HELPERS:
 | 
					// HELPERS:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var TSTPoolName = "TESTPOOL"
 | 
					var TSTPoolName = "TESTPOOL"
 | 
				
			||||||
 | 
					var TSTPoolGUID string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func CreateTmpSparse(prefix string, size int64) (path string, err error) {
 | 
					func CreateTmpSparse(prefix string, size int64) (path string, err error) {
 | 
				
			||||||
	sf, err := ioutil.TempFile("/tmp", prefix)
 | 
						sf, err := ioutil.TempFile("/tmp", prefix)
 | 
				
			||||||
| 
						 | 
					@ -83,16 +84,16 @@ func zpoolTestPoolCreate(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	disks := [2]string{s1path, s2path}
 | 
						disks := [2]string{s1path, s2path}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var vdevs, mdevs, sdevs []zfs.VDevSpec
 | 
						var vdevs, mdevs, sdevs []zfs.VDevTree
 | 
				
			||||||
	for _, d := range disks {
 | 
						for _, d := range disks {
 | 
				
			||||||
		mdevs = append(mdevs,
 | 
							mdevs = append(mdevs,
 | 
				
			||||||
			zfs.VDevSpec{Type: zfs.VDevTypeFile, Path: d})
 | 
								zfs.VDevTree{Type: zfs.VDevTypeFile, Path: d})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sdevs = []zfs.VDevSpec{
 | 
						sdevs = []zfs.VDevTree{
 | 
				
			||||||
		{Type: zfs.VDevTypeFile, Path: s3path}}
 | 
							{Type: zfs.VDevTypeFile, Path: s3path}}
 | 
				
			||||||
	vdevs = []zfs.VDevSpec{
 | 
						vdevs = []zfs.VDevTree{
 | 
				
			||||||
		zfs.VDevSpec{Type: zfs.VDevTypeMirror, Devices: mdevs},
 | 
							zfs.VDevTree{Type: zfs.VDevTypeMirror, Devices: mdevs},
 | 
				
			||||||
		zfs.VDevSpec{Type: zfs.VDevTypeSpare, Devices: sdevs},
 | 
							zfs.VDevTree{Type: zfs.VDevTypeSpare, Devices: sdevs},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	props := make(map[zfs.Prop]string)
 | 
						props := make(map[zfs.Prop]string)
 | 
				
			||||||
| 
						 | 
					@ -114,6 +115,9 @@ func zpoolTestPoolCreate(t *testing.T) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer pool.Close()
 | 
						defer pool.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pguid, _ := pool.GetProperty(zfs.PoolPropGUID)
 | 
				
			||||||
 | 
						TSTPoolGUID = pguid.Value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	print("PASS\n\n")
 | 
						print("PASS\n\n")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,6 +213,17 @@ func zpoolTestImport(t *testing.T) {
 | 
				
			||||||
	print("PASS\n\n")
 | 
						print("PASS\n\n")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func zpoolTestImportByGUID(t *testing.T) {
 | 
				
			||||||
 | 
						println("TEST POOL ImportByGUID( ", TSTPoolGUID, " ) ... ")
 | 
				
			||||||
 | 
						p, err := zfs.PoolImportByGUID(TSTPoolGUID, []string{"/tmp"})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Error(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer p.Close()
 | 
				
			||||||
 | 
						print("PASS\n\n")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func zpoolTestPoolProp(t *testing.T) {
 | 
					func zpoolTestPoolProp(t *testing.T) {
 | 
				
			||||||
	println("TEST PoolProp on ", TSTPoolName, " ... ")
 | 
						println("TEST PoolProp on ", TSTPoolName, " ... ")
 | 
				
			||||||
	if pool, err := zfs.PoolOpen(TSTPoolName); err == nil {
 | 
						if pool, err := zfs.PoolOpen(TSTPoolName); err == nil {
 | 
				
			||||||
| 
						 | 
					@ -335,22 +350,22 @@ func ExamplePoolOpenAll() {
 | 
				
			||||||
func ExamplePoolCreate() {
 | 
					func ExamplePoolCreate() {
 | 
				
			||||||
	disks := [2]string{"/dev/disk/by-id/ATA-123", "/dev/disk/by-id/ATA-456"}
 | 
						disks := [2]string{"/dev/disk/by-id/ATA-123", "/dev/disk/by-id/ATA-456"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var vdevs, mdevs, sdevs []zfs.VDevSpec
 | 
						var vdevs, mdevs, sdevs []zfs.VDevTree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// build mirror devices specs
 | 
						// build mirror devices specs
 | 
				
			||||||
	for _, d := range disks {
 | 
						for _, d := range disks {
 | 
				
			||||||
		mdevs = append(mdevs,
 | 
							mdevs = append(mdevs,
 | 
				
			||||||
			zfs.VDevSpec{Type: zfs.VDevTypeDisk, Path: d})
 | 
								zfs.VDevTree{Type: zfs.VDevTypeDisk, Path: d})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// spare device specs
 | 
						// spare device specs
 | 
				
			||||||
	sdevs = []zfs.VDevSpec{
 | 
						sdevs = []zfs.VDevTree{
 | 
				
			||||||
		{Type: zfs.VDevTypeDisk, Path: "/dev/disk/by-id/ATA-789"}}
 | 
							{Type: zfs.VDevTypeDisk, Path: "/dev/disk/by-id/ATA-789"}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// pool specs
 | 
						// pool specs
 | 
				
			||||||
	vdevs = []zfs.VDevSpec{
 | 
						vdevs = []zfs.VDevTree{
 | 
				
			||||||
		zfs.VDevSpec{Type: zfs.VDevTypeMirror, Devices: mdevs},
 | 
							zfs.VDevTree{Type: zfs.VDevTypeMirror, Devices: mdevs},
 | 
				
			||||||
		zfs.VDevSpec{Type: zfs.VDevTypeSpare, Devices: sdevs},
 | 
							zfs.VDevTree{Type: zfs.VDevTypeSpare, Devices: sdevs},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// pool properties
 | 
						// pool properties
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue