Path: blob/main/tests/sys/kern/kern_descrip_test.c
39483 views
/*-1* Copyright (c) 2014 EMC Corp.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <sys/param.h>27#include <sys/limits.h>28#include <sys/resource.h>29#include <sys/stat.h>30#include <sys/sysctl.h>31#include <sys/time.h>32#include <sys/wait.h>3334#include <errno.h>35#include <fcntl.h>36#include <signal.h>37#include <stdio.h>38#include <stdlib.h>39#include <string.h>40#include <strings.h>41#include <unistd.h>4243#include <atf-c.h>4445static volatile sig_atomic_t done;4647#define AFILE "afile"48#define EXPANDBY 100049#define PARALLEL 450#define RENDEZVOUS "rendezvous"51#define VALUE "value"5253ATF_TC_WITHOUT_HEAD(dup2__simple);54ATF_TC_BODY(dup2__simple, tc)55{56int fd1, fd2;57struct stat sb1, sb2;5859ATF_REQUIRE((fd1 = open(AFILE, O_CREAT, 0644)) != -1);60fd2 = 27;61ATF_REQUIRE(dup2(fd1, fd2) != -1);62ATF_REQUIRE(fstat(fd1, &sb1) != -1);63ATF_REQUIRE(fstat(fd2, &sb2) != -1);64ATF_REQUIRE(bcmp(&sb1, &sb2, sizeof(sb1)) == 0);65}6667ATF_TC(dup2__ebadf_when_2nd_arg_out_of_range);68ATF_TC_HEAD(dup2__ebadf_when_2nd_arg_out_of_range, tc)69{70atf_tc_set_md_var(tc, "descr", "Regression test for r234131");71}7273ATF_TC_BODY(dup2__ebadf_when_2nd_arg_out_of_range, tc)74{75int fd1, fd2, ret;7677ATF_REQUIRE((fd1 = open(AFILE, O_CREAT, 0644)) != -1);78fd2 = INT_MAX;79ret = dup2(fd1, fd2);80ATF_CHECK_EQ(-1, ret);81ATF_CHECK_EQ(EBADF, errno);82}8384static void85handler(int s __unused)86{87done++;88}8990static void91openfiles2(size_t n)92{93size_t i;94int r;9596errno = 0;97for (i = 0; i < n; i++) {98r = open(AFILE, O_RDONLY);99if (r < 0) {100fprintf(stderr, "open: %s\n", strerror(errno));101_exit(1);102}103}104kill(getppid(), SIGUSR1);105106for (;;) {107if (access(RENDEZVOUS, R_OK) != 0)108break;109usleep(1000);110}111_exit(0);112}113114static void115openfiles(size_t n)116{117int i, fd;118119signal(SIGUSR1, handler);120ATF_REQUIRE((fd = open(AFILE, O_CREAT, 0644)) != -1);121close(fd);122ATF_REQUIRE((fd = open(RENDEZVOUS, O_CREAT, 0644)) != -1);123close(fd);124done = 0;125for (i = 0; i < PARALLEL; i++)126if (fork() == 0)127openfiles2(n / PARALLEL);128while (done != PARALLEL) {129usleep(1000);130ATF_REQUIRE_EQ_MSG(0, waitpid(-1, NULL, WNOHANG),131"a child exited unexpectedly");132}133unlink(RENDEZVOUS);134for (i = 0; i < PARALLEL; i++)135ATF_CHECK_MSG(wait(NULL) > 0, "wait: %s", strerror(errno));136}137138ATF_TC_WITH_CLEANUP(kern_maxfiles__increase);139ATF_TC_HEAD(kern_maxfiles__increase, tc)140{141atf_tc_set_md_var(tc, "require.user", "root");142atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects");143atf_tc_set_md_var(tc, "descr",144"Check kern.maxfiles expansion");145}146147ATF_TC_BODY(kern_maxfiles__increase, tc)148{149size_t oldlen;150int maxfiles, oldmaxfiles, current;151char buf[80];152struct rlimit rl;153154oldlen = sizeof(maxfiles);155if (sysctlbyname("kern.maxfiles", &maxfiles, &oldlen, NULL, 0) == -1)156atf_tc_fail("getsysctlbyname(%s): %s", "kern.maxfiles",157strerror(errno));158if (sysctlbyname("kern.openfiles", ¤t, &oldlen, NULL, 0) == -1)159atf_tc_fail("getsysctlbyname(%s): %s", "kern.openfiles",160strerror(errno));161162oldmaxfiles = maxfiles;163164/* Store old kern.maxfiles in a symlink for cleanup */165snprintf(buf, sizeof(buf), "%d", oldmaxfiles);166if (symlink(buf, VALUE) == 1)167atf_tc_fail("symlink(%s, %s): %s", buf, VALUE,168strerror(errno));169170maxfiles += EXPANDBY;171if (sysctlbyname("kern.maxfiles", NULL, 0, &maxfiles, oldlen) == -1)172atf_tc_fail("getsysctlbyname(%s): %s", "kern.maxfiles",173strerror(errno));174175rl.rlim_cur = rl.rlim_max = maxfiles;176ATF_REQUIRE_EQ_MSG(0, setrlimit(RLIMIT_NOFILE, &rl),177"setrlimit(RLIMIT_NOFILE, %d): %s", maxfiles, strerror(errno));178179openfiles(oldmaxfiles - current + EXPANDBY / 2);180}181182ATF_TC_CLEANUP(kern_maxfiles__increase, tc)183{184size_t oldlen;185int n, oldmaxfiles;186char buf[80];187188if ((n = readlink(VALUE, buf, sizeof(buf))) > 0) {189buf[MIN((size_t)n, sizeof(buf) - 1)] = '\0';190if (sscanf(buf, "%d", &oldmaxfiles) == 1) {191oldlen = sizeof(oldmaxfiles);192(void) sysctlbyname("kern.maxfiles", NULL, 0,193&oldmaxfiles, oldlen);194}195}196(void)unlink(VALUE);197(void)unlink(AFILE);198}199200ATF_TP_ADD_TCS(tp)201{202203ATF_TP_ADD_TC(tp, dup2__simple);204ATF_TP_ADD_TC(tp, dup2__ebadf_when_2nd_arg_out_of_range);205ATF_TP_ADD_TC(tp, kern_maxfiles__increase);206207return (atf_no_error());208}209210211