-
Notifications
You must be signed in to change notification settings - Fork 261
/
Copy pathclone_image_by_id.go
82 lines (70 loc) · 2.23 KB
/
clone_image_by_id.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package rbd
/*
#cgo LDFLAGS: -lrbd
#include <errno.h>
#include <stdlib.h>
#include <rados/librados.h>
#include <rbd/librbd.h>
// 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 getError(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)
}