rebase: update go-ceph to v0.5.0

as go-ceph is 0.5.0 is released updating
the dependency to latest release.
more info about release at
https://github.com/ceph/go-ceph/releases/tag/v0.5.0

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna
2020-08-11 20:12:21 +05:30
committed by mergify[bot]
parent 5f6fec5f0a
commit 2808d526bb
26 changed files with 816 additions and 199 deletions

View File

@ -6,12 +6,14 @@ package rados
import "C"
import (
"bytes"
"unsafe"
"github.com/ceph/go-ceph/internal/cutil"
"github.com/ceph/go-ceph/internal/retry"
)
var argvPlaceholder = "placeholder"
// ClusterStat represents Ceph cluster statistics.
type ClusterStat struct {
Kb uint64
@ -117,14 +119,7 @@ func (c *Conn) ListPools() (names []string, err error) {
continue
}
tmp := bytes.SplitAfter(buf[:ret-1], []byte{0})
for _, s := range tmp {
if len(s) > 0 {
name := C.GoString((*C.char)(unsafe.Pointer(&s[0])))
names = append(names, name)
}
}
names = cutil.SplitSparseBuffer(buf[:ret])
return names, nil
}
}
@ -197,28 +192,47 @@ func (c *Conn) GetClusterStats() (stat ClusterStat, err error) {
}, nil
}
// ParseCmdLineArgs configures the connection from command line arguments.
func (c *Conn) ParseCmdLineArgs(args []string) error {
// add an empty element 0 -- Ceph treats the array as the actual contents
// of argv and skips the first element (the executable name)
argc := C.int(len(args) + 1)
argv := make([]*C.char, argc)
// make the first element a string just in case it is ever examined
argv[0] = C.CString("placeholder")
defer C.free(unsafe.Pointer(argv[0]))
for i, arg := range args {
argv[i+1] = C.CString(arg)
defer C.free(unsafe.Pointer(argv[i+1]))
// ParseConfigArgv configures the connection using a unix style command line
// argument vector.
//
// Implements:
// int rados_conf_parse_argv(rados_t cluster, int argc,
// const char **argv);
func (c *Conn) ParseConfigArgv(argv []string) error {
if c.cluster == nil {
return ErrNotConnected
}
if len(argv) == 0 {
return ErrEmptyArgument
}
cargv := make([]*C.char, len(argv))
for i := range argv {
cargv[i] = C.CString(argv[i])
defer C.free(unsafe.Pointer(cargv[i]))
}
ret := C.rados_conf_parse_argv(c.cluster, argc, &argv[0])
ret := C.rados_conf_parse_argv(c.cluster, C.int(len(cargv)), &cargv[0])
return getError(ret)
}
// ParseCmdLineArgs configures the connection from command line arguments.
//
// This function passes a placeholder value to Ceph as argv[0], see
// ParseConfigArgv for a version of this function that allows the caller to
// specify argv[0].
func (c *Conn) ParseCmdLineArgs(args []string) error {
argv := make([]string, len(args)+1)
// Ceph expects a proper argv array as the actual contents with the
// first element containing the executable name
argv[0] = argvPlaceholder
for i := range args {
argv[i+1] = args[i]
}
return c.ParseConfigArgv(argv)
}
// ParseDefaultConfigEnv configures the connection from the default Ceph
// environment variable(s).
// environment variable CEPH_ARGS.
func (c *Conn) ParseDefaultConfigEnv() error {
ret := C.rados_conf_parse_env(c.cluster, nil)
return getError(ret)
@ -273,7 +287,7 @@ func (c *Conn) GetPoolByName(name string) (int64, error) {
defer C.free(unsafe.Pointer(c_name))
ret := int64(C.rados_pool_lookup(c.cluster, c_name))
if ret < 0 {
return 0, RadosError(ret)
return 0, radosError(ret)
}
return ret, nil
}
@ -287,7 +301,7 @@ func (c *Conn) GetPoolByID(id int64) (string, error) {
c_id := C.int64_t(id)
ret := int(C.rados_pool_reverse_lookup(c.cluster, c_id, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))))
if ret < 0 {
return "", RadosError(ret)
return "", radosError(ret)
}
return C.GoString((*C.char)(unsafe.Pointer(&buf[0]))), nil
}

View File

@ -7,32 +7,27 @@ import "C"
import (
"errors"
"fmt"
"github.com/ceph/go-ceph/internal/errutil"
)
// revive:disable:exported Temporarily live with stuttering
// radosError represents an error condition returned from the Ceph RADOS APIs.
type radosError int
// RadosError represents an error condition returned from the Ceph RADOS APIs.
type RadosError int
// Error returns the error string for the radosError type.
func (e radosError) Error() string {
return errutil.FormatErrorCode("rados", int(e))
}
// revive:enable:exported
// Error returns the error string for the RadosError type.
func (e RadosError) Error() string {
errno, s := errutil.FormatErrno(int(e))
if s == "" {
return fmt.Sprintf("rados: ret=%d", errno)
}
return fmt.Sprintf("rados: ret=%d, %s", errno, s)
func (e radosError) ErrorCode() int {
return int(e)
}
func getError(e C.int) error {
if e == 0 {
return nil
}
return RadosError(e)
return radosError(e)
}
// getErrorIfNegative converts a ceph return code to error if negative.
@ -48,19 +43,26 @@ func getErrorIfNegative(ret C.int) error {
// Public go errors:
var (
// ErrNotConnected is returned when functions are called without a RADOS connection
// ErrNotConnected is returned when functions are called
// without a RADOS connection.
ErrNotConnected = errors.New("RADOS not connected")
// ErrEmptyArgument may be returned if a function argument is passed
// a zero-length slice or map.
ErrEmptyArgument = errors.New("Argument must contain at least one item")
// ErrInvalidIOContext may be returned if an api call requires an IOContext
// but IOContext is not ready for use.
ErrInvalidIOContext = errors.New("IOContext is not ready for use")
)
// Public RadosErrors:
// Public radosErrors:
const (
// ErrNotFound indicates a missing resource.
ErrNotFound = RadosError(-C.ENOENT)
ErrNotFound = radosError(-C.ENOENT)
// ErrPermissionDenied indicates a permissions issue.
ErrPermissionDenied = RadosError(-C.EPERM)
ErrPermissionDenied = radosError(-C.EPERM)
// ErrObjectExists indicates that an exclusive object creation failed.
ErrObjectExists = RadosError(-C.EEXIST)
ErrObjectExists = radosError(-C.EEXIST)
// RadosErrorNotFound indicates a missing resource.
//
@ -75,7 +77,7 @@ const (
// Private errors:
const (
errNameTooLong = RadosError(-C.ENAMETOOLONG)
errNameTooLong = radosError(-C.ENAMETOOLONG)
errRange = RadosError(-C.ERANGE)
errRange = radosError(-C.ERANGE)
)

View File

@ -92,6 +92,15 @@ type IOContext struct {
ioctx C.rados_ioctx_t
}
// validate returns an error if the ioctx is not ready to be used
// with ceph C calls.
func (ioctx *IOContext) validate() error {
if ioctx.ioctx == nil {
return ErrInvalidIOContext
}
return nil
}
// Pointer returns a pointer reference to an internal structure.
// This function should NOT be used outside of go-ceph itself.
func (ioctx *IOContext) Pointer() unsafe.Pointer {
@ -249,6 +258,15 @@ func (ioctx *IOContext) GetPoolStats() (stat PoolStat, err error) {
}, nil
}
// GetPoolID returns the pool ID associated with the I/O context.
//
// Implements:
// int64_t rados_ioctx_get_id(rados_ioctx_t io)
func (ioctx *IOContext) GetPoolID() int64 {
ret := C.rados_ioctx_get_id(ioctx.ioctx)
return int64(ret)
}
// GetPoolName returns the name of the pool associated with the I/O context.
func (ioctx *IOContext) GetPoolName() (name string, err error) {
var (
@ -589,7 +607,7 @@ func (ioctx *IOContext) ListLockers(oid, name string) (*LockInfo, error) {
}
if ret < 0 {
return nil, RadosError(ret)
return nil, radosError(ret)
}
return &LockInfo{int(ret), c_exclusive == 1, C.GoString(c_tag), splitCString(c_clients, c_clients_len), splitCString(c_cookies, c_cookies_len), splitCString(c_addrs, c_addrs_len)}, nil
}
@ -628,3 +646,16 @@ func (ioctx *IOContext) BreakLock(oid, name, client, cookie string) (int, error)
return int(ret), getError(ret)
}
}
// GetLastVersion will return the version number of the last object read or
// written to.
//
// Implements:
// uint64_t rados_get_last_version(rados_ioctx_t io);
func (ioctx *IOContext) GetLastVersion() (uint64, error) {
if err := ioctx.validate(); err != nil {
return 0, err
}
v := C.rados_get_last_version(ioctx.ioctx)
return uint64(v), nil
}

189
vendor/github.com/ceph/go-ceph/rados/snapshot.go generated vendored Normal file
View File

@ -0,0 +1,189 @@
package rados
// #cgo LDFLAGS: -lrados
// #include <stdlib.h>
// #include <rados/librados.h>
import "C"
import (
"time"
"unsafe"
"github.com/ceph/go-ceph/internal/retry"
)
// CreateSnap creates a pool-wide snapshot.
//
// Implements:
// int rados_ioctx_snap_create(rados_ioctx_t io, const char *snapname)
func (ioctx *IOContext) CreateSnap(snapName string) error {
if err := ioctx.validate(); err != nil {
return err
}
cSnapName := C.CString(snapName)
defer C.free(unsafe.Pointer(cSnapName))
ret := C.rados_ioctx_snap_create(ioctx.ioctx, cSnapName)
return getError(ret)
}
// RemoveSnap deletes the pool snapshot.
//
// Implements:
// int rados_ioctx_snap_remove(rados_ioctx_t io, const char *snapname)
func (ioctx *IOContext) RemoveSnap(snapName string) error {
if err := ioctx.validate(); err != nil {
return err
}
cSnapName := C.CString(snapName)
defer C.free(unsafe.Pointer(cSnapName))
ret := C.rados_ioctx_snap_remove(ioctx.ioctx, cSnapName)
return getError(ret)
}
// SnapID represents the ID of a rados snapshot.
type SnapID C.rados_snap_t
// LookupSnap returns the ID of a pool snapshot.
//
// Implements:
// int rados_ioctx_snap_lookup(rados_ioctx_t io, const char *name, rados_snap_t *id)
func (ioctx *IOContext) LookupSnap(snapName string) (SnapID, error) {
var snapID SnapID
if err := ioctx.validate(); err != nil {
return snapID, err
}
cSnapName := C.CString(snapName)
defer C.free(unsafe.Pointer(cSnapName))
ret := C.rados_ioctx_snap_lookup(
ioctx.ioctx,
cSnapName,
(*C.rados_snap_t)(&snapID))
return snapID, getError(ret)
}
// GetSnapName returns the name of a pool snapshot with the given snapshot ID.
//
// Implements:
// int rados_ioctx_snap_get_name(rados_ioctx_t io, rados_snap_t id, char *name, int maxlen)
func (ioctx *IOContext) GetSnapName(snapID SnapID) (string, error) {
if err := ioctx.validate(); err != nil {
return "", err
}
var (
buf []byte
err error
)
// range from 1k to 64KiB
retry.WithSizes(1024, 1<<16, func(len int) retry.Hint {
cLen := C.int(len)
buf = make([]byte, cLen)
ret := C.rados_ioctx_snap_get_name(
ioctx.ioctx,
(C.rados_snap_t)(snapID),
(*C.char)(unsafe.Pointer(&buf[0])),
cLen)
err = getError(ret)
return retry.Size(int(cLen)).If(err == errRange)
})
if err != nil {
return "", err
}
return C.GoString((*C.char)(unsafe.Pointer(&buf[0]))), nil
}
// GetSnapStamp returns the time of the pool snapshot creation.
//
// Implements:
// int rados_ioctx_snap_get_stamp(rados_ioctx_t io, rados_snap_t id, time_t *t)
func (ioctx *IOContext) GetSnapStamp(snapID SnapID) (time.Time, error) {
var cTime C.time_t
if err := ioctx.validate(); err != nil {
return time.Unix(int64(cTime), 0), err
}
ret := C.rados_ioctx_snap_get_stamp(
ioctx.ioctx,
(C.rados_snap_t)(snapID),
&cTime)
return time.Unix(int64(cTime), 0), getError(ret)
}
// ListSnaps returns a slice containing the SnapIDs of existing pool snapshots.
//
// Implements:
// int rados_ioctx_snap_list(rados_ioctx_t io, rados_snap_t *snaps, int maxlen)
func (ioctx *IOContext) ListSnaps() ([]SnapID, error) {
if err := ioctx.validate(); err != nil {
return nil, err
}
var (
snapList []SnapID
cLen C.int
err error
ret C.int
)
retry.WithSizes(100, 1000, func(maxlen int) retry.Hint {
cLen = C.int(maxlen)
snapList = make([]SnapID, cLen)
ret = C.rados_ioctx_snap_list(
ioctx.ioctx,
(*C.rados_snap_t)(unsafe.Pointer(&snapList[0])),
cLen)
err = getErrorIfNegative(ret)
return retry.Size(int(cLen)).If(err == errRange)
})
if err != nil {
return nil, err
}
return snapList[:ret], nil
}
// RollbackSnap rollbacks the object with key oID to the pool snapshot.
// The contents of the object will be the same as when the snapshot was taken.
//
// Implements:
// int rados_ioctx_snap_rollback(rados_ioctx_t io, const char *oid, const char *snapname);
func (ioctx *IOContext) RollbackSnap(oid, snapName string) error {
if err := ioctx.validate(); err != nil {
return err
}
coid := C.CString(oid)
defer C.free(unsafe.Pointer(coid))
cSnapName := C.CString(snapName)
defer C.free(unsafe.Pointer(cSnapName))
ret := C.rados_ioctx_snap_rollback(ioctx.ioctx, coid, cSnapName)
return getError(ret)
}
// SnapHead is the representation of LIBRADOS_SNAP_HEAD from librados.
// SnapHead can be used to reset the IOContext to stop reading from a snapshot.
const SnapHead = SnapID(C.LIBRADOS_SNAP_HEAD)
// SetReadSnap sets the snapshot from which reads are performed.
// Subsequent reads will return data as it was at the time of that snapshot.
// Pass SnapHead for no snapshot (i.e. normal operation).
//
// Implements:
// void rados_ioctx_snap_set_read(rados_ioctx_t io, rados_snap_t snap);
func (ioctx *IOContext) SetReadSnap(snapID SnapID) error {
if err := ioctx.validate(); err != nil {
return err
}
C.rados_ioctx_snap_set_read(ioctx.ioctx, (C.rados_snap_t)(snapID))
return nil
}