#include <internal/facts/bsd/filesystem_resolver.hpp> #include <leatherman/logging/logging.hpp> #include <facter/util/string.hpp> #include <sys/mount.h> #include <tuple> using namespace std; using namespace facter::facts; using namespace facter::util; namespace facter { namespace facts { namespace bsd { filesystem_resolver::data filesystem_resolver::collect_data(collection& facts) { data result; // First get the count of file systems int count = getfsstat(nullptr, 0, MNT_NOWAIT); if (count == -1) { LOG_ERROR("getfsstat failed: {1} ({2}): file system facts are unavailable.", strerror(errno), errno); return result; } // Get the actual data vector<struct statfs> filesystems(count); count = getfsstat(filesystems.data(), filesystems.size() * sizeof(struct statfs), MNT_NOWAIT); if (count == -1) { LOG_ERROR("getfsstat failed: {1} ({2}): file system facts are unavailable.", strerror(errno), errno); return result; } result.mountpoints.reserve(count); // Populate an entry for each mounted file system for (auto& fs : filesystems) { mountpoint point; point.name = fs.f_mntonname; point.device = fs.f_mntfromname; point.filesystem = fs.f_fstypename; point.size = (static_cast<uint64_t>(fs.f_bsize) * static_cast<uint64_t>(fs.f_blocks)); point.available = (static_cast<uint64_t>(fs.f_bsize) * static_cast<uint64_t>(fs.f_bfree)); point.options = to_options(fs); result.mountpoints.emplace_back(move(point)); result.filesystems.insert(fs.f_fstypename); } return result; } vector<string> filesystem_resolver::to_options(struct statfs const& fs) { static vector<tuple<unsigned int, string>> const flags = { make_tuple<unsigned int, string>(MNT_RDONLY, "readonly"), make_tuple<unsigned int, string>(MNT_SYNCHRONOUS, "noasync"), make_tuple<unsigned int, string>(MNT_NOEXEC, "noexec"), make_tuple<unsigned int, string>(MNT_NOSUID, "nosuid"), #ifndef __OpenBSD__ make_tuple<unsigned int, string>(MNT_UNION, "union"), #endif make_tuple<unsigned int, string>(MNT_ASYNC, "async"), make_tuple<unsigned int, string>(MNT_EXPORTED, "exported"), make_tuple<unsigned int, string>(MNT_LOCAL, "local"), make_tuple<unsigned int, string>(MNT_QUOTA, "quota"), make_tuple<unsigned int, string>(MNT_ROOTFS, "root"), make_tuple<unsigned int, string>(MNT_NOATIME, "noatime"), #if !defined(__FreeBSD__) make_tuple<unsigned int, string>(MNT_NODEV, "nodev"), #endif #if !defined(__FreeBSD__) && !defined(__OpenBSD__) // the following constants aren't defined on FreeBSD 10/OpenBSD make_tuple<unsigned int, string>(MNT_DONTBROWSE, "nobrowse"), make_tuple<unsigned int, string>(MNT_AUTOMOUNTED, "automounted"), make_tuple<unsigned int, string>(MNT_JOURNALED, "journaled"), make_tuple<unsigned int, string>(MNT_DEFWRITE, "deferwrites"), #endif #ifdef __OpenBSD__ make_tuple<unsigned int, string>(MNT_WXALLOWED, "wxallowed"), #endif }; vector<string> options; for (auto const& flag : flags) { if (fs.f_flags & get<0>(flag)) { options.push_back(get<1>(flag)); } } return options; } }}} // namespace facter::facts::bsd