mirror of
https://github.com/ceph/go-ceph
synced 2024-12-18 20:35:33 +00:00
6c944e8b65
In order to avoid external dependencies on implementation details, this change replaces RBDError with the unexported rbdError. In case some application really needs access to the integer value, it can use the pattern var errno interface{ Errno() int } if errors.As(err, errno) { ... errno.Errno() ... } Signed-off-by: Sven Anderson <sven@redhat.com>
107 lines
2.9 KiB
Go
107 lines
2.9 KiB
Go
// +build !luminous,!mimic
|
|
//
|
|
// Ceph Nautilus introduced rbd_get_parent() and deprecated rbd_get_parent_info().
|
|
// Ceph Nautilus introduced rbd_list_children3() and deprecated rbd_list_children().
|
|
|
|
package rbd
|
|
|
|
// #cgo LDFLAGS: -lrbd
|
|
// #include <rbd/librbd.h>
|
|
// #include <errno.h>
|
|
import "C"
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"github.com/ceph/go-ceph/internal/retry"
|
|
)
|
|
|
|
// GetParentInfo looks for the parent of the image and stores the pool, name
|
|
// and snapshot-name in the byte-arrays that are passed as arguments.
|
|
//
|
|
// Implements:
|
|
// int rbd_get_parent(rbd_image_t image,
|
|
// rbd_linked_image_spec_t *parent_image,
|
|
// rbd_snap_spec_t *parent_snap)
|
|
func (image *Image) GetParentInfo(pool, name, snapname []byte) error {
|
|
if err := image.validate(imageIsOpen); err != nil {
|
|
return err
|
|
}
|
|
|
|
parentImage := C.rbd_linked_image_spec_t{}
|
|
parentSnap := C.rbd_snap_spec_t{}
|
|
ret := C.rbd_get_parent(image.image, &parentImage, &parentSnap)
|
|
if ret != 0 {
|
|
return rbdError(ret)
|
|
}
|
|
|
|
defer C.rbd_linked_image_spec_cleanup(&parentImage)
|
|
defer C.rbd_snap_spec_cleanup(&parentSnap)
|
|
|
|
strlen := int(C.strlen(parentImage.pool_name))
|
|
if len(pool) < strlen {
|
|
return rbdError(C.ERANGE)
|
|
}
|
|
if copy(pool, C.GoString(parentImage.pool_name)) != strlen {
|
|
return rbdError(C.ERANGE)
|
|
}
|
|
|
|
strlen = int(C.strlen(parentImage.image_name))
|
|
if len(name) < strlen {
|
|
return rbdError(C.ERANGE)
|
|
}
|
|
if copy(name, C.GoString(parentImage.image_name)) != strlen {
|
|
return rbdError(C.ERANGE)
|
|
}
|
|
|
|
strlen = int(C.strlen(parentSnap.name))
|
|
if len(snapname) < strlen {
|
|
return rbdError(C.ERANGE)
|
|
}
|
|
if copy(snapname, C.GoString(parentSnap.name)) != strlen {
|
|
return rbdError(C.ERANGE)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ListChildren returns arrays with the pools and names of the images that are
|
|
// children of the given image. The index of the pools and images arrays can be
|
|
// used to link the two items together.
|
|
//
|
|
// Implements:
|
|
// int rbd_list_children3(rbd_image_t image, rbd_linked_image_spec_t *images,
|
|
// size_t *max_images);
|
|
func (image *Image) ListChildren() (pools []string, images []string, err error) {
|
|
if err := image.validate(imageIsOpen); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var (
|
|
csize C.size_t
|
|
children []C.rbd_linked_image_spec_t
|
|
)
|
|
retry.WithSizes(16, 4096, func(size int) retry.Hint {
|
|
csize = C.size_t(size)
|
|
children = make([]C.rbd_linked_image_spec_t, csize)
|
|
ret := C.rbd_list_children3(
|
|
image.image,
|
|
(*C.rbd_linked_image_spec_t)(unsafe.Pointer(&children[0])),
|
|
&csize)
|
|
err = getErrorIfNegative(ret)
|
|
return retry.Size(int(csize)).If(err == errRange)
|
|
})
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
defer C.rbd_linked_image_spec_list_cleanup((*C.rbd_linked_image_spec_t)(unsafe.Pointer(&children[0])), csize)
|
|
|
|
pools = make([]string, csize)
|
|
images = make([]string, csize)
|
|
for i, child := range children[:csize] {
|
|
pools[i] = C.GoString(child.pool_name)
|
|
images[i] = C.GoString(child.image_name)
|
|
}
|
|
return pools, images, nil
|
|
}
|