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