1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * Author: Rajeev Tiwari: rajeevti@in.ibm.com 4 * Copyright (c) 2004 Gernot Payer <gpayer@suse.de> 5 * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 * the GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 /* 23 * This test case provides a functional validation for mincore system call. 24 * We mmap a file of known size (multiple of page size) and lock it in 25 * memory. Then we obtain page location information via mincore and compare 26 * the result with the expected value. 27 */ 28 29 #include <sys/mman.h> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <sys/wait.h> 33 #include <fcntl.h> 34 #include <unistd.h> 35 #include <signal.h> 36 #include <errno.h> 37 38 #include "test.h" 39 #include "safe_macros.h" 40 41 char *TCID = "mincore02"; 42 int TST_TOTAL = 1; 43 44 static int fd = 0; 45 static void *addr = NULL; 46 static int page_size; 47 static int num_pages = 4; 48 static unsigned char *vec = NULL; 49 50 static void cleanup(void) 51 { 52 free(vec); 53 munlock(addr, page_size * num_pages); 54 munmap(addr, page_size * num_pages); 55 close(fd); 56 tst_rmdir(); 57 } 58 59 static void setup(void) 60 { 61 char *buf; 62 size_t size; 63 64 tst_tmpdir(); 65 66 page_size = getpagesize(); 67 if (page_size == -1) 68 tst_brkm(TBROK | TERRNO, cleanup, "Unable to get page size"); 69 70 size = page_size * num_pages; 71 buf = malloc(size); 72 73 memset(buf, 42, size); 74 vec = malloc((size + page_size - 1) / page_size); 75 76 fd = SAFE_OPEN(cleanup, "mincore02", O_CREAT | O_RDWR, 77 S_IRUSR | S_IWUSR); 78 79 /* fill the temporary file with two pages of data */ 80 if (write(fd, buf, size) < 0) { 81 tst_brkm(TBROK | TERRNO, cleanup, 82 "Error in writing to the file"); 83 } 84 free(buf); 85 86 addr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, 87 MAP_SHARED, fd, 0); 88 89 if (addr == MAP_FAILED) { 90 tst_brkm(TBROK | TERRNO, cleanup, 91 "Unable to map file for read/write"); 92 } 93 94 /* lock mmapped file, so mincore returns "in core" for all pages */ 95 if (mlock(addr, size) == -1) 96 tst_brkm(TBROK | TERRNO, cleanup, "Unable to lock the file"); 97 } 98 99 int main(int argc, char **argv) 100 { 101 int lock_pages, counter; 102 int lc; 103 104 tst_parse_opts(argc, argv, NULL, NULL); 105 106 setup(); 107 108 for (lc = 0; TEST_LOOPING(lc); lc++) { 109 tst_count = 0; 110 111 if (mincore(addr, num_pages * page_size, vec) == -1) { 112 tst_brkm(TBROK | TERRNO, cleanup, 113 "Unable to execute mincore system call"); 114 } 115 116 /* check status of pages */ 117 lock_pages = 0; 118 119 for (counter = 0; counter < num_pages; counter++) { 120 if (vec[counter] & 1) 121 lock_pages++; 122 } 123 124 if (lock_pages == num_pages) { 125 tst_resm(TPASS, "%d pages locked, %d pages in-core", num_pages, 126 lock_pages); 127 } else { 128 tst_resm(TFAIL, 129 "not all locked pages are in-core: no. locked: %d, no. in-core: %d", 130 num_pages, lock_pages); 131 } 132 } 133 134 cleanup(); 135 tst_exit(); 136 } 137