fix a variety of CGO memory leaks; watch out for C.CString()! some leaks still present, I mostly fixed those that were impacting me directly.
This commit is contained in:
		
							parent
							
								
									cd589deb96
								
							
						
					
					
						commit
						fffecd80c2
					
				
							
								
								
									
										87
									
								
								zpool.c
								
								
								
								
							
							
						
						
									
										87
									
								
								zpool.c
								
								
								
								
							| 
						 | 
				
			
			@ -9,6 +9,80 @@
 | 
			
		|||
 | 
			
		||||
#include "zpool.h"
 | 
			
		||||
 | 
			
		||||
char *sZPOOL_CONFIG_VERSION = ZPOOL_CONFIG_VERSION;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_NAME = ZPOOL_CONFIG_POOL_NAME;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_STATE = ZPOOL_CONFIG_POOL_STATE;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_TXG = ZPOOL_CONFIG_POOL_TXG;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_GUID = ZPOOL_CONFIG_POOL_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_CREATE_TXG = ZPOOL_CONFIG_CREATE_TXG;
 | 
			
		||||
char *sZPOOL_CONFIG_TOP_GUID = ZPOOL_CONFIG_TOP_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_VDEV_TREE = ZPOOL_CONFIG_VDEV_TREE;
 | 
			
		||||
char *sZPOOL_CONFIG_TYPE = ZPOOL_CONFIG_TYPE;
 | 
			
		||||
char *sZPOOL_CONFIG_CHILDREN = ZPOOL_CONFIG_CHILDREN;
 | 
			
		||||
char *sZPOOL_CONFIG_ID = ZPOOL_CONFIG_ID;
 | 
			
		||||
char *sZPOOL_CONFIG_GUID = ZPOOL_CONFIG_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_PATH = ZPOOL_CONFIG_PATH;
 | 
			
		||||
char *sZPOOL_CONFIG_DEVID = ZPOOL_CONFIG_DEVID;
 | 
			
		||||
char *sZPOOL_CONFIG_METASLAB_ARRAY = ZPOOL_CONFIG_METASLAB_ARRAY;
 | 
			
		||||
char *sZPOOL_CONFIG_METASLAB_SHIFT = ZPOOL_CONFIG_METASLAB_SHIFT;
 | 
			
		||||
char *sZPOOL_CONFIG_ASHIFT = ZPOOL_CONFIG_ASHIFT;
 | 
			
		||||
char *sZPOOL_CONFIG_ASIZE = ZPOOL_CONFIG_ASIZE;
 | 
			
		||||
char *sZPOOL_CONFIG_DTL = ZPOOL_CONFIG_DTL;
 | 
			
		||||
char *sZPOOL_CONFIG_SCAN_STATS = ZPOOL_CONFIG_SCAN_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_VDEV_STATS = ZPOOL_CONFIG_VDEV_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_WHOLE_DISK = ZPOOL_CONFIG_WHOLE_DISK;
 | 
			
		||||
char *sZPOOL_CONFIG_ERRCOUNT = ZPOOL_CONFIG_ERRCOUNT;
 | 
			
		||||
char *sZPOOL_CONFIG_NOT_PRESENT = ZPOOL_CONFIG_NOT_PRESENT;
 | 
			
		||||
char *sZPOOL_CONFIG_SPARES = ZPOOL_CONFIG_SPARES;
 | 
			
		||||
char *sZPOOL_CONFIG_IS_SPARE = ZPOOL_CONFIG_IS_SPARE;
 | 
			
		||||
char *sZPOOL_CONFIG_NPARITY = ZPOOL_CONFIG_NPARITY;
 | 
			
		||||
char *sZPOOL_CONFIG_HOSTID = ZPOOL_CONFIG_HOSTID;
 | 
			
		||||
char *sZPOOL_CONFIG_HOSTNAME = ZPOOL_CONFIG_HOSTNAME;
 | 
			
		||||
char *sZPOOL_CONFIG_LOADED_TIME = ZPOOL_CONFIG_LOADED_TIME;
 | 
			
		||||
char *sZPOOL_CONFIG_UNSPARE = ZPOOL_CONFIG_UNSPARE;
 | 
			
		||||
char *sZPOOL_CONFIG_PHYS_PATH = ZPOOL_CONFIG_PHYS_PATH;
 | 
			
		||||
