rbd: add wrapper for rbd_snap_get_timestamp()

Added a wrapper for rbd_snap_get_timestamp() function.

Signed-off-by: Mudit Agarwal <muagarwa@redhat.com>
This commit is contained in:
Mudit Agarwal 2020-09-02 19:32:17 +05:30 committed by John Mulligan
parent 0e09cd4370
commit 2f0905b585
2 changed files with 103 additions and 0 deletions

View File

@ -7,6 +7,8 @@ import "C"
import (
"unsafe"
ts "github.com/ceph/go-ceph/internal/timespec"
)
// Snapshot represents a snapshot on a particular rbd image.
@ -160,3 +162,25 @@ func (snapshot *Snapshot) Set() error {
return getError(C.rbd_snap_set(snapshot.image.image, c_snapname))
}
// GetSnapTimestamp returns the timestamp of a snapshot for an image.
// For a non-existing snap ID, GetSnapTimestamp() may trigger an assertion
// and crash in the ceph library.
// Check https://tracker.ceph.com/issues/47287 for details.
//
// Implements:
// int rbd_snap_get_timestamp(rbd_image_t image, uint64_t snap_id, struct timespec *timestamp)
func (image *Image) GetSnapTimestamp(snapID uint64) (Timespec, error) {
if err := image.validate(imageIsOpen); err != nil {
return Timespec{}, err
}
var cts C.struct_timespec
ret := C.rbd_snap_get_timestamp(image.image, C.uint64_t(snapID), &cts)
if ret < 0 {
return Timespec{}, getError(ret)
}
return Timespec(ts.CStructToTimespec(ts.CTimespecPtr(&cts))), nil
}

View File

@ -105,3 +105,82 @@ func TestErrorSnapshotNoName(t *testing.T) {
conn.DeletePool(poolname)
conn.Shutdown()
}
func TestGetSnapTimestamp(t *testing.T) {
conn := radosConnect(t)
poolName := GetUUID()
err := conn.MakePool(poolName)
assert.NoError(t, err)
ioctx, err := conn.OpenIOContext(poolName)
assert.NoError(t, err)
defer func() {
ioctx.Destroy()
assert.NoError(t, conn.DeletePool(poolName))
conn.Shutdown()
}()
t.Run("ClosedImage", func(t *testing.T) {
imgName := "someImage"
img, err := Create(ioctx, imgName, testImageSize, testImageOrder, 1)
assert.NoError(t, err)
defer func() {
assert.NoError(t, img.Remove())
}()
var snapID uint64
snapID = 22
_, err = img.GetSnapTimestamp(snapID)
assert.Error(t, err)
assert.Equal(t, err, ErrImageNotOpen)
})
t.Run("invalidSnapID", func(t *testing.T) {
t.Skip("hits assert due to https://tracker.ceph.com/issues/47287")
imgName := "someImage"
img, err := Create(ioctx, imgName, testImageSize, testImageOrder, 1)
assert.NoError(t, err)
defer func() {
assert.NoError(t, img.Remove())
}()
img, err = OpenImage(ioctx, imgName, NoSnapshot)
assert.NoError(t, err)
defer func() {
assert.NoError(t, img.Close())
}()
var snapID uint64
snapID = 22
_, err = img.GetSnapTimestamp(snapID)
assert.Error(t, err)
})
t.Run("happyPath", func(t *testing.T) {
imgName := "someImage"
img, err := Create(ioctx, imgName, testImageSize, testImageOrder, 1)
assert.NoError(t, err)
defer func() {
assert.NoError(t, img.Remove())
}()
img, err = OpenImage(ioctx, imgName, NoSnapshot)
assert.NoError(t, err)
defer func() {
assert.NoError(t, img.Close())
}()
snapName := "mysnap"
snapshot, err := img.CreateSnapshot(snapName)
assert.NoError(t, err)
defer func() {
assert.NoError(t, snapshot.Remove())
}()
snapInfo, err := img.GetSnapshotNames()
assert.NoError(t, err)
assert.Equal(t, snapName, snapInfo[0].Name)
snapID := snapInfo[0].Id
_, err = img.GetSnapTimestamp(snapID)
assert.NoError(t, err)
})
}