annotate src/os/linux/vm/attachListener_linux.cpp @ 4582:b24386206122

Made all vm builds go into subdirectories, even product builds to simplify building the various types of VMs (server, client and graal). Made HotSpot build jobs use the number of CPUs on the host machine.
author Doug Simon <doug.simon@oracle.com>
date Mon, 13 Feb 2012 23:13:37 +0100
parents f95d63e2154a
children e95fc50106cf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1868
diff changeset
2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1497
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1497
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1497
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1868
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1868
diff changeset
26 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1868
diff changeset
27 #include "runtime/os.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1868
diff changeset
28 #include "services/attachListener.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1868
diff changeset
29 #include "services/dtraceAttacher.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 #include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
32 #include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
33 #include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
34 #include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
35 #include <sys/un.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
36 #include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
37
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
38 #ifndef UNIX_PATH_MAX
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
39 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
40 #endif
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
41
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // The attach mechanism on Linux uses a UNIX domain socket. An attach listener
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // thread is created at startup or is created on-demand via a signal from
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // the client tool. The attach listener creates a socket and binds it to a file
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // in the filesystem. The attach listener then acts as a simple (single-
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
46 // threaded) server - it waits for a client to connect, reads the request,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // executes it, and returns the response to the client via the socket
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // connection.
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // As the socket is a UNIX domain socket it means that only clients on the
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // local machine can connect. In addition there are two other aspects to
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // the security:
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // 1. The well known file that the socket is bound to has permission 400
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // 2. When a client connect, the SO_PEERCRED socket option is used to
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // obtain the credentials of client. We check that the effective uid
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // of the client matches this process.
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // forward reference
a61af66fc99e Initial load
duke
parents:
diff changeset
59 class LinuxAttachOperation;
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 class LinuxAttachListener: AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // the path to which we bind the UNIX domain socket
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
64 static char _path[UNIX_PATH_MAX];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static bool _has_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // the file descriptor for the listening socket
a61af66fc99e Initial load
duke
parents:
diff changeset
68 static int _listener;
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 static void set_path(char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 if (path == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 _has_path = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 } else {
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
74 strncpy(_path, path, UNIX_PATH_MAX);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
75 _path[UNIX_PATH_MAX-1] = '\0';
0
a61af66fc99e Initial load
duke
parents:
diff changeset
76 _has_path = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 static void set_listener(int s) { _listener = s; }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // reads a request from the given connected socket
a61af66fc99e Initial load
duke
parents:
diff changeset
83 static LinuxAttachOperation* read_request(int s);
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
86 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 ATTACH_PROTOCOL_VER = 1 // protocol version
a61af66fc99e Initial load
duke
parents:
diff changeset
88 };
a61af66fc99e Initial load
duke
parents:
diff changeset
89 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 ATTACH_ERROR_BADVERSION = 101 // error codes
a61af66fc99e Initial load
duke
parents:
diff changeset
91 };
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // initialize the listener, returns 0 if okay
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static int init();
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 static char* path() { return _path; }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 static bool has_path() { return _has_path; }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 static int listener() { return _listener; }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // write the given buffer to a socket
a61af66fc99e Initial load
duke
parents:
diff changeset
101 static int write_fully(int s, char* buf, int len);
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static LinuxAttachOperation* dequeue();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 };
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 class LinuxAttachOperation: public AttachOperation {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // the connection to the client
a61af66fc99e Initial load
duke
parents:
diff changeset
109 int _socket;
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
112 void complete(jint res, bufferedStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 void set_socket(int s) { _socket = s; }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 int socket() const { return _socket; }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 LinuxAttachOperation(char* name) : AttachOperation(name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 set_socket(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 };
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // statics
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
123 char LinuxAttachListener::_path[UNIX_PATH_MAX];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
124 bool LinuxAttachListener::_has_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
125 int LinuxAttachListener::_listener = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Supporting class to help split a buffer into individual components
a61af66fc99e Initial load
duke
parents:
diff changeset
128 class ArgumentIterator : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
130 char* _pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 char* _end;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
133 ArgumentIterator(char* arg_buffer, size_t arg_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 _pos = arg_buffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 _end = _pos + arg_size - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137 char* next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (*_pos == '\0') {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 char* res = _pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 char* next_pos = strchr(_pos, '\0');
a61af66fc99e Initial load
duke
parents:
diff changeset
143 if (next_pos < _end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 next_pos++;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _pos = next_pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 };
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // atexit hook to stop listener and unlink the file that it is
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // bound too.
a61af66fc99e Initial load
duke
parents:
diff changeset
154 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static void listener_cleanup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 static int cleanup_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 if (!cleanup_done) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 cleanup_done = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 int s = LinuxAttachListener::listener();
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if (s != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 ::close(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (LinuxAttachListener::has_path()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 ::unlink(LinuxAttachListener::path());
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Initialization - create a listener socket and bind it to a file
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 int LinuxAttachListener::init() {
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
173 char path[UNIX_PATH_MAX]; // socket file
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
174 char initial_path[UNIX_PATH_MAX]; // socket file during setup
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
175 int listener; // listener socket (file descriptor)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // register function to cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
178 ::atexit(listener_cleanup);
a61af66fc99e Initial load
duke
parents:
diff changeset
179
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
180 int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
181 os::get_temp_directory(), os::current_process_id());
1868
3dc12ef8735e 6989297: Integrate additional portability improvements
bobv
parents: 1675
diff changeset
182 if (n < (int)UNIX_PATH_MAX) {
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
183 n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
184 }
1868
3dc12ef8735e 6989297: Integrate additional portability improvements
bobv
parents: 1675
diff changeset
185 if (n >= (int)UNIX_PATH_MAX) {
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
186 return -1;
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
187 }
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
188
0
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // create the listener socket
a61af66fc99e Initial load
duke
parents:
diff changeset
190 listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (listener == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
195 // bind socket
0
a61af66fc99e Initial load
duke
parents:
diff changeset
196 struct sockaddr_un addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 addr.sun_family = AF_UNIX;
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
198 strcpy(addr.sun_path, initial_path);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
199 ::unlink(initial_path);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
200 int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (res == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 RESTARTABLE(::close(listener), res);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
206 // put in listen mode, set permissions, and rename into place
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
207 res = ::listen(listener, 5);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
208 if (res == 0) {
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
209 RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
210 if (res == 0) {
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
211 res = ::rename(initial_path, path);
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
212 }
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
213 }
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
214 if (res == -1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
215 RESTARTABLE(::close(listener), res);
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
216 ::unlink(initial_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
217 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
1675
a81afd9c293c 6649594: Intermittent IOExceptions during dynamic attach on linux and solaris
alanb
parents: 1552
diff changeset
219 set_path(path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 set_listener(listener);
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Given a socket that is connected to a peer we read the request and
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // create an AttachOperation. As the socket is blocking there is potential
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // for a denial-of-service if the peer does not response. However this happens
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // after the peer credentials have been checked and in the worst case it just
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // means that the attach listener thread is blocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
230 //
a61af66fc99e Initial load
duke
parents:
diff changeset
231 LinuxAttachOperation* LinuxAttachListener::read_request(int s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 char ver_str[8];
a61af66fc99e Initial load
duke
parents:
diff changeset
233 sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // The request is a sequence of strings so we first figure out the
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // expected count and the maximum possible length of the request.
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // The request is:
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // <ver>0<cmd>0<arg>0<arg>0<arg>0
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // where <ver> is the protocol version (1), <cmd> is the command
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // name ("load", "datadump", ...), and <arg> is an argument
a61af66fc99e Initial load
duke
parents:
diff changeset
241 int expected_str_count = 2 + AttachOperation::arg_count_max;
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
242 const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
0
a61af66fc99e Initial load
duke
parents:
diff changeset
243 AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 char buf[max_len];
a61af66fc99e Initial load
duke
parents:
diff changeset
246 int str_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Read until all (expected) strings have been read, the buffer is
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // full, or EOF.
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 int off = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 int left = max_len;
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 int n;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 RESTARTABLE(read(s, buf+off, left), n);
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if (n == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 return NULL; // reset by peer or other error
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (n == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 for (int i=0; i<n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 if (buf[off+i] == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // EOS found
a61af66fc99e Initial load
duke
parents:
diff changeset
266 str_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // The first string is <ver> so check it now to
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // check for protocol mis-match
a61af66fc99e Initial load
duke
parents:
diff changeset
270 if (str_count == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if ((strlen(buf) != strlen(ver_str)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
272 (atoi(buf) != ATTACH_PROTOCOL_VER)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 char msg[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
274 sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION);
a61af66fc99e Initial load
duke
parents:
diff changeset
275 write_fully(s, msg, strlen(msg));
a61af66fc99e Initial load
duke
parents:
diff changeset
276 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 off += n;
a61af66fc99e Initial load
duke
parents:
diff changeset
282 left -= n;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 } while (left > 0 && str_count < expected_str_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 if (str_count != expected_str_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return NULL; // incomplete request
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // parse request
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 ArgumentIterator args(buf, (max_len)-left);
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // version already checked
a61af66fc99e Initial load
duke
parents:
diff changeset
294 char* v = args.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 char* name = args.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
297 if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 LinuxAttachOperation* op = new LinuxAttachOperation(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 for (int i=0; i<AttachOperation::arg_count_max; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 char* arg = args.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
305 if (arg == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 op->set_arg(i, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (strlen(arg) > AttachOperation::arg_length_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 delete op;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 op->set_arg(i, arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 op->set_socket(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 return op;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Dequeue an operation
a61af66fc99e Initial load
duke
parents:
diff changeset
322 //
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // In the Linux implementation there is only a single operation and clients
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // cannot queue commands (except at the socket level).
a61af66fc99e Initial load
duke
parents:
diff changeset
325 //
a61af66fc99e Initial load
duke
parents:
diff changeset
326 LinuxAttachOperation* LinuxAttachListener::dequeue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 int s;
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // wait for client to connect
a61af66fc99e Initial load
duke
parents:
diff changeset
331 struct sockaddr addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 socklen_t len = sizeof(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 RESTARTABLE(::accept(listener(), &addr, &len), s);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 if (s == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 return NULL; // log a warning?
a61af66fc99e Initial load
duke
parents:
diff changeset
336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // get the credentials of the peer and check the effective uid/guid
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // - check with jeff on this.
a61af66fc99e Initial load
duke
parents:
diff changeset
340 struct ucred cred_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 socklen_t optlen = sizeof(cred_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
342 if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 int res;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 RESTARTABLE(::close(s), res);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347 uid_t euid = geteuid();
a61af66fc99e Initial load
duke
parents:
diff changeset
348 gid_t egid = getegid();
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (cred_info.uid != euid || cred_info.gid != egid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 int res;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 RESTARTABLE(::close(s), res);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // peer credential look okay so we read the request
a61af66fc99e Initial load
duke
parents:
diff changeset
357 LinuxAttachOperation* op = read_request(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 if (op == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 int res;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 RESTARTABLE(::close(s), res);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return op;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // write the given buffer to the socket
a61af66fc99e Initial load
duke
parents:
diff changeset
369 int LinuxAttachListener::write_fully(int s, char* buf, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 int n = ::write(s, buf, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (n == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 if (errno != EINTR) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 buf += n;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 len -= n;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 while (len > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
380 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // Complete an operation by sending the operation result and any result
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // output to the client. At this time the socket is in blocking mode so
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // potentially we can block if there is a lot of data and the client is
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // non-responsive. For most operations this is a non-issue because the
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // default send buffer is sufficient to buffer everything. In the future
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // if there are operations that involves a very big reply then it the
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // socket could be made non-blocking and a timeout could be used.
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 void LinuxAttachOperation::complete(jint result, bufferedStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
393 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // write operation result
a61af66fc99e Initial load
duke
parents:
diff changeset
400 char msg[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
401 sprintf(msg, "%d\n", result);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 int rc = LinuxAttachListener::write_fully(this->socket(), msg, strlen(msg));
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // write any result data
a61af66fc99e Initial load
duke
parents:
diff changeset
405 if (rc == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 LinuxAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
407 ::shutdown(this->socket(), 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // done
a61af66fc99e Initial load
duke
parents:
diff changeset
411 RESTARTABLE(::close(this->socket()), rc);
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
414 thread->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 delete this;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // AttachListener functions
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 AttachOperation* AttachListener::dequeue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
424 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 AttachOperation* op = LinuxAttachListener::dequeue();
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
433 thread->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 return op;
a61af66fc99e Initial load
duke
parents:
diff changeset
436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 int AttachListener::pd_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 int ret_code = LinuxAttachListener::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
449 thread->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 return ret_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // Attach Listener is started lazily except in the case when
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // +ReduseSignalUsage is used
a61af66fc99e Initial load
duke
parents:
diff changeset
456 bool AttachListener::init_at_startup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // If the file .attach_pid<pid> exists in the working directory
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // or /tmp then this is the trigger to start the attach mechanism
a61af66fc99e Initial load
duke
parents:
diff changeset
466 bool AttachListener::is_init_trigger() {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 if (init_at_startup() || is_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 return false; // initialized at startup or already initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
1497
96d554193f72 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 1353
diff changeset
470 char fn[PATH_MAX+1];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
471 sprintf(fn, ".attach_pid%d", os::current_process_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
472 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 struct stat64 st;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 RESTARTABLE(::stat64(fn, &st), ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if (ret == -1) {
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 196
diff changeset
476 snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 196
diff changeset
477 os::get_temp_directory(), os::current_process_id());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
478 RESTARTABLE(::stat64(fn, &st), ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 if (ret == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // simple check to avoid starting the attach mechanism when
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // a bogus user creates the file
a61af66fc99e Initial load
duke
parents:
diff changeset
483 if (st.st_uid == geteuid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 init();
a61af66fc99e Initial load
duke
parents:
diff changeset
485 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // if VM aborts then remove listener
a61af66fc99e Initial load
duke
parents:
diff changeset
492 void AttachListener::abort() {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 listener_cleanup();
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 void AttachListener::pd_data_dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 os::signal_notify(SIGQUIT);
a61af66fc99e Initial load
duke
parents:
diff changeset
498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
499
a61af66fc99e Initial load
duke
parents:
diff changeset
500 AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 out->print_cr("flag '%s' cannot be changed", op->arg(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
506 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 void AttachListener::pd_detachall() {
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // do nothing for now
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }