rbd: implement rbdVolume.isInUse() with go-ceph

The new rbdVolume.isInUse() method will replace the rbdStatus()
function. This removes one more rbd command execution in the
DeleteVolume path.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2020-07-22 15:33:36 +02:00 committed by mergify[bot]
parent 9e0589cf12
commit 7afaac9c66
3 changed files with 28 additions and 6 deletions

View File

@ -613,12 +613,12 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
} }
defer cs.VolumeLocks.Release(rbdVol.RequestName) defer cs.VolumeLocks.Release(rbdVol.RequestName)
found, _, err := rbdStatus(ctx, rbdVol, cr) inUse, err := rbdVol.isInUse()
if err != nil { if err != nil {
klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), rbdVol, err) klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), rbdVol, err)
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
if found { if inUse {
klog.Errorf(util.Log(ctx, "rbd %s is still being used"), rbdVol) klog.Errorf(util.Log(ctx, "rbd %s is still being used"), rbdVol)
return nil, status.Errorf(codes.Internal, "rbd %s is still being used", rbdVol.RbdImageName) return nil, status.Errorf(codes.Internal, "rbd %s is still being used", rbdVol.RbdImageName)
} }

View File

@ -190,7 +190,7 @@ func attachRBDImage(ctx context.Context, volOptions *rbdVolume, cr *util.Credent
Steps: rbdImageWatcherSteps, Steps: rbdImageWatcherSteps,
} }
err = waitForrbdImage(ctx, backoff, volOptions, cr) err = waitForrbdImage(ctx, backoff, volOptions)
if err != nil { if err != nil {
return "", err return "", err
@ -246,13 +246,13 @@ func createPath(ctx context.Context, volOpt *rbdVolume, cr *util.Credentials) (s
return devicePath, nil return devicePath, nil
} }
func waitForrbdImage(ctx context.Context, backoff wait.Backoff, volOptions *rbdVolume, cr *util.Credentials) error { func waitForrbdImage(ctx context.Context, backoff wait.Backoff, volOptions *rbdVolume) error {
imagePath := volOptions.String() imagePath := volOptions.String()
err := wait.ExponentialBackoff(backoff, func() (bool, error) { err := wait.ExponentialBackoff(backoff, func() (bool, error) {
used, rbdOutput, err := rbdStatus(ctx, volOptions, cr) used, err := volOptions.isInUse()
if err != nil { if err != nil {
return false, fmt.Errorf("fail to check rbd image status with: (%v), rbd output: (%s)", err, rbdOutput) return false, fmt.Errorf("fail to check rbd image status: (%w)", err)
} }
if (volOptions.DisableInUseChecks) && (used) { if (volOptions.DisableInUseChecks) && (used) {
util.UsefulLog(ctx, "valid multi-node attach requested, ignoring watcher in-use result") util.UsefulLog(ctx, "valid multi-node attach requested, ignoring watcher in-use result")

View File

@ -275,6 +275,28 @@ func (rv *rbdVolume) open() (*librbd.Image, error) {
return image, nil return image, nil
} }
// isInUse checks if there is a watcher on the image. It returns true if there
// is a watcher on the image, otherwise returns false.
func (rv *rbdVolume) isInUse() (bool, error) {
image, err := rv.open()
if err != nil {
if errors.Is(err, ErrImageNotFound) || errors.Is(err, util.ErrPoolNotFound) {
return false, err
}
// any error should assume something else is using the image
return true, err
}
defer image.Close()
watchers, err := image.ListWatchers()
if err != nil {
return false, err
}
// because we opened the image, there is at least one watcher
return len(watchers) != 1, nil
}
// rbdStatus checks if there is watcher on the image. // rbdStatus checks if there is watcher on the image.
// It returns true if there is a watcher on the image, otherwise returns false. // It returns true if there is a watcher on the image, otherwise returns false.
func rbdStatus(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) (bool, string, error) { func rbdStatus(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) (bool, string, error) {