• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) International Business Machines  Corp., 2004
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  * FILE NAME	: mmapfile.c
21  *
22  * PURPOSE	: This executable is invoked by the mmap test case to invoke
23  * 		  mmap() from a process different than mmap.  If mmap() is
24  * 		  invoked by the mmap process, a hang will generally occur
25  * 		  because sys_mmap obtains write access to mmap_sem, and any
26  * 		  page fault within the same process (while process is
27  * 		  responding to read/write event generated by mmap() call)
28  * 		  requires read access to the same mmap_sem.
29  *
30  * PARAMETERS	: argv[1] - name of file being memory mapped
31  * 		  argv[2] - open flags:
32  * 		  	0 - read-only
33  * 		  	1 - write-only
34  * 		  	2 - read-write
35  * 		  argv[3] - offset within file of memory mapped region
36  * 		  argv[4] - length of memory mapped region
37  * 		  argv[5] - mmap() expected pass/fail status
38  * 		  	0 - fail
39  * 		  	1 - pass
40  *
41  */
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <errno.h>
46 #include <unistd.h>
47 #include <sys/mman.h>
48 #include <fcntl.h>
49 #include "dm_test.h"
50 
51 char DummyFile[FILENAME_MAX];
52 
main(int argc,char ** argv)53 int main(int argc, char **argv)
54 {
55 	int rc;
56 	int fd;
57 	int openflags;
58 	int offset;
59 	int length;
60 	int passflag;
61 	int flags;
62 	void *memmap;
63 
64 	if (--argc != 5) {
65 		printf("usage: %s filename openflags offset length passflag\n",
66 		       argv[0]);
67 		exit(-1);
68 	}
69 
70 	passflag = atoi(argv[5]);
71 	if ((passflag != 0) && (passflag != 1)) {
72 		printf("%s error: invalid passflag %s\n", argv[0], argv[5]);
73 		exit(-1);
74 	}
75 
76 	length = atoi(argv[4]);
77 	if (length < 0) {
78 		printf("%s error: invalid length %s\n", argv[0], argv[4]);
79 		exit(-1);
80 	}
81 
82 	offset = atoi(argv[3]);
83 	if (offset < 0) {
84 		printf("%s error: invalid offset %s\n", argv[0], argv[3]);
85 		exit(-1);
86 	}
87 	if (offset & (PAGE_SIZE - 1)) {
88 		printf("%s error: unaligned offset %d\n", argv[0], offset);
89 		exit(-1);
90 	}
91 
92 	openflags = atoi(argv[2]);
93 	if (openflags == O_RDONLY) {
94 		flags = PROT_READ;
95 	} else if (openflags == O_WRONLY) {
96 		flags = PROT_WRITE;
97 	} else if (openflags == O_RDWR) {
98 		flags = PROT_READ | PROT_WRITE;
99 	} else {
100 		printf("%s error: invalid openflags %s\n", argv[0], argv[2]);
101 		exit(-1);
102 	}
103 
104 	printf("invoking open(%s, %d)\n", argv[1], openflags);
105 	fd = open(argv[1], openflags);
106 	if (fd == -1) {
107 		printf("%s error: open failed with rc = %d (errno = %d)\n",
108 		       argv[0], rc, errno);
109 		exit(-1);
110 	}
111 
112 	printf("invoking memmap(%d, %d, %s, %d)\n", length, flags, argv[1],
113 	       offset);
114 	memmap = mmap(NULL, length, flags, MAP_SHARED, fd, offset);
115 	if (memmap == MAP_FAILED) {
116 		printf("%s error: mmap failed with errno = %d\n", argv[0],
117 		       errno);
118 		if (passflag) {
119 			close(fd);
120 			exit(-1);
121 		}
122 	}
123 
124 	EVENT_DELIVERY_DELAY;
125 
126 	if (memmap != MAP_FAILED) {
127 		printf("invoking munmap(%p, %d)\n", memmap, length);
128 		munmap(memmap, length);
129 	}
130 
131 	close(fd);
132 
133 	_exit(0);
134 	tst_exit();
135 }
136