1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * Copyright (c) 2017 Xiao Yang <yangx.jy@cn.fujitsu.com> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * DESCRIPTION 9f08c3bdfSopenharmony_ci * 1) Test for EPERM when the super-user tries to increase RLIMIT_NOFILE 10f08c3bdfSopenharmony_ci * beyond the system limit. 11f08c3bdfSopenharmony_ci * 2) Test for EINVAL when rlim->rlim_cur is greater than rlim->rlim_max. 12f08c3bdfSopenharmony_ci */ 13f08c3bdfSopenharmony_ci 14f08c3bdfSopenharmony_ci#include <errno.h> 15f08c3bdfSopenharmony_ci#include <sys/time.h> 16f08c3bdfSopenharmony_ci#include <sys/resource.h> 17f08c3bdfSopenharmony_ci#include <linux/fs.h> 18f08c3bdfSopenharmony_ci#include "tst_test.h" 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#if !defined(NR_OPEN) 21f08c3bdfSopenharmony_ci// Taken from definition in /usr/include/linux/fs.h 22f08c3bdfSopenharmony_ci# define NR_OPEN (1024*1024) 23f08c3bdfSopenharmony_ci#endif 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_ci#define NR_OPEN_PATH "/proc/sys/fs/nr_open" 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_cistatic struct rlimit rlim1, rlim2; 28f08c3bdfSopenharmony_cistatic unsigned int nr_open = NR_OPEN; 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_cistatic struct tcase { 31f08c3bdfSopenharmony_ci struct rlimit *rlimt; 32f08c3bdfSopenharmony_ci int exp_err; 33f08c3bdfSopenharmony_ci} tcases[] = { 34f08c3bdfSopenharmony_ci {&rlim1, EPERM}, 35f08c3bdfSopenharmony_ci {&rlim2, EINVAL} 36f08c3bdfSopenharmony_ci}; 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_cistatic void verify_setrlimit(unsigned int n) 39f08c3bdfSopenharmony_ci{ 40f08c3bdfSopenharmony_ci struct tcase *tc = &tcases[n]; 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci TEST(setrlimit(RLIMIT_NOFILE, tc->rlimt)); 43f08c3bdfSopenharmony_ci if (TST_RET != -1) { 44f08c3bdfSopenharmony_ci tst_res(TFAIL, "call succeeded unexpectedly " 45f08c3bdfSopenharmony_ci "(nr_open=%u rlim_cur=%lu rlim_max=%lu)", nr_open, 46f08c3bdfSopenharmony_ci (unsigned long)(tc->rlimt->rlim_cur), 47f08c3bdfSopenharmony_ci (unsigned long)(tc->rlimt->rlim_max)); 48f08c3bdfSopenharmony_ci return; 49f08c3bdfSopenharmony_ci } 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_ci if (TST_ERR != tc->exp_err) { 52f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "setrlimit() should fail with %s, got", 53f08c3bdfSopenharmony_ci tst_strerrno(tc->exp_err)); 54f08c3bdfSopenharmony_ci } else { 55f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "setrlimit() failed as expected"); 56f08c3bdfSopenharmony_ci } 57f08c3bdfSopenharmony_ci} 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_cistatic void setup(void) 60f08c3bdfSopenharmony_ci{ 61f08c3bdfSopenharmony_ci if (!access(NR_OPEN_PATH, F_OK)) 62f08c3bdfSopenharmony_ci SAFE_FILE_SCANF(NR_OPEN_PATH, "%u", &nr_open); 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci SAFE_GETRLIMIT(RLIMIT_NOFILE, &rlim1); 65f08c3bdfSopenharmony_ci rlim2.rlim_max = rlim1.rlim_cur; 66f08c3bdfSopenharmony_ci rlim2.rlim_cur = rlim1.rlim_max + 1; 67f08c3bdfSopenharmony_ci rlim1.rlim_max = nr_open + 1; 68f08c3bdfSopenharmony_ci} 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_cistatic struct tst_test test = { 71f08c3bdfSopenharmony_ci .setup = setup, 72f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 73f08c3bdfSopenharmony_ci .test = verify_setrlimit, 74f08c3bdfSopenharmony_ci .needs_root = 1 75f08c3bdfSopenharmony_ci}; 76