nwnss: remove mount-option quota provider fallback

This commit is contained in:
OpenAI
2026-06-19 13:43:46 +00:00
committed by Mario Fetka
parent 4f9282d82d
commit b0fc78b07d
7 changed files with 21 additions and 137 deletions

View File

@@ -95,9 +95,6 @@ int NssQuotaProviderIsNwQuota(NssQuotaProviderKind_e provider);
int NssQuotaProviderIsOtherfsApproximation(NssQuotaProviderKind_e provider);
NssQuotaProviderKind_e NssQuotaProviderForOtherfsCapabilities(uint32_t caps);
int NssQuotaProbeLinuxQuotaCapabilitiesFd(int fd, uint32_t *caps);
NssQuotaProviderKind_e NssQuotaProviderForOtherfsMount(const char *fsType,
const char *mountOptions,
int nwQuotaAvailable);
NssQuotaCheckResult_e NssQuotaCheckWrite(const NssQuotaWriteView_s *view);
const char *NssQuotaCheckResultName(NssQuotaCheckResult_e result);

View File

@@ -557,76 +557,6 @@ int NssQuotaProbeLinuxQuotaCapabilitiesFd(int fd, uint32_t *caps)
#endif
}
static int nssQuotaMountOptionMatches(const char *options, const char *needle)
{
size_t needleLen;
const char *p;
if (options == NULL || needle == NULL || needle[0] == '\0') {
return 0;
}
needleLen = strlen(needle);
p = options;
while (*p != '\0') {
const char *end;
size_t len;
while (*p == ',' || *p == ' ' || *p == '\t') {
p++;
}
end = p;
while (*end != '\0' && *end != ',' && *end != ' ' && *end != '\t') {
end++;
}
len = (size_t)(end - p);
if (len == needleLen && strncmp(p, needle, needleLen) == 0) {
return 1;
}
p = end;
}
return 0;
}
NssQuotaProviderKind_e
NssQuotaProviderForOtherfsMount(const char *fsType, const char *mountOptions,
int nwQuotaAvailable)
{
uint32_t caps = 0;
(void)fsType;
(void)nwQuotaAvailable;
/*
* Compatibility path for callers/tests that only have parsed mount
* properties. Live callers should prefer
* NssQuotaProbeLinuxQuotaCapabilitiesFd() and then pass the resulting
* capability mask to NssQuotaProviderForOtherfsCapabilities(). The
* simulated NWQuota provider is always the OtherFS fallback when no Linux
* quota capability is active.
*/
if (nssQuotaMountOptionMatches(mountOptions, "prjquota") ||
nssQuotaMountOptionMatches(mountOptions, "pquota") ||
nssQuotaMountOptionMatches(mountOptions, "project")) {
caps |= NSS_QUOTA_LINUX_CAP_PROJECT;
}
if (nssQuotaMountOptionMatches(mountOptions, "usrquota") ||
nssQuotaMountOptionMatches(mountOptions, "uquota") ||
nssQuotaMountOptionMatches(mountOptions, "userquota")) {
caps |= NSS_QUOTA_LINUX_CAP_USER;
}
if (nssQuotaMountOptionMatches(mountOptions, "grpquota") ||
nssQuotaMountOptionMatches(mountOptions, "gquota") ||
nssQuotaMountOptionMatches(mountOptions, "quota")) {
caps |= NSS_QUOTA_LINUX_CAP_GROUP;
}
return NssQuotaProviderForOtherfsCapabilities(caps);
}
const char *NssQuotaCheckResultName(NssQuotaCheckResult_e result)
{
switch (result) {

View File

@@ -99,17 +99,16 @@ Optional quota volume tests are also config-gated. For example,
`nwnss.quota.xfs-volume` creates throw-away loop-mounted XFS images and checks
that `libnwnss` detects a plain XFS mount as no Linux quota provider and an XFS
mount with `prjquota` as the Linux project-quota provider. Runtime provider
selection is capability based and not hardcoded to a filesystem name: any
OtherFS mount that reports matching quota mount properties can select the Linux
quota provider, and mounts without Linux quota support fall back to NWQuota
metadata when that metadata path is available. This first root smoke only
creates XFS loop images because XFS is a simple initial loop-volume target. The
test is skipped unless
`NWNSS_QUOTA_XFS_VOLUME_TEST=1` is set in the environment or the build-local
config file. It can run as root, or as a normal user with passwordless sudo for
the small set of loop/mount commands used by the test. Do not store the root
password in `mars_nwe_test_config.sh`; use sudoers `NOPASSWD` for the test
commands or run this one test as root.
selection is kernel-probe based: the test opens the mounted directory and uses
`quotactl_fd()`/`Q_GETINFO` capability probing instead of parsing mount options.
Mounts without Linux quota support fall back to NWQuota metadata. This first
root smoke only creates XFS loop images because XFS is a simple initial
loop-volume target; live provider selection is not tied to the filesystem name.
The test is skipped unless `NWNSS_QUOTA_XFS_VOLUME_TEST=1` is set in the
environment or the build-local config file. It can run as root or as a normal user with passwordless sudo for the small
set of loop/mount commands used by the test. Do not store the root password in
`mars_nwe_test_config.sh`; use sudoers `NOPASSWD` for the test commands or run
this one test as root.
On Gentoo, install/enable `sudo`, add the test user to `wheel`, and edit sudoers
with `visudo`. A locked-down local drop-in can be created with
@@ -122,8 +121,9 @@ Cmnd_Alias MARS_NWE_QUOTA_TEST = /usr/sbin/mkfs.xfs, /usr/bin/mount, /usr/bin/um
```
If the system is not merged-/usr, use `/sbin/mkfs.xfs`, `/bin/mount`, and
`/bin/umount` instead. Keep the build-local config at mode `0600`; it may hold
NCP test passwords, but not the root password.
`/bin/umount` instead. Keep the build-local config at mode `0600`; it may hold NCP test passwords,
but not the root password. For the optional root-only quota smoke, use sudoers
`NOPASSWD` or run the single test as root.
Quota-dual/all smokes additionally need `MARS_NWE_TEST_QUOTA_SYSROOT` and
`MARS_NWE_TEST_QUOTA_MOUNT`; optional variables include

View File

@@ -26,11 +26,10 @@
# Enable optional XFS loop-volume quota smoke for libnwnss.
# It creates throw-away loop-mounted XFS images in TMPDIR. Linux project
# quota provider detection is capability based and not hardcoded to a filesystem
# name. This first root smoke only creates XFS loop images because XFS is a
# quota provider detection is kernel-probe based and does not parse mount
# options. This first root smoke only creates XFS loop images because XFS is a
# simple initial loop-volume target. The test runs as root or via passwordless
# sudo. Do not store the root password here. Configure sudoers for only the
# needed test commands, or run this single test as root.
# sudo configured through sudoers. Do not store the root password here.
# NWNSS_QUOTA_XFS_VOLUME_TEST=1
# NWNSS_QUOTA_XFS_IMAGE_SIZE=512M
# NWNSS_QUOTA_SUDO=sudo

View File

@@ -40,7 +40,7 @@ if [ "$(id -u)" != 0 ]; then
command -v "${NWNSS_QUOTA_SUDO:-sudo}" >/dev/null 2>&1 || \
skip "sudo is not available and the test is not running as root"
run_root true >/dev/null 2>&1 || \
skip "passwordless sudo is required for loop-mounted XFS quota tests"
skip "root or passwordless sudo is required for loop-mounted XFS quota tests"
fi
TMPROOT=$(mktemp -d "${TMPDIR:-/tmp}/nwnss-quota-xfs.XXXXXX")
@@ -66,18 +66,8 @@ run_root mkfs.xfs -f -q "$QUOTA_IMG" >/dev/null 2>&1 || skip "mkfs.xfs failed fo
run_root mount -o loop "$PLAIN_IMG" "$PLAIN_MNT" || skip "plain XFS loop mount failed"
run_root mount -o loop,prjquota "$QUOTA_IMG" "$QUOTA_MNT" || skip "project-quota XFS loop mount failed"
plain_fstype=$(findmnt -n -o FSTYPE --target "$PLAIN_MNT")
plain_opts=$(findmnt -n -o OPTIONS --target "$PLAIN_MNT")
quota_fstype=$(findmnt -n -o FSTYPE --target "$QUOTA_MNT")
quota_opts=$(findmnt -n -o OPTIONS --target "$QUOTA_MNT")
"$PROBE" "$plain_fstype" "$plain_opts" 0 otherfs-nwquota
"$PROBE" "$plain_fstype" "$plain_opts" 1 otherfs-nwquota
"$PROBE" "$quota_fstype" "$quota_opts" 0 otherfs-linux-project-quota
"$PROBE" "$quota_fstype" "$quota_opts" 1 otherfs-linux-project-quota
run_root "$PROBE" --fd "$PLAIN_MNT" otherfs-nwquota
run_root "$PROBE" --fd "$QUOTA_MNT" otherfs-linux-project-quota
printf 'plain XFS: fs=%s options=%s\n' "$plain_fstype" "$plain_opts"
printf 'quota XFS: fs=%s options=%s\n' "$quota_fstype" "$quota_opts"
printf 'plain XFS: probed kernel quota caps -> otherfs-nwquota\n'
printf 'quota XFS: probed kernel quota caps -> otherfs-linux-project-quota\n'

View File

@@ -124,24 +124,6 @@ int main(void)
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_USER_QUOTA);
CHECK(NssQuotaProviderForOtherfsCapabilities(NSS_QUOTA_LINUX_CAP_GROUP) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("xfs", "rw,relatime", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_NWQUOTA);
CHECK(NssQuotaProviderForOtherfsMount("xfs", "rw,relatime", 1) ==
NSS_QUOTA_PROVIDER_OTHERFS_NWQUOTA);
CHECK(NssQuotaProviderForOtherfsMount("xfs", "rw,prjquota", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_PROJECT_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("btrfs", "rw,pquota", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_PROJECT_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("ext4", "rw,project", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_PROJECT_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("tmpfs", "rw,uquota", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_USER_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("ext4", "rw,usrquota", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_USER_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("anyfs", "rw,grpquota", 0) ==
NSS_QUOTA_PROVIDER_OTHERFS_LINUX_QUOTA);
CHECK(NssQuotaProviderForOtherfsMount("anyfs", "rw,relatime", 1) ==
NSS_QUOTA_PROVIDER_OTHERFS_NWQUOTA);
memset(&writeView, 0, sizeof(writeView));

View File

@@ -81,24 +81,10 @@ static int probe_fd_provider(const char *path, const char *expectedName)
int main(int argc, char **argv)
{
NssQuotaProviderKind_e actual;
int nwQuotaAvailable;
if (argc == 4 && strcmp(argv[1], "--fd") == 0) {
return probe_fd_provider(argv[2], argv[3]);
}
if (argc != 5) {
fprintf(stderr, "Usage: %s FSTYPE MOUNT_OPTIONS NWQUOTA_AVAILABLE EXPECTED_PROVIDER\n", argv[0]);
fprintf(stderr, " %s --fd MOUNTPOINT EXPECTED_PROVIDER\n", argv[0]);
return 2;
}
/* NWQuota is now the unconditional OtherFS fallback; keep the argument
* only for compatibility with existing test invocations. */
nwQuotaAvailable = atoi(argv[3]) != 0;
(void)nwQuotaAvailable;
actual = NssQuotaProviderForOtherfsMount(argv[1], argv[2], nwQuotaAvailable);
return check_expected(argv[2], actual, argv[4]);
fprintf(stderr, "Usage: %s --fd MOUNTPOINT EXPECTED_PROVIDER\n", argv[0]);
return 2;
}