diff --git a/go.mod b/go.mod index b7930a18b..ad3dc03b1 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/aws/aws-sdk-go v1.55.5 github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 - github.com/ceph/go-ceph v0.28.0 + github.com/ceph/go-ceph v0.29.0 github.com/container-storage-interface/spec v1.10.0 github.com/csi-addons/spec v0.2.1-0.20240730084235-3958a5b17d24 github.com/gemalto/kmip-go v0.0.10 diff --git a/go.sum b/go.sum index 2c668aaf4..15269be8b 100644 --- a/go.sum +++ b/go.sum @@ -1433,8 +1433,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/ceph/go-ceph v0.28.0 h1:ZjlDV9XiVmBQIe9bKbT5j2Ft/bse3Jm+Ui65yE/oFFU= -github.com/ceph/go-ceph v0.28.0/go.mod h1:EwEITEDpuFCMnFrPLbV+/Vyi59jUihgCxBKvlTWGot0= +github.com/ceph/go-ceph v0.29.0 h1:pJQY+++PyY2FMP0ffVaE7FbIdivemBPCu4MWr4S8CtI= +github.com/ceph/go-ceph v0.29.0/go.mod h1:U/l216/AzIWrFe7ny+9cJ5Yjzyb5otrEGfdrU5VtCME= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= diff --git a/vendor/github.com/ceph/go-ceph/cephfs/admin/fs_quiesce.go b/vendor/github.com/ceph/go-ceph/cephfs/admin/fs_quiesce.go index 3c93dcc8c..d22dc2194 100644 --- a/vendor/github.com/ceph/go-ceph/cephfs/admin/fs_quiesce.go +++ b/vendor/github.com/ceph/go-ceph/cephfs/admin/fs_quiesce.go @@ -1,5 +1,3 @@ -//go:build ceph_preview - package admin import "fmt" diff --git a/vendor/github.com/ceph/go-ceph/internal/dlsym/dlsym.go b/vendor/github.com/ceph/go-ceph/internal/dlsym/dlsym.go new file mode 100644 index 000000000..9e5782c4d --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/internal/dlsym/dlsym.go @@ -0,0 +1,41 @@ +package dlsym + +// #cgo LDFLAGS: -ldl +// +// #include +// #include +// +// #ifndef RTLD_DEFAULT /* from dlfcn.h */ +// #define RTLD_DEFAULT ((void *) 0) +// #endif +import "C" + +import ( + "errors" + "fmt" + "unsafe" +) + +// ErrUndefinedSymbol is returned by LookupSymbol when the requested symbol +// could not be found. +var ErrUndefinedSymbol = errors.New("symbol not found") + +// LookupSymbol resolves the named symbol from the already dynamically loaded +// libraries. If the symbol is found, a pointer to it is returned, in case of a +// failure, the message provided by dlerror() is included in the error message. +func LookupSymbol(symbol string) (unsafe.Pointer, error) { + cSymName := C.CString(symbol) + defer C.free(unsafe.Pointer(cSymName)) + + // clear dlerror before looking up the symbol + C.dlerror() + // resolve the address of the symbol + sym := C.dlsym(C.RTLD_DEFAULT, cSymName) + e := C.dlerror() + dlerr := C.GoString(e) + if dlerr != "" { + return nil, fmt.Errorf("%w: %s", ErrUndefinedSymbol, dlerr) + } + + return sym, nil +} diff --git a/vendor/github.com/ceph/go-ceph/rados/read_op_exec.go b/vendor/github.com/ceph/go-ceph/rados/read_op_exec.go new file mode 100644 index 000000000..44d6d18e8 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rados/read_op_exec.go @@ -0,0 +1,111 @@ +//go:build ceph_preview +// +build ceph_preview + +package rados + +// #cgo LDFLAGS: -lrados +// #include +// #include +// +import "C" + +import ( + "runtime" + "unsafe" +) + +// ReadOpExecStep - step for exec operation code. +type ReadOpExecStep struct { + withoutFree + + inBuffPtr *C.char + inBuffLen C.size_t + outBuffPtr *C.char + outBuffLen C.size_t + prval C.int + canReadOutput bool +} + +// newExecStepOp - init new *execStepOp. +func newReadOpExecStep(in []byte) *ReadOpExecStep { + es := &ReadOpExecStep{ + outBuffPtr: nil, + outBuffLen: 0, + prval: 0, + } + + if len(in) > 0 { + es.inBuffPtr = (*C.char)(unsafe.Pointer(&in[0])) + es.inBuffLen = C.size_t(len(in)) + } + + runtime.SetFinalizer(es, func(es *ReadOpExecStep) { + if es != nil { + es.freeBuffer() + es = nil + } + }) + return es +} + +// freeBuffer - releases C allocated buffer. It is separated from es.free() because lifespan of C allocated buffer is +// longer than lifespan of read operation. +func (es *ReadOpExecStep) freeBuffer() { + if es.outBuffPtr != nil { + C.free(unsafe.Pointer(es.outBuffPtr)) + es.outBuffPtr = nil + es.canReadOutput = false + } +} + +// update - update state operation. +func (es *ReadOpExecStep) update() error { + err := getError(es.prval) + es.canReadOutput = err == nil + return err +} + +// Bytes returns the result of the executed command as a byte slice. +func (es *ReadOpExecStep) Bytes() ([]byte, error) { + if !es.canReadOutput { + return nil, ErrOperationIncomplete + } + + return C.GoBytes(unsafe.Pointer(es.outBuffPtr), C.int(es.outBuffLen)), nil +} + +// Exec executes an OSD class method on an object. +// See rados_exec() in the RADOS C api documentation for a general description. +// +// Implements: +// +// void rados_read_op_exec(rados_read_op_t read_op, +// const char *cls, +// const char *method, +// const char *in_buf, +// size_t in_len, +// char **out_buf, +// size_t *out_len, +// int *prval); +func (r *ReadOp) Exec(clsName, method string, in []byte) *ReadOpExecStep { + cClsName := C.CString(clsName) + defer C.free(unsafe.Pointer(cClsName)) + + cMethod := C.CString(method) + defer C.free(unsafe.Pointer(cMethod)) + + es := newReadOpExecStep(in) + r.steps = append(r.steps, es) + C.rados_read_op_exec( + r.op, + cClsName, + cMethod, + es.inBuffPtr, + es.inBuffLen, + &es.outBuffPtr, + &es.outBuffLen, + &es.prval, + ) + + return es +} diff --git a/vendor/github.com/ceph/go-ceph/rados/write_op_exec.go b/vendor/github.com/ceph/go-ceph/rados/write_op_exec.go new file mode 100644 index 000000000..8f7fc07f3 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rados/write_op_exec.go @@ -0,0 +1,71 @@ +//go:build ceph_preview +// +build ceph_preview + +package rados + +// #cgo LDFLAGS: -lrados +// #include +// #include +// +import "C" + +import ( + "unsafe" +) + +// writeOpExecStep - exec step in write operation. +type writeOpExecStep struct { + withoutFree + + inBuffPtr *C.char + inBuffLen C.size_t + prval C.int +} + +// newWriteOpExecStep - init new *writeOpExecStep. +func newWriteOpExecStep(in []byte) *writeOpExecStep { + es := &writeOpExecStep{ + prval: 0, + } + if len(in) > 0 { + es.inBuffPtr = (*C.char)(unsafe.Pointer(&in[0])) + es.inBuffLen = C.size_t(len(in)) + } + + return es +} + +// update - update state operation. +func (es *writeOpExecStep) update() error { + return getError(es.prval) +} + +// Exec executes an OSD class method on an object. +// See rados_exec() in the RADOS C api documentation for a general description. +// +// Implements: +// +// void rados_write_op_exec(rados_write_op_t write_op, +// const char *cls, +// const char *method, +// const char *in_buf, +// size_t in_len, +// int *prval) +func (w *WriteOp) Exec(clsName, method string, in []byte) { + cClsName := C.CString(clsName) + defer C.free(unsafe.Pointer(cClsName)) + + cMethod := C.CString(method) + defer C.free(unsafe.Pointer(cMethod)) + + es := newWriteOpExecStep(in) + w.steps = append(w.steps, es) + C.rados_write_op_exec( + w.op, + cClsName, + cMethod, + es.inBuffPtr, + es.inBuffLen, + &es.prval, + ) +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/clone_image_by_id.go b/vendor/github.com/ceph/go-ceph/rbd/clone_image_by_id.go new file mode 100644 index 000000000..63cf552d9 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/clone_image_by_id.go @@ -0,0 +1,83 @@ +//go:build ceph_preview + +package rbd + +/* +#cgo LDFLAGS: -lrbd +#include +#include +#include +#include + +// rbd_clone4_fn matches the rbd_clone4 function signature. +typedef int(*rbd_clone4_fn)(rados_ioctx_t p_ioctx, const char *p_name, + uint64_t p_snap_id, rados_ioctx_t c_ioctx, + const char *c_name, rbd_image_options_t c_opts); + +// rbd_clone4_dlsym take *fn as rbd_clone4_fn and calls the dynamically loaded +// rbd_clone4 function passed as 1st argument. +static inline int rbd_clone4_dlsym(void *fn, rados_ioctx_t p_ioctx, + const char *p_name, uint64_t p_snap_id, + rados_ioctx_t c_ioctx, const char *c_name, + rbd_image_options_t c_opts) { + // cast function pointer fn to rbd_clone4 and call the function + return ((rbd_clone4_fn) fn)(p_ioctx, p_name, p_snap_id, c_ioctx, c_name, c_opts); +} +*/ +import "C" + +import ( + "fmt" + "sync" + "unsafe" + + "github.com/ceph/go-ceph/internal/dlsym" + "github.com/ceph/go-ceph/rados" +) + +var ( + rbdClone4Once sync.Once + rbdClone4 unsafe.Pointer + rbdClone4Err error +) + +// CloneImageByID creates a clone of the image from a snapshot with the given +// ID in the provided io-context with the given name and image options. +// +// Implements: +// +// int rbd_clone4(rados_ioctx_t p_ioctx, const char *p_name, +// uint64_t p_snap_id, rados_ioctx_t c_ioctx, +// const char *c_name, rbd_image_options_t c_opts); +func CloneImageByID(ioctx *rados.IOContext, parentName string, snapID uint64, + destctx *rados.IOContext, name string, rio *ImageOptions) error { + if rio == nil { + return rbdError(C.EINVAL) + } + + rbdClone4Once.Do(func() { + rbdClone4, rbdClone4Err = dlsym.LookupSymbol("rbd_clone4") + }) + + if rbdClone4Err != nil { + return fmt.Errorf("%w: %w", ErrNotImplemented, rbdClone4Err) + } + + cParentName := C.CString(parentName) + defer C.free(unsafe.Pointer(cParentName)) + cCloneName := C.CString(name) + defer C.free(unsafe.Pointer(cCloneName)) + + // call rbd_clone4_dlsym with the function pointer to rbd_clone4 as 1st + // argument + ret := C.rbd_clone4_dlsym( + rbdClone4, + cephIoctx(ioctx), + cParentName, + C.uint64_t(snapID), + cephIoctx(destctx), + cCloneName, + C.rbd_image_options_t(rio.options)) + + return getError(ret) +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/errors.go b/vendor/github.com/ceph/go-ceph/rbd/errors.go index 34693333f..4d98cce7c 100644 --- a/vendor/github.com/ceph/go-ceph/rbd/errors.go +++ b/vendor/github.com/ceph/go-ceph/rbd/errors.go @@ -75,6 +75,8 @@ var ( const ( // ErrNotExist indicates a non-specific missing resource. ErrNotExist = rbdError(-C.ENOENT) + // ErrNotImplemented indicates a function is not implemented in by librbd. + ErrNotImplemented = rbdError(-C.ENOSYS) ) // Private errors: diff --git a/vendor/github.com/ceph/go-ceph/rbd/snap_group_namespace.go b/vendor/github.com/ceph/go-ceph/rbd/snap_group_namespace.go index 88f975d05..f0bd765ea 100644 --- a/vendor/github.com/ceph/go-ceph/rbd/snap_group_namespace.go +++ b/vendor/github.com/ceph/go-ceph/rbd/snap_group_namespace.go @@ -1,5 +1,3 @@ -//go:build ceph_preview - package rbd // #cgo LDFLAGS: -lrbd diff --git a/vendor/modules.txt b/vendor/modules.txt index 3b43f1614..afe5a96df 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -206,7 +206,7 @@ github.com/ceph/ceph-csi/api/deploy/kubernetes/cephfs github.com/ceph/ceph-csi/api/deploy/kubernetes/nfs github.com/ceph/ceph-csi/api/deploy/kubernetes/rbd github.com/ceph/ceph-csi/api/deploy/ocp -# github.com/ceph/go-ceph v0.28.0 +# github.com/ceph/go-ceph v0.29.0 ## explicit; go 1.19 github.com/ceph/go-ceph/cephfs github.com/ceph/go-ceph/cephfs/admin @@ -216,6 +216,7 @@ github.com/ceph/go-ceph/common/commands github.com/ceph/go-ceph/internal/callbacks github.com/ceph/go-ceph/internal/commands github.com/ceph/go-ceph/internal/cutil +github.com/ceph/go-ceph/internal/dlsym github.com/ceph/go-ceph/internal/errutil github.com/ceph/go-ceph/internal/log github.com/ceph/go-ceph/internal/retry