rados: Make sure Conn isn't GC'd while it has dependant IOContexts.

Because we have a finalizer configured for Conn that cleans up Ceph
resources, it's important that we don't let it get GC'd before anything
that depends on it has been cleaned up. Since clients are free to hold a
reference to an IOContext without maintaining a reference to the
underlying Conn, we hold such a Conn reference within the IOContext to
signal this dependency to the Go GC.

Signed-off-by: Joshua Baergen <jbaergen@digitalocean.com>
This commit is contained in:
Joshua Baergen 2022-06-21 14:05:22 -06:00 committed by mergify[bot]
parent 1589706287
commit 9e340d1e4e
2 changed files with 6 additions and 1 deletions

View File

@ -100,7 +100,7 @@ func (c *Conn) ReadDefaultConfigFile() error {
func (c *Conn) OpenIOContext(pool string) (*IOContext, error) {
cPool := C.CString(pool)
defer C.free(unsafe.Pointer(cPool))
ioctx := &IOContext{}
ioctx := &IOContext{conn: c}
ret := C.rados_ioctx_create(c.cluster, cPool, &ioctx.ioctx)
if ret == 0 {
return ioctx, nil

View File

@ -99,6 +99,11 @@ type LockInfo struct {
// IOContext represents a context for performing I/O within a pool.
type IOContext struct {
ioctx C.rados_ioctx_t
// Hold a reference back to the connection that the ioctx depends on so
// that Go's GC doesn't trigger the Conn's finalizer before this
// IOContext is destroyed.
conn *Conn
}
// validate returns an error if the ioctx is not ready to be used