mirror of https://github.com/ceph/go-ceph
rbd: add OpenImageById and OpenImageByIdReadOnly functions
Add OpenImageById and OpenImageByIdReadOnly that wrap rbd_open_by_id and rbd_open_by_id_read_only respectively. The added test case can not currently test trivial error conditions due to a known bug in ceph, these tests are skipped for meanwhile. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
a1f2aefcf9
commit
f72828c5b2
73
rbd/rbd.go
73
rbd/rbd.go
|
@ -1356,6 +1356,79 @@ func OpenImageReadOnly(ioctx *rados.IOContext, name, snapName string) (*Image, e
|
|||
}, nil
|
||||
}
|
||||
|
||||
// OpenImageById will open an existing rbd image by ID and snapshot name,
|
||||
// returning a new opened image. Pass the NoSnapshot sentinel value as the
|
||||
// snapName to explicitly indicate that no snapshot name is being provided.
|
||||
// Error handling will fail & segfault unless compiled with a version of ceph
|
||||
// that fixes https://tracker.ceph.com/issues/43178
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_open_by_id(rados_ioctx_t io, const char *id,
|
||||
// rbd_image_t *image, const char *snap_name);
|
||||
func OpenImageById(ioctx *rados.IOContext, id, snapName string) (*Image, error) {
|
||||
cid := C.CString(id)
|
||||
defer C.free(unsafe.Pointer(cid))
|
||||
|
||||
var cSnapName *C.char
|
||||
if snapName != NoSnapshot {
|
||||
cSnapName = C.CString(snapName)
|
||||
defer C.free(unsafe.Pointer(cSnapName))
|
||||
}
|
||||
|
||||
var cImage C.rbd_image_t
|
||||
ret := C.rbd_open_by_id(
|
||||
C.rados_ioctx_t(ioctx.Pointer()),
|
||||
cid,
|
||||
&cImage,
|
||||
cSnapName)
|
||||
|
||||
if ret != 0 {
|
||||
return nil, getError(ret)
|
||||
}
|
||||
|
||||
return &Image{
|
||||
ioctx: ioctx,
|
||||
image: cImage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// OpenImageByIdReadOnly will open an existing rbd image by ID and snapshot
|
||||
// name, returning a new opened-for-read image. Pass the NoSnapshot sentinel
|
||||
// value as the snapName to explicitly indicate that no snapshot name is being
|
||||
// provided.
|
||||
// Error handling will fail & segfault unless compiled with a version of ceph
|
||||
// that fixes https://tracker.ceph.com/issues/43178
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_open_by_id_read_only(rados_ioctx_t io, const char *id,
|
||||
// rbd_image_t *image, const char *snap_name);
|
||||
func OpenImageByIdReadOnly(ioctx *rados.IOContext, id, snapName string) (*Image, error) {
|
||||
cid := C.CString(id)
|
||||
defer C.free(unsafe.Pointer(cid))
|
||||
|
||||
var cSnapName *C.char
|
||||
if snapName != NoSnapshot {
|
||||
cSnapName = C.CString(snapName)
|
||||
defer C.free(unsafe.Pointer(cSnapName))
|
||||
}
|
||||
|
||||
var cImage C.rbd_image_t
|
||||
ret := C.rbd_open_by_id_read_only(
|
||||
C.rados_ioctx_t(ioctx.Pointer()),
|
||||
cid,
|
||||
&cImage,
|
||||
cSnapName)
|
||||
|
||||
if ret != 0 {
|
||||
return nil, getError(ret)
|
||||
}
|
||||
|
||||
return &Image{
|
||||
ioctx: ioctx,
|
||||
image: cImage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateImage creates a new rbd image using provided image options.
|
||||
//
|
||||
// Implements:
|
||||
|
|
|
@ -1463,3 +1463,101 @@ func TestGetId(t *testing.T) {
|
|||
conn.DeletePool(poolname)
|
||||
conn.Shutdown()
|
||||
}
|
||||
|
||||
func TestOpenImageById(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)
|
||||
|
||||
name := GetUUID()
|
||||
options := NewRbdImageOptions()
|
||||
assert.NoError(t,
|
||||
options.SetUint64(RbdImageOptionOrder, uint64(testImageOrder)))
|
||||
err = CreateImage(ioctx, name, testImageSize, options)
|
||||
assert.NoError(t, err)
|
||||
|
||||
workingImage, err := OpenImage(ioctx, name, NoSnapshot)
|
||||
assert.NoError(t, err)
|
||||
id, err := workingImage.GetId()
|
||||
assert.NoError(t, err)
|
||||
err = workingImage.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
t.Run("ReadWriteBadId", func(t *testing.T) {
|
||||
t.Skip("segfaults due to https://tracker.ceph.com/issues/43178")
|
||||
// phony id
|
||||
img, err := OpenImageById(ioctx, "102f00aaabbbccd", NoSnapshot)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, img)
|
||||
})
|
||||
t.Run("ReadOnlyBadId", func(t *testing.T) {
|
||||
t.Skip("segfaults due to https://tracker.ceph.com/issues/43178")
|
||||
// phony id
|
||||
img, err := OpenImageByIdReadOnly(ioctx, "blubb", NoSnapshot)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, img)
|
||||
})
|
||||
t.Run("ReadWrite", func(t *testing.T) {
|
||||
img, err := OpenImageById(ioctx, id, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, img)
|
||||
defer func() { assert.NoError(t, img.Close()) }()
|
||||
|
||||
data := []byte("input data")
|
||||
_, err = img.Write(data)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("ReadOnly", func(t *testing.T) {
|
||||
img, err := OpenImageByIdReadOnly(ioctx, id, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, img)
|
||||
defer func() { assert.NoError(t, img.Close()) }()
|
||||
|
||||
data := []byte("input data")
|
||||
_, err = img.Write(data)
|
||||
// writing should fail in read-only mode
|
||||
assert.Error(t, err)
|
||||
})
|
||||
t.Run("Snapshot", func(t *testing.T) {
|
||||
img, err := OpenImageById(ioctx, id, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, img)
|
||||
defer func() { assert.NoError(t, img.Close()) }()
|
||||
|
||||
snapshot, err := img.CreateSnapshot("snerpshort")
|
||||
assert.NoError(t, err)
|
||||
defer func() { assert.NoError(t, snapshot.Remove()) }()
|
||||
|
||||
snapImage, err := OpenImageById(ioctx, id, "snerpshort")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, snapImage)
|
||||
assert.NoError(t, snapImage.Close())
|
||||
})
|
||||
t.Run("ReadOnlySnapshot", func(t *testing.T) {
|
||||
img, err := OpenImageById(ioctx, id, NoSnapshot)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, img)
|
||||
defer func() { assert.NoError(t, img.Close()) }()
|
||||
|
||||
snapshot, err := img.CreateSnapshot("snerpshort2")
|
||||
assert.NoError(t, err)
|
||||
defer func() { assert.NoError(t, snapshot.Remove()) }()
|
||||
|
||||
snapImage, err := OpenImageByIdReadOnly(ioctx, id, "snerpshort2")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, snapImage)
|
||||
assert.NoError(t, snapImage.Close())
|
||||
})
|
||||
|
||||
err = workingImage.Remove()
|
||||
assert.NoError(t, err)
|
||||
|
||||
ioctx.Destroy()
|
||||
conn.DeletePool(poolname)
|
||||
conn.Shutdown()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue