rebase: Make use of latest go ceph library

The go-ceph version 0.4.0 is available now which got some important
library changes required for ceph csi project.

Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
Humble Chirammal
2020-06-17 15:07:06 +05:30
committed by mergify[bot]
parent 306d5b1da0
commit 58bf45a13e
67 changed files with 1133 additions and 362 deletions

193
vendor/github.com/ceph/go-ceph/rados/command.go generated vendored Normal file
View File

@ -0,0 +1,193 @@
package rados
// #cgo LDFLAGS: -lrados
// #include <stdlib.h>
// #include <rados/librados.h>
import "C"
import (
"unsafe"
"github.com/ceph/go-ceph/internal/cutil"
)
func radosBufferFree(p unsafe.Pointer) {
C.rados_buffer_free((*C.char)(p))
}
// MonCommand sends a command to one of the monitors
func (c *Conn) MonCommand(args []byte) ([]byte, string, error) {
return c.MonCommandWithInputBuffer(args, nil)
}
// MonCommandWithInputBuffer sends a command to one of the monitors, with an input buffer
func (c *Conn) MonCommandWithInputBuffer(args, inputBuffer []byte) ([]byte, string, error) {
ci := cutil.NewCommandInput([][]byte{args}, inputBuffer)
defer ci.Free()
co := cutil.NewCommandOutput().SetFreeFunc(radosBufferFree)
defer co.Free()
ret := C.rados_mon_command(
c.cluster,
(**C.char)(ci.Cmd()),
C.size_t(ci.CmdLen()),
(*C.char)(ci.InBuf()),
C.size_t(ci.InBufLen()),
(**C.char)(co.OutBuf()),
(*C.size_t)(co.OutBufLen()),
(**C.char)(co.Outs()),
(*C.size_t)(co.OutsLen()))
buf, status := co.GoValues()
return buf, status, getError(ret)
}
// PGCommand sends a command to one of the PGs
//
// Implements:
// int rados_pg_command(rados_t cluster, const char *pgstr,
// const char **cmd, size_t cmdlen,
// const char *inbuf, size_t inbuflen,
// char **outbuf, size_t *outbuflen,
// char **outs, size_t *outslen);
func (c *Conn) PGCommand(pgid []byte, args [][]byte) ([]byte, string, error) {
return c.PGCommandWithInputBuffer(pgid, args, nil)
}
// PGCommandWithInputBuffer sends a command to one of the PGs, with an input buffer
//
// Implements:
// int rados_pg_command(rados_t cluster, const char *pgstr,
// const char **cmd, size_t cmdlen,
// const char *inbuf, size_t inbuflen,
// char **outbuf, size_t *outbuflen,
// char **outs, size_t *outslen);
func (c *Conn) PGCommandWithInputBuffer(pgid []byte, args [][]byte, inputBuffer []byte) ([]byte, string, error) {
name := C.CString(string(pgid))
defer C.free(unsafe.Pointer(name))
ci := cutil.NewCommandInput(args, inputBuffer)
defer ci.Free()
co := cutil.NewCommandOutput().SetFreeFunc(radosBufferFree)
defer co.Free()
ret := C.rados_pg_command(
c.cluster,
name,
(**C.char)(ci.Cmd()),
C.size_t(ci.CmdLen()),
(*C.char)(ci.InBuf()),
C.size_t(ci.InBufLen()),
(**C.char)(co.OutBuf()),
(*C.size_t)(co.OutBufLen()),
(**C.char)(co.Outs()),
(*C.size_t)(co.OutsLen()))
buf, status := co.GoValues()
return buf, status, getError(ret)
}
// MgrCommand sends a command to a ceph-mgr.
func (c *Conn) MgrCommand(args [][]byte) ([]byte, string, error) {
return c.MgrCommandWithInputBuffer(args, nil)
}
// MgrCommandWithInputBuffer sends a command, with an input buffer, to a ceph-mgr.
//
// Implements:
// int rados_mgr_command(rados_t cluster, const char **cmd,
// size_t cmdlen, const char *inbuf,
// size_t inbuflen, char **outbuf,
// size_t *outbuflen, char **outs,
// size_t *outslen);
func (c *Conn) MgrCommandWithInputBuffer(args [][]byte, inputBuffer []byte) ([]byte, string, error) {
ci := cutil.NewCommandInput(args, inputBuffer)
defer ci.Free()
co := cutil.NewCommandOutput().SetFreeFunc(radosBufferFree)
defer co.Free()
ret := C.rados_mgr_command(
c.cluster,
(**C.char)(ci.Cmd()),
C.size_t(ci.CmdLen()),
(*C.char)(ci.InBuf()),
C.size_t(ci.InBufLen()),
(**C.char)(co.OutBuf()),
(*C.size_t)(co.OutBufLen()),
(**C.char)(co.Outs()),
(*C.size_t)(co.OutsLen()))
buf, status := co.GoValues()
return buf, status, getError(ret)
}
// OsdCommand sends a command to the specified ceph OSD.
func (c *Conn) OsdCommand(osd int, args [][]byte) ([]byte, string, error) {
return c.OsdCommandWithInputBuffer(osd, args, nil)
}
// OsdCommandWithInputBuffer sends a command, with an input buffer, to the
// specified ceph OSD.
//
// Implements:
// int rados_osd_command(rados_t cluster, int osdid,
// const char **cmd, size_t cmdlen,
// const char *inbuf, size_t inbuflen,
// char **outbuf, size_t *outbuflen,
// char **outs, size_t *outslen);
func (c *Conn) OsdCommandWithInputBuffer(
osd int, args [][]byte, inputBuffer []byte) ([]byte, string, error) {
ci := cutil.NewCommandInput(args, inputBuffer)
defer ci.Free()
co := cutil.NewCommandOutput().SetFreeFunc(radosBufferFree)
defer co.Free()
ret := C.rados_osd_command(
c.cluster,
C.int(osd),
(**C.char)(ci.Cmd()),
C.size_t(ci.CmdLen()),
(*C.char)(ci.InBuf()),
C.size_t(ci.InBufLen()),
(**C.char)(co.OutBuf()),
(*C.size_t)(co.OutBufLen()),
(**C.char)(co.Outs()),
(*C.size_t)(co.OutsLen()))
buf, status := co.GoValues()
return buf, status, getError(ret)
}
// MonCommandTarget sends a command to a specified monitor.
func (c *Conn) MonCommandTarget(name string, args [][]byte) ([]byte, string, error) {
return c.MonCommandTargetWithInputBuffer(name, args, nil)
}
// MonCommandTargetWithInputBuffer sends a command, with an input buffer, to a specified monitor.
//
// Implements:
// int rados_mon_command_target(rados_t cluster, const char *name,
// const char **cmd, size_t cmdlen,
// const char *inbuf, size_t inbuflen,
// char **outbuf, size_t *outbuflen,
// char **outs, size_t *outslen);
func (c *Conn) MonCommandTargetWithInputBuffer(
name string, args [][]byte, inputBuffer []byte) ([]byte, string, error) {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
ci := cutil.NewCommandInput(args, inputBuffer)
defer ci.Free()
co := cutil.NewCommandOutput().SetFreeFunc(radosBufferFree)
defer co.Free()
ret := C.rados_mon_command_target(
c.cluster,
cName,
(**C.char)(ci.Cmd()),
C.size_t(ci.CmdLen()),
(*C.char)(ci.InBuf()),
C.size_t(ci.InBufLen()),
(**C.char)(co.OutBuf()),
(*C.size_t)(co.OutBufLen()),
(**C.char)(co.Outs()),
(*C.size_t)(co.OutsLen()))
buf, status := co.GoValues()
return buf, status, getError(ret)
}

