From b0fc78b07da517153a05d19296aee2d6dc149b7e Mon Sep 17 00:00:00 2001 From: OpenAI Date: Fri, 19 Jun 2026 13:43:46 +0000 Subject: [PATCH] nwnss: remove mount-option quota provider fallback --- include/nwnss/internal/nssUserspaceQuota.h | 3 - src/nwnss/nssUserspaceQuota.c | 70 ------------------- tests/README.md | 26 +++---- tests/mars_nwe_test_config.sh.example.in | 7 +- .../quota/nwnss_quota_xfs_volume_test.sh.in | 16 +---- tests/nwnss/quota/test_nwnss_quota.c | 18 ----- .../quota/test_nwnss_quota_mount_probe.c | 18 +---- 7 files changed, 21 insertions(+), 137 deletions(-) diff --git a/include/nwnss/internal/nssUserspaceQuota.h b/include/nwnss/internal/nssUserspaceQuota.h index 8318201..2b7ce3d 100644 --- a/include/nwnss/internal/nssUserspaceQuota.h +++ b/include/nwnss/internal/nssUserspaceQuota.h @@ -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); diff --git a/src/nwnss/nssUserspaceQuota.c b/src/nwnss/nssUserspaceQuota.c index 55ab7ac..f1f52c8 100644 --- a/src/nwnss/nssUserspaceQuota.c +++ b/src/nwnss/nssUserspaceQuota.c @@ -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) { diff --git a/tests/README.md b/tests/README.md index 5e0dbbf..8242301 100644 --- a/tests/README.md +++ b/tests/README.md @@ -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 diff --git a/tests/mars_nwe_test_config.sh.example.in b/tests/mars_nwe_test_config.sh.example.in index 7e7b8bd..f0ebb33 100644 --- a/tests/mars_nwe_test_config.sh.example.in +++ b/tests/mars_nwe_test_config.sh.example.in @@ -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 diff --git a/tests/nwnss/quota/nwnss_quota_xfs_volume_test.sh.in b/tests/nwnss/quota/nwnss_quota_xfs_volume_test.sh.in index fed6397..ec83f97 100644 --- a/tests/nwnss/quota/nwnss_quota_xfs_volume_test.sh.in +++ b/tests/nwnss/quota/nwnss_quota_xfs_volume_test.sh.in @@ -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' diff --git a/tests/nwnss/quota/test_nwnss_quota.c b/tests/nwnss/quota/test_nwnss_quota.c index 5d32c61..f268e20 100644 --- a/tests/nwnss/quota/test_nwnss_quota.c +++ b/tests/nwnss/quota/test_nwnss_quota.c @@ -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)); diff --git a/tests/nwnss/quota/test_nwnss_quota_mount_probe.c b/tests/nwnss/quota/test_nwnss_quota_mount_probe.c index 6650293..adcf48e 100644 --- a/tests/nwnss/quota/test_nwnss_quota_mount_probe.c +++ b/tests/nwnss/quota/test_nwnss_quota_mount_probe.c @@ -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; }