char *sZPOOL_CONFIG_IS_LOG = ZPOOL_CONFIG_IS_LOG;
 | 
			
		||||
char *sZPOOL_CONFIG_L2CACHE = ZPOOL_CONFIG_L2CACHE;
 | 
			
		||||
char *sZPOOL_CONFIG_HOLE_ARRAY = ZPOOL_CONFIG_HOLE_ARRAY;
 | 
			
		||||
char *sZPOOL_CONFIG_VDEV_CHILDREN = ZPOOL_CONFIG_VDEV_CHILDREN;
 | 
			
		||||
char *sZPOOL_CONFIG_IS_HOLE = ZPOOL_CONFIG_IS_HOLE;
 | 
			
		||||
char *sZPOOL_CONFIG_DDT_HISTOGRAM = ZPOOL_CONFIG_DDT_HISTOGRAM;
 | 
			
		||||
char *sZPOOL_CONFIG_DDT_OBJ_STATS = ZPOOL_CONFIG_DDT_OBJ_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_DDT_STATS = ZPOOL_CONFIG_DDT_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_SPLIT = ZPOOL_CONFIG_SPLIT;
 | 
			
		||||
char *sZPOOL_CONFIG_ORIG_GUID = ZPOOL_CONFIG_ORIG_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_SPLIT_GUID = ZPOOL_CONFIG_SPLIT_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_SPLIT_LIST = ZPOOL_CONFIG_SPLIT_LIST;
 | 
			
		||||
char *sZPOOL_CONFIG_REMOVING = ZPOOL_CONFIG_REMOVING;
 | 
			
		||||
char *sZPOOL_CONFIG_RESILVER_TXG = ZPOOL_CONFIG_RESILVER_TXG;
 | 
			
		||||
char *sZPOOL_CONFIG_COMMENT = ZPOOL_CONFIG_COMMENT;
 | 
			
		||||
char *sZPOOL_CONFIG_SUSPENDED = ZPOOL_CONFIG_SUSPENDED;
 | 
			
		||||
char *sZPOOL_CONFIG_TIMESTAMP = ZPOOL_CONFIG_TIMESTAMP;
 | 
			
		||||
char *sZPOOL_CONFIG_BOOTFS = ZPOOL_CONFIG_BOOTFS;
 | 
			
		||||
char *sZPOOL_CONFIG_MISSING_DEVICES = ZPOOL_CONFIG_MISSING_DEVICES;
 | 
			
		||||
char *sZPOOL_CONFIG_LOAD_INFO = ZPOOL_CONFIG_LOAD_INFO;
 | 
			
		||||
char *sZPOOL_CONFIG_REWIND_INFO = ZPOOL_CONFIG_REWIND_INFO;
 | 
			
		||||
char *sZPOOL_CONFIG_UNSUP_FEAT = ZPOOL_CONFIG_UNSUP_FEAT;
 | 
			
		||||
char *sZPOOL_CONFIG_ENABLED_FEAT = ZPOOL_CONFIG_ENABLED_FEAT;
 | 
			
		||||
char *sZPOOL_CONFIG_CAN_RDONLY = ZPOOL_CONFIG_CAN_RDONLY;
 | 
			
		||||
char *sZPOOL_CONFIG_FEATURES_FOR_READ = ZPOOL_CONFIG_FEATURES_FOR_READ;
 | 
			
		||||
char *sZPOOL_CONFIG_FEATURE_STATS = ZPOOL_CONFIG_FEATURE_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_ERRATA = ZPOOL_CONFIG_ERRATA;
 | 
			
		||||
char *sZPOOL_CONFIG_OFFLINE = ZPOOL_CONFIG_OFFLINE;
 | 
			
		||||
char *sZPOOL_CONFIG_FAULTED = ZPOOL_CONFIG_FAULTED;
 | 
			
		||||
char *sZPOOL_CONFIG_DEGRADED = ZPOOL_CONFIG_DEGRADED;
 | 
			
		||||
char *sZPOOL_CONFIG_REMOVED = ZPOOL_CONFIG_REMOVED;
 | 
			
		||||
char *sZPOOL_CONFIG_FRU = ZPOOL_CONFIG_FRU;
 | 
			
		||||
char *sZPOOL_CONFIG_AUX_STATE = ZPOOL_CONFIG_AUX_STATE;
 | 
			
		||||
char *sZPOOL_REWIND_POLICY = ZPOOL_REWIND_POLICY;
 | 
			
		||||
char *sZPOOL_REWIND_REQUEST = ZPOOL_REWIND_REQUEST;
 | 
			
		||||
char *sZPOOL_REWIND_REQUEST_TXG = ZPOOL_REWIND_REQUEST_TXG;
 | 
			
		||||
char *sZPOOL_REWIND_META_THRESH = ZPOOL_REWIND_META_THRESH;
 | 
			
		||||
char *sZPOOL_REWIND_DATA_THRESH = ZPOOL_REWIND_DATA_THRESH;
 | 
			
		||||
char *sZPOOL_CONFIG_LOAD_TIME = ZPOOL_CONFIG_LOAD_TIME;
 | 
			
		||||
char *sZPOOL_CONFIG_LOAD_DATA_ERRORS = ZPOOL_CONFIG_LOAD_DATA_ERRORS;
 | 
			
		||||
char *sZPOOL_CONFIG_REWIND_TIME = ZPOOL_CONFIG_REWIND_TIME;
 | 
			
		||||
 | 
			
		||||
static char _lasterr_[1024];
 | 
			
		||||
 | 
			
		||||
const char *lasterr(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -395,3 +469,16 @@ void free_cstring(char *str) {
 | 
			
		|||
nvlist_t *nvlist_array_at(nvlist_t **a, uint_t i) {
 | 
			
		||||
	return a[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int refresh_stats(zpool_list_t *pool)
 | 
			
		||||
{
 | 
			
		||||
	boolean_t missing;
 | 
			
		||||
	int err = zpool_refresh_stats(pool->zph, &missing);
 | 
			
		||||
	if ( err != 0 ) {
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
	if ( missing == B_TRUE ) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										79
									
								
								zpool.go
								
								
								
								
							
							
						
						
									
										79
									
								
								zpool.go
								
								
								
								
							| 
						 | 
				
			
			@ -129,7 +129,10 @@ type Pool struct {
 | 
			
		|||
// Returns Pool object, requires Pool.Close() to be called explicitly
 | 
			
		||||
// for memory cleanup after object is not needed anymore.
 | 
			
		||||
func PoolOpen(name string) (pool Pool, err error) {
 | 
			
		||||
	pool.list = C.zpool_list_open(libzfsHandle, C.CString(name))
 | 
			
		||||
	namestr := C.CString(name)
 | 
			
		||||
	pool.list = C.zpool_list_open(libzfsHandle, namestr)
 | 
			
		||||
	C.free_cstring(namestr)
 | 
			
		||||
 | 
			
		||||
	if pool.list != nil {
 | 
			
		||||
		err = pool.ReloadProperties()
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +148,7 @@ func poolGetConfig(name string, nv *C.nvlist_t) (vdevs VDevTree, err error) {
 | 
			
		|||
	var vs *C.vdev_stat_t
 | 
			
		||||
	var ps *C.pool_scan_stat_t
 | 
			
		||||
	var child **C.nvlist_t
 | 
			
		||||
	if 0 != C.nvlist_lookup_string(nv, C.CString(C.ZPOOL_CONFIG_TYPE), &dtype) {
 | 
			
		||||
	if 0 != C.nvlist_lookup_string(nv, C.sZPOOL_CONFIG_TYPE, &dtype) {
 | 
			
		||||
		err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_TYPE)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +159,7 @@ func poolGetConfig(name string, nv *C.nvlist_t) (vdevs VDevTree, err error) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Fetch vdev state
 | 
			
		||||
	if 0 != C.nvlist_lookup_uint64_array_vds(nv, C.CString(C.ZPOOL_CONFIG_VDEV_STATS),
 | 
			
		||||
	if 0 != C.nvlist_lookup_uint64_array_vds(nv, C.sZPOOL_CONFIG_VDEV_STATS,
 | 
			
		||||
		&vs, &c) {
 | 
			
		||||
		err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_VDEV_STATS)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +185,7 @@ func poolGetConfig(name string, nv *C.nvlist_t) (vdevs VDevTree, err error) {
 | 
			
		|||
	vdevs.Stat.Fragmentation = uint64(vs.vs_fragmentation)
 | 
			
		||||
 | 
			
		||||
	// Fetch vdev scan stats
 | 
			
		||||
	if 0 == C.nvlist_lookup_uint64_array_ps(nv, C.CString(C.ZPOOL_CONFIG_SCAN_STATS),
 | 
			
		||||
	if 0 == C.nvlist_lookup_uint64_array_ps(nv, C.sZPOOL_CONFIG_SCAN_STATS,
 | 
			
		||||
		&ps, &c) {
 | 
			
		||||
		vdevs.ScanStat.Func = uint64(ps.pss_func)
 | 
			
		||||
		vdevs.ScanStat.State = uint64(ps.pss_state)
 | 
			
		||||
| 
						 | 
				
			
			@ -198,17 +201,17 @@ func poolGetConfig(name string, nv *C.nvlist_t) (vdevs VDevTree, err error) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Fetch the children
 | 
			
		||||
	if C.nvlist_lookup_nvlist_array(nv, C.CString(C.ZPOOL_CONFIG_CHILDREN),
 | 
			
		||||
	if C.nvlist_lookup_nvlist_array(nv, C.sZPOOL_CONFIG_CHILDREN,
 | 
			
		||||
		&child, &children) != 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if children > 0 {
 | 
			
		||||
		vdevs.Devices = make([]VDevTree, 0, children)
 | 
			
		||||
	}
 | 
			
		||||
	if C.nvlist_lookup_uint64(nv, C.CString(C.ZPOOL_CONFIG_NOT_PRESENT),
 | 
			
		||||
	if C.nvlist_lookup_uint64(nv, C.sZPOOL_CONFIG_NOT_PRESENT,
 | 
			
		||||
		¬present) == 0 {
 | 
			
		||||
		var path *C.char
 | 
			
		||||
		if 0 != C.nvlist_lookup_string(nv, C.CString(C.ZPOOL_CONFIG_PATH), &path) {
 | 
			
		||||
		if 0 != C.nvlist_lookup_string(nv, C.sZPOOL_CONFIG_PATH, &path) {
 | 
			
		||||
			err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_PATH)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +221,7 @@ func poolGetConfig(name string, nv *C.nvlist_t) (vdevs VDevTree, err error) {
 | 
			
		|||
		var islog = C.uint64_t(C.B_FALSE)
 | 
			
		||||
 | 
			
		||||
		C.nvlist_lookup_uint64(C.nvlist_array_at(child, c),
 | 
			
		||||
			C.CString(C.ZPOOL_CONFIG_IS_LOG), &islog)
 | 
			
		||||
			C.sZPOOL_CONFIG_IS_LOG, &islog)
 | 
			
		||||
		if islog != C.B_FALSE {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -263,18 +266,18 @@ func PoolImportSearch(searchpaths []string) (epools []ExportedPool, err error) {
 | 
			
		|||
			err = LastError()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if C.nvlist_lookup_uint64(config, C.CString(C.ZPOOL_CONFIG_POOL_STATE),
 | 
			
		||||
		if C.nvlist_lookup_uint64(config, C.sZPOOL_CONFIG_POOL_STATE,
 | 
			
		||||
			&poolState) != 0 {
 | 
			
		||||
			err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_POOL_STATE)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		ep.State = PoolState(poolState)
 | 
			
		||||
		if C.nvlist_lookup_string(config, C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cname) != 0 {
 | 
			
		||||
		if C.nvlist_lookup_string(config, C.sZPOOL_CONFIG_POOL_NAME, &cname) != 0 {
 | 
			
		||||
			err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_POOL_NAME)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		ep.Name = C.GoString(cname)
 | 
			
		||||
		if C.nvlist_lookup_uint64(config, C.CString(C.ZPOOL_CONFIG_POOL_GUID), &guid) != 0 {
 | 
			
		||||
		if C.nvlist_lookup_uint64(config, C.sZPOOL_CONFIG_POOL_GUID, &guid) != 0 {
 | 
			
		||||
			err = fmt.Errorf("Failed to fetch %s", C.ZPOOL_CONFIG_POOL_GUID)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -282,11 +285,11 @@ func PoolImportSearch(searchpaths []string) (epools []ExportedPool, err error) {
 | 
			
		|||
		reason = C.zpool_import_status(config, &msgid, &errata)
 | 
			
		||||
		ep.Status = PoolStatus(reason)
 | 
			
		||||
 | 
			
		||||
		if C.nvlist_lookup_string(config, C.CString(C.ZPOOL_CONFIG_COMMENT), &comment) == 0 {
 | 
			
		||||
		if C.nvlist_lookup_string(config, C.sZPOOL_CONFIG_COMMENT, &comment) == 0 {
 | 
			
		||||
			ep.Comment = C.GoString(comment)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if C.nvlist_lookup_nvlist(config, C.CString(C.ZPOOL_CONFIG_VDEV_TREE),
 | 
			
		||||
		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
 | 
			
		||||
| 
						 | 
				
			
			@ -325,7 +328,7 @@ func poolSearchImport(q string, searchpaths []string, guid bool) (name string,
 | 
			
		|||
		if guid {
 | 
			
		||||
			var iguid C.uint64_t
 | 
			
		||||
			if retcode = C.nvlist_lookup_uint64(tconfig,
 | 
			
		||||
				C.CString(C.ZPOOL_CONFIG_POOL_GUID), &iguid); retcode != 0 {
 | 
			
		||||
				C.sZPOOL_CONFIG_POOL_GUID, &iguid); retcode != 0 {
 | 
			
		||||
				err = errPoolList
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -336,7 +339,7 @@ func poolSearchImport(q string, searchpaths []string, guid bool) (name string,
 | 
			
		|||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if retcode = C.nvlist_lookup_string(tconfig,
 | 
			
		||||
				C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cq); retcode != 0 {
 | 
			
		||||
				C.sZPOOL_CONFIG_POOL_NAME, &cq); retcode != 0 {
 | 
			
		||||
				err = errPoolList
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +358,7 @@ func poolSearchImport(q string, searchpaths []string, guid bool) (name string,
 | 
			
		|||
	if guid {
 | 
			
		||||
		// We need to get name so we can open pool by name
 | 
			
		||||
		if retcode := C.nvlist_lookup_string(config,
 | 
			
		||||
			C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cname); retcode != 0 {
 | 
			
		||||
			C.sZPOOL_CONFIG_POOL_NAME, &cname); retcode != 0 {
 | 
			
		||||
			err = errPoolList
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -445,13 +448,9 @@ func PoolStateToName(state PoolState) (name string) {
 | 
			
		|||
 | 
			
		||||
// Refresh the pool's vdev statistics, e.g. bytes read/written.
 | 
			
		||||
func (pool *Pool) RefreshStats() (err error) {
 | 
			
		||||
	var missing C.boolean_t
 | 
			
		||||
	if 0 != C.zpool_refresh_stats(pool.list.zph, &missing) {
 | 
			
		||||
	if 0 != C.refresh_stats(pool.list) {
 | 
			
		||||
		return errors.New("error refreshing stats")
 | 
			
		||||
	}
 | 
			
		||||
	if missing == C.B_TRUE {
 | 
			
		||||
		return errors.New("pool has gone missing")
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -486,7 +485,10 @@ func (pool *Pool) ReloadProperties() (err error) {
 | 
			
		|||
		"filesystem_limits":  "disabled",
 | 
			
		||||
		"large_blocks":       "disabled"}
 | 
			
		||||
	for name := range pool.Features {
 | 
			
		||||
		pool.GetFeature(name)
 | 
			
		||||
		_, ferr := pool.GetFeature(name)
 | 
			
		||||
		if ferr != nil {
 | 
			
		||||
			// tolerate it
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -518,8 +520,11 @@ func (pool *Pool) GetProperty(p Prop) (prop Property, err error) {
 | 
			
		|||
// feature in Features map.
 | 
			
		||||
func (pool *Pool) GetFeature(name string) (value string, err error) {
 | 
			
		||||
	var fvalue [512]C.char
 | 
			
		||||
	sname := fmt.Sprint("feature@", name)
 | 
			
		||||
	r := C.zpool_prop_get_feature(pool.list.zph, C.CString(sname), &(fvalue[0]), 512)
 | 
			
		||||
	var sname *C.char
 | 
			
		||||
	sname = C.CString(fmt.Sprint("feature@", name))
 | 
			
		||||
	r := C.zpool_prop_get_feature(pool.list.zph, sname, &(fvalue[0]), 512)
 | 
			
		||||
	C.free_cstring(sname)
 | 
			
		||||
 | 
			
		||||
	if r != 0 {
 | 
			
		||||
		err = errors.New(fmt.Sprint("Unknown zpool feature: ", name))
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -686,12 +691,12 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
				vdev.Type, mindevs, maxdevs)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if r := C.nvlist_add_string(child, C.CString(C.ZPOOL_CONFIG_TYPE),
 | 
			
		||||
		if r := C.nvlist_add_string(child, C.sZPOOL_CONFIG_TYPE,
 | 
			
		||||
			C.CString(string(vdev.Type))); r != 0 {
 | 
			
		||||
			err = errors.New("Failed to set vdev type")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if r := C.nvlist_add_uint64(child, C.CString(C.ZPOOL_CONFIG_IS_LOG),
 | 
			
		||||
		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
 | 
			
		||||
| 
						 | 
				
			
			@ -699,7 +704,7 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
		if grouping {
 | 
			
		||||
			if vdev.Type == VDevTypeRaidz {
 | 
			
		||||
				r := C.nvlist_add_uint64(child,
 | 
			
		||||
					C.CString(C.ZPOOL_CONFIG_NPARITY),
 | 
			
		||||
					C.sZPOOL_CONFIG_NPARITY,
 | 
			
		||||
					C.uint64_t(mindevs-1))
 | 
			
		||||
				if r != 0 {
 | 
			
		||||
					err = errors.New("Failed to allocate vdev (parity)")
 | 
			
		||||
| 
						 | 
				
			
			@ -713,14 +718,14 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
		} else {
 | 
			
		||||
			// if vdev.Type == VDevTypeDisk {
 | 
			
		||||
			if r := C.nvlist_add_uint64(child,
 | 
			
		||||
				C.CString(C.ZPOOL_CONFIG_WHOLE_DISK), 1); r != 0 {
 | 
			
		||||
				C.sZPOOL_CONFIG_WHOLE_DISK, 1); r != 0 {
 | 
			
		||||
				err = errors.New("Failed to allocate vdev child (whdisk)")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			// }
 | 
			
		||||
			if len(vdev.Path) > 0 {
 | 
			
		||||
				if r := C.nvlist_add_string(
 | 
			
		||||
					child, C.CString(C.ZPOOL_CONFIG_PATH),
 | 
			
		||||
					child, C.sZPOOL_CONFIG_PATH,
 | 
			
		||||
					C.CString(vdev.Path)); r != 0 {
 | 
			
		||||
					err = errors.New("Failed to allocate vdev child (type)")
 | 
			
		||||
					return
 | 
			
		||||
| 
						 | 
				
			
			@ -728,7 +733,7 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
				ashift, _ := strconv.Atoi(props[PoolPropAshift])
 | 
			
		||||
				if ashift > 0 {
 | 
			
		||||
					if r := C.nvlist_add_uint64(child,
 | 
			
		||||
						C.CString(C.ZPOOL_CONFIG_ASHIFT),
 | 
			
		||||
						C.sZPOOL_CONFIG_ASHIFT,
 | 
			
		||||
						C.uint64_t(ashift)); r != 0 {
 | 
			
		||||
						err = errors.New("Failed to allocate vdev child (ashift)")
 | 
			
		||||
						return
 | 
			
		||||
| 
						 | 
				
			
			@ -751,7 +756,7 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
	}
 | 
			
		||||
	if count > 0 {
 | 
			
		||||
		if r := C.nvlist_add_nvlist_array(root,
 | 
			
		||||
			C.CString(C.ZPOOL_CONFIG_CHILDREN), childrens,
 | 
			
		||||
			C.sZPOOL_CONFIG_CHILDREN, childrens,
 | 
			
		||||
			C.uint_t(count)); r != 0 {
 | 
			
		||||
			err = errors.New("Failed to allocate vdev children")
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -761,7 +766,7 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
	}
 | 
			
		||||
	if nl2cache > 0 {
 | 
			
		||||
		if r := C.nvlist_add_nvlist_array(root,
 | 
			
		||||
			C.CString(C.ZPOOL_CONFIG_L2CACHE), l2cache,
 | 
			
		||||
			C.sZPOOL_CONFIG_L2CACHE, l2cache,
 | 
			
		||||
			C.uint_t(nl2cache)); r != 0 {
 | 
			
		||||
			err = errors.New("Failed to allocate vdev cache")
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -769,7 +774,7 @@ func buildVDevTree(root *C.nvlist_t, rtype VDevType, vdevs []VDevTree,
 | 
			
		|||
	}
 | 
			
		||||
	if nspares > 0 {
 | 
			
		||||
		if r := C.nvlist_add_nvlist_array(root,
 | 
			
		||||
			C.CString(C.ZPOOL_CONFIG_SPARES), spares,
 | 
			
		||||
			C.sZPOOL_CONFIG_SPARES, spares,
 | 
			
		||||
			C.uint_t(nspares)); r != 0 {
 | 
			
		||||
			err = errors.New("Failed to allocate vdev spare")
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -788,7 +793,7 @@ func PoolCreate(name string, vdevs []VDevTree, features map[string]string,
 | 
			
		|||
		err = errors.New("Failed to allocate root vdev")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if r := C.nvlist_add_string(nvroot, C.CString(C.ZPOOL_CONFIG_TYPE),
 | 
			
		||||
	if r := C.nvlist_add_string(nvroot, C.sZPOOL_CONFIG_TYPE,
 | 
			
		||||
		C.CString(string(VDevTypeRoot))); r != 0 {
 | 
			
		||||
		err = errors.New("Failed to allocate root vdev")
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -887,9 +892,11 @@ func (pool *Pool) Export(force bool, log string) (err error) {
 | 
			
		|||
 | 
			
		||||
// ExportForce hard force export of the pool from the system.
 | 
			
		||||
func (pool *Pool) ExportForce(log string) (err error) {
 | 
			
		||||
	if rc := C.zpool_export_force(pool.list.zph, C.CString(log)); rc != 0 {
 | 
			
		||||
	logstr := C.CString(log)
 | 
			
		||||
	if rc := C.zpool_export_force(pool.list.zph, logstr); rc != 0 {
 | 
			
		||||
		err = LastError()
 | 
			
		||||
	}
 | 
			
		||||
	C.free_cstring(logstr)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -902,7 +909,7 @@ func (pool *Pool) VDevTree() (vdevs VDevTree, err error) {
 | 
			
		|||
		err = fmt.Errorf("Failed zpool_get_config")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if C.nvlist_lookup_nvlist(config, C.CString(C.ZPOOL_CONFIG_VDEV_TREE),
 | 
			
		||||
	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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										77
									
								
								zpool.h
								
								
								
								
							
							
						
						
									
										77
									
								
								zpool.h
								
								
								
								
							| 
						 | 
				
			
			@ -61,5 +61,82 @@ int nvlist_lookup_uint64_array_vds(nvlist_t *nv, const char *p,
 | 
			
		|||
int nvlist_lookup_uint64_array_ps(nvlist_t *nv, const char *p,
 | 
			
		||||
	pool_scan_stat_t **vds, uint_t *c);
 | 
			
		||||
 | 
			
		||||
int refresh_stats(zpool_list_t *pool);
 | 
			
		||||
 | 
			
		||||
char *sZPOOL_CONFIG_VERSION;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_NAME;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_STATE;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_TXG;
 | 
			
		||||
char *sZPOOL_CONFIG_POOL_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_CREATE_TXG;
 | 
			
		||||
char *sZPOOL_CONFIG_TOP_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_VDEV_TREE;
 | 
			
		||||
char *sZPOOL_CONFIG_TYPE;
 | 
			
		||||
char *sZPOOL_CONFIG_CHILDREN;
 | 
			
		||||
char *sZPOOL_CONFIG_ID;
 | 
			
		||||
char *sZPOOL_CONFIG_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_PATH;
 | 
			
		||||
char *sZPOOL_CONFIG_DEVID;
 | 
			
		||||
char *sZPOOL_CONFIG_METASLAB_ARRAY;
 | 
			
		||||
char *sZPOOL_CONFIG_METASLAB_SHIFT;
 | 
			
		||||
char *sZPOOL_CONFIG_ASHIFT;
 | 
			
		||||
char *sZPOOL_CONFIG_ASIZE;
 | 
			
		||||
char *sZPOOL_CONFIG_DTL;
 | 
			
		||||
char *sZPOOL_CONFIG_SCAN_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_VDEV_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_WHOLE_DISK;
 | 
			
		||||
char *sZPOOL_CONFIG_ERRCOUNT;
 | 
			
		||||
char *sZPOOL_CONFIG_NOT_PRESENT;
 | 
			
		||||
char *sZPOOL_CONFIG_SPARES;
 | 
			
		||||
char *sZPOOL_CONFIG_IS_SPARE;
 | 
			
		||||
char *sZPOOL_CONFIG_NPARITY;
 | 
			
		||||
char *sZPOOL_CONFIG_HOSTID;
 | 
			
		||||
char *sZPOOL_CONFIG_HOSTNAME;
 | 
			
		||||
char *sZPOOL_CONFIG_LOADED_TIME;
 | 
			
		||||
char *sZPOOL_CONFIG_UNSPARE;
 | 
			
		||||
char *sZPOOL_CONFIG_PHYS_PATH;
 | 
			
		||||
char *sZPOOL_CONFIG_IS_LOG;
 | 
			
		||||
char *sZPOOL_CONFIG_L2CACHE;
 | 
			
		||||
char *sZPOOL_CONFIG_HOLE_ARRAY;
 | 
			
		||||
char *sZPOOL_CONFIG_VDEV_CHILDREN;
 | 
			
		||||
char *sZPOOL_CONFIG_IS_HOLE;
 | 
			
		||||
char *sZPOOL_CONFIG_DDT_HISTOGRAM;
 | 
			
		||||
char *sZPOOL_CONFIG_DDT_OBJ_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_DDT_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_SPLIT;
 | 
			
		||||
char *sZPOOL_CONFIG_ORIG_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_SPLIT_GUID;
 | 
			
		||||
char *sZPOOL_CONFIG_SPLIT_LIST;
 | 
			
		||||
char *sZPOOL_CONFIG_REMOVING;
 | 
			
		||||
char *sZPOOL_CONFIG_RESILVER_TXG;
 | 
			
		||||
char *sZPOOL_CONFIG_COMMENT;
 | 
			
		||||
char *sZPOOL_CONFIG_SUSPENDED;
 | 
			
		||||
char *sZPOOL_CONFIG_TIMESTAMP;
 | 
			
		||||
char *sZPOOL_CONFIG_BOOTFS;
 | 
			
		||||
char *sZPOOL_CONFIG_MISSING_DEVICES;
 | 
			
		||||
char *sZPOOL_CONFIG_LOAD_INFO;
 | 
			
		||||
char *sZPOOL_CONFIG_REWIND_INFO;
 | 
			
		||||
char *sZPOOL_CONFIG_UNSUP_FEAT;
 | 
			
		||||
char *sZPOOL_CONFIG_ENABLED_FEAT;
 | 
			
		||||
char *sZPOOL_CONFIG_CAN_RDONLY;
 | 
			
		||||
char *sZPOOL_CONFIG_FEATURES_FOR_READ;
 | 
			
		||||
char *sZPOOL_CONFIG_FEATURE_STATS;
 | 
			
		||||
char *sZPOOL_CONFIG_ERRATA;
 | 
			
		||||
char *sZPOOL_CONFIG_OFFLINE;
 | 
			
		||||
char *sZPOOL_CONFIG_FAULTED;
 | 
			
		||||
char *sZPOOL_CONFIG_DEGRADED;
 | 
			
		||||
char *sZPOOL_CONFIG_REMOVED;
 | 
			
		||||
char *sZPOOL_CONFIG_FRU;
 | 
			
		||||
char *sZPOOL_CONFIG_AUX_STATE;
 | 
			
		||||
char *sZPOOL_REWIND_POLICY;
 | 
			
		||||
char *sZPOOL_REWIND_REQUEST;
 | 
			
		||||
char *sZPOOL_REWIND_REQUEST_TXG;
 | 
			
		||||
char *sZPOOL_REWIND_META_THRESH;
 | 
			
		||||
char *sZPOOL_REWIND_DATA_THRESH;
 | 
			
		||||
char *sZPOOL_CONFIG_LOAD_TIME;
 | 
			
		||||
char *sZPOOL_CONFIG_LOAD_DATA_ERRORS;
 | 
			
		||||
char *sZPOOL_CONFIG_REWIND_TIME;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/* SERVERWARE_ZPOOL_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue