annotate src/os/linux/vm/perfMemory_linux.cpp @ 17716:cdb71841f4bc

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