1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
281 }
282 }
283
284 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
285 strcpy(user_name, user);
286
287 return user_name;
288 }
289
290 // return the name of the user that owns the process identified by vmid.
291 //
292 // This method uses a slow directory search algorithm to find the backing
293 // store file for the specified vmid and returns the user name, as determined
294 // by the user name suffix of the hsperfdata_<username> directory name.
295 //
296 // the caller is expected to free the allocated memory.
297 //
298 static char* get_user_name_slow(int vmid) {
299
300 // directory search
301 char* oldest_user = NULL;
302 time_t oldest_ctime = 0;
303
304 const char* tmpdirname = os::get_temp_directory();
305
306 DIR* tmpdirp = os::opendir(tmpdirname);
307
308 if (tmpdirp == NULL) {
309 return NULL;
310 }
311
312 // for each entry in the directory that matches the pattern hsperfdata_*,
313 // open the directory and check if the file for the given vmid exists.
314 // The file with the expected name and the latest creation date is used
315 // to determine the user name for the process id.
316 //
317 struct dirent* dentry;
318 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
319 errno = 0;
320 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
321
322 // check if the directory entry is a hsperfdata file
358 struct stat statbuf;
359
360 char* filename = NEW_C_HEAP_ARRAY(char,
361 strlen(usrdir_name) + strlen(udentry->d_name) + 2);
362
363 strcpy(filename, usrdir_name);
364 strcat(filename, "\\");
365 strcat(filename, udentry->d_name);
366
367 if (::stat(filename, &statbuf) == OS_ERR) {
368 FREE_C_HEAP_ARRAY(char, filename);
369 continue;
370 }
371
372 // skip over files that are not regular files.
373 if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
374 FREE_C_HEAP_ARRAY(char, filename);
375 continue;
376 }
377
378 // compare and save filename with latest creation time
379 if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
380
381 if (statbuf.st_ctime > oldest_ctime) {
382 char* user = strchr(dentry->d_name, '_') + 1;
383
384 if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
385 oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
386
387 strcpy(oldest_user, user);
388 oldest_ctime = statbuf.st_ctime;
389 }
390 }
391
392 FREE_C_HEAP_ARRAY(char, filename);
393 }
394 }
395 os::closedir(subdirp);
396 FREE_C_HEAP_ARRAY(char, udbuf);
397 FREE_C_HEAP_ARRAY(char, usrdir_name);
398 }
399 os::closedir(tmpdirp);
400 FREE_C_HEAP_ARRAY(char, tdbuf);
401
402 return(oldest_user);
403 }
404
405 // return the name of the user that owns the process identified by vmid.
406 //
407 // note: this method should only be used via the Perf native methods.
408 // There are various costs to this method and limiting its use to the
409 // Perf native methods limits the impact to monitoring applications only.
410 //
411 static char* get_user_name(int vmid) {
412
413 // A fast implementation is not provided at this time. It's possible
414 // to provide a fast process id to user name mapping function using
415 // the win32 apis, but the default ACL for the process object only
416 // allows processes with the same owner SID to acquire the process
417 // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
418 // to have the JVM change the ACL for the process object to allow arbitrary
419 // users to access the process handle and the process security token.
420 // The security ramifications need to be studied before providing this
421 // mechanism.
422 //
1322 if (PrintMiscellaneous && Verbose) {
1323 warning("could not create file %s: %d\n", filename, lasterror);
1324 }
1325 return NULL;
1326 }
1327
1328 // try to create the file mapping
1329 fmh = create_file_mapping(objectname, fh, lpSmoSA, size);
1330
1331 free_security_attr(lpSmoSA);
1332
1333 if (fmh == NULL) {
1334 // closing the file handle here will decrement the reference count
1335 // on the file. When all processes accessing the file close their
1336 // handle to it, the reference count will decrement to 0 and the
1337 // OS will delete the file. These semantics are requested by the
1338 // FILE_FLAG_DELETE_ON_CLOSE flag in CreateFile call above.
1339 CloseHandle(fh);
1340 fh = NULL;
1341 return NULL;
1342 }
1343
1344 // the file has been successfully created and the file mapping
1345 // object has been created.
1346 sharedmem_fileHandle = fh;
1347 sharedmem_fileName = strdup(filename);
1348
1349 return fmh;
1350 }
1351
1352 // open the shared memory object for the given vmid.
1353 //
1354 static HANDLE open_sharedmem_object(const char* objectname, DWORD ofm_access, TRAPS) {
1355
1356 HANDLE fmh;
1357
1358 // open the file mapping with the requested mode
1359 fmh = OpenFileMapping(
1360 ofm_access, /* DWORD access mode */
1361 FALSE, /* BOOL inherit flag - Do not allow inherit */
1362 objectname); /* name for object */
1363
|
1 /*
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
281 }
282 }
283
284 char* user_name = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
285 strcpy(user_name, user);
286
287 return user_name;
288 }
289
290 // return the name of the user that owns the process identified by vmid.
291 //
292 // This method uses a slow directory search algorithm to find the backing
293 // store file for the specified vmid and returns the user name, as determined
294 // by the user name suffix of the hsperfdata_<username> directory name.
295 //
296 // the caller is expected to free the allocated memory.
297 //
298 static char* get_user_name_slow(int vmid) {
299
300 // directory search
301 char* latest_user = NULL;
302 time_t latest_ctime = 0;
303
304 const char* tmpdirname = os::get_temp_directory();
305
306 DIR* tmpdirp = os::opendir(tmpdirname);
307
308 if (tmpdirp == NULL) {
309 return NULL;
310 }
311
312 // for each entry in the directory that matches the pattern hsperfdata_*,
313 // open the directory and check if the file for the given vmid exists.
314 // The file with the expected name and the latest creation date is used
315 // to determine the user name for the process id.
316 //
317 struct dirent* dentry;
318 char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
319 errno = 0;
320 while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
321
322 // check if the directory entry is a hsperfdata file
358 struct stat statbuf;
359
360 char* filename = NEW_C_HEAP_ARRAY(char,
361 strlen(usrdir_name) + strlen(udentry->d_name) + 2);
362
363 strcpy(filename, usrdir_name);
364 strcat(filename, "\\");
365 strcat(filename, udentry->d_name);
366
367 if (::stat(filename, &statbuf) == OS_ERR) {
368 FREE_C_HEAP_ARRAY(char, filename);
369 continue;
370 }
371
372 // skip over files that are not regular files.
373 if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
374 FREE_C_HEAP_ARRAY(char, filename);
375 continue;
376 }
377
378 // If we found a matching file with a newer creation time, then
379 // save the user name. The newer creation time indicates that
380 // we found a newer incarnation of the process associated with
381 // vmid. Due to the way that Windows recycles pids and the fact
382 // that we can't delete the file from the file system namespace
383 // until last close, it is possible for there to be more than
384 // one hsperfdata file with a name matching vmid (diff users).
385 //
386 // We no longer ignore hsperfdata files where (st_size == 0).
387 // In this function, all we're trying to do is determine the
388 // name of the user that owns the process associated with vmid
389 // so the size doesn't matter. Very rarely, we have observed
390 // hsperfdata files where (st_size == 0) and the st_size field
391 // later becomes the expected value.
392 //
393 if (statbuf.st_ctime > latest_ctime) {
394 char* user = strchr(dentry->d_name, '_') + 1;
395
396 if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
397 latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
398
399 strcpy(latest_user, user);
400 latest_ctime = statbuf.st_ctime;
401 }
402
403 FREE_C_HEAP_ARRAY(char, filename);
404 }
405 }
406 os::closedir(subdirp);
407 FREE_C_HEAP_ARRAY(char, udbuf);
408 FREE_C_HEAP_ARRAY(char, usrdir_name);
409 }
410 os::closedir(tmpdirp);
411 FREE_C_HEAP_ARRAY(char, tdbuf);
412
413 return(latest_user);
414 }
415
416 // return the name of the user that owns the process identified by vmid.
417 //
418 // note: this method should only be used via the Perf native methods.
419 // There are various costs to this method and limiting its use to the
420 // Perf native methods limits the impact to monitoring applications only.
421 //
422 static char* get_user_name(int vmid) {
423
424 // A fast implementation is not provided at this time. It's possible
425 // to provide a fast process id to user name mapping function using
426 // the win32 apis, but the default ACL for the process object only
427 // allows processes with the same owner SID to acquire the process
428 // handle (via OpenProcess(PROCESS_QUERY_INFORMATION)). It's possible
429 // to have the JVM change the ACL for the process object to allow arbitrary
430 // users to access the process handle and the process security token.
431 // The security ramifications need to be studied before providing this
432 // mechanism.
433 //
1333 if (PrintMiscellaneous && Verbose) {
1334 warning("could not create file %s: %d\n", filename, lasterror);
1335 }
1336 return NULL;
1337 }
1338
1339 // try to create the file mapping
1340 fmh = create_file_mapping(objectname, fh, lpSmoSA, size);
1341
1342 free_security_attr(lpSmoSA);
1343
1344 if (fmh == NULL) {
1345 // closing the file handle here will decrement the reference count
1346 // on the file. When all processes accessing the file close their
1347 // handle to it, the reference count will decrement to 0 and the
1348 // OS will delete the file. These semantics are requested by the
1349 // FILE_FLAG_DELETE_ON_CLOSE flag in CreateFile call above.
1350 CloseHandle(fh);
1351 fh = NULL;
1352 return NULL;
1353 } else {
1354 // We created the file mapping, but rarely the size of the
1355 // backing store file is reported as zero (0) which can cause
1356 // failures when trying to use the hsperfdata file.
1357 struct stat statbuf;
1358 int ret_code = ::stat(filename, &statbuf);
1359 if (ret_code == OS_ERR) {
1360 if (PrintMiscellaneous && Verbose) {
1361 warning("could not stat file %s: %d\n", filename, ret_code);
1362 }
1363 CloseHandle(fmh);
1364 CloseHandle(fh);
1365 fh = NULL;
1366 fmh = NULL;
1367 return NULL;
1368 }
1369
1370 // We could always call FlushFileBuffers() but the Microsoft
1371 // docs indicate that it is considered expensive so we only
1372 // call it when we observe the size as zero (0).
1373 if (statbuf.st_size == 0 && FlushFileBuffers(fh) != TRUE) {
1374 DWORD lasterror = GetLastError();
1375 if (PrintMiscellaneous && Verbose) {
1376 warning("could not flush file %s: %d\n", filename, lasterror);
1377 }
1378 CloseHandle(fmh);
1379 CloseHandle(fh);
1380 fh = NULL;
1381 fmh = NULL;
1382 return NULL;
1383 }
1384 }
1385
1386 // the file has been successfully created and the file mapping
1387 // object has been created.
1388 sharedmem_fileHandle = fh;
1389 sharedmem_fileName = strdup(filename);
1390
1391 return fmh;
1392 }
1393
1394 // open the shared memory object for the given vmid.
1395 //
1396 static HANDLE open_sharedmem_object(const char* objectname, DWORD ofm_access, TRAPS) {
1397
1398 HANDLE fmh;
1399
1400 // open the file mapping with the requested mode
1401 fmh = OpenFileMapping(
1402 ofm_access, /* DWORD access mode */
1403 FALSE, /* BOOL inherit flag - Do not allow inherit */
1404 objectname); /* name for object */
1405
|