go-ceph/rbd/locks.go
John Mulligan 70ddb1dbea rbd: promote lock apis to stable
Signed-off-by: John Mulligan <jmulligan@redhat.com>
2023-10-05 11:22:38 +00:00

141 lines
3.3 KiB
Go

//go:build !nautilus
// +build !nautilus
package rbd
// #cgo LDFLAGS: -lrbd
// #include <errno.h>
// #include <stdlib.h>
// #include <rbd/librbd.h>
import "C"
import (
"unsafe"
)
// LockMode represents a group of configurable lock modes.
type LockMode C.rbd_lock_mode_t
const (
// LockModeExclusive is the representation of RBD_LOCK_MODE_EXCLUSIVE from librbd.
LockModeExclusive = LockMode(C.RBD_LOCK_MODE_EXCLUSIVE)
// LockModeShared is the representation of RBD_LOCK_MODE_SHARED from librbd.
LockModeShared = LockMode(C.RBD_LOCK_MODE_SHARED)
)
// LockAcquire takes a lock on the given image as per the provided lock_mode.
//
// Implements:
//
// int rbd_lock_acquire(rbd_image_t image, rbd_lock_mode_t lock_mode);
func (image *Image) LockAcquire(lockMode LockMode) error {
if err := image.validate(imageIsOpen); err != nil {
return err
}
ret := C.rbd_lock_acquire(image.image, C.rbd_lock_mode_t(lockMode))
return getError(ret)
}
// LockBreak breaks the lock of lock_mode on the provided lock_owner.
//
// Implements:
//
// int rbd_lock_break(rbd_image_t image, rbd_lock_mode_t lock_mode,
// const char *lock_owner);
func (image *Image) LockBreak(lockMode LockMode, lockOwner string) error {
if err := image.validate(imageIsOpen); err != nil {
return err
}
cLockOwner := C.CString(lockOwner)
defer C.free(unsafe.Pointer(cLockOwner))
ret := C.rbd_lock_break(image.image, C.rbd_lock_mode_t(lockMode), cLockOwner)
return getError(ret)
}
// LockOwner represents information about a lock owner.
type LockOwner struct {
Mode LockMode
Owner string
}
// LockGetOwners fetches the list of lock owners.
//
// Implements:
//
// int rbd_lock_get_owners(rbd_image_t image, rbd_lock_mode_t *lock_mode,
// char **lock_owners, size_t *max_lock_owners);
func (image *Image) LockGetOwners() ([]*LockOwner, error) {
if err := image.validate(imageIsOpen); err != nil {
return nil, err
}
var (
maxLockOwners = C.size_t(8)
cLockOwners = make([]*C.char, 8)
lockMode LockMode
lockOwnersList []*LockOwner
)
for {
ret := C.rbd_lock_get_owners(image.image, (*C.rbd_lock_mode_t)(&lockMode), &cLockOwners[0], &maxLockOwners)
if ret >= 0 {
break
} else if ret == -C.ENOENT {
return nil, nil
} else if ret != -C.ERANGE {
return nil, getError(ret)
}
}
defer C.rbd_lock_get_owners_cleanup(&cLockOwners[0], maxLockOwners)
for i := 0; i < int(maxLockOwners); i++ {
lockOwnersList = append(lockOwnersList, &LockOwner{
Mode: LockMode(lockMode),
Owner: C.GoString(cLockOwners[i]),
})
}
return lockOwnersList, nil
}
// LockIsExclusiveOwner gets the status of the image exclusive lock.
//
// Implements:
//
// int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner);
func (image *Image) LockIsExclusiveOwner() (bool, error) {
if err := image.validate(imageIsOpen); err != nil {
return false, err
}
cIsOwner := C.int(0)
ret := C.rbd_is_exclusive_lock_owner(image.image, &cIsOwner)
if ret != 0 {
return false, getError(ret)
}
return cIsOwner == 1, nil
}
// LockRelease releases a lock on the image.
//
// Implements:
//
// int rbd_lock_release(rbd_image_t image);
func (image *Image) LockRelease() error {
if err := image.validate(imageIsOpen); err != nil {
return err
}
ret := C.rbd_lock_release(image.image)
return getError(ret)
}