Index: contrib/netbsd-tests/lib/libc/sys/t_mlock.c =================================================================== --- contrib/netbsd-tests/lib/libc/sys/t_mlock.c +++ contrib/netbsd-tests/lib/libc/sys/t_mlock.c @@ -47,12 +47,89 @@ #include #ifdef __FreeBSD__ +#include #define _KMEMUSER #include #endif static long page = 0; +#ifdef __FreeBSD__ +#define VM_MAX_WIRED "vm.max_wired" + +static void +vm_max_wired_sysctl(int *old_value, int *new_value) +{ + size_t old_len; + size_t new_len = (new_value == NULL ? 0 : sizeof(int)); + + if (old_value == NULL) + printf("Setting the new value to %d\n", *new_value); + else { + ATF_REQUIRE_MSG(sysctlbyname(VM_MAX_WIRED, NULL, &old_len, + new_value, new_len) == 0, + "sysctlbyname(%s) failed: %s", VM_MAX_WIRED, strerror(errno)); + } + + ATF_REQUIRE_MSG(sysctlbyname(VM_MAX_WIRED, old_value, &old_len, + new_value, new_len) == 0, + "sysctlbyname(%s) failed: %s", VM_MAX_WIRED, strerror(errno)); + + if (old_value != NULL) + printf("Saved the old value (%d)\n", *old_value); +} + +static void +set_vm_max_wired(int new_value) +{ + FILE *fp; + int old_value; + + fp = fopen(VM_MAX_WIRED, "w"); + if (fp == NULL) { + atf_tc_skip("could not open %s for writing: %s", + VM_MAX_WIRED, strerror(errno)); + return; + } + + vm_max_wired_sysctl(&old_value, NULL); + + ATF_REQUIRE_MSG(fprintf(fp, "%d", old_value) > 0, + "saving %s failed", VM_MAX_WIRED); + + fclose(fp); + + vm_max_wired_sysctl(NULL, &new_value); +} + +static void +restore_vm_max_wired(void) +{ + FILE *fp; + int saved_max_wired; + + fp = fopen(VM_MAX_WIRED, "r"); + if (fp == NULL) { + perror("fopen failed\n"); + return; + } + + if (fscanf(fp, "%d", &saved_max_wired) != 1) { + perror("fscanf failed\n"); + fclose(fp); + return; + } + + fclose(fp); + printf("old value in %s: %d\n", VM_MAX_WIRED, saved_max_wired); + + if (saved_max_wired == 0) /* This will cripple the test host */ + return; + + vm_max_wired_sysctl(NULL, &saved_max_wired); +} +#endif + ATF_TC(mlock_clip); ATF_TC_HEAD(mlock_clip, tc) { @@ -78,11 +155,19 @@ free(buf); } +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_err); +#else ATF_TC(mlock_err); +#endif ATF_TC_HEAD(mlock_err, tc) { atf_tc_set_md_var(tc, "descr", "Test error conditions in mlock(2) and munlock(2)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif } ATF_TC_BODY(mlock_err, tc) @@ -99,6 +184,8 @@ if ((uintptr_t)VM_MIN_ADDRESS > 0) null_errno = EINVAL; /* NULL is not inside user VM */ #endif + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); #else if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0) atf_tc_fail("failed to read vm.minaddress"); @@ -139,6 +226,14 @@ ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1); } +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_err, tc) +{ + + restore_vm_max_wired(); +} +#endif + ATF_TC(mlock_limits); ATF_TC_HEAD(mlock_limits, tc) { @@ -200,10 +295,18 @@ free(buf); } +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_mmap); +#else ATF_TC(mlock_mmap); +#endif ATF_TC_HEAD(mlock_mmap, tc) { atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif } ATF_TC_BODY(mlock_mmap, tc) @@ -215,6 +318,11 @@ #endif void *buf; +#ifdef __FreeBSD__ + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#endif + /* * Make a wired RW mapping and check that mlock(2) * does not fail for the (already locked) mapping. @@ -248,11 +356,27 @@ ATF_REQUIRE(munmap(buf, page) == 0); } +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_mmap, tc) +{ + + restore_vm_max_wired(); +} +#endif + +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_nested); +#else ATF_TC(mlock_nested); +#endif ATF_TC_HEAD(mlock_nested, tc) { atf_tc_set_md_var(tc, "descr", "Test that consecutive mlock(2) calls succeed"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif } ATF_TC_BODY(mlock_nested, tc) @@ -260,6 +384,11 @@ const size_t maxiter = 100; void *buf; +#ifdef __FreeBSD__ + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#endif + buf = malloc(page); ATF_REQUIRE(buf != NULL); @@ -270,6 +399,14 @@ free(buf); } +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_nested, tc) +{ + + restore_vm_max_wired(); +} +#endif + ATF_TP_ADD_TCS(tp) {