Merge pull request #3602 from lendandgit/main

df: better error message when executed in a chroot without /proc #3601
This commit is contained in:
Terts Diepraam 2022-07-11 23:02:39 +02:00 committed by GitHub
commit 6b00aec48e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 20 deletions

View file

@ -14,6 +14,7 @@ mod table;
use blocks::HumanReadable; use blocks::HumanReadable;
use table::HeaderMode; use table::HeaderMode;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::FromIo;
use uucore::error::{UError, UResult, USimpleError}; use uucore::error::{UError, UResult, USimpleError};
use uucore::fsext::{read_fs_list, MountInfo}; use uucore::fsext::{read_fs_list, MountInfo};
use uucore::parse_size::ParseSizeError; use uucore::parse_size::ParseSizeError;
@ -333,7 +334,7 @@ fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> {
/// `opt` excludes certain filesystems from consideration and allows for the synchronization of filesystems before running; see /// `opt` excludes certain filesystems from consideration and allows for the synchronization of filesystems before running; see
/// [`Options`] for more information. /// [`Options`] for more information.
fn get_all_filesystems(opt: &Options) -> Vec<Filesystem> { fn get_all_filesystems(opt: &Options) -> Result<Vec<Filesystem>, std::io::Error> {
// Run a sync call before any operation if so instructed. // Run a sync call before any operation if so instructed.
if opt.sync { if opt.sync {
#[cfg(not(windows))] #[cfg(not(windows))]
@ -349,19 +350,19 @@ fn get_all_filesystems(opt: &Options) -> Vec<Filesystem> {
// //
// Filesystems excluded by the command-line options are // Filesystems excluded by the command-line options are
// not considered. // not considered.
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list(), opt); let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list()?, opt);
// Convert each `MountInfo` into a `Filesystem`, which contains // Convert each `MountInfo` into a `Filesystem`, which contains
// both the mount information and usage information. // both the mount information and usage information.
mounts Ok(mounts
.into_iter() .into_iter()
.filter_map(|m| Filesystem::new(m, None)) .filter_map(|m| Filesystem::new(m, None))
.filter(|fs| opt.show_all_fs || fs.usage.blocks > 0) .filter(|fs| opt.show_all_fs || fs.usage.blocks > 0)
.collect() .collect())
} }
/// For each path, get the filesystem that contains that path. /// For each path, get the filesystem that contains that path.
fn get_named_filesystems<P>(paths: &[P], opt: &Options) -> Vec<Filesystem> fn get_named_filesystems<P>(paths: &[P], opt: &Options) -> Result<Vec<Filesystem>, std::io::Error>
where where
P: AsRef<Path>, P: AsRef<Path>,
{ {
@ -371,7 +372,7 @@ where
// considered. The "lofs" filesystem is a loopback // considered. The "lofs" filesystem is a loopback
// filesystem present on Solaris and FreeBSD systems. It // filesystem present on Solaris and FreeBSD systems. It
// is similar to a symbolic link. // is similar to a symbolic link.
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list(), opt) let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list()?, opt)
.into_iter() .into_iter()
.filter(|mi| mi.fs_type != "lofs" && !mi.dummy) .filter(|mi| mi.fs_type != "lofs" && !mi.dummy)
.collect(); .collect();
@ -381,7 +382,7 @@ where
// this happens if the file system type doesn't exist // this happens if the file system type doesn't exist
if mounts.is_empty() { if mounts.is_empty() {
show!(USimpleError::new(1, "no file systems processed")); show!(USimpleError::new(1, "no file systems processed"));
return result; return Ok(result);
} }
// Convert each path into a `Filesystem`, which contains // Convert each path into a `Filesystem`, which contains
@ -402,7 +403,7 @@ where
} }
} }
} }
result Ok(result)
} }
#[derive(Debug)] #[derive(Debug)]
@ -443,7 +444,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// Get the list of filesystems to display in the output table. // Get the list of filesystems to display in the output table.
let filesystems: Vec<Filesystem> = match matches.values_of(OPT_PATHS) { let filesystems: Vec<Filesystem> = match matches.values_of(OPT_PATHS) {
None => { None => {
let filesystems = get_all_filesystems(&opt); let filesystems = get_all_filesystems(&opt)
.map_err_context(|| "cannot read table of mounted file systems".into())?;
if filesystems.is_empty() { if filesystems.is_empty() {
return Err(USimpleError::new(1, "no file systems processed")); return Err(USimpleError::new(1, "no file systems processed"));
@ -453,7 +455,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
} }
Some(paths) => { Some(paths) => {
let paths: Vec<&str> = paths.collect(); let paths: Vec<&str> = paths.collect();
let filesystems = get_named_filesystems(&paths, &opt); let filesystems = get_named_filesystems(&paths, &opt)
.map_err_context(|| "cannot read table of mounted file systems".into())?;
// This can happen if paths are given as command-line arguments // This can happen if paths are given as command-line arguments
// but none of the paths exist. // but none of the paths exist.

View file

@ -8,7 +8,7 @@
#[macro_use] #[macro_use]
extern crate uucore; extern crate uucore;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError}; use uucore::error::{FromIo, UResult, USimpleError};
use uucore::fs::display_permissions; use uucore::fs::display_permissions;
use uucore::fsext::{ use uucore::fsext::{
pretty_filetype, pretty_fstype, pretty_time, read_fs_list, statfs, BirthTime, FsMeta, pretty_filetype, pretty_fstype, pretty_time, read_fs_list, statfs, BirthTime, FsMeta,
@ -502,6 +502,7 @@ impl Stater {
None None
} else { } else {
let mut mount_list = read_fs_list() let mut mount_list = read_fs_list()
.map_err_context(|| "cannot read table of mounted file systems".into())?
.iter() .iter()
.map(|mi| mi.mount_dir.clone()) .map(|mi| mi.mount_dir.clone())
.collect::<Vec<String>>(); .collect::<Vec<String>>();

View file

@ -405,22 +405,21 @@ use std::ptr;
))] ))]
use std::slice; use std::slice;
/// Read file system list. /// Read file system list.
pub fn read_fs_list() -> Vec<MountInfo> { pub fn read_fs_list() -> Result<Vec<MountInfo>, std::io::Error> {
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
{ {
let (file_name, f) = File::open(LINUX_MOUNTINFO) let (file_name, f) = File::open(LINUX_MOUNTINFO)
.map(|f| (LINUX_MOUNTINFO, f)) .map(|f| (LINUX_MOUNTINFO, f))
.or_else(|_| File::open(LINUX_MTAB).map(|f| (LINUX_MTAB, f))) .or_else(|_| File::open(LINUX_MTAB).map(|f| (LINUX_MTAB, f)))?;
.expect("failed to find mount list files");
let reader = BufReader::new(f); let reader = BufReader::new(f);
reader Ok(reader
.lines() .lines()
.filter_map(|line| line.ok()) .filter_map(|line| line.ok())
.filter_map(|line| { .filter_map(|line| {
let raw_data = line.split_whitespace().collect::<Vec<&str>>(); let raw_data = line.split_whitespace().collect::<Vec<&str>>();
MountInfo::new(file_name, &raw_data) MountInfo::new(file_name, &raw_data)
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>())
} }
#[cfg(any( #[cfg(any(
target_os = "freebsd", target_os = "freebsd",
@ -435,10 +434,10 @@ pub fn read_fs_list() -> Vec<MountInfo> {
crash!(1, "get_mount_info() failed"); crash!(1, "get_mount_info() failed");
} }
let mounts = unsafe { slice::from_raw_parts(mount_buffer_ptr, len as usize) }; let mounts = unsafe { slice::from_raw_parts(mount_buffer_ptr, len as usize) };
mounts Ok(mounts
.iter() .iter()
.map(|m| MountInfo::from(*m)) .map(|m| MountInfo::from(*m))
.collect::<Vec<_>>() .collect::<Vec<_>>())
} }
#[cfg(windows)] #[cfg(windows)]
{ {
@ -482,12 +481,12 @@ pub fn read_fs_list() -> Vec<MountInfo> {
unsafe { unsafe {
FindVolumeClose(find_handle); FindVolumeClose(find_handle);
} }
mounts Ok(mounts)
} }
#[cfg(any(target_os = "redox", target_os = "illumos", target_os = "solaris"))] #[cfg(any(target_os = "redox", target_os = "illumos", target_os = "solaris"))]
{ {
// No method to read mounts, yet // No method to read mounts, yet
Vec::new() Ok(Vec::new())
} }
} }