Skip to content

Commit 7ef770a

Browse files
black-dragon74mergify[bot]
authored andcommitted
rbd: Fix connection leak when a non-nil volume is returned
This patch calls `Destroy` on the non-nil Volume/Snap object so that conn pool GC can clean it up. Not doing this always kept ref count > 0, preventing cleanup and leading to lock contention, which in turn kicked in librbd lock breaking leading to blacklisting of actual clients. Signed-off-by: Niraj Yadav <niryadav@redhat.com>
1 parent d67d704 commit 7ef770a

4 files changed

Lines changed: 20 additions & 13 deletions

File tree

internal/rbd/controllerserver.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,7 @@ func checkContentSource(
886886
}
887887
rbdSnap, err := genSnapFromSnapID(ctx, snapshotID, cr, req.GetSecrets())
888888
if err != nil {
889+
rbdSnap.Destroy(ctx)
889890
log.ErrorLog(ctx, "failed to get backend snapshot for %s: %v", snapshotID, err)
890891
if !errors.Is(err, rbderrors.ErrSnapNotFound) {
891892
return nil, nil, status.Error(codes.Internal, err.Error())
@@ -906,6 +907,7 @@ func checkContentSource(
906907
}
907908
rbdvol, err := GenVolFromVolID(ctx, volID, cr, req.GetSecrets())
908909
if err != nil {
910+
rbdvol.Destroy(ctx)
909911
log.ErrorLog(ctx, "failed to get backend image for %s: %v", volID, err)
910912
if !errors.Is(err, rbderrors.ErrImageNotFound) {
911913
return nil, nil, status.Error(codes.Internal, err.Error())
@@ -1531,6 +1533,8 @@ func (cs *ControllerServer) DeleteSnapshot(
15311533

15321534
rbdSnap, err := genSnapFromSnapID(ctx, snapshotID, cr, req.GetSecrets())
15331535
if err != nil {
1536+
rbdSnap.Destroy(ctx)
1537+
15341538
// if error is ErrPoolNotFound, the pool is already deleted we don't
15351539
// need to worry about deleting snapshot or omap data, return success
15361540
if errors.Is(err, util.ErrPoolNotFound) {
@@ -1845,6 +1849,8 @@ func (cs *ControllerServer) ControllerUnpublishVolume(
18451849

18461850
rv, err := GenVolFromVolID(ctx, volumeId, credentials, secrets)
18471851
if err != nil {
1852+
rv.Destroy(ctx)
1853+
18481854
return nil, status.Errorf(codes.Internal, "failed to generate volume from volume ID %s: %v",
18491855
volumeId, err)
18501856
}

internal/rbd/manager.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,13 @@ func (mgr *rbdManager) GetVolumeByID(ctx context.Context, id string) (types.Volu
7575

7676
volume, err := GenVolFromVolID(ctx, id, creds, mgr.secrets)
7777
if err != nil {
78+
volume.Destroy(ctx)
79+
7880
switch {
7981
case errors.Is(err, rbderrors.ErrImageNotFound):
80-
err = fmt.Errorf("volume %s not found: %w", id, err)
81-
82-
return nil, err
82+
return nil, fmt.Errorf("volume %s not found: %w", id, err)
8383
case errors.Is(err, util.ErrPoolNotFound):
84-
err = fmt.Errorf("pool %s not found for %s: %w", volume.Pool, id, err)
85-
86-
return nil, err
84+
return nil, fmt.Errorf("pool not found for %s: %w", id, err)
8785
default:
8886
return nil, fmt.Errorf("failed to get volume from id %q: %w", id, err)
8987
}
@@ -100,17 +98,15 @@ func (mgr *rbdManager) GetSnapshotByID(ctx context.Context, id string) (types.Sn
10098

10199
snapshot, err := genSnapFromSnapID(ctx, id, creds, mgr.secrets)
102100
if err != nil {
101+
snapshot.Destroy(ctx)
102+
103103
switch {
104104
case errors.Is(err, rbderrors.ErrImageNotFound):
105-
err = fmt.Errorf("volume %s not found: %w", id, err)
106-
107-
return nil, err
105+
return nil, fmt.Errorf("snapshot %s not found: %w", id, err)
108106
case errors.Is(err, util.ErrPoolNotFound):
109-
err = fmt.Errorf("pool %s not found for %s: %w", snapshot.Pool, id, err)
110-
111-
return nil, err
107+
return nil, fmt.Errorf("pool not found for %s: %w", id, err)
112108
default:
113-
return nil, fmt.Errorf("failed to get volume from id %q: %w", id, err)
109+
return nil, fmt.Errorf("failed to get snapshot from id %q: %w", id, err)
114110
}
115111
}
116112

internal/rbd/nodeserver.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,8 @@ func (ns *NodeServer) blockNodeGetVolumeStats(
17441744

17451745
rv, err := GenVolFromVolID(ctx, volumeId, credentials, secrets)
17461746
if err != nil {
1747+
rv.Destroy(ctx)
1748+
17471749
return nil, status.Errorf(codes.Internal, "failed to generate volume from volume ID %s: %v",
17481750
volumeId, err)
17491751
}

internal/rbd/rbd_util.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,9 @@ func (ri *rbdImage) Connect(cr *util.Credentials) error {
420420
// Destroy cleans up the rbdVolume and closes the connection to the Ceph
421421
// cluster in case one was setup.
422422
func (ri *rbdImage) Destroy(ctx context.Context) {
423+
if ri == nil {
424+
return
425+
}
423426
if ri.ioctx != nil {
424427
ri.ioctx.Destroy()
425428
ri.ioctx = nil

0 commit comments

Comments
 (0)