Hello,
While writing some tests for the Rust bindings, I discovered a memory
leak with Valgrind due to a completion callback not being freed. More
specificly, the completion callback of `aio_opt_info()` doesn't seem to
be if `aio_opt_info()` failes. In this case, `aio_opt_info()` was called
in the connected state, so it should indeed fail, but it should perhaps
also call the free function associated with the callback.
According to libnbd(3) <
https://libguestfs.org/libnbd.3.html>:
Callback lifetimes
You can associate an optional free function with callbacks. Libnbd
will call this function when the callback will not be called again by
libnbd, including in the case where the API fails.
After studying the code in lib/opt.c, I think that the situation with
synchronous callbacks like `nbd_opt_list()` is even worse. Here the list
callback will not be freed if the internal call to
`nbd_unlocked_aio_opt_list()` failes, but it will be freed if the
completion callback got an error which is returned by `nbd_opt_list()`.
/* Issue NBD_OPT_LIST and wait for the reply. */
int
nbd_unlocked_opt_list (struct nbd_handle *h, nbd_list_callback *list)
{
struct list_helper s = { .list = *list };
nbd_list_callback l = { .callback = list_visitor, .user_data = &s };
nbd_completion_callback c = { .callback = list_complete, .user_data
= &s };
if (nbd_unlocked_aio_opt_list (h, &l, &c) == -1)
Here the list callback
has not been freed.
return -1;
SET_CALLBACK_TO_NULL (*list);
if (wait_fo_option (h) == -1)
return -1;
if (s.err) {
But here I think that the callback has been freed.
set_error (s.err, "server replied with error to list
request");
return -1;
}
return s.count;
}
The problem is that if `nbd_opt_list()` returns an error, I as a user
cannot know wether I should free the data associated with the list
callback myself or if that has been done already.
Maybe I am just misunderstanding the code or the API, but if not then I
wonder how I should know when I need to free the user data associated
with a callback myself and when that is done by libnbd?
Best regards,
Tage