1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * NAME 22 * sysctl01.c 23 * 24 * DESCRIPTION 25 * Testcase for testing the basic functionality of sysctl(2) system call. 26 * This testcase attempts to read the kernel parameters using 27 * sysctl({CTL_KERN, KERN_* }, ...) and compares it with the known 28 * values. 29 * 30 * USAGE: <for command-line> 31 * sysctl01 [-c n] [-f] [-i n] [-I x] [-P x] [-t] 32 * where, -c n : Run n copies concurrently. 33 * -f : Turn off functionality Testing. 34 * -i n : Execute test n times. 35 * -I x : Execute test for x seconds. 36 * -P x : Pause for x seconds between iterations. 37 * -t : Turn on syscall timing. 38 * 39 * HISTORY 40 * 07/2001 Ported by Wayne Boyer 41 * 42 * RESTRICTIONS 43 * None 44 */ 45 #include "test.h" 46 #include <stdio.h> 47 #include <errno.h> 48 #include <unistd.h> 49 #include <linux/version.h> 50 #include <sys/utsname.h> 51 #include <linux/unistd.h> 52 #include <linux/sysctl.h> 53 54 char *TCID = "sysctl01"; 55 56 /* This is an older/deprecated syscall that newer arches are omitting */ 57 #ifdef __NR_sysctl 58 59 int TST_TOTAL = 3; 60 61 static int sysctl(int *name, int nlen, void *oldval, size_t * oldlenp, 62 void *newval, size_t newlen) 63 { 64 struct __sysctl_args args = 65 { name, nlen, oldval, oldlenp, newval, newlen }; 66 return syscall(__NR__sysctl, &args); 67 } 68 69 struct utsname buf; 70 char osname[BUFSIZ]; 71 size_t osnamelth; 72 73 void setup(void); 74 void cleanup(void); 75 76 struct test_case_t { 77 char *desc; 78 int name[2]; 79 int size; 80 char *oldval; 81 size_t *oldlen; 82 void *newval; 83 int newlen; 84 int (*cleanup) (); 85 int exp_retval; 86 } TC[] = { 87 { 88 "Test for KERN_OSTYPE", { 89 CTL_KERN, KERN_OSTYPE}, 2, osname, &osnamelth, NULL, 0, NULL, 0}, { 90 "Test for KERN_OSRELEASE", { 91 CTL_KERN, KERN_OSRELEASE}, 2, 92 osname, &osnamelth, NULL, 0, NULL, 0}, { 93 "Test for KERN_VERSION", { 94 CTL_KERN, KERN_VERSION}, 2, osname, &osnamelth, NULL, 0, NULL, 0} 95 }; 96 97 int main(int ac, char **av) 98 { 99 int lc; 100 int i; 101 char *comp_string; 102 103 comp_string = NULL; 104 105 tst_parse_opts(ac, av, NULL, NULL); 106 107 setup(); 108 109 for (lc = 0; TEST_LOOPING(lc); lc++) { 110 111 /* reset tst_count in case we are looping */ 112 tst_count = 0; 113 114 for (i = 0; i < TST_TOTAL; ++i) { 115 116 osnamelth = sizeof(osname); 117 118 switch (i) { 119 case 0: 120 comp_string = buf.sysname; 121 break; 122 case 1: 123 comp_string = buf.release; 124 break; 125 case 2: 126 comp_string = buf.version; 127 break; 128 } 129 130 TEST(sysctl(TC[i].name, TC[i].size, TC[i].oldval, 131 TC[i].oldlen, TC[i].newval, TC[i].newlen)); 132 133 if (TEST_RETURN != 0) { 134 if (TEST_ERRNO == ENOSYS) { 135 tst_resm(TCONF, 136 "You may need to make CONFIG_SYSCTL_SYSCALL=y" 137 " to your kernel config."); 138 } else { 139 tst_resm(TFAIL, 140 "sysctl(2) failed unexpectedly " 141 "errno:%d", TEST_ERRNO); 142 } 143 continue; 144 } 145 146 if (strcmp(TC[i].oldval, comp_string) != 0) { 147 tst_resm(TFAIL, "strings don't match - %s : %s", 148 TC[i].oldval, comp_string); 149 } else { 150 tst_resm(TPASS, "%s is correct", TC[i].desc); 151 } 152 if (TC[i].cleanup) { 153 (void)TC[i].cleanup(); 154 } 155 } 156 } 157 158 cleanup(); 159 tst_exit(); 160 } 161 162 /* 163 * setup() - performs all ONE TIME setup for this test. 164 */ 165 void setup(void) 166 { 167 168 tst_sig(NOFORK, DEF_HANDLER, cleanup); 169 170 TEST_PAUSE; 171 172 /* get kernel name and information */ 173 if (uname(&buf) == -1) { 174 tst_brkm(TBROK, cleanup, "uname() failed"); 175 } 176 } 177 178 /* 179 * cleanup() - performs all ONE TIME cleanup for this test at 180 * completion or premature exit. 181 */ 182 void cleanup(void) 183 { 184 185 } 186 187 #else 188 int TST_TOTAL = 0; 189 190 int main(void) 191 { 192 193 tst_brkm(TCONF, NULL, 194 "This test needs a kernel that has sysctl syscall."); 195 } 196 #endif 197