downgrade ceph
This commit is contained in:
Generated
+2
-2
@@ -11,14 +11,14 @@
|
|||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:371dbf7f04fe7ddbcf65b88aef026278e21c9a7df810339bbe94abcf830e0627"
|
digest = "1:30f50828e5a6aa9257130334f34425a1bcba4e19b9f531f1da7747fbdc3235be"
|
||||||
name = "github.com/ceph/go-ceph"
|
name = "github.com/ceph/go-ceph"
|
||||||
packages = [
|
packages = [
|
||||||
"rados",
|
"rados",
|
||||||
"rbd",
|
"rbd",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "e32f9f0f2e941422937c0a6c4f0a61b8f0c82995"
|
revision = "bd5bc6d4cb3e3d3441f2ec4e9f89899178edfc71"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:5155f7153c694dc8e2efd74d799a27fd54e65778fa3f0c3e17626df724857db9"
|
digest = "1:5155f7153c694dc8e2efd74d799a27fd54e65778fa3f0c3e17626df724857db9"
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ func (s *ISCSITargetDriver) BindISCSISession(conn *iscsiConnection) error {
|
|||||||
newSess.Target.SessionsRWMutex.Unlock()
|
newSess.Target.SessionsRWMutex.Unlock()
|
||||||
} else {
|
} else {
|
||||||
if existConn != nil {
|
if existConn != nil {
|
||||||
log.Infof("Connection Reinstatement initiator name:%v,target name:%v,ISID:0x%x,CID:%v",
|
log.Infof("Connection Reinstatement initiator name:%v,target name:%v,ISID:0x%x",
|
||||||
conn.loginParam.initiator, conn.loginParam.target, conn.loginParam.isid)
|
conn.loginParam.initiator, conn.loginParam.target, conn.loginParam.isid)
|
||||||
existConn.ReInstatement(conn)
|
existConn.ReInstatement(conn)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-24
@@ -7,7 +7,6 @@ import "C"
|
|||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
import "bytes"
|
import "bytes"
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// ClusterStat represents Ceph cluster statistics.
|
// ClusterStat represents Ceph cluster statistics.
|
||||||
type ClusterStat struct {
|
type ClusterStat struct {
|
||||||
@@ -19,8 +18,7 @@ type ClusterStat struct {
|
|||||||
|
|
||||||
// Conn is a connection handle to a Ceph cluster.
|
// Conn is a connection handle to a Ceph cluster.
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
cluster C.rados_t
|
cluster C.rados_t
|
||||||
connected bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PingMonitor sends a ping to a monitor and returns the reply.
|
// PingMonitor sends a ping to a monitor and returns the reply.
|
||||||
@@ -46,18 +44,15 @@ func (c *Conn) PingMonitor(id string) (string, error) {
|
|||||||
// if any.
|
// if any.
|
||||||
func (c *Conn) Connect() error {
|
func (c *Conn) Connect() error {
|
||||||
ret := C.rados_connect(c.cluster)
|
ret := C.rados_connect(c.cluster)
|
||||||
if ret != 0 {
|
if ret == 0 {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
return RadosError(int(ret))
|
return RadosError(int(ret))
|
||||||
}
|
}
|
||||||
c.connected = true
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown disconnects from the cluster.
|
// Shutdown disconnects from the cluster.
|
||||||
func (c *Conn) Shutdown() {
|
func (c *Conn) Shutdown() {
|
||||||
if err := c.ensure_connected(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
C.rados_shutdown(c.cluster)
|
C.rados_shutdown(c.cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,20 +162,9 @@ func (c *Conn) WaitForLatestOSDMap() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) ensure_connected() error {
|
|
||||||
if c.connected {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return RadosError(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetClusterStat returns statistics about the cluster associated with the
|
// GetClusterStat returns statistics about the cluster associated with the
|
||||||
// connection.
|
// connection.
|
||||||
func (c *Conn) GetClusterStats() (stat ClusterStat, err error) {
|
func (c *Conn) GetClusterStats() (stat ClusterStat, err error) {
|
||||||
if err := c.ensure_connected(); err != nil {
|
|
||||||
return ClusterStat{}, err
|
|
||||||
}
|
|
||||||
c_stat := C.struct_rados_cluster_stat_t{}
|
c_stat := C.struct_rados_cluster_stat_t{}
|
||||||
ret := C.rados_cluster_stat(c.cluster, &c_stat)
|
ret := C.rados_cluster_stat(c.cluster, &c_stat)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
@@ -266,10 +250,6 @@ func (c *Conn) MakePool(name string) error {
|
|||||||
|
|
||||||
// DeletePool deletes a pool and all the data inside the pool.
|
// DeletePool deletes a pool and all the data inside the pool.
|
||||||
func (c *Conn) DeletePool(name string) error {
|
func (c *Conn) DeletePool(name string) error {
|
||||||
if err := c.ensure_connected(); err != nil {
|
|
||||||
fmt.Println("NOT CONNECTED WHOOPS")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c_name := C.CString(name)
|
c_name := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(c_name))
|
defer C.free(unsafe.Pointer(c_name))
|
||||||
ret := int(C.rados_pool_delete(c.cluster, c_name))
|
ret := int(C.rados_pool_delete(c.cluster, c_name))
|
||||||
|
|||||||
+23
-41
@@ -99,13 +99,8 @@ func (ioctx *IOContext) Write(oid string, data []byte, offset uint64) error {
|
|||||||
c_oid := C.CString(oid)
|
c_oid := C.CString(oid)
|
||||||
defer C.free(unsafe.Pointer(c_oid))
|
defer C.free(unsafe.Pointer(c_oid))
|
||||||
|
|
||||||
dataPointer := unsafe.Pointer(nil)
|
|
||||||
if len(data) > 0 {
|
|
||||||
dataPointer = unsafe.Pointer(&data[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := C.rados_write(ioctx.ioctx, c_oid,
|
ret := C.rados_write(ioctx.ioctx, c_oid,
|
||||||
(*C.char)(dataPointer),
|
(*C.char)(unsafe.Pointer(&data[0])),
|
||||||
(C.size_t)(len(data)),
|
(C.size_t)(len(data)),
|
||||||
(C.uint64_t)(offset))
|
(C.uint64_t)(offset))
|
||||||
|
|
||||||
@@ -141,18 +136,17 @@ func (ioctx *IOContext) Append(oid string, data []byte) error {
|
|||||||
// Read reads up to len(data) bytes from the object with key oid starting at byte
|
// Read reads up to len(data) bytes from the object with key oid starting at byte
|
||||||
// offset offset. It returns the number of bytes read and an error, if any.
|
// offset offset. It returns the number of bytes read and an error, if any.
|
||||||
func (ioctx *IOContext) Read(oid string, data []byte, offset uint64) (int, error) {
|
func (ioctx *IOContext) Read(oid string, data []byte, offset uint64) (int, error) {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
c_oid := C.CString(oid)
|
c_oid := C.CString(oid)
|
||||||
defer C.free(unsafe.Pointer(c_oid))
|
defer C.free(unsafe.Pointer(c_oid))
|
||||||
|
|
||||||
var buf *C.char
|
|
||||||
if len(data) > 0 {
|
|
||||||
buf = (*C.char)(unsafe.Pointer(&data[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := C.rados_read(
|
ret := C.rados_read(
|
||||||
ioctx.ioctx,
|
ioctx.ioctx,
|
||||||
c_oid,
|
c_oid,
|
||||||
buf,
|
(*C.char)(unsafe.Pointer(&data[0])),
|
||||||
(C.size_t)(len(data)),
|
(C.size_t)(len(data)),
|
||||||
(C.uint64_t)(offset))
|
(C.uint64_t)(offset))
|
||||||
|
|
||||||
@@ -220,7 +214,7 @@ func (ioctx *IOContext) GetPoolName() (name string, err error) {
|
|||||||
for {
|
for {
|
||||||
ret := C.rados_ioctx_get_pool_name(ioctx.ioctx,
|
ret := C.rados_ioctx_get_pool_name(ioctx.ioctx,
|
||||||
(*C.char)(unsafe.Pointer(&buf[0])), C.unsigned(len(buf)))
|
(*C.char)(unsafe.Pointer(&buf[0])), C.unsigned(len(buf)))
|
||||||
if ret == -C.ERANGE {
|
if ret == -34 { // FIXME
|
||||||
buf = make([]byte, len(buf)*2)
|
buf = make([]byte, len(buf)*2)
|
||||||
continue
|
continue
|
||||||
} else if ret < 0 {
|
} else if ret < 0 {
|
||||||
@@ -237,9 +231,7 @@ type ObjectListFunc func(oid string)
|
|||||||
|
|
||||||
// ListObjects lists all of the objects in the pool associated with the I/O
|
// ListObjects lists all of the objects in the pool associated with the I/O
|
||||||
// context, and called the provided listFn function for each object, passing
|
// context, and called the provided listFn function for each object, passing
|
||||||
// to the function the name of the object. Call SetNamespace with
|
// to the function the name of the object.
|
||||||
// RadosAllNamespaces before calling this function to return objects from all
|
|
||||||
// namespaces
|
|
||||||
func (ioctx *IOContext) ListObjects(listFn ObjectListFunc) error {
|
func (ioctx *IOContext) ListObjects(listFn ObjectListFunc) error {
|
||||||
var ctx C.rados_list_ctx_t
|
var ctx C.rados_list_ctx_t
|
||||||
ret := C.rados_nobjects_list_open(ioctx.ioctx, &ctx)
|
ret := C.rados_nobjects_list_open(ioctx.ioctx, &ctx)
|
||||||
@@ -251,13 +243,15 @@ func (ioctx *IOContext) ListObjects(listFn ObjectListFunc) error {
|
|||||||
for {
|
for {
|
||||||
var c_entry *C.char
|
var c_entry *C.char
|
||||||
ret := C.rados_nobjects_list_next(ctx, &c_entry, nil, nil)
|
ret := C.rados_nobjects_list_next(ctx, &c_entry, nil, nil)
|
||||||
if ret == -C.ENOENT {
|
if ret == -2 { // FIXME
|
||||||
return nil
|
return nil
|
||||||
} else if ret < 0 {
|
} else if ret < 0 {
|
||||||
return GetRadosError(int(ret))
|
return GetRadosError(int(ret))
|
||||||
}
|
}
|
||||||
listFn(C.GoString(c_entry))
|
listFn(C.GoString(c_entry))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panic("invalid state")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns the size of the object and its last modification time
|
// Stat returns the size of the object and its last modification time
|
||||||
@@ -450,13 +444,12 @@ func (ioctx *IOContext) ListOmapValues(oid string, startAfter string, filterPref
|
|||||||
|
|
||||||
var c_iter C.rados_omap_iter_t
|
var c_iter C.rados_omap_iter_t
|
||||||
var c_prval C.int
|
var c_prval C.int
|
||||||
C.rados_read_op_omap_get_vals2(
|
C.rados_read_op_omap_get_vals(
|
||||||
op,
|
op,
|
||||||
c_start_after,
|
c_start_after,
|
||||||
c_filter_prefix,
|
c_filter_prefix,
|
||||||
c_max_return,
|
c_max_return,
|
||||||
&c_iter,
|
&c_iter,
|
||||||
nil,
|
|
||||||
&c_prval,
|
&c_prval,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -587,10 +580,9 @@ func (ioctx *IOContext) CleanOmap(oid string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Iter struct {
|
type Iter struct {
|
||||||
ctx C.rados_list_ctx_t
|
ctx C.rados_list_ctx_t
|
||||||
err error
|
err error
|
||||||
entry string
|
entry string
|
||||||
namespace string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IterToken uint32
|
type IterToken uint32
|
||||||
@@ -629,13 +621,11 @@ func (iter *Iter) Seek(token IterToken) {
|
|||||||
//
|
//
|
||||||
func (iter *Iter) Next() bool {
|
func (iter *Iter) Next() bool {
|
||||||
var c_entry *C.char
|
var c_entry *C.char
|
||||||
var c_namespace *C.char
|
if cerr := C.rados_nobjects_list_next(iter.ctx, &c_entry, nil, nil); cerr < 0 {
|
||||||
if cerr := C.rados_nobjects_list_next(iter.ctx, &c_entry, nil, &c_namespace); cerr < 0 {
|
|
||||||
iter.err = GetRadosError(int(cerr))
|
iter.err = GetRadosError(int(cerr))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
iter.entry = C.GoString(c_entry)
|
iter.entry = C.GoString(c_entry)
|
||||||
iter.namespace = C.GoString(c_namespace)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,14 +637,6 @@ func (iter *Iter) Value() string {
|
|||||||
return iter.entry
|
return iter.entry
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the namespace associated with the current value of the iterator (object name), after a successful call to Next.
|
|
||||||
func (iter *Iter) Namespace() string {
|
|
||||||
if iter.err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return iter.namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks whether the iterator has encountered an error.
|
// Checks whether the iterator has encountered an error.
|
||||||
func (iter *Iter) Err() error {
|
func (iter *Iter) Err() error {
|
||||||
if iter.err == RadosErrorNotFound {
|
if iter.err == RadosErrorNotFound {
|
||||||
@@ -708,9 +690,9 @@ func (ioctx *IOContext) LockExclusive(oid, name, cookie, desc string, duration t
|
|||||||
switch ret {
|
switch ret {
|
||||||
case 0:
|
case 0:
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.EBUSY:
|
case -16: // EBUSY
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.EEXIST:
|
case -17: // EEXIST
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
default:
|
default:
|
||||||
return int(ret), RadosError(int(ret))
|
return int(ret), RadosError(int(ret))
|
||||||
@@ -759,9 +741,9 @@ func (ioctx *IOContext) LockShared(oid, name, cookie, tag, desc string, duration
|
|||||||
switch ret {
|
switch ret {
|
||||||
case 0:
|
case 0:
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.EBUSY:
|
case -16: // EBUSY
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.EEXIST:
|
case -17: // EEXIST
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
default:
|
default:
|
||||||
return int(ret), RadosError(int(ret))
|
return int(ret), RadosError(int(ret))
|
||||||
@@ -790,7 +772,7 @@ func (ioctx *IOContext) Unlock(oid, name, cookie string) (int, error) {
|
|||||||
switch ret {
|
switch ret {
|
||||||
case 0:
|
case 0:
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.ENOENT:
|
case -2: // -ENOENT
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
default:
|
default:
|
||||||
return int(ret), RadosError(int(ret))
|
return int(ret), RadosError(int(ret))
|
||||||
@@ -880,9 +862,9 @@ func (ioctx *IOContext) BreakLock(oid, name, client, cookie string) (int, error)
|
|||||||
switch ret {
|
switch ret {
|
||||||
case 0:
|
case 0:
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.ENOENT:
|
case -2: // -ENOENT
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
case -C.EINVAL: // -EINVAL
|
case -22: // -EINVAL
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
default:
|
default:
|
||||||
return int(ret), RadosError(int(ret))
|
return int(ret), RadosError(int(ret))
|
||||||
|
|||||||
+15
-17
@@ -17,8 +17,6 @@ func (e RadosError) Error() string {
|
|||||||
return fmt.Sprintf("rados: %s", C.GoString(C.strerror(C.int(-e))))
|
return fmt.Sprintf("rados: %s", C.GoString(C.strerror(C.int(-e))))
|
||||||
}
|
}
|
||||||
|
|
||||||
var RadosAllNamespaces = C.LIBRADOS_ALL_NSPACES
|
|
||||||
|
|
||||||
var RadosErrorNotFound = RadosError(-C.ENOENT)
|
var RadosErrorNotFound = RadosError(-C.ENOENT)
|
||||||
var RadosErrorPermissionDenied = RadosError(-C.EPERM)
|
var RadosErrorPermissionDenied = RadosError(-C.EPERM)
|
||||||
|
|
||||||
@@ -37,13 +35,11 @@ func Version() (int, int, int) {
|
|||||||
return int(c_major), int(c_minor), int(c_patch)
|
return int(c_major), int(c_minor), int(c_patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeConn() *Conn {
|
// NewConn creates a new connection object. It returns the connection and an
|
||||||
return &Conn{connected: false}
|
// error, if any.
|
||||||
}
|
func NewConn() (*Conn, error) {
|
||||||
|
conn := &Conn{}
|
||||||
func newConn(user *C.char) (*Conn, error) {
|
ret := C.rados_create(&conn.cluster, nil)
|
||||||
conn := makeConn()
|
|
||||||
ret := C.rados_create(&conn.cluster, user)
|
|
||||||
|
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
@@ -52,18 +48,20 @@ func newConn(user *C.char) (*Conn, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConn creates a new connection object. It returns the connection and an
|
|
||||||
// error, if any.
|
|
||||||
func NewConn() (*Conn, error) {
|
|
||||||
return newConn(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConnWithUser creates a new connection object with a custom username.
|
// NewConnWithUser creates a new connection object with a custom username.
|
||||||
// It returns the connection and an error, if any.
|
// It returns the connection and an error, if any.
|
||||||
func NewConnWithUser(user string) (*Conn, error) {
|
func NewConnWithUser(user string) (*Conn, error) {
|
||||||
c_user := C.CString(user)
|
c_user := C.CString(user)
|
||||||
defer C.free(unsafe.Pointer(c_user))
|
defer C.free(unsafe.Pointer(c_user))
|
||||||
return newConn(c_user)
|
|
||||||
|
conn := &Conn{}
|
||||||
|
ret := C.rados_create(&conn.cluster, c_user)
|
||||||
|
|
||||||
|
if ret == 0 {
|
||||||
|
return conn, nil
|
||||||
|
} else {
|
||||||
|
return nil, RadosError(int(ret))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConnWithClusterAndUser creates a new connection object for a specific cluster and username.
|
// NewConnWithClusterAndUser creates a new connection object for a specific cluster and username.
|
||||||
@@ -75,7 +73,7 @@ func NewConnWithClusterAndUser(clusterName string, userName string) (*Conn, erro
|
|||||||
c_name := C.CString(userName)
|
c_name := C.CString(userName)
|
||||||
defer C.free(unsafe.Pointer(c_name))
|
defer C.free(unsafe.Pointer(c_name))
|
||||||
|
|
||||||
conn := makeConn()
|
conn := &Conn{}
|
||||||
ret := C.rados_create2(&conn.cluster, c_cluster_name, c_name, 0)
|
ret := C.rados_create2(&conn.cluster, c_cluster_name, c_name, 0)
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
|
|||||||
+84
-201
@@ -5,7 +5,6 @@ package rbd
|
|||||||
// #include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
// #include <rados/librados.h>
|
// #include <rados/librados.h>
|
||||||
// #include <rbd/librbd.h>
|
// #include <rbd/librbd.h>
|
||||||
// #include <rbd/features.h>
|
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -14,44 +13,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ceph/go-ceph/rados"
|
"github.com/ceph/go-ceph/rados"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// RBD features.
|
|
||||||
RbdFeatureLayering = C.RBD_FEATURE_LAYERING
|
|
||||||
RbdFeatureStripingV2 = C.RBD_FEATURE_STRIPINGV2
|
|
||||||
RbdFeatureExclusiveLock = C.RBD_FEATURE_EXCLUSIVE_LOCK
|
|
||||||
RbdFeatureObjectMap = C.RBD_FEATURE_OBJECT_MAP
|
|
||||||
RbdFeatureFastDiff = C.RBD_FEATURE_FAST_DIFF
|
|
||||||
RbdFeatureDeepFlatten = C.RBD_FEATURE_DEEP_FLATTEN
|
|
||||||
RbdFeatureJournaling = C.RBD_FEATURE_JOURNALING
|
|
||||||
RbdFeatureDataPool = C.RBD_FEATURE_DATA_POOL
|
|
||||||
|
|
||||||
RbdFeaturesDefault = C.RBD_FEATURES_DEFAULT
|
|
||||||
|
|
||||||
// Features that make an image inaccessible for read or write by clients that don't understand
|
|
||||||
// them.
|
|
||||||
RbdFeaturesIncompatible = C.RBD_FEATURES_INCOMPATIBLE
|
|
||||||
|
|
||||||
// Features that make an image unwritable by clients that don't understand them.
|
|
||||||
RbdFeaturesRwIncompatible = C.RBD_FEATURES_RW_INCOMPATIBLE
|
|
||||||
|
|
||||||
// Features that may be dynamically enabled or disabled.
|
|
||||||
RbdFeaturesMutable = C.RBD_FEATURES_MUTABLE
|
|
||||||
|
|
||||||
// Features that only work when used with a single client using the image for writes.
|
|
||||||
RbdFeaturesSingleClient = C.RBD_FEATURES_SINGLE_CLIENT
|
|
||||||
)
|
|
||||||
|
|
||||||
//
|
//
|
||||||
type RBDError int
|
type RBDError int
|
||||||
|
|
||||||
var (
|
var RbdErrorImageNotOpen = errors.New("RBD image not open")
|
||||||
RbdErrorImageNotOpen = errors.New("RBD image not open")
|
var RbdErrorNotFound = errors.New("RBD image not found")
|
||||||
RbdErrorNotFound = errors.New("RBD image not found")
|
|
||||||
)
|
//Rdb feature
|
||||||
|
var RbdFeatureLayering = uint64(1 << 0)
|
||||||
|
var RbdFeatureStripingV2 = uint64(1 << 1)
|
||||||
|
|
||||||
//
|
//
|
||||||
type ImageInfo struct {
|
type ImageInfo struct {
|
||||||
@@ -97,14 +70,6 @@ type Snapshot struct {
|
|||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrashInfo contains information about trashed RBDs.
|
|
||||||
type TrashInfo struct {
|
|
||||||
Id string // Id string, required to remove / restore trashed RBDs.
|
|
||||||
Name string // Original name of trashed RBD.
|
|
||||||
DeletionTime time.Time // Date / time at which the RBD was moved to the trash.
|
|
||||||
DefermentEndTime time.Time // Date / time after which the trashed RBD may be permanently deleted.
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
func split(buf []byte) (values []string) {
|
func split(buf []byte) (values []string) {
|
||||||
tmp := bytes.Split(buf[:len(buf)-1], []byte{0})
|
tmp := bytes.Split(buf[:len(buf)-1], []byte{0})
|
||||||
@@ -148,7 +113,7 @@ func GetImageNames(ioctx *rados.IOContext) (names []string, err error) {
|
|||||||
size := C.size_t(len(buf))
|
size := C.size_t(len(buf))
|
||||||
ret := C.rbd_list(C.rados_ioctx_t(ioctx.Pointer()),
|
ret := C.rbd_list(C.rados_ioctx_t(ioctx.Pointer()),
|
||||||
(*C.char)(unsafe.Pointer(&buf[0])), &size)
|
(*C.char)(unsafe.Pointer(&buf[0])), &size)
|
||||||
if ret == -C.ERANGE {
|
if ret == -34 { // FIXME
|
||||||
buf = make([]byte, size)
|
buf = make([]byte, size)
|
||||||
continue
|
continue
|
||||||
} else if ret < 0 {
|
} else if ret < 0 {
|
||||||
@@ -182,14 +147,12 @@ func GetImage(ioctx *rados.IOContext, name string) *Image {
|
|||||||
func Create(ioctx *rados.IOContext, name string, size uint64, order int,
|
func Create(ioctx *rados.IOContext, name string, size uint64, order int,
|
||||||
args ...uint64) (image *Image, err error) {
|
args ...uint64) (image *Image, err error) {
|
||||||
var ret C.int
|
var ret C.int
|
||||||
|
var c_order C.int = C.int(order)
|
||||||
c_order := C.int(order)
|
var c_name *C.char = C.CString(name)
|
||||||
c_name := C.CString(name)
|
|
||||||
|
|
||||||
defer C.free(unsafe.Pointer(c_name))
|
defer C.free(unsafe.Pointer(c_name))
|
||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 3:
|
case 2:
|
||||||
ret = C.rbd_create3(C.rados_ioctx_t(ioctx.Pointer()),
|
ret = C.rbd_create3(C.rados_ioctx_t(ioctx.Pointer()),
|
||||||
c_name, C.uint64_t(size),
|
c_name, C.uint64_t(size),
|
||||||
C.uint64_t(args[0]), &c_order,
|
C.uint64_t(args[0]), &c_order,
|
||||||
@@ -206,7 +169,7 @@ func Create(ioctx *rados.IOContext, name string, size uint64, order int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, RBDError(ret)
|
return nil, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Image{
|
return &Image{
|
||||||
@@ -223,11 +186,10 @@ func Create(ioctx *rados.IOContext, name string, size uint64, order int,
|
|||||||
// const char *c_name, uint64_t features, int *c_order,
|
// const char *c_name, uint64_t features, int *c_order,
|
||||||
// uint64_t stripe_unit, int stripe_count);
|
// uint64_t stripe_unit, int stripe_count);
|
||||||
func (image *Image) Clone(snapname string, c_ioctx *rados.IOContext, c_name string, features uint64, order int) (*Image, error) {
|
func (image *Image) Clone(snapname string, c_ioctx *rados.IOContext, c_name string, features uint64, order int) (*Image, error) {
|
||||||
c_order := C.int(order)
|
var c_order C.int = C.int(order)
|
||||||
c_p_name := C.CString(image.name)
|
var c_p_name *C.char = C.CString(image.name)
|
||||||
c_p_snapname := C.CString(snapname)
|
var c_p_snapname *C.char = C.CString(snapname)
|
||||||
c_c_name := C.CString(c_name)
|
var c_c_name *C.char = C.CString(c_name)
|
||||||
|
|
||||||
defer C.free(unsafe.Pointer(c_p_name))
|
defer C.free(unsafe.Pointer(c_p_name))
|
||||||
defer C.free(unsafe.Pointer(c_p_snapname))
|
defer C.free(unsafe.Pointer(c_p_snapname))
|
||||||
defer C.free(unsafe.Pointer(c_c_name))
|
defer C.free(unsafe.Pointer(c_c_name))
|
||||||
@@ -237,7 +199,7 @@ func (image *Image) Clone(snapname string, c_ioctx *rados.IOContext, c_name stri
|
|||||||
C.rados_ioctx_t(c_ioctx.Pointer()),
|
C.rados_ioctx_t(c_ioctx.Pointer()),
|
||||||
c_c_name, C.uint64_t(features), &c_order)
|
c_c_name, C.uint64_t(features), &c_order)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, RBDError(ret)
|
return nil, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Image{
|
return &Image{
|
||||||
@@ -250,29 +212,17 @@ func (image *Image) Clone(snapname string, c_ioctx *rados.IOContext, c_name stri
|
|||||||
// int rbd_remove_with_progress(rados_ioctx_t io, const char *name,
|
// int rbd_remove_with_progress(rados_ioctx_t io, const char *name,
|
||||||
// librbd_progress_fn_t cb, void *cbdata);
|
// librbd_progress_fn_t cb, void *cbdata);
|
||||||
func (image *Image) Remove() error {
|
func (image *Image) Remove() error {
|
||||||
c_name := C.CString(image.name)
|
var c_name *C.char = C.CString(image.name)
|
||||||
defer C.free(unsafe.Pointer(c_name))
|
defer C.free(unsafe.Pointer(c_name))
|
||||||
return GetError(C.rbd_remove(C.rados_ioctx_t(image.ioctx.Pointer()), c_name))
|
return GetError(C.rbd_remove(C.rados_ioctx_t(image.ioctx.Pointer()), c_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trash will move an image into the RBD trash, where it will be protected (i.e., salvageable) for
|
|
||||||
// at least the specified delay.
|
|
||||||
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,
|
|
||||||
C.uint64_t(delay.Seconds())))
|
|
||||||
}
|
|
||||||
|
|
||||||
// int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname, const char *destname);
|
// int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname, const char *destname);
|
||||||
func (image *Image) Rename(destname string) error {
|
func (image *Image) Rename(destname string) error {
|
||||||
c_srcname := C.CString(image.name)
|
var c_srcname *C.char = C.CString(image.name)
|
||||||
c_destname := C.CString(destname)
|
var c_destname *C.char = C.CString(destname)
|
||||||
|
|
||||||
defer C.free(unsafe.Pointer(c_srcname))
|
defer C.free(unsafe.Pointer(c_srcname))
|
||||||
defer C.free(unsafe.Pointer(c_destname))
|
defer C.free(unsafe.Pointer(c_destname))
|
||||||
|
|
||||||
err := RBDError(C.rbd_rename(C.rados_ioctx_t(image.ioctx.Pointer()),
|
err := RBDError(C.rbd_rename(C.rados_ioctx_t(image.ioctx.Pointer()),
|
||||||
c_srcname, c_destname))
|
c_srcname, c_destname))
|
||||||
if err == 0 {
|
if err == 0 {
|
||||||
@@ -287,11 +237,10 @@ func (image *Image) Rename(destname string) error {
|
|||||||
// const char *snap_name);
|
// const char *snap_name);
|
||||||
func (image *Image) Open(args ...interface{}) error {
|
func (image *Image) Open(args ...interface{}) error {
|
||||||
var c_image C.rbd_image_t
|
var c_image C.rbd_image_t
|
||||||
|
var c_name *C.char = C.CString(image.name)
|
||||||
var c_snap_name *C.char
|
var c_snap_name *C.char
|
||||||
var ret C.int
|
var ret C.int
|
||||||
var read_only bool
|
var read_only bool = false
|
||||||
|
|
||||||
c_name := C.CString(image.name)
|
|
||||||
|
|
||||||
defer C.free(unsafe.Pointer(c_name))
|
defer C.free(unsafe.Pointer(c_name))
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
@@ -327,10 +276,10 @@ func (image *Image) Close() error {
|
|||||||
return RbdErrorImageNotOpen
|
return RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret := C.rbd_close(image.image); ret != 0 {
|
ret := C.rbd_close(image.image)
|
||||||
|
if ret != 0 {
|
||||||
return RBDError(ret)
|
return RBDError(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
image.image = nil
|
image.image = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -351,9 +300,10 @@ func (image *Image) Stat() (info *ImageInfo, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var c_stat C.rbd_image_info_t
|
var c_stat C.rbd_image_info_t
|
||||||
|
ret := C.rbd_stat(image.image,
|
||||||
if ret := C.rbd_stat(image.image, &c_stat, C.size_t(unsafe.Sizeof(info))); ret < 0 {
|
&c_stat, C.size_t(unsafe.Sizeof(info)))
|
||||||
return info, RBDError(ret)
|
if ret < 0 {
|
||||||
|
return info, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ImageInfo{
|
return &ImageInfo{
|
||||||
@@ -376,7 +326,7 @@ func (image *Image) IsOldFormat() (old_format bool, err error) {
|
|||||||
ret := C.rbd_get_old_format(image.image,
|
ret := C.rbd_get_old_format(image.image,
|
||||||
&c_old_format)
|
&c_old_format)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return false, RBDError(ret)
|
return false, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c_old_format != 0, nil
|
return c_old_format != 0, nil
|
||||||
@@ -388,8 +338,10 @@ func (image *Image) GetSize() (size uint64, err error) {
|
|||||||
return 0, RbdErrorImageNotOpen
|
return 0, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret := C.rbd_get_size(image.image, (*C.uint64_t)(&size)); ret < 0 {
|
ret := C.rbd_get_size(image.image,
|
||||||
return 0, RBDError(ret)
|
(*C.uint64_t)(&size))
|
||||||
|
if ret < 0 {
|
||||||
|
return 0, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return size, nil
|
return size, nil
|
||||||
@@ -401,8 +353,10 @@ func (image *Image) GetFeatures() (features uint64, err error) {
|
|||||||
return 0, RbdErrorImageNotOpen
|
return 0, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret := C.rbd_get_features(image.image, (*C.uint64_t)(&features)); ret < 0 {
|
ret := C.rbd_get_features(image.image,
|
||||||
return 0, RBDError(ret)
|
(*C.uint64_t)(&features))
|
||||||
|
if ret < 0 {
|
||||||
|
return 0, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return features, nil
|
return features, nil
|
||||||
@@ -414,8 +368,9 @@ func (image *Image) GetStripeUnit() (stripe_unit uint64, err error) {
|
|||||||
return 0, RbdErrorImageNotOpen
|
return 0, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret := C.rbd_get_stripe_unit(image.image, (*C.uint64_t)(&stripe_unit)); ret < 0 {
|
ret := C.rbd_get_stripe_unit(image.image, (*C.uint64_t)(&stripe_unit))
|
||||||
return 0, RBDError(ret)
|
if ret < 0 {
|
||||||
|
return 0, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return stripe_unit, nil
|
return stripe_unit, nil
|
||||||
@@ -427,8 +382,9 @@ func (image *Image) GetStripeCount() (stripe_count uint64, err error) {
|
|||||||
return 0, RbdErrorImageNotOpen
|
return 0, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret := C.rbd_get_stripe_count(image.image, (*C.uint64_t)(&stripe_count)); ret < 0 {
|
ret := C.rbd_get_stripe_count(image.image, (*C.uint64_t)(&stripe_count))
|
||||||
return 0, RBDError(ret)
|
if ret < 0 {
|
||||||
|
return 0, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return stripe_count, nil
|
return stripe_count, nil
|
||||||
@@ -440,8 +396,9 @@ func (image *Image) GetOverlap() (overlap uint64, err error) {
|
|||||||
return 0, RbdErrorImageNotOpen
|
return 0, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret := C.rbd_get_overlap(image.image, (*C.uint64_t)(&overlap)); ret < 0 {
|
ret := C.rbd_get_overlap(image.image, (*C.uint64_t)(&overlap))
|
||||||
return overlap, RBDError(ret)
|
if ret < 0 {
|
||||||
|
return overlap, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return overlap, nil
|
return overlap, nil
|
||||||
@@ -462,7 +419,7 @@ func (image *Image) Copy(args ...interface{}) error {
|
|||||||
case rados.IOContext:
|
case rados.IOContext:
|
||||||
switch t2 := args[1].(type) {
|
switch t2 := args[1].(type) {
|
||||||
case string:
|
case string:
|
||||||
c_destname := C.CString(t2)
|
var c_destname *C.char = C.CString(t2)
|
||||||
defer C.free(unsafe.Pointer(c_destname))
|
defer C.free(unsafe.Pointer(c_destname))
|
||||||
return RBDError(C.rbd_copy(image.image,
|
return RBDError(C.rbd_copy(image.image,
|
||||||
C.rados_ioctx_t(t.Pointer()),
|
C.rados_ioctx_t(t.Pointer()),
|
||||||
@@ -475,9 +432,11 @@ func (image *Image) Copy(args ...interface{}) error {
|
|||||||
if dest.image == nil {
|
if dest.image == nil {
|
||||||
return errors.New(fmt.Sprintf("RBD image %s is not open", dest.name))
|
return errors.New(fmt.Sprintf("RBD image %s is not open", dest.name))
|
||||||
}
|
}
|
||||||
return GetError(C.rbd_copy2(image.image, dest.image))
|
return GetError(C.rbd_copy2(image.image,
|
||||||
|
dest.image))
|
||||||
default:
|
default:
|
||||||
return errors.New("Must specify either destination pool or destination image")
|
return errors.New("Must specify either destination pool " +
|
||||||
|
"or destination image")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,7 +465,7 @@ func (image *Image) ListChildren() (pools []string, images []string, err error)
|
|||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
if ret < 0 && ret != -C.ERANGE {
|
if ret < 0 && ret != -C.ERANGE {
|
||||||
return nil, nil, RBDError(ret)
|
return nil, nil, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
pools_buf := make([]byte, c_pools_len)
|
pools_buf := make([]byte, c_pools_len)
|
||||||
@@ -518,7 +477,7 @@ func (image *Image) ListChildren() (pools []string, images []string, err error)
|
|||||||
(*C.char)(unsafe.Pointer(&images_buf[0])),
|
(*C.char)(unsafe.Pointer(&images_buf[0])),
|
||||||
&c_images_len)
|
&c_images_len)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, nil, RBDError(ret)
|
return nil, nil, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp := bytes.Split(pools_buf[:c_pools_len-1], []byte{0})
|
tmp := bytes.Split(pools_buf[:c_pools_len-1], []byte{0})
|
||||||
@@ -559,32 +518,32 @@ func (image *Image) ListLockers() (tag string, lockers []Locker, err error) {
|
|||||||
nil, (*C.size_t)(&c_clients_len),
|
nil, (*C.size_t)(&c_clients_len),
|
||||||
nil, (*C.size_t)(&c_cookies_len),
|
nil, (*C.size_t)(&c_cookies_len),
|
||||||
nil, (*C.size_t)(&c_addrs_len))
|
nil, (*C.size_t)(&c_addrs_len))
|
||||||
|
|
||||||
// no locker held on rbd image when either c_clients_len,
|
// no locker held on rbd image when either c_clients_len,
|
||||||
// c_cookies_len or c_addrs_len is *0*, so just quickly returned
|
// c_cookies_len or c_addrs_len is *0*, so just quickly returned
|
||||||
if int(c_clients_len) == 0 || int(c_cookies_len) == 0 ||
|
if int(c_clients_len) == 0 || int(c_cookies_len) == 0 ||
|
||||||
int(c_addrs_len) == 0 {
|
int(c_addrs_len) ==0 {
|
||||||
lockers = make([]Locker, 0)
|
lockers = make([]Locker, 0)
|
||||||
return "", lockers, nil
|
return "", lockers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_buf := make([]byte, c_tag_len)
|
tag_buf := make([]byte, c_tag_len)
|
||||||
clients_buf := make([]byte, c_clients_len)
|
clients_buf := make([]byte, c_clients_len)
|
||||||
cookies_buf := make([]byte, c_cookies_len)
|
cookies_buf := make([]byte, c_cookies_len)
|
||||||
addrs_buf := make([]byte, c_addrs_len)
|
addrs_buf := make([]byte, c_addrs_len)
|
||||||
|
|
||||||
c_locker_cnt = C.rbd_list_lockers(image.image, &c_exclusive,
|
c_locker_cnt = C.rbd_list_lockers(image.image, &c_exclusive,
|
||||||
(*C.char)(unsafe.Pointer(&tag_buf[0])), (*C.size_t)(&c_tag_len),
|
(*C.char)(unsafe.Pointer(&tag_buf[0])), (*C.size_t)(&c_tag_len),
|
||||||
(*C.char)(unsafe.Pointer(&clients_buf[0])), (*C.size_t)(&c_clients_len),
|
(*C.char)(unsafe.Pointer(&clients_buf[0])), (*C.size_t)(&c_clients_len),
|
||||||
(*C.char)(unsafe.Pointer(&cookies_buf[0])), (*C.size_t)(&c_cookies_len),
|
(*C.char)(unsafe.Pointer(&cookies_buf[0])), (*C.size_t)(&c_cookies_len),
|
||||||
(*C.char)(unsafe.Pointer(&addrs_buf[0])), (*C.size_t)(&c_addrs_len))
|
(*C.char)(unsafe.Pointer(&addrs_buf[0])), (*C.size_t)(&c_addrs_len))
|
||||||
|
|
||||||
// rbd_list_lockers returns negative value for errors
|
// rbd_list_lockers returns negative value for errors
|
||||||
// and *0* means no locker held on rbd image.
|
// and *0* means no locker held on rbd image.
|
||||||
// but *0* is unexpected here because first rbd_list_lockers already
|
// but *0* is unexpected here because first rbd_list_lockers already
|
||||||
// dealt with no locker case
|
// dealt with no locker case
|
||||||
if int(c_locker_cnt) <= 0 {
|
if int(c_locker_cnt) <= 0 {
|
||||||
return "", nil, RBDError(c_locker_cnt)
|
return "", nil, RBDError(int(c_locker_cnt))
|
||||||
}
|
}
|
||||||
|
|
||||||
clients := split(clients_buf)
|
clients := split(clients_buf)
|
||||||
@@ -607,7 +566,7 @@ func (image *Image) LockExclusive(cookie string) error {
|
|||||||
return RbdErrorImageNotOpen
|
return RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
c_cookie := C.CString(cookie)
|
var c_cookie *C.char = C.CString(cookie)
|
||||||
defer C.free(unsafe.Pointer(c_cookie))
|
defer C.free(unsafe.Pointer(c_cookie))
|
||||||
|
|
||||||
return GetError(C.rbd_lock_exclusive(image.image, c_cookie))
|
return GetError(C.rbd_lock_exclusive(image.image, c_cookie))
|
||||||
@@ -619,8 +578,8 @@ func (image *Image) LockShared(cookie string, tag string) error {
|
|||||||
return RbdErrorImageNotOpen
|
return RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
c_cookie := C.CString(cookie)
|
var c_cookie *C.char = C.CString(cookie)
|
||||||
c_tag := C.CString(tag)
|
var c_tag *C.char = C.CString(tag)
|
||||||
defer C.free(unsafe.Pointer(c_cookie))
|
defer C.free(unsafe.Pointer(c_cookie))
|
||||||
defer C.free(unsafe.Pointer(c_tag))
|
defer C.free(unsafe.Pointer(c_tag))
|
||||||
|
|
||||||
@@ -633,7 +592,7 @@ func (image *Image) Unlock(cookie string) error {
|
|||||||
return RbdErrorImageNotOpen
|
return RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
c_cookie := C.CString(cookie)
|
var c_cookie *C.char = C.CString(cookie)
|
||||||
defer C.free(unsafe.Pointer(c_cookie))
|
defer C.free(unsafe.Pointer(c_cookie))
|
||||||
|
|
||||||
return GetError(C.rbd_unlock(image.image, c_cookie))
|
return GetError(C.rbd_unlock(image.image, c_cookie))
|
||||||
@@ -645,8 +604,8 @@ func (image *Image) BreakLock(client string, cookie string) error {
|
|||||||
return RbdErrorImageNotOpen
|
return RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
c_client := C.CString(client)
|
var c_client *C.char = C.CString(client)
|
||||||
c_cookie := C.CString(cookie)
|
var c_cookie *C.char = C.CString(cookie)
|
||||||
defer C.free(unsafe.Pointer(c_client))
|
defer C.free(unsafe.Pointer(c_client))
|
||||||
defer C.free(unsafe.Pointer(c_cookie))
|
defer C.free(unsafe.Pointer(c_cookie))
|
||||||
|
|
||||||
@@ -699,7 +658,7 @@ func (image *Image) Write(data []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ret != len(data) {
|
if ret != len(data) {
|
||||||
err = RBDError(-C.EPERM)
|
err = RBDError(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
@@ -768,7 +727,7 @@ func (image *Image) WriteAt(data []byte, off int64) (n int, err error) {
|
|||||||
C.size_t(len(data)), (*C.char)(unsafe.Pointer(&data[0]))))
|
C.size_t(len(data)), (*C.char)(unsafe.Pointer(&data[0]))))
|
||||||
|
|
||||||
if ret != len(data) {
|
if ret != len(data) {
|
||||||
err = RBDError(-C.EPERM)
|
err = RBDError(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
@@ -786,7 +745,7 @@ func (image *Image) GetSnapshotNames() (snaps []SnapInfo, err error) {
|
|||||||
return nil, RbdErrorImageNotOpen
|
return nil, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
var c_max_snaps C.int
|
var c_max_snaps C.int = 0
|
||||||
|
|
||||||
ret := C.rbd_snap_list(image.image, nil, &c_max_snaps)
|
ret := C.rbd_snap_list(image.image, nil, &c_max_snaps)
|
||||||
|
|
||||||
@@ -796,7 +755,7 @@ func (image *Image) GetSnapshotNames() (snaps []SnapInfo, err error) {
|
|||||||
ret = C.rbd_snap_list(image.image,
|
ret = C.rbd_snap_list(image.image,
|
||||||
&c_snaps[0], &c_max_snaps)
|
&c_snaps[0], &c_max_snaps)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, RBDError(ret)
|
return nil, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range c_snaps {
|
for i, s := range c_snaps {
|
||||||
@@ -815,12 +774,12 @@ func (image *Image) CreateSnapshot(snapname string) (*Snapshot, error) {
|
|||||||
return nil, RbdErrorImageNotOpen
|
return nil, RbdErrorImageNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
c_snapname := C.CString(snapname)
|
var c_snapname *C.char = C.CString(snapname)
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
ret := C.rbd_snap_create(image.image, c_snapname)
|
ret := C.rbd_snap_create(image.image, c_snapname)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, RBDError(ret)
|
return nil, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Snapshot{
|
return &Snapshot{
|
||||||
@@ -852,17 +811,13 @@ func (image *Image) GetParentInfo(p_pool, p_name, p_snapname []byte) error {
|
|||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return RBDError(ret)
|
return RBDError(int(ret))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// int rbd_snap_remove(rbd_image_t image, const char *snapname);
|
// int rbd_snap_remove(rbd_image_t image, const char *snapname);
|
||||||
func (snapshot *Snapshot) Remove() error {
|
func (snapshot *Snapshot) Remove() error {
|
||||||
if snapshot.image.image == nil {
|
var c_snapname *C.char = C.CString(snapshot.name)
|
||||||
return RbdErrorImageNotOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
c_snapname := C.CString(snapshot.name)
|
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
return GetError(C.rbd_snap_remove(snapshot.image.image, c_snapname))
|
return GetError(C.rbd_snap_remove(snapshot.image.image, c_snapname))
|
||||||
@@ -872,11 +827,7 @@ func (snapshot *Snapshot) Remove() error {
|
|||||||
// int rbd_snap_rollback_with_progress(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);
|
// librbd_progress_fn_t cb, void *cbdata);
|
||||||
func (snapshot *Snapshot) Rollback() error {
|
func (snapshot *Snapshot) Rollback() error {
|
||||||
if snapshot.image.image == nil {
|
var c_snapname *C.char = C.CString(snapshot.name)
|
||||||
return RbdErrorImageNotOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
c_snapname := C.CString(snapshot.name)
|
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
return GetError(C.rbd_snap_rollback(snapshot.image.image, c_snapname))
|
return GetError(C.rbd_snap_rollback(snapshot.image.image, c_snapname))
|
||||||
@@ -884,11 +835,7 @@ func (snapshot *Snapshot) Rollback() error {
|
|||||||
|
|
||||||
// int rbd_snap_protect(rbd_image_t image, const char *snap_name);
|
// int rbd_snap_protect(rbd_image_t image, const char *snap_name);
|
||||||
func (snapshot *Snapshot) Protect() error {
|
func (snapshot *Snapshot) Protect() error {
|
||||||
if snapshot.image.image == nil {
|
var c_snapname *C.char = C.CString(snapshot.name)
|
||||||
return RbdErrorImageNotOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
c_snapname := C.CString(snapshot.name)
|
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
return GetError(C.rbd_snap_protect(snapshot.image.image, c_snapname))
|
return GetError(C.rbd_snap_protect(snapshot.image.image, c_snapname))
|
||||||
@@ -896,11 +843,7 @@ func (snapshot *Snapshot) Protect() error {
|
|||||||
|
|
||||||
// int rbd_snap_unprotect(rbd_image_t image, const char *snap_name);
|
// int rbd_snap_unprotect(rbd_image_t image, const char *snap_name);
|
||||||
func (snapshot *Snapshot) Unprotect() error {
|
func (snapshot *Snapshot) Unprotect() error {
|
||||||
if snapshot.image.image == nil {
|
var c_snapname *C.char = C.CString(snapshot.name)
|
||||||
return RbdErrorImageNotOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
c_snapname := C.CString(snapshot.name)
|
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
return GetError(C.rbd_snap_unprotect(snapshot.image.image, c_snapname))
|
return GetError(C.rbd_snap_unprotect(snapshot.image.image, c_snapname))
|
||||||
@@ -909,19 +852,14 @@ func (snapshot *Snapshot) Unprotect() error {
|
|||||||
// int rbd_snap_is_protected(rbd_image_t image, const char *snap_name,
|
// int rbd_snap_is_protected(rbd_image_t image, const char *snap_name,
|
||||||
// int *is_protected);
|
// int *is_protected);
|
||||||
func (snapshot *Snapshot) IsProtected() (bool, error) {
|
func (snapshot *Snapshot) IsProtected() (bool, error) {
|
||||||
if snapshot.image.image == nil {
|
|
||||||
return false, RbdErrorImageNotOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
var c_is_protected C.int
|
var c_is_protected C.int
|
||||||
|
var c_snapname *C.char = C.CString(snapshot.name)
|
||||||
c_snapname := C.CString(snapshot.name)
|
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
ret := C.rbd_snap_is_protected(snapshot.image.image, c_snapname,
|
ret := C.rbd_snap_is_protected(snapshot.image.image, c_snapname,
|
||||||
&c_is_protected)
|
&c_is_protected)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return false, RBDError(ret)
|
return false, RBDError(int(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c_is_protected != 0, nil
|
return c_is_protected != 0, nil
|
||||||
@@ -929,63 +867,8 @@ func (snapshot *Snapshot) IsProtected() (bool, error) {
|
|||||||
|
|
||||||
// int rbd_snap_set(rbd_image_t image, const char *snapname);
|
// int rbd_snap_set(rbd_image_t image, const char *snapname);
|
||||||
func (snapshot *Snapshot) Set() error {
|
func (snapshot *Snapshot) Set() error {
|
||||||
if snapshot.image.image == nil {
|
var c_snapname *C.char = C.CString(snapshot.name)
|
||||||
return RbdErrorImageNotOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
c_snapname := C.CString(snapshot.name)
|
|
||||||
defer C.free(unsafe.Pointer(c_snapname))
|
defer C.free(unsafe.Pointer(c_snapname))
|
||||||
|
|
||||||
return GetError(C.rbd_snap_set(snapshot.image.image, 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 {
|
|
||||||
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 {
|
|
||||||
return nil, RBDError(ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, ti := range c_entries {
|
|
||||||
trashList[i] = TrashInfo{
|
|
||||||
Id: C.GoString(ti.id),
|
|
||||||
Name: C.GoString(ti.name),
|
|
||||||
DeletionTime: time.Unix(int64(ti.deletion_time), 0),
|
|
||||||
DefermentEndTime: time.Unix(int64(ti.deferment_end_time), 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free rbd_trash_image_info_t pointers
|
|
||||||
C.rbd_trash_list_cleanup(&c_entries[0], num_entries)
|
|
||||||
|
|
||||||
return trashList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrashRemove permanently deletes the trashed RBD with the specified id.
|
|
||||||
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)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrashRestore restores the trashed RBD with the specified id back to the pool from whence it
|
|
||||||
// came, with the specified new name.
|
|
||||||
func TrashRestore(ioctx *rados.IOContext, id, name string) error {
|
|
||||||
c_id := C.CString(id)
|
|
||||||
c_name := C.CString(name)
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user