| /* |
| * Stack size mapping is decreased through mlock/munlock call. |
| * |
| * This is to test kernel if it has a problem with shortening [stack] |
| * mapping through several loops of mlock/munlock of /proc/self/maps. |
| * |
| * From: |
| * munlock 76KiB bfef2000-bff05000 rw-p 00000000 00:00 0 [stack] |
| * |
| * To: |
| * munlock 44KiB bfefa000-bff05000 rw-p 00000000 00:00 0 [stack] |
| * |
| * with more iterations - could drop to 0KiB. |
| * |
| * Copyright (C) 2010 Red Hat, Inc. |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of version 2 of the GNU General Public |
| * License as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it would be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * |
| * Further, this software is distributed without any warranty that it |
| * is free of the rightful claim of any third person regarding |
| * infringement or the like. Any license provided herein, whether |
| * implied or otherwise, applies only to this software file. Patent |
| * licenses, if any, provided herein do not apply to combinations of |
| * this program with other software, or any other product whatsoever. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| * 02110-1301, USA. |
| */ |
| #include <sys/mman.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include "test.h" |
| |
| #define KB 1024 |
| |
| char *TCID = "mlock03"; |
| int TST_TOTAL = 1; |
| |
| static void setup(void); |
| static void cleanup(void); |
| |
| int main(int argc, char *argv[]) |
| { |
| int lc; |
| const char *msg; |
| long from, to; |
| long first = -1, last = -1; |
| char b[KB]; |
| FILE *fp; |
| |
| if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) |
| tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
| |
| setup(); |
| |
| for (lc = 0; TEST_LOOPING(lc); lc++) { |
| fp = fopen("/proc/self/maps", "r"); |
| if (fp == NULL) |
| tst_brkm(TBROK | TERRNO, cleanup, "fopen"); |
| while (!feof(fp)) { |
| if (!fgets(b, KB - 1, fp)) |
| break; |
| b[strlen(b) - 1] = '\0'; |
| sscanf(b, "%lx-%lx", &from, &to); |
| |
| /* Record the initial stack size. */ |
| if (lc == 0 && strstr(b, "[stack]") != NULL) |
| first = (to - from) / KB; |
| |
| switch (lc & 1) { |
| case 0: |
| if (mlock((const void *)from, to - from) == -1) |
| tst_resm(TINFO | TERRNO, |
| "mlock failed"); |
| break; |
| case 1: |
| if (munlock((void *)from, to - from) == -1) |
| tst_resm(TINFO | TERRNO, |
| "munlock failed"); |
| break; |
| default: |
| break; |
| } |
| tst_resm(TINFO, "%s from %lx to %0lx", |
| (lc & 1) ? "munlock" : "mlock", from, to); |
| |
| /* Record the final stack size. */ |
| if (strstr(b, "[stack]") != NULL) |
| last = (to - from) / KB; |
| } |
| fclose(fp); |
| } |
| tst_resm(TINFO, "starting stack size is %ld", first); |
| tst_resm(TINFO, "final stack size is %ld", last); |
| if (last < first) |
| tst_resm(TFAIL, "stack size is decreased."); |
| else |
| tst_resm(TPASS, "stack size is not decreased."); |
| |
| cleanup(); |
| tst_exit(); |
| } |
| |
| void setup(void) |
| { |
| tst_require_root(NULL); |
| |
| tst_sig(FORK, DEF_HANDLER, cleanup); |
| TEST_PAUSE; |
| } |
| |
| void cleanup(void) |
| { |
| } |