Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement wrappers around rbd_trash_* functions #66

Merged
merged 3 commits into from
Sep 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions rbd/rbd.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"fmt"
"github.com/ceph/go-ceph/rados"
"io"
"time"
"unsafe"
)

Expand Down Expand Up @@ -96,6 +97,14 @@ type Snapshot struct {
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) {
tmp := bytes.Split(buf[:len(buf)-1], []byte{0})
Expand Down Expand Up @@ -243,6 +252,16 @@ func (image *Image) Remove() error {
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);
func (image *Image) Rename(destname string) error {
var c_srcname *C.char = C.CString(image.name)
Expand Down Expand Up @@ -922,3 +941,54 @@ func (snapshot *Snapshot) Set() error {

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))
}
43 changes: 43 additions & 0 deletions rbd/rbd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os/exec"
"sort"
"testing"
"time"
)

//Rdb feature
Expand Down Expand Up @@ -316,3 +317,45 @@ func TestNotFound(t *testing.T) {
conn.DeletePool(poolname)
conn.Shutdown()
}

func TestTrashImage(t *testing.T) {
conn, _ := rados.NewConn()
conn.ReadDefaultConfigFile()
conn.Connect()

poolname := GetUUID()
err := conn.MakePool(poolname)
assert.NoError(t, err)

ioctx, err := conn.OpenIOContext(poolname)
assert.NoError(t, err)

name := GetUUID()
image, err := rbd.Create(ioctx, name, 1<<22, 22)
assert.NoError(t, err)

err = image.Trash(time.Hour)
assert.NoError(t, err)

trashList, err := rbd.GetTrashList(ioctx)
assert.NoError(t, err)
assert.Equal(t, len(trashList), 1, "trashList length equal")

err = rbd.TrashRestore(ioctx, trashList[0].Id, name+"_restored")
assert.NoError(t, err)

image2 := rbd.GetImage(ioctx, name+"_restored")
err = image2.Trash(time.Hour)
assert.NoError(t, err)

trashList, err = rbd.GetTrashList(ioctx)
assert.NoError(t, err)
assert.Equal(t, len(trashList), 1, "trashList length equal")

err = rbd.TrashRemove(ioctx, trashList[0].Id, true)
assert.NoError(t, err)

ioctx.Destroy()
conn.DeletePool(poolname)
conn.Shutdown()
}