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 #include "safe_macros.h" 86 87 #define TEMPFILE "mremapfile" 88 89 char *TCID = "mremap01"; 90 int TST_TOTAL = 1; 91 char *addr; /* addr of memory mapped region */ 92 int memsize; /* memory mapped size */ 93 int newsize; /* new size of virtual memory block */ 94 int fildes; /* file descriptor for tempfile */ 95 96 void setup(); /* Main setup function of test */ 97 void cleanup(); /* cleanup function for the test */ 98 99 int main(int ac, char **av) 100 { 101 int ind; /* counter variable */ 102 103 tst_parse_opts(ac, av, NULL, NULL); 104 105 tst_count = 0; 106 107 setup(); 108 109 /* 110 * Call mremap to expand the existing mapped 111 * memory region (memsize) by newsize limits. 112 */ 113 addr = mremap(addr, memsize, newsize, MREMAP_MAYMOVE); 114 115 /* Check for the return value of mremap() */ 116 if (addr == MAP_FAILED) 117 tst_brkm(TFAIL | TERRNO, cleanup, "mremap failed"); 118 119 /* 120 * Attempt to initialize the expanded memory 121 * mapped region with data. If the map area 122 * was bad, we'd get SIGSEGV. 123 */ 124 for (ind = 0; ind < newsize; ind++) { 125 addr[ind] = (char)ind; 126 } 127 128 /* 129 * Memory mapped area is good. Now, attempt 130 * to synchronize the mapped memory region 131 * with the file. 132 */ 133 if (msync(addr, newsize, MS_SYNC) != 0) { 134 tst_resm(TFAIL | TERRNO, "msync failed to synch " 135 "mapped file"); 136 } else { 137 tst_resm(TPASS, "Functionality of " 138 "mremap() is correct"); 139 } 140 141 cleanup(); 142 tst_exit(); 143 } 144 145 /* 146 * void 147 * setup() - performs all ONE TIME setup for this test. 148 * 149 * Get system page size, Set the size of virtual memory area and the 150 * new size after resize, 151 * Creat a temporary directory and a file under it. 152 * Stratch the file size to the size of virtual memory area and 153 * write 1 byte (\0). Map the temporary file for the length of virtual 154 * memory (memsize) into memory. 155 */ 156 void setup(void) 157 { 158 int pagesz; /* system's page size */ 159 160 tst_sig(NOFORK, DEF_HANDLER, cleanup); 161 162 TEST_PAUSE; 163 164 /* Get the system page size */ 165 if ((pagesz = getpagesize()) < 0) { 166 tst_brkm(TFAIL, NULL, 167 "getpagesize failed to get system page size"); 168 } 169 170 /* Get the size of virtual memory area to be mapped */ 171 memsize = (1000 * pagesz); 172 173 /* Get the New size of virtual memory block after resize */ 174 newsize = (memsize * 2); 175 176 tst_tmpdir(); 177 178 /* Creat a temporary file used for mapping */ 179 if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) 180 tst_brkm(TBROK | TERRNO, cleanup, "opening %s failed", 181 TEMPFILE); 182 183 /* Stretch the file to the size of virtual memory area */ 184 if (lseek(fildes, (off_t) memsize, SEEK_SET) != (off_t) memsize) { 185 tst_brkm(TBROK | TERRNO, cleanup, 186 "lseeking to %d offset pos. failed", memsize); 187 } 188 189 /* Write one byte data into temporary file */ 190 if (write(fildes, "\0", 1) != 1) { 191 tst_brkm(TBROK, cleanup, "writing to %s failed", TEMPFILE); 192 } 193 194 /* 195 * Call mmap to map virtual memory (memsize bytes) from the 196 * beginning of temporary file (offset is 0) into memory. 197 */ 198 addr = mmap(0, memsize, PROT_WRITE, MAP_SHARED, fildes, 0); 199 200 /* Check for the return value of mmap() */ 201 if (addr == (char *)MAP_FAILED) { 202 tst_brkm(TBROK, cleanup, "mmaping Failed on %s", TEMPFILE); 203 } 204 205 /* Stretch the file to newsize of virtual memory block */ 206 if (lseek(fildes, (off_t) newsize, SEEK_SET) != (off_t) newsize) { 207 tst_brkm(TBROK, cleanup, "lseek() to %d offset pos. Failed, " 208 "error=%d : %s", newsize, errno, strerror(errno)); 209 } 210 211 /* Write one byte data into temporary file */ 212 if (write(fildes, "\0", 1) != 1) { 213 tst_brkm(TBROK | TERRNO, cleanup, "writing to %s failed", 214 TEMPFILE); 215 } 216 } 217 218 /* 219 * void 220 * cleanup() - performs all ONE TIME cleanup for this test at 221 * completion or premature exit. 222 * Unmap the mapped memory area done in the test. 223 * Close the temporary file. 224 * Remove the temporary directory. 225 */ 226 void cleanup(void) 227 { 228 229 /* Unmap the mapped memory */ 230 if (munmap(addr, newsize) != 0) 231 tst_brkm(TBROK | TERRNO, NULL, "munmap failed"); 232 233 /* Close the temporary file */ 234 SAFE_CLOSE(NULL, fildes); 235 236 tst_rmdir(); 237 } 238