annotate src/os/solaris/vm/perfMemory_solaris.cpp @ 4582:b24386206122

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