- 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