Home | History | Annotate | Download | only in mmap
      1 /*
      2  * Copyright (c) 2013 FNST, DAN LI <li.dan (at) cn.fujitsu.com>
      3  *
      4  * This program is free software;  you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation; either version 2 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     12  * the GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program;  if not, write to the Free Software
     16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17  */
     18 
     19 /*
     20  * Test Description:
     21  *  Verify MAP_LOCKED works fine.
     22  *  "Lock the pages of the mapped region into memory in the manner of mlock(2)."
     23  *
     24  * Expected Result:
     25  *  mmap() should succeed returning the address of the mapped region,
     26  *  and this region should be locked into memory.
     27  */
     28 #include <stdio.h>
     29 #include <sys/mman.h>
     30 
     31 #include "test.h"
     32 
     33 #define TEMPFILE        "mmapfile"
     34 #define MMAPSIZE        (1UL<<20)
     35 #define LINELEN         256
     36 
     37 char *TCID = "mmap14";
     38 int TST_TOTAL = 1;
     39 
     40 static char *addr;
     41 
     42 static void getvmlck(unsigned int *lock_sz);
     43 static void setup(void);
     44 static void cleanup(void);
     45 
     46 int main(int argc, char *argv[])
     47 {
     48 	int lc;
     49 	unsigned int sz_before;
     50 	unsigned int sz_after;
     51 	unsigned int sz_ch;
     52 
     53 	tst_parse_opts(argc, argv, NULL, NULL);
     54 
     55 	setup();
     56 
     57 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     58 
     59 		tst_count = 0;
     60 
     61 		getvmlck(&sz_before);
     62 
     63 		addr = mmap(NULL, MMAPSIZE, PROT_READ | PROT_WRITE,
     64 			    MAP_PRIVATE | MAP_LOCKED | MAP_ANONYMOUS,
     65 			    -1, 0);
     66 
     67 		if (addr == MAP_FAILED) {
     68 			tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE);
     69 			continue;
     70 		}
     71 
     72 		getvmlck(&sz_after);
     73 
     74 		sz_ch = sz_after - sz_before;
     75 		if (sz_ch == MMAPSIZE / 1024) {
     76 			tst_resm(TPASS, "Functionality of mmap() "
     77 					"successful");
     78 		} else {
     79 			tst_resm(TFAIL, "Expected %luK locked, "
     80 					"get %uK locked",
     81 					MMAPSIZE / 1024, sz_ch);
     82 		}
     83 
     84 		if (munmap(addr, MMAPSIZE) != 0)
     85 			tst_brkm(TFAIL | TERRNO, NULL, "munmap failed");
     86 	}
     87 
     88 	cleanup();
     89 	tst_exit();
     90 }
     91 
     92 void getvmlck(unsigned int *lock_sz)
     93 {
     94 	int ret;
     95 	char line[LINELEN];
     96 	FILE *fstatus = NULL;
     97 
     98 	fstatus = fopen("/proc/self/status", "r");
     99 	if (fstatus == NULL)
    100 		tst_brkm(TFAIL | TERRNO, NULL, "Open dev status failed");
    101 
    102 	while (fgets(line, LINELEN, fstatus) != NULL)
    103 		if (strstr(line, "VmLck") != NULL)
    104 			break;
    105 
    106 	ret = sscanf(line, "%*[^0-9]%d%*[^0-9]", lock_sz);
    107 	if (ret != 1)
    108 		tst_brkm(TFAIL | TERRNO, NULL, "Get lock size failed");
    109 
    110 	fclose(fstatus);
    111 }
    112 
    113 static void setup(void)
    114 {
    115 	tst_require_root();
    116 
    117 	tst_sig(FORK, DEF_HANDLER, cleanup);
    118 
    119 	TEST_PAUSE;
    120 }
    121 
    122 static void cleanup(void)
    123 {
    124 }
    125