/
filesystem_resolver.cc
92 lines (79 loc) · 3.06 KB
/
filesystem_resolver.cc
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
#include <internal/facts/solaris/filesystem_resolver.hpp>
#include <internal/util/solaris/k_stat.hpp>
#include <internal/util/scoped_file.hpp>
#include <leatherman/file_util/file.hpp>
#include <facter/util/string.hpp>
#include <leatherman/util/regex.hpp>
#include <leatherman/execution/execution.hpp>
#include <leatherman/logging/logging.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <sys/mnttab.h>
#include <fcntl.h>
#include <sys/vfs.h>
#include <sys/statvfs.h>
#include <unordered_set>
using namespace std;
using namespace facter::facts;
using namespace facter::util;
using namespace facter::util::solaris;
using namespace leatherman::util;
using namespace boost::filesystem;
namespace facter { namespace facts { namespace solaris {
filesystem_resolver::data filesystem_resolver::collect_data(collection& facts)
{
data result;
collect_mountpoint_data(result);
collect_filesystem_data(result);
return result;
}
void filesystem_resolver::collect_mountpoint_data(data& result)
{
scoped_file file(fopen("/etc/mnttab", "r"));
if (!static_cast<FILE*>(file)) {
LOG_ERROR("fopen of /etc/mnttab failed: {1} ({2}): mountpoint data is unavailable.", strerror(errno), errno);
return;
}
mnttab entry;
unordered_set<string> auto_home_paths;
vector<mountpoint> mountpoints;
while (getmntent(file, &entry) == 0) {
mountpoint point;
struct statvfs64 stats;
if (statvfs64(entry.mnt_mountp, &stats) != -1) {
point.size = stats.f_frsize * stats.f_blocks;
point.available = stats.f_frsize * stats.f_bfree;
}
if (entry.mnt_special == string("auto_home")) {
auto_home_paths.emplace(entry.mnt_mountp);
continue;
} else if (entry.mnt_fstype == string("autofs")) {
continue;
}
point.name = entry.mnt_mountp;
point.device = entry.mnt_special;
point.filesystem = entry.mnt_fstype;
boost::split(point.options, entry.mnt_mntopts, boost::is_any_of(","), boost::token_compress_on);
mountpoints.emplace_back(move(point));
}
for (auto& point : mountpoints) {
auto mount_parent = point.name.substr(0, point.name.find_last_of('/'));
// Only add entries that are not mounted from an auto_home setup
if (auto_home_paths.count(mount_parent) == 0) {
result.mountpoints.emplace_back(move(point));
}
}
}
void filesystem_resolver::collect_filesystem_data(data& result)
{
// Build a list of mounted filesystems
static boost::regex fs_re("^fs/.*/(.*)$");
leatherman::execution::each_line("/usr/sbin/sysdef", [&](string& line) {
string fs;
if (re_search(line, fs_re, &fs)) {
result.filesystems.insert(move(fs));
}
return true;
});
}
}}} // namespace facter::facts::solaris