Last active
January 30, 2019 13:55
-
-
Save dgdavid/54880e42ae6578c805ae0ad2bdc49843 to your computer and use it in GitHub Desktop.
Check if the given path is in a btrfs filesystem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'yast' | |
| require 'yast2/execute' | |
| require 'pathname' | |
| # Returns if the given path is placed in a btrfs | |
| # | |
| # @param path [String, Pathname] | |
| # | |
| # @return [Boolean] | |
| def btrfs_available_for?(path) | |
| mounted_btrfs = Yast::Execute.locally!.stdout( | |
| ["df", "-t", "btrfs", "--output=target"], | |
| ["tail", "-n", "+2"] | |
| ).split.uniq | |
| not_mounted_btrfs = Yast::Execute.locally!.stdout( | |
| ["df", "-x", "btrfs", "--output=target"], | |
| ["tail", "-n", "+2"] | |
| ).split.uniq | |
| candidate_paths = Pathname.new(path).descend.map(&:to_s) | |
| return false if mounted_btrfs.empty? | |
| return false if (not_mounted_btrfs & candidate_paths).any? | |
| (mounted_btrfs & candidate_paths).any? | |
| end | |
| # Simply for testing (manually, through irb) the scenario | |
| # > for a system with "/" in btrfs and a separate "/home" with ext4 | |
| # | |
| def fake_btrfs_available_for?(path) | |
| candidate_paths = Pathname.new(path).descend.map(&:to_s) | |
| return false if btrfs_targets.empty? | |
| return false if (not_btrfs_targets & candidate_paths).any? | |
| (btrfs_targets & candidate_paths).any? | |
| end | |
| def btrfs_targets | |
| ["/"] | |
| end | |
| def not_btrfs_targets | |
| ["/home"] | |
| end |
Author
Author
In a system with below df output
❯ df -t btrfs
df: no file systems processedit will returns false
irb(main):001:0> require_relative './btrfs_check_poc.rb'
=> true
irb(main):002:0> btrfs_available_for?('/home/ytm_tester')
=> false
irb(main):003:0>
Author
for a system with "/" in btrfs and a separate "/home" with ext4
irb(main):001:0> require_relative './btrfs_check_poc.rb'
=> true
irb(main):002:0> btrfs_available_for?('/home/ytm_tester')
=> false
irb(main):003:0> btrfs_available_for?('/alternative_home/ytm_tester')
=> true
I would have gone for something like df --output=fstype /home simply to avoid path operations and symlink complications.
What if /home is a symlink to a different file system?
Author
Thank you @wfeldt
So,
def btrfs?(path)
dirname = Pathname.new(path).dirname
fstype = Yast::Execute.locally!.stdout(
["df", "--output=fstype", dirname],
["tail", "-n", "+2"]
).chomp
fstype == "btrfs"
endwill be enough :)
Related to the recent security hardening, we should call /usr/bin/df (with full path).
But I found an easier way:
# /usr/bin/stat -f --format '%T' /home
xfsNo need for removing the df header from the output...
Ah, you might need to add the --dereference to follow symlinks...
Author
Pretty nice! Thank you!
Author
BTW,
Related to the recent security hardening
Thank you for the reminder! :) I was using the Yast::Execute.locally! because of this, but I forgot to use the full path.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In a system with below
dfoutputit will returns
true