diff --git a/rbd/group_snap.go b/rbd/group_snap.go index ad32f5e..a698368 100644 --- a/rbd/group_snap.go +++ b/rbd/group_snap.go @@ -130,3 +130,20 @@ func GroupSnapList(ioctx *rados.IOContext, group string) ([]GroupSnapInfo, error cSize) return snaps, getError(ret) } + +// GroupSnapRollback will roll back the images in the group to that of the +// given snapshot. +// +// Implements: +// int rbd_group_snap_rollback(rados_ioctx_t group_p, +// const char *group_name, +// const char *snap_name); +func GroupSnapRollback(ioctx *rados.IOContext, group, snap string) error { + cGroupName := C.CString(group) + defer C.free(unsafe.Pointer(cGroupName)) + cSnapName := C.CString(snap) + defer C.free(unsafe.Pointer(cSnapName)) + + ret := C.rbd_group_snap_rollback(cephIoctx(ioctx), cGroupName, cSnapName) + return getError(ret) +} diff --git a/rbd/group_snap_test.go b/rbd/group_snap_test.go index 7e0d26e..b7107bd 100644 --- a/rbd/group_snap_test.go +++ b/rbd/group_snap_test.go @@ -104,6 +104,56 @@ func TestGroupSnapshots(t *testing.T) { assert.NoError(t, err) assert.Len(t, gsl, 0) }) + t.Run("groupSnapRollback", func(t *testing.T) { + img, err := OpenImage(ioctx, name1, NoSnapshot) + assert.NoError(t, err) + _, err = img.WriteAt([]byte("HELLO WORLD"), 0) + assert.NoError(t, err) + err = img.Close() + assert.NoError(t, err) + + snapname := "snap1" + err = GroupSnapCreate(ioctx, gname, snapname) + assert.NoError(t, err) + + img, err = OpenImage(ioctx, name1, NoSnapshot) + assert.NoError(t, err) + _, err = img.WriteAt([]byte("GOODBYE WORLD"), 0) + assert.NoError(t, err) + err = img.Close() + assert.NoError(t, err) + + img, err = OpenImage(ioctx, name2, NoSnapshot) + assert.NoError(t, err) + _, err = img.WriteAt([]byte("2222222222222"), 0) + assert.NoError(t, err) + err = img.Close() + assert.NoError(t, err) + + err = GroupSnapRollback(ioctx, gname, snapname) + assert.NoError(t, err) + + b := make([]byte, 8) + img, err = OpenImage(ioctx, name1, NoSnapshot) + assert.NoError(t, err) + _, err = img.ReadAt(b, 0) + assert.NoError(t, err) + err = img.Close() + assert.NoError(t, err) + assert.Equal(t, []byte("HELLO WO"), b) + + img, err = OpenImage(ioctx, name2, NoSnapshot) + assert.NoError(t, err) + _, err = img.ReadAt(b, 0) + assert.NoError(t, err) + err = img.Close() + assert.NoError(t, err) + assert.Equal(t, []byte("\x00\x00\x00\x00\x00\x00\x00\x00"), b) + + err = GroupSnapRemove(ioctx, gname, snapname) + assert.NoError(t, err) + }) + }) t.Run("invalidIOContext", func(t *testing.T) { assert.Panics(t, func() { GroupSnapCreate(nil, gname, "foo") @@ -117,5 +167,8 @@ func TestGroupSnapshots(t *testing.T) { assert.Panics(t, func() { GroupSnapList(nil, gname) }) + assert.Panics(t, func() { + GroupSnapRollback(nil, gname, "foo") + }) }) }