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 * Test Name: mremap01 22 * 23 * Test Description: 24 * Verify that, mremap() succeeds when used to expand the existing 25 * virtual memory mapped region to the requested size where the 26 * virtual memory area was previously mapped to a file using mmap(). 27 * 28 * Expected Result: 29 * mremap() should succeed returning the address of new virtual memory area. 30 * The expanded mapped memory region should be accessible and able to 31 * synchronize with the file. 32 * 33 * Algorithm: 34 * Setup: 35 * Setup signal handling. 36 * Create temporary directory. 37 * Pause for SIGUSR1 if option specified. 38 * 39 * Test: 40 * Loop if the proper options are given. 41 * Execute system call 42 * Check return code, if system call failed (return=-1) 43 * Log the errno and Issue a FAIL message. 44 * Otherwise, 45 * Verify the Functionality of system call 46 * if successful, 47 * Issue Functionality-Pass message. 48 * Otherwise, 49 * Issue Functionality-Fail message. 50 * Cleanup: 51 * Print errno log and/or timing stats if options given 52 * Delete the temporary directory created. 53 * 54 * Usage: <for command-line> 55 * mremap01 [-c n] [-f] [-i n] [-I x] [-P x] [-t] 56 * where, -c n : Run n copies concurrently. 57 * -f : Turn off functionality Testing. 58 * -i n : Execute test n times. 59 * -I x : Execute test for x seconds. 60 * -P x : Pause for x seconds between iterations. 61 * -t : Turn on syscall timing. 62 * 63 * HISTORY 64 * 07/2001 Ported by Wayne Boyer 65 * 66 * 11/09/2001 Manoj Iyer (manjo@austin.ibm.com) 67 * Modified. 68 * - #include <linux/mman.h> should not be included as per man page for 69 * mremap, #include <sys/mman.h> alone should do the job. But inorder 70 * to include definition of MREMAP_MAYMOVE defined in bits/mman.h 71 * (included by sys/mman.h) __USE_GNU needs to be defined. 72 * There may be a more elegant way of doing this... 73 * 74 * RESTRICTIONS: 75 * None. 76 */ 77#include <unistd.h> 78#include <errno.h> 79#define __USE_GNU 80#include <sys/mman.h> 81#undef __USE_GNU 82#include <fcntl.h> 83 84#include "test.h" 85 86#define TEMPFILE "mremapfile" 87 88char *TCID = "mremap01"; 89int TST_TOTAL = 1; 90char *addr; /* addr of memory mapped region */ 91int memsize; /* memory mapped size */ 92int newsize; /* new size of virtual memory block */ 93int fildes; /* file descriptor for tempfile */ 94 95void setup(); /* Main setup function of test */ 96void cleanup(); /* cleanup function for the test */ 97 98int main(int ac, char **av) 99{ 100 int ind; /* counter variable */ 101 102 tst_parse_opts(ac, av, NULL, NULL); 103 104 tst_count = 0; 105 106 setup(); 107 108 /* 109 * Call mremap to expand the existing mapped 110 * memory region (memsize) by newsize limits. 111 */ 112 addr = mremap(addr, memsize, newsize, MREMAP_MAYMOVE); 113 114 /* Check for the return value of mremap() */ 115 if (addr == MAP_FAILED) 116 tst_brkm(TFAIL | TERRNO, cleanup, "mremap failed"); 117 118 /* 119 * Attempt to initialize the expanded memory 120 * mapped region with data. If the map area 121 * was bad, we'd get SIGSEGV. 122 */ 123 for (ind = 0; ind < newsize; ind++) { 124 addr[ind] = (char)ind; 125 } 126 127 /* 128 * Memory mapped area is good. Now, attempt 129 * to synchronize the mapped memory region 130 * with the file. 131 */ 132 if (msync(addr, newsize, MS_SYNC) != 0) { 133 tst_resm(TFAIL | TERRNO, "msync failed to synch " 134 "mapped file"); 135 } else { 136 tst_resm(TPASS, "Functionality of " 137 "mremap() is correct"); 138 } 139 140 cleanup(); 141 tst_exit(); 142} 143 144/* 145 * void 146 * setup() - performs all ONE TIME setup for this test. 147 * 148 * Get system page size, Set the size of virtual memory area and the 149 * new size after resize, 150 * Creat a temporary directory and a file under it. 151 * Stratch the file size to the size of virtual memory area and 152 * write 1 byte (\0). Map the temporary file for the length of virtual 153 * memory (memsize) into memory. 154 */ 155void setup(void) 156{ 157 int pagesz; /* system's page size */ 158 159 tst_sig(NOFORK, DEF_HANDLER, cleanup); 160 161 TEST_PAUSE; 162 163 /* Get the system page size */ 164 if ((pagesz = getpagesize()) < 0) { 165 tst_brkm(TFAIL, NULL, 166 "getpagesize failed to get system page size"); 167 } 168 169 /* Get the size of virtual memory area to be mapped */ 170 memsize = (1000 * pagesz); 171 172 /* Get the New size of virtual memory block after resize */ 173 newsize = (memsize * 2); 174 175 tst_tmpdir(); 176 177 /* Creat a temporary file used for mapping */ 178 if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) 179 tst_brkm(TBROK | TERRNO, cleanup, "opening %s failed", 180 TEMPFILE); 181 182 /* Stretch the file to the size of virtual memory area */ 183 if (lseek(fildes, (off_t) memsize, SEEK_SET) != (off_t) memsize) { 184 tst_brkm(TBROK | TERRNO, cleanup, 185 "lseeking to %d offset pos. failed", memsize); 186 } 187 188 /* Write one byte data into temporary file */ 189 if (write(fildes, "\0", 1) != 1) { 190 tst_brkm(TBROK, cleanup, "writing to %s failed", TEMPFILE); 191 } 192 193 /* 194 * Call mmap to map virtual memory (memsize bytes) from the 195 * beginning of temporary file (offset is 0) into memory. 196 */ 197 addr = mmap(0, memsize, PROT_WRITE, MAP_SHARED, fildes, 0); 198 199 /* Check for the return value of mmap() */ 200 if (addr == (char *)MAP_FAILED) { 201 tst_brkm(TBROK, cleanup, "mmaping Failed on %s", TEMPFILE); 202 } 203 204 /* Stretch the file to newsize of virtual memory block */ 205 if (lseek(fildes, (off_t) newsize, SEEK_SET) != (off_t) newsize) { 206 tst_brkm(TBROK, cleanup, "lseek() to %d offset pos. Failed, " 207 "error=%d : %s", newsize, errno, strerror(errno)); 208 } 209 210 /* Write one byte data into temporary file */ 211 if (write(fildes, "\0", 1) != 1) { 212 tst_brkm(TBROK | TERRNO, cleanup, "writing to %s failed", 213 TEMPFILE); 214 } 215} 216 217/* 218 * void 219 * cleanup() - performs all ONE TIME cleanup for this test at 220 * completion or premature exit. 221 * Unmap the mapped memory area done in the test. 222 * Close the temporary file. 223 * Remove the temporary directory. 224 */ 225void cleanup(void) 226{ 227 228 /* Unmap the mapped memory */ 229 if (munmap(addr, newsize) != 0) 230 tst_brkm(TBROK | TERRNO, NULL, "munmap failed"); 231 232 /* Close the temporary file */ 233 if (close(fildes) < 0) { 234 tst_brkm(TBROK, NULL, "closing %s failed", TEMPFILE); 235 } 236 237 tst_rmdir(); 238} 239