update more code to use the retry lib.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
Signed-off-by: Sven Anderson <sven@redhat.com>
This commit is contained in:
Sven Anderson 2020-04-16 22:58:36 +02:00 committed by John Mulligan
parent e8da761769
commit 6072f41bd6
3 changed files with 65 additions and 54 deletions

View File

@ -15,23 +15,29 @@ import (
"bytes"
"unsafe"
"github.com/ceph/go-ceph/internal/retry"
"github.com/ceph/go-ceph/rados"
)
// GetImageNames returns the list of current RBD images.
func GetImageNames(ioctx *rados.IOContext) (names []string, err error) {
buf := make([]byte, 4096)
for {
size := C.size_t(len(buf))
var (
buf []byte
csize C.size_t
)
// from 4KiB to 32KiB
retry.WithSizes(4096, 1<<15, func(size int) retry.Hint {
csize = C.size_t(size)
buf = make([]byte, csize)
ret := C.rbd_list(cephIoctx(ioctx),
(*C.char)(unsafe.Pointer(&buf[0])), &size)
if ret == -C.ERANGE {
buf = make([]byte, size)
continue
} else if ret < 0 {
return nil, RBDError(ret)
(*C.char)(unsafe.Pointer(&buf[0])), &csize)
err = getErrorIfNegative(ret)
return retry.Size(int(csize)).If(err == errRange)
})
if err != nil {
return nil, err
}
tmp := bytes.Split(buf[:size-1], []byte{0})
tmp := bytes.Split(buf[:csize-1], []byte{0})
for _, s := range tmp {
if len(s) > 0 {
name := C.GoString((*C.char)(unsafe.Pointer(&s[0])))
@ -40,4 +46,3 @@ func GetImageNames(ioctx *rados.IOContext) (names []string, err error) {
}
return names, nil
}
}

View File

@ -11,8 +11,9 @@ package rbd
import "C"
import (
"fmt"
"unsafe"
"github.com/ceph/go-ceph/internal/retry"
)
// GetParentInfo looks for the parent of the image and stores the pool, name
@ -76,27 +77,28 @@ func (image *Image) ListChildren() (pools []string, images []string, err error)
return nil, nil, err
}
size := C.size_t(0)
ret := C.rbd_list_children3(image.image, nil, &size)
if ret < 0 && ret != -C.ERANGE {
return nil, nil, RBDError(ret)
} else if ret > 0 {
return nil, nil, fmt.Errorf("rbd_list_children3() returned %d, expected 0", ret)
} else if ret == 0 && size == 0 {
return nil, nil, nil
var (
csize C.size_t
children []C.rbd_linked_image_spec_t
)
retry.WithSizes(16, 4096, func(size int) retry.Hint {
csize = C.size_t(size)
children = make([]C.rbd_linked_image_spec_t, csize)
ret := C.rbd_list_children3(
image.image,
(*C.rbd_linked_image_spec_t)(unsafe.Pointer(&children[0])),
&csize)
err = getErrorIfNegative(ret)
return retry.Size(int(csize)).If(err == errRange)
})
if err != nil {
return nil, nil, err
}
defer C.rbd_linked_image_spec_list_cleanup((*C.rbd_linked_image_spec_t)(unsafe.Pointer(&children[0])), csize)
// expected: ret == -ERANGE, size contains number of image names
children := make([]C.rbd_linked_image_spec_t, size)
ret = C.rbd_list_children3(image.image, (*C.rbd_linked_image_spec_t)(unsafe.Pointer(&children[0])), &size)
if ret < 0 {
return nil, nil, RBDError(ret)
}
defer C.rbd_linked_image_spec_list_cleanup((*C.rbd_linked_image_spec_t)(unsafe.Pointer(&children[0])), size)
pools = make([]string, size)
images = make([]string, size)
for i, child := range children {
pools = make([]string, csize)
images = make([]string, csize)
for i, child := range children[:csize] {
pools[i] = C.GoString(child.pool_name)
images[i] = C.GoString(child.image_name)
}

View File

@ -9,6 +9,10 @@ package rbd
// #include <rbd/librbd.h>
import "C"
import (
"github.com/ceph/go-ceph/internal/retry"
)
// ImageWatcher is a representation of the rbd_image_watcher_t from librbd.h
type ImageWatcher struct {
Addr string
@ -30,28 +34,28 @@ func (image *Image) ListWatchers() ([]ImageWatcher, error) {
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)
var (
err error
count C.size_t
watchers []C.rbd_image_watcher_t
)
retry.WithSizes(16, 4096, func(size int) retry.Hint {
count = C.size_t(size)
watchers = make([]C.rbd_image_watcher_t, count)
ret := C.rbd_watchers_list(image.image, &watchers[0], &count)
err = getErrorIfNegative(ret)
return retry.Size(int(count)).If(err == errRange)
})
if err != nil {
return nil, err
}
defer C.rbd_watchers_list_cleanup(&watchers[0], count)
imageWatchers := make([]ImageWatcher, len(watchers))
for i, watcher := range watchers {
imageWatchers := make([]ImageWatcher, count)
for i, watcher := range watchers[:count] {
imageWatchers[i].Addr = C.GoString(watcher.addr)
imageWatchers[i].Id = int64(watcher.id)
imageWatchers[i].Cookie = uint64(watcher.cookie)
}
return imageWatchers, nil
}