Home | History | Annotate | Download | only in hugeshmctl
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2004
      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  *	hugeshmctl02.c
     23  *
     24  * DESCRIPTION
     25  *	hugeshmctl02 - check for EACCES, EFAULT and EINVAL errors
     26  *
     27  * ALGORITHM
     28  *	create a large shared memory segment without read or write permissions
     29  *	create a large shared memory segment with read & write permissions
     30  *	loop if that option was specified
     31  *	  call shmctl() using five different invalid cases
     32  *	  check the errno value
     33  *	    issue a PASS message if we get EACCES, EFAULT or EINVAL
     34  *	  otherwise, the tests fails
     35  *	    issue a FAIL message
     36  *	call cleanup
     37  *
     38  * USAGE:  <for command-line>
     39  *  hugeshmctl02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
     40  *     where,  -c n : Run n copies concurrently.
     41  *             -e   : Turn on errno logging.
     42  *	       -i n : Execute test n times.
     43  *	       -I x : Execute test for x seconds.
     44  *	       -P x : Pause for x seconds between iterations.
     45  *	       -t   : Turn on syscall timing.
     46  *
     47  * HISTORY
     48  *	03/2001 - Written by Wayne Boyer
     49  *	04/2004 - Updated by Robbie Williamson
     50  *
     51  * RESTRICTIONS
     52  *	none
     53  */
     54 
     55 #include <pwd.h>
     56 #include "test.h"
     57 #include "safe_macros.h"
     58 #include "mem.h"
     59 #include "hugetlb.h"
     60 
     61 char *TCID = "hugeshmctl02";
     62 int TST_TOTAL = 4;
     63 
     64 static size_t shm_size;
     65 static int shm_id_1 = -1;
     66 static int shm_id_2 = -1;
     67 static int shm_id_3 = -1;
     68 static struct shmid_ds buf;
     69 
     70 static long hugepages = 128;
     71 static option_t options[] = {
     72 	{"s:", &sflag, &nr_opt},
     73 	{NULL, NULL, NULL}
     74 };
     75 
     76 struct test_case_t {
     77 	int *shmid;
     78 	int cmd;
     79 	struct shmid_ds *sbuf;
     80 	int error;
     81 } TC[] = {
     82 	/* EFAULT - IPC_SET & buf isn't valid */
     83 	{
     84 	&shm_id_2, IPC_SET, (struct shmid_ds *)-1, EFAULT},
     85 	    /* EFAULT - IPC_STAT & buf isn't valid */
     86 	{
     87 	&shm_id_2, IPC_STAT, (struct shmid_ds *)-1, EFAULT},
     88 	    /* EINVAL - the shmid is not valid */
     89 	{
     90 	&shm_id_3, IPC_STAT, &buf, EINVAL},
     91 	    /* EINVAL - the command is not valid */
     92 	{
     93 &shm_id_2, -1, &buf, EINVAL},};
     94 
     95 int main(int ac, char **av)
     96 {
     97 	int lc, i;
     98 
     99 	tst_parse_opts(ac, av, options, NULL);
    100 
    101 	if (sflag)
    102 		hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX);
    103 
    104 	setup();
    105 
    106 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    107 		tst_count = 0;
    108 
    109 		for (i = 0; i < TST_TOTAL; i++) {
    110 			TEST(shmctl(*(TC[i].shmid), TC[i].cmd, TC[i].sbuf));
    111 			if (TEST_RETURN != -1) {
    112 				tst_resm(TFAIL, "shmctl succeeded "
    113 					 "unexpectedly");
    114 				continue;
    115 			}
    116 			if (TEST_ERRNO == TC[i].error)
    117 				tst_resm(TPASS | TTERRNO, "shmctl failed "
    118 					 "as expected");
    119 			else
    120 				tst_resm(TFAIL | TTERRNO, "shmctl failed "
    121 					 "unexpectedly - expect errno = "
    122 					 "%d, got", TC[i].error);
    123 		}
    124 	}
    125 	cleanup();
    126 	tst_exit();
    127 }
    128 
    129 void setup(void)
    130 {
    131 	long hpage_size;
    132 
    133 	tst_require_root();
    134 	check_hugepage();
    135 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    136 	tst_tmpdir();
    137 
    138 	orig_hugepages = get_sys_tune("nr_hugepages");
    139 	set_sys_tune("nr_hugepages", hugepages, 1);
    140 	hpage_size = read_meminfo("Hugepagesize:") * 1024;
    141 
    142 	shm_size = hpage_size * hugepages / 2;
    143 	update_shm_size(&shm_size);
    144 	shmkey = getipckey(cleanup);
    145 
    146 	/* create a shared memory segment without read or write permissions */
    147 	shm_id_1 = shmget(shmkey, shm_size, SHM_HUGETLB | IPC_CREAT | IPC_EXCL);
    148 	if (shm_id_1 == -1)
    149 		tst_brkm(TBROK | TERRNO, cleanup, "shmget #1");
    150 
    151 	/* create a shared memory segment with read and write permissions */
    152 	shm_id_2 = shmget(shmkey + 1, shm_size,
    153 			  SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
    154 	if (shm_id_2 == -1)
    155 		tst_brkm(TBROK | TERRNO, cleanup, "shmget #2");
    156 
    157 	TEST_PAUSE;
    158 }
    159 
    160 void cleanup(void)
    161 {
    162 	rm_shm(shm_id_1);
    163 	rm_shm(shm_id_2);
    164 
    165 	set_sys_tune("nr_hugepages", orig_hugepages, 0);
    166 
    167 	tst_rmdir();
    168 }
    169