From 4f48e254cd3dbf95206d1944a6aa64f8d03724e8 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 31 Mar 2021 03:22:40 +0100 Subject: [PATCH] Decode FreeBSD flags from statfs(2). --- setter/src/unix/bsd/bsd.h | 4 + setter/src/unix/bsd/volume.c | 317 ++++++++++++++++++++++++++++------- setter/src/unix/bsd/volume.h | 134 +++++++++++++++ setter/src/unix/volume.c | 2 + 4 files changed, 400 insertions(+), 57 deletions(-) diff --git a/setter/src/unix/bsd/bsd.h b/setter/src/unix/bsd/bsd.h index 5a02fdb..7bd385b 100644 --- a/setter/src/unix/bsd/bsd.h +++ b/setter/src/unix/bsd/bsd.h @@ -30,6 +30,10 @@ void BsdFileAttributes(const char* path); #if defined(__NetBSD__) void NetBsdPrintStatvfsFlags(unsigned long flags); +#elif defined(__FreeBSD__) +#include + +void FreeBsdPrintStatfsFlags(uint64_t flags); #endif #endif // SETTER_SRC_BSD_H_ diff --git a/setter/src/unix/bsd/volume.c b/setter/src/unix/bsd/volume.c index e0a16a5..e392169 100644 --- a/setter/src/unix/bsd/volume.c +++ b/setter/src/unix/bsd/volume.c @@ -26,6 +26,14 @@ Copyright (C) 2011-2021 Natalia Portillo #include #endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif + +#if defined(__FreeBSD__) +#include +#endif + #include "../../log.h" #include "volume.h" @@ -34,174 +42,369 @@ void NetBsdPrintStatvfsFlags(unsigned long flags) { log_write("\tFlags:\n"); - if(flags & ST_RDONLY) + if(flags & MNT_RDONLY) { log_write("\t\tVolume is read-only.\n"); - flags -= ST_RDONLY; + flags -= MNT_RDONLY; } - if(flags & ST_NOSUID) + if(flags & MNT_NOSUID) { log_write("\t\tVolume ignores suid and sgid bits.\n"); - flags -= ST_NOSUID; + flags -= MNT_NOSUID; } - if(flags & ST_NODEV) + if(flags & MNT_NODEV) { log_write("\t\tVolume disallows access to device special files.\n"); - flags -= ST_NODEV; + flags -= MNT_NODEV; } - if(flags & ST_NOEXEC) + if(flags & MNT_NOEXEC) { log_write("\t\tVolume disallows program execution.\n"); - flags -= ST_NOEXEC; + flags -= MNT_NOEXEC; } - if(flags & ST_SYNCHRONOUS) + if(flags & MNT_SYNCHRONOUS) { log_write("\t\tVolume writes are synced at once.\n"); - flags -= ST_SYNCHRONOUS; + flags -= MNT_SYNCHRONOUS; } - if(flags & ST_NOATIME) + if(flags & MNT_NOATIME) { log_write("\t\tVolume does not update access times.\n"); - flags -= ST_NOATIME; + flags -= MNT_NOATIME; } - if(flags & ST_UNION) + if(flags & MNT_UNION) { log_write("\t\tVolume is a union.\n"); - flags -= ST_UNION; + flags -= MNT_UNION; } - if(flags & ST_ASYNC) + if(flags & MNT_ASYNC) { log_write("\t\tVolume is written asynchronously.\n"); - flags -= ST_ASYNC; + flags -= MNT_ASYNC; } - if(flags & ST_NOCOREDUMP) + if(flags & MNT_NOCOREDUMP) { log_write("\t\tVolume shall not have core dumps written.\n"); - flags -= ST_NOCOREDUMP; + flags -= MNT_NOCOREDUMP; } - if(flags & ST_RELATIME) + if(flags & MNT_RELATIME) { log_write("\t\tVolume only updates access time on changes.\n"); - flags -= ST_RELATIME; + flags -= MNT_RELATIME; } - if(flags & ST_IGNORE) + if(flags & MNT_IGNORE) { log_write("\t\tVolume does not appear in df.\n"); - flags -= ST_IGNORE; + flags -= MNT_IGNORE; } - if(flags & ST_SYMPERM) + if(flags & MNT_SYMPERM) { log_write("\t\tVolume recognizes symbolic link permissions.\n"); - flags -= ST_SYMPERM; + flags -= MNT_SYMPERM; } - if(flags & ST_NODEVMTIME) + if(flags & MNT_NODEVMTIME) { log_write("\t\tVolume does not update modification times for devices.\n"); - flags -= ST_NODEVMTIME; + flags -= MNT_NODEVMTIME; } - if(flags & ST_SOFTDEP) + if(flags & MNT_SOFTDEP) { log_write("\t\tVolume uses soft dependencies.\n"); - flags -= ST_SOFTDEP; + flags -= MNT_SOFTDEP; } - if(flags & ST_LOG) + if(flags & MNT_LOG) { log_write("\t\tVolume uses logging.\n"); - flags -= ST_LOG; + flags -= MNT_LOG; } - if(flags & ST_EXTATTR) + if(flags & MNT_EXTATTR) { log_write("\t\tVolume has extended attributes enabled.\n"); - flags -= ST_EXTATTR; + flags -= MNT_EXTATTR; } - if(flags & ST_EXRDONLY) + if(flags & MNT_EXRDONLY) { log_write("\t\tVolume is exported read-only.\n"); - flags -= ST_EXRDONLY; + flags -= MNT_EXRDONLY; } - if(flags & ST_EXPORTED) + if(flags & MNT_EXPORTED) { log_write("\t\tVolume is exported.\n"); - flags -= ST_EXPORTED; + flags -= MNT_EXPORTED; } - if(flags & ST_DEFEXPORTED) + if(flags & MNT_DEFEXPORTED) { log_write("\t\tVolume is exported to the world.\n"); - flags -= ST_DEFEXPORTED; + flags -= MNT_DEFEXPORTED; } - if(flags & ST_EXPORTANON) + if(flags & MNT_EXPORTANON) { log_write("\t\tVolume uses anon id.\n"); - flags -= ST_EXPORTANON; + flags -= MNT_EXPORTANON; } - if(flags & ST_EXKERB) + if(flags & MNT_EXKERB) { log_write("\t\tVolume is exported with Kerberos ID.\n"); - flags -= ST_EXKERB; + flags -= MNT_EXKERB; } - if(flags & ST_EXNORESPORT) + if(flags & MNT_EXNORESPORT) { log_write("\t\tVolume export does not enforce reserved ports.\n"); - flags -= ST_EXNORESPORT; + flags -= MNT_EXNORESPORT; } - if(flags & ST_EXPUBLIC) + if(flags & MNT_EXPUBLIC) { log_write("\t\tVolume is exported publicly.\n"); - flags -= ST_EXPUBLIC; + flags -= MNT_EXPUBLIC; } - if(flags & ST_LOCAL) + if(flags & MNT_LOCAL) { log_write("\t\tVolume is local.\n"); - flags -= ST_LOCAL; + flags -= MNT_LOCAL; } - if(flags & ST_QUOTA) + if(flags & MNT_QUOTA) { log_write("\t\tVolume has quotas enabled.\n"); - flags -= ST_QUOTA; + flags -= MNT_QUOTA; } - if(flags & ST_ROOTFS) + if(flags & MNT_ROOTFS) { log_write("\t\tVolume is the root filesystem.\n"); - flags -= ST_ROOTFS; + flags -= MNT_ROOTFS; } - if(flags & ST_DISCARD) + if(flags & MNT_DISCARD) { log_write("\t\tVolume is TRIMmed/DISCARDed.\n"); - flags -= ST_DISCARD; + flags -= MNT_DISCARD; } - if(flags & ST_AUTOMOUNTED) + if(flags & MNT_AUTOMOUNTED) { log_write("\t\tVolume is automounted.\n"); - flags -= ST_AUTOMOUNTED; + flags -= MNT_AUTOMOUNTED; } if(flags) { log_write("\t\tRemaining flags: 0x%08lX\n", flags); } } -#endif \ No newline at end of file +#endif + +#if defined(__FreeBSD__) +void FreeBsdPrintStatfsFlags(uint64_t flags) +{ + log_write("\tFlags:\n"); + + if(flags & MNT_RDONLY) + { + log_write("\t\tVolume is read-only.\n"); + flags -= MNT_RDONLY; + } + + if(flags & MNT_NOEXEC) + { + log_write("\t\tVolume disallows program execution.\n"); + flags -= MNT_NOEXEC; + } + + if(flags & MNT_NOSUID) + { + log_write("\t\tVolume ignores suid and sgid bits.\n"); + flags -= MNT_NOSUID; + } + + if(flags & MNT_SYNCHRONOUS) + { + log_write("\t\tVolume writes are synced at once.\n"); + flags -= MNT_SYNCHRONOUS; + } + + if(flags & MNT_ASYNC) + { + log_write("\t\tVolume is written asynchronously.\n"); + flags -= MNT_ASYNC; + } + + if(flags & MNT_SOFTDEP) + { + log_write("\t\tVolume uses soft dependencies.\n"); + flags -= MNT_SOFTDEP; + } + + if(flags & MNT_GJOURNAL) + { + log_write("\t\tVolume uses journaling with gjournal.\n"); + flags -= MNT_GJOURNAL; + } + + if(flags & MNT_SUIDDIR) + { + log_write("\t\tVolume handles SUID in directories in a special way.\n"); + flags -= MNT_SUIDDIR; + } + + if(flags & MNT_UNION) + { + log_write("\t\tVolume is a union.\n"); + flags -= MNT_UNION; + } + + if(flags & MNT_NOSYMFOLLOW) + { + log_write("\t\tVolume does not follow symbolic links.\n"); + flags -= MNT_NOSYMFOLLOW; + } + + if(flags & MNT_NOCLUSTERR) + { + log_write("\t\tVolume has read clustering disabled.\n"); + flags -= MNT_NOCLUSTERR; + } + + if(flags & MNT_NOCLUSTERW) + { + log_write("\t\tVolume has write clustering disabled.\n"); + flags -= MNT_NOCLUSTERW; + } + + if(flags & MNT_MULTILABEL) + { + log_write("\t\tVolume supports mandatory access control for individual objects.\n"); + flags -= MNT_MULTILABEL; + } + + if(flags & MNT_ACLS) + { + log_write("\t\tVolume supports Access Control Lists.\n"); + flags -= MNT_ACLS; + } + + if(flags & MNT_LOCAL) + { + log_write("\t\tVolume is local.\n"); + flags -= MNT_LOCAL; + } + + if(flags & MNT_QUOTA) + { + log_write("\t\tVolume has quotas enabled.\n"); + flags -= MNT_QUOTA; + } + + if(flags & MNT_ROOTFS) + { + log_write("\t\tVolume is the root filesystem.\n"); + flags -= MNT_ROOTFS; + } + + if(flags & MNT_EXRDONLY) + { + log_write("\t\tVolume is exported read-only.\n"); + flags -= MNT_EXRDONLY; + } + + if(flags & MNT_NOATIME) + { + log_write("\t\tVolume does not update access times.\n"); + flags -= MNT_NOATIME; + } + + if(flags & MNT_USER) + { + log_write("\t\tVolume has been mounted by a user.\n"); + flags -= MNT_USER; + } + + if(flags & MNT_EXPORTED) + { + log_write("\t\tVolume is exported.\n"); + flags -= MNT_EXPORTED; + } + + if(flags & MNT_DEFEXPORTED) + { + log_write("\t\tVolume is exported to the world.\n"); + flags -= MNT_DEFEXPORTED; + } + + if(flags & MNT_EXPORTANON) + { + log_write("\t\tVolume uses anon id.\n"); + flags -= MNT_EXPORTANON; + } + + if(flags & MNT_EXKERB) + { + log_write("\t\tVolume is exported with Kerberos ID.\n"); + flags -= MNT_EXKERB; + } + + if(flags & MNT_EXPUBLIC) + { + log_write("\t\tVolume is exported publicly.\n"); + flags -= MNT_EXPUBLIC; + } + + if(flags & MNT_IGNORE) + { + log_write("\t\tVolume does not appear in df.\n"); + flags -= MNT_IGNORE; + } + + if(flags & MNT_AUTOMOUNTED) + { + log_write("\t\tVolume is automounted.\n"); + flags -= MNT_AUTOMOUNTED; + } + + if(flags & MNT_NFS4ACLS) + { + log_write("\t\tVolume supports NFS4 access control lists.\n"); + flags -= MNT_NFS4ACLS; + } + + if(flags & MNT_SUJ) + { + log_write("\t\tVolume uses journaled soft updates.\n"); + flags -= MNT_SUJ; + } + + if(flags & MNT_UNTRUSTED) + { + log_write("\t\tVolume's metadata is untrusted.\n"); + flags -= MNT_UNTRUSTED; + } + + if(flags & MNT_VERIFIED) + { + log_write("\t\tVolume is verified.\n"); + flags -= MNT_VERIFIED; + } + + if(flags) { log_write("\t\tRemaining flags: 0x%08lX\n", flags); } +} +#endif diff --git a/setter/src/unix/bsd/volume.h b/setter/src/unix/bsd/volume.h index a1fa3dc..d75046f 100644 --- a/setter/src/unix/bsd/volume.h +++ b/setter/src/unix/bsd/volume.h @@ -25,6 +25,14 @@ Copyright (C) 2011-2021 Natalia Portillo #ifndef AARU_FSTESTER_SETTER_SRC_BSD_VOLUME_H_ #define AARU_FSTESTER_SETTER_SRC_BSD_VOLUME_H_ +#if defined(HAVE_SYS_STATVFS_H) +#include +#endif + +#if defined(HAVE_SYS_MOUNT_H) +#include +#endif + #if defined(__NetBSD__) #ifndef ST_RDONLY #define ST_RDONLY 0x00000001 /* read only filesystem */ @@ -139,4 +147,130 @@ Copyright (C) 2011-2021 Natalia Portillo #endif #endif // NetBSD +#if defined(__FreeBSD__) +#ifndef MNT_RDONLY +#define MNT_RDONLY 0x0000000000000001ULL /* read only filesystem */ +#endif + +#ifndef MNT_SYNCHRONOUS +#define MNT_SYNCHRONOUS 0x0000000000000002ULL /* fs written synchronously */ +#endif + +#ifndef MNT_NOEXEC +#define MNT_NOEXEC 0x0000000000000004ULL /* can't exec from filesystem */ +#endif + +#ifndef MNT_NOSUID +#define MNT_NOSUID 0x0000000000000008ULL /* don't honor setuid fs bits */ +#endif + +#ifndef MNT_NFS4ACLS +#define MNT_NFS4ACLS 0x0000000000000010ULL /* enable NFS version 4 ACLs */ +#endif + +#ifndef MNT_UNION +#define MNT_UNION 0x0000000000000020ULL /* union with underlying fs */ +#endif + +#ifndef MNT_ASYNC +#define MNT_ASYNC 0x0000000000000040ULL /* fs written asynchronously */ +#endif + +#ifndef MNT_SUIDDIR +#define MNT_SUIDDIR 0x0000000000100000ULL /* special SUID dir handling */ +#endif + +#ifndef MNT_SOFTDEP +#define MNT_SOFTDEP 0x0000000000200000ULL /* using soft updates */ +#endif + +#ifndef MNT_NOSYMFOLLOW +#define MNT_NOSYMFOLLOW 0x0000000000400000ULL /* do not follow symlinks */ +#endif + +#ifndef MNT_GJOURNAL +#define MNT_GJOURNAL 0x0000000002000000ULL /* GEOM journal support enabled */ +#endif + +#ifndef MNT_MULTILABEL +#define MNT_MULTILABEL 0x0000000004000000ULL /* MAC support for objects */ +#endif + +#ifndef MNT_ACLS +#define MNT_ACLS 0x0000000008000000ULL /* ACL support enabled */ +#endif + +#ifndef MNT_NOATIME +#define MNT_NOATIME 0x0000000010000000ULL /* dont update file access time */ +#endif + +#ifndef MNT_NOCLUSTERR +#define MNT_NOCLUSTERR 0x0000000040000000ULL /* disable cluster read */ +#endif + +#ifndef MNT_NOCLUSTERW +#define MNT_NOCLUSTERW 0x0000000080000000ULL /* disable cluster write */ +#endif + +#ifndef MNT_SUJ +#define MNT_SUJ 0x0000000100000000ULL /* using journaled soft updates */ +#endif + +#ifndef MNT_AUTOMOUNTED +#define MNT_AUTOMOUNTED 0x0000000200000000ULL /* mounted by automountd(8) */ +#endif + +#ifndef MNT_UNTRUSTED +#define MNT_UNTRUSTED 0x0000000800000000ULL /* filesys metadata untrusted */ +#endif + +#ifndef MNT_EXRDONLY +#define MNT_EXRDONLY 0x0000000000000080ULL /* exported read only */ +#endif + +#ifndef MNT_EXPORTED +#define MNT_EXPORTED 0x0000000000000100ULL /* filesystem is exported */ +#endif + +#ifndef MNT_DEFEXPORTED +#define MNT_DEFEXPORTED 0x0000000000000200ULL /* exported to the world */ +#endif + +#ifndef MNT_EXPORTANON +#define MNT_EXPORTANON 0x0000000000000400ULL /* anon uid mapping for all */ +#endif + +#ifndef MNT_EXKERB +#define MNT_EXKERB 0x0000000000000800ULL /* exported with Kerberos */ +#endif + +#ifndef MNT_EXPUBLIC +#define MNT_EXPUBLIC 0x0000000020000000ULL /* public export (WebNFS) */ +#endif + +#ifndef MNT_LOCAL +#define MNT_LOCAL 0x0000000000001000ULL /* filesystem is stored locally */ +#endif + +#ifndef MNT_QUOTA +#define MNT_QUOTA 0x0000000000002000ULL /* quotas are enabled on fs */ +#endif + +#ifndef MNT_ROOTFS +#define MNT_ROOTFS 0x0000000000004000ULL /* identifies the root fs */ +#endif + +#ifndef MNT_USER +#define MNT_USER 0x0000000000008000ULL /* mounted by a user */ +#endif + +#ifndef MNT_IGNORE +#define MNT_IGNORE 0x0000000000800000ULL /* do not show entry in df */ +#endif + +#ifndef MNT_VERIFIED +#define MNT_VERIFIED 0x0000000400000000ULL /* filesystem is verified */ +#endif +#endif // FreeBSD + #endif // AARU_FSTESTER_SETTER_SRC_BSD_VOLUME_H_ diff --git a/setter/src/unix/volume.c b/setter/src/unix/volume.c index e2ea5b7..d1b60ca 100644 --- a/setter/src/unix/volume.c +++ b/setter/src/unix/volume.c @@ -193,6 +193,8 @@ void GetVolumeInfo(const char* path, size_t* clusterSize) LinuxPrintStatfsFlags(buf.f_flags); #elif defined(__APPLE__) && defined(__MACH__) DarwinPrintStatfsFlags(buf.f_flags); +#elif defined(__FreeBSD__) + FreeBsdPrintStatfsFlags(buf.f_flags); #else log_write("\tFlags: 0x%08lX\n", buf.f_flags); #endif