rbd: update inuse logic of a rbd image

in case of mirrored image, if the image is
primary a watcher will be added by the rbd
mirror deamon on the rbd image.
we have to consider 2 watcher to check image
is in use.

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna 2020-10-21 11:04:03 +05:30 committed by mergify[bot]
parent ba84f14241
commit 14700b89d1

View File

@ -103,6 +103,7 @@ type rbdVolume struct {
DisableInUseChecks bool `json:"disableInUseChecks"`
Encrypted bool
readOnly bool
Primary bool
KMS util.EncryptionKMS
CreatedAt *timestamp.Timestamp
// conn is a connection to the Ceph cluster obtained from a ConnPool
@ -301,8 +302,19 @@ func (rv *rbdVolume) isInUse() (bool, error) {
return false, err
}
// TODO replace this with logic to get mirroring information once
// https://github.com/ceph/go-ceph/issues/379 is fixed
err = rv.updateVolWithImageInfo()
if err != nil {
return false, err
}
// because we opened the image, there is at least one watcher
return len(watchers) != 1, nil
defaultWatchers := 1
if rv.Primary {
// a watcher will be added by the rbd mirror daemon if the image is primary
defaultWatchers++
}
return len(watchers) != defaultWatchers, nil
}
// addRbdManagerTask adds a ceph manager task to execute command
@ -963,6 +975,52 @@ func (rv *rbdVolume) getImageInfo() error {
return nil
}
// imageInfo strongly typed JSON spec for image info.
type imageInfo struct {
Mirroring mirroring `json:"mirroring"`
}
// parentInfo spec for parent volume info.
type mirroring struct {
Mode string `json:"mode"`
State string `json:"state"`
GlobalID string `json:"global_id"`
Primary bool `json:"primary"`
}
// updateVolWithImageInfo updates provided rbdVolume with information from on-disk data
// regarding the same.
func (rv *rbdVolume) updateVolWithImageInfo() error {
// rbd --format=json info [image-spec | snap-spec]
var imgInfo imageInfo
stdout, stderr, err := util.ExecCommand(
context.TODO(),
"rbd",
"-m", rv.Monitors,
"--id", rv.conn.Creds.ID,
"--keyfile="+rv.conn.Creds.KeyFile,
"-c", util.CephConfigPath,
"--format="+"json",
"info", rv.String())
if err != nil {
if strings.Contains(stderr, "rbd: error opening image "+rv.RbdImageName+
": (2) No such file or directory") {
return util.JoinErrors(ErrImageNotFound, err)
}
return err
}
if stdout != "" {
err = json.Unmarshal([]byte(stdout), &imgInfo)
if err != nil {
return fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, stdout)
}
rv.Primary = imgInfo.Mirroring.Primary
}
return nil
}
/*
checkSnapExists queries rbd about the snapshots of the given image and returns
ErrImageNotFound if provided image is not found, and ErrSnapNotFound if