blob: 7de8ad4e67bdf4becaf52d98a2f858bf356331bb [file] [log] [blame]
mridge56130dc2004-08-24 20:30:46 +00001/*
Cyril Hrubis123895c2013-04-24 13:34:46 +02002 * 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>
mridge56130dc2004-08-24 20:30:46 +00006 *
Cyril Hrubis123895c2013-04-24 13:34:46 +02007 * 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.
mridge56130dc2004-08-24 20:30:46 +000011 *
Cyril Hrubis123895c2013-04-24 13:34:46 +020012 * 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.
mridge56130dc2004-08-24 20:30:46 +000016 *
Cyril Hrubis123895c2013-04-24 13:34:46 +020017 * 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
mridge56130dc2004-08-24 20:30:46 +000020 */
21
22/*
Cyril Hrubis123895c2013-04-24 13:34:46 +020023 * 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.
mridge56130dc2004-08-24 20:30:46 +000027 */
28
mridge56130dc2004-08-24 20:30:46 +000029#include <sys/mman.h>
30#include <sys/types.h>
31#include <sys/stat.h>
mridge051f4232004-09-13 21:59:01 +000032#include <sys/wait.h>
mridge56130dc2004-08-24 20:30:46 +000033#include <fcntl.h>
34#include <unistd.h>
35#include <signal.h>
36#include <errno.h>
subrata_modak4bb656a2009-02-26 12:02:09 +000037
mridge56130dc2004-08-24 20:30:46 +000038#include "test.h"
mridge56130dc2004-08-24 20:30:46 +000039
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020040char *TCID = "mincore02";
41int TST_TOTAL = 1;
mridge56130dc2004-08-24 20:30:46 +000042
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020043static int fd = 0;
44static void *addr = NULL;
Cyril Hrubis123895c2013-04-24 13:34:46 +020045static int page_size;
46static int num_pages = 4;
subrata_modak56207ce2009-03-23 13:35:39 +000047static unsigned char *vec = NULL;
mridge051f4232004-09-13 21:59:01 +000048
Cyril Hrubis123895c2013-04-24 13:34:46 +020049static void cleanup(void)
mridge56130dc2004-08-24 20:30:46 +000050{
mridge051f4232004-09-13 21:59:01 +000051 free(vec);
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020052 munlock(addr, page_size * num_pages);
53 munmap(addr, page_size * num_pages);
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020054 close(fd);
55 tst_rmdir();
mridge56130dc2004-08-24 20:30:46 +000056}
57
Cyril Hrubis123895c2013-04-24 13:34:46 +020058static void setup(void)
mridge56130dc2004-08-24 20:30:46 +000059{
mridge051f4232004-09-13 21:59:01 +000060 char *buf;
Cyril Hrubis123895c2013-04-24 13:34:46 +020061 size_t size;
subrata_modakbdbaec52009-02-26 12:14:51 +000062
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020063 tst_tmpdir();
64
Cyril Hrubis123895c2013-04-24 13:34:46 +020065 page_size = getpagesize();
66 if (page_size == -1)
67 tst_brkm(TBROK | TERRNO, cleanup, "Unable to get page size");
subrata_modakbdbaec52009-02-26 12:14:51 +000068
Cyril Hrubis123895c2013-04-24 13:34:46 +020069 size = page_size * num_pages;
70 buf = malloc(size);
subrata_modak56207ce2009-03-23 13:35:39 +000071
72 memset(buf, 42, size);
Cyril Hrubis123895c2013-04-24 13:34:46 +020073 vec = malloc((size + page_size - 1) / page_size);
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020074
75 fd = open("mincore02", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
76 if (fd == -1) {
Cyril Hrubis123895c2013-04-24 13:34:46 +020077 tst_brkm(TBROK | TERRNO, cleanup,
78 "Unable to create temporary file");
subrata_modak4bb656a2009-02-26 12:02:09 +000079 }
subrata_modakbdbaec52009-02-26 12:14:51 +000080
mridge56130dc2004-08-24 20:30:46 +000081 /* fill the temporary file with two pages of data */
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020082 if (write(fd, buf, size) < 0) {
Cyril Hrubis123895c2013-04-24 13:34:46 +020083 tst_brkm(TBROK | TERRNO, cleanup,
84 "Error in writing to the file");
mridge56130dc2004-08-24 20:30:46 +000085 }
mridge051f4232004-09-13 21:59:01 +000086 free(buf);
87
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020088 addr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
89 MAP_SHARED, fd, 0);
subrata_modakbdbaec52009-02-26 12:14:51 +000090
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020091 if (addr == MAP_FAILED) {
Cyril Hrubis123895c2013-04-24 13:34:46 +020092 tst_brkm(TBROK | TERRNO, cleanup,
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020093 "Unable to map file for read/write");
mridge56130dc2004-08-24 20:30:46 +000094 }
95
mridge051f4232004-09-13 21:59:01 +000096 /* lock mmapped file, so mincore returns "in core" for all pages */
Cyril Hrubis8e9b9972013-04-24 14:22:24 +020097 if (mlock(addr, size) == -1)
Cyril Hrubis123895c2013-04-24 13:34:46 +020098 tst_brkm(TBROK | TERRNO, cleanup, "Unable to lock the file");
mridge56130dc2004-08-24 20:30:46 +000099}
100
mridge051f4232004-09-13 21:59:01 +0000101int main(int argc, char **argv)
mridge56130dc2004-08-24 20:30:46 +0000102{
subrata_modak56207ce2009-03-23 13:35:39 +0000103 int lock_pages, counter;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200104 const char *msg;
Cyril Hrubis8e9b9972013-04-24 14:22:24 +0200105 int lc;
106
107 msg = parse_opts(argc, argv, NULL, NULL);
108 if (msg != NULL)
109 tst_brkm(TBROK, cleanup, "error parsing options: %s", msg);
subrata_modakbdbaec52009-02-26 12:14:51 +0000110
mridge051f4232004-09-13 21:59:01 +0000111 setup();
Cyril Hrubis8e9b9972013-04-24 14:22:24 +0200112
113 for (lc = 0; TEST_LOOPING(lc); lc++) {
114 tst_count = 0;
mridge56130dc2004-08-24 20:30:46 +0000115
Cyril Hrubis8e9b9972013-04-24 14:22:24 +0200116 if (mincore(addr, num_pages * page_size, vec) == -1) {
117 tst_brkm(TBROK | TERRNO, cleanup,
118 "Unable to execute mincore system call");
119 }
120
121 /* check status of pages */
122 lock_pages = 0;
123
124 for (counter = 0; counter < num_pages; counter++) {
125 if (vec[counter] & 1)
126 lock_pages++;
127 }
128
129 if (lock_pages == num_pages) {
130 tst_resm(TPASS, "%d pages locked, %d pages in-core", num_pages,
131 lock_pages);
132 } else {
133 tst_resm(TFAIL,
134 "not all locked pages are in-core: no. locked: %d, no. in-core: %d",
135 num_pages, lock_pages);
136 }
subrata_modak56207ce2009-03-23 13:35:39 +0000137 }
138
mridge051f4232004-09-13 21:59:01 +0000139 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800140 tst_exit();
mridge56130dc2004-08-24 20:30:46 +0000141}