rbd: add a new version of GetParentInfo()

GetParentInfo() currently requires the caller to specify the
string length for various attributes it returns. If the
specified string length is less than required, it can return
ERANGE error. Replacing it with a new function which avoids
this.

Signed-off-by: Mudit Agarwal <muagarwa@redhat.com>
This commit is contained in:
Mudit Agarwal 2020-08-26 12:51:23 +05:30 committed by John Mulligan
parent c362706640
commit 34cab3407f
2 changed files with 131 additions and 0 deletions

View File

@ -123,3 +123,80 @@ func TestSparsify(t *testing.T) {
assert.Error(t, err)
})
}
func TestGetParent(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()
}()
imgName := "parent"
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())
}()
t.Run("ParentNotAvailable", func(t *testing.T) {
_, err := img.GetParent()
assert.Error(t, err)
assert.Equal(t, err, ErrNotFound)
})
t.Run("ParentAvailable", func(t *testing.T) {
cloneName := "child"
optionsClone := NewRbdImageOptions()
defer optionsClone.Destroy()
err := optionsClone.SetUint64(ImageOptionCloneFormat, 2)
assert.NoError(t, err)
// Create a clone of the image using the snapshot.
err = CloneImage(ioctx, imgName, snapName, ioctx, cloneName, optionsClone)
assert.NoError(t, err)
defer func() { assert.NoError(t, RemoveImage(ioctx, cloneName)) }()
imgNew, err := OpenImage(ioctx, cloneName, NoSnapshot)
defer func() {
assert.NoError(t, imgNew.Close())
}()
assert.NoError(t, err)
parentInfo, err := imgNew.GetParent()
assert.NoError(t, err)
assert.Equal(t, parentInfo.Image.ImageName, imgName)
assert.Equal(t, parentInfo.Snap.SnapName, snapName)
assert.Equal(t, parentInfo.Image.PoolName, poolName)
// TODO: add a comaprison for snap ID
})
t.Run("ClosedImage", func(t *testing.T) {
closedImg, err := Create(ioctx, "someImage", testImageSize, testImageOrder, 1)
assert.NoError(t, err)
defer func() {
assert.NoError(t, closedImg.Remove())
}()
_, err = closedImg.GetParent()
assert.Error(t, err)
})
}

View File

@ -65,6 +65,60 @@ func (image *Image) GetParentInfo(pool, name, snapname []byte) error {
return nil
}
// ImageSpec represents the image information.
type ImageSpec struct {
ImageName string
PoolName string
}
// SnapSpec represents the snapshot infomation.
type SnapSpec struct {
ID uint64
SnapName string
}
// ParentInfo represents the parent image and the parent snapshot information.
type ParentInfo struct {
Image ImageSpec
Snap SnapSpec
}
// GetParent looks for the parent of the image and returns the parent image
// information which includes the image name, the pool name and
// the snapshot information.
//
// Implements:
// int rbd_get_parent(rbd_image_t image, rbd_linked_image_spec_t *parent_image, rbd_snap_spec_t *parent_snap)
func (image *Image) GetParent() (*ParentInfo, error) {
if err := image.validate(imageIsOpen); err != nil {
return nil, err
}
parentImage := C.rbd_linked_image_spec_t{}
parentSnap := C.rbd_snap_spec_t{}
ret := C.rbd_get_parent(image.image, &parentImage, &parentSnap)
if ret != 0 {
return nil, getError(ret)
}
defer C.rbd_linked_image_spec_cleanup(&parentImage)
defer C.rbd_snap_spec_cleanup(&parentSnap)
imageSpec := ImageSpec{
ImageName: C.GoString(parentImage.image_name),
PoolName: C.GoString(parentImage.pool_name),
}
snapSpec := SnapSpec{
ID: uint64(parentSnap.id),
SnapName: C.GoString(parentSnap.name),
}
return &ParentInfo{
Image: imageSpec,
Snap: snapSpec,
}, nil
}
// ListChildren returns arrays with the pools and names of the images that are
// children of the given image. The index of the pools and images arrays can be
// used to link the two items together.