- Bug fixes for send recv, and mount

This commit is contained in:
Faruk Kasumovic 2017-08-04 13:12:41 +02:00
parent 307acf899a
commit a7726113d4
3 changed files with 77 additions and 27 deletions

View File

@ -246,7 +246,7 @@ func (d *Dataset) SendSize(FromName string, flags SendFlags) (size uint64, err e
return return
} }
func (d *Dataset) Receive(name string, inf *os.File, flags RecvFlags) (err error) { func (d *Dataset) Receive(inf *os.File, flags RecvFlags) (err error) {
var dpath string var dpath string
if dpath, err = d.Path(); err != nil { if dpath, err = d.Path(); err != nil {
return return
@ -259,7 +259,7 @@ func (d *Dataset) Receive(name string, inf *os.File, flags RecvFlags) (err error
defer C.nvlist_free(props) defer C.nvlist_free(props)
cflags := to_recvflags_t(&flags) cflags := to_recvflags_t(&flags)
defer C.free(unsafe.Pointer(cflags)) defer C.free(unsafe.Pointer(cflags))
dest := C.CString(dpath + "/" + name) dest := C.CString(dpath)
defer C.free(unsafe.Pointer(dest)) defer C.free(unsafe.Pointer(dest))
ec := C.zfs_receive(C.libzfsHandle, dest, cflags, C.int(inf.Fd()), nil) ec := C.zfs_receive(C.libzfsHandle, dest, cflags, C.int(inf.Fd()), nil)
if ec != 0 { if ec != 0 {

22
zfs.c
View File

@ -19,8 +19,13 @@ dataset_list_t *create_dataset_list_item() {
} }
void dataset_list_close(dataset_list_t *list) { void dataset_list_close(dataset_list_t *list) {
zfs_close(list->zh); if (list != NULL) {
free(list); if (list->zh != NULL) {
zfs_close(list->zh);
list->zh = NULL;
}
free(list);
}
// dataset_list_free(list); // dataset_list_free(list);
} }
@ -132,15 +137,20 @@ int dataset_rename(dataset_list_ptr dataset, const char* new_name, boolean_t rec
} }
const char *dataset_is_mounted(dataset_list_ptr dataset){ const char *dataset_is_mounted(dataset_list_ptr dataset){
char *mp; char *mp = NULL;
// zfs_is_mounted returns B_TRUE or B_FALSE
if (0 != zfs_is_mounted(dataset->zh, &mp)) { if (0 != zfs_is_mounted(dataset->zh, &mp)) {
return NULL; return mp;
} }
return mp; return NULL;
} }
int dataset_mount(dataset_list_ptr dataset, const char *options, int flags) { int dataset_mount(dataset_list_ptr dataset, const char *options, int flags) {
return zfs_mount(dataset->zh, options, flags); if ( 0 < strlen(options)) {
return zfs_mount(dataset->zh, options, flags);
} else {
return zfs_mount(dataset->zh, NULL, flags);
}
} }
int dataset_unmount(dataset_list_ptr dataset, int flags) { int dataset_unmount(dataset_list_ptr dataset, int flags) {

78
zfs.go
View File

@ -10,6 +10,7 @@ import "C"
import ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"unsafe" "unsafe"
) )
@ -114,7 +115,6 @@ func DatasetOpen(path string) (d Dataset, err error) {
d.Properties = make(map[Prop]Property) d.Properties = make(map[Prop]Property)
err = d.ReloadProperties() err = d.ReloadProperties()
if err != nil { if err != nil {
println("reload properties failed")
return return
} }
err = d.openChildren() err = d.openChildren()
@ -165,10 +165,9 @@ func DatasetCreate(path string, dtype DatasetType,
// Close close dataset and all its recursive children datasets (close handle // Close close dataset and all its recursive children datasets (close handle
// and cleanup dataset object/s from memory) // and cleanup dataset object/s from memory)
func (d *Dataset) Close() { func (d *Dataset) Close() {
if d.list != nil && d.list.zh != nil { // path, _ := d.Path()
C.dataset_list_close(d.list) C.dataset_list_close(d.list)
d.list = nil d.list = nil
}
for _, cd := range d.Children { for _, cd := range d.Children {
cd.Close() cd.Close()
} }
@ -204,18 +203,51 @@ func (d *Dataset) Destroy(Defer bool) (err error) {
// DestroyRecursive recursively destroy children of dataset and dataset. // DestroyRecursive recursively destroy children of dataset and dataset.
func (d *Dataset) DestroyRecursive() (err error) { func (d *Dataset) DestroyRecursive() (err error) {
if len(d.Children) > 0 { var path string
for _, c := range d.Children { if path, err = d.Path(); err != nil {
if err = c.DestroyRecursive(); err != nil { return
return }
} if !strings.Contains(path, "@") { // not snapshot
// close handle to destroyed child dataset if len(d.Children) > 0 {
c.Close() for _, c := range d.Children {
} if err = c.DestroyRecursive(); err != nil {
// clear closed children array return
d.Children = make([]Dataset, 0) }
// close handle to destroyed child dataset
c.Close()
}
// clear closed children array
d.Children = make([]Dataset, 0)
}
err = d.Destroy(false)
} else {
var parent Dataset
tmp := strings.Split(path, "@")
ppath, snapname := tmp[0], tmp[1]
if parent, err = DatasetOpen(ppath); err != nil {
return
}
defer parent.Close()
if len(parent.Children) > 0 {
for _, c := range parent.Children {
if path, err = c.Path(); err != nil {
return
}
if strings.Contains(path, "@") {
continue // skip other snapshots
}
if c, err = DatasetOpen(path + "@" + snapname); err != nil {
continue
}
if err = c.DestroyRecursive(); err != nil {
c.Close()
return
}
c.Close()
}
}
err = d.Destroy(false)
} }
err = d.Destroy(false)
return return
} }
@ -241,6 +273,8 @@ func (d *Dataset) ReloadProperties() (err error) {
return return
} }
d.Properties = make(map[Prop]Property) d.Properties = make(map[Prop]Property)
Global.Mtx.Lock()
defer Global.Mtx.Unlock()
for prop := DatasetPropType; prop < DatasetNumProps; prop++ { for prop := DatasetPropType; prop < DatasetNumProps; prop++ {
plist := C.read_dataset_property(d.list, C.int(prop)) plist := C.read_dataset_property(d.list, C.int(prop))
if plist == nil { if plist == nil {
@ -434,6 +468,7 @@ func (d *Dataset) IsMounted() (mounted bool, where string) {
// defer C.free(mp) // defer C.free(mp)
if mounted = (mp != nil); mounted { if mounted = (mp != nil); mounted {
where = C.GoString(mp) where = C.GoString(mp)
C.free(unsafe.Pointer(mp))
} }
return return
} }
@ -471,10 +506,15 @@ func (d *Dataset) UnmountAll(flags int) (err error) {
err = errors.New(msgDatasetIsNil) err = errors.New(msgDatasetIsNil)
return return
} }
if ec := C.dataset_unmountall(d.list, C.int(flags)); ec != 0 { // This is implemented recursive because zfs_unmountall() didn't work
err = LastError() if len(d.Children) > 0 {
for _, c := range d.Children {
if err = c.UnmountAll(flags); err != nil {
return
}
}
} }
return return d.Unmount(flags)
} }
// DatasetPropertyToName convert property to name // DatasetPropertyToName convert property to name