- Ability to create pool with spares, and l2cache
This breaks previous API PoolCreate function call, changes to fix this break will be necessary.
This commit is contained in:
parent
006e8a798a
commit
08a4903509
24
zpool.c
24
zpool.c
|
@ -408,6 +408,30 @@ vdev_children_ptr get_vdev_children(nvlist_t *nv) {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vdev_children_ptr get_vdev_spares(nvlist_t *nv) {
|
||||||
|
int r;
|
||||||
|
vdev_children_ptr children = malloc(sizeof(vdev_children_t));
|
||||||
|
memset(children, 0, sizeof(vdev_children_t));
|
||||||
|
r = nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &(children->first), &(children->count));
|
||||||
|
if (r != 0) {
|
||||||
|
free(children);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
vdev_children_ptr get_vdev_l2cache(nvlist_t *nv) {
|
||||||
|
int r;
|
||||||
|
vdev_children_ptr children = malloc(sizeof(vdev_children_t));
|
||||||
|
memset(children, 0, sizeof(vdev_children_t));
|
||||||
|
r = nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, &(children->first), &(children->count));
|
||||||
|
if (r != 0) {
|
||||||
|
free(children);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
const char *get_vdev_path(nvlist_ptr nv) {
|
const char *get_vdev_path(nvlist_ptr nv) {
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
uint64_t notpresent = 0;
|
uint64_t notpresent = 0;
|
||||||
|
|
248
zpool.go
248
zpool.go
|
@ -101,6 +101,9 @@ type PoolScanStat struct {
|
||||||
type VDevTree struct {
|
type VDevTree struct {
|
||||||
Type VDevType
|
Type VDevType
|
||||||
Devices []VDevTree // groups other devices (e.g. mirror)
|
Devices []VDevTree // groups other devices (e.g. mirror)
|
||||||
|
Spares []VDevTree
|
||||||
|
L2Cache []VDevTree
|
||||||
|
Logs []VDevTree
|
||||||
Parity uint
|
Parity uint
|
||||||
Path string
|
Path string
|
||||||
Name string
|
Name string
|
||||||
|
@ -233,6 +236,60 @@ func poolGetConfig(name string, nv C.nvlist_ptr) (vdevs VDevTree, err error) {
|
||||||
}
|
}
|
||||||
vdevs.Devices = append(vdevs.Devices, vdev)
|
vdevs.Devices = append(vdevs.Devices, vdev)
|
||||||
}
|
}
|
||||||
|
if vdevs.Spares, err = poolGetSpares(name, nv); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if vdevs.L2Cache, err = poolGetL2Cache(name, nv); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func poolGetSpares(name string, nv C.nvlist_ptr) (vdevs []VDevTree, err error) {
|
||||||
|
// Fetch the spares
|
||||||
|
var spares C.vdev_children_ptr
|
||||||
|
spares = C.get_vdev_spares(nv)
|
||||||
|
if spares != nil {
|
||||||
|
// this object that reference spares and count should be deallocated from memory
|
||||||
|
defer C.free(unsafe.Pointer(spares))
|
||||||
|
vdevs = make([]VDevTree, 0, spares.count)
|
||||||
|
}
|
||||||
|
for c := C.uint_t(0); spares != nil && c < spares.count; c++ {
|
||||||
|
vname := C.zpool_vdev_name(C.libzfsHandle, nil, C.nvlist_array_at(spares.first, c),
|
||||||
|
C.B_TRUE)
|
||||||
|
var vdev VDevTree
|
||||||
|
vdev, err = poolGetConfig(C.GoString(vname),
|
||||||
|
C.nvlist_array_at(spares.first, c))
|
||||||
|
C.free(unsafe.Pointer(vname))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vdevs = append(vdevs, vdev)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func poolGetL2Cache(name string, nv C.nvlist_ptr) (vdevs []VDevTree, err error) {
|
||||||
|
// Fetch the spares
|
||||||
|
var l2cache C.vdev_children_ptr
|
||||||
|
l2cache = C.get_vdev_l2cache(nv)
|
||||||
|
if l2cache != nil {
|
||||||
|
// this object that reference l2cache and count should be deallocated from memory
|
||||||
|
defer C.free(unsafe.Pointer(l2cache))
|
||||||
|
vdevs = make([]VDevTree, 0, l2cache.count)
|
||||||
|
}
|
||||||
|
for c := C.uint_t(0); l2cache != nil && c < l2cache.count; c++ {
|
||||||
|
vname := C.zpool_vdev_name(C.libzfsHandle, nil, C.nvlist_array_at(l2cache.first, c),
|
||||||
|
C.B_TRUE)
|
||||||
|
var vdev VDevTree
|
||||||
|
vdev, err = poolGetConfig(C.GoString(vname),
|
||||||
|
C.nvlist_array_at(l2cache.first, c))
|
||||||
|
C.free(unsafe.Pointer(vname))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vdevs = append(vdevs, vdev)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,7 +708,52 @@ func toCDatasetProperties(props DatasetProperties) (cprops C.nvlist_ptr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
|
func buildVdev(vdev VDevTree, ashift int) (nvvdev *C.struct_nvlist, err error) {
|
||||||
|
if r := C.nvlist_alloc(&nvvdev, C.NV_UNIQUE_NAME, 0); r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
csType := C.CString(string(vdev.Type))
|
||||||
|
r := C.nvlist_add_string(nvvdev, C.sZPOOL_CONFIG_TYPE,
|
||||||
|
csType)
|
||||||
|
C.free(unsafe.Pointer(csType))
|
||||||
|
if r != 0 {
|
||||||
|
err = errors.New("Failed to set vdev type")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r := C.nvlist_add_uint64(nvvdev, C.sZPOOL_CONFIG_IS_LOG,
|
||||||
|
vdev.isLog()); r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev (is_log)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r := C.nvlist_add_uint64(nvvdev,
|
||||||
|
C.sZPOOL_CONFIG_WHOLE_DISK, 1); r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev nvvdev (whdisk)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(vdev.Path) > 0 {
|
||||||
|
csPath := C.CString(vdev.Path)
|
||||||
|
r := C.nvlist_add_string(
|
||||||
|
nvvdev, C.sZPOOL_CONFIG_PATH,
|
||||||
|
csPath)
|
||||||
|
C.free(unsafe.Pointer(csPath))
|
||||||
|
if r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev nvvdev (type)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ashift > 0 {
|
||||||
|
if r := C.nvlist_add_uint64(nvvdev,
|
||||||
|
C.sZPOOL_CONFIG_ASHIFT,
|
||||||
|
C.uint64_t(ashift)); r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev nvvdev (ashift)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs, spares, l2cache []VDevTree,
|
||||||
props PoolProperties) (err error) {
|
props PoolProperties) (err error) {
|
||||||
count := len(vdevs)
|
count := len(vdevs)
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
|
@ -663,28 +765,9 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer C.nvlist_free_array(childrens)
|
defer C.nvlist_free_array(childrens)
|
||||||
spares := C.nvlist_alloc_array(C.int(count))
|
|
||||||
if childrens == nil {
|
|
||||||
err = errors.New("No enough memory")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nspares := 0
|
|
||||||
defer C.nvlist_free_array(spares)
|
|
||||||
l2cache := C.nvlist_alloc_array(C.int(count))
|
|
||||||
if childrens == nil {
|
|
||||||
err = errors.New("No enough memory")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nl2cache := 0
|
|
||||||
defer C.nvlist_free_array(l2cache)
|
|
||||||
for i, vdev := range vdevs {
|
for i, vdev := range vdevs {
|
||||||
grouping, mindevs, maxdevs := vdev.isGrouping()
|
grouping, mindevs, maxdevs := vdev.isGrouping()
|
||||||
var child *C.struct_nvlist
|
var child *C.struct_nvlist
|
||||||
// fmt.Println(vdev.Type)
|
|
||||||
if r := C.nvlist_alloc(&child, C.NV_UNIQUE_NAME, 0); r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
vcount := len(vdev.Devices)
|
vcount := len(vdev.Devices)
|
||||||
if vcount < mindevs || vcount > maxdevs {
|
if vcount < mindevs || vcount > maxdevs {
|
||||||
err = fmt.Errorf(
|
err = fmt.Errorf(
|
||||||
|
@ -692,6 +775,11 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
|
||||||
vdev.Type, mindevs, maxdevs)
|
vdev.Type, mindevs, maxdevs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if grouping {
|
||||||
|
if r := C.nvlist_alloc(&child, C.NV_UNIQUE_NAME, 0); r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev")
|
||||||
|
return
|
||||||
|
}
|
||||||
csType := C.CString(string(vdev.Type))
|
csType := C.CString(string(vdev.Type))
|
||||||
r := C.nvlist_add_string(child, C.sZPOOL_CONFIG_TYPE,
|
r := C.nvlist_add_string(child, C.sZPOOL_CONFIG_TYPE,
|
||||||
csType)
|
csType)
|
||||||
|
@ -700,12 +788,6 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
|
||||||
err = errors.New("Failed to set vdev type")
|
err = errors.New("Failed to set vdev type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r := C.nvlist_add_uint64(child, C.sZPOOL_CONFIG_IS_LOG,
|
|
||||||
vdev.isLog()); r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev (is_log)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if grouping {
|
|
||||||
if vdev.Type == VDevTypeRaidz {
|
if vdev.Type == VDevTypeRaidz {
|
||||||
r := C.nvlist_add_uint64(child,
|
r := C.nvlist_add_uint64(child,
|
||||||
C.sZPOOL_CONFIG_NPARITY,
|
C.sZPOOL_CONFIG_NPARITY,
|
||||||
|
@ -715,50 +797,16 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = buildVDevTree(child, vdev.Type, vdev.Devices,
|
if err = buildVDevTree(child, vdev.Type, vdev.Devices, nil, nil,
|
||||||
props); err != nil {
|
props); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if vdev.Type == VDevTypeDisk {
|
|
||||||
if r := C.nvlist_add_uint64(child,
|
|
||||||
C.sZPOOL_CONFIG_WHOLE_DISK, 1); r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev child (whdisk)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
if len(vdev.Path) > 0 {
|
|
||||||
csPath := C.CString(vdev.Path)
|
|
||||||
r := C.nvlist_add_string(
|
|
||||||
child, C.sZPOOL_CONFIG_PATH,
|
|
||||||
csPath)
|
|
||||||
C.free(unsafe.Pointer(csPath))
|
|
||||||
if r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev child (type)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ashift, _ := strconv.Atoi(props[PoolPropAshift])
|
ashift, _ := strconv.Atoi(props[PoolPropAshift])
|
||||||
if ashift > 0 {
|
if child, err = buildVdev(vdev, ashift); err != nil {
|
||||||
if r := C.nvlist_add_uint64(child,
|
|
||||||
C.sZPOOL_CONFIG_ASHIFT,
|
|
||||||
C.uint64_t(ashift)); r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev child (ashift)")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if vdev.Type == VDevTypeSpare {
|
|
||||||
C.nvlist_array_set(spares, C.int(nspares), child)
|
|
||||||
nspares++
|
|
||||||
count--
|
|
||||||
continue
|
|
||||||
} else if vdev.Type == VDevTypeL2cache {
|
|
||||||
C.nvlist_array_set(l2cache, C.int(nl2cache), child)
|
|
||||||
nl2cache++
|
|
||||||
count--
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
C.nvlist_array_set(childrens, C.int(i), child)
|
C.nvlist_array_set(childrens, C.int(i), child)
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
@ -768,31 +816,74 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
|
||||||
err = errors.New("Failed to allocate vdev children")
|
err = errors.New("Failed to allocate vdev children")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// fmt.Println("childs", root, count, rtype)
|
|
||||||
// debug.PrintStack()
|
|
||||||
}
|
}
|
||||||
if nl2cache > 0 {
|
if len(spares) > 0 {
|
||||||
if r := C.nvlist_add_nvlist_array(root,
|
ashift, _ := strconv.Atoi(props[PoolPropAshift])
|
||||||
C.sZPOOL_CONFIG_L2CACHE, l2cache,
|
if err = buildVdevSpares(root, VDevTypeRoot, spares, ashift); err != nil {
|
||||||
C.uint_t(nl2cache)); r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev cache")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if nspares > 0 {
|
if len(l2cache) > 0 {
|
||||||
|
ashift, _ := strconv.Atoi(props[PoolPropAshift])
|
||||||
|
if err = buildVdevL2Cache(root, VDevTypeRoot, l2cache, ashift); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildVdevSpares(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree, ashift int) (err error) {
|
||||||
|
count := len(vdevs)
|
||||||
|
if count == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
spares := C.nvlist_alloc_array(C.int(count))
|
||||||
|
if spares == nil {
|
||||||
|
err = errors.New("No enough memory buildVdevSpares")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer C.nvlist_free_array(spares)
|
||||||
|
for i, vdev := range vdevs {
|
||||||
|
var child *C.struct_nvlist
|
||||||
|
if child, err = buildVdev(vdev, ashift); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
C.nvlist_array_set(spares, C.int(i), child)
|
||||||
|
}
|
||||||
if r := C.nvlist_add_nvlist_array(root,
|
if r := C.nvlist_add_nvlist_array(root,
|
||||||
C.sZPOOL_CONFIG_SPARES, spares,
|
C.sZPOOL_CONFIG_SPARES, spares, C.uint_t(len(vdevs))); r != 0 {
|
||||||
C.uint_t(nspares)); r != 0 {
|
|
||||||
err = errors.New("Failed to allocate vdev spare")
|
err = errors.New("Failed to allocate vdev spare")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildVdevL2Cache(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree, ashift int) (err error) {
|
||||||
|
count := len(vdevs)
|
||||||
|
if count == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// fmt.Println("spares", root, count)
|
l2cache := C.nvlist_alloc_array(C.int(count))
|
||||||
|
if l2cache == nil {
|
||||||
|
err = errors.New("No enough memory buildVdevL2Cache")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer C.nvlist_free_array(l2cache)
|
||||||
|
for i, vdev := range vdevs {
|
||||||
|
var child *C.struct_nvlist
|
||||||
|
if child, err = buildVdev(vdev, ashift); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
C.nvlist_array_set(l2cache, C.int(i), child)
|
||||||
|
}
|
||||||
|
if r := C.nvlist_add_nvlist_array(root,
|
||||||
|
C.sZPOOL_CONFIG_SPARES, l2cache, C.uint_t(len(vdevs))); r != 0 {
|
||||||
|
err = errors.New("Failed to allocate vdev l2cache")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 []VDevTree, features map[string]string,
|
func PoolCreate(name string, vdev 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.struct_nvlist
|
var nvroot *C.struct_nvlist
|
||||||
|
@ -811,7 +902,7 @@ func PoolCreate(name string, vdevs []VDevTree, 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 = buildVDevTree(nvroot, VDevTypeRoot, vdevs, props); err != nil {
|
if err = buildVDevTree(nvroot, VDevTypeRoot, vdev.Devices, vdev.Spares, vdev.L2Cache, props); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,7 +1039,12 @@ func (pool *Pool) VDevTree() (vdevs VDevTree, err error) {
|
||||||
if poolName, err = pool.Name(); err != nil {
|
if poolName, err = pool.Name(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return poolGetConfig(poolName, nvroot)
|
if vdevs, err = poolGetConfig(poolName, nvroot); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vdevs.Spares, err = poolGetSpares(poolName, nvroot)
|
||||||
|
vdevs.L2Cache, err = poolGetL2Cache(poolName, nvroot)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s PoolState) String() string {
|
func (s PoolState) String() string {
|
||||||
|
|
2
zpool.h
2
zpool.h
|
@ -56,6 +56,8 @@ const char *get_vdev_type(nvlist_ptr nv);
|
||||||
const vdev_stat_ptr get_vdev_stats(nvlist_ptr nv);
|
const vdev_stat_ptr get_vdev_stats(nvlist_ptr nv);
|
||||||
pool_scan_stat_ptr get_vdev_scan_stats(nvlist_t *nv);
|
pool_scan_stat_ptr get_vdev_scan_stats(nvlist_t *nv);
|
||||||
vdev_children_ptr get_vdev_children(nvlist_t *nv);
|
vdev_children_ptr get_vdev_children(nvlist_t *nv);
|
||||||
|
vdev_children_ptr get_vdev_spares(nvlist_t *nv);
|
||||||
|
vdev_children_ptr get_vdev_l2cache(nvlist_t *nv);
|
||||||
const char *get_vdev_path(nvlist_ptr nv);
|
const char *get_vdev_path(nvlist_ptr nv);
|
||||||
uint64_t get_vdev_is_log(nvlist_ptr nv);
|
uint64_t get_vdev_is_log(nvlist_ptr nv);
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ func zpoolTestPoolCreate(t *testing.T) {
|
||||||
|
|
||||||
disks := [2]string{s1path, s2path}
|
disks := [2]string{s1path, s2path}
|
||||||
|
|
||||||
|
var vdev zfs.VDevTree
|
||||||
var vdevs, mdevs, sdevs []zfs.VDevTree
|
var vdevs, mdevs, sdevs []zfs.VDevTree
|
||||||
for _, d := range disks {
|
for _, d := range disks {
|
||||||
mdevs = append(mdevs,
|
mdevs = append(mdevs,
|
||||||
|
@ -93,8 +94,9 @@ func zpoolTestPoolCreate(t *testing.T) {
|
||||||
{Type: zfs.VDevTypeFile, Path: s3path}}
|
{Type: zfs.VDevTypeFile, Path: s3path}}
|
||||||
vdevs = []zfs.VDevTree{
|
vdevs = []zfs.VDevTree{
|
||||||
zfs.VDevTree{Type: zfs.VDevTypeMirror, Devices: mdevs},
|
zfs.VDevTree{Type: zfs.VDevTypeMirror, Devices: mdevs},
|
||||||
zfs.VDevTree{Type: zfs.VDevTypeSpare, Devices: sdevs},
|
|
||||||
}
|
}
|
||||||
|
vdev.Devices = vdevs
|
||||||
|
vdev.Spares = sdevs
|
||||||
|
|
||||||
props := make(map[zfs.Prop]string)
|
props := make(map[zfs.Prop]string)
|
||||||
fsprops := make(map[zfs.Prop]string)
|
fsprops := make(map[zfs.Prop]string)
|
||||||
|
@ -104,7 +106,7 @@ func zpoolTestPoolCreate(t *testing.T) {
|
||||||
features["empty_bpobj"] = zfs.FENABLED
|
features["empty_bpobj"] = zfs.FENABLED
|
||||||
features["lz4_compress"] = zfs.FENABLED
|
features["lz4_compress"] = zfs.FENABLED
|
||||||
|
|
||||||
pool, err := zfs.PoolCreate(TSTPoolName, vdevs, features, props, fsprops)
|
pool, err := zfs.PoolCreate(TSTPoolName, vdev, features, props, fsprops)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
// try cleanup
|
// try cleanup
|
||||||
|
@ -231,6 +233,19 @@ func printVDevTree(vt zfs.VDevTree, pref string) {
|
||||||
for _, v := range vt.Devices {
|
for _, v := range vt.Devices {
|
||||||
printVDevTree(v, " "+pref)
|
printVDevTree(v, " "+pref)
|
||||||
}
|
}
|
||||||
|
if len(vt.Spares) > 0 {
|
||||||
|
fmt.Println("spares:")
|
||||||
|
for _, v := range vt.Spares {
|
||||||
|
printVDevTree(v, " "+pref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(vt.L2Cache) > 0 {
|
||||||
|
fmt.Println("l2cache:")
|
||||||
|
for _, v := range vt.L2Cache {
|
||||||
|
printVDevTree(v, " "+pref)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func zpoolTestPoolImportSearch(t *testing.T) {
|
func zpoolTestPoolImportSearch(t *testing.T) {
|
||||||
|
@ -249,7 +264,6 @@ func zpoolTestPoolImportSearch(t *testing.T) {
|
||||||
fmt.Printf("%-30s | %-10s | %-10s | %s\n", "NAME", "TYPE", "STATE", "PATH")
|
fmt.Printf("%-30s | %-10s | %-10s | %s\n", "NAME", "TYPE", "STATE", "PATH")
|
||||||
println("---------------------------------------------------------------")
|
println("---------------------------------------------------------------")
|
||||||
printVDevTree(p.VDevs, "")
|
printVDevTree(p.VDevs, "")
|
||||||
|
|
||||||
}
|
}
|
||||||
print("PASS\n\n")
|
print("PASS\n\n")
|
||||||
}
|
}
|
||||||
|
@ -408,6 +422,7 @@ 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 vdev zfs.VDevTree
|
||||||
var vdevs, mdevs, sdevs []zfs.VDevTree
|
var vdevs, mdevs, sdevs []zfs.VDevTree
|
||||||
|
|
||||||
// build mirror devices specs
|
// build mirror devices specs
|
||||||
|
@ -423,9 +438,11 @@ func ExamplePoolCreate() {
|
||||||
// pool specs
|
// pool specs
|
||||||
vdevs = []zfs.VDevTree{
|
vdevs = []zfs.VDevTree{
|
||||||
zfs.VDevTree{Type: zfs.VDevTypeMirror, Devices: mdevs},
|
zfs.VDevTree{Type: zfs.VDevTypeMirror, Devices: mdevs},
|
||||||
zfs.VDevTree{Type: zfs.VDevTypeSpare, Devices: sdevs},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vdev.Devices = vdevs
|
||||||
|
vdev.Spares = sdevs
|
||||||
|
|
||||||
// pool properties
|
// pool properties
|
||||||
props := make(map[zfs.Prop]string)
|
props := make(map[zfs.Prop]string)
|
||||||
// root dataset filesystem properties
|
// root dataset filesystem properties
|
||||||
|
@ -443,7 +460,7 @@ func ExamplePoolCreate() {
|
||||||
|
|
||||||
// Based on specs formed above create test pool as 2 disk mirror and
|
// Based on specs formed above create test pool as 2 disk mirror and
|
||||||
// one spare disk
|
// one spare disk
|
||||||
pool, err := zfs.PoolCreate("TESTPOOL", vdevs, features, props, fsprops)
|
pool, err := zfs.PoolCreate("TESTPOOL", vdev, features, props, fsprops)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
println("Error: ", err.Error())
|
println("Error: ", err.Error())
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue