mirror of https://github.com/ceph/go-ceph
rbd: add GroupSnapList implementing rbd_group_snap_list
* Add GroupSnapList implementing rbd_group_snap_list Adds tests for the above. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
fd08e791cc
commit
ffeabf1436
|
@ -10,6 +10,7 @@ import "C"
|
|||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ceph/go-ceph/internal/retry"
|
||||
"github.com/ceph/go-ceph/rados"
|
||||
)
|
||||
|
||||
|
@ -64,3 +65,68 @@ func GroupSnapRename(ioctx *rados.IOContext, group, src, dest string) error {
|
|||
cephIoctx(ioctx), cGroupName, cOldSnapName, cNewSnapName)
|
||||
return getError(ret)
|
||||
}
|
||||
|
||||
// GroupSnapState represents the state of a group snapshot in GroupSnapInfo.
|
||||
type GroupSnapState int
|
||||
|
||||
const (
|
||||
// GroupSnapStateIncomplete is equivalent to RBD_GROUP_SNAP_STATE_INCOMPLETE.
|
||||
GroupSnapStateIncomplete = GroupSnapState(C.RBD_GROUP_SNAP_STATE_INCOMPLETE)
|
||||
// GroupSnapStateComplete is equivalent to RBD_GROUP_SNAP_STATE_COMPLETE.
|
||||
GroupSnapStateComplete = GroupSnapState(C.RBD_GROUP_SNAP_STATE_COMPLETE)
|
||||
)
|
||||
|
||||
// GroupSnapInfo values are returned by GroupSnapList, representing the
|
||||
// snapshots that are part of an rbd group.
|
||||
type GroupSnapInfo struct {
|
||||
Name string
|
||||
State GroupSnapState
|
||||
}
|
||||
|
||||
// GroupSnapList returns a slice of snapshots in a group.
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_group_snap_list(rados_ioctx_t group_p,
|
||||
// const char *group_name,
|
||||
// rbd_group_snap_info_t *snaps,
|
||||
// size_t group_snap_info_size,
|
||||
// size_t *num_entries);
|
||||
func GroupSnapList(ioctx *rados.IOContext, group string) ([]GroupSnapInfo, error) {
|
||||
cGroupName := C.CString(group)
|
||||
defer C.free(unsafe.Pointer(cGroupName))
|
||||
|
||||
var (
|
||||
cSnaps []C.rbd_group_snap_info_t
|
||||
cSize C.size_t
|
||||
err error
|
||||
)
|
||||
retry.WithSizes(1024, 262144, func(size int) retry.Hint {
|
||||
cSize = C.size_t(size)
|
||||
cSnaps = make([]C.rbd_group_snap_info_t, cSize)
|
||||
ret := C.rbd_group_snap_list(
|
||||
cephIoctx(ioctx),
|
||||
cGroupName,
|
||||
(*C.rbd_group_snap_info_t)(unsafe.Pointer(&cSnaps[0])),
|
||||
C.sizeof_rbd_group_snap_info_t,
|
||||
&cSize)
|
||||
err = getErrorIfNegative(ret)
|
||||
return retry.Size(int(cSize)).If(err == errRange)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snaps := make([]GroupSnapInfo, cSize)
|
||||
for i := range snaps {
|
||||
snaps[i].Name = C.GoString(cSnaps[i].name)
|
||||
snaps[i].State = GroupSnapState(cSnaps[i].state)
|
||||
}
|
||||
|
||||
// free C memory allocated by C.rbd_group_snap_list call
|
||||
ret := C.rbd_group_snap_list_cleanup(
|
||||
(*C.rbd_group_snap_info_t)(unsafe.Pointer(&cSnaps[0])),
|
||||
C.sizeof_rbd_group_snap_info_t,
|
||||
cSize)
|
||||
return snaps, getError(ret)
|
||||
}
|
||||
|
|
|
@ -63,6 +63,47 @@ func TestGroupSnapshots(t *testing.T) {
|
|||
err = GroupSnapRemove(ioctx, gname, "snap2b")
|
||||
assert.NoError(t, err, "remove of current name: expect success")
|
||||
})
|
||||
t.Run("groupSnappList", func(t *testing.T) {
|
||||
err := GroupSnapCreate(ioctx, gname, "snap1")
|
||||
assert.NoError(t, err)
|
||||
err = GroupSnapCreate(ioctx, gname, "snap2")
|
||||
assert.NoError(t, err)
|
||||
err = GroupSnapCreate(ioctx, gname, "snap3")
|
||||
assert.NoError(t, err)
|
||||
|
||||
gsl, err := GroupSnapList(ioctx, gname)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, gsl, 3) {
|
||||
names := []string{}
|
||||
for _, gsi := range gsl {
|
||||
assert.Equal(t, GroupSnapStateComplete, gsi.State)
|
||||
names = append(names, gsi.Name)
|
||||
}
|
||||
assert.Contains(t, names, "snap1")
|
||||
assert.Contains(t, names, "snap2")
|
||||
assert.Contains(t, names, "snap3")
|
||||
}
|
||||
|
||||
err = GroupSnapRemove(ioctx, gname, "snap3")
|
||||
assert.NoError(t, err)
|
||||
err = GroupSnapRemove(ioctx, gname, "snap2")
|
||||
assert.NoError(t, err)
|
||||
err = GroupSnapRename(ioctx, gname, "snap1", "snap1a")
|
||||
|
||||
gsl, err = GroupSnapList(ioctx, gname)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, gsl, 1) {
|
||||
assert.Equal(t, GroupSnapStateComplete, gsl[0].State)
|
||||
assert.Equal(t, "snap1a", gsl[0].Name)
|
||||
}
|
||||
|
||||
err = GroupSnapRemove(ioctx, gname, "snap1a")
|
||||
assert.NoError(t, err)
|
||||
|
||||
gsl, err = GroupSnapList(ioctx, gname)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, gsl, 0)
|
||||
})
|
||||
t.Run("invalidIOContext", func(t *testing.T) {
|
||||
assert.Panics(t, func() {
|
||||
GroupSnapCreate(nil, gname, "foo")
|
||||
|
@ -73,5 +114,8 @@ func TestGroupSnapshots(t *testing.T) {
|
|||
assert.Panics(t, func() {
|
||||
GroupSnapRename(nil, gname, "foo", "bar")
|
||||
})
|
||||
assert.Panics(t, func() {
|
||||
GroupSnapList(nil, gname)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue