- Implemented pool initialization actions
This commit is contained in:
parent
e24c488fee
commit
5a4d618fa5
|
@ -13,6 +13,7 @@ func Test(t *testing.T) {
|
|||
zpoolTestExport(t)
|
||||
zpoolTestPoolImportSearch(t)
|
||||
zpoolTestImport(t)
|
||||
zpoolTestInitialization(t)
|
||||
zpoolTestExportForce(t)
|
||||
zpoolTestImportByGUID(t)
|
||||
zpoolTestPoolProp(t)
|
||||
|
|
24
zpool.c
24
zpool.c
|
@ -526,3 +526,27 @@ int do_zpool_clear(zpool_list_t *pool, const char *device, u_int32_t load_policy
|
|||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void collect_zpool_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *nv){
|
||||
uint_t children = 0;
|
||||
nvlist_t **child;
|
||||
uint_t i;
|
||||
|
||||
(void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children);
|
||||
|
||||
if (children == 0) {
|
||||
char *path = zpool_vdev_name(libzfsHandle, zhp, nvroot,
|
||||
VDEV_NAME_PATH);
|
||||
|
||||
if (strcmp(path, VDEV_TYPE_INDIRECT) != 0)
|
||||
fnvlist_add_boolean(nv, path);
|
||||
|
||||
free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < children; i++) {
|
||||
collect_zpool_leaves(zhp, child[i], nv);
|
||||
}
|
||||
}
|
67
zpool.go
67
zpool.go
|
@ -59,6 +59,16 @@ const (
|
|||
PoolScanFuncs // Number of scan functions
|
||||
)
|
||||
|
||||
// PoolInitializeAction type representing pool initialize action
|
||||
type PoolInitializeAction int
|
||||
|
||||
// Initialize actions
|
||||
const (
|
||||
PoolInitializeStart PoolInitializeAction = iota // start initialization
|
||||
PoolInitializeCancel // cancel initialization
|
||||
PoolInitializeSuspend // suspend initialization
|
||||
)
|
||||
|
||||
// VDevStat - Vdev statistics. Note: all fields should be 64-bit because this
|
||||
// is passed between kernel and userland as an nvlist uint64 array.
|
||||
type VDevStat struct {
|
||||
|
@ -1055,6 +1065,50 @@ func (pool *Pool) VDevTree() (vdevs VDevTree, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Initialize - initializes pool
|
||||
func (pool *Pool) Initialize() (err error) {
|
||||
return pool.initialize(PoolInitializeStart)
|
||||
}
|
||||
|
||||
// CancelInitialization - cancels ongoing initialization
|
||||
func (pool *Pool) CancelInitialization() (err error) {
|
||||
return pool.initialize(PoolInitializeCancel)
|
||||
}
|
||||
|
||||
// SuspendInitialization - suspends ongoing initialization
|
||||
func (pool *Pool) SuspendInitialization() (err error) {
|
||||
return pool.initialize(PoolInitializeSuspend)
|
||||
}
|
||||
|
||||
func (pool *Pool) initialize(action PoolInitializeAction) (err error) {
|
||||
var nvroot *C.struct_nvlist
|
||||
|
||||
config := C.zpool_get_config(pool.list.zph, nil)
|
||||
if config == nil {
|
||||
err = fmt.Errorf("Failed zpool_get_config")
|
||||
return
|
||||
}
|
||||
if C.nvlist_lookup_nvlist(config, C.sZPOOL_CONFIG_VDEV_TREE, &nvroot) != 0 {
|
||||
err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_VDEV_TREE)
|
||||
return
|
||||
}
|
||||
|
||||
var vds *C.nvlist_t
|
||||
if r := C.nvlist_alloc(&vds, C.NV_UNIQUE_NAME, 0); r != 0 {
|
||||
err = errors.New("Failed to allocate vdev")
|
||||
return
|
||||
}
|
||||
defer C.nvlist_free(vds)
|
||||
|
||||
C.collect_zpool_leaves(pool.list.zph, nvroot, vds)
|
||||
|
||||
if C.zpool_initialize(pool.list.zph, C.pool_initialize_func_t(action), vds) != 0 {
|
||||
err = fmt.Errorf("Initialization action %s failed", action.String())
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s PoolState) String() string {
|
||||
switch s {
|
||||
case PoolStateActive:
|
||||
|
@ -1186,3 +1240,16 @@ func (s PoolStatus) String() string {
|
|||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
func (s PoolInitializeAction) String() string {
|
||||
switch s {
|
||||
case PoolInitializeStart:
|
||||
return "START"
|
||||
case PoolInitializeCancel:
|
||||
return "CANCEL"
|
||||
case PoolInitializeSuspend:
|
||||
return "SUSPEND"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
|
1
zpool.h
1
zpool.h
|
@ -82,6 +82,7 @@ nvlist_ptr go_zpool_search_import(libzfs_handle_ptr zfsh, int paths, char **path
|
|||
uint64_t set_zpool_vdev_online(zpool_list_t *pool, const char *path, int flags);
|
||||
int set_zpool_vdev_offline(zpool_list_t *pool, const char *path, boolean_t istmp, boolean_t force);
|
||||
int do_zpool_clear(zpool_list_t *pool, const char *device, u_int32_t rewind_policy);
|
||||
void collect_zpool_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *nv);
|
||||
|
||||
|
||||
extern char *sZPOOL_CONFIG_VERSION;
|
||||
|
|
|
@ -5,8 +5,9 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/bicomsystems/go-libzfs"
|
||||
zfs "github.com/bicomsystems/go-libzfs"
|
||||
)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -362,6 +363,40 @@ func zpoolTestPoolVDevTree(t *testing.T) {
|
|||
print("PASS\n\n")
|
||||
}
|
||||
|
||||
func zpoolTestInitialization(t *testing.T) {
|
||||
println("TEST POOL Initialization ( ", TSTPoolName, " ) ... ")
|
||||
pool, err := zfs.PoolOpen(TSTPoolName)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
err = pool.Initialize()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
err = pool.SuspendInitialization()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
err = pool.Initialize()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
err = pool.CancelInitialization()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
return
|
||||
}
|
||||
print("PASS\n\n")
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// EXAMPLES:
|
||||
|
||||
|
|
Loading…
Reference in New Issue