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))
|
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.
|
// Flatten removes snapshot references from the image.
|
||||||
//
|
//
|
||||||
// Implements:
|
// Implements:
|
||||||
|
|
|
@ -958,6 +958,87 @@ func TestImageCopy(t *testing.T) {
|
||||||
conn.Shutdown()
|
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) {
|
func TestParentInfo(t *testing.T) {
|
||||||
conn := radosConnect(t)
|
conn := radosConnect(t)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue