diff --git a/go.mod b/go.mod index 7fad99708..73ec24b1c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ceph/ceph-csi go 1.13 require ( - github.com/ceph/go-ceph v0.2.0 + github.com/ceph/go-ceph v0.3.0 github.com/container-storage-interface/spec v1.2.0 github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect diff --git a/go.sum b/go.sum index f6615a154..f461f42ee 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/ceph/go-ceph v0.2.0 h1:AMTlFmyU+ipCNj/l41m84c02At/6sP4vuQfCr+CtcsE= -github.com/ceph/go-ceph v0.2.0/go.mod h1:6gzI3dc/5hfl98DIK25fQ0iFSdyCRjVEFTuCoGwvjEY= +github.com/ceph/go-ceph v0.3.0 h1:DBAQTu2GGznczfoiwaRroPttiZe10J8SaHdH3v/0lIE= +github.com/ceph/go-ceph v0.3.0/go.mod h1:6gzI3dc/5hfl98DIK25fQ0iFSdyCRjVEFTuCoGwvjEY= github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= diff --git a/vendor/github.com/ceph/go-ceph/internal/callbacks/callbacks.go b/vendor/github.com/ceph/go-ceph/internal/callbacks/callbacks.go new file mode 100644 index 000000000..2bce42a86 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/internal/callbacks/callbacks.go @@ -0,0 +1,64 @@ +package callbacks + +import ( + "sync" +) + +// The logic of this file is largely adapted from: +// https://github.com/golang/go/wiki/cgo#function-variables +// +// Also helpful: +// https://eli.thegreenplace.net/2019/passing-callbacks-and-pointers-to-cgo/ + +// Callbacks provides a tracker for data that is to be passed between Go +// and C callback functions. The Go callback/object may not be passed +// by a pointer to C code and so instead integer indexes into an internal +// map are used. +// Typically the item being added will either be a callback function or +// a data structure containing a callback function. It is up to the caller +// to control and validate what "callbacks" get used. +type Callbacks struct { + mutex sync.RWMutex + cmap map[int]interface{} +} + +// New returns a new callbacks tracker. +func New() *Callbacks { + return &Callbacks{cmap: make(map[int]interface{})} +} + +// Add a callback/object to the tracker and return a new index +// for the object. +func (cb *Callbacks) Add(v interface{}) int { + cb.mutex.Lock() + defer cb.mutex.Unlock() + // this approach assumes that there are typically very few callbacks + // in play at once and can just use the length of the map as our + // index. But in case of collisions we fall back to simply incrementing + // until we find a free key like in the cgo wiki page. + // If this code ever becomes a hot path there's surely plenty of room + // for optimization in the future :-) + index := len(cb.cmap) + 1 + for { + if _, found := cb.cmap[index]; !found { + break + } + index++ + } + cb.cmap[index] = v + return index +} + +// Remove a callback/object given it's index. +func (cb *Callbacks) Remove(index int) { + cb.mutex.Lock() + defer cb.mutex.Unlock() + delete(cb.cmap, index) +} + +// Lookup returns a mapped callback/object given an index. +func (cb *Callbacks) Lookup(index int) interface{} { + cb.mutex.RLock() + defer cb.mutex.RUnlock() + return cb.cmap[index] +} diff --git a/vendor/github.com/ceph/go-ceph/errutil/strerror.go b/vendor/github.com/ceph/go-ceph/internal/errutil/strerror.go similarity index 100% rename from vendor/github.com/ceph/go-ceph/errutil/strerror.go rename to vendor/github.com/ceph/go-ceph/internal/errutil/strerror.go diff --git a/vendor/github.com/ceph/go-ceph/rados/conn.go b/vendor/github.com/ceph/go-ceph/rados/conn.go index 78c3b268a..cd69a181c 100644 --- a/vendor/github.com/ceph/go-ceph/rados/conn.go +++ b/vendor/github.com/ceph/go-ceph/rados/conn.go @@ -7,15 +7,9 @@ import "C" import ( "bytes" - "errors" "unsafe" ) -var ( - // ErrNotConnected is returned when functions are called without a RADOS connection - ErrNotConnected = errors.New("RADOS not connected") -) - // ClusterStat represents Ceph cluster statistics. type ClusterStat struct { Kb uint64 @@ -53,7 +47,7 @@ func (c *Conn) PingMonitor(id string) (string, error) { reply := C.GoStringN(strout, (C.int)(strlen)) return reply, nil } - return "", RadosError(int(ret)) + return "", getError(ret) } // Connect establishes a connection to a RADOS cluster. It returns an error, @@ -61,7 +55,7 @@ func (c *Conn) PingMonitor(id string) (string, error) { func (c *Conn) Connect() error { ret := C.rados_connect(c.cluster) if ret != 0 { - return RadosError(int(ret)) + return getError(ret) } c.connected = true return nil @@ -80,14 +74,14 @@ func (c *Conn) ReadConfigFile(path string) error { c_path := C.CString(path) defer C.free(unsafe.Pointer(c_path)) ret := C.rados_conf_read_file(c.cluster, c_path) - return getRadosError(int(ret)) + return getError(ret) } // ReadDefaultConfigFile configures the connection using a Ceph configuration // file located at default locations. func (c *Conn) ReadDefaultConfigFile() error { ret := C.rados_conf_read_file(c.cluster, nil) - return getRadosError(int(ret)) + return getError(ret) } // OpenIOContext creates and returns a new IOContext for the given pool. @@ -103,20 +97,20 @@ func (c *Conn) OpenIOContext(pool string) (*IOContext, error) { if ret == 0 { return ioctx, nil } - return nil, RadosError(int(ret)) + return nil, getError(ret) } // ListPools returns the names of all existing pools. func (c *Conn) ListPools() (names []string, err error) { buf := make([]byte, 4096) for { - ret := int(C.rados_pool_list(c.cluster, - (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))) + ret := C.rados_pool_list(c.cluster, + (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) if ret < 0 { - return nil, RadosError(int(ret)) + return nil, getError(ret) } - if ret > len(buf) { + if int(ret) > len(buf) { buf = make([]byte, ret) continue } @@ -140,7 +134,7 @@ func (c *Conn) SetConfigOption(option, value string) error { defer C.free(unsafe.Pointer(c_opt)) defer C.free(unsafe.Pointer(c_val)) ret := C.rados_conf_set(c.cluster, c_opt, c_val) - return getRadosError(int(ret)) + return getError(ret) } // GetConfigOption returns the value of the Ceph configuration option @@ -165,7 +159,7 @@ func (c *Conn) GetConfigOption(name string) (value string, err error) { // retrieved. func (c *Conn) WaitForLatestOSDMap() error { ret := C.rados_wait_for_latest_osdmap(c.cluster) - return getRadosError(int(ret)) + return getError(ret) } func (c *Conn) ensure_connected() error { @@ -184,7 +178,7 @@ func (c *Conn) GetClusterStats() (stat ClusterStat, err error) { c_stat := C.struct_rados_cluster_stat_t{} ret := C.rados_cluster_stat(c.cluster, &c_stat) if ret < 0 { - return ClusterStat{}, RadosError(int(ret)) + return ClusterStat{}, getError(ret) } return ClusterStat{ Kb: uint64(c_stat.kb), @@ -211,28 +205,28 @@ func (c *Conn) ParseCmdLineArgs(args []string) error { } ret := C.rados_conf_parse_argv(c.cluster, argc, &argv[0]) - return getRadosError(int(ret)) + return getError(ret) } // ParseDefaultConfigEnv configures the connection from the default Ceph // environment variable(s). func (c *Conn) ParseDefaultConfigEnv() error { ret := C.rados_conf_parse_env(c.cluster, nil) - return getRadosError(int(ret)) + return getError(ret) } // GetFSID returns the fsid of the cluster as a hexadecimal string. The fsid // is a unique identifier of an entire Ceph cluster. func (c *Conn) GetFSID() (fsid string, err error) { buf := make([]byte, 37) - ret := int(C.rados_cluster_fsid(c.cluster, - (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))) + ret := C.rados_cluster_fsid(c.cluster, + (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) // FIXME: the success case isn't documented correctly in librados.h if ret == 36 { fsid = C.GoString((*C.char)(unsafe.Pointer(&buf[0]))) return fsid, nil } - return "", RadosError(int(ret)) + return "", getError(ret) } // GetInstanceID returns a globally unique identifier for the cluster @@ -246,8 +240,8 @@ func (c *Conn) GetInstanceID() uint64 { func (c *Conn) MakePool(name string) error { c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) - ret := int(C.rados_pool_create(c.cluster, c_name)) - return getRadosError(int(ret)) + ret := C.rados_pool_create(c.cluster, c_name) + return getError(ret) } // DeletePool deletes a pool and all the data inside the pool. @@ -257,8 +251,8 @@ func (c *Conn) DeletePool(name string) error { } c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) - ret := int(C.rados_pool_delete(c.cluster, c_name)) - return getRadosError(int(ret)) + ret := C.rados_pool_delete(c.cluster, c_name) + return getError(ret) } // GetPoolByName returns the ID of the pool with a given name. @@ -329,7 +323,7 @@ func (c *Conn) monCommand(args, inputBuffer []byte) (buffer []byte, info string, C.free(unsafe.Pointer(outbuf)) } if ret != 0 { - err = RadosError(int(ret)) + err = getError(ret) return nil, info, err } @@ -400,7 +394,7 @@ func (c *Conn) pgCommand(pgid []byte, args [][]byte, inputBuffer []byte) (buffer C.free(unsafe.Pointer(outbuf)) } if ret != 0 { - err = RadosError(int(ret)) + err = getError(ret) return nil, info, err } diff --git a/vendor/github.com/ceph/go-ceph/rados/errors.go b/vendor/github.com/ceph/go-ceph/rados/errors.go new file mode 100644 index 000000000..d01a425b2 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rados/errors.go @@ -0,0 +1,63 @@ +package rados + +/* +#include +*/ +import "C" + +import ( + "errors" + "fmt" + + "github.com/ceph/go-ceph/internal/errutil" +) + +// revive:disable:exported Temporarily live with stuttering + +// RadosError represents an error condition returned from the Ceph RADOS APIs. +type RadosError int + +// revive:enable:exported + +// Error returns the error string for the RadosError type. +func (e RadosError) Error() string { + errno, s := errutil.FormatErrno(int(e)) + if s == "" { + return fmt.Sprintf("rados: ret=%d", errno) + } + return fmt.Sprintf("rados: ret=%d, %s", errno, s) +} + +func getError(e C.int) error { + if e == 0 { + return nil + } + return RadosError(e) +} + +// Public go errors: + +var ( + // ErrNotConnected is returned when functions are called without a RADOS connection + ErrNotConnected = errors.New("RADOS not connected") +) + +// Public RadosErrors: + +const ( + // ErrNotFound indicates a missing resource. + ErrNotFound = RadosError(-C.ENOENT) + // ErrPermissionDenied indicates a permissions issue. + ErrPermissionDenied = RadosError(-C.EPERM) + // ErrObjectExists indicates that an exclusive object creation failed. + ErrObjectExists = RadosError(-C.EEXIST) + + // RadosErrorNotFound indicates a missing resource. + // + // Deprecated: use ErrNotFound instead + RadosErrorNotFound = ErrNotFound + // RadosErrorPermissionDenied indicates a permissions issue. + // + // Deprecated: use ErrPermissionDenied instead + RadosErrorPermissionDenied = ErrPermissionDenied +) diff --git a/vendor/github.com/ceph/go-ceph/rados/ioctx.go b/vendor/github.com/ceph/go-ceph/rados/ioctx.go index 0c7e641ef..45069a9d8 100644 --- a/vendor/github.com/ceph/go-ceph/rados/ioctx.go +++ b/vendor/github.com/ceph/go-ceph/rados/ioctx.go @@ -90,9 +90,10 @@ type IOContext struct { ioctx C.rados_ioctx_t } -// Pointer returns a uintptr representation of the IOContext. -func (ioctx *IOContext) Pointer() uintptr { - return uintptr(ioctx.ioctx) +// Pointer returns a pointer reference to an internal structure. +// This function should NOT be used outside of go-ceph itself. +func (ioctx *IOContext) Pointer() unsafe.Pointer { + return unsafe.Pointer(ioctx.ioctx) } // SetNamespace sets the namespace for objects within this IO context (pool). @@ -120,7 +121,7 @@ func (ioctx *IOContext) Create(oid string, exclusive CreateOption) error { ret := C.rados_write_op_operate(op, ioctx.ioctx, c_oid, nil, 0) C.rados_release_write_op(op) - return getRadosError(int(ret)) + return getError(ret) } // Write writes len(data) bytes to the object with key oid starting at byte @@ -139,7 +140,7 @@ func (ioctx *IOContext) Write(oid string, data []byte, offset uint64) error { (C.size_t)(len(data)), (C.uint64_t)(offset)) - return getRadosError(int(ret)) + return getError(ret) } // WriteFull writes len(data) bytes to the object with key oid. @@ -152,7 +153,7 @@ func (ioctx *IOContext) WriteFull(oid string, data []byte) error { ret := C.rados_write_full(ioctx.ioctx, c_oid, (*C.char)(unsafe.Pointer(&data[0])), (C.size_t)(len(data))) - return getRadosError(int(ret)) + return getError(ret) } // Append appends len(data) bytes to the object with key oid. @@ -165,7 +166,7 @@ func (ioctx *IOContext) Append(oid string, data []byte) error { ret := C.rados_append(ioctx.ioctx, c_oid, (*C.char)(unsafe.Pointer(&data[0])), (C.size_t)(len(data))) - return getRadosError(int(ret)) + return getError(ret) } // Read reads up to len(data) bytes from the object with key oid starting at byte @@ -189,7 +190,7 @@ func (ioctx *IOContext) Read(oid string, data []byte, offset uint64) (int, error if ret >= 0 { return int(ret), nil } - return 0, getRadosError(int(ret)) + return 0, getError(ret) } // Delete deletes the object with key oid. It returns an error, if any. @@ -197,7 +198,7 @@ func (ioctx *IOContext) Delete(oid string) error { c_oid := C.CString(oid) defer C.free(unsafe.Pointer(c_oid)) - return getRadosError(int(C.rados_remove(ioctx.ioctx, c_oid))) + return getError(C.rados_remove(ioctx.ioctx, c_oid)) } // Truncate resizes the object with key oid to size size. If the operation @@ -208,7 +209,7 @@ func (ioctx *IOContext) Truncate(oid string, size uint64) error { c_oid := C.CString(oid) defer C.free(unsafe.Pointer(c_oid)) - return getRadosError(int(C.rados_trunc(ioctx.ioctx, c_oid, (C.uint64_t)(size)))) + return getError(C.rados_trunc(ioctx.ioctx, c_oid, (C.uint64_t)(size))) } // Destroy informs librados that the I/O context is no longer in use. @@ -228,7 +229,7 @@ func (ioctx *IOContext) GetPoolStats() (stat PoolStat, err error) { c_stat := C.struct_rados_pool_stat_t{} ret := C.rados_ioctx_pool_stat(ioctx.ioctx, &c_stat) if ret < 0 { - return PoolStat{}, getRadosError(int(ret)) + return PoolStat{}, getError(ret) } return PoolStat{ Num_bytes: uint64(c_stat.num_bytes), @@ -256,7 +257,7 @@ func (ioctx *IOContext) GetPoolName() (name string, err error) { buf = make([]byte, len(buf)*2) continue } else if ret < 0 { - return "", getRadosError(int(ret)) + return "", getError(ret) } name = C.GoStringN((*C.char)(unsafe.Pointer(&buf[0])), ret) return name, nil @@ -276,7 +277,7 @@ func (ioctx *IOContext) ListObjects(listFn ObjectListFunc) error { var ctx C.rados_list_ctx_t ret := C.rados_nobjects_list_open(ioctx.ioctx, &ctx) if ret < 0 { - return getRadosError(int(ret)) + return getError(ret) } defer func() { C.rados_nobjects_list_close(ctx) }() @@ -286,7 +287,7 @@ func (ioctx *IOContext) ListObjects(listFn ObjectListFunc) error { if ret == -C.ENOENT { return nil } else if ret < 0 { - return getRadosError(int(ret)) + return getError(ret) } listFn(C.GoString(c_entry)) } @@ -306,7 +307,7 @@ func (ioctx *IOContext) Stat(object string) (stat ObjectStat, err error) { &c_pmtime) if ret < 0 { - return ObjectStat{}, getRadosError(int(ret)) + return ObjectStat{}, getError(ret) } return ObjectStat{ Size: uint64(c_psize), @@ -332,7 +333,7 @@ func (ioctx *IOContext) GetXattr(object string, name string, data []byte) (int, if ret >= 0 { return int(ret), nil } - return 0, getRadosError(int(ret)) + return 0, getError(ret) } // SetXattr sets an xattr for an object with key `name` with value as `data` @@ -349,7 +350,7 @@ func (ioctx *IOContext) SetXattr(object string, name string, data []byte) error (*C.char)(unsafe.Pointer(&data[0])), (C.size_t)(len(data))) - return getRadosError(int(ret)) + return getError(ret) } // ListXattrs lists all the xattrs for an object. The xattrs are returned as a @@ -362,7 +363,7 @@ func (ioctx *IOContext) ListXattrs(oid string) (map[string][]byte, error) { ret := C.rados_getxattrs(ioctx.ioctx, c_oid, &it) if ret < 0 { - return nil, getRadosError(int(ret)) + return nil, getError(ret) } defer func() { C.rados_getxattrs_end(it) }() m := make(map[string][]byte) @@ -374,7 +375,7 @@ func (ioctx *IOContext) ListXattrs(oid string) (map[string][]byte, error) { ret := C.rados_getxattrs_next(it, &c_name, &c_val, &c_len) if ret < 0 { - return nil, getRadosError(int(ret)) + return nil, getError(ret) } // rados api returns a null name,val & 0-length upon // end of iteration @@ -397,7 +398,7 @@ func (ioctx *IOContext) RmXattr(oid string, name string) error { c_oid, c_name) - return getRadosError(int(ret)) + return getError(ret) } // LockExclusive takes an exclusive lock on an object. @@ -444,7 +445,7 @@ func (ioctx *IOContext) LockExclusive(oid, name, cookie, desc string, duration t case -C.EEXIST: return int(ret), nil default: - return int(ret), RadosError(int(ret)) + return int(ret), getError(ret) } } @@ -495,7 +496,7 @@ func (ioctx *IOContext) LockShared(oid, name, cookie, tag, desc string, duration case -C.EEXIST: return int(ret), nil default: - return int(ret), RadosError(int(ret)) + return int(ret), getError(ret) } } @@ -524,7 +525,7 @@ func (ioctx *IOContext) Unlock(oid, name, cookie string) (int, error) { case -C.ENOENT: return int(ret), nil default: - return int(ret), RadosError(int(ret)) + return int(ret), getError(ret) } } @@ -581,7 +582,7 @@ func (ioctx *IOContext) ListLockers(oid, name string) (*LockInfo, error) { } if ret < 0 { - return nil, RadosError(int(ret)) + return nil, RadosError(ret) } return &LockInfo{int(ret), c_exclusive == 1, C.GoString(c_tag), splitCString(c_clients, c_clients_len), splitCString(c_cookies, c_cookies_len), splitCString(c_addrs, c_addrs_len)}, nil } @@ -617,6 +618,6 @@ func (ioctx *IOContext) BreakLock(oid, name, client, cookie string) (int, error) case -C.EINVAL: // -EINVAL return int(ret), nil default: - return int(ret), RadosError(int(ret)) + return int(ret), getError(ret) } } diff --git a/vendor/github.com/ceph/go-ceph/rados/object_iter.go b/vendor/github.com/ceph/go-ceph/rados/object_iter.go index c0969eb20..6add2bdbe 100644 --- a/vendor/github.com/ceph/go-ceph/rados/object_iter.go +++ b/vendor/github.com/ceph/go-ceph/rados/object_iter.go @@ -20,7 +20,7 @@ type IterToken uint32 func (ioctx *IOContext) Iter() (*Iter, error) { iter := Iter{} if cerr := C.rados_nobjects_list_open(ioctx.ioctx, &iter.ctx); cerr < 0 { - return nil, getRadosError(int(cerr)) + return nil, getError(cerr) } return &iter, nil } @@ -53,7 +53,7 @@ func (iter *Iter) Next() bool { var c_entry *C.char var c_namespace *C.char if cerr := C.rados_nobjects_list_next(iter.ctx, &c_entry, nil, &c_namespace); cerr < 0 { - iter.err = getRadosError(int(cerr)) + iter.err = getError(cerr) return false } iter.entry = C.GoString(c_entry) diff --git a/vendor/github.com/ceph/go-ceph/rados/omap.go b/vendor/github.com/ceph/go-ceph/rados/omap.go index bea0ddaea..7d279c2b4 100644 --- a/vendor/github.com/ceph/go-ceph/rados/omap.go +++ b/vendor/github.com/ceph/go-ceph/rados/omap.go @@ -63,7 +63,7 @@ func (ioctx *IOContext) SetOmap(oid string, pairs map[string][]byte) error { ret := C.rados_write_op_operate(op, ioctx.ioctx, c_oid, nil, 0) C.rados_release_write_op(op) - return getRadosError(int(ret)) + return getError(ret) } // OmapListFunc is the type of the function called for each omap key @@ -104,9 +104,9 @@ func (ioctx *IOContext) ListOmapValues(oid string, startAfter string, filterPref ret := C.rados_read_op_operate(op, ioctx.ioctx, c_oid, 0) if int(ret) != 0 { - return getRadosError(int(ret)) + return getError(ret) } else if int(c_prval) != 0 { - return RadosError(int(c_prval)) + return getError(c_prval) } for { @@ -117,7 +117,7 @@ func (ioctx *IOContext) ListOmapValues(oid string, startAfter string, filterPref ret = C.rados_omap_get_next(c_iter, &c_key, &c_val, &c_len) if int(ret) != 0 { - return getRadosError(int(ret)) + return getError(ret) } if c_key == nil { @@ -210,7 +210,7 @@ func (ioctx *IOContext) RmOmapKeys(oid string, keys []string) error { ret := C.rados_write_op_operate(op, ioctx.ioctx, c_oid, nil, 0) C.rados_release_write_op(op) - return getRadosError(int(ret)) + return getError(ret) } // CleanOmap clears the omap `oid` @@ -224,5 +224,5 @@ func (ioctx *IOContext) CleanOmap(oid string) error { ret := C.rados_write_op_operate(op, ioctx.ioctx, c_oid, nil, 0) C.rados_release_write_op(op) - return getRadosError(int(ret)) + return getError(ret) } diff --git a/vendor/github.com/ceph/go-ceph/rados/rados.go b/vendor/github.com/ceph/go-ceph/rados/rados.go index 2e4a48756..d1f000ac0 100644 --- a/vendor/github.com/ceph/go-ceph/rados/rados.go +++ b/vendor/github.com/ceph/go-ceph/rados/rados.go @@ -7,37 +7,15 @@ package rados import "C" import ( - "fmt" "runtime" "unsafe" - - "github.com/ceph/go-ceph/errutil" ) -// RadosError represents an error condition returned from the Ceph RADOS APIs. -type RadosError int - -// Error returns the error string for the RadosError type. -func (e RadosError) Error() string { - errno, s := errutil.FormatErrno(int(e)) - if s == "" { - return fmt.Sprintf("rados: ret=%d", errno) - } - return fmt.Sprintf("rados: ret=%d, %s", errno, s) -} - const ( // AllNamespaces is used to reset a selected namespace to all // namespaces. See the IOContext SetNamespace function. AllNamespaces = C.LIBRADOS_ALL_NSPACES - // ErrNotFound indicates a missing resource. - ErrNotFound = RadosError(-C.ENOENT) - // ErrPermissionDenied indicates a permissions issue. - ErrPermissionDenied = RadosError(-C.EPERM) - // ErrObjectExists indicates that an exclusive object creation failed. - ErrObjectExists = RadosError(-C.EEXIST) - // FIXME: for backwards compatibility // RadosAllNamespaces is used to reset a selected namespace to all @@ -45,23 +23,8 @@ const ( // // Deprecated: use AllNamespaces instead RadosAllNamespaces = AllNamespaces - // RadosErrorNotFound indicates a missing resource. - // - // Deprecated: use ErrNotFound instead - RadosErrorNotFound = ErrNotFound - // RadosErrorPermissionDenied indicates a permissions issue. - // - // Deprecated: use ErrPermissionDenied instead - RadosErrorPermissionDenied = ErrPermissionDenied ) -func getRadosError(err int) error { - if err == 0 { - return nil - } - return RadosError(err) -} - // Version returns the major, minor, and patch components of the version of // the RADOS library linked against. func Version() (int, int, int) { @@ -79,7 +42,7 @@ func newConn(user *C.char) (*Conn, error) { ret := C.rados_create(&conn.cluster, user) if ret != 0 { - return nil, RadosError(int(ret)) + return nil, getError(ret) } runtime.SetFinalizer(conn, freeConn) @@ -112,7 +75,7 @@ func NewConnWithClusterAndUser(clusterName string, userName string) (*Conn, erro conn := makeConn() ret := C.rados_create2(&conn.cluster, c_cluster_name, c_name, 0) if ret != 0 { - return nil, RadosError(int(ret)) + return nil, getError(ret) } runtime.SetFinalizer(conn, freeConn) diff --git a/vendor/github.com/ceph/go-ceph/rbd/callback_shims.go b/vendor/github.com/ceph/go-ceph/rbd/callback_shims.go new file mode 100644 index 000000000..ab040e7dc --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/callback_shims.go @@ -0,0 +1,13 @@ +package rbd + +/* + +#include + +extern int diffIterateCallback(uint64_t ofs, size_t len, int exists, int index); + +int callDiffIterateCallback(uint64_t ofs, size_t len, int exists, int index) { + return diffIterateCallback(ofs, len, exists, index); +} +*/ +import "C" diff --git a/vendor/github.com/ceph/go-ceph/rbd/diff_iterate.go b/vendor/github.com/ceph/go-ceph/rbd/diff_iterate.go new file mode 100644 index 000000000..20cf9c435 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/diff_iterate.go @@ -0,0 +1,135 @@ +package rbd + +/* +#cgo LDFLAGS: -lrbd +#undef _GNU_SOURCE +#include +#include +#include + +extern int callDiffIterateCallback(uint64_t ofs, size_t len, int exists, int index); + +// cgo is having trouble converting the callback from the librbd header +// to a unsafe.Pointer. This shim exists solely to help it along. +static inline int wrap_rbd_diff_iterate2( + rbd_image_t image, + const char *fromsnapname, + uint64_t ofs, uint64_t len, + uint8_t include_parent, uint8_t whole_object, + void *cb, + uintptr_t arg) { + return rbd_diff_iterate2(image, fromsnapname, ofs, len, include_parent, whole_object, cb, (void*)arg); +} +*/ +import "C" + +import ( + "unsafe" + + "github.com/ceph/go-ceph/internal/callbacks" +) + +var diffIterateCallbacks = callbacks.New() + +// DiffIncludeParent values control if the difference should include the parent +// image. +type DiffIncludeParent uint8 + +// DiffWholeObject values control if the diff extents should cover the whole +// object. +type DiffWholeObject uint8 + +// DiffIterateCallback defines the function signature needed for the +// DiffIterate callback. +// +// The function will be called with the arguments: offset, length, exists, and +// data. The offset and length correspond to the changed region of the image. +// The exists value is set to zero if the region is known to be zeros, +// otherwise it is set to 1. The data value is the extra data parameter that +// was set on the DiffIterateConfig and is meant to be used for passing +// arbitrary user-defined items to the callback function. +// +// The callback can trigger the iteration to terminate early by returning +// a non-zero error code. +type DiffIterateCallback func(uint64, uint64, int, interface{}) int + +// DiffIterateConfig is used to define the parameters of a DiffIterate call. +// Callback, Offset, and Length should always be specified when passed to +// DiffIterate. The other values are optional. +type DiffIterateConfig struct { + SnapName string + Offset uint64 + Length uint64 + IncludeParent DiffIncludeParent + WholeObject DiffWholeObject + Callback DiffIterateCallback + Data interface{} +} + +const ( + // ExcludeParent will exclude the parent from the diff. + ExcludeParent = DiffIncludeParent(0) + // IncludeParent will include the parent in the diff. + IncludeParent = DiffIncludeParent(1) + + // DisableWholeObject will not use the whole object in the diff. + DisableWholeObject = DiffWholeObject(0) + // EnableWholeObject will use the whole object in the diff. + EnableWholeObject = DiffWholeObject(1) +) + +// DiffIterate calls a callback on changed extents of an image. +// +// Calling DiffIterate will cause the callback specified in the +// DiffIterateConfig to be called as many times as there are changed +// regions in the image (controlled by the parameters as passed to librbd). +// +// See the documentation of DiffIterateCallback for a description of the +// arguments to the callback and the return behavior. +// +// Implements: +// int rbd_diff_iterate2(rbd_image_t image, +// const char *fromsnapname, +// uint64_t ofs, uint64_t len, +// uint8_t include_parent, uint8_t whole_object, +// int (*cb)(uint64_t, size_t, int, void *), +// void *arg); +func (image *Image) DiffIterate(config DiffIterateConfig) error { + if err := image.validate(imageIsOpen); err != nil { + return err + } + if config.Callback == nil { + return RBDError(C.EINVAL) + } + + var cSnapName *C.char + if config.SnapName != NoSnapshot { + cSnapName = C.CString(config.SnapName) + defer C.free(unsafe.Pointer(cSnapName)) + } + + cbIndex := diffIterateCallbacks.Add(config) + defer diffIterateCallbacks.Remove(cbIndex) + + ret := C.wrap_rbd_diff_iterate2( + image.image, + cSnapName, + C.uint64_t(config.Offset), + C.uint64_t(config.Length), + C.uint8_t(config.IncludeParent), + C.uint8_t(config.WholeObject), + C.callDiffIterateCallback, + C.uintptr_t(cbIndex)) + + return getError(ret) +} + +//export diffIterateCallback +func diffIterateCallback( + offset C.uint64_t, length C.size_t, exists, index C.int) C.int { + + v := diffIterateCallbacks.Lookup(int(index)) + config := v.(DiffIterateConfig) + return C.int(config.Callback( + uint64(offset), uint64(length), int(exists), config.Data)) +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/errors.go b/vendor/github.com/ceph/go-ceph/rbd/errors.go new file mode 100644 index 000000000..0ad766efd --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/errors.go @@ -0,0 +1,62 @@ +package rbd + +/* +#include +*/ +import "C" + +import ( + "errors" + "fmt" + + "github.com/ceph/go-ceph/internal/errutil" +) + +// revive:disable:exported Temporarily live with stuttering + +// RBDError represents an error condition returned from the librbd APIs. +type RBDError int + +// revive:enable:exported + +func (e RBDError) Error() string { + errno, s := errutil.FormatErrno(int(e)) + if s == "" { + return fmt.Sprintf("rbd: ret=%d", errno) + } + return fmt.Sprintf("rbd: ret=%d, %s", errno, s) +} + +func getError(err C.int) error { + if err != 0 { + if err == -C.ENOENT { + return ErrNotFound + } + return RBDError(err) + } + return nil +} + +// Public go errors: + +var ( + // ErrNoIOContext may be returned if an api call requires an IOContext and + // it is not provided. + ErrNoIOContext = errors.New("RBD image does not have an IOContext") + // ErrNoName may be returned if an api call requires a name and it is + // not provided. + ErrNoName = errors.New("RBD image does not have a name") + // ErrSnapshotNoName may be returned if an aip call requires a snapshot + // name and it is not provided. + ErrSnapshotNoName = errors.New("RBD snapshot does not have a name") + // ErrImageNotOpen may be returnened if an api call requires an open image handle and one is not provided. + ErrImageNotOpen = errors.New("RBD image not open") + // ErrNotFound may be returned from an api call when the requested item is + // missing. + ErrNotFound = errors.New("RBD image not found") + + // revive:disable:exported for compatibility with old versions + RbdErrorImageNotOpen = ErrImageNotOpen + RbdErrorNotFound = ErrNotFound + // revive:enable:exported +) diff --git a/vendor/github.com/ceph/go-ceph/rbd/features.go b/vendor/github.com/ceph/go-ceph/rbd/features.go new file mode 100644 index 000000000..c61b5efbe --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/features.go @@ -0,0 +1,176 @@ +package rbd + +// #cgo LDFLAGS: -lrbd +// #include +import "C" + +const ( + // RBD features, bit values + + // FeatureLayering is the representation of RBD_FEATURE_LAYERING from + // librbd + FeatureLayering = uint64(C.RBD_FEATURE_LAYERING) + + // FeatureStripingV2 is the representation of RBD_FEATURE_STRIPINGV2 + // from librbd + FeatureStripingV2 = uint64(C.RBD_FEATURE_STRIPINGV2) + + // FeatureExclusiveLock is the representation of + // RBD_FEATURE_EXCLUSIVE_LOCK from librbd + FeatureExclusiveLock = uint64(C.RBD_FEATURE_EXCLUSIVE_LOCK) + + // FeatureObjectMap is the representation of RBD_FEATURE_OBJECT_MAP + // from librbd + FeatureObjectMap = uint64(C.RBD_FEATURE_OBJECT_MAP) + + // FeatureFastDiff is the representation of RBD_FEATURE_FAST_DIFF from + // librbd + FeatureFastDiff = uint64(C.RBD_FEATURE_FAST_DIFF) + + // FeatureDeepFlatten is the representation of RBD_FEATURE_DEEP_FLATTEN + // from librbd + FeatureDeepFlatten = uint64(C.RBD_FEATURE_DEEP_FLATTEN) + + // FeatureJournaling is the representation of RBD_FEATURE_JOURNALING + // from librbd + FeatureJournaling = uint64(C.RBD_FEATURE_JOURNALING) + + // FeatureDataPool is the representation of RBD_FEATURE_DATA_POOL from + // librbd + FeatureDataPool = uint64(C.RBD_FEATURE_DATA_POOL) + + // RBD features, strings + + // FeatureNameLayering is the representation of + // RBD_FEATURE_NAME_LAYERING from librbd + FeatureNameLayering = C.RBD_FEATURE_NAME_LAYERING + + // FeatureNameStripingV2 is the representation of + // RBD_FEATURE_NAME_STRIPINGV2 from librbd + FeatureNameStripingV2 = C.RBD_FEATURE_NAME_STRIPINGV2 + + // FeatureNameExclusiveLock is the representation of + // RBD_FEATURE_NAME_EXCLUSIVE_LOCK from librbd + FeatureNameExclusiveLock = C.RBD_FEATURE_NAME_EXCLUSIVE_LOCK + + // FeatureNameObjectMap is the representation of + // RBD_FEATURE_NAME_OBJECT_MAP from librbd + FeatureNameObjectMap = C.RBD_FEATURE_NAME_OBJECT_MAP + + // FeatureNameFastDiff is the representation of + // RBD_FEATURE_NAME_FAST_DIFF from librbd + FeatureNameFastDiff = C.RBD_FEATURE_NAME_FAST_DIFF + + // FeatureNameDeepFlatten is the representation of + // RBD_FEATURE_NAME_DEEP_FLATTEN from librbd + FeatureNameDeepFlatten = C.RBD_FEATURE_NAME_DEEP_FLATTEN + + // FeatureNameJournaling is the representation of + // RBD_FEATURE_NAME_JOURNALING from librbd + FeatureNameJournaling = C.RBD_FEATURE_NAME_JOURNALING + + // FeatureNameDataPool is the representation of + // RBD_FEATURE_NAME_DATA_POOL from librbd + FeatureNameDataPool = C.RBD_FEATURE_NAME_DATA_POOL + + // old names for backwards compatibility (unused?) + + // RbdFeatureLayering deprecated alias for FeatureLayering + RbdFeatureLayering = FeatureLayering + // RbdFeatureStripingV2 deprecated alias for FeatureStripingV2 + RbdFeatureStripingV2 = FeatureStripingV2 + // RbdFeatureExclusiveLock deprecated alias for FeatureExclusiveLock + RbdFeatureExclusiveLock = FeatureExclusiveLock + // RbdFeatureObjectMap deprecated alias for FeatureObjectMap + RbdFeatureObjectMap = FeatureObjectMap + // RbdFeatureFastDiff deprecated alias for FeatureFastDiff + RbdFeatureFastDiff = FeatureFastDiff + // RbdFeatureDeepFlatten deprecated alias for FeatureDeepFlatten + RbdFeatureDeepFlatten = FeatureDeepFlatten + // RbdFeatureJournaling deprecated alias for FeatureJournaling + RbdFeatureJournaling = FeatureJournaling + // RbdFeatureDataPool deprecated alias for FeatureDataPool + RbdFeatureDataPool = FeatureDataPool + + // revive:disable:exported Maybe unused + // the following are probably really unused? + RbdFeaturesDefault = uint64(C.RBD_FEATURES_DEFAULT) + RbdFeaturesIncompatible = uint64(C.RBD_FEATURES_INCOMPATIBLE) + RbdFeaturesRwIncompatible = uint64(C.RBD_FEATURES_RW_INCOMPATIBLE) + RbdFeaturesMutable = uint64(C.RBD_FEATURES_MUTABLE) + RbdFeaturesSingleClient = uint64(C.RBD_FEATURES_SINGLE_CLIENT) + // revive:enable:exported +) + +// FeatureSet is a combination of the bit value for multiple featurs. +type FeatureSet uint64 + +var ( + featureNameToBit = map[string]uint64{ + FeatureNameLayering: FeatureLayering, + FeatureNameStripingV2: FeatureStripingV2, + FeatureNameExclusiveLock: FeatureExclusiveLock, + FeatureNameObjectMap: FeatureObjectMap, + FeatureNameFastDiff: FeatureFastDiff, + FeatureNameDeepFlatten: FeatureDeepFlatten, + FeatureNameJournaling: FeatureJournaling, + FeatureNameDataPool: FeatureDataPool, + } +) + +// FeatureSetFromNames returns a FeatureSet built from flag bits corresponding +// to the provided feature names. +func FeatureSetFromNames(names []string) FeatureSet { + var fs uint64 + for _, name := range names { + fs |= featureNameToBit[name] + } + return FeatureSet(fs) +} + +// Names converts all of the enabled feature bits in the FeatureSet to +// a slice of strings corresponding to the names for each feature. +func (fs *FeatureSet) Names() []string { + names := []string{} + + for name, bit := range featureNameToBit { + if (uint64(*fs) & bit) == bit { + names = append(names, name) + } + } + + return names +} + +// GetFeatures returns the features bitmask for the rbd image. +// +// Implements: +// int rbd_get_features(rbd_image_t image, uint64_t *features); +func (image *Image) GetFeatures() (features uint64, err error) { + if err := image.validate(imageIsOpen); err != nil { + return 0, err + } + + if ret := C.rbd_get_features(image.image, (*C.uint64_t)(&features)); ret < 0 { + return 0, RBDError(ret) + } + + return features, nil +} + +// UpdateFeatures updates the features on the Image. +// +// Implements: +// int rbd_update_features(rbd_image_t image, uint64_t features, +// uint8_t enabled); +func (image *Image) UpdateFeatures(features uint64, enabled bool) error { + if image.image == nil { + return RbdErrorImageNotOpen + } + + cEnabled := C.uint8_t(0) + if enabled { + cEnabled = 1 + } + return getError(C.rbd_update_features(image.image, C.uint64_t(features), cEnabled)) +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/features_mimic.go b/vendor/github.com/ceph/go-ceph/rbd/features_mimic.go new file mode 100644 index 000000000..9f6571aa1 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/features_mimic.go @@ -0,0 +1,20 @@ +// +build !luminous + +package rbd + +// #include +import "C" + +const ( + // FeatureOperations is the representation of RBD_FEATURE_OPERATIONS + // from librbd + FeatureOperations = uint64(C.RBD_FEATURE_OPERATIONS) + + // FeatureNameOperations is the representation of + // RBD_FEATURE_NAME_OPERATIONS from librbd + FeatureNameOperations = C.RBD_FEATURE_NAME_OPERATIONS +) + +func init() { + featureNameToBit[FeatureNameOperations] = FeatureOperations +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/features_nautilus.go b/vendor/github.com/ceph/go-ceph/rbd/features_nautilus.go new file mode 100644 index 000000000..ce320c382 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/features_nautilus.go @@ -0,0 +1,20 @@ +// +build !luminous,!mimic + +package rbd + +// #include +import "C" + +const ( + // FeatureMigrating is the representation of RBD_FEATURE_MIGRATING from + // librbd + FeatureMigrating = uint64(C.RBD_FEATURE_MIGRATING) + + // FeatureNameMigrating is the representation of + // RBD_FEATURE_NAME_MIGRATING from librbd + FeatureNameMigrating = C.RBD_FEATURE_NAME_MIGRATING +) + +func init() { + featureNameToBit[FeatureNameMigrating] = FeatureMigrating +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/options.go b/vendor/github.com/ceph/go-ceph/rbd/options.go index 46ece701b..404968ade 100644 --- a/vendor/github.com/ceph/go-ceph/rbd/options.go +++ b/vendor/github.com/ceph/go-ceph/rbd/options.go @@ -12,34 +12,93 @@ import ( const ( // RBD image options. - RbdImageOptionFormat = C.RBD_IMAGE_OPTION_FORMAT - RbdImageOptionFeatures = C.RBD_IMAGE_OPTION_FEATURES - RbdImageOptionOrder = C.RBD_IMAGE_OPTION_ORDER - RbdImageOptionStripeUnit = C.RBD_IMAGE_OPTION_STRIPE_UNIT - RbdImageOptionStripeCount = C.RBD_IMAGE_OPTION_STRIPE_COUNT - RbdImageOptionJournalOrder = C.RBD_IMAGE_OPTION_JOURNAL_ORDER - RbdImageOptionJournalSplayWidth = C.RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH - RbdImageOptionJournalPool = C.RBD_IMAGE_OPTION_JOURNAL_POOL - RbdImageOptionFeaturesSet = C.RBD_IMAGE_OPTION_FEATURES_SET - RbdImageOptionFeaturesClear = C.RBD_IMAGE_OPTION_FEATURES_CLEAR - RbdImageOptionDataPool = C.RBD_IMAGE_OPTION_DATA_POOL + + // ImageOptionFormat is the representation of RBD_IMAGE_OPTION_FORMAT from + // librbd + ImageOptionFormat = C.RBD_IMAGE_OPTION_FORMAT + // ImageOptionFeatures is the representation of RBD_IMAGE_OPTION_FEATURES + // from librbd + ImageOptionFeatures = C.RBD_IMAGE_OPTION_FEATURES + // ImageOptionOrder is the representation of RBD_IMAGE_OPTION_ORDER from + // librbd + ImageOptionOrder = C.RBD_IMAGE_OPTION_ORDER + // ImageOptionStripeUnit is the representation of + // RBD_IMAGE_OPTION_STRIPE_UNIT from librbd + ImageOptionStripeUnit = C.RBD_IMAGE_OPTION_STRIPE_UNIT + // ImageOptionStripeCount is the representation of + // RBD_IMAGE_OPTION_STRIPE_COUNT from librbd + ImageOptionStripeCount = C.RBD_IMAGE_OPTION_STRIPE_COUNT + // ImageOptionJournalOrder is the representation of + // RBD_IMAGE_OPTION_JOURNAL_ORDER from librbd + ImageOptionJournalOrder = C.RBD_IMAGE_OPTION_JOURNAL_ORDER + // ImageOptionJournalSplayWidth is the representation of + // RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH from librbd + ImageOptionJournalSplayWidth = C.RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH + // ImageOptionJournalPool is the representation of + // RBD_IMAGE_OPTION_JOURNAL_POOL from librbd + ImageOptionJournalPool = C.RBD_IMAGE_OPTION_JOURNAL_POOL + // ImageOptionFeaturesSet is the representation of + // RBD_IMAGE_OPTION_FEATURES_SET from librbd + ImageOptionFeaturesSet = C.RBD_IMAGE_OPTION_FEATURES_SET + // ImageOptionFeaturesClear is the representation of + // RBD_IMAGE_OPTION_FEATURES_CLEAR from librbd + ImageOptionFeaturesClear = C.RBD_IMAGE_OPTION_FEATURES_CLEAR + // ImageOptionDataPool is the representation of RBD_IMAGE_OPTION_DATA_POOL + // from librbd + ImageOptionDataPool = C.RBD_IMAGE_OPTION_DATA_POOL + + // RbdImageOptionFormat deprecated alias for ImageOptionFormat + RbdImageOptionFormat = ImageOptionFormat + // RbdImageOptionFeatures deprecated alias for ImageOptionFeatures + RbdImageOptionFeatures = ImageOptionFeatures + // RbdImageOptionOrder deprecated alias for ImageOptionOrder + RbdImageOptionOrder = ImageOptionOrder + // RbdImageOptionStripeUnit deprecated alias for ImageOptionStripeUnit + RbdImageOptionStripeUnit = ImageOptionStripeUnit + // RbdImageOptionStripeCount deprecated alias for ImageOptionStripeCount + RbdImageOptionStripeCount = ImageOptionStripeCount + // RbdImageOptionJournalOrder deprecated alias for ImageOptionJournalOrder + RbdImageOptionJournalOrder = ImageOptionJournalOrder + // RbdImageOptionJournalSplayWidth deprecated alias for + RbdImageOptionJournalSplayWidth = ImageOptionJournalSplayWidth + // RbdImageOptionJournalPool deprecated alias for ImageOptionJournalPool + RbdImageOptionJournalPool = ImageOptionJournalPool + // RbdImageOptionFeaturesSet deprecated alias for ImageOptionFeaturesSet + RbdImageOptionFeaturesSet = ImageOptionFeaturesSet + // RbdImageOptionFeaturesClear deprecated alias for ImageOptionFeaturesClear + RbdImageOptionFeaturesClear = ImageOptionFeaturesClear + // RbdImageOptionDataPool deprecated alias for ImageOptionDataPool + RbdImageOptionDataPool = ImageOptionDataPool + // introduced with Ceph Mimic //RbdImageOptionFlatten = C.RBD_IMAGE_OPTION_FLATTEN ) -type RbdImageOptions struct { +// ImageOptions represents a group of configurable image options. +type ImageOptions struct { options C.rbd_image_options_t } -type RbdImageOption C.int +// ImageOption values are unique keys for configurable options. +type ImageOption C.int + +// revive:disable:exported Deprecated aliases + +// RbdImageOptions deprecated alias for ImageOptions +type RbdImageOptions = ImageOptions + +// RbdImageOption is a deprecated alias for ImageOption +type RbdImageOption = ImageOption + +//revive:enable:exported // NewRbdImageOptions creates a new RbdImageOptions struct. Call // RbdImageOptions.Destroy() to free the resources. // // Implements: // void rbd_image_options_create(rbd_image_options_t* opts) -func NewRbdImageOptions() *RbdImageOptions { - rio := &RbdImageOptions{} +func NewRbdImageOptions() *ImageOptions { + rio := &ImageOptions{} C.rbd_image_options_create(&rio.options) return rio } @@ -48,7 +107,7 @@ func NewRbdImageOptions() *RbdImageOptions { // // Implements: // void rbd_image_options_destroy(rbd_image_options_t opts); -func (rio *RbdImageOptions) Destroy() { +func (rio *ImageOptions) Destroy() { C.rbd_image_options_destroy(rio.options) } @@ -57,7 +116,7 @@ func (rio *RbdImageOptions) Destroy() { // Implements: // int rbd_image_options_set_string(rbd_image_options_t opts, int optname, // const char* optval); -func (rio *RbdImageOptions) SetString(option RbdImageOption, value string) error { +func (rio *ImageOptions) SetString(option ImageOption, value string) error { c_value := C.CString(value) defer C.free(unsafe.Pointer(c_value)) @@ -75,7 +134,7 @@ func (rio *RbdImageOptions) SetString(option RbdImageOption, value string) error // Implements: // int rbd_image_options_get_string(rbd_image_options_t opts, int optname, // char* optval, size_t maxlen); -func (rio *RbdImageOptions) GetString(option RbdImageOption) (string, error) { +func (rio *ImageOptions) GetString(option ImageOption) (string, error) { value := make([]byte, 4096) ret := C.rbd_image_options_get_string(rio.options, C.int(option), @@ -93,7 +152,7 @@ func (rio *RbdImageOptions) GetString(option RbdImageOption) (string, error) { // Implements: // int rbd_image_options_set_uint64(rbd_image_options_t opts, int optname, // const uint64_t optval); -func (rio *RbdImageOptions) SetUint64(option RbdImageOption, value uint64) error { +func (rio *ImageOptions) SetUint64(option ImageOption, value uint64) error { c_value := C.uint64_t(value) ret := C.rbd_image_options_set_uint64(rio.options, C.int(option), c_value) @@ -110,7 +169,7 @@ func (rio *RbdImageOptions) SetUint64(option RbdImageOption, value uint64) error // Implements: // int rbd_image_options_get_uint64(rbd_image_options_t opts, int optname, // uint64_t* optval); -func (rio *RbdImageOptions) GetUint64(option RbdImageOption) (uint64, error) { +func (rio *ImageOptions) GetUint64(option ImageOption) (uint64, error) { var c_value C.uint64_t ret := C.rbd_image_options_get_uint64(rio.options, C.int(option), &c_value) @@ -126,7 +185,7 @@ func (rio *RbdImageOptions) GetUint64(option RbdImageOption) (uint64, error) { // Implements: // int rbd_image_options_is_set(rbd_image_options_t opts, int optname, // bool* is_set); -func (rio *RbdImageOptions) IsSet(option RbdImageOption) (bool, error) { +func (rio *ImageOptions) IsSet(option ImageOption) (bool, error) { var c_set C.bool ret := C.rbd_image_options_is_set(rio.options, C.int(option), &c_set) @@ -141,7 +200,7 @@ func (rio *RbdImageOptions) IsSet(option RbdImageOption) (bool, error) { // // Implements: // int rbd_image_options_unset(rbd_image_options_t opts, int optname) -func (rio *RbdImageOptions) Unset(option RbdImageOption) error { +func (rio *ImageOptions) Unset(option ImageOption) error { ret := C.rbd_image_options_unset(rio.options, C.int(option)) if ret != 0 { return fmt.Errorf("%v, could not unset option %v", getError(ret), option) @@ -154,7 +213,7 @@ func (rio *RbdImageOptions) Unset(option RbdImageOption) error { // // Implements: // void rbd_image_options_clear(rbd_image_options_t opts) -func (rio *RbdImageOptions) Clear() { +func (rio *ImageOptions) Clear() { C.rbd_image_options_clear(rio.options) } @@ -163,7 +222,7 @@ func (rio *RbdImageOptions) Clear() { // // Implements: // int rbd_image_options_is_empty(rbd_image_options_t opts) -func (rio *RbdImageOptions) IsEmpty() bool { +func (rio *ImageOptions) IsEmpty() bool { ret := C.rbd_image_options_is_empty(rio.options) return ret != 0 } diff --git a/vendor/github.com/ceph/go-ceph/rbd/rbd.go b/vendor/github.com/ceph/go-ceph/rbd/rbd.go index ad6bf0755..df5da19da 100644 --- a/vendor/github.com/ceph/go-ceph/rbd/rbd.go +++ b/vendor/github.com/ceph/go-ceph/rbd/rbd.go @@ -8,50 +8,27 @@ package rbd // #include // #include // #include -// #include import "C" import ( "bytes" "errors" - "fmt" "io" "time" "unsafe" - "github.com/ceph/go-ceph/errutil" "github.com/ceph/go-ceph/rados" ) const ( - // RBD features. - RbdFeatureLayering = uint64(C.RBD_FEATURE_LAYERING) - RbdFeatureStripingV2 = uint64(C.RBD_FEATURE_STRIPINGV2) - RbdFeatureExclusiveLock = uint64(C.RBD_FEATURE_EXCLUSIVE_LOCK) - RbdFeatureObjectMap = uint64(C.RBD_FEATURE_OBJECT_MAP) - RbdFeatureFastDiff = uint64(C.RBD_FEATURE_FAST_DIFF) - RbdFeatureDeepFlatten = uint64(C.RBD_FEATURE_DEEP_FLATTEN) - RbdFeatureJournaling = uint64(C.RBD_FEATURE_JOURNALING) - RbdFeatureDataPool = uint64(C.RBD_FEATURE_DATA_POOL) + // Image.Seek() constants: - RbdFeaturesDefault = uint64(C.RBD_FEATURES_DEFAULT) - - // Features that make an image inaccessible for read or write by clients that don't understand - // them. - RbdFeaturesIncompatible = uint64(C.RBD_FEATURES_INCOMPATIBLE) - - // Features that make an image unwritable by clients that don't understand them. - RbdFeaturesRwIncompatible = uint64(C.RBD_FEATURES_RW_INCOMPATIBLE) - - // Features that may be dynamically enabled or disabled. - RbdFeaturesMutable = uint64(C.RBD_FEATURES_MUTABLE) - - // Features that only work when used with a single client using the image for writes. - RbdFeaturesSingleClient = uint64(C.RBD_FEATURES_SINGLE_CLIENT) - - // Image.Seek() constants + // SeekSet is used with Seek to absolutely position the file. SeekSet = int(C.SEEK_SET) + // SeekCur is used with Seek to position the file relatively to the current + // position. SeekCur = int(C.SEEK_CUR) + // SeekEnd is used with Seek to position the file relatively to the end. SeekEnd = int(C.SEEK_END) ) @@ -66,22 +43,7 @@ const ( NoSnapshot = "" ) -// -type RBDError int - -var ( - ErrNoIOContext = errors.New("RBD image does not have an IOContext") - ErrNoName = errors.New("RBD image does not have a name") - ErrSnapshotNoName = errors.New("RBD snapshot does not have a name") - ErrImageNotOpen = errors.New("RBD image not open") - ErrNotFound = errors.New("RBD image not found") - - // retained for compatibility with old versions - RbdErrorImageNotOpen = ErrImageNotOpen - RbdErrorNotFound = ErrNotFound -) - -// +// ImageInfo represents the status information for an image. type ImageInfo struct { Size uint64 Obj_size uint64 @@ -92,21 +54,21 @@ type ImageInfo struct { Parent_name string } -// +// SnapInfo represents the status information for a snapshot. type SnapInfo struct { Id uint64 Size uint64 Name string } -// +// Locker provides info about a client that is locking an image. type Locker struct { Client string Cookie string Addr string } -// +// Image is a handle for an RBD image. type Image struct { io.Reader io.Writer @@ -119,12 +81,6 @@ type Image struct { image C.rbd_image_t } -// -type Snapshot struct { - image *Image - name string -} - // TrashInfo contains information about trashed RBDs. type TrashInfo struct { Id string // Id string, required to remove / restore trashed RBDs. @@ -145,6 +101,11 @@ func split(buf []byte) (values []string) { return values } +// cephIoctx returns a ceph rados_ioctx_t given a go-ceph rados IOContext. +func cephIoctx(radosIoctx *rados.IOContext) C.rados_ioctx_t { + return C.rados_ioctx_t(radosIoctx.Pointer()) +} + // test if a bit is set in the given value func hasBit(value, bit uint32) bool { return (value & bit) == bit @@ -164,38 +125,6 @@ func (image *Image) validate(req uint32) error { return nil } -// validate the attributes listed in the req bitmask, and return an error in -// case the attribute is not set -// Calls snapshot.image.validate(req) to validate the image attributes. -func (snapshot *Snapshot) validate(req uint32) error { - if hasBit(req, snapshotNeedsName) && snapshot.name == "" { - return ErrSnapshotNoName - } else if snapshot.image != nil { - return snapshot.image.validate(req) - } - - return nil -} - -func (e RBDError) Error() string { - errno, s := errutil.FormatErrno(int(e)) - if s == "" { - return fmt.Sprintf("rbd: ret=%d", errno) - } - return fmt.Sprintf("rbd: ret=%d, %s", errno, s) -} - -func getError(err C.int) error { - if err != 0 { - if err == -C.ENOENT { - return ErrNotFound - } - return RBDError(err) - } else { - return nil - } -} - // Version returns the major, minor, and patch level of the librbd library. func Version() (int, int, int) { var c_major, c_minor, c_patch C.int @@ -238,7 +167,7 @@ func Create(ioctx *rados.IOContext, name string, size uint64, order int, defer C.free(unsafe.Pointer(c_name)) - ret = C.rbd_create(C.rados_ioctx_t(ioctx.Pointer()), + ret = C.rbd_create(cephIoctx(ioctx), c_name, C.uint64_t(size), &c_order) default: return nil, errors.New("Wrong number of argument") @@ -268,7 +197,7 @@ func Create2(ioctx *rados.IOContext, name string, size uint64, features uint64, defer C.free(unsafe.Pointer(c_name)) - ret = C.rbd_create2(C.rados_ioctx_t(ioctx.Pointer()), c_name, + ret = C.rbd_create2(cephIoctx(ioctx), c_name, C.uint64_t(size), C.uint64_t(features), &c_order) if ret < 0 { return nil, RBDError(ret) @@ -296,7 +225,7 @@ func Create3(ioctx *rados.IOContext, name string, size uint64, features uint64, defer C.free(unsafe.Pointer(c_name)) - ret = C.rbd_create3(C.rados_ioctx_t(ioctx.Pointer()), c_name, + ret = C.rbd_create3(cephIoctx(ioctx), c_name, C.uint64_t(size), C.uint64_t(features), &c_order, C.uint64_t(stripe_unit), C.uint64_t(stripe_count)) if ret < 0 { @@ -329,9 +258,9 @@ func (image *Image) Clone(snapname string, c_ioctx *rados.IOContext, c_name stri defer C.free(unsafe.Pointer(c_p_snapname)) defer C.free(unsafe.Pointer(c_c_name)) - ret := C.rbd_clone(C.rados_ioctx_t(image.ioctx.Pointer()), + ret := C.rbd_clone(cephIoctx(image.ioctx), c_p_name, c_p_snapname, - C.rados_ioctx_t(c_ioctx.Pointer()), + cephIoctx(c_ioctx), c_c_name, C.uint64_t(features), &c_order) if ret < 0 { return nil, RBDError(ret) @@ -364,7 +293,7 @@ func (image *Image) Trash(delay time.Duration) error { c_name := C.CString(image.name) defer C.free(unsafe.Pointer(c_name)) - return getError(C.rbd_trash_move(C.rados_ioctx_t(image.ioctx.Pointer()), c_name, + return getError(C.rbd_trash_move(cephIoctx(image.ioctx), c_name, C.uint64_t(delay.Seconds()))) } @@ -383,7 +312,7 @@ func (image *Image) Rename(destname string) error { defer C.free(unsafe.Pointer(c_srcname)) defer C.free(unsafe.Pointer(c_destname)) - err := RBDError(C.rbd_rename(C.rados_ioctx_t(image.ioctx.Pointer()), + err := RBDError(C.rbd_rename(cephIoctx(image.ioctx), c_srcname, c_destname)) if err == 0 { image.name = destname @@ -523,22 +452,6 @@ func (image *Image) GetSize() (size uint64, err error) { return size, nil } -// GetFeatures returns the features bitmask for the rbd image. -// -// Implements: -// int rbd_get_features(rbd_image_t image, uint64_t *features); -func (image *Image) GetFeatures() (features uint64, err error) { - if err := image.validate(imageIsOpen); err != nil { - return 0, err - } - - if ret := C.rbd_get_features(image.image, (*C.uint64_t)(&features)); ret < 0 { - return 0, RBDError(ret) - } - - return features, nil -} - // GetStripeUnit returns the stripe-unit value for the rbd image. // // Implements: @@ -605,10 +518,10 @@ func (image *Image) Copy(ioctx *rados.IOContext, destname string) error { defer C.free(unsafe.Pointer(c_destname)) return getError(C.rbd_copy(image.image, - C.rados_ioctx_t(ioctx.Pointer()), c_destname)) + cephIoctx(ioctx), c_destname)) } -// Copy one rbd image to another, using an image handle. +// Copy2 copies one rbd image to another, using an image handle. // // Implements: // int rbd_copy2(rbd_image_t src, rbd_image_t dest); @@ -818,6 +731,7 @@ func (image *Image) Write(data []byte) (n int, err error) { return ret, err } +// Seek updates the internal file position for the current image. func (image *Image) Seek(offset int64, whence int) (int64, error) { switch whence { case SeekSet: @@ -836,7 +750,12 @@ func (image *Image) Seek(offset int64, whence int) (int64, error) { return image.offset, nil } -// int rbd_discard(rbd_image_t image, uint64_t ofs, uint64_t len); +// Discard the supplied range from the image. The supplied range will be read +// as zeros once Discard returns. The discarded range will no longer take up +// space. +// +// Implements: +// int rbd_discard(rbd_image_t image, uint64_t ofs, uint64_t len); func (image *Image) Discard(ofs uint64, length uint64) (int, error) { if err := image.validate(imageIsOpen); err != nil { return 0, err @@ -850,6 +769,7 @@ func (image *Image) Discard(ofs uint64, length uint64) (int, error) { return int(ret), nil } +// ReadAt copies data from the image into the supplied buffer. func (image *Image) ReadAt(data []byte, off int64) (int, error) { if err := image.validate(imageIsOpen); err != nil { return 0, err @@ -876,6 +796,7 @@ func (image *Image) ReadAt(data []byte, off int64) (int, error) { return ret, nil } +// WriteAt copies data from the supplied buffer to the image. func (image *Image) WriteAt(data []byte, off int64) (n int, err error) { if err := image.validate(imageIsOpen); err != nil { return 0, err @@ -895,7 +816,10 @@ func (image *Image) WriteAt(data []byte, off int64) (n int, err error) { return ret, err } -// int rbd_flush(rbd_image_t image); +// Flush all cached writes to storage. +// +// Implements: +// int rbd_flush(rbd_image_t image); func (image *Image) Flush() error { if err := image.validate(imageIsOpen); err != nil { return err @@ -904,8 +828,11 @@ func (image *Image) Flush() error { return getError(C.rbd_flush(image.image)) } -// int rbd_snap_list(rbd_image_t image, rbd_snap_info_t *snaps, int *max_snaps); -// void rbd_snap_list_end(rbd_snap_info_t *snaps); +// GetSnapshotNames returns more than just the names of snapshots +// associated with the rbd image. +// +// Implements: +// int rbd_snap_list(rbd_image_t image, rbd_snap_info_t *snaps, int *max_snaps); func (image *Image) GetSnapshotNames() (snaps []SnapInfo, err error) { if err := image.validate(imageIsOpen); err != nil { return nil, err @@ -934,35 +861,10 @@ func (image *Image) GetSnapshotNames() (snaps []SnapInfo, err error) { return snaps[:len(snaps)-1], nil } -// int rbd_snap_create(rbd_image_t image, const char *snapname); -func (image *Image) CreateSnapshot(snapname string) (*Snapshot, error) { - if err := image.validate(imageIsOpen); err != nil { - return nil, err - } - - c_snapname := C.CString(snapname) - defer C.free(unsafe.Pointer(c_snapname)) - - ret := C.rbd_snap_create(image.image, c_snapname) - if ret < 0 { - return nil, RBDError(ret) - } - - return &Snapshot{ - image: image, - name: snapname, - }, nil -} - +// GetMetadata returns the metadata string associated with the given key. // -func (image *Image) GetSnapshot(snapname string) *Snapshot { - return &Snapshot{ - image: image, - name: snapname, - } -} - -// int rbd_metadata_get(rbd_image_t image, const char *key, char *value, size_t *vallen) +// Implements: +// int rbd_metadata_get(rbd_image_t image, const char *key, char *value, size_t *vallen) func (image *Image) GetMetadata(key string) (string, error) { if err := image.validate(imageIsOpen); err != nil { return "", err @@ -989,7 +891,10 @@ func (image *Image) GetMetadata(key string) (string, error) { return string(value), nil } -// int rbd_metadata_set(rbd_image_t image, const char *key, const char *value) +// SetMetadata updates the metadata string associated with the given key. +// +// Implements: +// int rbd_metadata_set(rbd_image_t image, const char *key, const char *value) func (image *Image) SetMetadata(key string, value string) error { if err := image.validate(imageIsOpen); err != nil { return err @@ -1008,7 +913,10 @@ func (image *Image) SetMetadata(key string, value string) error { return nil } -// int rbd_metadata_remove(rbd_image_t image, const char *key) +// RemoveMetadata clears the metadata associated with the given key. +// +// Implements: +// int rbd_metadata_remove(rbd_image_t image, const char *key) func (image *Image) RemoveMetadata(key string) error { if err := image.validate(imageIsOpen); err != nil { return err @@ -1051,103 +959,20 @@ func (image *Image) GetId() (string, error) { } } -// int rbd_snap_remove(rbd_image_t image, const char *snapname); -func (snapshot *Snapshot) Remove() error { - if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { - return err - } - - c_snapname := C.CString(snapshot.name) - defer C.free(unsafe.Pointer(c_snapname)) - - return getError(C.rbd_snap_remove(snapshot.image.image, c_snapname)) -} - -// int rbd_snap_rollback(rbd_image_t image, const char *snapname); -// int rbd_snap_rollback_with_progress(rbd_image_t image, const char *snapname, -// librbd_progress_fn_t cb, void *cbdata); -func (snapshot *Snapshot) Rollback() error { - if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { - return err - } - - c_snapname := C.CString(snapshot.name) - defer C.free(unsafe.Pointer(c_snapname)) - - return getError(C.rbd_snap_rollback(snapshot.image.image, c_snapname)) -} - -// int rbd_snap_protect(rbd_image_t image, const char *snap_name); -func (snapshot *Snapshot) Protect() error { - if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { - return err - } - - c_snapname := C.CString(snapshot.name) - defer C.free(unsafe.Pointer(c_snapname)) - - return getError(C.rbd_snap_protect(snapshot.image.image, c_snapname)) -} - -// int rbd_snap_unprotect(rbd_image_t image, const char *snap_name); -func (snapshot *Snapshot) Unprotect() error { - if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { - return err - } - - c_snapname := C.CString(snapshot.name) - defer C.free(unsafe.Pointer(c_snapname)) - - return getError(C.rbd_snap_unprotect(snapshot.image.image, c_snapname)) -} - -// int rbd_snap_is_protected(rbd_image_t image, const char *snap_name, -// int *is_protected); -func (snapshot *Snapshot) IsProtected() (bool, error) { - if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { - return false, err - } - - var c_is_protected C.int - - c_snapname := C.CString(snapshot.name) - defer C.free(unsafe.Pointer(c_snapname)) - - ret := C.rbd_snap_is_protected(snapshot.image.image, c_snapname, - &c_is_protected) - if ret < 0 { - return false, RBDError(ret) - } - - return c_is_protected != 0, nil -} - -// int rbd_snap_set(rbd_image_t image, const char *snapname); -func (snapshot *Snapshot) Set() error { - if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { - return err - } - - c_snapname := C.CString(snapshot.name) - defer C.free(unsafe.Pointer(c_snapname)) - - return getError(C.rbd_snap_set(snapshot.image.image, c_snapname)) -} - // GetTrashList returns a slice of TrashInfo structs, containing information about all RBD images // currently residing in the trash. func GetTrashList(ioctx *rados.IOContext) ([]TrashInfo, error) { var num_entries C.size_t // Call rbd_trash_list with nil pointer to get number of trash entries. - if C.rbd_trash_list(C.rados_ioctx_t(ioctx.Pointer()), nil, &num_entries); num_entries == 0 { + if C.rbd_trash_list(cephIoctx(ioctx), nil, &num_entries); num_entries == 0 { return nil, nil } c_entries := make([]C.rbd_trash_image_info_t, num_entries) trashList := make([]TrashInfo, num_entries) - if ret := C.rbd_trash_list(C.rados_ioctx_t(ioctx.Pointer()), &c_entries[0], &num_entries); ret < 0 { + if ret := C.rbd_trash_list(cephIoctx(ioctx), &c_entries[0], &num_entries); ret < 0 { return nil, RBDError(ret) } @@ -1171,7 +996,7 @@ func TrashRemove(ioctx *rados.IOContext, id string, force bool) error { c_id := C.CString(id) defer C.free(unsafe.Pointer(c_id)) - return getError(C.rbd_trash_remove(C.rados_ioctx_t(ioctx.Pointer()), c_id, C.bool(force))) + return getError(C.rbd_trash_remove(cephIoctx(ioctx), c_id, C.bool(force))) } // TrashRestore restores the trashed RBD with the specified id back to the pool from whence it @@ -1182,7 +1007,7 @@ func TrashRestore(ioctx *rados.IOContext, id, name string) error { defer C.free(unsafe.Pointer(c_id)) defer C.free(unsafe.Pointer(c_name)) - return getError(C.rbd_trash_restore(C.rados_ioctx_t(ioctx.Pointer()), c_id, c_name)) + return getError(C.rbd_trash_restore(cephIoctx(ioctx), c_id, c_name)) } // OpenImage will open an existing rbd image by name and snapshot name, @@ -1204,7 +1029,7 @@ func OpenImage(ioctx *rados.IOContext, name, snapName string) (*Image, error) { var cImage C.rbd_image_t ret := C.rbd_open( - C.rados_ioctx_t(ioctx.Pointer()), + cephIoctx(ioctx), cName, &cImage, cSnapName) @@ -1240,7 +1065,7 @@ func OpenImageReadOnly(ioctx *rados.IOContext, name, snapName string) (*Image, e var cImage C.rbd_image_t ret := C.rbd_open_read_only( - C.rados_ioctx_t(ioctx.Pointer()), + cephIoctx(ioctx), cName, &cImage, cSnapName) @@ -1277,7 +1102,7 @@ func OpenImageById(ioctx *rados.IOContext, id, snapName string) (*Image, error) var cImage C.rbd_image_t ret := C.rbd_open_by_id( - C.rados_ioctx_t(ioctx.Pointer()), + cephIoctx(ioctx), cid, &cImage, cSnapName) @@ -1314,7 +1139,7 @@ func OpenImageByIdReadOnly(ioctx *rados.IOContext, id, snapName string) (*Image, var cImage C.rbd_image_t ret := C.rbd_open_by_id_read_only( - C.rados_ioctx_t(ioctx.Pointer()), + cephIoctx(ioctx), cid, &cImage, cSnapName) @@ -1334,7 +1159,7 @@ func OpenImageByIdReadOnly(ioctx *rados.IOContext, id, snapName string) (*Image, // Implements: // int rbd_create4(rados_ioctx_t io, const char *name, uint64_t size, // rbd_image_options_t opts); -func CreateImage(ioctx *rados.IOContext, name string, size uint64, rio *RbdImageOptions) error { +func CreateImage(ioctx *rados.IOContext, name string, size uint64, rio *ImageOptions) error { if rio == nil { return RBDError(C.EINVAL) @@ -1343,7 +1168,7 @@ func CreateImage(ioctx *rados.IOContext, name string, size uint64, rio *RbdImage c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) - ret := C.rbd_create4(C.rados_ioctx_t(ioctx.Pointer()), c_name, + ret := C.rbd_create4(cephIoctx(ioctx), c_name, C.uint64_t(size), C.rbd_image_options_t(rio.options)) return getError(ret) } @@ -1355,7 +1180,7 @@ func CreateImage(ioctx *rados.IOContext, name string, size uint64, rio *RbdImage func RemoveImage(ioctx *rados.IOContext, name string) error { c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) - return getError(C.rbd_remove(C.rados_ioctx_t(ioctx.Pointer()), c_name)) + return getError(C.rbd_remove(cephIoctx(ioctx), c_name)) } // CloneImage creates a clone of the image from the named snapshot in the @@ -1366,7 +1191,7 @@ func RemoveImage(ioctx *rados.IOContext, name string) error { // const char *p_snapname, rados_ioctx_t c_ioctx, // const char *c_name, rbd_image_options_t c_opts); func CloneImage(ioctx *rados.IOContext, parentName, snapName string, - destctx *rados.IOContext, name string, rio *RbdImageOptions) error { + destctx *rados.IOContext, name string, rio *ImageOptions) error { if rio == nil { return RBDError(C.EINVAL) @@ -1380,10 +1205,10 @@ func CloneImage(ioctx *rados.IOContext, parentName, snapName string, defer C.free(unsafe.Pointer(cCloneName)) ret := C.rbd_clone3( - C.rados_ioctx_t(ioctx.Pointer()), + cephIoctx(ioctx), cParentName, cParentSnapName, - C.rados_ioctx_t(destctx.Pointer()), + cephIoctx(destctx), cCloneName, C.rbd_image_options_t(rio.options)) return getError(ret) @@ -1394,7 +1219,7 @@ func CloneImage(ioctx *rados.IOContext, parentName, snapName string, // This function is a convenience wrapper around CloneImage to support cloning // from an existing Image. func CloneFromImage(parent *Image, snapName string, - destctx *rados.IOContext, name string, rio *RbdImageOptions) error { + destctx *rados.IOContext, name string, rio *ImageOptions) error { if err := parent.validate(imageNeedsIOContext); err != nil { return err diff --git a/vendor/github.com/ceph/go-ceph/rbd/rbd_mimic.go b/vendor/github.com/ceph/go-ceph/rbd/rbd_mimic.go index 5e602ece3..523e8068d 100644 --- a/vendor/github.com/ceph/go-ceph/rbd/rbd_mimic.go +++ b/vendor/github.com/ceph/go-ceph/rbd/rbd_mimic.go @@ -23,7 +23,7 @@ func GetImageNames(ioctx *rados.IOContext) (names []string, err error) { buf := make([]byte, 4096) for { size := C.size_t(len(buf)) - ret := C.rbd_list(C.rados_ioctx_t(ioctx.Pointer()), + ret := C.rbd_list(cephIoctx(ioctx), (*C.char)(unsafe.Pointer(&buf[0])), &size) if ret == -C.ERANGE { buf = make([]byte, size) diff --git a/vendor/github.com/ceph/go-ceph/rbd/rbd_nautilus.go b/vendor/github.com/ceph/go-ceph/rbd/rbd_nautilus.go index f722c0a21..95c07e2c3 100644 --- a/vendor/github.com/ceph/go-ceph/rbd/rbd_nautilus.go +++ b/vendor/github.com/ceph/go-ceph/rbd/rbd_nautilus.go @@ -20,7 +20,7 @@ import ( // GetImageNames returns the list of current RBD images. func GetImageNames(ioctx *rados.IOContext) ([]string, error) { size := C.size_t(0) - ret := C.rbd_list2(C.rados_ioctx_t(ioctx.Pointer()), nil, &size) + ret := C.rbd_list2(cephIoctx(ioctx), nil, &size) if ret < 0 && ret != -C.ERANGE { return nil, RBDError(ret) } else if ret > 0 { @@ -31,7 +31,7 @@ func GetImageNames(ioctx *rados.IOContext) ([]string, error) { // expected: ret == -ERANGE, size contains number of image names images := make([]C.rbd_image_spec_t, size) - ret = C.rbd_list2(C.rados_ioctx_t(ioctx.Pointer()), (*C.rbd_image_spec_t)(unsafe.Pointer(&images[0])), &size) + ret = C.rbd_list2(cephIoctx(ioctx), (*C.rbd_image_spec_t)(unsafe.Pointer(&images[0])), &size) if ret < 0 { return nil, RBDError(ret) } diff --git a/vendor/github.com/ceph/go-ceph/rbd/snapshot.go b/vendor/github.com/ceph/go-ceph/rbd/snapshot.go new file mode 100644 index 000000000..0eddc56c7 --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/snapshot.go @@ -0,0 +1,162 @@ +package rbd + +// #cgo LDFLAGS: -lrbd +// #include +// #include +import "C" + +import ( + "unsafe" +) + +// Snapshot represents a snapshot on a particular rbd image. +type Snapshot struct { + image *Image + name string +} + +// CreateSnapshot returns a new Snapshot objects after creating +// a snapshot of the rbd image. +// +// Implements: +// int rbd_snap_create(rbd_image_t image, const char *snapname); +func (image *Image) CreateSnapshot(snapname string) (*Snapshot, error) { + if err := image.validate(imageIsOpen); err != nil { + return nil, err + } + + c_snapname := C.CString(snapname) + defer C.free(unsafe.Pointer(c_snapname)) + + ret := C.rbd_snap_create(image.image, c_snapname) + if ret < 0 { + return nil, RBDError(ret) + } + + return &Snapshot{ + image: image, + name: snapname, + }, nil +} + +// validate the attributes listed in the req bitmask, and return an error in +// case the attribute is not set +// Calls snapshot.image.validate(req) to validate the image attributes. +func (snapshot *Snapshot) validate(req uint32) error { + if hasBit(req, snapshotNeedsName) && snapshot.name == "" { + return ErrSnapshotNoName + } else if snapshot.image != nil { + return snapshot.image.validate(req) + } + + return nil +} + +// GetSnapshot constructs a snapshot object for the image given +// the snap name. It does not validate that this snapshot exists. +func (image *Image) GetSnapshot(snapname string) *Snapshot { + return &Snapshot{ + image: image, + name: snapname, + } +} + +// Remove the snapshot from the connected rbd image. +// +// Implements: +// int rbd_snap_remove(rbd_image_t image, const char *snapname); +func (snapshot *Snapshot) Remove() error { + if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { + return err + } + + c_snapname := C.CString(snapshot.name) + defer C.free(unsafe.Pointer(c_snapname)) + + return getError(C.rbd_snap_remove(snapshot.image.image, c_snapname)) +} + +// Rollback the image to the snapshot. +// +// Implements: +// int rbd_snap_rollback(rbd_image_t image, const char *snapname); +func (snapshot *Snapshot) Rollback() error { + if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { + return err + } + + c_snapname := C.CString(snapshot.name) + defer C.free(unsafe.Pointer(c_snapname)) + + return getError(C.rbd_snap_rollback(snapshot.image.image, c_snapname)) +} + +// Protect a snapshot from unwanted deletion. +// +// Implements: +// int rbd_snap_protect(rbd_image_t image, const char *snap_name); +func (snapshot *Snapshot) Protect() error { + if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { + return err + } + + c_snapname := C.CString(snapshot.name) + defer C.free(unsafe.Pointer(c_snapname)) + + return getError(C.rbd_snap_protect(snapshot.image.image, c_snapname)) +} + +// Unprotect stops protecting the snapshot. +// +// Implements: +// int rbd_snap_unprotect(rbd_image_t image, const char *snap_name); +func (snapshot *Snapshot) Unprotect() error { + if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { + return err + } + + c_snapname := C.CString(snapshot.name) + defer C.free(unsafe.Pointer(c_snapname)) + + return getError(C.rbd_snap_unprotect(snapshot.image.image, c_snapname)) +} + +// IsProtected returns true if the snapshot is currently protected. +// +// Implements: +// int rbd_snap_is_protected(rbd_image_t image, const char *snap_name, +// int *is_protected); +func (snapshot *Snapshot) IsProtected() (bool, error) { + if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { + return false, err + } + + var c_is_protected C.int + + c_snapname := C.CString(snapshot.name) + defer C.free(unsafe.Pointer(c_snapname)) + + ret := C.rbd_snap_is_protected(snapshot.image.image, c_snapname, + &c_is_protected) + if ret < 0 { + return false, RBDError(ret) + } + + return c_is_protected != 0, nil +} + +// Set updates the rbd image (not the Snapshot) such that the snapshot +// is the source of readable data. +// +// Implements: +// int rbd_snap_set(rbd_image_t image, const char *snapname); +func (snapshot *Snapshot) Set() error { + if err := snapshot.validate(snapshotNeedsName | imageIsOpen); err != nil { + return err + } + + c_snapname := C.CString(snapshot.name) + defer C.free(unsafe.Pointer(c_snapname)) + + return getError(C.rbd_snap_set(snapshot.image.image, c_snapname)) +} diff --git a/vendor/github.com/ceph/go-ceph/rbd/watchers_mimic.go b/vendor/github.com/ceph/go-ceph/rbd/watchers_mimic.go new file mode 100644 index 000000000..6f6bfbd2c --- /dev/null +++ b/vendor/github.com/ceph/go-ceph/rbd/watchers_mimic.go @@ -0,0 +1,57 @@ +// +build !luminous +// +// Ceph Mimic is the first version that supports watchers through librbd. + +package rbd + +// #cgo LDFLAGS: -lrbd +// #include +// #include +import "C" + +// ImageWatcher is a representation of the rbd_image_watcher_t from librbd.h +type ImageWatcher struct { + Addr string + Id int64 + Cookie uint64 +} + +// ListWatchers returns the watchers on an RBD image. In case of an error, nil +// and an error are returned. +// +// Note: +// Only supported in Ceph Mimic and newer. +// +// Implements: +// int rbd_watchers_list(rbd_image_t image, +// rbd_image_watcher_t *watchers, size_t *max_watchers) +func (image *Image) ListWatchers() ([]ImageWatcher, error) { + if err := image.validate(imageIsOpen); err != nil { + return nil, err + } + + count := C.ulong(0) + ret := C.rbd_watchers_list(image.image, nil, &count) + if ret != 0 && ret != -C.ERANGE { + return nil, getError(ret) + } + if ret == 0 && count == 0 { + return nil, nil + } + + watchers := make([]C.rbd_image_watcher_t, count) + ret = C.rbd_watchers_list(image.image, &watchers[0], &count) + if ret != 0 && ret != -C.ERANGE { + return nil, getError(ret) + } + defer C.rbd_watchers_list_cleanup(&watchers[0], count) + + imageWatchers := make([]ImageWatcher, len(watchers)) + for i, watcher := range watchers { + imageWatchers[i].Addr = C.GoString(watcher.addr) + imageWatchers[i].Id = int64(watcher.id) + imageWatchers[i].Cookie = uint64(watcher.cookie) + } + + return imageWatchers, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e9a0e4525..edbeb8eb8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2,8 +2,9 @@ github.com/beorn7/perks/quantile # github.com/blang/semver v3.5.0+incompatible github.com/blang/semver -# github.com/ceph/go-ceph v0.2.0 -github.com/ceph/go-ceph/errutil +# github.com/ceph/go-ceph v0.3.0 +github.com/ceph/go-ceph/internal/callbacks +github.com/ceph/go-ceph/internal/errutil github.com/ceph/go-ceph/rados github.com/ceph/go-ceph/rbd # github.com/cespare/xxhash/v2 v2.1.1