mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-02-24 10:59:30 +00:00
106 lines
3.2 KiB
Go
106 lines
3.2 KiB
Go
|
//go:build !octopus && !pacific && !quincy && ceph_preview
|
||
|
|
||
|
package rbd
|
||
|
|
||
|
// #cgo LDFLAGS: -lrbd
|
||
|
// /* force XSI-complaint strerror_r() */
|
||
|
// #define _POSIX_C_SOURCE 200112L
|
||
|
// #undef _GNU_SOURCE
|
||
|
// #include <stdlib.h>
|
||
|
// #include <errno.h>
|
||
|
// #include <rbd/librbd.h>
|
||
|
import "C"
|
||
|
|
||
|
import (
|
||
|
"unsafe"
|
||
|
)
|
||
|
|
||
|
type encryptionOptions2 interface {
|
||
|
EncryptionOptions
|
||
|
writeEncryptionSpec(spec *C.rbd_encryption_spec_t) func()
|
||
|
}
|
||
|
|
||
|
func (opts EncryptionOptionsLUKS1) writeEncryptionSpec(spec *C.rbd_encryption_spec_t) func() {
|
||
|
/* only C memory should be attached to spec */
|
||
|
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))
|
||
|
|
||
|
spec.format = C.RBD_ENCRYPTION_FORMAT_LUKS1
|
||
|
spec.opts = C.rbd_encryption_options_t(cOpts)
|
||
|
spec.opts_size = cOptsSize
|
||
|
return func() {
|
||
|
C.free(unsafe.Pointer(cOpts.passphrase))
|
||
|
C.free(unsafe.Pointer(cOpts))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (opts EncryptionOptionsLUKS2) writeEncryptionSpec(spec *C.rbd_encryption_spec_t) func() {
|
||
|
/* only C memory should be attached to spec */
|
||
|
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))
|
||
|
|
||
|
spec.format = C.RBD_ENCRYPTION_FORMAT_LUKS2
|
||
|
spec.opts = C.rbd_encryption_options_t(cOpts)
|
||
|
spec.opts_size = cOptsSize
|
||
|
return func() {
|
||
|
C.free(unsafe.Pointer(cOpts.passphrase))
|
||
|
C.free(unsafe.Pointer(cOpts))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// EncryptionLoad2 enables IO on an open encrypted image. Multiple encryption
|
||
|
// option values can be passed to this call in a slice. For more information
|
||
|
// about how items in the slice are applied to images, and possibly ancestor
|
||
|
// images refer to the documentation in the C api for rbd_encryption_load2.
|
||
|
//
|
||
|
// Implements:
|
||
|
//
|
||
|
// int rbd_encryption_load2(rbd_image_t image,
|
||
|
// const rbd_encryption_spec_t *specs,
|
||
|
// size_t spec_count);
|
||
|
func (image *Image) EncryptionLoad2(opts []EncryptionOptions) error {
|
||
|
if image.image == nil {
|
||
|
return ErrImageNotOpen
|
||
|
}
|
||
|
for _, o := range opts {
|
||
|
if _, ok := o.(encryptionOptions2); !ok {
|
||
|
// this should not happen unless someone adds a new type
|
||
|
// implementing EncryptionOptions but fails to add a
|
||
|
// writeEncryptionSpec such that the type is not also implementing
|
||
|
// encryptionOptions2.
|
||
|
return getError(C.EINVAL)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
length := len(opts)
|
||
|
cspecs := (*C.rbd_encryption_spec_t)(C.malloc(
|
||
|
C.size_t(C.sizeof_rbd_encryption_spec_t * length)))
|
||
|
specs := unsafe.Slice(cspecs, length)
|
||
|
freeFuncs := make([]func(), length)
|
||
|
|
||
|
for idx, option := range opts {
|
||
|
f := option.(encryptionOptions2).writeEncryptionSpec(&specs[idx])
|
||
|
freeFuncs[idx] = f
|
||
|
}
|
||
|
defer func() {
|
||
|
for _, f := range freeFuncs {
|
||
|
f()
|
||
|
}
|
||
|
C.free(unsafe.Pointer(cspecs))
|
||
|
}()
|
||
|
|
||
|
ret := C.rbd_encryption_load2(
|
||
|
image.image,
|
||
|
cspecs,
|
||
|
C.size_t(length))
|
||
|
return getError(ret)
|
||
|
}
|