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"` DisableInUseChecks bool `json:"disableInUseChecks"`
Encrypted bool Encrypted bool
readOnly bool readOnly bool
Primary bool
KMS util.EncryptionKMS KMS util.EncryptionKMS
CreatedAt *timestamp.Timestamp CreatedAt *timestamp.Timestamp
// conn is a connection to the Ceph cluster obtained from a ConnPool // 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 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 // 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 // addRbdManagerTask adds a ceph manager task to execute command
@ -963,6 +975,52 @@ func (rv *rbdVolume) getImageInfo() error {
return nil 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 checkSnapExists queries rbd about the snapshots of the given image and returns
ErrImageNotFound if provided image is not found, and ErrSnapNotFound if ErrImageNotFound if provided image is not found, and ErrSnapNotFound if