# HG changeset patch # User apangin # Date 1279428563 25200 # Node ID 726692f4de19b88a323e65fcc56ae6a70ef71dd5 # Parent f172b22065d7bf4af50fe05e39317485a709e6b3# Parent 82aea418ab2de25d42a638f512b6ea0b423a406e Merge diff -r f172b22065d7 -r 726692f4de19 hotspot/src/os/linux/vm/attachListener_linux.cpp --- a/hotspot/src/os/linux/vm/attachListener_linux.cpp Thu Jul 15 13:48:01 2010 -0700 +++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp Sat Jul 17 21:49:23 2010 -0700 @@ -32,11 +32,15 @@ #include #include +#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 // 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 // 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 // connection. // @@ -54,7 +58,7 @@ class LinuxAttachListener: AllStatic { private: // 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; // the file descriptor for the listening socket @@ -64,8 +68,8 @@ if (path == NULL) { _has_path = false; } else { - strncpy(_path, path, PATH_MAX); - _path[PATH_MAX] = '\0'; + strncpy(_path, path, UNIX_PATH_MAX); + _path[UNIX_PATH_MAX-1] = '\0'; _has_path = true; } } @@ -113,7 +117,7 @@ }; // statics -char LinuxAttachListener::_path[PATH_MAX+1]; +char LinuxAttachListener::_path[UNIX_PATH_MAX]; bool LinuxAttachListener::_has_path; int LinuxAttachListener::_listener = -1; @@ -163,54 +167,53 @@ // Initialization - create a listener socket and bind it to a file int LinuxAttachListener::init() { - char path[PATH_MAX+1]; // socket file - int listener; // listener socket (file descriptor) + char path[UNIX_PATH_MAX]; // socket file + char initial_path[UNIX_PATH_MAX]; // socket file during setup + int listener; // listener socket (file descriptor) // register function to 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 listener = ::socket(PF_UNIX, SOCK_STREAM, 0); if (listener == -1) { return -1; } - int res = -1; + // bind socket struct sockaddr_un addr; addr.sun_family = AF_UNIX; - - // FIXME: Prior to b39 the tool-side API expected to find the well - // known file in the working directory. To allow this libjvm.so work with - // 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)); - } + strcpy(addr.sun_path, initial_path); + ::unlink(initial_path); + int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); if (res == -1) { RESTARTABLE(::close(listener), res); return -1; } - set_path(path); - // put in listen mode and set permission - if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) { + // put in listen mode, set permissions, and rename into place + 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); - ::unlink(path); - set_path(NULL); + ::unlink(initial_path); return -1; } + set_path(path); set_listener(listener); return 0; diff -r f172b22065d7 -r 726692f4de19 hotspot/src/os/solaris/vm/attachListener_solaris.cpp --- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Thu Jul 15 13:48:01 2010 -0700 +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Sat Jul 17 21:49:23 2010 -0700 @@ -364,6 +364,7 @@ // Create the door int SolarisAttachListener::create_door() { char door_path[PATH_MAX+1]; + char initial_path[PATH_MAX+1]; int fd, res; // register exit function @@ -375,36 +376,46 @@ return -1; } + // create initial file to attach door descriptor snprintf(door_path, sizeof(door_path), "%s/.java_pid%d", 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) { - 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; } assert(fd >= 0, "bad file descriptor"); - set_door_path(door_path); RESTARTABLE(::close(fd), res); // 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 (errno == EBUSY) { - ::fdetach(door_path); - res = ::fattach(dd, door_path); + ::fdetach(initial_path); + res = ::fattach(dd, initial_path); } if (res == -1) { ::door_revoke(dd); 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) { set_door_descriptor(dd); + set_door_path(door_path); } else { - // unable to create door or attach it to the file - ::unlink(door_path); - set_door_path(NULL); + // unable to create door, attach it to file, or rename file into place + ::unlink(initial_path); return -1; }