1 /*
2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
54 // the security:
55 // 1. The well known file that the socket is bound to has permission 400
56 // 2. When a client connect, the SO_PEERID socket option is used to
57 // obtain the credentials of client. We check that the effective uid
58 // of the client matches this process.
59
60 // forward reference
61 class AixAttachOperation;
62
63 class AixAttachListener: AllStatic {
64 private:
65 // the path to which we bind the UNIX domain socket
66 static char _path[UNIX_PATH_MAX];
67 static bool _has_path;
68 // Shutdown marker to prevent accept blocking during clean-up.
69 static bool _shutdown;
70
71 // the file descriptor for the listening socket
72 static int _listener;
73
74 static void set_path(char* path) {
75 if (path == NULL) {
76 _has_path = false;
77 } else {
78 strncpy(_path, path, UNIX_PATH_MAX);
79 _path[UNIX_PATH_MAX-1] = '\0';
80 _has_path = true;
81 }
82 }
83
84 static void set_listener(int s) { _listener = s; }
85
86 // reads a request from the given connected socket
87 static AixAttachOperation* read_request(int s);
88
89 public:
90 enum {
91 ATTACH_PROTOCOL_VER = 1 // protocol version
92 };
93 enum {
94 ATTACH_ERROR_BADVERSION = 101 // error codes
95 };
96
97 // initialize the listener, returns 0 if okay
98 static int init();
99
100 static char* path() { return _path; }
101 static bool has_path() { return _has_path; }
102 static int listener() { return _listener; }
103 // Shutdown marker to prevent accept blocking during clean-up
104 static void set_shutdown(bool shutdown) { _shutdown = shutdown; }
105 static bool is_shutdown() { return _shutdown; }
106
107 // write the given buffer to a socket
108 static int write_fully(int s, char* buf, int len);
109
110 static AixAttachOperation* dequeue();
111 };
112
113 class AixAttachOperation: public AttachOperation {
114 private:
115 // the connection to the client
116 int _socket;
117
118 public:
119 void complete(jint res, bufferedStream* st);
120
121 void set_socket(int s) { _socket = s; }
122 int socket() const { return _socket; }
123
124 AixAttachOperation(char* name) : AttachOperation(name) {
125 set_socket(-1);
126 }
127 };
128
129 // statics
130 char AixAttachListener::_path[UNIX_PATH_MAX];
131 bool AixAttachListener::_has_path;
132 int AixAttachListener::_listener = -1;
133 // Shutdown marker to prevent accept blocking during clean-up
134 bool AixAttachListener::_shutdown = false;
135
136 // Supporting class to help split a buffer into individual components
137 class ArgumentIterator : public StackObj {
138 private:
139 char* _pos;
140 char* _end;
141 public:
142 ArgumentIterator(char* arg_buffer, size_t arg_size) {
143 _pos = arg_buffer;
144 _end = _pos + arg_size - 1;
145 }
146 char* next() {
147 if (*_pos == '\0') {
148 // advance the iterator if possible (null arguments)
149 if (_pos < _end) {
150 _pos += 1;
151 }
152 return NULL;
160 return res;
161 }
162 };
163
164 // On AIX if sockets block until all data has been transmitted
165 // successfully in some communication domains a socket "close" may
166 // never complete. We have to take care that after the socket shutdown
167 // the listener never enters accept state.
168
169 // atexit hook to stop listener and unlink the file that it is
170 // bound too.
171
172 // Some modifications to the listener logic to prevent deadlocks on exit.
173 // 1. We Shutdown the socket here instead. AixAttachOperation::complete() is not the right place
174 // since more than one agent in a sequence in JPLIS live tests wouldn't work (Listener thread
175 // would be dead after the first operation completion).
176 // 2. close(s) may never return if the listener thread is in socket accept(). Unlinking the file
177 // should be sufficient for cleanup.
178 extern "C" {
179 static void listener_cleanup() {
180 static int cleanup_done;
181 if (!cleanup_done) {
182 cleanup_done = 1;
183 AixAttachListener::set_shutdown(true);
184 int s = AixAttachListener::listener();
185 if (s != -1) {
186 ::shutdown(s, 2);
187 }
188 if (AixAttachListener::has_path()) {
189 ::unlink(AixAttachListener::path());
190 }
191 }
192 }
193 }
194
195 // Initialization - create a listener socket and bind it to a file
196
197 int AixAttachListener::init() {
198 char path[UNIX_PATH_MAX]; // socket file
199 char initial_path[UNIX_PATH_MAX]; // socket file during setup
200 int listener; // listener socket (file descriptor)
201
202 // register function to cleanup
203 ::atexit(listener_cleanup);
204
205 int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
206 os::get_temp_directory(), os::current_process_id());
207 if (n < (int)UNIX_PATH_MAX) {
208 n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
209 }
210 if (n >= (int)UNIX_PATH_MAX) {
211 return -1;
212 }
213
214 // create the listener socket
215 listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
216 if (listener == -1) {
217 return -1;
218 }
219
220 // bind socket
221 struct sockaddr_un addr;
222 memset((void *)&addr, 0, sizeof(addr));
223 addr.sun_family = AF_UNIX;
496 if (ret == -1) {
497 log_debug(attach)("Failed to remove stale attach pid file at %s", fn);
498 }
499 }
500 }
501
502 int AttachListener::pd_init() {
503 JavaThread* thread = JavaThread::current();
504 ThreadBlockInVM tbivm(thread);
505
506 thread->set_suspend_equivalent();
507 // cleared by handle_special_suspend_equivalent_condition() or
508 // java_suspend_self() via check_and_wait_while_suspended()
509
510 int ret_code = AixAttachListener::init();
511
512 // were we externally suspended while we were waiting?
513 thread->check_and_wait_while_suspended();
514
515 return ret_code;
516 }
517
518 // Attach Listener is started lazily except in the case when
519 // +ReduseSignalUsage is used
520 bool AttachListener::init_at_startup() {
521 if (ReduceSignalUsage) {
522 return true;
523 } else {
524 return false;
525 }
526 }
527
528 // If the file .attach_pid<pid> exists in the working directory
529 // or /tmp then this is the trigger to start the attach mechanism
530 bool AttachListener::is_init_trigger() {
531 if (init_at_startup() || is_initialized()) {
532 return false; // initialized at startup or already initialized
533 }
534 char fn[PATH_MAX + 1];
535 int ret;
|
1 /*
2 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
54 // the security:
55 // 1. The well known file that the socket is bound to has permission 400
56 // 2. When a client connect, the SO_PEERID socket option is used to
57 // obtain the credentials of client. We check that the effective uid
58 // of the client matches this process.
59
60 // forward reference
61 class AixAttachOperation;
62
63 class AixAttachListener: AllStatic {
64 private:
65 // the path to which we bind the UNIX domain socket
66 static char _path[UNIX_PATH_MAX];
67 static bool _has_path;
68 // Shutdown marker to prevent accept blocking during clean-up.
69 static bool _shutdown;
70
71 // the file descriptor for the listening socket
72 static int _listener;
73
74 static bool _atexit_registered;
75
76 // reads a request from the given connected socket
77 static AixAttachOperation* read_request(int s);
78
79 public:
80 enum {
81 ATTACH_PROTOCOL_VER = 1 // protocol version
82 };
83 enum {
84 ATTACH_ERROR_BADVERSION = 101 // error codes
85 };
86
87 static void set_path(char* path) {
88 if (path == NULL) {
89 _path[0] = '\0';
90 _has_path = false;
91 } else {
92 strncpy(_path, path, UNIX_PATH_MAX);
93 _path[UNIX_PATH_MAX-1] = '\0';
94 _has_path = true;
95 }
96 }
97
98 static void set_listener(int s) { _listener = s; }
99
100 // initialize the listener, returns 0 if okay
101 static int init();
102
103 static char* path() { return _path; }
104 static bool has_path() { return _has_path; }
105 static int listener() { return _listener; }
106 // Shutdown marker to prevent accept blocking during clean-up
107 static void set_shutdown(bool shutdown) { _shutdown = shutdown; }
108 static bool is_shutdown() { return _shutdown; }
109
110 // write the given buffer to a socket
111 static int write_fully(int s, char* buf, int len);
112
113 static AixAttachOperation* dequeue();
114 };
115
116 class AixAttachOperation: public AttachOperation {
117 private:
118 // the connection to the client
119 int _socket;
120
121 public:
122 void complete(jint res, bufferedStream* st);
123
124 void set_socket(int s) { _socket = s; }
125 int socket() const { return _socket; }
126
127 AixAttachOperation(char* name) : AttachOperation(name) {
128 set_socket(-1);
129 }
130 };
131
132 // statics
133 char AixAttachListener::_path[UNIX_PATH_MAX];
134 bool AixAttachListener::_has_path;
135 int AixAttachListener::_listener = -1;
136 bool AixAttachListener::_atexit_registered = false;
137 // Shutdown marker to prevent accept blocking during clean-up
138 bool AixAttachListener::_shutdown = false;
139
140 // Supporting class to help split a buffer into individual components
141 class ArgumentIterator : public StackObj {
142 private:
143 char* _pos;
144 char* _end;
145 public:
146 ArgumentIterator(char* arg_buffer, size_t arg_size) {
147 _pos = arg_buffer;
148 _end = _pos + arg_size - 1;
149 }
150 char* next() {
151 if (*_pos == '\0') {
152 // advance the iterator if possible (null arguments)
153 if (_pos < _end) {
154 _pos += 1;
155 }
156 return NULL;
164 return res;
165 }
166 };
167
168 // On AIX if sockets block until all data has been transmitted
169 // successfully in some communication domains a socket "close" may
170 // never complete. We have to take care that after the socket shutdown
171 // the listener never enters accept state.
172
173 // atexit hook to stop listener and unlink the file that it is
174 // bound too.
175
176 // Some modifications to the listener logic to prevent deadlocks on exit.
177 // 1. We Shutdown the socket here instead. AixAttachOperation::complete() is not the right place
178 // since more than one agent in a sequence in JPLIS live tests wouldn't work (Listener thread
179 // would be dead after the first operation completion).
180 // 2. close(s) may never return if the listener thread is in socket accept(). Unlinking the file
181 // should be sufficient for cleanup.
182 extern "C" {
183 static void listener_cleanup() {
184 AixAttachListener::set_shutdown(true);
185 int s = AixAttachListener::listener();
186 if (s != -1) {
187 AixAttachListener::set_listener(-1);
188 ::shutdown(s, 2);
189 }
190 if (AixAttachListener::has_path()) {
191 ::unlink(AixAttachListener::path());
192 AixAttachListener::set_path(NULL);
193 }
194 }
195 }
196
197 // Initialization - create a listener socket and bind it to a file
198
199 int AixAttachListener::init() {
200 char path[UNIX_PATH_MAX]; // socket file
201 char initial_path[UNIX_PATH_MAX]; // socket file during setup
202 int listener; // listener socket (file descriptor)
203
204 // register function to cleanup
205 if (!_atexit_registered) {
206 _atexit_registered = true;
207 ::atexit(listener_cleanup);
208 }
209
210 int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
211 os::get_temp_directory(), os::current_process_id());
212 if (n < (int)UNIX_PATH_MAX) {
213 n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
214 }
215 if (n >= (int)UNIX_PATH_MAX) {
216 return -1;
217 }
218
219 // create the listener socket
220 listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
221 if (listener == -1) {
222 return -1;
223 }
224
225 // bind socket
226 struct sockaddr_un addr;
227 memset((void *)&addr, 0, sizeof(addr));
228 addr.sun_family = AF_UNIX;
501 if (ret == -1) {
502 log_debug(attach)("Failed to remove stale attach pid file at %s", fn);
503 }
504 }
505 }
506
507 int AttachListener::pd_init() {
508 JavaThread* thread = JavaThread::current();
509 ThreadBlockInVM tbivm(thread);
510
511 thread->set_suspend_equivalent();
512 // cleared by handle_special_suspend_equivalent_condition() or
513 // java_suspend_self() via check_and_wait_while_suspended()
514
515 int ret_code = AixAttachListener::init();
516
517 // were we externally suspended while we were waiting?
518 thread->check_and_wait_while_suspended();
519
520 return ret_code;
521 }
522
523 bool AttachListener::check_socket_file() {
524 int ret;
525 struct stat64 st;
526 ret = stat64(AixAttachListener::path(), &st);
527 if (ret == -1) { // need to restart attach listener.
528 log_debug(attach)("Socket file %s does not exist - Restart Attach Listener",
529 AixAttachListener::path());
530
531 listener_cleanup();
532
533 // wait to terminate current attach listener instance...
534 while (AttachListener::transit_state(AL_INITIALIZING,
535 AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
536 os::naked_yield();
537 }
538 is_init_trigger();
539 return true;
540 }
541 return false;
542 }
543
544 // Attach Listener is started lazily except in the case when
545 // +ReduseSignalUsage is used
546 bool AttachListener::init_at_startup() {
547 if (ReduceSignalUsage) {
548 return true;
549 } else {
550 return false;
551 }
552 }
553
554 // If the file .attach_pid<pid> exists in the working directory
555 // or /tmp then this is the trigger to start the attach mechanism
556 bool AttachListener::is_init_trigger() {
557 if (init_at_startup() || is_initialized()) {
558 return false; // initialized at startup or already initialized
559 }
560 char fn[PATH_MAX + 1];
561 int ret;
|