mirror of
https://github.com/ceph/go-ceph
synced 2024-12-24 07:03:00 +00:00
rbd: add support for RbdImageOptions
There are several RbdImageOptions that can be used to configure features of an RBD image while creating, cloning, migrating and copying. A follow-up patch will add Create4() where the RbdImageOptions can be used. Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
parent
1a06d47a0d
commit
c06593eef7
122
rbd/options.go
Normal file
122
rbd/options.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package rbd
|
||||||
|
|
||||||
|
// #cgo LDFLAGS: -lrbd
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// #include <rbd/librbd.h>
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RBD image options.
|
||||||
|
RbdImageOptionFormat = C.RBD_IMAGE_OPTION_FORMAT
|
||||||
|
RbdImageOptionFeatures = C.RBD_IMAGE_OPTION_FEATURES
|
||||||
|
RbdImageOptionOrder = C.RBD_IMAGE_OPTION_ORDER
|
||||||
|
RbdImageOptionStripeUnit = C.RBD_IMAGE_OPTION_STRIPE_UNIT
|
||||||
|
RbdImageOptionStripeCount = C.RBD_IMAGE_OPTION_STRIPE_COUNT
|
||||||
|
RbdImageOptionJournalOrder = C.RBD_IMAGE_OPTION_JOURNAL_ORDER
|
||||||
|
RbdImageOptionJournalSplayWidth = C.RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH
|
||||||
|
RbdImageOptionJournalPool = C.RBD_IMAGE_OPTION_JOURNAL_POOL
|
||||||
|
RbdImageOptionFeaturesSet = C.RBD_IMAGE_OPTION_FEATURES_SET
|
||||||
|
RbdImageOptionFeaturesClear = C.RBD_IMAGE_OPTION_FEATURES_CLEAR
|
||||||
|
RbdImageOptionDataPool = C.RBD_IMAGE_OPTION_DATA_POOL
|
||||||
|
// introduced with Ceph Mimic
|
||||||
|
//RbdImageOptionFlatten = C.RBD_IMAGE_OPTION_FLATTEN
|
||||||
|
)
|
||||||
|
|
||||||
|
type RbdImageOptions struct {
|
||||||
|
options C.rbd_image_options_t
|
||||||
|
}
|
||||||
|
|
||||||
|
type RbdImageOption C.int
|
||||||
|
|
||||||
|
func NewRbdImageOptions() *RbdImageOptions {
|
||||||
|
rio := &RbdImageOptions{}
|
||||||
|
C.rbd_image_options_create(&rio.options)
|
||||||
|
return rio
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) Destroy() {
|
||||||
|
C.rbd_image_options_destroy(rio.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) SetString(option RbdImageOption, value string) error {
|
||||||
|
c_value := C.CString(value)
|
||||||
|
defer C.free(unsafe.Pointer(c_value))
|
||||||
|
|
||||||
|
ret := C.rbd_image_options_set_string(rio.options, C.int(option), c_value)
|
||||||
|
if ret != 0 {
|
||||||
|
return fmt.Errorf("%v, could not set option %v to \"%v\"",
|
||||||
|
GetError(ret), option, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) GetString(option RbdImageOption) (string, error) {
|
||||||
|
value := make([]byte, 4096)
|
||||||
|
|
||||||
|
ret := C.rbd_image_options_get_string(rio.options, C.int(option),
|
||||||
|
(*C.char)(unsafe.Pointer(&value[0])),
|
||||||
|
C.size_t(len(value)))
|
||||||
|
if ret != 0 {
|
||||||
|
return "", fmt.Errorf("%v, could not get option %v", GetError(ret), option)
|
||||||
|
}
|
||||||
|
|
||||||
|
return C.GoString((*C.char)(unsafe.Pointer(&value[0]))), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) SetUint64(option RbdImageOption, value uint64) error {
|
||||||
|
c_value := C.uint64_t(value)
|
||||||
|
|
||||||
|
ret := C.rbd_image_options_set_uint64(rio.options, C.int(option), c_value)
|
||||||
|
if ret != 0 {
|
||||||
|
return fmt.Errorf("%v, could not set option %v to \"%v\"",
|
||||||
|
GetError(ret), option, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) GetUint64(option RbdImageOption) (uint64, error) {
|
||||||
|
var c_value C.uint64_t
|
||||||
|
|
||||||
|
ret := C.rbd_image_options_get_uint64(rio.options, C.int(option), &c_value)
|
||||||
|
if ret != 0 {
|
||||||
|
return 0, fmt.Errorf("%v, could not get option %v", GetError(ret), option)
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint64(c_value), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) IsSet(option RbdImageOption) (bool, error) {
|
||||||
|
var c_set C.bool
|
||||||
|
|
||||||
|
ret := C.rbd_image_options_is_set(rio.options, C.int(option), &c_set)
|
||||||
|
if ret != 0 {
|
||||||
|
return false, fmt.Errorf("%v, could not check option %v", GetError(ret), option)
|
||||||
|
}
|
||||||
|
|
||||||
|
return bool(c_set), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) Unset(option RbdImageOption) error {
|
||||||
|
ret := C.rbd_image_options_unset(rio.options, C.int(option))
|
||||||
|
if ret != 0 {
|
||||||
|
return fmt.Errorf("%v, could not unset option %v", GetError(ret), option)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) Clear() {
|
||||||
|
C.rbd_image_options_clear(rio.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rio *RbdImageOptions) IsEmpty() bool {
|
||||||
|
ret := C.rbd_image_options_is_empty(rio.options)
|
||||||
|
return ret != 0
|
||||||
|
}
|
155
rbd/options_test.go
Normal file
155
rbd/options_test.go
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package rbd_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ceph/go-ceph/rbd"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRbdOptions(t *testing.T) {
|
||||||
|
var i uint64
|
||||||
|
var s string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
options := rbd.NewRbdImageOptions()
|
||||||
|
defer options.Destroy()
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionFormat, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionFormat, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionFormat)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionFormat)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionFeatures, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionFeatures, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionFeatures)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionFeatures)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionOrder, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionOrder, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionOrder)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionOrder)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionStripeUnit, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionStripeUnit, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionStripeUnit)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionStripeUnit)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionStripeCount, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionStripeCount, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionStripeCount)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionStripeCount)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionJournalOrder, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionJournalOrder, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionJournalOrder)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionJournalOrder)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionJournalSplayWidth, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionJournalSplayWidth, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionJournalSplayWidth)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionJournalSplayWidth)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionJournalPool, 1)
|
||||||
|
assert.Error(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionJournalPool, "journal")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = options.GetUint64(rbd.RbdImageOptionJournalPool)
|
||||||
|
assert.Error(t, err)
|
||||||
|
s, err = options.GetString(rbd.RbdImageOptionJournalPool)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, s == "journal")
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionFeaturesSet, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionFeaturesSet, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionFeaturesSet)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionFeaturesSet)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionFeaturesClear, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionFeaturesClear, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionFeaturesClear)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionFeaturesClear)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionDataPool, 1)
|
||||||
|
assert.Error(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionDataPool, "data")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = options.GetUint64(rbd.RbdImageOptionDataPool)
|
||||||
|
assert.Error(t, err)
|
||||||
|
s, err = options.GetString(rbd.RbdImageOptionDataPool)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, s == "data")
|
||||||
|
|
||||||
|
/* introduced with Ceph Mimic, can not be tested on Luminous
|
||||||
|
err = options.SetUint64(rbd.RbdImageOptionFlatten, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = options.SetString(rbd.RbdImageOptionFlatten, "string not allowed")
|
||||||
|
assert.Error(t, err)
|
||||||
|
i, err = options.GetUint64(rbd.RbdImageOptionFlatten)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, i == 1)
|
||||||
|
_, err = options.GetString(rbd.RbdImageOptionFlatten)
|
||||||
|
assert.Error(t, err)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRbdOptionsClear(t *testing.T) {
|
||||||
|
options := rbd.NewRbdImageOptions()
|
||||||
|
|
||||||
|
// set at least one option
|
||||||
|
err := options.SetUint64(rbd.RbdImageOptionFormat, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
empty := options.IsEmpty()
|
||||||
|
assert.False(t, empty)
|
||||||
|
|
||||||
|
options.Clear()
|
||||||
|
empty = options.IsEmpty()
|
||||||
|
assert.True(t, empty)
|
||||||
|
|
||||||
|
options.Destroy()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user