annotate src/os/windows/vm/perfMemory_windows.cpp @ 3095:d3d00c1ea071

IdealGraphVisualizer: Enhance text view so it can display arbitrary properties from the active graph's group. For diff graphs, it shows the textual difference between the property strings using the NetBeans Diff module.
author Peter Hofer <peter.hofer@jku.at>
date Wed, 29 Jun 2011 17:33:35 +0200
parents de14f1eee390
children d2a62e0f25eb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
2 * Copyright (c) 2001, 2011, 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: 1968
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
26 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
27 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
28 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
29 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
30 #include "os_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
31 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
32 #include "runtime/perfMemory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1968
diff changeset
33 #include "utilities/exceptions.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 #include <windows.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
36 #include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
37 #include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
38 #include <errno.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
39 #include <lmcons.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 typedef BOOL (WINAPI *SetSecurityDescriptorControlFnPtr)(
a61af66fc99e Initial load
duke
parents:
diff changeset
42 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
a61af66fc99e Initial load
duke
parents:
diff changeset
43 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
a61af66fc99e Initial load
duke
parents:
diff changeset
44 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet);
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // Standard Memory Implementation Details
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // create the PerfData memory region in standard memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //
a61af66fc99e Initial load
duke
parents:
diff changeset
50 static char* create_standard_memory(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // allocate an aligned chuck of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
53 char* mapAddress = os::reserve_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 if (mapAddress == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // commit memory
a61af66fc99e Initial load
duke
parents:
diff changeset
60 if (!os::commit_memory(mapAddress, size)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 warning("Could not commit PerfData memory\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 os::release_memory(mapAddress, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
65 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 return mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // delete the PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
72 //
a61af66fc99e Initial load
duke
parents:
diff changeset
73 static void delete_standard_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // there are no persistent external resources to cleanup for standard
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // memory. since DestroyJavaVM does not support unloading of the JVM,
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // cleanup of the memory resource is not performed. The memory will be
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // reclaimed by the OS upon termination of the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
79 //
a61af66fc99e Initial load
duke
parents:
diff changeset
80 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // save the specified memory region to the given file
a61af66fc99e Initial load
duke
parents:
diff changeset
85 //
a61af66fc99e Initial load
duke
parents:
diff changeset
86 static void save_memory_to_file(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 const char* destfile = PerfMemory::get_perfdata_file_path();
a61af66fc99e Initial load
duke
parents:
diff changeset
89 assert(destfile[0] != '\0', "invalid Perfdata file path");
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 int fd = ::_open(destfile, _O_BINARY|_O_CREAT|_O_WRONLY|_O_TRUNC,
a61af66fc99e Initial load
duke
parents:
diff changeset
92 _S_IREAD|_S_IWRITE);
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (fd == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 warning("Could not create Perfdata save file: %s: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
97 destfile, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 for (size_t remaining = size; remaining > 0;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 int nbytes = ::_write(fd, addr, (unsigned int)remaining);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (nbytes == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 warning("Could not write Perfdata save file: %s: %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
106 destfile, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 remaining -= (size_t)nbytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 addr += nbytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 int result = ::_close(fd);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if (result == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 warning("Could not close %s: %s\n", destfile, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 FREE_C_HEAP_ARRAY(char, destfile);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Shared Memory Implementation Details
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Note: the win32 shared memory implementation uses two objects to represent
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // the shared memory: a windows kernel based file mapping object and a backing
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // store file. On windows, the name space for shared memory is a kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // based name space that is disjoint from other win32 name spaces. Since Java
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // is unaware of this name space, a parallel file system based name space is
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // maintained, which provides a common file system based shared memory name
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // space across the supported platforms and one that Java apps can deal with
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // through simple file apis.
a61af66fc99e Initial load
duke
parents:
diff changeset
136 //
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // For performance and resource cleanup reasons, it is recommended that the
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // user specific directory and the backing store file be stored in either a
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // RAM based file system or a local disk based file system. Network based
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // file systems are not recommended for performance reasons. In addition,
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // use of SMB network based file systems may result in unsuccesful cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // of the disk based resource on exit of the VM. The Windows TMP and TEMP
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // environement variables, as used by the GetTempPath() Win32 API (see
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // os::get_temp_directory() in os_win32.cpp), control the location of the
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // user specific directory and the shared memory backing store file.
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 static HANDLE sharedmem_fileMapHandle = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 static HANDLE sharedmem_fileHandle = INVALID_HANDLE_VALUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 static char* sharedmem_fileName = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // return the user specific temporary directory name.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 //
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 //
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static char* get_user_tmp_dir(const char* user) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 const char* tmpdir = os::get_temp_directory();
a61af66fc99e Initial load
duke
parents:
diff changeset
158 const char* perfdir = PERFDATA_NAME;
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 605
diff changeset
159 size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160 char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // 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
163 _snprintf(dirname, nbytes, "%s\\%s_%s", tmpdir, perfdir, user);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return dirname;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // convert the given file name into a process id. if the file
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // does not meet the file naming constraints, return 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 //
a61af66fc99e Initial load
duke
parents:
diff changeset
171 static int filename_to_pid(const char* filename) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // a filename that doesn't begin with a digit is not a
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // candidate for conversion.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 //
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if (!isdigit(*filename)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // check if file name can be converted to an integer without
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // any leftover characters.
a61af66fc99e Initial load
duke
parents:
diff changeset
182 //
a61af66fc99e Initial load
duke
parents:
diff changeset
183 char* remainder = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 int pid = (int)strtol(filename, &remainder, 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (errno != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // check for left over characters. If any, then the filename is
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // not a candidate for conversion.
a61af66fc99e Initial load
duke
parents:
diff changeset
193 //
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (remainder != NULL && *remainder != '\0') {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // successful conversion, return the pid
a61af66fc99e Initial load
duke
parents:
diff changeset
199 return pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // check if the given path is considered a secure directory for
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // the backing store files. Returns true if the directory exists
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // and is considered a secure location. Returns false if the path
605
98cb887364d3 6810672: Comment typos
twisti
parents: 0
diff changeset
205 // is a symbolic link or if an error occurred.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
206 //
a61af66fc99e Initial load
duke
parents:
diff changeset
207 static bool is_directory_secure(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 DWORD fa;
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 fa = GetFileAttributes(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if (fa == 0xFFFFFFFF) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 DWORD lasterror = GetLastError();
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (lasterror == ERROR_FILE_NOT_FOUND) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // unexpected error, declare the path insecure
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 warning("could not get attributes for file %s: ",
a61af66fc99e Initial load
duke
parents:
diff changeset
221 " lasterror = %d\n", path, lasterror);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if (fa & FILE_ATTRIBUTE_REPARSE_POINT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // we don't accept any redirection for the user specific directory
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // so declare the path insecure. This may be too conservative,
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // as some types of reparse points might be acceptable, but it
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // is probably more secure to avoid these conditions.
a61af66fc99e Initial load
duke
parents:
diff changeset
232 //
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 warning("%s is a reparse point\n", path);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (fa & FILE_ATTRIBUTE_DIRECTORY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // this is the expected case. Since windows supports symbolic
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // links to directories only, not to files, there is no need
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // to check for open write permissions on the directory. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // directory has open write permissions, any files deposited that
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // are not expected will be removed by the cleanup code.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 //
a61af66fc99e Initial load
duke
parents:
diff changeset
246 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // this is either a regular file or some other type of file,
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // any of which are unexpected and therefore insecure.
a61af66fc99e Initial load
duke
parents:
diff changeset
251 //
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 warning("%s is not a directory, file attributes = "
a61af66fc99e Initial load
duke
parents:
diff changeset
254 INTPTR_FORMAT "\n", path, fa);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // return the user name for the owner of this process
a61af66fc99e Initial load
duke
parents:
diff changeset
261 //
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
263 //
a61af66fc99e Initial load
duke
parents:
diff changeset
264 static char* get_user_name() {
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 /* get the user name. This code is adapted from code found in
a61af66fc99e Initial load
duke
parents:
diff changeset
267 * the jdk in src/windows/native/java/lang/java_props_md.c
a61af66fc99e Initial load
duke
parents:
diff changeset
268 * java_props_md.c 1.29 02/02/06. According to the original
a61af66fc99e Initial load
duke
parents:
diff changeset
269 * source, the call to GetUserName is avoided because of a resulting
a61af66fc99e Initial load
duke
parents:
diff changeset
270 * increase in footprint of 100K.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 */
a61af66fc99e Initial load
duke
parents:
diff changeset
272 char* user = getenv("USERNAME");
a61af66fc99e Initial load
duke
parents:
diff changeset
273 char buf[UNLEN+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
274 DWORD buflen = sizeof(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
275 if (user == NULL || strlen(user) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if (GetUserName(buf, &buflen)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 user = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 strcpy(user_name, user);
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 return user_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // return the name of the user that owns the process identified by vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 //
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // This method uses a slow directory search algorithm to find the backing
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // store file for the specified vmid and returns the user name, as determined
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // by the user name suffix of the hsperfdata_<username> directory name.
a61af66fc99e Initial load
duke
parents:
diff changeset
295 //
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 //
a61af66fc99e Initial load
duke
parents:
diff changeset
298 static char* get_user_name_slow(int vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // directory search
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
301 char* latest_user = NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
302 time_t latest_ctime = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 const char* tmpdirname = os::get_temp_directory();
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 DIR* tmpdirp = os::opendir(tmpdirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (tmpdirp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // for each entry in the directory that matches the pattern hsperfdata_*,
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // open the directory and check if the file for the given vmid exists.
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // The file with the expected name and the latest creation date is used
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // to determine the user name for the process id.
a61af66fc99e Initial load
duke
parents:
diff changeset
316 //
a61af66fc99e Initial load
duke
parents:
diff changeset
317 struct dirent* dentry;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
a61af66fc99e Initial load
duke
parents:
diff changeset
319 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // check if the directory entry is a hsperfdata file
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 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
328 strlen(tmpdirname) + strlen(dentry->d_name) + 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
329 strcpy(usrdir_name, tmpdirname);
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 605
diff changeset
330 strcat(usrdir_name, "\\");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
331 strcat(usrdir_name, dentry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 DIR* subdirp = os::opendir(usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 if (subdirp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 FREE_C_HEAP_ARRAY(char, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // Since we don't create the backing store files in directories
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // pointed to by symbolic links, we also don't follow them when
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // looking for the files. We check for a symbolic link after the
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // call to opendir in order to eliminate a small window where the
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // symlink can be exploited.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 //
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if (!is_directory_secure(usrdir_name)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 FREE_C_HEAP_ARRAY(char, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 os::closedir(subdirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 struct dirent* udentry;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
a61af66fc99e Initial load
duke
parents:
diff changeset
354 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (filename_to_pid(udentry->d_name) == vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 struct stat statbuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 char* filename = NEW_C_HEAP_ARRAY(char,
a61af66fc99e Initial load
duke
parents:
diff changeset
361 strlen(usrdir_name) + strlen(udentry->d_name) + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 strcpy(filename, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 strcat(filename, "\\");
a61af66fc99e Initial load
duke
parents:
diff changeset
365 strcat(filename, udentry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 if (::stat(filename, &statbuf) == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
369 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // skip over files that are not regular files.
a61af66fc99e Initial load
duke
parents:
diff changeset
373 if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
378 // If we found a matching file with a newer creation time, then
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
379 // save the user name. The newer creation time indicates that
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
380 // we found a newer incarnation of the process associated with
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
381 // vmid. Due to the way that Windows recycles pids and the fact
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
382 // that we can't delete the file from the file system namespace
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
383 // until last close, it is possible for there to be more than
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
384 // one hsperfdata file with a name matching vmid (diff users).
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
385 //
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
386 // We no longer ignore hsperfdata files where (st_size == 0).
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
387 // In this function, all we're trying to do is determine the
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
388 // name of the user that owns the process associated with vmid
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
389 // so the size doesn't matter. Very rarely, we have observed
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
390 // hsperfdata files where (st_size == 0) and the st_size field
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
391 // later becomes the expected value.
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
392 //
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
393 if (statbuf.st_ctime > latest_ctime) {
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
394 char* user = strchr(dentry->d_name, '_') + 1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
395
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
396 if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
397 latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
398
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
399 strcpy(latest_user, user);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
400 latest_ctime = statbuf.st_ctime;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 os::closedir(subdirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 FREE_C_HEAP_ARRAY(char, udbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 FREE_C_HEAP_ARRAY(char, usrdir_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410 os::closedir(tmpdirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
411 FREE_C_HEAP_ARRAY(char, tdbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
412
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
413 return(latest_user);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // return the name of the user that owns the process identified by vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 //
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // note: this method should only be used via the Perf native methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // There are various costs to this method and limiting its use to the
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Perf native methods limits the impact to monitoring applications only.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 //
a61af66fc99e Initial load
duke
parents:
diff changeset
422 static char* get_user_name(int vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // A fast implementation is not provided at this time. It's possible
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // to provide a fast process id to user name mapping function using
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // the win32 apis, but the default ACL for the process object only
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // allows processes with the same owner SID to acquire the process
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // to have the JVM change the ACL for the process object to allow arbitrary
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // users to access the process handle and the process security token.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // The security ramifications need to be studied before providing this
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
433 //
a61af66fc99e Initial load
duke
parents:
diff changeset
434 return get_user_name_slow(vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // return the name of the shared memory file mapping object for the
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // named shared memory region for the given user name and vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
439 //
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // The file mapping object's name is not the file name. It is a name
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // in a separate name space.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 //
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
444 //
a61af66fc99e Initial load
duke
parents:
diff changeset
445 static char *get_sharedmem_objectname(const char* user, int vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // construct file mapping object's name, add 3 for two '_' and a
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // null terminator.
a61af66fc99e Initial load
duke
parents:
diff changeset
449 int nbytes = (int)strlen(PERFDATA_NAME) + (int)strlen(user) + 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // the id is converted to an unsigned value here because win32 allows
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // negative process ids. However, OpenFileMapping API complains
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // about a name containing a '-' characters.
a61af66fc99e Initial load
duke
parents:
diff changeset
454 //
a61af66fc99e Initial load
duke
parents:
diff changeset
455 nbytes += UINT_CHARS;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 char* name = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 _snprintf(name, nbytes, "%s_%s_%u", PERFDATA_NAME, user, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 return name;
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // return the file name of the backing store file for the named
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // shared memory region for the given user name and vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
464 //
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // the caller is expected to free the allocated memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
466 //
a61af66fc99e Initial load
duke
parents:
diff changeset
467 static char* get_sharedmem_filename(const char* dirname, int vmid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // add 2 for the file separator and a null terminator.
a61af66fc99e Initial load
duke
parents:
diff changeset
470 size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 char* name = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 _snprintf(name, nbytes, "%s\\%d", dirname, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 return name;
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // remove file
a61af66fc99e Initial load
duke
parents:
diff changeset
479 //
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // this method removes the file with the given file name.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 //
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // Note: if the indicated file is on an SMB network file system, this
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // method may be unsuccessful in removing the file.
a61af66fc99e Initial load
duke
parents:
diff changeset
484 //
a61af66fc99e Initial load
duke
parents:
diff changeset
485 static void remove_file(const char* dirname, const char* filename) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 size_t nbytes = strlen(dirname) + strlen(filename) + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 char* path = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 strcpy(path, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
491 strcat(path, "\\");
a61af66fc99e Initial load
duke
parents:
diff changeset
492 strcat(path, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (::unlink(path) == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 if (PrintMiscellaneous && Verbose) {
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 FREE_C_HEAP_ARRAY(char, path);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // returns true if the process represented by pid is alive, otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // returns false. the validity of the result is only accurate if the
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // target process is owned by the same principal that owns this process.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // this method should not be used if to test the status of an otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // arbitrary process unless it is know that this process has the appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // privileges to guarantee a result valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
512 //
a61af66fc99e Initial load
duke
parents:
diff changeset
513 static bool is_alive(int pid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 if (ph == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // the process does not exist.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 DWORD lastError = GetLastError();
a61af66fc99e Initial load
duke
parents:
diff changeset
520 if (lastError != ERROR_INVALID_PARAMETER) {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 warning("OpenProcess failed: %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
524 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 DWORD exit_status;
a61af66fc99e Initial load
duke
parents:
diff changeset
528 if (!GetExitCodeProcess(ph, &exit_status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 warning("GetExitCodeProcess failed: %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532 CloseHandle(ph);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 CloseHandle(ph);
a61af66fc99e Initial load
duke
parents:
diff changeset
537 return (exit_status == STILL_ACTIVE) ? true : false;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // check if the file system is considered secure for the backing store files
a61af66fc99e Initial load
duke
parents:
diff changeset
541 //
a61af66fc99e Initial load
duke
parents:
diff changeset
542 static bool is_filesystem_secure(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 char root_path[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
545 char fs_type[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 if (PerfBypassFileSystemCheck) {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 warning("bypassing file system criteria checks for %s\n", path);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 char* first_colon = strchr((char *)path, ':');
a61af66fc99e Initial load
duke
parents:
diff changeset
555 if (first_colon == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 warning("expected device specifier in path: %s\n", path);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 size_t len = (size_t)(first_colon - path);
a61af66fc99e Initial load
duke
parents:
diff changeset
563 assert(len + 2 <= MAX_PATH, "unexpected device specifier length");
a61af66fc99e Initial load
duke
parents:
diff changeset
564 strncpy(root_path, path, len + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 root_path[len + 1] = '\\';
a61af66fc99e Initial load
duke
parents:
diff changeset
566 root_path[len + 2] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // check that we have something like "C:\" or "AA:\"
a61af66fc99e Initial load
duke
parents:
diff changeset
569 assert(strlen(root_path) >= 3, "device specifier too short");
a61af66fc99e Initial load
duke
parents:
diff changeset
570 assert(strchr(root_path, ':') != NULL, "bad device specifier format");
a61af66fc99e Initial load
duke
parents:
diff changeset
571 assert(strchr(root_path, '\\') != NULL, "bad device specifier format");
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 DWORD maxpath;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 DWORD flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 if (!GetVolumeInformation(root_path, NULL, 0, NULL, &maxpath,
a61af66fc99e Initial load
duke
parents:
diff changeset
577 &flags, fs_type, MAX_PATH)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // we can't get information about the volume, so assume unsafe.
a61af66fc99e Initial load
duke
parents:
diff changeset
579 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 warning("could not get device information for %s: "
a61af66fc99e Initial load
duke
parents:
diff changeset
581 " path = %s: lasterror = %d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
582 root_path, path, GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 if ((flags & FS_PERSISTENT_ACLS) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // file system doesn't support ACLs, declare file system unsafe
a61af66fc99e Initial load
duke
parents:
diff changeset
589 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 warning("file system type %s on device %s does not support"
a61af66fc99e Initial load
duke
parents:
diff changeset
591 " ACLs\n", fs_type, root_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
593 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 if ((flags & FS_VOL_IS_COMPRESSED) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // file system is compressed, declare file system unsafe
a61af66fc99e Initial load
duke
parents:
diff changeset
598 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
599 warning("file system type %s on device %s is compressed\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
600 fs_type, root_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // cleanup stale shared memory resources
a61af66fc99e Initial load
duke
parents:
diff changeset
609 //
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // This method attempts to remove all stale shared memory files in
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // the named user temporary directory. It scans the named directory
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // for files matching the pattern ^$[0-9]*$. For each file found, the
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // process id is extracted from the file name and a test is run to
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // determine if the process is alive. If the process is not alive,
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // any stale file resources are removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
616 //
a61af66fc99e Initial load
duke
parents:
diff changeset
617 static void cleanup_sharedmem_resources(const char* dirname) {
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // open the user temp directory
a61af66fc99e Initial load
duke
parents:
diff changeset
620 DIR* dirp = os::opendir(dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 if (dirp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // directory doesn't exist, so there is nothing to cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
624 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (!is_directory_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // the directory is not secure, don't attempt any cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
629 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // for each entry in the directory that matches the expected file
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // name pattern, determine if the file resources are stale and if
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // so, remove the file resources. Note, instrumented HotSpot processes
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // for this user may start and/or terminate during this search and
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // remove or create new files in this directory. The behavior of this
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // loop under these conditions is dependent upon the implementation of
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // opendir/readdir.
a61af66fc99e Initial load
duke
parents:
diff changeset
639 //
a61af66fc99e Initial load
duke
parents:
diff changeset
640 struct dirent* entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
a61af66fc99e Initial load
duke
parents:
diff changeset
642 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 int pid = filename_to_pid(entry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 if (pid == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // attempt to remove all unexpected files, except "." and ".."
a61af66fc99e Initial load
duke
parents:
diff changeset
652 remove_file(dirname, entry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654
a61af66fc99e Initial load
duke
parents:
diff changeset
655 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // we now have a file name that converts to a valid integer
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // that could represent a process id . if this process id
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // matches the current process id or the process is not running,
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // then remove the stale file resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
663 //
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // process liveness is detected by checking the exit status
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // of the process. if the process id is valid and the exit status
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // indicates that it is still running, the file file resources
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // are not removed. If the process id is invalid, or if we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // have permissions to check the process status, or if the process
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // id is valid and the process has terminated, the the file resources
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // are assumed to be stale and are removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
671 //
a61af66fc99e Initial load
duke
parents:
diff changeset
672 if (pid == os::current_process_id() || !is_alive(pid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // we can only remove the file resources. Any mapped views
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // of the file can only be unmapped by the processes that
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // opened those views and the file mapping object will not
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // get removed until all views are unmapped.
a61af66fc99e Initial load
duke
parents:
diff changeset
678 //
a61af66fc99e Initial load
duke
parents:
diff changeset
679 remove_file(dirname, entry->d_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683 os::closedir(dirp);
a61af66fc99e Initial load
duke
parents:
diff changeset
684 FREE_C_HEAP_ARRAY(char, dbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // create a file mapping object with the requested name, and size
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // from the file represented by the given Handle object
a61af66fc99e Initial load
duke
parents:
diff changeset
689 //
a61af66fc99e Initial load
duke
parents:
diff changeset
690 static HANDLE create_file_mapping(const char* name, HANDLE fh, LPSECURITY_ATTRIBUTES fsa, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
691
a61af66fc99e Initial load
duke
parents:
diff changeset
692 DWORD lowSize = (DWORD)size;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 DWORD highSize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 HANDLE fmh = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // Create a file mapping object with the given name. This function
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // will grow the file to the specified size.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
699 fmh = CreateFileMapping(
a61af66fc99e Initial load
duke
parents:
diff changeset
700 fh, /* HANDLE file handle for backing store */
a61af66fc99e Initial load
duke
parents:
diff changeset
701 fsa, /* LPSECURITY_ATTRIBUTES Not inheritable */
a61af66fc99e Initial load
duke
parents:
diff changeset
702 PAGE_READWRITE, /* DWORD protections */
a61af66fc99e Initial load
duke
parents:
diff changeset
703 highSize, /* DWORD High word of max size */
a61af66fc99e Initial load
duke
parents:
diff changeset
704 lowSize, /* DWORD Low word of max size */
a61af66fc99e Initial load
duke
parents:
diff changeset
705 name); /* LPCTSTR name for object */
a61af66fc99e Initial load
duke
parents:
diff changeset
706
a61af66fc99e Initial load
duke
parents:
diff changeset
707 if (fmh == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 warning("CreateFileMapping failed, lasterror = %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 if (GetLastError() == ERROR_ALREADY_EXISTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // a stale file mapping object was encountered. This object may be
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // owned by this or some other user and cannot be removed until
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // the other processes either exit or close their mapping objects
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // and/or mapped views of this mapping object.
a61af66fc99e Initial load
duke
parents:
diff changeset
720 //
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 warning("file mapping already exists, lasterror = %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 CloseHandle(fmh);
a61af66fc99e Initial load
duke
parents:
diff changeset
726 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 return fmh;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // method to free the given security descriptor and the contained
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // access control list.
a61af66fc99e Initial load
duke
parents:
diff changeset
735 //
a61af66fc99e Initial load
duke
parents:
diff changeset
736 static void free_security_desc(PSECURITY_DESCRIPTOR pSD) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738 BOOL success, exists, isdefault;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 PACL pACL;
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (pSD != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // get the access control list from the security descriptor
a61af66fc99e Initial load
duke
parents:
diff changeset
744 success = GetSecurityDescriptorDacl(pSD, &exists, &pACL, &isdefault);
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // if an ACL existed and it was not a default acl, then it must
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // be an ACL we enlisted. free the resources.
a61af66fc99e Initial load
duke
parents:
diff changeset
748 //
a61af66fc99e Initial load
duke
parents:
diff changeset
749 if (success && exists && pACL != NULL && !isdefault) {
a61af66fc99e Initial load
duke
parents:
diff changeset
750 FREE_C_HEAP_ARRAY(char, pACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // free the security descriptor
a61af66fc99e Initial load
duke
parents:
diff changeset
754 FREE_C_HEAP_ARRAY(char, pSD);
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // method to free up a security attributes structure and any
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // contained security descriptors and ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
760 //
a61af66fc99e Initial load
duke
parents:
diff changeset
761 static void free_security_attr(LPSECURITY_ATTRIBUTES lpSA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762
a61af66fc99e Initial load
duke
parents:
diff changeset
763 if (lpSA != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // free the contained security descriptor and the ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
765 free_security_desc(lpSA->lpSecurityDescriptor);
a61af66fc99e Initial load
duke
parents:
diff changeset
766 lpSA->lpSecurityDescriptor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // free the security attributes structure
a61af66fc99e Initial load
duke
parents:
diff changeset
769 FREE_C_HEAP_ARRAY(char, lpSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // get the user SID for the process indicated by the process handle
a61af66fc99e Initial load
duke
parents:
diff changeset
774 //
a61af66fc99e Initial load
duke
parents:
diff changeset
775 static PSID get_user_sid(HANDLE hProcess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 HANDLE hAccessToken;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 PTOKEN_USER token_buf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
779 DWORD rsize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
780
a61af66fc99e Initial load
duke
parents:
diff changeset
781 if (hProcess == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // get the process token
a61af66fc99e Initial load
duke
parents:
diff changeset
786 if (!OpenProcessToken(hProcess, TOKEN_READ, &hAccessToken)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 warning("OpenProcessToken failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
790 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // determine the size of the token structured needed to retrieve
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // the user token information from the access token.
a61af66fc99e Initial load
duke
parents:
diff changeset
795 //
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if (!GetTokenInformation(hAccessToken, TokenUser, NULL, rsize, &rsize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797 DWORD lasterror = GetLastError();
a61af66fc99e Initial load
duke
parents:
diff changeset
798 if (lasterror != ERROR_INSUFFICIENT_BUFFER) {
a61af66fc99e Initial load
duke
parents:
diff changeset
799 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 warning("GetTokenInformation failure: lasterror = %d,"
a61af66fc99e Initial load
duke
parents:
diff changeset
801 " rsize = %d\n", lasterror, rsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 CloseHandle(hAccessToken);
a61af66fc99e Initial load
duke
parents:
diff changeset
804 return 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 token_buf = (PTOKEN_USER) NEW_C_HEAP_ARRAY(char, rsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
809
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // get the user token information
a61af66fc99e Initial load
duke
parents:
diff changeset
811 if (!GetTokenInformation(hAccessToken, TokenUser, token_buf, rsize, &rsize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
813 warning("GetTokenInformation failure: lasterror = %d,"
a61af66fc99e Initial load
duke
parents:
diff changeset
814 " rsize = %d\n", GetLastError(), rsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 FREE_C_HEAP_ARRAY(char, token_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
817 CloseHandle(hAccessToken);
a61af66fc99e Initial load
duke
parents:
diff changeset
818 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 DWORD nbytes = GetLengthSid(token_buf->User.Sid);
a61af66fc99e Initial load
duke
parents:
diff changeset
822 PSID pSID = NEW_C_HEAP_ARRAY(char, nbytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 if (!CopySid(nbytes, pSID, token_buf->User.Sid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 warning("GetTokenInformation failure: lasterror = %d,"
a61af66fc99e Initial load
duke
parents:
diff changeset
827 " rsize = %d\n", GetLastError(), rsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
829 FREE_C_HEAP_ARRAY(char, token_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
830 FREE_C_HEAP_ARRAY(char, pSID);
a61af66fc99e Initial load
duke
parents:
diff changeset
831 CloseHandle(hAccessToken);
a61af66fc99e Initial load
duke
parents:
diff changeset
832 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // close the access token.
a61af66fc99e Initial load
duke
parents:
diff changeset
836 CloseHandle(hAccessToken);
a61af66fc99e Initial load
duke
parents:
diff changeset
837 FREE_C_HEAP_ARRAY(char, token_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 return pSID;
a61af66fc99e Initial load
duke
parents:
diff changeset
840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // structure used to consolidate access control entry information
a61af66fc99e Initial load
duke
parents:
diff changeset
843 //
a61af66fc99e Initial load
duke
parents:
diff changeset
844 typedef struct ace_data {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 PSID pSid; // SID of the ACE
a61af66fc99e Initial load
duke
parents:
diff changeset
846 DWORD mask; // mask for the ACE
a61af66fc99e Initial load
duke
parents:
diff changeset
847 } ace_data_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // method to add an allow access control entry with the access rights
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // indicated in mask for the principal indicated in SID to the given
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // security descriptor. Much of the DACL handling was adapted from
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // the example provided here:
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // http://support.microsoft.com/kb/102102/EN-US/
a61af66fc99e Initial load
duke
parents:
diff changeset
855 //
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 static bool add_allow_aces(PSECURITY_DESCRIPTOR pSD,
a61af66fc99e Initial load
duke
parents:
diff changeset
858 ace_data_t aces[], int ace_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 PACL newACL = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 PACL oldACL = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
861
a61af66fc99e Initial load
duke
parents:
diff changeset
862 if (pSD == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
863 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 BOOL exists, isdefault;
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // retrieve any existing access control list.
a61af66fc99e Initial load
duke
parents:
diff changeset
869 if (!GetSecurityDescriptorDacl(pSD, &exists, &oldACL, &isdefault)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
870 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 warning("GetSecurityDescriptor failure: lasterror = %d \n",
a61af66fc99e Initial load
duke
parents:
diff changeset
872 GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
874 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // get the size of the DACL
a61af66fc99e Initial load
duke
parents:
diff changeset
878 ACL_SIZE_INFORMATION aclinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // GetSecurityDescriptorDacl may return true value for exists (lpbDaclPresent)
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // while oldACL is NULL for some case.
a61af66fc99e Initial load
duke
parents:
diff changeset
882 if (oldACL == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 exists = FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 if (exists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
887 if (!GetAclInformation(oldACL, &aclinfo,
a61af66fc99e Initial load
duke
parents:
diff changeset
888 sizeof(ACL_SIZE_INFORMATION),
a61af66fc99e Initial load
duke
parents:
diff changeset
889 AclSizeInformation)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
890 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 warning("GetAclInformation failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
892 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
895 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 aclinfo.AceCount = 0; // assume NULL DACL
a61af66fc99e Initial load
duke
parents:
diff changeset
897 aclinfo.AclBytesFree = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
898 aclinfo.AclBytesInUse = sizeof(ACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // compute the size needed for the new ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // initial size of ACL is sum of the following:
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // * size of ACL structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // * size of each ACE structure that ACL is to contain minus the sid
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // sidStart member (DWORD) of the ACE.
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // * length of the SID that each ACE is to contain.
a61af66fc99e Initial load
duke
parents:
diff changeset
907 DWORD newACLsize = aclinfo.AclBytesInUse +
a61af66fc99e Initial load
duke
parents:
diff changeset
908 (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) * ace_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
909 for (int i = 0; i < ace_count; i++) {
1968
0b33f0736406 6837842: JNI_CreateJavaVM crashes under impersonation
poonam
parents: 1552
diff changeset
910 assert(aces[i].pSid != 0, "pSid should not be 0");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
911 newACLsize += GetLengthSid(aces[i].pSid);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // create the new ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
915 newACL = (PACL) NEW_C_HEAP_ARRAY(char, newACLsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 if (!InitializeAcl(newACL, newACLsize, ACL_REVISION)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
922 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 unsigned int ace_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // copy any existing ACEs from the old ACL (if any) to the new ACL.
a61af66fc99e Initial load
duke
parents:
diff changeset
927 if (aclinfo.AceCount != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 while (ace_index < aclinfo.AceCount) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 LPVOID ace;
a61af66fc99e Initial load
duke
parents:
diff changeset
930 if (!GetAce(oldACL, ace_index, &ace)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
932 warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937 if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // this is an inherited, allowed ACE; break from loop so we can
a61af66fc99e Initial load
duke
parents:
diff changeset
939 // add the new access allowed, non-inherited ACE in the correct
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // position, immediately following all non-inherited ACEs.
a61af66fc99e Initial load
duke
parents:
diff changeset
941 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // determine if the SID of this ACE matches any of the SIDs
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // for which we plan to set ACEs.
a61af66fc99e Initial load
duke
parents:
diff changeset
946 int matches = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
947 for (int i = 0; i < ace_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 if (EqualSid(aces[i].pSid, &(((ACCESS_ALLOWED_ACE *)ace)->SidStart))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
949 matches++;
a61af66fc99e Initial load
duke
parents:
diff changeset
950 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // if there are no SID matches, then add this existing ACE to the new ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
955 if (matches == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
a61af66fc99e Initial load
duke
parents:
diff changeset
957 ((PACE_HEADER)ace)->AceSize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
959 warning("AddAce failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
961 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
962 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965 ace_index++;
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 // add the passed-in access control entries to the new ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
970 for (int i = 0; i < ace_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if (!AddAccessAllowedAce(newACL, ACL_REVISION,
a61af66fc99e Initial load
duke
parents:
diff changeset
972 aces[i].mask, aces[i].pSid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
973 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 warning("AddAccessAllowedAce failure: lasterror = %d \n",
a61af66fc99e Initial load
duke
parents:
diff changeset
975 GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
978 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
981
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // now copy the rest of the inherited ACEs from the old ACL
a61af66fc99e Initial load
duke
parents:
diff changeset
983 if (aclinfo.AceCount != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // picking up at ace_index, where we left off in the
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // previous ace_index loop
a61af66fc99e Initial load
duke
parents:
diff changeset
986 while (ace_index < aclinfo.AceCount) {
a61af66fc99e Initial load
duke
parents:
diff changeset
987 LPVOID ace;
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if (!GetAce(oldACL, ace_index, &ace)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
993 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
995 if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
a61af66fc99e Initial load
duke
parents:
diff changeset
996 ((PACE_HEADER)ace)->AceSize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 warning("AddAce failure: lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 ace_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // add the new ACL to the security descriptor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if (!SetSecurityDescriptorDacl(pSD, TRUE, newACL, FALSE)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 warning("SetSecurityDescriptorDacl failure:"
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 " lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
605
98cb887364d3 6810672: Comment typos
twisti
parents: 0
diff changeset
1017 // if running on windows 2000 or later, set the automatic inheritance
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // control flags.
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 _SetSecurityDescriptorControl = (SetSecurityDescriptorControlFnPtr)
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 "SetSecurityDescriptorControl");
a61af66fc99e Initial load
duke
parents:
diff changeset
1023
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 if (_SetSecurityDescriptorControl != NULL) {
605
98cb887364d3 6810672: Comment typos
twisti
parents: 0
diff changeset
1025 // We do not want to further propagate inherited DACLs, so making them
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // protected prevents that.
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 if (!_SetSecurityDescriptorControl(pSD, SE_DACL_PROTECTED,
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 SE_DACL_PROTECTED)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 warning("SetSecurityDescriptorControl failure:"
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 " lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 FREE_C_HEAP_ARRAY(char, newACL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // Note, the security descriptor maintains a reference to the newACL, not
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // a copy of it. Therefore, the newACL is not freed here. It is freed when
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // the security descriptor containing its reference is freed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // method to create a security attributes structure, which contains a
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // security descriptor and an access control list comprised of 0 or more
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // access control entries. The method take an array of ace_data structures
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // that indicate the ACE to be added to the security descriptor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // the caller must free the resources associated with the security
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // attributes structure created by this method by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // free_security_attr() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 static LPSECURITY_ATTRIBUTES make_security_attr(ace_data_t aces[], int count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // allocate space for a security descriptor
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 NEW_C_HEAP_ARRAY(char, SECURITY_DESCRIPTOR_MIN_LENGTH);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // initialize the security descriptor
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 warning("InitializeSecurityDescriptor failure: "
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 "lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 free_security_desc(pSD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // add the access control entries
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (!add_allow_aces(pSD, aces, count)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 free_security_desc(pSD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // allocate and initialize the security attributes structure and
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // return it to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 LPSECURITY_ATTRIBUTES lpSA = (LPSECURITY_ATTRIBUTES)
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 NEW_C_HEAP_ARRAY(char, sizeof(SECURITY_ATTRIBUTES));
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 lpSA->nLength = sizeof(SECURITY_ATTRIBUTES);
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 lpSA->lpSecurityDescriptor = pSD;
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 lpSA->bInheritHandle = FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 return(lpSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1086
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // method to create a security attributes structure with a restrictive
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // access control list that creates a set access rights for the user/owner
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // of the securable object and a separate set access rights for everyone else.
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 // also provides for full access rights for the administrator group.
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // the caller must free the resources associated with the security
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // attributes structure created by this method by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // free_security_attr() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 static LPSECURITY_ATTRIBUTES make_user_everybody_admin_security_attr(
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 DWORD umask, DWORD emask, DWORD amask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 ace_data_t aces[3];
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // initialize the user ace data
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 aces[0].pSid = get_user_sid(GetCurrentProcess());
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 aces[0].mask = umask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
1968
0b33f0736406 6837842: JNI_CreateJavaVM crashes under impersonation
poonam
parents: 1552
diff changeset
1106 if (aces[0].pSid == 0)
0b33f0736406 6837842: JNI_CreateJavaVM crashes under impersonation
poonam
parents: 1552
diff changeset
1107 return NULL;
0b33f0736406 6837842: JNI_CreateJavaVM crashes under impersonation
poonam
parents: 1552
diff changeset
1108
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // get the well known SID for BUILTIN\Administrators
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 PSID administratorsSid = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 SID_IDENTIFIER_AUTHORITY SIDAuthAdministrators = SECURITY_NT_AUTHORITY;
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 if (!AllocateAndInitializeSid( &SIDAuthAdministrators, 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 SECURITY_BUILTIN_DOMAIN_RID,
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 DOMAIN_ALIAS_RID_ADMINS,
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 0, 0, 0, 0, 0, 0, &administratorsSid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 warning("AllocateAndInitializeSid failure: "
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 "lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // initialize the ace data for administrator group
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 aces[1].pSid = administratorsSid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 aces[1].mask = amask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1128
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // get the well known SID for the universal Everybody
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 PSID everybodySid = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 SID_IDENTIFIER_AUTHORITY SIDAuthEverybody = SECURITY_WORLD_SID_AUTHORITY;
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 if (!AllocateAndInitializeSid( &SIDAuthEverybody, 1, SECURITY_WORLD_RID,
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 0, 0, 0, 0, 0, 0, 0, &everybodySid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 warning("AllocateAndInitializeSid failure: "
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 "lasterror = %d \n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // initialize the ace data for everybody else.
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 aces[2].pSid = everybodySid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 aces[2].mask = emask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // create a security attributes structure with access control
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // entries as initialized above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 FREE_C_HEAP_ARRAY(char, aces[0].pSid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 FreeSid(everybodySid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 FreeSid(administratorsSid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 return(lpSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1155
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // method to create the security attributes structure for restricting
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // access to the user temporary directory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // the caller must free the resources associated with the security
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // attributes structure created by this method by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // free_security_attr() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 static LPSECURITY_ATTRIBUTES make_tmpdir_security_attr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // create full access rights for the user/owner of the directory
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // and read-only access rights for everybody else. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // effectively equivalent to UNIX 755 permissions on a directory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 DWORD umask = STANDARD_RIGHTS_REQUIRED | FILE_ALL_ACCESS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 DWORD emask = GENERIC_READ | FILE_LIST_DIRECTORY | FILE_TRAVERSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 DWORD amask = STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 return make_user_everybody_admin_security_attr(umask, emask, amask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // method to create the security attributes structure for restricting
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // access to the shared memory backing store file.
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // the caller must free the resources associated with the security
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // attributes structure created by this method by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // free_security_attr() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 static LPSECURITY_ATTRIBUTES make_file_security_attr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // create extensive access rights for the user/owner of the file
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // and attribute read-only access rights for everybody else. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // is effectively equivalent to UNIX 600 permissions on a file.
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 DWORD umask = STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 DWORD emask = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES |
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 FILE_READ_EA | FILE_LIST_DIRECTORY | FILE_TRAVERSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 DWORD amask = STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 return make_user_everybody_admin_security_attr(umask, emask, amask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1197
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // method to create the security attributes structure for restricting
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // access to the name shared memory file mapping object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // the caller must free the resources associated with the security
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // attributes structure created by this method by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 // free_security_attr() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 static LPSECURITY_ATTRIBUTES make_smo_security_attr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // create extensive access rights for the user/owner of the shared
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // memory object and attribute read-only access rights for everybody
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // else. This is effectively equivalent to UNIX 600 permissions on
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // on the shared memory object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 DWORD umask = STANDARD_RIGHTS_REQUIRED | FILE_MAP_ALL_ACCESS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 DWORD emask = STANDARD_RIGHTS_READ; // attributes only
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 DWORD amask = STANDARD_RIGHTS_ALL | FILE_MAP_ALL_ACCESS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 return make_user_everybody_admin_security_attr(umask, emask, amask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // make the user specific temporary directory
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 static bool make_user_tmp_dir(const char* dirname) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 LPSECURITY_ATTRIBUTES pDirSA = make_tmpdir_security_attr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if (pDirSA == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // create the directory with the given security attributes
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (!CreateDirectory(dirname, pDirSA)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 DWORD lasterror = GetLastError();
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 if (lasterror == ERROR_ALREADY_EXISTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // The directory already exists and was probably created by another
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 // JVM instance. However, this could also be the result of a
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 // deliberate symlink. Verify that the existing directory is safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 if (!is_directory_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // directory is not secure
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 warning("%s directory is insecure\n", dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // The administrator should be able to delete this directory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // But the directory created by previous version of JVM may not
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // have permission for administrators to delete this directory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // So add full permission to the administrator. Also setting new
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // DACLs might fix the corrupted the DACLs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 if (!SetFileSecurity(dirname, secInfo, pDirSA->lpSecurityDescriptor)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 lasterror = GetLastError();
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 warning("SetFileSecurity failed for %s directory. lasterror %d \n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 dirname, lasterror);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 warning("CreateDirectory failed: %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1266
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // free the security attributes structure
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 free_security_attr(pDirSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // create the shared memory resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // This function creates the shared memory resources. This includes
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // the backing store file and the file mapping shared memory object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 static HANDLE create_sharedmem_resources(const char* dirname, const char* filename, const char* objectname, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 HANDLE fh = INVALID_HANDLE_VALUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 HANDLE fmh = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // create the security attributes for the backing store file
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 LPSECURITY_ATTRIBUTES lpFileSA = make_file_security_attr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 if (lpFileSA == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1289
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // create the security attributes for the shared memory object
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 LPSECURITY_ATTRIBUTES lpSmoSA = make_smo_security_attr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 if (lpSmoSA == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 free_security_attr(lpFileSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1296
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // create the user temporary directory
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 if (!make_user_tmp_dir(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // could not make/find the directory or the found directory
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // was not secure
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // Create the file - the FILE_FLAG_DELETE_ON_CLOSE flag allows the
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // file to be deleted by the last process that closes its handle to
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // the file. This is important as the apis do not allow a terminating
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // JVM being monitored by another process to remove the file name.
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // the FILE_SHARE_DELETE share mode is valid only in winnt
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 fh = CreateFile(
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 filename, /* LPCTSTR file name */
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 GENERIC_READ|GENERIC_WRITE, /* DWORD desired access */
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 (os::win32::is_nt() ? FILE_SHARE_DELETE : 0)|
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 FILE_SHARE_READ, /* DWORD share mode, future READONLY
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 * open operations allowed
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 lpFileSA, /* LPSECURITY security attributes */
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 CREATE_ALWAYS, /* DWORD creation disposition
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 * create file, if it already
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 * exists, overwrite it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 FILE_FLAG_DELETE_ON_CLOSE, /* DWORD flags and attributes */
a61af66fc99e Initial load
duke
parents:
diff changeset
1326
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 NULL); /* HANDLE template file access */
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 free_security_attr(lpFileSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 if (fh == INVALID_HANDLE_VALUE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 DWORD lasterror = GetLastError();
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 warning("could not create file %s: %d\n", filename, lasterror);
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // try to create the file mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 fmh = create_file_mapping(objectname, fh, lpSmoSA, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 free_security_attr(lpSmoSA);
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 if (fmh == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // closing the file handle here will decrement the reference count
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // on the file. When all processes accessing the file close their
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // handle to it, the reference count will decrement to 0 and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // OS will delete the file. These semantics are requested by the
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // FILE_FLAG_DELETE_ON_CLOSE flag in CreateFile call above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 CloseHandle(fh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 fh = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 return NULL;
2236
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1353 } else {
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1354 // We created the file mapping, but rarely the size of the
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1355 // backing store file is reported as zero (0) which can cause
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1356 // failures when trying to use the hsperfdata file.
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1357 struct stat statbuf;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1358 int ret_code = ::stat(filename, &statbuf);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1359 if (ret_code == OS_ERR) {
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1360 if (PrintMiscellaneous && Verbose) {
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1361 warning("Could not get status information from file %s: %s\n",
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1362 filename, strerror(errno));
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1363 }
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1364 CloseHandle(fmh);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1365 CloseHandle(fh);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1366 fh = NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1367 fmh = NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1368 return NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1369 }
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1370
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1371 // We could always call FlushFileBuffers() but the Microsoft
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1372 // docs indicate that it is considered expensive so we only
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1373 // call it when we observe the size as zero (0).
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1374 if (statbuf.st_size == 0 && FlushFileBuffers(fh) != TRUE) {
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1375 DWORD lasterror = GetLastError();
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1376 if (PrintMiscellaneous && Verbose) {
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1377 warning("could not flush file %s: %d\n", filename, lasterror);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1378 }
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1379 CloseHandle(fmh);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1380 CloseHandle(fh);
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1381 fh = NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1382 fmh = NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1383 return NULL;
de14f1eee390 6954420: 2/4 jps shows "process information unavailable" sometimes
dcubed
parents: 1972
diff changeset
1384 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // the file has been successfully created and the file mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // object has been created.
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 sharedmem_fileHandle = fh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 sharedmem_fileName = strdup(filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
1391
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 return fmh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // open the shared memory object for the given vmid.
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 static HANDLE open_sharedmem_object(const char* objectname, DWORD ofm_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1398
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 HANDLE fmh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // open the file mapping with the requested mode
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 fmh = OpenFileMapping(
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 ofm_access, /* DWORD access mode */
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 FALSE, /* BOOL inherit flag - Do not allow inherit */
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 objectname); /* name for object */
a61af66fc99e Initial load
duke
parents:
diff changeset
1406
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 if (fmh == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 warning("OpenFileMapping failed for shared memory object %s:"
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 " lasterror = %d\n", objectname, GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 THROW_MSG_(vmSymbols::java_lang_Exception(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 "Could not open PerfMemory", INVALID_HANDLE_VALUE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 return fmh;;
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // create a named shared memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // On Win32, a named shared memory object has a name space that
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // is independent of the file system name space. Shared memory object,
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // or more precisely, file mapping objects, provide no mechanism to
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // inquire the size of the memory region. There is also no api to
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 // enumerate the memory regions for various processes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // This implementation utilizes the shared memory name space in parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 // with the file system name space. This allows us to determine the
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // size of the shared memory region from the size of the file and it
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // allows us to provide a common, file system based name space for
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // shared memory across platforms.
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 static char* mapping_create_shared(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 void *mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 int vmid = os::current_process_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1437
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // get the name of the user associated with this process
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 char* user = get_user_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
1440
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 if (user == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 // construct the name of the user specific temporary directory
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 char* dirname = get_user_tmp_dir(user);
a61af66fc99e Initial load
duke
parents:
diff changeset
1447
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // check that the file system is secure - i.e. it supports ACLs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 if (!is_filesystem_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1452
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // create the names of the backing store files and for the
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // share memory object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 char* filename = get_sharedmem_filename(dirname, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 char* objectname = get_sharedmem_objectname(user, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // cleanup any stale shared memory resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 cleanup_sharedmem_resources(dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1461
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 assert(((size != 0) && (size % os::vm_page_size() == 0)),
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 "unexpected PerfMemry region size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 FREE_C_HEAP_ARRAY(char, user);
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // create the shared memory resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 sharedmem_fileMapHandle =
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 create_sharedmem_resources(dirname, filename, objectname, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1470
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 FREE_C_HEAP_ARRAY(char, objectname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 FREE_C_HEAP_ARRAY(char, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1474
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 if (sharedmem_fileMapHandle == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // map the file into the address space
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 mapAddress = MapViewOfFile(
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 sharedmem_fileMapHandle, /* HANDLE = file mapping object */
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 FILE_MAP_ALL_ACCESS, /* DWORD access flags */
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 0, /* DWORD High word of offset */
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 0, /* DWORD Low word of offset */
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 (DWORD)size); /* DWORD Number of bytes to map */
a61af66fc99e Initial load
duke
parents:
diff changeset
1486
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 if (mapAddress == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 warning("MapViewOfFile failed, lasterror = %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 CloseHandle(sharedmem_fileMapHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 sharedmem_fileMapHandle = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // clear the shared memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 (void)memset(mapAddress, '\0', size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1498
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 return (char*) mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // this method deletes the file mapping object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 static void delete_file_mapping(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1505
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // cleanup the persistent shared memory resources. since DestroyJavaVM does
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // not support unloading of the JVM, unmapping of the memory resource is not
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 // performed. The memory will be reclaimed by the OS upon termination of all
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 // processes mapping the resource. The file mapping handle and the file
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // handle are closed here to expedite the remove of the file by the OS. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // file is not removed directly because it was created with
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 // FILE_FLAG_DELETE_ON_CLOSE semantics and any attempt to remove it would
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 // be unsuccessful.
a61af66fc99e Initial load
duke
parents:
diff changeset
1514
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // close the fileMapHandle. the file mapping will still be retained
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // by the OS as long as any other JVM processes has an open file mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // handle or a mapped view of the file.
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 if (sharedmem_fileMapHandle != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 CloseHandle(sharedmem_fileMapHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 sharedmem_fileMapHandle = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // close the file handle. This will decrement the reference count on the
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 // backing store file. When the reference count decrements to 0, the OS
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 // will delete the file. These semantics apply because the file was
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // created with the FILE_FLAG_DELETE_ON_CLOSE flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 if (sharedmem_fileHandle != INVALID_HANDLE_VALUE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 CloseHandle(sharedmem_fileHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 sharedmem_fileHandle = INVALID_HANDLE_VALUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // this method determines the size of the shared memory file
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 static size_t sharedmem_filesize(const char* filename, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 struct stat statbuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1540
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // get the file size
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // on win95/98/me, _stat returns a file size of 0 bytes, but on
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // winnt/2k the appropriate file size is returned. support for
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // the sharable aspects of performance counters was abandonded
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 // on the non-nt win32 platforms due to this and other api
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 // inconsistencies
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 if (::stat(filename, &statbuf) == OS_ERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 warning("stat %s failed: %s\n", filename, strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 THROW_MSG_0(vmSymbols::java_io_IOException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 "Could not determine PerfMemory size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 if ((statbuf.st_size == 0) || (statbuf.st_size % os::vm_page_size() != 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 warning("unexpected file size: size = " SIZE_FORMAT "\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 statbuf.st_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 THROW_MSG_0(vmSymbols::java_lang_Exception(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 "Invalid PerfMemory size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 return statbuf.st_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1568
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // this method opens a file mapping object and maps the object
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 // into the address space of the process
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 static void open_file_mapping(const char* user, int vmid,
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 PerfMemory::PerfMemoryMode mode,
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 char** addrp, size_t* sizep, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1575
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1577
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 void *mapAddress = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 HANDLE fmh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 DWORD ofm_access;
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 DWORD mv_access;
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 const char* luser = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1584
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 if (mode == PerfMemory::PERF_MODE_RO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 ofm_access = FILE_MAP_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 mv_access = FILE_MAP_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 else if (mode == PerfMemory::PERF_MODE_RW) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 #ifdef LATER
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 ofm_access = FILE_MAP_READ | FILE_MAP_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 mv_access = FILE_MAP_READ | FILE_MAP_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 "Unsupported access mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 "Illegal access mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1602
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // if a user name wasn't specified, then find the user name for
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // the owner of the target vm.
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 if (user == NULL || strlen(user) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 luser = get_user_name(vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 luser = user;
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1611
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 if (luser == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 "Could not map vmid to user name");
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1616
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // get the names for the resources for the target vm
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 char* dirname = get_user_tmp_dir(luser);
a61af66fc99e Initial load
duke
parents:
diff changeset
1619
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // since we don't follow symbolic links when creating the backing
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 // store file, we also don't following them when attaching
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 if (!is_directory_secure(dirname)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 FREE_C_HEAP_ARRAY(char, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 "Process not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 char* filename = get_sharedmem_filename(dirname, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 char* objectname = get_sharedmem_objectname(luser, vmid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1631
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // copy heap memory to resource memory. the objectname and
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // filename are passed to methods that may throw exceptions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // using resource arrays for these names prevents the leaks
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // that would otherwise occur.
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 char* robjectname = NEW_RESOURCE_ARRAY(char, strlen(objectname) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 strcpy(rfilename, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 strcpy(robjectname, objectname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // free the c heap resources that are no longer needed
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 FREE_C_HEAP_ARRAY(char, dirname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 FREE_C_HEAP_ARRAY(char, filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 FREE_C_HEAP_ARRAY(char, objectname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1647
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 if (*sizep == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 size = sharedmem_filesize(rfilename, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 assert(size != 0, "unexpected size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1652
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // Open the file mapping object with the given name
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 fmh = open_sharedmem_object(robjectname, ofm_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1655
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 assert(fmh != INVALID_HANDLE_VALUE, "unexpected handle value");
a61af66fc99e Initial load
duke
parents:
diff changeset
1657
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // map the entire file into the address space
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 mapAddress = MapViewOfFile(
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 fmh, /* HANDLE Handle of file mapping object */
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 mv_access, /* DWORD access flags */
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 0, /* DWORD High word of offset */
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 0, /* DWORD Low word of offset */
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 size); /* DWORD Number of bytes to map */
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 if (mapAddress == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 warning("MapViewOfFile failed, lasterror = %d\n", GetLastError());
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 CloseHandle(fmh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 "Could not map PerfMemory");
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1674
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 *addrp = (char*)mapAddress;
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 *sizep = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1677
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // File mapping object can be closed at this time without
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // invalidating the mapped view of the file
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 CloseHandle(fmh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1681
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 if (PerfTraceMemOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at "
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 INTPTR_FORMAT "\n", size, vmid, mapAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1687
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 // this method unmaps the the mapped view of the the
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // file mapping object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 static void remove_file_mapping(char* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 // the file mapping object was closed in open_file_mapping()
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // after the file map view was created. We only need to
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // unmap the file view here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 UnmapViewOfFile(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // create the PerfData memory region in shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 static char* create_shared_memory(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1701
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 return mapping_create_shared(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // release a named, shared memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 void delete_shared_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1708
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 delete_file_mapping(addr, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1711
a61af66fc99e Initial load
duke
parents:
diff changeset
1712
a61af66fc99e Initial load
duke
parents:
diff changeset
1713
a61af66fc99e Initial load
duke
parents:
diff changeset
1714
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // create the PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // This method creates the memory region used to store performance
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // data for the JVM. The memory may be created in standard or
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 void PerfMemory::create_memory_region(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1722
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 if (PerfDisableSharedMem || !os::win32::is_nt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // do not share the memory for the performance data.
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 PerfDisableSharedMem = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 _start = create_standard_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 _start = create_shared_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 if (_start == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // creation of the shared memory region failed, attempt
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // to create a contiguous, non-shared memory region instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 warning("Reverting to non-shared PerfMemory region.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 PerfDisableSharedMem = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 _start = create_standard_memory(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1742
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 if (_start != NULL) _capacity = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1746
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 // delete the PerfData memory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 // This method deletes the memory region used to store performance
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // data for the JVM. The memory region indicated by the <address, size>
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // tuple will be inaccessible after a call to this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 void PerfMemory::delete_memory_region() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1754
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 assert((start() != NULL && capacity() > 0), "verify proper state");
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 // If user specifies PerfDataSaveFile, it will save the performance data
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // to the specified file name no matter whether PerfDataSaveToFile is specified
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // -XX:+PerfDataSaveToFile.
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 if (PerfDataSaveToFile || PerfDataSaveFile != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 save_memory_to_file(start(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 if (PerfDisableSharedMem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 delete_standard_memory(start(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 delete_shared_memory(start(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1772
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 // attach to the PerfData memory region for another JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // This method returns an <address, size> tuple that points to
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 // a memory buffer that is kept reasonably synchronized with
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 // the PerfData memory region for the indicated JVM. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // buffer may be kept in synchronization via shared memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // or some other mechanism that keeps the buffer updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 // If the JVM chooses not to support the attachability feature,
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 // this method should throw an UnsupportedOperation exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // This implementation utilizes named shared memory to map
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 // the indicated process's PerfData memory region into this JVMs
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // address space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 void PerfMemory::attach(const char* user, int vmid, PerfMemoryMode mode,
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 char** addrp, size_t* sizep, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1790
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 if (vmid == 0 || vmid == os::current_process_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 *addrp = start();
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 *sizep = capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1796
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 open_file_mapping(user, vmid, mode, addrp, sizep, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1799
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 // detach from the PerfData memory region of another JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // This method detaches the PerfData memory region of another
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // JVM, specified as an <address, size> tuple of a buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 // in this process's address space. This method may perform
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 // arbitrary actions to accomplish the detachment. The memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 // region specified by <address, size> will be inaccessible after
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 // a call to this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // If the JVM chooses not to support the attachability feature,
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // this method should throw an UnsupportedOperation exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 // This implementation utilizes named shared memory to detach
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 // the indicated process's PerfData memory region from this
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // process's address space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 void PerfMemory::detach(char* addr, size_t bytes, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 assert(addr != 0, "address sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 assert(bytes > 0, "capacity sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 if (PerfMemory::contains(addr) || PerfMemory::contains(addr + bytes - 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // prevent accidental detachment of this process's PerfMemory region
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1825
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 remove_file_mapping(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 char* PerfMemory::backing_store_filename() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 return sharedmem_fileName;
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 }