// 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 }
// Create dataset snapshot. Set recur to true to snapshot child datasets. func DatasetSnapshot(path string, recur bool, props map[ZFSProp]Property) (rd Dataset, err error) { var cprops *C.nvlist_t if cprops, err = datasetPropertiesTo_nvlist(props); err != nil { return } defer C.nvlist_free(cprops) if errc := C.zfs_snapshot(libzfs_handle, C.CString(path), boolean_t(recur), cprops); errc != 0 { err = LastError() return } rd, err = DatasetOpen(path) return }
// Create a new filesystem or volume on path representing pool/dataset or pool/parent/dataset func DatasetCreate(path string, dtype DatasetType, props map[ZFSProp]Property) (d Dataset, err error) { var cprops *C.nvlist_t if cprops, err = datasetPropertiesTo_nvlist(props); err != nil { return } defer C.nvlist_free(cprops) errcode := C.zfs_create(libzfs_handle, C.CString(path), C.zfs_type_t(dtype), cprops) if errcode != 0 { err = LastError() } return }
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 }
// Given a list of directories to search, find and import pool with matching // name stored on disk. func PoolImport(name string, searchpaths []string) (pool Pool, err error) { errPoolList := errors.New("Failed to list pools") var elem *C.nvpair_t var config *C.nvlist_t numofp := len(searchpaths) cpaths := C.alloc_strings(C.int(numofp)) for i, path := range searchpaths { C.strings_setat(cpaths, C.int(i), C.CString(path)) } pools := C.zpool_find_import(libzfs_handle, C.int(numofp), cpaths) defer C.nvlist_free(pools) elem = C.nvlist_next_nvpair(pools, elem) for ; elem != nil; elem = C.nvlist_next_nvpair(pools, elem) { var cname *C.char var tconfig *C.nvlist_t retcode := C.nvpair_value_nvlist(elem, &tconfig) if retcode != 0 { err = errPoolList return } retcode = C.nvlist_lookup_string(tconfig, C.CString(C.ZPOOL_CONFIG_POOL_NAME), &cname) if retcode != 0 { err = errPoolList return } oname := C.GoString(cname) if name == oname { config = tconfig break } } if config == nil { err = errors.New("No pools to import found with name " + name) return } retcode := C.zpool_import(libzfs_handle, config, C.CString(name), nil) if retcode != 0 { err = LastError() return } pool, err = PoolOpen(name) return }
// Clones the dataset. The target must be of the same type as // the source. func (d *Dataset) Clone(target string, props map[ZFSProp]Property) (rd Dataset, err error) { var cprops *C.nvlist_t if d.list == nil { err = errors.New(msgDatasetIsNil) return } if cprops, err = datasetPropertiesTo_nvlist(props); err != nil { return } defer C.nvlist_free(cprops) if errc := C.zfs_clone(d.list.zh, C.CString(target), cprops); errc != 0 { err = LastError() return } rd, err = DatasetOpen(target) return }