Skip to content

Commit

Permalink
Merge #1264
Browse files Browse the repository at this point in the history
1264: fix(csi-node): cherry-pick wait until filesystem shutdown before disc… r=tiagolobocastro a=tiagolobocastro

…onnecting

Sometimes after/during disconnect we get some page write errors, triggered by a journal update by the JBD2 worker task.
To get around these, wait until the filesystem&jbd2 is shutdown before disconnecting.

Signed-off-by: Tiago Castro <tiagolobocastro@gmail.com>

Co-authored-by: Tiago Castro <tiagolobocastro@gmail.com>
  • Loading branch information
mayastor-bors and tiagolobocastro committed Dec 2, 2022
2 parents a9ac4d9 + cc810bd commit af792fa
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 10 deletions.
9 changes: 2 additions & 7 deletions csi/src/filesystem_vol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,6 @@ pub async fn unstage_fs_volume(
));
}

// Sometimes after/during disconnect we get some page write errors,
// triggered by a journal update by the JBD2 worker task. We
// don't really know how we can "flush" these tasks so at the
// moment the best solution we have is to remount the staging path
// as RO before we umount it for good, which seems to help.
mount::remount(fs_staging_path, true)?;

if let Err(error) = mount::filesystem_unmount(fs_staging_path) {
return Err(failure!(
Code::Internal,
Expand All @@ -179,6 +172,8 @@ pub async fn unstage_fs_volume(
error
));
}

mount::wait_fs_shutdown(&device, Some(mount.fstype)).await?;
}

Ok(())
Expand Down
56 changes: 56 additions & 0 deletions csi/src/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,59 @@ pub fn blockdevice_unmount(target: &str) -> Result<(), Error> {
info!("block device at {} has been unmounted", target);
Ok(())
}

/// Waits until a device's filesystem is shutdown.
/// This is useful to know if it's safe to detach a device from a node or not as
/// it seems that even after a umount completes the filesystem and more
/// specifically the filesystem's journal might not be completely shutdown.
/// Specifically, this waits for the filesystem (eg: ext4) shutdown and the
/// filesystem's journal shutdown: jbd2.
pub(crate) async fn wait_fs_shutdown(
device: &str,
fstype: Option<String>,
) -> Result<(), Error> {
let device_trim = device.replace("/dev/", "");

let start = std::time::Instant::now();
let timeout = std::time::Duration::from_secs(2);

if let Some(fstype) = fstype {
let proc_fs_str = format!("/proc/fs/{}/{}", fstype, device_trim);
let proc_fs = std::path::Path::new(&proc_fs_str);
wait_file_removal(proc_fs, start, timeout).await?;
}

let jbd2_pattern = format!("/proc/fs/jbd2/{}-*", device_trim);
let proc_jbd2 = glob::glob(&jbd2_pattern)
.expect("valid pattern")
.next()
.and_then(|v| v.ok());
if let Some(proc_jbd2) = proc_jbd2 {
wait_file_removal(&proc_jbd2, start, timeout).await?;
}

Ok(())
}

/// Waits until a file is removed, up to a timeout.
async fn wait_file_removal(
proc: &std::path::Path,
start: std::time::Instant,
timeout: std::time::Duration,
) -> Result<(), Error> {
let check_interval = std::time::Duration::from_millis(200);
let proc_str = proc.to_string_lossy().to_string();
let mut exists = proc.exists();
while start.elapsed() < timeout && exists {
tracing::debug!(proc = %proc_str, "proc entry still exists");
tokio::time::sleep(check_interval).await;
exists = proc.exists();
}
match exists {
false => Ok(()),
true => Err(Error::new(
std::io::ErrorKind::TimedOut,
format!("Timed out waiting for '{}' to be removed", proc_str),
)),
}
}
2 changes: 2 additions & 0 deletions csi/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ async fn detach(uuid: &Uuid, errheader: String) -> Result<(), Status> {
));
}

crate::mount::wait_fs_shutdown(&device_path, None).await?;

if let Err(error) = device.detach().await {
return Err(failure!(
Code::Internal,
Expand Down
2 changes: 1 addition & 1 deletion deploy/csi-daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ spec:
# the same.
containers:
- name: mayastor-csi
image: mayadata/mayastor:v1.0.4
image: mayadata/mayastor:v1.0.5
imagePullPolicy: IfNotPresent
# we need privileged because we mount filesystems and use mknod
securityContext:
Expand Down
2 changes: 1 addition & 1 deletion deploy/mayastor-daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ spec:
command: ['sh', '-c', 'until nc -vz nats 4222; do echo "Waiting for message bus..."; sleep 1; done;']
containers:
- name: mayastor
image: mayadata/mayastor:v1.0.4
image: mayadata/mayastor:v1.0.5
imagePullPolicy: IfNotPresent
env:
- name: RUST_LOG
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-deploy-yamls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DEPLOYDIR="$ROOTDIR"/deploy

CORES=2
PROFILE=release
TAG=v1.0.4
TAG=v1.0.5

"$SCRIPTDIR"/generate-deploy-yamls.sh -c "$CORES" -t "$TAG" "$PROFILE"

Expand Down

0 comments on commit af792fa

Please sign in to comment.