Esempio n. 1
0
// Create ZFS pool per specs, features and properties of pool and root dataset
func PoolCreate(name string, vdevs []VDevSpec, features map[string]string,
	props PoolProperties, fsprops ZFSProperties) (pool Pool, err error) {
	// create root vdev nvroot
	var nvroot *C.nvlist_t = nil
	if r := C.nvlist_alloc(&nvroot, C.NV_UNIQUE_NAME, 0); r != 0 {
		err = errors.New("Failed to allocate root vdev")
		return
	}
	if r := C.nvlist_add_string(nvroot, C.CString(C.ZPOOL_CONFIG_TYPE),
		C.CString(string(VDevTypeRoot))); r != 0 {
		err = errors.New("Failed to allocate root vdev")
		return
	}
	defer C.nvlist_free(nvroot)

	// Now we need to build specs (vdev hierarchy)
	if err = buildVDevSpec(nvroot, VDevTypeRoot, vdevs, props); err != nil {
		return
	}

	// convert properties
	cprops := toCPoolProperties(props)
	if cprops != nil {
		defer C.nvlist_free(cprops)
	} else if len(props) > 0 {
		err = errors.New("Failed to allocate pool properties")
		return
	}
	cfsprops := toCZFSProperties(fsprops)
	if cfsprops != nil {
		defer C.nvlist_free(cfsprops)
	} else if len(fsprops) > 0 {
		err = errors.New("Failed to allocate FS properties")
		return
	}
	for fname, fval := range features {
		sfname := fmt.Sprintf("feature@%s", fname)
		r := C.add_prop_list(C.CString(sfname), C.CString(fval), &cprops,
			C.boolean_t(1))
		if r != 0 {
			if cprops != nil {
				C.nvlist_free(cprops)
				cprops = nil
			}
			return
		}
	}

	// Create actual pool then open
	if r := C.zpool_create(libzfs_handle, C.CString(name), nvroot,
		cprops, cfsprops); r != 0 {
		err = LastError()
		return
	}
	pool, err = PoolOpen(name)
	return
}
Esempio n. 2
0
func toCZFSProperties(props ZFSProperties) (cprops *C.nvlist_t) {
	cprops = nil
	for prop, value := range props {
		name := C.zfs_prop_to_name(C.zfs_prop_t(prop))
		r := C.add_prop_list(name, C.CString(value), &cprops, C.boolean_t(0))
		if r != 0 {
			if cprops != nil {
				C.nvlist_free(cprops)
				cprops = nil
			}
			return
		}
	}
	return
}