forked from kwilczynski/facter-facts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mounts.rb
135 lines (114 loc) · 4.58 KB
/
mounts.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#
# mounts.rb
#
# This fact provides list of mount points present in the system alongside
# any known block devices on which a particular mount point resides ...
#
# We do some filtering based on patterns for file systems and devices that
# make no sense and are not of our concern ...
#
require 'thread'
require 'facter'
if Facter.value(:kernel) == 'Linux'
mutex = Mutex.new
# We store a list of block devices hosting mount points here ...
mounts = []
# We store a list of mount points present in the system here ...
devices = []
# Support for the following might not be of interest ...
exclude = %w(afs anon_inodefs aufs autofs bdev bind binfmt_.* cgroup cifs
coda cpuset debugfs devfs devpts ecryptfs fd ftpfs fuse.* gvfs.*
hugetlbfs inotifyfs iso9660 lustre.* mfs mqueue ncpfs NFS nfs.*
none pipefs proc ramfs rootfs rpc_.* securityfs shfs shm smbfs
sockfs sysfs tmpfs udev udf unionfs usbfs)
#
# Modern Linux kernels provide "/proc/mounts" in the following format:
#
# rootfs / rootfs rw 0 0
# none /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
# none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
# udev /dev tmpfs rw,relatime,mode=755 0 0
# none /sys/kernel/security securityfs rw,relatime 0 0
# none /sys/fs/fuse/connections fusectl rw,relatime 0 0
# none /sys/kernel/debug debugfs rw,relatime 0 0
# none /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
# none /dev/shm tmpfs rw,nosuid,nodev,relatime 0 0
# none /var/run tmpfs rw,nosuid,relatime,mode=755 0 0
# none /var/lock tmpfs rw,nosuid,nodev,noexec,relatime 0 0
# none /lib/init/rw tmpfs rw,nosuid,relatime,mode=755 0 0
# /dev/sda5 /home xfs rw,relatime,attr2,noquota 0 0
# /dev/sda1 /boot ext3 rw,relatime,errors=continue,data=ordered 0 0
# binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0
#
# Make regular expression form our patterns ...
exclude = Regexp.union(*exclude.collect { |i| Regexp.new(i) })
# List of numeric identifiers with their corresponding canonical forms ...
known_devices = Dir['/dev/*'].inject({}) do |k,v|
#
# We protect ourselves against broken symbolic links under "/dev" and
# skip all non-block devices as for example a sound card cannot really
# host a file system ...
#
if File.exists?(v) and File.blockdev?(v)
# Resolve any symbolic links we may encounter ...
v = File.readlink(v) if File.symlink?(v)
#
# Make sure that we have full path to the entry under "/dev" ...
# This tends to be often broken there ... Relative path hell ...
#
v = File.join('/dev', v) unless File.exists?(v)
mutex.synchronize do
k.update(File.stat(v).rdev => v)
end
end
k # Yield hash back into the block ...
end
#
# We utilise rely on "cat" for reading values from entries under "/proc".
# This is due to some problems with IO#read in Ruby and reading content of
# the "proc" file system that was reported more than once in the past ...
#
Facter::Util::Resolution.exec('cat /proc/mounts 2> /dev/null').each_line do |line|
# Remove bloat ...
line.strip!
# Line of interest should not start with ...
next if line.empty? or line.match(/^none/)
# We have something, so let us apply our device type filter ...
next if line.match(exclude)
# At this point we split single and valid row into tokens ...
row = line.split(' ')
#
# Only device and mount point are of interest ...
#
# When tere are any spaces in the mount point name then Kernel will
# replace them with as octal "\040" (which is 32 decimal). We have
# to accommodate for this and convert them back into proper spaces ...
#
# An example of such case:
#
# /dev/sda1 /srv/shares/My\040Files ext3 rw,relatime,errors=continue,data=ordered 0 0
#
device = row[0].strip.gsub('\\040', ' ')
mount = row[1].strip.gsub('\\040', ' ')
#
# Correlate mount point with a real device that exists in the system.
# This is to take care about entries like "rootfs" under "/proc/mounts".
#
device = known_devices.values_at(File.stat(mount).dev).shift || device
# Add where appropriate ...
mutex.synchronize do
devices << device
mounts << mount
end
end
Facter.add('devices') do
confine :kernel => :linux
setcode { devices.sort.uniq.join(',') }
end
Facter.add('mounts') do
confine :kernel => :linux
setcode { mounts.uniq.join(',') }
end
end
# vim: set ts=2 sw=2 et :
# encoding: utf-8