rbd: do not execute rbd sparsify when volume is in use

This commit makes sure sparsify() is not run when rbd
image is in use.
Running rbd sparsify with workload doing io and too
frequently is not desirable.
When a image is in use fstrim is run and sparsify will
be run only when image is not mapped.

Signed-off-by: Rakshith R <rar@redhat.com>
(cherry picked from commit 98fdadfde7)
This commit is contained in:
Rakshith R 2023-07-11 12:36:08 +05:30 committed by mergify[bot]
parent 81dc964740
commit 9c5e921839
3 changed files with 22 additions and 0 deletions

View File

@ -18,11 +18,13 @@ package rbd
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
csicommon "github.com/ceph/ceph-csi/internal/csi-common" csicommon "github.com/ceph/ceph-csi/internal/csi-common"
rbdutil "github.com/ceph/ceph-csi/internal/rbd" rbdutil "github.com/ceph/ceph-csi/internal/rbd"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log"
"github.com/container-storage-interface/spec/lib/go/csi" "github.com/container-storage-interface/spec/lib/go/csi"
rs "github.com/csi-addons/spec/lib/go/reclaimspace" rs "github.com/csi-addons/spec/lib/go/reclaimspace"
@ -69,6 +71,13 @@ func (rscs *ReclaimSpaceControllerServer) ControllerReclaimSpace(
defer rbdVol.Destroy() defer rbdVol.Destroy()
err = rbdVol.Sparsify() err = rbdVol.Sparsify()
if errors.Is(err, rbdutil.ErrImageInUse) {
// FIXME: https://github.com/csi-addons/kubernetes-csi-addons/issues/406.
// treat sparsify call as no-op if volume is in use.
log.DebugLog(ctx, fmt.Sprintf("volume with ID %q is in use, skipping sparsify operation", volumeID))
return &rs.ControllerReclaimSpaceResponse{}, nil
}
if err != nil { if err != nil {
// TODO: check for different error codes? // TODO: check for different error codes?
return nil, status.Errorf(codes.Internal, "failed to sparsify volume %q: %s", rbdVol, err.Error()) return nil, status.Errorf(codes.Internal, "failed to sparsify volume %q: %s", rbdVol, err.Error())

View File

@ -23,7 +23,18 @@ import (
// Sparsify checks the size of the objects in the RBD image and calls // Sparsify checks the size of the objects in the RBD image and calls
// rbd_sparify() to free zero-filled blocks and reduce the storage consumption // rbd_sparify() to free zero-filled blocks and reduce the storage consumption
// of the image. // of the image.
// This function will return ErrImageInUse if the image is in use, since
// sparsifying an image on which i/o is in progress is not optimal.
func (ri *rbdImage) Sparsify() error { func (ri *rbdImage) Sparsify() error {
inUse, err := ri.isInUse()
if err != nil {
return fmt.Errorf("failed to check if image is in use: %w", err)
}
if inUse {
// if the image is in use, we should not sparsify it, return ErrImageInUse.
return ErrImageInUse
}
image, err := ri.open() image, err := ri.open()
if err != nil { if err != nil {
return err return err

View File

@ -63,4 +63,6 @@ var (
ErrFetchingMirroringInfo = errors.New("failed to get mirroring info of image") ErrFetchingMirroringInfo = errors.New("failed to get mirroring info of image")
// ErrResyncImageFailed is returned when the operation to resync the image fails. // ErrResyncImageFailed is returned when the operation to resync the image fails.
ErrResyncImageFailed = errors.New("failed to resync image") ErrResyncImageFailed = errors.New("failed to resync image")
// ErrImageInUse is returned when the image is in use.
ErrImageInUse = errors.New("image is in use")
) )