annotate src/os/linux/vm/perfMemory_linux.cpp @ 4582:b24386206122

Made all vm builds go into subdirectories, even product builds to simplify building the various types of VMs (server, client and graal). Made HotSpot build jobs use the number of CPUs on the host machine.
author Doug Simon <doug.simon@oracle.com>
date Mon, 13 Feb 2012 23:13:37 +0100
parents 02895c6a2f82
children d2a62e0f25eb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1353
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1353
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1353
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "os_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "runtime/perfMemory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "utilities/exceptions.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
36 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
37 # include <sys/mman.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
38 # include <errno.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
39 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
40 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
41 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
42 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
43 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 static char* backing_store_file_name = NULL; // name of the backing store
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // file, if successfully created.
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // Standard Memory Implementation Details
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // create the PerfData memory region in standard memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 //
a61af66fc99e Initial load
duke
parents:
diff changeset
52 static char* create_standard_memory(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // allocate an aligned chuck of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
55 char* mapAddress = os::reserve_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if (mapAddress == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // commit memory
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if (!os::commit_memory(mapAddress, size)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 warning("Could not commit PerfData memory\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66 os::release_memory(mapAddress, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 return mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // delete the PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
74 //
a61af66fc99e Initial load
duke
parents:
diff changeset
75 static void delete_standard_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // there are no persistent external resources to cleanup for standard
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // memory. since DestroyJavaVM does not support unloading of the JVM,
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // cleanup of the memory resource is not performed. The memory will be
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // reclaimed by the OS upon termination of the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
81 //
a61af66fc99e Initial load
duke
parents:
diff changeset
82 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // save the specified memory region to the given file
a61af66fc99e Initial load
duke
parents:
diff changeset
86 //
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Note: this function might be called from signal handler (by os::abort()),
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // don't allocate heap memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
89 //
a61af66fc99e Initial load
duke
parents:
diff changeset
90 static void save_memory_to_file(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 const char* destfile = PerfMemory::get_perfdata_file_path();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 assert(destfile[0] != '\0', "invalid PerfData file path");
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 RESTARTABLE(::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE),
a61af66fc99e Initial load
duke
parents:
diff changeset
98 result);;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 warning("Could not create Perfdata save file: %s: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
102 destfile, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 int fd = result;
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 for (size_t remaining = size; remaining > 0;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 RESTARTABLE(::write(fd, addr, remaining), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 warning("Could not write Perfdata save file: %s: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
113 destfile, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 remaining -= (size_t)result;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 addr += result;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 RESTARTABLE(::close(fd), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 warning("Could not close %s: %s\n", destfile, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 FREE_C_HEAP_ARRAY(char, destfile);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // Shared Memory Implementation Details
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Note: the solaris and linux shared memory implementation uses the mmap
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // interface with a backing store file to implement named shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // Using the file system as the name space for shared memory allows a
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // common name space to be supported across a variety of platforms. It
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // also provides a name space that Java applications can deal with through
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // simple file apis.
a61af66fc99e Initial load
duke
parents:
diff changeset
141 //
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // The solaris and linux implementations store the backing store file in
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // a user specific temporary directory located in the /tmp file system,
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // which is always a local file system and is sometimes a RAM based file
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // system.
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // return the user specific temporary directory name.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 //
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 //
a61af66fc99e Initial load
duke
parents:
diff changeset
151 static char* get_user_tmp_dir(const char* user) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 const char* tmpdir = os::get_temp_directory();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 const char* perfdir = PERFDATA_NAME;
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 605
diff changeset
155 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
156 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // construct the path name to user specific tmp directory
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 605
diff changeset
159 snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 return dirname;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // convert the given file name into a process id. if the file
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // does not meet the file naming constraints, return 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 //
a61af66fc99e Initial load
duke
parents:
diff changeset
167 static pid_t filename_to_pid(const char* filename) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // a filename that doesn't begin with a digit is not a
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // candidate for conversion.
a61af66fc99e Initial load
duke
parents:
diff changeset
171 //
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if (!isdigit(*filename)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // check if file name can be converted to an integer without
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // any leftover characters.
a61af66fc99e Initial load
duke
parents:
diff changeset
178 //
a61af66fc99e Initial load
duke
parents:
diff changeset
179 char* remainder = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 pid_t pid = (pid_t)strtol(filename, &remainder, 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 if (errno != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // check for left over characters. If any, then the filename is
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // not a candidate for conversion.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 //
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (remainder != NULL && *remainder != '\0') {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // successful conversion, return the pid
a61af66fc99e Initial load
duke
parents:
diff changeset
195 return pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // check if the given path is considered a secure directory for
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // the backing store files. Returns true if the directory exists
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // and is considered a secure location. Returns false if the path
605
98cb887364d3 6810672: Comment typos
twisti
parents: 0
diff changeset
202 // is a symbolic link or if an error occurred.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
203 //
a61af66fc99e Initial load
duke
parents:
diff changeset
204 static bool is_directory_secure(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 struct stat statbuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 int result = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 RESTARTABLE(::lstat(path, &statbuf), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // the path exists, now check it's mode
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // the path represents a link or some non-directory file type,
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // which is not what we expected. declare it insecure.
a61af66fc99e Initial load
duke
parents:
diff changeset
217 //
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // we have an existing directory, check if the permissions are safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
222 //
a61af66fc99e Initial load
duke
parents:
diff changeset
223 if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // the directory is open for writing and could be subjected
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // to a symlnk attack. declare it insecure.
a61af66fc99e Initial load
duke
parents:
diff changeset
226 //
a61af66fc99e Initial load
duke
parents:
diff changeset
227 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // return the user name for the given user id
a61af66fc99e Initial load
duke
parents:
diff changeset
235 //
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
237 //
a61af66fc99e Initial load
duke
parents:
diff changeset
238 static char* get_user_name(uid_t uid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 struct passwd pwent;
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // determine the max pwbuf size from sysconf, and hardcode
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // a default if this not available through sysconf.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 //
a61af66fc99e Initial load
duke
parents:
diff changeset
245 long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 if (bufsize == -1)
a61af66fc99e Initial load
duke
parents:
diff changeset
247 bufsize = 1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // POSIX interface to getpwuid_r is used on LINUX
a61af66fc99e Initial load
duke
parents:
diff changeset
252 struct passwd* p;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p);
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if (result != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if (result != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 warning("Could not retrieve passwd entry: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
259 strerror(result));
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 else if (p == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // this check is added to protect against an observed problem
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // with getpwuid_r() on RedHat 9 where getpwuid_r returns 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // indicating success, but has p == NULL. This was observed when
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // inserting a file descriptor exhaustion fault prior to the call
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // getpwuid_r() call. In this case, error is set to the appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // error condition, but this is undocumented behavior. This check
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // is safe under any condition, but the use of errno in the output
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // message may result in an erroneous message.
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Bug Id 89052 was opened with RedHat.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 //
a61af66fc99e Initial load
duke
parents:
diff changeset
272 warning("Could not retrieve passwd entry: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
273 strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 warning("Could not determine user name: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
277 p->pw_name == NULL ? "pw_name = NULL" :
a61af66fc99e Initial load
duke
parents:
diff changeset
278 "pw_name zero length");
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 FREE_C_HEAP_ARRAY(char, pwbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 strcpy(user_name, p->pw_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 FREE_C_HEAP_ARRAY(char, pwbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
289 return user_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // return the name of the user that owns the process identified by vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
293 //
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // This method uses a slow directory search algorithm to find the backing
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // store file for the specified vmid and returns the user name, as determined
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // by the user name suffix of the hsperfdata_<username> directory name.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 //
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 //
a61af66fc99e Initial load
duke
parents:
diff changeset
300 static char* get_user_name_slow(int vmid, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // short circuit the directory search if the process doesn't even exist.
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if (kill(vmid, 0) == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (errno == ESRCH) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
306 "Process not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 else /* EPERM */ {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // directory search
a61af66fc99e Initial load
duke
parents:
diff changeset
314 char* oldest_user = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 time_t oldest_ctime = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 const char* tmpdirname = os::get_temp_directory();
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 DIR* tmpdirp = os::opendir(tmpdirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if (tmpdirp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // for each entry in the directory that matches the pattern hsperfdata_*,
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // open the directory and check if the file for the given vmid exists.
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // The file with the expected name and the latest creation date is used
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // to determine the user name for the process id.
a61af66fc99e Initial load
duke
parents:
diff changeset
329 //
a61af66fc99e Initial load
duke
parents:
diff changeset
330 struct dirent* dentry;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
a61af66fc99e Initial load
duke
parents:
diff changeset
332 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // check if the directory entry is a hsperfdata file
a61af66fc99e Initial load
duke
parents:
diff changeset
336 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 char* usrdir_name = NEW_C_HEAP_ARRAY(char,
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 605
diff changeset
341 strlen(tmpdirname) + strlen(dentry->d_name) + 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
342 strcpy(usrdir_name, tmpdirname);
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 605
diff changeset
343 strcat(usrdir_name, "/");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
344 strcat(usrdir_name, dentry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 DIR* subdirp = os::opendir(usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 if (subdirp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 FREE_C_HEAP_ARRAY(char, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Since we don't create the backing store files in directories
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // pointed to by symbolic links, we also don't follow them when
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // looking for the files. We check for a symbolic link after the
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // call to opendir in order to eliminate a small window where the
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // symlink can be exploited.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 //
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (!is_directory_secure(usrdir_name)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 FREE_C_HEAP_ARRAY(char, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 os::closedir(subdirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 struct dirent* udentry;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
a61af66fc99e Initial load
duke
parents:
diff changeset
367 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if (filename_to_pid(udentry->d_name) == vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 struct stat statbuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374 char* filename = NEW_C_HEAP_ARRAY(char,
a61af66fc99e Initial load
duke
parents:
diff changeset
375 strlen(usrdir_name) + strlen(udentry->d_name) + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 strcpy(filename, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 strcat(filename, "/");
a61af66fc99e Initial load
duke
parents:
diff changeset
379 strcat(filename, udentry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // don't follow symbolic links for the file
a61af66fc99e Initial load
duke
parents:
diff changeset
382 RESTARTABLE(::lstat(filename, &statbuf), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
384 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // skip over files that are not regular files.
a61af66fc99e Initial load
duke
parents:
diff changeset
389 if (!S_ISREG(statbuf.st_mode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // compare and save filename with latest creation time
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 if (statbuf.st_ctime > oldest_ctime) {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 char* user = strchr(dentry->d_name, '_') + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 strcpy(oldest_user, user);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 oldest_ctime = statbuf.st_ctime;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411 os::closedir(subdirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 FREE_C_HEAP_ARRAY(char, udbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 FREE_C_HEAP_ARRAY(char, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415 os::closedir(tmpdirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 FREE_C_HEAP_ARRAY(char, tdbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 return(oldest_user);
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // return the name of the user that owns the JVM indicated by the given vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
422 //
a61af66fc99e Initial load
duke
parents:
diff changeset
423 static char* get_user_name(int vmid, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 return get_user_name_slow(vmid, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // return the file name of the backing store file for the named
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // shared memory region for the given user name and vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
429 //
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 //
a61af66fc99e Initial load
duke
parents:
diff changeset
432 static char* get_sharedmem_filename(const char* dirname, int vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // add 2 for the file separator and a null terminator.
a61af66fc99e Initial load
duke
parents:
diff changeset
435 size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 char* name = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 snprintf(name, nbytes, "%s/%d", dirname, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 return name;
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // remove file
a61af66fc99e Initial load
duke
parents:
diff changeset
445 //
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // this method removes the file specified by the given path
a61af66fc99e Initial load
duke
parents:
diff changeset
447 //
a61af66fc99e Initial load
duke
parents:
diff changeset
448 static void remove_file(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // if the file is a directory, the following unlink will fail. since
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // we don't expect to find directories in the user temp directory, we
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // won't try to handle this situation. even if accidentially or
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // maliciously planted, the directory's presence won't hurt anything.
a61af66fc99e Initial load
duke
parents:
diff changeset
456 //
a61af66fc99e Initial load
duke
parents:
diff changeset
457 RESTARTABLE(::unlink(path), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
458 if (PrintMiscellaneous && Verbose && result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (errno != ENOENT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 warning("Could not unlink shared memory backing"
a61af66fc99e Initial load
duke
parents:
diff changeset
461 " store file %s : %s\n", path, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // remove file
a61af66fc99e Initial load
duke
parents:
diff changeset
468 //
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // this method removes the file with the given file name in the
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // named directory.
a61af66fc99e Initial load
duke
parents:
diff changeset
471 //
a61af66fc99e Initial load
duke
parents:
diff changeset
472 static void remove_file(const char* dirname, const char* filename) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 size_t nbytes = strlen(dirname) + strlen(filename) + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
475 char* path = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
476
a61af66fc99e Initial load
duke
parents:
diff changeset
477 strcpy(path, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 strcat(path, "/");
a61af66fc99e Initial load
duke
parents:
diff changeset
479 strcat(path, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 remove_file(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 FREE_C_HEAP_ARRAY(char, path);
a61af66fc99e Initial load
duke
parents:
diff changeset
484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // cleanup stale shared memory resources
a61af66fc99e Initial load
duke
parents:
diff changeset
488 //
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // This method attempts to remove all stale shared memory files in
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // the named user temporary directory. It scans the named directory
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // for files matching the pattern ^$[0-9]*$. For each file found, the
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // process id is extracted from the file name and a test is run to
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // determine if the process is alive. If the process is not alive,
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // any stale file resources are removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
495 //
a61af66fc99e Initial load
duke
parents:
diff changeset
496 static void cleanup_sharedmem_resources(const char* dirname) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // open the user temp directory
a61af66fc99e Initial load
duke
parents:
diff changeset
499 DIR* dirp = os::opendir(dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 if (dirp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // directory doesn't exist, so there is nothing to cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
503 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 if (!is_directory_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // the directory is not a secure directory
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // for each entry in the directory that matches the expected file
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // name pattern, determine if the file resources are stale and if
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // so, remove the file resources. Note, instrumented HotSpot processes
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // for this user may start and/or terminate during this search and
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // remove or create new files in this directory. The behavior of this
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // loop under these conditions is dependent upon the implementation of
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // opendir/readdir.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 //
a61af66fc99e Initial load
duke
parents:
diff changeset
519 struct dirent* entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
520 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
a61af66fc99e Initial load
duke
parents:
diff changeset
521 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 pid_t pid = filename_to_pid(entry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (pid == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // attempt to remove all unexpected files, except "." and ".."
a61af66fc99e Initial load
duke
parents:
diff changeset
531 remove_file(dirname, entry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // we now have a file name that converts to a valid integer
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // that could represent a process id . if this process id
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // matches the current process id or the process is not running,
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // then remove the stale file resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
542 //
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // process liveness is detected by sending signal number 0 to
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // the process id (see kill(2)). if kill determines that the
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // process does not exist, then the file resources are removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // if kill determines that that we don't have permission to
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // signal the process, then the file resources are assumed to
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // be stale and are removed because the resources for such a
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // process should be in a different user specific directory.
a61af66fc99e Initial load
duke
parents:
diff changeset
550 //
a61af66fc99e Initial load
duke
parents:
diff changeset
551 if ((pid == os::current_process_id()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
552 (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 remove_file(dirname, entry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558 os::closedir(dirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 FREE_C_HEAP_ARRAY(char, dbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // make the user specific temporary directory. Returns true if
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // the directory exists and is secure upon return. Returns false
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // if the directory exists but is either a symlink, is otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // insecure, or if an error occurred.
a61af66fc99e Initial load
duke
parents:
diff changeset
566 //
a61af66fc99e Initial load
duke
parents:
diff changeset
567 static bool make_user_tmp_dir(const char* dirname) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // create the directory with 0755 permissions. note that the directory
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // will be owned by euid::egid, which may not be the same as uid::gid.
a61af66fc99e Initial load
duke
parents:
diff changeset
571 //
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if (errno == EEXIST) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // The directory already exists and was probably created by another
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // JVM instance. However, this could also be the result of a
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // deliberate symlink. Verify that the existing directory is safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
577 //
a61af66fc99e Initial load
duke
parents:
diff changeset
578 if (!is_directory_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // directory is not secure
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 warning("%s directory is insecure\n", dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // we encountered some other failure while attempting
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // to create the directory
a61af66fc99e Initial load
duke
parents:
diff changeset
589 //
a61af66fc99e Initial load
duke
parents:
diff changeset
590 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 warning("could not create directory %s: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
592 dirname, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596 }
a61af66fc99e Initial load
duke
parents:
diff changeset
597 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // create the shared memory file resources
a61af66fc99e Initial load
duke
parents:
diff changeset
601 //
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // This method creates the shared memory file with the given size
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // This method also creates the user specific temporary directory, if
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // it does not yet exist.
a61af66fc99e Initial load
duke
parents:
diff changeset
605 //
a61af66fc99e Initial load
duke
parents:
diff changeset
606 static int create_sharedmem_resources(const char* dirname, const char* filename, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // make the user temporary directory
a61af66fc99e Initial load
duke
parents:
diff changeset
609 if (!make_user_tmp_dir(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // could not make/find the directory or the found directory
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // was not secure
a61af66fc99e Initial load
duke
parents:
diff changeset
612 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
614
a61af66fc99e Initial load
duke
parents:
diff changeset
615 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 warning("could not create file %s: %s\n", filename, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // save the file descriptor
a61af66fc99e Initial load
duke
parents:
diff changeset
626 int fd = result;
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // set the file size
a61af66fc99e Initial load
duke
parents:
diff changeset
629 RESTARTABLE(::ftruncate(fd, (off_t)size), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 warning("could not set shared memory file size: %s\n", strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 RESTARTABLE(::close(fd), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637
2066
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
638 // Verify that we have enough disk space for this file.
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
639 // We'll get random SIGBUS crashes on memory accesses if
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
640 // we don't.
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
641
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
642 for (size_t seekpos = 0; seekpos < size; seekpos += os::vm_page_size()) {
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
643 int zero_int = 0;
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
644 result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos));
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
645 if (result == -1 ) break;
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
646 RESTARTABLE(::write(fd, &zero_int, 1), result);
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
647 if (result != 1) {
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
648 if (errno == ENOSPC) {
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
649 warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
650 }
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
651 break;
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
652 }
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
653 }
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
654
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
655 if (result != -1) {
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
656 return fd;
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
657 } else {
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
658 RESTARTABLE(::close(fd), result);
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
659 return -1;
02895c6a2f82 7007769: VM crashes with SIGBUS writing PerfData if tmp space is full
bobv
parents: 1972
diff changeset
660 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // open the shared memory file for the given user and vmid. returns
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // the file descriptor for the open file or -1 if the file could not
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // be opened.
a61af66fc99e Initial load
duke
parents:
diff changeset
666 //
a61af66fc99e Initial load
duke
parents:
diff changeset
667 static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // open the file
a61af66fc99e Initial load
duke
parents:
diff changeset
670 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
671 RESTARTABLE(::open(filename, oflags), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
672 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 if (errno == ENOENT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
674 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
675 "Process not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
677 else if (errno == EACCES) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
679 "Permission denied");
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // create a named shared memory region. returns the address of the
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // memory region on success or NULL on failure. A return value of
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // NULL will ultimately disable the shared memory feature.
a61af66fc99e Initial load
duke
parents:
diff changeset
692 //
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // On Solaris and Linux, the name space for shared memory objects
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // is the file system name space.
a61af66fc99e Initial load
duke
parents:
diff changeset
695 //
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // A monitoring application attaching to a JVM does not need to know
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // the file system name of the shared memory object. However, it may
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // be convenient for applications to discover the existence of newly
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // created and terminating JVMs by watching the file system name space
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // for files being created or removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
701 //
a61af66fc99e Initial load
duke
parents:
diff changeset
702 static char* mmap_create_shared(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
705 int fd;
a61af66fc99e Initial load
duke
parents:
diff changeset
706 char* mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 int vmid = os::current_process_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 char* user_name = get_user_name(geteuid());
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if (user_name == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
713 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 char* dirname = get_user_tmp_dir(user_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
716 char* filename = get_sharedmem_filename(dirname, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // cleanup any stale shared memory files
a61af66fc99e Initial load
duke
parents:
diff changeset
719 cleanup_sharedmem_resources(dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 assert(((size > 0) && (size % os::vm_page_size() == 0)),
a61af66fc99e Initial load
duke
parents:
diff changeset
722 "unexpected PerfMemory region size");
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 fd = create_sharedmem_resources(dirname, filename, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 FREE_C_HEAP_ARRAY(char, user_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
727 FREE_C_HEAP_ARRAY(char, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if (fd == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
731 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // attempt to close the file - restart it if it was interrupted,
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // but ignore other failures
a61af66fc99e Initial load
duke
parents:
diff changeset
738 RESTARTABLE(::close(fd), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
739 assert(result != OS_ERR, "could not close file");
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (mapAddress == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
743 warning("mmap failed - %s\n", strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745 remove_file(filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
746 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
747 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // save the file name for use in delete_shared_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
751 backing_store_file_name = filename;
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // clear the shared memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
754 (void)::memset((void*) mapAddress, 0, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 return mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // release a named shared memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
760 //
a61af66fc99e Initial load
duke
parents:
diff changeset
761 static void unmap_shared(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 os::release_memory(addr, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // create the PerfData memory region in shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
766 //
a61af66fc99e Initial load
duke
parents:
diff changeset
767 static char* create_shared_memory(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // create the shared memory region.
a61af66fc99e Initial load
duke
parents:
diff changeset
770 return mmap_create_shared(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // delete the shared PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
774 //
a61af66fc99e Initial load
duke
parents:
diff changeset
775 static void delete_shared_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // cleanup the persistent shared memory resources. since DestroyJavaVM does
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // not support unloading of the JVM, unmapping of the memory resource is
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // not performed. The memory will be reclaimed by the OS upon termination of
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // the process. The backing store file is deleted from the file system.
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 assert(!PerfDisableSharedMem, "shouldn't be here");
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 if (backing_store_file_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
785 remove_file(backing_store_file_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Don't.. Free heap memory could deadlock os::abort() if it is called
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // from signal handler. OS will reclaim the heap memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // FREE_C_HEAP_ARRAY(char, backing_store_file_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 backing_store_file_name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // return the size of the file for the given file descriptor
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // or 0 if it is not a valid size for a shared memory file
a61af66fc99e Initial load
duke
parents:
diff changeset
795 //
a61af66fc99e Initial load
duke
parents:
diff changeset
796 static size_t sharedmem_filesize(int fd, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 struct stat statbuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
799 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 RESTARTABLE(::fstat(fd, &statbuf), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
802 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
804 warning("fstat failed: %s\n", strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
806 THROW_MSG_0(vmSymbols::java_io_IOException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
807 "Could not determine PerfMemory size");
a61af66fc99e Initial load
duke
parents:
diff changeset
808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
809
a61af66fc99e Initial load
duke
parents:
diff changeset
810 if ((statbuf.st_size == 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
811 ((size_t)statbuf.st_size % os::vm_page_size() != 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 THROW_MSG_0(vmSymbols::java_lang_Exception(),
a61af66fc99e Initial load
duke
parents:
diff changeset
813 "Invalid PerfMemory size");
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816 return (size_t)statbuf.st_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // attach to a named shared memory region.
a61af66fc99e Initial load
duke
parents:
diff changeset
820 //
a61af66fc99e Initial load
duke
parents:
diff changeset
821 static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemoryMode mode, char** addr, size_t* sizep, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 char* mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
825 int fd;
a61af66fc99e Initial load
duke
parents:
diff changeset
826 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
827 const char* luser = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 int mmap_prot;
a61af66fc99e Initial load
duke
parents:
diff changeset
830 int file_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
831
a61af66fc99e Initial load
duke
parents:
diff changeset
832 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // map the high level access mode to the appropriate permission
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // constructs for the file and the shared memory mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
836 if (mode == PerfMemory::PERF_MODE_RO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 mmap_prot = PROT_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 file_flags = O_RDONLY;
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 else if (mode == PerfMemory::PERF_MODE_RW) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 #ifdef LATER
a61af66fc99e Initial load
duke
parents:
diff changeset
842 mmap_prot = PROT_READ | PROT_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
843 file_flags = O_RDWR;
a61af66fc99e Initial load
duke
parents:
diff changeset
844 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
845 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
846 "Unsupported access mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
847 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
850 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
851 "Illegal access mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 if (user == NULL || strlen(user) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
855 luser = get_user_name(vmid, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
857 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 luser = user;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (luser == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
863 "Could not map vmid to user Name");
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 char* dirname = get_user_tmp_dir(luser);
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // since we don't follow symbolic links when creating the backing
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // store file, we don't follow them when attaching either.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 //
a61af66fc99e Initial load
duke
parents:
diff changeset
871 if (!is_directory_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
872 FREE_C_HEAP_ARRAY(char, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
873 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
874 "Process not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 char* filename = get_sharedmem_filename(dirname, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // copy heap memory to resource memory. the open_sharedmem_file
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // method below need to use the filename, but could throw an
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // exception. using a resource array prevents the leak that
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // would otherwise occur.
a61af66fc99e Initial load
duke
parents:
diff changeset
883 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 strcpy(rfilename, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // free the c heap resources that are no longer needed
a61af66fc99e Initial load
duke
parents:
diff changeset
887 if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
a61af66fc99e Initial load
duke
parents:
diff changeset
888 FREE_C_HEAP_ARRAY(char, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // open the shared memory file for the give vmid
a61af66fc99e Initial load
duke
parents:
diff changeset
892 fd = open_sharedmem_file(rfilename, file_flags, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
893 assert(fd != OS_ERR, "unexpected value");
a61af66fc99e Initial load
duke
parents:
diff changeset
894
a61af66fc99e Initial load
duke
parents:
diff changeset
895 if (*sizep == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 size = sharedmem_filesize(fd, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 assert(size != 0, "unexpected size");
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // attempt to close the file - restart if it gets interrupted,
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // but ignore other failures
a61af66fc99e Initial load
duke
parents:
diff changeset
904 RESTARTABLE(::close(fd), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
905 assert(result != OS_ERR, "could not close file");
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (mapAddress == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 warning("mmap failed: %s\n", strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
912 "Could not map PerfMemory");
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
914
a61af66fc99e Initial load
duke
parents:
diff changeset
915 *addr = mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
916 *sizep = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (PerfTraceMemOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at "
a61af66fc99e Initial load
duke
parents:
diff changeset
920 INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // create the PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
928 //
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // This method creates the memory region used to store performance
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // data for the JVM. The memory may be created in standard or
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
932 //
a61af66fc99e Initial load
duke
parents:
diff changeset
933 void PerfMemory::create_memory_region(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 if (PerfDisableSharedMem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // do not share the memory for the performance data.
a61af66fc99e Initial load
duke
parents:
diff changeset
937 _start = create_standard_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 _start = create_shared_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
941 if (_start == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // creation of the shared memory region failed, attempt
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // to create a contiguous, non-shared memory region instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
945 //
a61af66fc99e Initial load
duke
parents:
diff changeset
946 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 warning("Reverting to non-shared PerfMemory region.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949 PerfDisableSharedMem = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
950 _start = create_standard_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if (_start != NULL) _capacity = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // delete the PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
959 //
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // This method deletes the memory region used to store performance
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // data for the JVM. The memory region indicated by the <address, size>
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // tuple will be inaccessible after a call to this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
963 //
a61af66fc99e Initial load
duke
parents:
diff changeset
964 void PerfMemory::delete_memory_region() {
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 assert((start() != NULL && capacity() > 0), "verify proper state");
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // If user specifies PerfDataSaveFile, it will save the performance data
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // to the specified file name no matter whether PerfDataSaveToFile is specified
a61af66fc99e Initial load
duke
parents:
diff changeset
970 // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // -XX:+PerfDataSaveToFile.
a61af66fc99e Initial load
duke
parents:
diff changeset
972 if (PerfDataSaveToFile || PerfDataSaveFile != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
973 save_memory_to_file(start(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 if (PerfDisableSharedMem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 delete_standard_memory(start(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
980 delete_shared_memory(start(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // attach to the PerfData memory region for another JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
985 //
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // This method returns an <address, size> tuple that points to
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // a memory buffer that is kept reasonably synchronized with
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // the PerfData memory region for the indicated JVM. This
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // buffer may be kept in synchronization via shared memory
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // or some other mechanism that keeps the buffer updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
991 //
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // If the JVM chooses not to support the attachability feature,
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // this method should throw an UnsupportedOperation exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
994 //
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // This implementation utilizes named shared memory to map
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // the indicated process's PerfData memory region into this JVMs
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // address space.
a61af66fc99e Initial load
duke
parents:
diff changeset
998 //
a61af66fc99e Initial load
duke
parents:
diff changeset
999 void PerfMemory::attach(const char* user, int vmid, PerfMemoryMode mode, char** addrp, size_t* sizep, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 if (vmid == 0 || vmid == os::current_process_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 *addrp = start();
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 *sizep = capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 mmap_attach_shared(user, vmid, mode, addrp, sizep, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // detach from the PerfData memory region of another JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 // This method detaches the PerfData memory region of another
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // JVM, specified as an <address, size> tuple of a buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // in this process's address space. This method may perform
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // arbitrary actions to accomplish the detachment. The memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // region specified by <address, size> will be inaccessible after
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // a call to this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // If the JVM chooses not to support the attachability feature,
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // this method should throw an UnsupportedOperation exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // This implementation utilizes named shared memory to detach
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // the indicated process's PerfData memory region from this
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // process's address space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 void PerfMemory::detach(char* addr, size_t bytes, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 assert(addr != 0, "address sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 assert(bytes > 0, "capacity sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 if (PerfMemory::contains(addr) || PerfMemory::contains(addr + bytes - 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // prevent accidental detachment of this process's PerfMemory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 unmap_shared(addr, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 char* PerfMemory::backing_store_filename() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 return backing_store_file_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }