Skip to content

Commit ac7c98e

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> (cherry picked from commit 7ef770a)
1 parent 5ace268 commit ac7c98e

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
@@ -853,6 +853,7 @@ func checkContentSource(
853853
}
854854
rbdSnap, err := genSnapFromSnapID(ctx, snapshotID, cr, req.GetSecrets())
855855
if err != nil {
856+
rbdSnap.Destroy(ctx)
856857
log.ErrorLog(ctx, "failed to get backend snapshot for %s: %v", snapshotID, err)
857858
if !errors.Is(err, rbderrors.ErrSnapNotFound) {
858859
return nil, nil, status.Error(codes.Internal, err.Error())
@@ -873,6 +874,7 @@ func checkContentSource(
873874
}
874875
rbdvol, err := GenVolFromVolID(ctx, volID, cr, req.GetSecrets())
875876
if err != nil {
877+
rbdvol.Destroy(ctx)
876878
log.ErrorLog(ctx, "failed to get backend image for %s: %v", volID, err)
877879
if !errors.Is(err, rbderrors.ErrImageNotFound) {
878880
return nil, nil, status.Error(codes.Internal, err.Error())
@@ -1498,6 +1500,8 @@ func (cs *ControllerServer) DeleteSnapshot(
14981500

14991501
rbdSnap, err := genSnapFromSnapID(ctx, snapshotID, cr, req.GetSecrets())
15001502
if err != nil {
1503+
rbdSnap.Destroy(ctx)
1504+
15011505
// if error is ErrPoolNotFound, the pool is already deleted we don't
15021506
// need to worry about deleting snapshot or omap data, return success
15031507
if errors.Is(err, util.ErrPoolNotFound) {
@@ -1812,6 +1816,8 @@ func (cs *ControllerServer) ControllerUnpublishVolume(
18121816

18131817
rv, err := GenVolFromVolID(ctx, volumeId, credentials, secrets)
18141818
if err != nil {
1819+
rv.Destroy(ctx)
1820+
18151821
return nil, status.Errorf(codes.Internal, "failed to generate volume from volume ID %s: %v",
18161822
volumeId, err)
18171823
}

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
@@ -1597,6 +1597,8 @@ func (ns *NodeServer) blockNodeGetVolumeStats(
15971597

15981598
rv, err := GenVolFromVolID(ctx, volumeId, credentials, secrets)
15991599
if err != nil {
1600+
rv.Destroy(ctx)
1601+
16001602
return nil, status.Errorf(codes.Internal, "failed to generate volume from volume ID %s: %v",
16011603
volumeId, err)
16021604
}

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)