On Fri, Feb 24, 2023 at 04:41:20PM -0600, Eric Blake wrote:
I'm out of time this weekend, but while trying to write a test
for an
nbdkit bug fix (a nasty assertion failure when the client disconnects
uncleanly without NBD_CMD_DISC, which is what nbdcopy does if it gets
an EIO read response from the server), I realized it is extremely hard
to trigger this using nbdsh, but easy to do in C or the Go bindings.
In the Go bindings, we intentionally coded things so that the Go
structure knows if its underlying C pointer is live or not; it exposes
a way to force early closure, then the bindings return a
closed_handle_error() if early closure has happened. We probably need
to support something similar in the Python bindings.
As a short-term hack, I tried directly calling h.__del__() - this is
not a good idea, as our current __del__ implementation is not designed
to be called twice, and when the later garbage collection calls it
again, we segfault trying to free invalid memory.
This is a bug :-(
But less drastic
measures, such as:
import gc
del h
h = None
gc.collect()
were still insufficient to trigger a normal __del__ of h, because I
can't figure out how to force the garbage collector to see that I want
to close the handle but keep python open.
In the end, I did get a working test written (by just quit()ing python
instead of trying to keep it alive). See my next email for the nbdkit
patch that spawned my request here.
I think we want an explicit h.close method, just like we already have
in OCaml and golang bindings. This also implies a "handle is closed"
error/exception which is raised when you call another method on the
handle after it is closed.
I thought that this was how the Python bindings already worked, but
I've checked and it's as you say - there's no method to explicitly
close the handle.
Such a change is backwards compatible with existing clients (since you
can still let the handle go out of scope and have it closed
automatically).
I can have a go at adding this since I unexpectedly have some free
time this weekend.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW