mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-04-11 18:13:00 +00:00
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>
157 lines
4.7 KiB
Go
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)
|
|
}
|