mirror of https://github.com/ceph/go-ceph
rbd: add DeepCopy()
With rbd_deep_copy() an image can be copied with selected options. This can be used to create a copy and flatten the image in one go. Updates: ceph/ceph-csi#2077 Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
parent
e0e56486b0
commit
92b808cbbe
27
rbd/rbd.go
27
rbd/rbd.go
|
@ -531,6 +531,33 @@ func (image *Image) Copy2(dest *Image) error {
|
|||
return getError(C.rbd_copy2(image.image, dest.image))
|
||||
}
|
||||
|
||||
// DeepCopy an rbd image to a new image with specific options.
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_deep_copy(rbd_image_t src, rados_ioctx_t dest_io_ctx,
|
||||
// const char *destname, rbd_image_options_t dest_opts);
|
||||
func (image *Image) DeepCopy(ioctx *rados.IOContext, destname string, rio *ImageOptions) error {
|
||||
if err := image.validate(imageIsOpen); err != nil {
|
||||
return err
|
||||
}
|
||||
if ioctx == nil {
|
||||
return ErrNoIOContext
|
||||
}
|
||||
if destname == "" {
|
||||
return ErrNoName
|
||||
}
|
||||
if rio == nil {
|
||||
return rbdError(C.EINVAL)
|
||||
}
|
||||
|
||||
cDestname := C.CString(destname)
|
||||
defer C.free(unsafe.Pointer(cDestname))
|
||||
|
||||
ret := C.rbd_deep_copy(image.image, cephIoctx(ioctx), cDestname,
|
||||
C.rbd_image_options_t(rio.options))
|
||||
return getError(ret)
|
||||
}
|
||||
|
||||
// Flatten removes snapshot references from the image.
|
||||
//
|
||||
// Implements:
|
||||
|
|
|
@ -958,6 +958,87 @@ func TestImageCopy(t *testing.T) {
|
|||
conn.Shutdown()
|
||||
}
|
||||
|
||||
func TestImageDeepCopy(t *testing.T) {
|
||||
conn := radosConnect(t)
|
||||
|
||||
poolname := GetUUID()
|
||||
err := conn.MakePool(poolname)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ioctx, err := conn.OpenIOContext(poolname)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("invalidParameters", func(t *testing.T) {
|
||||
name := GetUUID()
|
||||
options := NewRbdImageOptions()
|
||||
defer options.Destroy()
|
||||
err = options.SetUint64(ImageOptionOrder, uint64(testImageOrder))
|
||||
assert.NoError(t, err)
|
||||
err = CreateImage(ioctx, name, testImageSize, options)
|
||||
require.NoError(t, err)
|
||||
|
||||
// img not open, should fail
|
||||
img := GetImage(ioctx, name)
|
||||
err = img.DeepCopy(nil, "", nil)
|
||||
assert.Equal(t, err, ErrImageNotOpen)
|
||||
|
||||
img, err := OpenImage(ioctx, name, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
|
||||
// pass invalid parameters
|
||||
err = img.DeepCopy(nil, "", nil)
|
||||
assert.Error(t, err) // order of errors not enforced
|
||||
|
||||
err = img.DeepCopy(ioctx, "", options)
|
||||
assert.Equal(t, err, ErrNoName)
|
||||
|
||||
err = img.DeepCopy(nil, "duplicate", options)
|
||||
assert.Equal(t, err, ErrNoIOContext)
|
||||
|
||||
err = img.DeepCopy(ioctx, "copied", nil)
|
||||
assert.Error(t, err) // rbdError(C.EINVAL), but can not use C in tests
|
||||
|
||||
err = img.Close()
|
||||
assert.NoError(t, err)
|
||||
err = RemoveImage(ioctx, name)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
// try successful copying
|
||||
t.Run("successfulDeepCopy", func(t *testing.T) {
|
||||
name := GetUUID()
|
||||
options := NewRbdImageOptions()
|
||||
defer options.Destroy()
|
||||
err = options.SetUint64(ImageOptionOrder, uint64(testImageOrder))
|
||||
assert.NoError(t, err)
|
||||
err = CreateImage(ioctx, name, testImageSize, options)
|
||||
require.NoError(t, err)
|
||||
|
||||
img, err := OpenImage(ioctx, name, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
|
||||
name2 := GetUUID()
|
||||
err = img.DeepCopy(ioctx, name2, options)
|
||||
require.NoError(t, err)
|
||||
|
||||
img2, err := OpenImage(ioctx, name2, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = img2.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = img2.Remove()
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = img.Close()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
ioctx.Destroy()
|
||||
conn.DeletePool(poolname)
|
||||
conn.Shutdown()
|
||||
}
|
||||
|
||||
func TestParentInfo(t *testing.T) {
|
||||
conn := radosConnect(t)
|
||||
|
||||
|
|
Loading…
Reference in New Issue