mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-27 00:30:18 +00:00
259 lines
7.3 KiB
Go
259 lines
7.3 KiB
Go
|
package rbd
|
||
|
|
||
|
/*
|
||
|
#cgo LDFLAGS: -lrbd
|
||
|
#include <stdlib.h>
|
||
|
#include <rbd/librbd.h>
|
||
|
*/
|
||
|
import "C"
|
||
|
|
||
|
import (
|
||
|
"unsafe"
|
||
|
|
||
|
"github.com/ceph/go-ceph/internal/cutil"
|
||
|
"github.com/ceph/go-ceph/internal/retry"
|
||
|
"github.com/ceph/go-ceph/rados"
|
||
|
)
|
||
|
|
||
|
// GroupCreate is used to create an image group.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_create(rados_ioctx_t p, const char *name);
|
||
|
func GroupCreate(ioctx *rados.IOContext, name string) error {
|
||
|
cName := C.CString(name)
|
||
|
defer C.free(unsafe.Pointer(cName))
|
||
|
|
||
|
ret := C.rbd_group_create(cephIoctx(ioctx), cName)
|
||
|
return getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupRemove is used to remove an image group.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_remove(rados_ioctx_t p, const char *name);
|
||
|
func GroupRemove(ioctx *rados.IOContext, name string) error {
|
||
|
cName := C.CString(name)
|
||
|
defer C.free(unsafe.Pointer(cName))
|
||
|
|
||
|
ret := C.rbd_group_remove(cephIoctx(ioctx), cName)
|
||
|
return getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupRename will rename an existing image group.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_rename(rados_ioctx_t p, const char *src_name,
|
||
|
// const char *dest_name);
|
||
|
func GroupRename(ioctx *rados.IOContext, src, dest string) error {
|
||
|
cSrc := C.CString(src)
|
||
|
defer C.free(unsafe.Pointer(cSrc))
|
||
|
cDest := C.CString(dest)
|
||
|
defer C.free(unsafe.Pointer(cDest))
|
||
|
|
||
|
ret := C.rbd_group_rename(cephIoctx(ioctx), cSrc, cDest)
|
||
|
return getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupList returns a slice of image group names.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_list(rados_ioctx_t p, char *names, size_t *size);
|
||
|
func GroupList(ioctx *rados.IOContext) ([]string, error) {
|
||
|
var (
|
||
|
buf []byte
|
||
|
err error
|
||
|
ret C.int
|
||
|
)
|
||
|
retry.WithSizes(1024, 262144, func(size int) retry.Hint {
|
||
|
cSize := C.size_t(size)
|
||
|
buf = make([]byte, cSize)
|
||
|
ret = C.rbd_group_list(
|
||
|
cephIoctx(ioctx),
|
||
|
(*C.char)(unsafe.Pointer(&buf[0])),
|
||
|
&cSize)
|
||
|
err = getErrorIfNegative(ret)
|
||
|
return retry.Size(int(cSize)).If(err == errRange)
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// cSize is not set to the expected size when it is sufficiently large
|
||
|
// but ret will be set to the size in a non-error condition.
|
||
|
groups := cutil.SplitBuffer(buf[:ret])
|
||
|
return groups, nil
|
||
|
}
|
||
|
|
||
|
// GroupImageAdd will add the specified image to the named group.
|
||
|
// An io context must be supplied for both the group and image.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_image_add(rados_ioctx_t group_p,
|
||
|
// const char *group_name,
|
||
|
// rados_ioctx_t image_p,
|
||
|
// const char *image_name);
|
||
|
func GroupImageAdd(groupIoctx *rados.IOContext, groupName string,
|
||
|
imageIoctx *rados.IOContext, imageName string) error {
|
||
|
|
||
|
cGroupName := C.CString(groupName)
|
||
|
defer C.free(unsafe.Pointer(cGroupName))
|
||
|
cImageName := C.CString(imageName)
|
||
|
defer C.free(unsafe.Pointer(cImageName))
|
||
|
|
||
|
ret := C.rbd_group_image_add(
|
||
|
cephIoctx(groupIoctx),
|
||
|
cGroupName,
|
||
|
cephIoctx(imageIoctx),
|
||
|
cImageName)
|
||
|
return getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupImageRemove will remove the specified image from the named group.
|
||
|
// An io context must be supplied for both the group and image.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_image_remove(rados_ioctx_t group_p,
|
||
|
// const char *group_name,
|
||
|
// rados_ioctx_t image_p,
|
||
|
// const char *image_name);
|
||
|
func GroupImageRemove(groupIoctx *rados.IOContext, groupName string,
|
||
|
imageIoctx *rados.IOContext, imageName string) error {
|
||
|
|
||
|
cGroupName := C.CString(groupName)
|
||
|
defer C.free(unsafe.Pointer(cGroupName))
|
||
|
cImageName := C.CString(imageName)
|
||
|
defer C.free(unsafe.Pointer(cImageName))
|
||
|
|
||
|
ret := C.rbd_group_image_remove(
|
||
|
cephIoctx(groupIoctx),
|
||
|
cGroupName,
|
||
|
cephIoctx(imageIoctx),
|
||
|
cImageName)
|
||
|
return getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupImageRemoveByID will remove the specified image from the named group.
|
||
|
// An io context must be supplied for both the group and image.
|
||
|
//
|
||
|
// Implements:
|
||
|
// CEPH_RBD_API int rbd_group_image_remove_by_id(rados_ioctx_t group_p,
|
||
|
// const char *group_name,
|
||
|
// rados_ioctx_t image_p,
|
||
|
// const char *image_id);
|
||
|
func GroupImageRemoveByID(groupIoctx *rados.IOContext, groupName string,
|
||
|
imageIoctx *rados.IOContext, imageID string) error {
|
||
|
|
||
|
cGroupName := C.CString(groupName)
|
||
|
defer C.free(unsafe.Pointer(cGroupName))
|
||
|
cid := C.CString(imageID)
|
||
|
defer C.free(unsafe.Pointer(cid))
|
||
|
|
||
|
ret := C.rbd_group_image_remove_by_id(
|
||
|
cephIoctx(groupIoctx),
|
||
|
cGroupName,
|
||
|
cephIoctx(imageIoctx),
|
||
|
cid)
|
||
|
return getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupImageState indicates an image's state in a group.
|
||
|
type GroupImageState int
|
||
|
|
||
|
const (
|
||
|
// GroupImageStateAttached is equivalent to RBD_GROUP_IMAGE_STATE_ATTACHED
|
||
|
GroupImageStateAttached = GroupImageState(C.RBD_GROUP_IMAGE_STATE_ATTACHED)
|
||
|
// GroupImageStateIncomplete is equivalent to RBD_GROUP_IMAGE_STATE_INCOMPLETE
|
||
|
GroupImageStateIncomplete = GroupImageState(C.RBD_GROUP_IMAGE_STATE_INCOMPLETE)
|
||
|
)
|
||
|
|
||
|
// GroupImageInfo reports on images within a group.
|
||
|
type GroupImageInfo struct {
|
||
|
Name string
|
||
|
PoolID int64
|
||
|
State GroupImageState
|
||
|
}
|
||
|
|
||
|
// GroupImageList returns a slice of GroupImageInfo types based on the
|
||
|
// images that are part of the named group.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_group_image_list(rados_ioctx_t group_p,
|
||
|
// const char *group_name,
|
||
|
// rbd_group_image_info_t *images,
|
||
|
// size_t group_image_info_size,
|
||
|
// size_t *num_entries);
|
||
|
func GroupImageList(ioctx *rados.IOContext, name string) ([]GroupImageInfo, error) {
|
||
|
cName := C.CString(name)
|
||
|
defer C.free(unsafe.Pointer(cName))
|
||
|
|
||
|
var (
|
||
|
cImages []C.rbd_group_image_info_t
|
||
|
cSize C.size_t
|
||
|
err error
|
||
|
)
|
||
|
retry.WithSizes(1024, 262144, func(size int) retry.Hint {
|
||
|
cSize = C.size_t(size)
|
||
|
cImages = make([]C.rbd_group_image_info_t, cSize)
|
||
|
ret := C.rbd_group_image_list(
|
||
|
cephIoctx(ioctx),
|
||
|
cName,
|
||
|
(*C.rbd_group_image_info_t)(unsafe.Pointer(&cImages[0])),
|
||
|
C.sizeof_rbd_group_image_info_t,
|
||
|
&cSize)
|
||
|
err = getErrorIfNegative(ret)
|
||
|
return retry.Size(int(cSize)).If(err == errRange)
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
images := make([]GroupImageInfo, cSize)
|
||
|
for i := range images {
|
||
|
images[i].Name = C.GoString(cImages[i].name)
|
||
|
images[i].PoolID = int64(cImages[i].pool)
|
||
|
images[i].State = GroupImageState(cImages[i].state)
|
||
|
}
|
||
|
|
||
|
// free C memory allocated by C.rbd_group_image_list call
|
||
|
ret := C.rbd_group_image_list_cleanup(
|
||
|
(*C.rbd_group_image_info_t)(unsafe.Pointer(&cImages[0])),
|
||
|
C.sizeof_rbd_group_image_info_t,
|
||
|
cSize)
|
||
|
return images, getError(ret)
|
||
|
}
|
||
|
|
||
|
// GroupInfo contains the name and pool id of a RBD group.
|
||
|
type GroupInfo struct {
|
||
|
Name string
|
||
|
PoolID int64
|
||
|
}
|
||
|
|
||
|
// GetGroup returns group info for the group this image is part of.
|
||
|
//
|
||
|
// Implements:
|
||
|
// int rbd_get_group(rbd_image_t image, rbd_group_info_t *group_info,
|
||
|
// size_t group_info_size);
|
||
|
func (image *Image) GetGroup() (GroupInfo, error) {
|
||
|
if err := image.validate(imageIsOpen); err != nil {
|
||
|
return GroupInfo{}, err
|
||
|
}
|
||
|
|
||
|
var cgi C.rbd_group_info_t
|
||
|
ret := C.rbd_get_group(
|
||
|
image.image,
|
||
|
&cgi,
|
||
|
C.sizeof_rbd_group_info_t)
|
||
|
if err := getErrorIfNegative(ret); err != nil {
|
||
|
return GroupInfo{}, err
|
||
|
}
|
||
|
|
||
|
gi := GroupInfo{
|
||
|
Name: C.GoString(cgi.name),
|
||
|
PoolID: int64(cgi.pool),
|
||
|
}
|
||
|
ret = C.rbd_group_info_cleanup(&cgi, C.sizeof_rbd_group_info_t)
|
||
|
return gi, getError(ret)
|
||
|
}
|