Home | History | Annotate | Download | only in sysctl
      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