2015-05-01 19:35:40 +00:00
|
|
|
package cephfs
|
|
|
|
|
|
|
|
/*
|
|
|
|
#cgo LDFLAGS: -lcephfs
|
|
|
|
#cgo CPPFLAGS: -D_FILE_OFFSET_BITS=64
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <cephfs/libcephfs.h>
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
|
2018-10-09 04:26:51 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"math"
|
|
|
|
"syscall"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
type cephError int
|
2015-05-01 19:35:40 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
func (e cephError) Error() string {
|
2018-10-09 04:26:51 +00:00
|
|
|
if e == 0 {
|
2018-10-10 22:06:47 +00:00
|
|
|
return fmt.Sprintf("cephfs: no error given")
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
2018-10-10 22:06:47 +00:00
|
|
|
err := syscall.Errno(uint(math.Abs(float64(e))))
|
|
|
|
return fmt.Sprintf("cephfs: ret=(%d) %v", e, err)
|
2015-05-01 19:35:40 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// MountInfo exports ceph's ceph_mount_info from libcephfs.cc
|
2015-05-01 19:35:40 +00:00
|
|
|
type MountInfo struct {
|
2015-07-08 08:34:54 +00:00
|
|
|
mount *C.struct_ceph_mount_info
|
2015-05-01 19:35:40 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// CreateMount creates a mount handle for interacting with Ceph.
|
2015-05-01 19:35:40 +00:00
|
|
|
func CreateMount() (*MountInfo, error) {
|
2015-07-08 08:34:54 +00:00
|
|
|
mount := &MountInfo{}
|
|
|
|
ret := C.ceph_create(&mount.mount, nil)
|
2018-10-11 18:36:26 +00:00
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("CreateMount: Failed to create mount")
|
|
|
|
return nil, cephError(ret)
|
2015-07-08 08:34:54 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return mount, nil
|
2015-05-01 19:35:40 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// ReadDefaultConfigFile loads the ceph configuration from the specified config file.
|
2018-10-10 22:06:47 +00:00
|
|
|
func (mount *MountInfo) ReadDefaultConfigFile() error {
|
|
|
|
ret := C.ceph_conf_read_file(mount.mount, nil)
|
2018-10-11 18:36:26 +00:00
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("ReadDefaultConfigFile: Failed to read ceph config")
|
|
|
|
return cephError(ret)
|
2018-10-10 22:06:47 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-10 22:06:47 +00:00
|
|
|
}
|
2018-10-09 04:26:51 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// Mount mounts the mount handle.
|
2018-10-10 22:06:47 +00:00
|
|
|
func (mount *MountInfo) Mount() error {
|
|
|
|
ret := C.ceph_mount(mount.mount, nil)
|
2018-10-11 18:36:26 +00:00
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("Mount: Failed to mount")
|
|
|
|
return cephError(ret)
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// Unmount unmounts the mount handle.
|
2018-10-09 04:26:51 +00:00
|
|
|
func (mount *MountInfo) Unmount() error {
|
|
|
|
ret := C.ceph_unmount(mount.mount)
|
2018-10-11 18:36:26 +00:00
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("Unmount: Failed to unmount")
|
|
|
|
return cephError(ret)
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// Release destroys the mount handle.
|
2018-10-09 04:26:51 +00:00
|
|
|
func (mount *MountInfo) Release() error {
|
|
|
|
ret := C.ceph_release(mount.mount)
|
2018-10-11 18:36:26 +00:00
|
|
|
if ret != 0 {
|
2018-10-09 04:26:51 +00:00
|
|
|
log.Errorf("Release: Failed to release mount")
|
2018-10-11 18:36:26 +00:00
|
|
|
return cephError(ret)
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// SyncFs synchronizes all filesystem data to persistent media.
|
2015-05-01 19:35:40 +00:00
|
|
|
func (mount *MountInfo) SyncFs() error {
|
2015-07-08 08:34:54 +00:00
|
|
|
ret := C.ceph_sync_fs(mount.mount)
|
2018-10-11 18:36:26 +00:00
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("Mount: Failed to sync filesystem")
|
|
|
|
return cephError(ret)
|
2015-07-08 08:34:54 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2015-05-01 19:35:40 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// CurrentDir gets the current working directory.
|
2015-05-01 19:35:40 +00:00
|
|
|
func (mount *MountInfo) CurrentDir() string {
|
2018-10-11 18:36:26 +00:00
|
|
|
cDir := C.ceph_getcwd(mount.mount)
|
|
|
|
return C.GoString(cDir)
|
2015-05-01 19:35:40 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// ChangeDir changes the current working directory.
|
2015-05-01 19:35:40 +00:00
|
|
|
func (mount *MountInfo) ChangeDir(path string) error {
|
2018-10-11 18:36:26 +00:00
|
|
|
cPath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cPath))
|
2015-05-01 19:35:40 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
ret := C.ceph_chdir(mount.mount, cPath)
|
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("ChangeDir: Failed to change directory")
|
|
|
|
return cephError(ret)
|
2015-07-08 08:34:54 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2015-05-01 19:35:40 +00:00
|
|
|
}
|
2015-05-01 19:54:38 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// MakeDir creates a directory.
|
2015-05-01 19:54:38 +00:00
|
|
|
func (mount *MountInfo) MakeDir(path string, mode uint32) error {
|
2018-10-11 18:36:26 +00:00
|
|
|
cPath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cPath))
|
2015-05-01 19:54:38 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
ret := C.ceph_mkdir(mount.mount, cPath, C.mode_t(mode))
|
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("MakeDir: Failed to make directory %s", path)
|
|
|
|
return cephError(ret)
|
2015-07-08 08:34:54 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-10 22:06:47 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// RemoveDir removes a directory.
|
2018-10-10 22:06:47 +00:00
|
|
|
func (mount *MountInfo) RemoveDir(path string) error {
|
2018-10-11 18:36:26 +00:00
|
|
|
cPath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cPath))
|
2018-10-10 22:06:47 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
ret := C.ceph_rmdir(mount.mount, cPath)
|
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("RemoveDir: Failed to remove directory")
|
|
|
|
return cephError(ret)
|
2018-10-10 22:06:47 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2015-05-01 19:54:38 +00:00
|
|
|
}
|
2018-10-09 04:26:51 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// Chmod changes the mode bits (permissions) of a file/directory.
|
2018-10-09 04:26:51 +00:00
|
|
|
func (mount *MountInfo) Chmod(path string, mode uint32) error {
|
2018-10-11 18:36:26 +00:00
|
|
|
cPath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cPath))
|
2018-10-09 04:26:51 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
ret := C.ceph_chmod(mount.mount, cPath, C.mode_t(mode))
|
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("Chmod: Failed to chmod :%s", path)
|
|
|
|
return cephError(ret)
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// Chown changes the ownership of a file/directory.
|
2018-10-09 04:26:51 +00:00
|
|
|
func (mount *MountInfo) Chown(path string, user uint32, group uint32) error {
|
2018-10-11 18:36:26 +00:00
|
|
|
cPath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cPath))
|
2018-10-09 04:26:51 +00:00
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
ret := C.ceph_chown(mount.mount, cPath, C.int(user), C.int(group))
|
|
|
|
if ret != 0 {
|
|
|
|
log.Errorf("Chown: Failed to chown :%s", path)
|
|
|
|
return cephError(ret)
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
2018-10-11 18:36:26 +00:00
|
|
|
return nil
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|
|
|
|
|
2018-10-11 18:36:26 +00:00
|
|
|
// IsMounted checks mount status.
|
2018-10-09 04:26:51 +00:00
|
|
|
func (mount *MountInfo) IsMounted() bool {
|
|
|
|
ret := C.ceph_is_mounted(mount.mount)
|
2018-10-10 22:06:47 +00:00
|
|
|
return ret == 1
|
2018-10-09 04:26:51 +00:00
|
|
|
}
|