mirror of https://github.com/ceph/go-ceph
rbd: add new more idomatic functions for opening rbd images
Create new OpenImage & OpenImageReadOnly functions to replace the use of Open() on image types. This function more closely matches the underlying of the librbd function calls. The third argument to the functions is a snapshot name but we also create a new constant to clearly indicate that an image should be opened w/o a snapshot. Internally, this also ensures that a null string is passed to the C api. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
09813739ed
commit
20a458a614
74
rbd/rbd.go
74
rbd/rbd.go
|
@ -61,6 +61,9 @@ const (
|
|||
imageNeedsIOContext
|
||||
imageIsOpen
|
||||
snapshotNeedsName
|
||||
|
||||
// NoSnapshot indicates that no snapshot name is in use (see OpenImage)
|
||||
NoSnapshot = ""
|
||||
)
|
||||
|
||||
//
|
||||
|
@ -1286,3 +1289,74 @@ func TrashRestore(ioctx *rados.IOContext, id, name string) error {
|
|||
|
||||
return GetError(C.rbd_trash_restore(C.rados_ioctx_t(ioctx.Pointer()), c_id, c_name))
|
||||
}
|
||||
|
||||
// OpenImage will open an existing rbd image by name 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.
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_open(rados_ioctx_t io, const char *name,
|
||||
// rbd_image_t *image, const char *snap_name);
|
||||
func OpenImage(ioctx *rados.IOContext, name, snapName string) (*Image, error) {
|
||||
cName := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
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(
|
||||
C.rados_ioctx_t(ioctx.Pointer()),
|
||||
cName,
|
||||
&cImage,
|
||||
cSnapName)
|
||||
|
||||
if ret != 0 {
|
||||
return nil, GetError(ret)
|
||||
}
|
||||
|
||||
return &Image{
|
||||
ioctx: ioctx,
|
||||
name: name,
|
||||
image: cImage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// OpenImageReadOnly will open an existing rbd image by name 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.
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_open_read_only(rados_ioctx_t io, const char *name,
|
||||
// rbd_image_t *image, const char *snap_name);
|
||||
func OpenImageReadOnly(ioctx *rados.IOContext, name, snapName string) (*Image, error) {
|
||||
cName := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
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_read_only(
|
||||
C.rados_ioctx_t(ioctx.Pointer()),
|
||||
cName,
|
||||
&cImage,
|
||||
cSnapName)
|
||||
|
||||
if ret != 0 {
|
||||
return nil, GetError(ret)
|
||||
}
|
||||
|
||||
return &Image{
|
||||
ioctx: ioctx,
|
||||
name: name,
|
||||
image: cImage,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -1259,3 +1259,50 @@ func TestClosedImage(t *testing.T) {
|
|||
conn.DeletePool(poolname)
|
||||
conn.Shutdown()
|
||||
}
|
||||
|
||||
func TestOpenImage(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()
|
||||
|
||||
_, err = OpenImage(ioctx, name, NoSnapshot)
|
||||
assert.Error(t, err)
|
||||
|
||||
image, err := Create(ioctx, name, 1<<22, 22)
|
||||
assert.NoError(t, err)
|
||||
|
||||
oImage, err := OpenImage(ioctx, name, NoSnapshot)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, name, oImage.name)
|
||||
err = oImage.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// open read-only
|
||||
oImage, err = OpenImageReadOnly(ioctx, name, NoSnapshot)
|
||||
assert.NoError(t, err)
|
||||
|
||||
bytes_in := []byte("input data")
|
||||
_, err = image.Write(bytes_in)
|
||||
// writing should fail in read-only mode
|
||||
assert.Error(t, err)
|
||||
|
||||
err = oImage.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = oImage.Remove()
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = OpenImageReadOnly(ioctx, name, NoSnapshot)
|
||||
assert.Error(t, err)
|
||||
|
||||
ioctx.Destroy()
|
||||
conn.DeletePool(poolname)
|
||||
conn.Shutdown()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue