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
50b26b4
commit b559f05
Showing
7 changed files
with
409 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,32 @@ | ||
//go: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,42 @@ | ||
//go:build ceph_preview | ||
|
||
package striper | ||
|
||
// #cgo LDFLAGS: -lrados -lradosstriper | ||
// #include <stdlib.h> | ||
// #include <radosstriper/libradosstriper.h> | ||
import "C" | ||
|
||
import ( | ||
"unsafe" | ||
) | ||
|
||
// 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) | ||
} |
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,47 @@ | ||
//go:build (octopus || pacific || quincy) && ceph_preview | ||
|
||
package striper | ||
|
||
// #cgo LDFLAGS: -lrados -lradosstriper | ||
// #include <stdlib.h> | ||
// #include <radosstriper/libradosstriper.h> | ||
import "C" | ||
|
||
import ( | ||
"unsafe" | ||
) | ||
|
||
// Stat returns metadata describing the striped object. | ||
// This version of Stat uses an older API that does not provide time | ||
// granularity below a second: the Nsec value of the StatInfo.ModTime field | ||
// will always be zero. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_stat(rados_striper_t striper, | ||
// const char* soid, | ||
// uint64_t *psize, | ||
// time_t *pmtime); | ||
func (s *Striper) Stat(soid string) (StatInfo, error) { | ||
csoid := C.CString(soid) | ||
defer C.free(unsafe.Pointer(csoid)) | ||
|
||
var ( | ||
size C.uint64_t | ||
mtime C.time_t | ||
) | ||
ret := C.rados_striper_stat( | ||
s.striper, | ||
csoid, | ||
&size, | ||
&mtime) | ||
|
||
if ret < 0 { | ||
return StatInfo{}, getError(ret) | ||
} | ||
modts := Timespec{Sec: int64(mtime)} | ||
return StatInfo{ | ||
Size: uint64(size), | ||
ModTime: modts, | ||
}, 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,45 @@ | ||
//go:build !(octopus || pacific || quincy) && 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" | ||
) | ||
|
||
// 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) (StatInfo, 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 StatInfo{}, getError(ret) | ||
} | ||
return StatInfo{ | ||
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,16 @@ | ||
//go:build ceph_preview | ||
|
||
package striper | ||
|
||
import ( | ||
ts "github.com/ceph/go-ceph/internal/timespec" | ||
) | ||
|
||
// Timespec behaves similarly to C's struct timespec. | ||
type Timespec ts.Timespec | ||
|
||
// StatInfo contains values returned by a Striper's Stat call. | ||
type StatInfo struct { | ||
Size uint64 | ||
ModTime Timespec | ||
} |
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,121 @@ | ||
//go:build ceph_preview | ||
|
||
package striper | ||
|
||
// #cgo LDFLAGS: -lrados -lradosstriper | ||
// #include <errno.h> | ||
// #include <stdlib.h> | ||
// #include <radosstriper/libradosstriper.h> | ||
import "C" | ||
|
||
import ( | ||
"github.com/ceph/go-ceph/rados" | ||
) | ||
|
||
// Striper helps manage the reading, writing, and management of RADOS | ||
// striped objects. | ||
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 garbage collect it prematurely. | ||
ioctx *rados.IOContext | ||
} | ||
|
||
// Layout contains a group of values used to define the size parameters of | ||
// striped objects. Note that these parameters only effect new striped objects. | ||
// Existing striped objects retain the parameters they were created with. | ||
type Layout 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 | ||
} | ||
|
||
// NewWithLayout returns a rados Striper object created from a rados IOContext | ||
// and striper layout parameters. These parameters will be used when new | ||
// objects are created. | ||
func NewWithLayout(ioctx *rados.IOContext, layout Layout) (*Striper, error) { | ||
striper, err := New(ioctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if err := striper.SetObjectLayoutStripeUnit(layout.StripeUnit); err != nil { | ||
return nil, err | ||
} | ||
if err := striper.SetObjectLayoutStripeCount(layout.StripeCount); err != nil { | ||
return nil, err | ||
} | ||
if err := striper.SetObjectLayoutObjectSize(layout.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) | ||
} | ||
|
||
// SetObjectLayoutStripeUnit sets the stripe unit value used to layout | ||
// new objects. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_set_object_layout_stripe_unit(rados_striper_t striper, | ||
// unsigned int stripe_unit); | ||
func (s *Striper) SetObjectLayoutStripeUnit(count uint) error { | ||
ret := C.rados_striper_set_object_layout_stripe_unit( | ||
s.striper, | ||
C.uint(count), | ||
) | ||
return getError(ret) | ||
} | ||
|
||
// SetObjectLayoutStripeCount sets the stripe count value used to layout | ||
// new objects. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_set_object_layout_stripe_count(rados_striper_t striper, | ||
// unsigned int stripe_count); | ||
func (s *Striper) SetObjectLayoutStripeCount(count uint) error { | ||
ret := C.rados_striper_set_object_layout_stripe_count( | ||
s.striper, | ||
C.uint(count), | ||
) | ||
return getError(ret) | ||
} | ||
|
||
// SetObjectLayoutObjectSize sets the object size value used to layout | ||
// new objects. | ||
// | ||
// Implements: | ||
// | ||
// int rados_striper_set_object_layout_object_size(rados_striper_t striper, | ||
// unsigned int object_size); | ||
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) | ||
} |
Oops, something went wrong.