View File

@ -8,6 +8,8 @@ import "C"
import (
"bytes"
"unsafe"
"github.com/ceph/go-ceph/internal/retry"
)
// ClusterStat represents Ceph cluster statistics.
@ -140,19 +142,26 @@ func (c *Conn) SetConfigOption(option, value string) error {
// GetConfigOption returns the value of the Ceph configuration option
// identified by the given name.
func (c *Conn) GetConfigOption(name string) (value string, err error) {
buf := make([]byte, 4096)
c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))
ret := int(C.rados_conf_get(c.cluster, c_name,
(*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))))
// FIXME: ret may be -ENAMETOOLONG if the buffer is not large enough. We
// can handle this case, but we need a reliable way to test for
// -ENAMETOOLONG constant. Will the syscall/Errno stuff in Go help?
if ret == 0 {
value = C.GoString((*C.char)(unsafe.Pointer(&buf[0])))
return value, nil
cOption := C.CString(name)
defer C.free(unsafe.Pointer(cOption))
var buf []byte
// range from 4k to 256KiB
retry.WithSizes(4096, 1<<18, func(size int) retry.Hint {
buf = make([]byte, size)
ret := C.rados_conf_get(
c.cluster,
cOption,
(*C.char)(unsafe.Pointer(&buf[0])),
C.size_t(len(buf)))
err = getError(ret)
return retry.DoubleSize.If(err == errNameTooLong)
})
if err != nil {
return "", err
}
return "", RadosError(ret)
value = C.GoString((*C.char)(unsafe.Pointer(&buf[0])))
return value, nil
}
// WaitForLatestOSDMap blocks the caller until the latest OSD map has been
@ -282,121 +291,3 @@ func (c *Conn) GetPoolByID(id int64) (string, error) {
}
return C.GoString((*C.char)(unsafe.Pointer(&buf[0]))), nil
}
// MonCommand sends a command to one of the monitors
func (c *Conn) MonCommand(args []byte) (buffer []byte, info string, err error) {
return c.monCommand(args, nil)
}
// MonCommandWithInputBuffer sends a command to one of the monitors, with an input buffer
func (c *Conn) MonCommandWithInputBuffer(args, inputBuffer []byte) (buffer []byte, info string, err error) {
return c.monCommand(args, inputBuffer)
}
func (c *Conn) monCommand(args, inputBuffer []byte) (buffer []byte, info string, err error) {
argv := C.CString(string(args))
defer C.free(unsafe.Pointer(argv))
var (
outs, outbuf *C.char
outslen, outbuflen C.size_t
)
inbuf := C.CString(string(inputBuffer))
inbufLen := len(inputBuffer)
defer C.free(unsafe.Pointer(inbuf))
ret := C.rados_mon_command(c.cluster,
&argv, 1,
inbuf, // bulk input (e.g. crush map)
C.size_t(inbufLen), // length inbuf
&outbuf, // buffer
&outbuflen, // buffer length
&outs, // status string
&outslen)
if outslen > 0 {
info = C.GoStringN(outs, C.int(outslen))
C.free(unsafe.Pointer(outs))
}
if outbuflen > 0 {
buffer = C.GoBytes(unsafe.Pointer(outbuf), C.int(outbuflen))
C.free(unsafe.Pointer(outbuf))
}
if ret != 0 {
err = getError(ret)
return nil, info, err
}
return
}
// PGCommand sends a command to one of the PGs
//
// Implements:
// int rados_pg_command(rados_t cluster, const char *pgstr,
// const char **cmd, size_t cmdlen,
// const char *inbuf, size_t inbuflen,
// char **outbuf, size_t *outbuflen,
// char **outs, size_t *outslen);
func (c *Conn) PGCommand(pgid []byte, args [][]byte) (buffer []byte, info string, err error) {
return c.pgCommand(pgid, args, nil)
}
// PGCommandWithInputBuffer sends a command to one of the PGs, with an input buffer
//
// Implements:
// int rados_pg_command(rados_t cluster, const char *pgstr,
// const char **cmd, size_t cmdlen,
// const char *inbuf, size_t inbuflen,
// char **outbuf, size_t *outbuflen,
// char **outs, size_t *outslen);
func (c *Conn) PGCommandWithInputBuffer(pgid []byte, args [][]byte, inputBuffer []byte) (buffer []byte, info string, err error) {
return c.pgCommand(pgid, args, inputBuffer)
}
func (c *Conn) pgCommand(pgid []byte, args [][]byte, inputBuffer []byte) (buffer []byte, info string, err error) {
name := C.CString(string(pgid))
defer C.free(unsafe.Pointer(name))
argc := len(args)
argv := make([]*C.char, argc)
for i, arg := range args {
argv[i] = C.CString(string(arg))
defer C.free(unsafe.Pointer(argv[i]))
}
var (
outs, outbuf *C.char
outslen, outbuflen C.size_t
)
inbuf := C.CString(string(inputBuffer))
inbufLen := len(inputBuffer)
defer C.free(unsafe.Pointer(inbuf))
ret := C.rados_pg_command(c.cluster,
name,
&argv[0],
C.size_t(argc),
inbuf, // bulk input
C.size_t(inbufLen), // length inbuf
&outbuf, // buffer
&outbuflen, // buffer length
&outs, // status string
&outslen)
if outslen > 0 {
info = C.GoStringN(outs, C.int(outslen))
C.free(unsafe.Pointer(outs))
}
if outbuflen > 0 {
buffer = C.GoBytes(unsafe.Pointer(outbuf), C.int(outbuflen))
C.free(unsafe.Pointer(outbuf))
}
if ret != 0 {
err = getError(ret)
return nil, info, err
}
return
}

View File

@ -35,6 +35,16 @@ func getError(e C.int) error {
return RadosError(e)
}
// getErrorIfNegative converts a ceph return code to error if negative.
// This is useful for functions that return a usable positive value on
// success but a negative error number on error.
func getErrorIfNegative(ret C.int) error {
if ret >= 0 {
return nil
}
return getError(ret)
}
// Public go errors:
var (
@ -61,3 +71,11 @@ const (
// Deprecated: use ErrPermissionDenied instead
RadosErrorPermissionDenied = ErrPermissionDenied
)
// Private errors:
const (
errNameTooLong = RadosError(-C.ENAMETOOLONG)
errRange = RadosError(-C.ERANGE)
)

View File

@ -28,6 +28,8 @@ import (
"syscall"
"time"
"unsafe"
"github.com/ceph/go-ceph/internal/retry"
)
// CreateOption is passed to IOContext.Create() and should be one of
@ -249,19 +251,24 @@ func (ioctx *IOContext) GetPoolStats() (stat PoolStat, err error) {
// GetPoolName returns the name of the pool associated with the I/O context.
func (ioctx *IOContext) GetPoolName() (name string, err error) {
buf := make([]byte, 128)
for {
ret := C.rados_ioctx_get_pool_name(ioctx.ioctx,
(*C.char)(unsafe.Pointer(&buf[0])), C.unsigned(len(buf)))
if ret == -C.ERANGE {
buf = make([]byte, len(buf)*2)
continue
} else if ret < 0 {
return "", getError(ret)
}
name = C.GoStringN((*C.char)(unsafe.Pointer(&buf[0])), ret)
return name, nil
var (
buf []byte
ret C.int
)
retry.WithSizes(128, 8192, func(size int) retry.Hint {
buf = make([]byte, size)
ret = C.rados_ioctx_get_pool_name(
ioctx.ioctx,
(*C.char)(unsafe.Pointer(&buf[0])),
C.unsigned(len(buf)))
err = getErrorIfNegative(ret)
return retry.DoubleSize.If(err == errRange)
})
if err != nil {
return "", err
}
name = C.GoStringN((*C.char)(unsafe.Pointer(&buf[0])), ret)
return name, nil
}
// ObjectListFunc is the type of the function called for each object visited