Skip to content

Commit

Permalink
fix(csi-node): cherry-pick don't detach if mounts are present
Browse files Browse the repository at this point in the history
When staging fails, we must not stage if another mount point exists already, which can happen
when trying to stage with a different staging path.
When unstaging, don't detach if any mount points exist for the device.

Signed-off-by: Tiago Castro <[email protected]>
  • Loading branch information
tiagolobocastro committed Nov 28, 2022
1 parent 4331c18 commit 3901cf5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
10 changes: 5 additions & 5 deletions csi/src/filesystem_vol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{

pub async fn stage_fs_volume(
msg: &NodeStageVolumeRequest,
device_path: String,
device_path: &str,
mnt: &MountVolume,
filesystems: &[String],
) -> Result<(), Status> {
Expand Down Expand Up @@ -56,7 +56,7 @@ pub async fn stage_fs_volume(
};

if let Some(existing) =
mount::find_mount(Some(&device_path), Some(fs_staging_path))
mount::find_mount(Some(device_path), Some(fs_staging_path))
{
debug!(
"Device {} is already mounted onto {}",
Expand All @@ -77,7 +77,7 @@ pub async fn stage_fs_volume(
}

// abort if device is mounted somewhere else
if mount::find_mount(Some(&device_path), None).is_some() {
if mount::find_mount(Some(device_path), None).is_some() {
return Err(failure!(
Code::AlreadyExists,
"Failed to stage volume {}: device {} is already mounted elsewhere",
Expand All @@ -96,7 +96,7 @@ pub async fn stage_fs_volume(
));
}

if let Err(error) = prepare_device(&device_path, &fstype).await {
if let Err(error) = prepare_device(device_path, &fstype).await {
return Err(failure!(
Code::Internal,
"Failed to stage volume {}: error preparing device {}: {}",
Expand All @@ -109,7 +109,7 @@ pub async fn stage_fs_volume(
debug!("Mounting device {} onto {}", device_path, fs_staging_path);

if let Err(error) = mount::filesystem_mount(
&device_path,
device_path,
fs_staging_path,
&fstype,
&mnt.mount_flags,
Expand Down
35 changes: 26 additions & 9 deletions csi/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ async fn detach(uuid: &Uuid, errheader: String) -> Result<(), Status> {
})? {
let device_path = device.devname();
debug!("Detaching device {}", device_path);

let mounts = crate::mount::find_src_mounts(&device_path, None);
if !mounts.is_empty() {
return Err(failure!(
Code::FailedPrecondition,
"{} device is still mounted {}: {:?}",
errheader,
device_path,
mounts
));
}

if let Err(error) = device.detach().await {
return Err(failure!(
Code::Internal,
Expand Down Expand Up @@ -508,17 +520,22 @@ impl node_server::Node for Node {
match access_type {
AccessType::Mount(mnt) => {
if let Err(fsmount_error) =
stage_fs_volume(&msg, device_path, mnt, &self.filesystems)
stage_fs_volume(&msg, &device_path, mnt, &self.filesystems)
.await
{
detach(
&uuid,
format!(
"Failed to stage volume {}: {};",
&msg.volume_id, fsmount_error
),
)
.await?;
let mounts =
crate::mount::find_src_mounts(&device_path, None);
// If the device is mounted elsewhere, don't detach it!
if mounts.is_empty() {
detach(
&uuid,
format!(
"Failed to stage volume {}: {};",
&msg.volume_id, fsmount_error
),
)
.await?;
}
return Err(fsmount_error);
}
}
Expand Down

0 comments on commit 3901cf5

Please sign in to comment.