forked from ceph/go-ceph
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rados/striper: start new striper package
Start a new `rados/striper` package that wraps Ceph's libradosstriper. The libradosstriper library builds on top of the librados library to support striping large "objects" over multiple RADOS objects. Fixes: ceph#1011 Signed-off-by: John Mulligan <jmulligan@redhat.com>
- Loading branch information
1 parent
e20ffbd
commit 9331e1e
Showing
4 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//go:build ceph_preview | ||
// +build ceph_preview | ||
|
||
package striper | ||
|
||
/* | ||
#include <errno.h> | ||
*/ | ||
import "C" | ||
|
||
import ( | ||
"github.com/ceph/go-ceph/internal/errutil" | ||
) | ||
|
||
// radosStriperError represents an error condition returned from the Ceph | ||
// rados striper APIs. | ||
type radosStriperError int | ||
|
||
// Error returns the error string for the radosStriperError type. | ||
func (e radosStriperError) Error() string { | ||
return errutil.FormatErrorCode("rados", int(e)) | ||
} | ||
|
||
func (e radosStriperError) ErrorCode() int { | ||
return int(e) | ||
} | ||
|
||
func getError(e C.int) error { | ||
if e == 0 { | ||
return nil | ||
} | ||
return radosStriperError(e) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//go:build ceph_preview | ||
// +build ceph_preview | ||
|
||
package striper | ||
|
||
// #cgo LDFLAGS: -lrados -lradosstriper | ||
// #include <stdlib.h> | ||
// #include <radosstriper/libradosstriper.h> | ||
import "C" | ||
|
||
import ( | ||
"unsafe" | ||
|
||
ts "github.com/ceph/go-ceph/internal/timespec" | ||
) | ||
|
||
// Read bytes into data from the striped object at the specified offset. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_read(rados_striper_t striper, | ||
// const char *soid, | ||
// const char *buf, | ||
// size_t len, | ||
// uint64_t off); | ||
func (s *Striper) Read(soid string, data []byte, offset uint64) (int, error) { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
var bufptr *C.char | ||
if len(data) > 0 { | ||
bufptr = (*C.char)(unsafe.Pointer(&data[0])) | ||
} | ||
|
||
ret := C.rados_striper_read( | ||
s.striper, | ||
csoid, | ||
bufptr, | ||
C.size_t(len(data)), | ||
C.uint64_t(offset)) | ||
if ret >= 0 { | ||
return int(ret), nil | ||
} | ||
return 0, getError(ret) | ||
} | ||
|
||
// Timespec behaves similarly to C's struct timespec. | ||
type Timespec ts.Timespec | ||
|
||
type StriperStat struct { | ||
Size uint64 | ||
ModTime Timespec | ||
} | ||
|
||
// Stat returns metadata describing the striped object. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_stat2(rados_striper_t striper, | ||
// const char* soid, | ||
// uint64_t *psize, | ||
// struct timespec *pmtime); | ||
func (s *Striper) Stat(soid string) (StriperStat, error) { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
var ( | ||
size C.uint64_t | ||
mtime C.struct_timespec | ||
) | ||
ret := C.rados_striper_stat2( | ||
s.striper, | ||
csoid, | ||
&size, | ||
&mtime) | ||
|
||
if ret < 0 { | ||
return StriperStat{}, getError(ret) | ||
} | ||
return StriperStat{ | ||
Size: uint64(size), | ||
ModTime: Timespec(ts.CStructToTimespec(ts.CTimespecPtr(&mtime))), | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
//go:build ceph_preview | ||
// +build ceph_preview | ||
|
||
package striper | ||
|
||
// #cgo LDFLAGS: -lrados -lradosstriper | ||
// #include <errno.h> | ||
// #include <stdlib.h> | ||
// #include <rados/librados.h> | ||
// #include <radosstriper/libradosstriper.h> | ||
import "C" | ||
|
||
import ( | ||
"github.com/ceph/go-ceph/rados" | ||
) | ||
|
||
type Striper struct { | ||
striper C.rados_striper_t | ||
|
||
// Hold a reference back to the ioctx that the striper depends on so | ||
// that Go doesn't CG it prematurely. | ||
ioctx *rados.IOContext | ||
} | ||
|
||
type StriperParams struct { | ||
StripeUnit uint | ||
StripeCount uint | ||
ObjectSize uint | ||
} | ||
|
||
// New returns a rados Striper object created from a rados IOContext. | ||
func New(ioctx *rados.IOContext) (*Striper, error) { | ||
var s C.rados_striper_t | ||
ret := C.rados_striper_create(cephIoctx(ioctx), &s) | ||
if err := getError(ret); err != nil { | ||
return nil, err | ||
} | ||
return &Striper{s, ioctx}, nil | ||
} | ||
|
||
// NewWithParams returns a rados Striper object created from a rados | ||
// IOContext and striper parameters. These parameters will be used when | ||
// new objects are created. | ||
func NewWithParams(ioctx *rados.IOContext, params StriperParams) (*Striper, error) { | ||
striper, err := New(ioctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if err := striper.SetObjectLayoutStripeUnit(params.StripeUnit); err != nil { | ||
return nil, err | ||
} | ||
if err := striper.SetObjectLayoutStripeCount(params.StripeCount); err != nil { | ||
return nil, err | ||
} | ||
if err := striper.SetObjectLayoutObjectSize(params.ObjectSize); err != nil { | ||
return nil, err | ||
} | ||
return striper, nil | ||
} | ||
|
||
// Destroy the radosstriper object at the Ceph API level. | ||
func (s *Striper) Destroy() { | ||
C.rados_striper_destroy(s.striper) | ||
} | ||
|
||
func (s *Striper) SetObjectLayoutStripeUnit(count uint) error { | ||
ret := C.rados_striper_set_object_layout_stripe_unit( | ||
s.striper, | ||
C.uint(count), | ||
) | ||
return getError(ret) | ||
} | ||
|
||
func (s *Striper) SetObjectLayoutStripeCount(count uint) error { | ||
ret := C.rados_striper_set_object_layout_stripe_count( | ||
s.striper, | ||
C.uint(count), | ||
) | ||
return getError(ret) | ||
} | ||
|
||
func (s *Striper) SetObjectLayoutObjectSize(count uint) error { | ||
ret := C.rados_striper_set_object_layout_object_size( | ||
s.striper, | ||
C.uint(count), | ||
) | ||
return getError(ret) | ||
} | ||
|
||
// cephIoctx returns a ceph rados_ioctx_t given a go-ceph rados IOContext. | ||
func cephIoctx(radosIoctx *rados.IOContext) C.rados_ioctx_t { | ||
p := radosIoctx.Pointer() | ||
if p == nil { | ||
panic("invalid IOContext pointer") | ||
} | ||
return C.rados_ioctx_t(p) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//go:build ceph_preview | ||
// +build ceph_preview | ||
|
||
package striper | ||
|
||
// #cgo LDFLAGS: -lrados -lradosstriper | ||
// #include <stdlib.h> | ||
// #include <radosstriper/libradosstriper.h> | ||
import "C" | ||
|
||
import "unsafe" | ||
|
||
// Write bytes from data into the striped object at the specified offset. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_write(rados_striper_t striper, | ||
// const char *soid, | ||
// const char *buf, | ||
// size_t len, | ||
// uint64_t off); | ||
func (s *Striper) Write(soid string, data []byte, offset uint64) error { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
bufptr := (*C.char)(unsafe.Pointer(&data[0])) | ||
ret := C.rados_striper_write( | ||
s.striper, | ||
csoid, | ||
bufptr, | ||
C.size_t(len(data)), | ||
C.uint64_t(offset)) | ||
return getError(ret) | ||
} | ||
|
||
// WriteFull writes all of the bytes in data to the striped object, truncating | ||
// the object to the length of data. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_write_full(rados_striper_t striper, | ||
// const char *soid, | ||
// const char *buf, | ||
// size_t len); | ||
func (s *Striper) WriteFull(soid string, data []byte) error { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
bufptr := (*C.char)(unsafe.Pointer(&data[0])) | ||
ret := C.rados_striper_write_full( | ||
s.striper, | ||
csoid, | ||
bufptr, | ||
C.size_t(len(data))) | ||
return getError(ret) | ||
} | ||
|
||
// Append the bytes in data to the end of the striped object. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_append(rados_striper_t striper, | ||
// const char *soid, | ||
// const char *buf, | ||
// size_t len); | ||
func (s *Striper) Append(soid string, data []byte) error { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
bufptr := (*C.char)(unsafe.Pointer(&data[0])) | ||
ret := C.rados_striper_append( | ||
s.striper, | ||
csoid, | ||
bufptr, | ||
C.size_t(len(data))) | ||
return getError(ret) | ||
} | ||
|
||
// Remove a striped RADOS object. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_remove(rados_striper_t striper, | ||
// const char *soid); | ||
func (s *Striper) Remove(soid string) error { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
ret := C.rados_striper_remove(s.striper, csoid) | ||
return getError(ret) | ||
} | ||
|
||
// Truncate a striped object, setting it to the specified size. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_trunc(rados_striper_t striper, const char *soid, uint64_t size); | ||
func (s *Striper) Truncate(soid string, size uint64) error { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
ret := C.rados_striper_trunc( | ||
s.striper, | ||
csoid, | ||
C.uint64_t(size)) | ||
return getError(ret) | ||
} |