ceph-csi/vendor/github.com/ceph/go-ceph/rbd/encryption.go
Rakshith R 796e6b6c44 rbd: use ListChildrenAttributes() instead of ListChildren()
This commit modifies listSnapAndChildren() to make use of
ListChildrenAttributes() instead of ListChildren() which
allows us to filter out images in trash.
This commit also order the alive images so that temp clone
images are followed by images backing volume snapshots so
that temp clone images are flattened first.

Signed-off-by: Rakshith R <rar@redhat.com>
2025-03-12 08:51:02 +00:00

157 lines
4.7 KiB
Go

//go:build !octopus && !nautilus
// +build !octopus,!nautilus
package rbd
// #cgo LDFLAGS: -lrbd
// /* force XSI-complaint strerror_r() */
// #define _POSIX_C_SOURCE 200112L
// #undef _GNU_SOURCE
// #include <errno.h>
// #include <stdlib.h>
// #include <rados/librados.h>
// #include <rbd/librbd.h>
import "C"
import (
"unsafe"
)
// cEncryptionData contains the data needed by the encryption functions
type cEncryptionData struct {
format C.rbd_encryption_format_t
opts C.rbd_encryption_options_t
optsSize C.size_t
free func()
}
// EncryptionAlgorithm is the encryption algorithm
type EncryptionAlgorithm C.rbd_encryption_algorithm_t
// Possible values for EncryptionAlgorithm:
// EncryptionAlgorithmAES128: AES 128bits
// EncryptionAlgorithmAES256: AES 256bits
const (
EncryptionAlgorithmAES128 = EncryptionAlgorithm(C.RBD_ENCRYPTION_ALGORITHM_AES128)
EncryptionAlgorithmAES256 = EncryptionAlgorithm(C.RBD_ENCRYPTION_ALGORITHM_AES256)
)
// EncryptionOptionsLUKS1 and EncryptionOptionsLUKS2 are identical
// structures at the moment, just as they are in the librbd api.
// The purpose behind creating different identical structures, is to facilitate
// future modifications of one of the formats, while maintaining backwards
// compatibility with the other.
// EncryptionOptionsLUKS1 options required for LUKS v1
type EncryptionOptionsLUKS1 struct {
Alg EncryptionAlgorithm
Passphrase []byte
}
// EncryptionOptionsLUKS2 options required for LUKS v2
type EncryptionOptionsLUKS2 struct {
Alg EncryptionAlgorithm
Passphrase []byte
}
// EncryptionOptions interface is used to encapsulate the different encryption
// formats options and enable converting them from go to C structures.
type EncryptionOptions interface {
allocateEncryptionOptions() cEncryptionData
}
func (opts EncryptionOptionsLUKS1) allocateEncryptionOptions() cEncryptionData {
var retData cEncryptionData
// CBytes allocates memory. it will be freed when cEncryptionData.free is called
cPassphrase := (*C.char)(C.CBytes(opts.Passphrase))
cOptsSize := C.size_t(C.sizeof_rbd_encryption_luks1_format_options_t)
cOpts := (*C.rbd_encryption_luks1_format_options_t)(C.malloc(cOptsSize))
cOpts.alg = C.rbd_encryption_algorithm_t(opts.Alg)
cOpts.passphrase = cPassphrase
cOpts.passphrase_size = C.size_t(len(opts.Passphrase))
retData.format = C.RBD_ENCRYPTION_FORMAT_LUKS1
retData.opts = C.rbd_encryption_options_t(cOpts)
retData.optsSize = cOptsSize
retData.free = func() {
C.free(unsafe.Pointer(cOpts.passphrase))
C.free(unsafe.Pointer(cOpts))
}
return retData
}
func (opts EncryptionOptionsLUKS2) allocateEncryptionOptions() cEncryptionData {
var retData cEncryptionData
// CBytes allocates memory. it will be freed when cEncryptionData.free is called
cPassphrase := (*C.char)(C.CBytes(opts.Passphrase))
cOptsSize := C.size_t(C.sizeof_rbd_encryption_luks2_format_options_t)
cOpts := (*C.rbd_encryption_luks2_format_options_t)(C.malloc(cOptsSize))
cOpts.alg = C.rbd_encryption_algorithm_t(opts.Alg)
cOpts.passphrase = cPassphrase
cOpts.passphrase_size = C.size_t(len(opts.Passphrase))
retData.format = C.RBD_ENCRYPTION_FORMAT_LUKS2
retData.opts = C.rbd_encryption_options_t(cOpts)
retData.optsSize = cOptsSize
retData.free = func() {
C.free(unsafe.Pointer(cOpts.passphrase))
C.free(unsafe.Pointer(cOpts))
}
return retData
}
// EncryptionFormat creates an encryption format header
//
// Implements:
//
// int rbd_encryption_format(rbd_image_t image,
// rbd_encryption_format_t format,
// rbd_encryption_options_t opts,
// size_t opts_size);
//
// To issue an IO against the image, you need to mount the image
// with libvirt/qemu using the LUKS format, or make a call to
// rbd_encryption_load().
func (image *Image) EncryptionFormat(opts EncryptionOptions) error {
if image.image == nil {
return ErrImageNotOpen
}
encryptionOpts := opts.allocateEncryptionOptions()
defer encryptionOpts.free()
ret := C.rbd_encryption_format(
image.image,
encryptionOpts.format,
encryptionOpts.opts,
encryptionOpts.optsSize)
return getError(ret)
}
// EncryptionLoad enables IO on an open encrypted image
//
// Implements:
//
// int rbd_encryption_load(rbd_image_t image,
// rbd_encryption_format_t format,
// rbd_encryption_options_t opts,
// size_t opts_size);
func (image *Image) EncryptionLoad(opts EncryptionOptions) error {
if image.image == nil {
return ErrImageNotOpen
}
encryptionOpts := opts.allocateEncryptionOptions()
defer encryptionOpts.free()
ret := C.rbd_encryption_load(
image.image,
encryptionOpts.format,
encryptionOpts.opts,
encryptionOpts.optsSize)
return getError(ret)
}