mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-09 16:00:22 +00:00
rbd: discover if StagingTargetPath in NodeExpandVolume
The StagingTargetPath is an optional entry in NodeExpandVolumeRequest, We cannot expect it to be set always and at the same time cephcsi depended on the StaingTargetPath to retrieve some metadata information. This commit will check all the mount ref and identifies the stagingTargetPath by checking the image-meta.json file exists and this is a costly operation as we need to loop through all the mounts and check image-meta.json in each mount but this is happens only if the StaingTargetPath is not set in the NodeExpandVolumeRequest fixes #3623 Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
parent
a4fac623ff
commit
e54a97ba85
@ -269,11 +269,11 @@ func populateRbdVol(
|
||||
// Implementation notes:
|
||||
// - stagingTargetPath is the directory passed in the request where the volume needs to be staged
|
||||
// - We stage the volume into a directory, named after the VolumeID inside stagingTargetPath if
|
||||
// it is a file system
|
||||
// it is a file system
|
||||
// - We stage the volume into a file, named after the VolumeID inside stagingTargetPath if it is
|
||||
// a block volume
|
||||
// - Order of operation execution: (useful for defer stacking and when Unstaging to ensure steps
|
||||
// are done in reverse, this is done in undoStagingTransaction)
|
||||
// a block volume
|
||||
// - Order of operation execution: (useful for defer stacking and when Unstaging to ensure steps
|
||||
// are done in reverse, this is done in undoStagingTransaction)
|
||||
// - Stash image metadata under staging path
|
||||
// - Map the image (creates a device)
|
||||
// - Create the staging file/directory under staging path
|
||||
@ -1026,6 +1026,29 @@ func (ns *NodeServer) NodeUnstageVolume(
|
||||
return &csi.NodeUnstageVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
// getStagingPath returns the staging path for the volume from the volume path.
|
||||
// The staingTargetPath looks like
|
||||
// /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-08937eb8-7e00-4033-b6ce-bc36147b4ed0/
|
||||
// globalmount/0001-0009-rook-ceph-0000000000000002-50d53503-9da1-11ed-847e-bacf8f2f1297
|
||||
// the last directory is the volumeID returned in the NodeStageVolumeRespose.
|
||||
// The image-meta.json file is present in the staging path without volumeID.
|
||||
func (ns *NodeServer) getStagingPath(volPath string) (string, error) {
|
||||
mounts, err := ns.Mounter.GetMountRefs(volPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, mount := range mounts {
|
||||
// strip the last directory from the staging path
|
||||
stp := strings.Split(mount, "/")
|
||||
stagingTargetPath := strings.Join(stp[:len(stp)-1], "/")
|
||||
if checkRBDImageMetadataStashExists(stagingTargetPath) {
|
||||
return stagingTargetPath, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("failed to get staging path for volume %s", volPath)
|
||||
}
|
||||
|
||||
// NodeExpandVolume resizes rbd volumes.
|
||||
func (ns *NodeServer) NodeExpandVolume(
|
||||
ctx context.Context,
|
||||
@ -1042,8 +1065,18 @@ func (ns *NodeServer) NodeExpandVolume(
|
||||
volumePath := req.GetStagingTargetPath()
|
||||
if volumePath == "" {
|
||||
// If Kubernetes version < v1.19.0 the volume_path would be
|
||||
// having the staging_target_path information
|
||||
volumePath = req.GetVolumePath()
|
||||
// having the staging_target_path information.
|
||||
// stagingTargetPath is optional parameter in NodeExpandVolumeRequest request
|
||||
// Kubernetes will not send the staging_target_path in the volume_path in some cases
|
||||
// Refer https://github.com/kubernetes/kubernetes/issues/115343
|
||||
var err error
|
||||
volumePath, err = ns.getStagingPath(req.GetVolumePath())
|
||||
if err != nil {
|
||||
// If stagingTargetPath is not found in volumePath then use
|
||||
// volumePath
|
||||
volumePath = req.GetVolumePath()
|
||||
log.UsefulLog(ctx, "failed to find stagingTargetPath from volumePath %v: %v", volumePath, err)
|
||||
}
|
||||
}
|
||||
if volumePath == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "volume path must be provided")
|
||||
|
@ -1731,6 +1731,14 @@ func stashRBDImageMetadata(volOptions *rbdVolume, metaDataPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkRBDImageMetadataStashExists checks if the stashFile exists at the passed in path.
|
||||
func checkRBDImageMetadataStashExists(metaDataPath string) bool {
|
||||
imageMetaPath := filepath.Join(metaDataPath, stashFileName)
|
||||
_, err := os.Stat(imageMetaPath)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// lookupRBDImageMetadataStash reads and returns stashed image metadata at passed in path.
|
||||
func lookupRBDImageMetadataStash(metaDataPath string) (rbdImageMetadataStash, error) {
|
||||
var imgMeta rbdImageMetadataStash
|
||||
|
Loading…
Reference in New Issue
Block a user