提交 2e768006 编写于 作者: A apangin

Merge

...@@ -32,11 +32,15 @@ ...@@ -32,11 +32,15 @@
#include <sys/un.h> #include <sys/un.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
#endif
// The attach mechanism on Linux uses a UNIX domain socket. An attach listener // The attach mechanism on Linux uses a UNIX domain socket. An attach listener
// thread is created at startup or is created on-demand via a signal from // thread is created at startup or is created on-demand via a signal from
// the client tool. The attach listener creates a socket and binds it to a file // the client tool. The attach listener creates a socket and binds it to a file
// in the filesystem. The attach listener then acts as a simple (single- // in the filesystem. The attach listener then acts as a simple (single-
// threaded) server - tt waits for a client to connect, reads the request, // threaded) server - it waits for a client to connect, reads the request,
// executes it, and returns the response to the client via the socket // executes it, and returns the response to the client via the socket
// connection. // connection.
// //
...@@ -54,7 +58,7 @@ class LinuxAttachOperation; ...@@ -54,7 +58,7 @@ class LinuxAttachOperation;
class LinuxAttachListener: AllStatic { class LinuxAttachListener: AllStatic {
private: private:
// the path to which we bind the UNIX domain socket // the path to which we bind the UNIX domain socket
static char _path[PATH_MAX+1]; static char _path[UNIX_PATH_MAX];
static bool _has_path; static bool _has_path;
// the file descriptor for the listening socket // the file descriptor for the listening socket
...@@ -64,8 +68,8 @@ class LinuxAttachListener: AllStatic { ...@@ -64,8 +68,8 @@ class LinuxAttachListener: AllStatic {
if (path == NULL) { if (path == NULL) {
_has_path = false; _has_path = false;
} else { } else {
strncpy(_path, path, PATH_MAX); strncpy(_path, path, UNIX_PATH_MAX);
_path[PATH_MAX] = '\0'; _path[UNIX_PATH_MAX-1] = '\0';
_has_path = true; _has_path = true;
} }
} }
...@@ -113,7 +117,7 @@ class LinuxAttachOperation: public AttachOperation { ...@@ -113,7 +117,7 @@ class LinuxAttachOperation: public AttachOperation {
}; };
// statics // statics
char LinuxAttachListener::_path[PATH_MAX+1]; char LinuxAttachListener::_path[UNIX_PATH_MAX];
bool LinuxAttachListener::_has_path; bool LinuxAttachListener::_has_path;
int LinuxAttachListener::_listener = -1; int LinuxAttachListener::_listener = -1;
...@@ -163,54 +167,53 @@ extern "C" { ...@@ -163,54 +167,53 @@ extern "C" {
// Initialization - create a listener socket and bind it to a file // Initialization - create a listener socket and bind it to a file
int LinuxAttachListener::init() { int LinuxAttachListener::init() {
char path[PATH_MAX+1]; // socket file char path[UNIX_PATH_MAX]; // socket file
int listener; // listener socket (file descriptor) char initial_path[UNIX_PATH_MAX]; // socket file during setup
int listener; // listener socket (file descriptor)
// register function to cleanup // register function to cleanup
::atexit(listener_cleanup); ::atexit(listener_cleanup);
int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id());
if (n <= (int)UNIX_PATH_MAX) {
n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
}
if (n > (int)UNIX_PATH_MAX) {
return -1;
}
// create the listener socket // create the listener socket
listener = ::socket(PF_UNIX, SOCK_STREAM, 0); listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
if (listener == -1) { if (listener == -1) {
return -1; return -1;
} }
int res = -1; // bind socket
struct sockaddr_un addr; struct sockaddr_un addr;
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, initial_path);
// FIXME: Prior to b39 the tool-side API expected to find the well ::unlink(initial_path);
// known file in the working directory. To allow this libjvm.so work with int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
// a pre-b39 SDK we create it in the working directory if
// +StartAttachListener is used is used. All unit tests for this feature
// currently used this flag. Once b39 SDK has been promoted we can remove
// this code.
if (StartAttachListener) {
sprintf(path, ".java_pid%d", os::current_process_id());
strcpy(addr.sun_path, path);
::unlink(path);
res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
}
if (res == -1) {
snprintf(path, PATH_MAX+1, "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id());
strcpy(addr.sun_path, path);
::unlink(path);
res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
}
if (res == -1) { if (res == -1) {
RESTARTABLE(::close(listener), res); RESTARTABLE(::close(listener), res);
return -1; return -1;
} }
set_path(path);
// put in listen mode and set permission // put in listen mode, set permissions, and rename into place
if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) { res = ::listen(listener, 5);
if (res == 0) {
RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
if (res == 0) {
res = ::rename(initial_path, path);
}
}
if (res == -1) {
RESTARTABLE(::close(listener), res); RESTARTABLE(::close(listener), res);
::unlink(path); ::unlink(initial_path);
set_path(NULL);
return -1; return -1;
} }
set_path(path);
set_listener(listener); set_listener(listener);
return 0; return 0;
......
...@@ -364,6 +364,7 @@ extern "C" { ...@@ -364,6 +364,7 @@ extern "C" {
// Create the door // Create the door
int SolarisAttachListener::create_door() { int SolarisAttachListener::create_door() {
char door_path[PATH_MAX+1]; char door_path[PATH_MAX+1];
char initial_path[PATH_MAX+1];
int fd, res; int fd, res;
// register exit function // register exit function
...@@ -375,36 +376,46 @@ int SolarisAttachListener::create_door() { ...@@ -375,36 +376,46 @@ int SolarisAttachListener::create_door() {
return -1; return -1;
} }
// create initial file to attach door descriptor
snprintf(door_path, sizeof(door_path), "%s/.java_pid%d", snprintf(door_path, sizeof(door_path), "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id()); os::get_temp_directory(), os::current_process_id());
RESTARTABLE(::creat(door_path, S_IRUSR | S_IWUSR), fd); snprintf(initial_path, sizeof(initial_path), "%s.tmp", door_path);
RESTARTABLE(::creat(initial_path, S_IRUSR | S_IWUSR), fd);
if (fd == -1) { if (fd == -1) {
debug_only(warning("attempt to create %s failed", door_path)); debug_only(warning("attempt to create %s failed", initial_path));
::door_revoke(dd);
return -1; return -1;
} }
assert(fd >= 0, "bad file descriptor"); assert(fd >= 0, "bad file descriptor");
set_door_path(door_path);
RESTARTABLE(::close(fd), res); RESTARTABLE(::close(fd), res);
// attach the door descriptor to the file // attach the door descriptor to the file
if ((res = ::fattach(dd, door_path)) == -1) { if ((res = ::fattach(dd, initial_path)) == -1) {
// if busy then detach and try again // if busy then detach and try again
if (errno == EBUSY) { if (errno == EBUSY) {
::fdetach(door_path); ::fdetach(initial_path);
res = ::fattach(dd, door_path); res = ::fattach(dd, initial_path);
} }
if (res == -1) { if (res == -1) {
::door_revoke(dd); ::door_revoke(dd);
dd = -1; dd = -1;
} }
} }
// rename file so that clients can attach
if (dd >= 0) {
if (::rename(initial_path, door_path) == -1) {
RESTARTABLE(::close(dd), res);
::fdetach(initial_path);
dd = -1;
}
}
if (dd >= 0) { if (dd >= 0) {
set_door_descriptor(dd); set_door_descriptor(dd);
set_door_path(door_path);
} else { } else {
// unable to create door or attach it to the file // unable to create door, attach it to file, or rename file into place
::unlink(door_path); ::unlink(initial_path);
set_door_path(NULL);
return -1; return -1;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册