From b68bd88243cce59544b89a0ab1bf55527639a952 Mon Sep 17 00:00:00 2001 From: Zhi Zhang Date: Fri, 20 May 2016 17:26:29 +0800 Subject: [PATCH] Fix rbd list lockers crashing Signed-off-by: Zhi Zhang --- rbd/rbd.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/rbd/rbd.go b/rbd/rbd.go index 3e9b57a..5ce87a1 100644 --- a/rbd/rbd.go +++ b/rbd/rbd.go @@ -508,30 +508,47 @@ func (image *Image) ListLockers() (tag string, lockers []Locker, err error) { var c_exclusive C.int var c_tag_len, c_clients_len, c_cookies_len, c_addrs_len C.size_t + var c_locker_cnt C.ssize_t C.rbd_list_lockers(image.image, &c_exclusive, nil, (*C.size_t)(&c_tag_len), nil, (*C.size_t)(&c_clients_len), nil, (*C.size_t)(&c_cookies_len), nil, (*C.size_t)(&c_addrs_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 + if int(c_clients_len) == 0 || int(c_cookies_len) == 0 || + int(c_addrs_len) ==0 { + lockers = make([]Locker, 0) + return "", lockers, nil + } tag_buf := make([]byte, c_tag_len) clients_buf := make([]byte, c_clients_len) cookies_buf := make([]byte, c_cookies_len) addrs_buf := make([]byte, c_addrs_len) - - 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(&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(&addrs_buf[0])), (*C.size_t)(&c_addrs_len)) + + // rbd_list_lockers returns negative value for errors + // and *0* means no locker held on rbd image. + // but *0* is unexpected here because first rbd_list_lockers already + // dealt with no locker case + if int(c_locker_cnt) <= 0 { + return "", nil, RBDError(int(c_locker_cnt)) + } clients := split(clients_buf) cookies := split(cookies_buf) addrs := split(addrs_buf) - lockers = make([]Locker, c_clients_len) - for i := 0; i < int(c_clients_len); i++ { + lockers = make([]Locker, c_locker_cnt) + for i := 0; i < int(c_locker_cnt); i++ { lockers[i] = Locker{Client: clients[i], Cookie: cookies[i], Addr: addrs[i]}