src/hotspot/os/solaris/attachListener_solaris.cpp
author ysuenaga
Tue, 16 Jul 2019 07:29:12 +0900
changeset 55682 70fab3a8ff02
parent 51584 d395677d99f3
permissions -rw-r--r--
8225690: Multiple AttachListener threads can be created Reviewed-by: sspitsyn, cjplummer
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
     2
 * Copyright (c) 2005, 2019, 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: 5410
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5410
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: 5410
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: 6170
diff changeset
    25
#include "precompiled.hpp"
49593
4dd58ecc9912 8200105: Remove cyclic dependency between oop.inline.hpp and collectedHeap.inline.hpp
stefank
parents: 49449
diff changeset
    26
#include "logging/log.hpp"
49449
ef5d5d343e2a 8199263: Split interfaceSupport.hpp to not require including .inline.hpp files
coleenp
parents: 47216
diff changeset
    27
#include "runtime/interfaceSupport.inline.hpp"
25468
5331df506290 8048241: Introduce umbrella header os.inline.hpp and clean up includes
goetz
parents: 23870
diff changeset
    28
#include "runtime/os.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6170
diff changeset
    29
#include "services/attachListener.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6170
diff changeset
    30
#include "services/dtraceAttacher.hpp"
46589
f1c04490ded1 8182848: Some functions misplaced in debug.hpp
coleenp
parents: 40625
diff changeset
    31
#include "utilities/vmError.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
#include <door.h>
23870
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
    34
#include <limits.h>
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
#include <string.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
#include <signal.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
#include <sys/types.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
#include <sys/socket.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
#include <sys/stat.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
// stropts.h uses STR in stream ioctl defines
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
#undef STR
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
#include <stropts.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
#undef STR
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
#define STR(a) #a
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// The attach mechanism on Solaris is implemented using the Doors IPC
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// mechanism. The first tool to attempt to attach causes the attach
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
// listener thread to startup. This thread creats a door that is
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
// associated with a function that enqueues an operation to the attach
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// listener. The door is attached to a file in the file system so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// client (tools) can locate it. To enqueue an operation to the VM the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// client calls through the door which invokes the enqueue function in
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
// this process. The credentials of the client are checked and if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
// effective uid matches this process then the operation is enqueued.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// When an operation completes the attach listener is required to send the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// operation result and any result data to the client. In this implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
// the result is returned via a UNIX domain socket. A pair of connected
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
// sockets (socketpair) is created in the enqueue function and the file
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
// descriptor for one of the sockets is returned to the client as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
// return from the door call. The other end is retained in this process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
// When the operation completes the result is sent to the client and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
// the socket is closed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
// forward reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
class SolarisAttachOperation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
class SolarisAttachListener: AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  // the path to which we attach the door file descriptor
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  static char _door_path[PATH_MAX+1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  static volatile bool _has_door_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // door descriptor returned by door_create
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  static int _door_descriptor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
    78
  static bool _atexit_registered;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // mutex to protect operation list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  static mutex_t _mutex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  // semaphore to wakeup listener thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  static sema_t _wakeup;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  static mutex_t* mutex()                               { return &_mutex; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  static sema_t* wakeup()                               { return &_wakeup; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  // enqueued operation list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  static SolarisAttachOperation* _head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  static SolarisAttachOperation* _tail;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  static SolarisAttachOperation* head()                 { return _head; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  static void set_head(SolarisAttachOperation* head)    { _head = head; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  static SolarisAttachOperation* tail()                 { return _tail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  static void set_tail(SolarisAttachOperation* tail)    { _tail = tail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  // create the door
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  static int create_door();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
    ATTACH_PROTOCOL_VER = 1                             // protocol version
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    ATTACH_ERROR_BADREQUEST     = 100,                  // error code returned by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    ATTACH_ERROR_BADVERSION     = 101,                  // the door call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    ATTACH_ERROR_RESOURCE       = 102,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    ATTACH_ERROR_INTERNAL       = 103,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    ATTACH_ERROR_DENIED         = 104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   114
  static void set_door_path(char* path) {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   115
    if (path == NULL) {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   116
      _door_path[0] = '\0';
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   117
      _has_door_path = false;
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   118
    } else {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   119
      strncpy(_door_path, path, PATH_MAX);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   120
      _door_path[PATH_MAX] = '\0';      // ensure it's nul terminated
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   121
      _has_door_path = true;
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   122
    }
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   123
  }
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   124
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   125
  static void set_door_descriptor(int dd)               { _door_descriptor = dd; }
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   126
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  // initialize the listener
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  static int init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  static bool has_door_path()                           { return _has_door_path; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  static char* door_path()                              { return _door_path; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  static int door_descriptor()                          { return _door_descriptor; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  // enqueue an operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  static void enqueue(SolarisAttachOperation* op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  // dequeue an operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  static SolarisAttachOperation* dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
// SolarisAttachOperation is an AttachOperation that additionally encapsulates
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
// a socket connection to the requesting client/tool. SolarisAttachOperation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
// can additionally be held in a linked list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
class SolarisAttachOperation: public AttachOperation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  friend class SolarisAttachListener;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  // connection to client
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  int _socket;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  // linked list support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  SolarisAttachOperation* _next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  SolarisAttachOperation* next()                         { return _next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  void set_next(SolarisAttachOperation* next)            { _next = next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  void complete(jint res, bufferedStream* st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  int socket() const                                     { return _socket; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  void set_socket(int s)                                 { _socket = s; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  SolarisAttachOperation(char* name) : AttachOperation(name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    set_socket(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
// statics
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
char SolarisAttachListener::_door_path[PATH_MAX+1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
volatile bool SolarisAttachListener::_has_door_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
int SolarisAttachListener::_door_descriptor = -1;
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   175
bool SolarisAttachListener::_atexit_registered = false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
mutex_t SolarisAttachListener::_mutex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
sema_t SolarisAttachListener::_wakeup;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
SolarisAttachOperation* SolarisAttachListener::_head = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
SolarisAttachOperation* SolarisAttachListener::_tail = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
// Supporting class to help split a buffer into individual components
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
class ArgumentIterator : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  char* _pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  char* _end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  ArgumentIterator(char* arg_buffer, size_t arg_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    _pos = arg_buffer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    _end = _pos + arg_size - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  char* next() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    if (*_pos == '\0') {
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   193
      // advance the iterator if possible (null arguments)
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   194
      if (_pos < _end) {
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   195
        _pos += 1;
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   196
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    char* res = _pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    char* next_pos = strchr(_pos, '\0');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    if (next_pos < _end)  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
      next_pos++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    _pos = next_pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
// Calls from the door function to check that the client credentials
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
// match this process. Returns 0 if credentials okay, otherwise -1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
static int check_credentials() {
25891
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   212
  ucred_t *cred_info = NULL;
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   213
  int ret = -1; // deny by default
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  // get client credentials
25891
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   216
  if (door_ucred(&cred_info) == -1) {
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   217
    return -1; // unable to get them, deny
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
25891
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   220
  // get euid/egid from ucred_free
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   221
  uid_t ucred_euid = ucred_geteuid(cred_info);
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   222
  gid_t ucred_egid = ucred_getegid(cred_info);
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   223
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   224
  // check that the effective uid/gid matches
50333
7cea35f78b50 8197387: jcmd started by "root" must be allowed to access all VM processes
dtitov
parents: 49742
diff changeset
   225
  if (os::Posix::matches_effective_uid_and_gid_or_root(ucred_euid, ucred_egid)) {
25891
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   226
    ret =  0;  // allow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  }
25891
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   228
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   229
  ucred_free(cred_info);
103846690fc2 8049046: Deprecated Function in hotspot/src/os/solaris/vm/attachListener_solaris.cpp
dsamersoff
parents: 25468
diff changeset
   230
  return ret;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
// Parses the argument buffer to create an AttachOperation that we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
// enqueue to the attach listener.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
// The buffer is expected to be formatted as follows:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
// <ver>0<cmd>0<arg>0<arg>0<arg>0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
// where <ver> is the version number (must be "1"), <cmd> is the command
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
// name ("load, "datadump", ...) and <arg> is an argument.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
static SolarisAttachOperation* create_operation(char* argp, size_t arg_size, int* err) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  // assume bad request until parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  *err = SolarisAttachListener::ATTACH_ERROR_BADREQUEST;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  if (arg_size < 2 || argp[arg_size-1] != '\0') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    return NULL;   // no ver or not null terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  // Use supporting class to iterate over the buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  ArgumentIterator args(argp, arg_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // First check the protocol version
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  char* ver = args.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  if (ver == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  if (atoi(ver) != SolarisAttachListener::ATTACH_PROTOCOL_VER) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    *err = SolarisAttachListener::ATTACH_ERROR_BADVERSION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  // Get command name and create the operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  char* name = args.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  SolarisAttachOperation* op = new SolarisAttachOperation(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  // Iterate over the arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  for (int i=0; i<AttachOperation::arg_count_max; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    char* arg = args.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    if (arg == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
      op->set_arg(i, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
      if (strlen(arg) > AttachOperation::arg_length_max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
        delete op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      op->set_arg(i, arg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  // return operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  *err = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
// create special operation to indicate all clients have detached
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
static SolarisAttachOperation* create_detachall_operation() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  return new SolarisAttachOperation(AttachOperation::detachall_operation_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
// This is door function which the client executes via a door_call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  static void enqueue_proc(void* cookie, char* argp, size_t arg_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
                           door_desc_t* dt, uint_t n_desc)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    int return_fd = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    SolarisAttachOperation* op = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
51584
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   301
    // wait up to 10 seconds for listener to be up and running
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    jint res = 0;
51584
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   303
    int sleep_count = 0;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   304
    while (!AttachListener::is_initialized()) {
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   305
      sleep(1); // 1 second
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   306
      sleep_count++;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   307
      if (sleep_count > 10) { // try for 10 seconds
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   308
        debug_only(warning("door_call when not enabled"));
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   309
        res = (jint)SolarisAttachListener::ATTACH_ERROR_INTERNAL;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   310
        break;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 50333
diff changeset
   311
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    // check client credentials
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    if (res == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
      if (check_credentials() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
        res = (jint)SolarisAttachListener::ATTACH_ERROR_DENIED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    // if we are stopped at ShowMessageBoxOnError then maybe we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    // load a diagnostic library
46589
f1c04490ded1 8182848: Some functions misplaced in debug.hpp
coleenp
parents: 40625
diff changeset
   323
    if (res == 0 && VMError::is_error_reported()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
      if (ShowMessageBoxOnError) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
        // TBD - support loading of diagnostic library here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      // can't enqueue operation after fatal error
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
      res = (jint)SolarisAttachListener::ATTACH_ERROR_RESOURCE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    // create the operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    if (res == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
      int err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
      op = create_operation(argp, arg_size, &err);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
      res = (op == NULL) ? (jint)err : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    // create a pair of connected sockets. Store the file descriptor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
    // for one end in the operation and enqueue the operation. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
    // file descriptor for the other end wil be returned to the client.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    if (res == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      int s[2];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
      if (socketpair(PF_UNIX, SOCK_STREAM, 0, s) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
        delete op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
        res = (jint)SolarisAttachListener::ATTACH_ERROR_RESOURCE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
        op->set_socket(s[0]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
        return_fd = s[1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
        SolarisAttachListener::enqueue(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    // Return 0 (success) + file descriptor, or non-0 (error)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    if (res == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
      door_desc_t desc;
12505
80f2bda36ea8 7162955: Attach api on Solaris, too many open files
dlong
parents: 7397
diff changeset
   357
      // DOOR_RELEASE flag makes sure fd is closed after passing it to
80f2bda36ea8 7162955: Attach api on Solaris, too many open files
dlong
parents: 7397
diff changeset
   358
      // the client.  See door_return(3DOOR) man page.
80f2bda36ea8 7162955: Attach api on Solaris, too many open files
dlong
parents: 7397
diff changeset
   359
      desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
      desc.d_data.d_desc.d_descriptor = return_fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
      door_return((char*)&res, sizeof(res), &desc, 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
      door_return((char*)&res, sizeof(res), NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
// atexit hook to detach the door and remove the file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  static void listener_cleanup() {
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   371
    int dd = SolarisAttachListener::door_descriptor();
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   372
    if (dd >= 0) {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   373
      SolarisAttachListener::set_door_descriptor(-1);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   374
      ::close(dd);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   375
    }
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   376
    if (SolarisAttachListener::has_door_path()) {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   377
      char* path = SolarisAttachListener::door_path();
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   378
      ::fdetach(path);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   379
      ::unlink(path);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   380
      SolarisAttachListener::set_door_path(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
// Create the door
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
int SolarisAttachListener::create_door() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  char door_path[PATH_MAX+1];
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   388
  char initial_path[PATH_MAX+1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  int fd, res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  // register exit function
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   392
  if (!_atexit_registered) {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   393
    _atexit_registered = true;
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   394
    ::atexit(listener_cleanup);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   395
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  // create the door descriptor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  int dd = ::door_create(enqueue_proc, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  if (dd < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   403
  // create initial file to attach door descriptor
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5089
diff changeset
   404
  snprintf(door_path, sizeof(door_path), "%s/.java_pid%d",
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5089
diff changeset
   405
           os::get_temp_directory(), os::current_process_id());
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   406
  snprintf(initial_path, sizeof(initial_path), "%s.tmp", door_path);
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   407
  RESTARTABLE(::creat(initial_path, S_IRUSR | S_IWUSR), fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  if (fd == -1) {
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   409
    log_debug(attach)("attempt to create door file %s failed (%d)", initial_path, errno);
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   410
    ::door_revoke(dd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  assert(fd >= 0, "bad file descriptor");
18078
10417cf9967d 7178026: os::close can restart ::close but that is not a restartable syscall
rdurbin
parents: 13963
diff changeset
   414
  ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  // attach the door descriptor to the file
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   417
  if ((res = ::fattach(dd, initial_path)) == -1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    // if busy then detach and try again
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
    if (errno == EBUSY) {
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   420
      ::fdetach(initial_path);
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   421
      res = ::fattach(dd, initial_path);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    if (res == -1) {
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   424
      log_debug(attach)("unable to create door - fattach failed (%d)", errno);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
      ::door_revoke(dd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      dd = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  }
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   429
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   430
  // rename file so that clients can attach
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   431
  if (dd >= 0) {
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   432
    if (::rename(initial_path, door_path) == -1) {
18078
10417cf9967d 7178026: os::close can restart ::close but that is not a restartable syscall
rdurbin
parents: 13963
diff changeset
   433
        ::close(dd);
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   434
        ::fdetach(initial_path);
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   435
        log_debug(attach)("unable to create door - rename %s to %s failed (%d)", errno);
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   436
        dd = -1;
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   437
    }
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   438
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  if (dd >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
    set_door_descriptor(dd);
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   441
    set_door_path(door_path);
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   442
    log_trace(attach)("door file %s created succesfully", door_path);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  } else {
6170
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   444
    // unable to create door, attach it to file, or rename file into place
82aea418ab2d 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 5547
diff changeset
   445
    ::unlink(initial_path);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
// Initialization - create the door, locks, and other initialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
int SolarisAttachListener::init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  if (create_door()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  int status = os::Solaris::mutex_init(&_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  assert_status(status==0, status, "mutex_init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  status = ::sema_init(&_wakeup, 0, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  assert_status(status==0, status, "sema_init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  set_head(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  set_tail(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
// Dequeue an operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
SolarisAttachOperation* SolarisAttachListener::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
    int res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    // wait for somebody to enqueue something
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    while ((res = ::sema_wait(wakeup())) == EINTR)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
      ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    if (res) {
37113
5a33bf5089ac 8148425: strerror() function is not thread-safe
stuefe
parents: 25891
diff changeset
   479
      warning("sema_wait failed: %s", os::strerror(res));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
    // lock the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
    res = os::Solaris::mutex_lock(mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    assert(res == 0, "mutex_lock failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    // remove the head of the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    SolarisAttachOperation* op = head();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    if (op != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
      set_head(op->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
      if (head() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
        set_tail(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
    // unlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
    os::Solaris::mutex_unlock(mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
    // if we got an operation when return it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
    if (op != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
      return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
// Enqueue an operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
void SolarisAttachListener::enqueue(SolarisAttachOperation* op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  // lock list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  int res = os::Solaris::mutex_lock(mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  assert(res == 0, "mutex_lock failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  // enqueue at tail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  op->set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  if (head() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
    set_head(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
    tail()->set_next(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  set_tail(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // wakeup the attach listener
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  RESTARTABLE(::sema_post(wakeup()), res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  assert(res == 0, "sema_post failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  // unlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  os::Solaris::mutex_unlock(mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
// support function - writes the (entire) buffer to a socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
static int write_fully(int s, char* buf, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    int n = ::write(s, buf, len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    if (n == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
      if (errno != EINTR) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      buf += n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
      len -= n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  while (len > 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
// Complete an operation by sending the operation result and any result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
// output to the client. At this time the socket is in blocking mode so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
// potentially we can block if there is a lot of data and the client is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
// non-responsive. For most operations this is a non-issue because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
// default send buffer is sufficient to buffer everything. In the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
// if there are operations that involves a very big reply then it the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
// socket could be made non-blocking and a timeout could be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
void SolarisAttachOperation::complete(jint res, bufferedStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  if (this->socket() >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
    ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
    // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    // write operation result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    char msg[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    sprintf(msg, "%d\n", res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    int rc = write_fully(this->socket(), msg, strlen(msg));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    // write any result data
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
    if (rc == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
      write_fully(this->socket(), (char*) st->base(), st->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
      ::shutdown(this->socket(), 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    // close socket and we're done
18078
10417cf9967d 7178026: os::close can restart ::close but that is not a restartable syscall
rdurbin
parents: 13963
diff changeset
   574
    ::close(this->socket());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
    // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  delete this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
// AttachListener functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
AttachOperation* AttachListener::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  AttachOperation* op = SolarisAttachListener::dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
18931
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   601
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   602
// Performs initialization at vm startup
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   603
// For Solaris we remove any stale .java_pid file which could cause
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   604
// an attaching process to think we are ready to receive a door_call
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   605
// before we are properly initialized
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   606
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   607
void AttachListener::vm_start() {
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   608
  char fn[PATH_MAX+1];
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   609
  struct stat64 st;
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   610
  int ret;
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   611
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   612
  int n = snprintf(fn, sizeof(fn), "%s/.java_pid%d",
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   613
           os::get_temp_directory(), os::current_process_id());
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   614
  assert(n < sizeof(fn), "java_pid file name buffer overflow");
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   615
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   616
  RESTARTABLE(::stat64(fn, &st), ret);
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   617
  if (ret == 0) {
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   618
    ret = ::unlink(fn);
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   619
    if (ret == -1) {
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   620
      log_debug(attach)("Failed to remove stale attach pid file at %s", fn);
18931
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   621
    }
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   622
  }
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   623
}
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 18078
diff changeset
   624
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
int AttachListener::pd_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  // java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  int ret_code = SolarisAttachListener::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  return ret_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
// Attach Listener is started lazily except in the case when
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
// +ReduseSignalUsage is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
bool AttachListener::init_at_startup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  if (ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
55682
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   651
bool AttachListener::check_socket_file() {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   652
  int ret;
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   653
  struct stat64 st;
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   654
  ret = stat64(SolarisAttachListener::door_path(), &st);
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   655
  if (ret == -1) { // need to restart attach listener.
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   656
    log_debug(attach)("Door file %s does not exist - Restart Attach Listener",
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   657
                      SolarisAttachListener::door_path());
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   658
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   659
    listener_cleanup();
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   660
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   661
    // wait to terminate current attach listener instance...
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   662
    while (AttachListener::transit_state(AL_INITIALIZING,
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   663
                                         AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   664
      os::naked_yield();
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   665
    }
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   666
    return is_init_trigger();
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   667
  }
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   668
  return false;
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   669
}
70fab3a8ff02 8225690: Multiple AttachListener threads can be created
ysuenaga
parents: 51584
diff changeset
   670
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
// If the file .attach_pid<pid> exists in the working directory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
// or /tmp then this is the trigger to start the attach mechanism
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
bool AttachListener::is_init_trigger() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  if (init_at_startup() || is_initialized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    return false;               // initialized at startup or already initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  }
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   677
  char fn[PATH_MAX + 1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  int ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
  struct stat64 st;
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   680
  sprintf(fn, ".attach_pid%d", os::current_process_id());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  RESTARTABLE(::stat64(fn, &st), ret);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  if (ret == -1) {
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   683
    log_trace(attach)("Failed to find attach file: %s, trying alternate", fn);
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5089
diff changeset
   684
    snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5089
diff changeset
   685
             os::get_temp_directory(), os::current_process_id());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
    RESTARTABLE(::stat64(fn, &st), ret);
40625
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   687
    if (ret == -1) {
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   688
      log_debug(attach)("Failed to find attach file: %s", fn);
6b45fb9188f9 8157236: attach on ARMv7 fails with com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file
dsamersoff
parents: 37113
diff changeset
   689
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  if (ret == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    // simple check to avoid starting the attach mechanism when
50333
7cea35f78b50 8197387: jcmd started by "root" must be allowed to access all VM processes
dtitov
parents: 49742
diff changeset
   693
    // a bogus non-root user creates the file
7cea35f78b50 8197387: jcmd started by "root" must be allowed to access all VM processes
dtitov
parents: 49742
diff changeset
   694
    if (os::Posix::matches_effective_uid_or_root(st.st_uid)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
      init();
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   696
      log_trace(attach)("Attach triggered by %s", fn);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
      return true;
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   698
    } else {
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49593
diff changeset
   699
      log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not triggered", fn, st.st_uid, geteuid());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
// if VM aborts then detach/cleanup
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
void AttachListener::abort() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  listener_cleanup();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
void AttachListener::pd_data_dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  os::signal_notify(SIGQUIT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
static jint enable_dprobes(AttachOperation* op, outputStream* out) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  const char* probe = op->arg(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  if (probe == NULL || probe[0] == '\0') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
    out->print_cr("No probe specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
    return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  } else {
23870
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   720
    char *end;
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   721
    long val = strtol(probe, &end, 10);
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   722
    if (end == probe || val < 0 || val > INT_MAX) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
      out->print_cr("invalid probe type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
      return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
    } else {
23870
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   726
      int probe_typess = (int) val;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
      DTrace::enable_dprobes(probe_typess);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
      return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
// platform specific operations table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
static AttachOperationFunctionInfo funcs[] = {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  { "enabledprobes", enable_dprobes },
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  { NULL, NULL }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  for (i = 0; funcs[i].name != NULL; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    if (strcmp(funcs[i].name, name) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
      return &funcs[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
// Solaris specific global flag set. Currently, we support only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
// changing ExtendedDTraceProbes flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
  const char* name = op->arg(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
  assert(name != NULL, "flag name should not be null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  bool flag = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  const char* arg1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  if ((arg1 = op->arg(1)) != NULL) {
23870
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   757
    char *end;
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   758
    flag = (strtol(arg1, &end, 10) != 0);
2c9e85bccffb 8038296: sun/tools/jinfo/Basic.sh: java.io.IOException: Command failed in target VM
sla
parents: 18931
diff changeset
   759
    if (arg1 == end) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
      out->print_cr("flag value has to be an integer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
      return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   765
  if (strcmp(name, "ExtendedDTraceProbes") == 0) {
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   766
    DTrace::set_extended_dprobes(flag);
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   767
    return JNI_OK;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   770
  if (strcmp(name, "DTraceMonitorProbes") == 0) {
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   771
    DTrace::set_monitor_dprobes(flag);
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   772
    return JNI_OK;
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   773
  }
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   774
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   775
  out->print_cr("flag '%s' cannot be changed", name);
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 1
diff changeset
   776
  return JNI_ERR;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
void AttachListener::pd_detachall() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  DTrace::detach_all_clients();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
}