rbd: add functions and constants related to snapshot namespace.

Added few constants used for determining snapshot namespace.
Added wrapper for function rbd_snap_get_namespace_type() which returns namespace type for a given snapshot.

Signed-off-by: Mudit Agarwal <muagarwa@redhat.com>
This commit is contained in:
Mudit Agarwal 2020-06-24 19:46:18 +05:30 committed by John Mulligan
parent 7dea1f728f
commit a5da5e308b
2 changed files with 153 additions and 0 deletions

42
rbd/snapshot_namespace.go Normal file
View File

@ -0,0 +1,42 @@
// +build !luminous
//
// Ceph Mimic introduced rbd_snap_get_namespace_type().
package rbd
// #cgo LDFLAGS: -lrbd
// #include <rbd/librbd.h>
import "C"
// SnapNamespaceType indicates the namespace to which the snapshot belongs to.
type SnapNamespaceType C.rbd_snap_namespace_type_t
const (
// SnapNamespaceTypeUser indicates that the snapshot belongs to user namespace.
SnapNamespaceTypeUser = SnapNamespaceType(C.RBD_SNAP_NAMESPACE_TYPE_USER)
// SnapNamespaceTypeGroup indicates that the snapshot belongs to group namespace.
// Such snapshots will have associated group information.
SnapNamespaceTypeGroup = SnapNamespaceType(C.RBD_SNAP_NAMESPACE_TYPE_GROUP)
// SnapNamespaceTypeTrash indicates that the snapshot belongs to trash namespace.
SnapNamespaceTypeTrash = SnapNamespaceType(C.RBD_SNAP_NAMESPACE_TYPE_TRASH)
)
// GetSnapNamespaceType gets the type of namespace to which the snapshot belongs to,
// returns error on failure.
//
// Implements:
// int rbd_snap_get_namespace_type(rbd_image_t image, uint64_t snap_id, rbd_snap_namespace_type_t *namespace_type)
func (image *Image) GetSnapNamespaceType(snapID uint64) (SnapNamespaceType, error) {
var nsType SnapNamespaceType
if err := image.validate(imageIsOpen); err != nil {
return nsType, err
}
ret := C.rbd_snap_get_namespace_type(image.image,
C.uint64_t(snapID),
(*C.rbd_snap_namespace_type_t)(&nsType))
return nsType, getError(ret)
}

View File

@ -0,0 +1,111 @@
// +build !luminous
package rbd
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetSnapNamespaceType(t *testing.T) {
conn := radosConnect(t)
defer conn.Shutdown()
poolname := GetUUID()
err := conn.MakePool(poolname)
require.NoError(t, err)
defer conn.DeletePool(poolname)
ioctx, err := conn.OpenIOContext(poolname)
require.NoError(t, err)
defer ioctx.Destroy()
imageName := "parent"
snapName := "mySnap"
options := NewRbdImageOptions()
defer options.Destroy()
err = options.SetUint64(ImageOptionOrder, uint64(testImageOrder))
assert.NoError(t, err)
err = options.SetUint64(ImageOptionFeatures, 1)
assert.NoError(t, err)
err = CreateImage(ioctx, imageName, testImageSize, options)
assert.NoError(t, err)
img, err := OpenImage(ioctx, imageName, NoSnapshot)
assert.NoError(t, err)
defer func() {
assert.NoError(t, img.Close())
assert.NoError(t, img.Remove())
}()
snapshot, err := img.CreateSnapshot(snapName)
assert.NoError(t, err)
snapInfoList, err := img.GetSnapshotNames()
assert.NoError(t, err)
snapInfo := snapInfoList[0]
assert.Equal(t, snapInfo.Name, snapName)
t.Run("SnapNamespaceTypeInvalidArgs", func(t *testing.T) {
validImageName := GetUUID()
validImg, err := Create(ioctx, validImageName, testImageSize, testImageOrder, 1)
assert.NoError(t, err)
defer func() {
assert.NoError(t, validImg.Remove())
}()
validImg = GetImage(ioctx, validImageName)
// Closed image and a snapshot ID which doesn't belong to this image.
_, err = validImg.GetSnapNamespaceType(snapInfo.Id)
assert.Error(t, err)
// Open image but invalid snap ID.
validImg, err = OpenImage(ioctx, validImageName, NoSnapshot)
assert.NoError(t, err)
defer func() {
assert.NoError(t, validImg.Close())
}()
_, err = validImg.GetSnapNamespaceType(uint64(22))
assert.Error(t, err)
// With non-existing image.
invalidImageName := GetUUID()
invalidImg := GetImage(ioctx, invalidImageName)
_, err = invalidImg.GetSnapNamespaceType(snapInfo.Id)
assert.Error(t, err)
})
t.Run("SnapNamespaceTypeUser", func(t *testing.T) {
nsType, err := img.GetSnapNamespaceType(snapInfo.Id)
assert.NoError(t, err)
assert.Equal(t, nsType, SnapNamespaceTypeUser)
})
t.Run("SnapNamespaceTypeTrash", func(t *testing.T) {
cloneName := "myClone"
optionsClone := NewRbdImageOptions()
defer optionsClone.Destroy()
err := optionsClone.SetUint64(ImageOptionCloneFormat, 2)
assert.NoError(t, err)
// Create a clone of the image using the same snapshot.
err = CloneImage(ioctx, imageName, snapName, ioctx, cloneName, optionsClone)
assert.NoError(t, err)
defer func() { assert.NoError(t, RemoveImage(ioctx, cloneName)) }()
// Once clone is created, remove the snapshot.
err = snapshot.Remove()
assert.NoError(t, err)
// Snapshot would move to the trash because linked clone is still there.
nsType, err := img.GetSnapNamespaceType(snapInfo.Id)
assert.NoError(t, err)
assert.Equal(t, nsType, SnapNamespaceTypeTrash)
})
}