-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
rm: Implement --one-file-system and --preserve-root=all #7569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
src/uu/rm/src/rm.rs
Outdated
| match validate_single_filesystem(path) { | ||
| Ok(()) => true, | ||
| Err(additional_reason) => { | ||
| if !additional_reason.is_empty() { | ||
| show_error!("{}", additional_reason); | ||
| } | ||
| show_error!( | ||
| "skipping {}, since it's on a different device", | ||
| path.quote() | ||
| ); | ||
| if options.preserve_root == PreserveRoot::YesAll { | ||
| show_error!("and --preserve-root=all is in effect"); | ||
| } | ||
| false | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can probably be simplified with something like:
| match validate_single_filesystem(path) { | |
| Ok(()) => true, | |
| Err(additional_reason) => { | |
| if !additional_reason.is_empty() { | |
| show_error!("{}", additional_reason); | |
| } | |
| show_error!( | |
| "skipping {}, since it's on a different device", | |
| path.quote() | |
| ); | |
| if options.preserve_root == PreserveRoot::YesAll { | |
| show_error!("and --preserve-root=all is in effect"); | |
| } | |
| false | |
| } | |
| } | |
| let result = validate_single_filesystem(path); | |
| if result.is_ok() { | |
| return true; | |
| } | |
| if let Err(additional_reason) = result { | |
| if !additional_reason.is_empty() { | |
| show_error!("{}", additional_reason); | |
| } | |
| } | |
| show_error!( | |
| "skipping {}, since it's on a different device", | |
| path.quote() | |
| ); | |
| if options.preserve_root == PreserveRoot::YesAll { | |
| show_error!("and --preserve-root=all is in effect"); | |
| } | |
| false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for pointing that out! I've implemented the suggested simplification.
|
GNU testsuite comparison: |
|
some jobs are failing :) |
|
GNU testsuite comparison: |
|
GNU testsuite comparison: |
|
does |
|
GNU testsuite comparison: |
|
The following is the test result. It has passed. |
|
I tried again and it failed, so I will fix it. |
|
GNU testsuite comparison: |
|
GNU testsuite comparison: |
2b9e697 to
3882f38
Compare
|
GNU testsuite comparison: |
|
Sorry, i think i made a mistake with the conflict resolution :( could you please fix it? thanks |
|
No warries, I'll fix it. |
5e09b83 to
42a24fb
Compare
|
GNU testsuite comparison: |
|
sorry, i missed it :( |
42a24fb to
f4adf86
Compare
|
GNU testsuite comparison: |
f4adf86 to
5dd9c19
Compare
This comment enhances the safety of recursive deletion in `rm` by introducing two key features to prevent accidental data loss. `--one-file-system`: When specified, `rm` will not traverse into directories that are on a different file system from the one on which the traversal began, this prevents `rm -r` from accidentally deleting data on mounted volumes. `--preserve-root=all`: The `--preserve-root` option is enhanced to accept an optional argument, `all`. When set to `all`, `rm` will refuse to remove any directory that is a mount point. The default behavior (`--preserve-root` without an argument) remains, protecting only the root directory (`/`).
5dd9c19 to
8d0a839
Compare
|
GNU testsuite comparison: |
|
I've finished rebasing the branch. |
src/uu/rm/src/rm.rs
Outdated
| } else { | ||
| match matches | ||
| .get_one::<String>(OPT_PRESERVE_ROOT) | ||
| .unwrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove the unwrap()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed:
a0df78a
src/uu/rm/src/rm.rs
Outdated
| .map_err(|err| format!("cannot canonicalize {}: {err}", path.quote()))?; | ||
|
|
||
| // Get parent path, handling root case | ||
| let parent_canon = child_canon.parent().ok_or("")?.to_path_buf(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we avoid the empty strings in ok_or(") ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed:
2617af7
src/uu/rm/src/rm.rs
Outdated
| fn handle_dir(path: &Path, options: &Options, progress_bar: Option<&ProgressBar>) -> bool { | ||
| let mut had_err = false; | ||
|
|
||
| if let Err(additional_reason) = check_one_fs(path, options) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same code as in line 621, please dedup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed:
f1c3436
|
I see the Smack tests are failing in the CI here and it appears that its due to no space left on device. I'm guessing its caused when downloading the arch linux img |
Merging this PR will not alter performance
Comparing Footnotes
|
- Replace `.unwrap()` with `.map()` to handle options safely without risking panics. - Update the abbreviation check to compare against the `PreserveRoot` enum directly.
|
GNU testsuite comparison: |
Replace empty error strings with descriptive messages when path parent or mount point resolution fails. This aids in debugging by identifying specifically which path caused the resolution failure during the one-file-system check.
|
GNU testsuite comparison: |
Introduce `check_and_report_one_fs` to encapsulate the logic for verifying filesystem boundaries (`-x`) and root preservation. This removes code duplication between `remove_dir_recursive` and `handle_dir`, ensuring consistent error reporting for "different device" skips and `--preserve-root=all` violations.
|
GNU testsuite comparison: |
Split the initialization of `stat_path` in `Filesystem::new` into distinct `#[cfg(unix)]` and `#[cfg(windows)]` blocks. This improves readability and ensures that Windows builds consistently use the volume ID (`dev_id`).
|
GNU testsuite comparison: |
|
GNU testsuite comparison: |
|
any idea why we don't get "Congrats! The gnu test tests/rm/one-file-system is no longer failing!" anymore? thanks |
|
It appears that one of the error messages is returning differently in the test: |
|
I'm taking a deeper look into the implementation and I'm curious about the decision to use the mount tables. The when using stat on the files you are able to get the device id from the st_dev value. When reading from the mount tables it brings in the potential for a race condition and that appears to be whats causing the GNU tests to fail. |
|
Would you be interested if I cherry-pick your PR and just modify the mount part to swap with the stat? Sorry that the feedback is getting there so much later than when you made the PR, but was wondering if this was something you were still interested in following up on? |
Fixes #7011
Implement
--one-file-systemand--preserve-root=alloptions for thermcommand.