fn should_unmount(
    logger: &slog::Logger,
    mount: &MountedFilesystem,
    timeout: u32,
) -> Result<ShouldUnmountResult> {
    // Only consider certain mount types.
    match mount.fstype.as_str() {
        "fuse.squashfuse" | "fuse.squashfuse_ll" | "osxfusefs" | "osxfuse" | "macfuse" => {}
        _ => return Ok(ShouldUnmountResult::new(false, None)),
    }
    info!(
        logger,
        "Considering {} ({})", mount.mountpoint, mount.fstype
    );

    let lockfiles = get_lockfile_path(&logger, &mount);

    // Sometimes mtab gets out of sync with reality; all XARs should
    // contain files, so let's confirm they actually do, and if not,
    // still consider them for unmounting.
    let mut chrooted_mountpoint = mount.chroot.clone();
    chrooted_mountpoint.push(&mount.mountpoint[1..]);
    if let Ok(it) = fs::read_dir(&chrooted_mountpoint) {
        if it.take_while(|r| r.is_ok()).next().is_none() {
            debug!(
                logger,
                "Unmounting empty directory: {:?}", chrooted_mountpoint
            );
            return Ok(ShouldUnmountResult::new(true, None));
        }
    } else {
        info!(
            logger,
            "Unable to read dir {:?}, skipping emptiness check", chrooted_mountpoint
        );
    }

    debug!(logger, "lockfile candidates: {:?}", lockfiles);

    // Find the lockfile; use its mtime to determine if the mount
    // point is old enough to try to reap.
    let lock_opt = lockfiles
        .iter()
        .map(|ref filename| {
            nix::fcntl::open(
                filename.as_path().as_os_str(),
                nix::fcntl::OFlag::O_RDWR | nix::fcntl::OFlag::O_CLOEXEC,
                nix::sys::stat::Mode::from_bits(0700).unwrap(),
            )
        })
        .filter_map(|open_result| open_result.ok())
        .next();
    let lock_fd = match lock_opt {
        Some(fd) => fd,
        None => {
            debug!(
                logger,
                "Unable to find lock file for {}, skipping...", mount.mountpoint
            );
            return Ok(ShouldUnmountResult::new(false, None));
        }
    };

    // lock the file before checking timestamp to protect against a
    // race with XarexecFuse.
    if !flock_with_timeout(lock_fd, 60) {
        info!(
            logger,
            "Unable to flock {:?}, skipping...", chrooted_mountpoint
        );
        return Ok(ShouldUnmountResult::new(false, lock_opt));
    }
    let stat = nix::sys::stat::fstat(lock_fd)?;
    let epoch_now = SystemTime::now().duration_since(UNIX_EPOCH)?;
    let age = epoch_now.as_secs_f64()
        - Duration::new(stat.st_mtime as u64, stat.st_mtime_nsec as u32).as_secs_f64();
    let timeout = timeout as f64 * 60.0;
    if age <= timeout {
        info!(
            logger,
            "Skipping unmount of {}, too recent ({:.2}s)", mount.mountpoint, age
        );
        return Ok(ShouldUnmountResult::new(false, lock_opt));
    }

    Ok(ShouldUnmountResult::new(true, lock_opt))
}
/// Check whether a mount point should be unmounted.  We only consider
/// squashfuse mounts in the correct locations.  Returns a
/// ShouldUnmountResult.
Check whether a mount point should be unmounted.  We only consider
squashfuse mounts in the correct locations.
Check whether a mount point should be unmounted . We only consider squashfuse mounts in the correct locations .
fn should_unmount(
    logger: &slog::Logger,
    mount: &MountedFilesystem,
    timeout: u32,
) -> Result<ShouldUnmountResult> {
    // Only consider certain mount types.
    match mount.fstype.as_str() {
        "fuse.squashfuse" | "fuse.squashfuse_ll" | "osxfusefs" | "osxfuse" | "macfuse" => {}
        _ => return Ok(ShouldUnmountResult::new(false, None)),
    }
    info!(
        logger,
        "Considering {} ({})", mount.mountpoint, mount.fstype
    );
    let lockfiles = get_lockfile_path(&logger, &mount);
    // Sometimes mtab gets out of sync with reality; all XARs should
    // contain files, so let's confirm they actually do, and if not,
    // still consider them for unmounting.
    let mut chrooted_mountpoint = mount.chroot.clone();
    chrooted_mountpoint.push(&mount.mountpoint[1..]);
    if let Ok(it) = fs::read_dir(&chrooted_mountpoint) {
        if it.take_while(|r| r.is_ok()).next().is_none() {
            debug!(
                logger,
                "Unmounting empty directory: {:?}", chrooted_mountpoint
            );
            return Ok(ShouldUnmountResult::new(true, None));
        }
    } else {
        info!(
            logger,
            "Unable to read dir {:?}, skipping emptiness check", chrooted_mountpoint
        );
    }
    debug!(logger, "lockfile candidates: {:?}", lockfiles);
    // Find the lockfile; use its mtime to determine if the mount
    // point is old enough to try to reap.
    let lock_opt = lockfiles
        .iter()
        .map(|ref filename| {
            nix::fcntl::open(
                filename.as_path().as_os_str(),
                nix::fcntl::OFlag::O_RDWR | nix::fcntl::OFlag::O_CLOEXEC,
                nix::sys::stat::Mode::from_bits(0700).unwrap(),
            )
        })
        .filter_map(|open_result| open_result.ok())
        .next();
    let lock_fd = match lock_opt {
        Some(fd) => fd,
        None => {
            debug!(
                logger,
                "Unable to find lock file for {}, skipping...", mount.mountpoint
            );
            return Ok(ShouldUnmountResult::new(false, None));
        }
    };
    // lock the file before checking timestamp to protect against a
    // race with XarexecFuse.
    if !flock_with_timeout(lock_fd, 60) {
        info!(
            logger,
            "Unable to flock {:?}, skipping...", chrooted_mountpoint
        );
        return Ok(ShouldUnmountResult::new(false, lock_opt));
    }
    let stat = nix::sys::stat::fstat(lock_fd)?;
    let epoch_now = SystemTime::now().duration_since(UNIX_EPOCH)?;
    let age = epoch_now.as_secs_f64()
        - Duration::new(stat.st_mtime as u64, stat.st_mtime_nsec as u32).as_secs_f64();
    let timeout = timeout as f64 * 60.0;
    if age <= timeout {
        info!(
            logger,
            "Skipping unmount of {}, too recent ({:.2}s)", mount.mountpoint, age
        );
        return Ok(ShouldUnmountResult::new(false, lock_opt));
    }
    Ok(ShouldUnmountResult::new(true, lock_opt))
}
fn should_unmount ( logger : & slog :: Logger , mount : & MountedFilesystem , timeout : u32 , ) -> Result < ShouldUnmountResult > { // Only consider certain mount types. match mount . fstype . as_str ( ) { " " | " " | " " | " " | " " => { } _ => return Ok ( ShouldUnmountResult :: new ( false , None ) ) , } info ! ( logger " " mount mountpoint mount fstype ) ; let lockfiles = get_lockfile_path ( & logger , & mount ) ; // Sometimes mtab gets out of sync with reality; all XARs should // contain files, so let's confirm they actually do, and if not, // still consider them for unmounting. let mut chrooted_mountpoint = mount . chroot . clone ( ) ; chrooted_mountpoint . push ( & mount . mountpoint [ 1 .. ] ) ; if let Ok ( it ) = fs :: read_dir ( & chrooted_mountpoint ) { if it . take_while ( | r | r . is_ok ( ) ) . next ( ) . is_none ( ) { debug ! ( logger " " chrooted_mountpoint ) ; return Ok ( ShouldUnmountResult :: new ( true , None ) ) ; } } else { info ! ( logger " " chrooted_mountpoint ) ; } debug ! ( logger " " lockfiles ) ; // Find the lockfile; use its mtime to determine if the mount // point is old enough to try to reap. let lock_opt = lockfiles . iter ( ) . map ( | ref filename | { nix :: fcntl :: open ( filename . as_path ( ) . as_os_str ( ) , nix :: fcntl :: OFlag :: O_RDWR | nix :: fcntl :: OFlag :: O_CLOEXEC , nix :: sys :: stat :: Mode :: from_bits ( 0700 ) . unwrap ( ) , ) } ) . filter_map ( | open_result | open_result . ok ( ) ) . next ( ) ; let lock_fd = match lock_opt { Some ( fd ) => fd , None => { debug ! ( logger " " mount mountpoint ) ; return Ok ( ShouldUnmountResult :: new ( false , None ) ) ; } } ; // lock the file before checking timestamp to protect against a // race with XarexecFuse. if ! flock_with_timeout ( lock_fd , 60 ) { info ! ( logger " " chrooted_mountpoint ) ; return Ok ( ShouldUnmountResult :: new ( false , lock_opt ) ) ; } let stat = nix :: sys :: stat :: fstat ( lock_fd ) ? ; let epoch_now = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) ? ; let age = epoch_now . as_secs_f64 ( ) - Duration :: new ( stat . st_mtime as u64 , stat . st_mtime_nsec as u32 ) . as_secs_f64 ( ) ; let timeout = timeout as f64 * 60.0 ; if age <= timeout { info ! ( logger " " mount mountpoint age ) ; return Ok ( ShouldUnmountResult :: new ( false , lock_opt ) ) ; } Ok ( ShouldUnmountResult :: new ( true , lock_opt ) ) }
Check whether a mount point should be unmounted.
Check whether a mount point should be unmounted .
logger
&slog::Logger
mount
&MountedFilesystem
timeout
u32
logger
&slog::Logger
mount
&MountedFilesystem
timeout
u32