Index: kern_descrip_test.c =================================================================== --- kern_descrip_test.c (revision 262781) +++ kern_descrip_test.c (working copy) @@ -29,14 +29,22 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include +#include #include #include +static int done; +static int oldmaxfiles; + +#define PARALLEL 4 +#define RENDEZVOUS "rendezvous" + ATF_TC_WITHOUT_HEAD(dup2__simple); ATF_TC_BODY(dup2__simple, tc) { @@ -68,11 +76,115 @@ ATF_TC_BODY(dup2__ebadf_when_2nd_arg_out_of_range, ATF_CHECK_EQ(EBADF, errno); } +static void +handler(int s __unused) +{ + done++; +} + +static void +openfiles2(size_t n, int ignore) +{ + int i, r; + + errno = 0; + for (i = 0; i < (int)n; i++) { + if (ignore == 1) { + if ((r = open("/etc/passwd", O_RDONLY)) == -1) + break; + } else + ATF_REQUIRE((r = open("/etc/passwd", O_RDONLY)) != -1); + } + kill(getppid(), SIGUSR1); + + if (r != -1) { + for (;;) { + if (access(RENDEZVOUS, R_OK) != 0) + break; + usleep(1000); + } + } + _exit(0); +} + +static void +openfiles(size_t n, int ignore) +{ + int i, fd; + + signal(SIGUSR1, handler); + ATF_REQUIRE((fd = open(RENDEZVOUS, O_CREAT, 0644)) != -1); + close(fd); + done = 0; + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + openfiles2(n / PARALLEL, ignore); + while (done != PARALLEL) + usleep(1000); + unlink(RENDEZVOUS); + usleep(40000); +} + +static void +cleanup(void) +{ + size_t oldlen; + + if (oldmaxfiles > 0) { + oldlen = sizeof(oldmaxfiles); + if (sysctlbyname("kern.maxfiles", NULL, 0, &oldmaxfiles, + oldlen) == -1) + atf_tc_fail("getsysctlbyname(%s): %s", "kern.maxfiles", + strerror(errno)); + } + unlink(RENDEZVOUS); +} + +ATF_TC(kern.maxfiles__increase); +ATF_TC_HEAD(kern.maxfiles__increase, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Check kern.maxfiles expansion"); +} + +ATF_TC_BODY(kern.maxfiles__increase, tc) +{ + int maxfiles; + size_t oldlen; + + oldlen = sizeof(maxfiles); + if (sysctlbyname("kern.maxfiles", &maxfiles, &oldlen, NULL, 0) == -1) + atf_tc_fail("getsysctlbyname(%s): %s", "kern.maxfiles", + strerror(errno)); +#ifdef TEST + /* The next line will cause: + kern.maxfiles limit exceeded by uid 0, please see tuning(7). + */ + openfiles(maxfiles, 1); +#endif + + if (atexit(cleanup) == -1) + atf_tc_fail("atexit(): %s", strerror(errno)); + oldmaxfiles = maxfiles; + maxfiles += 1000; + if (sysctlbyname("kern.maxfiles", NULL, 0, &maxfiles, oldlen) == -1) + atf_tc_fail("getsysctlbyname(%s): %s", "kern.maxfiles", + strerror(errno)); + openfiles(oldmaxfiles + 50, 0); + if (sysctlbyname("kern.maxfiles", NULL, 0, &oldmaxfiles, + oldlen) == -1) + atf_tc_fail("getsysctlbyname(%s): %s", "kern.maxfiles", + strerror(errno)); + oldmaxfiles = 0; +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, dup2__simple); ATF_TP_ADD_TC(tp, dup2__ebadf_when_2nd_arg_out_of_range); + ATF_TP_ADD_TC(tp, kern.maxfiles__increase); return atf_no_error(); }