src/os/bsd/vm/attachListener_bsd.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
7089790_bsd_vs_linux Cdiff src/os/bsd/vm/attachListener_bsd.cpp
src/os/bsd/vm/attachListener_bsd.cpp
Print this page
rev 2698 : new bsd files
*** 37,47 ****
#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 - it waits for a client to connect, reads the request,
// executes it, and returns the response to the client via the socket
--- 37,47 ----
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
#endif
! // The attach mechanism on Bsd 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 - it waits for a client to connect, reads the request,
// executes it, and returns the response to the client via the socket
*** 54,66 ****
// 2. When a client connect, the SO_PEERCRED socket option is used to
// obtain the credentials of client. We check that the effective uid
// of the client matches this process.
// forward reference
! class LinuxAttachOperation;
! class LinuxAttachListener: AllStatic {
private:
// the path to which we bind the UNIX domain socket
static char _path[UNIX_PATH_MAX];
static bool _has_path;
--- 54,66 ----
// 2. When a client connect, the SO_PEERCRED socket option is used to
// obtain the credentials of client. We check that the effective uid
// of the client matches this process.
// forward reference
! class BsdAttachOperation;
! class BsdAttachListener: AllStatic {
private:
// the path to which we bind the UNIX domain socket
static char _path[UNIX_PATH_MAX];
static bool _has_path;
*** 78,88 ****
}
static void set_listener(int s) { _listener = s; }
// reads a request from the given connected socket
! static LinuxAttachOperation* read_request(int s);
public:
enum {
ATTACH_PROTOCOL_VER = 1 // protocol version
};
--- 78,88 ----
}
static void set_listener(int s) { _listener = s; }
// reads a request from the given connected socket
! static BsdAttachOperation* read_request(int s);
public:
enum {
ATTACH_PROTOCOL_VER = 1 // protocol version
};
*** 98,111 ****
static int listener() { return _listener; }
// write the given buffer to a socket
static int write_fully(int s, char* buf, int len);
! static LinuxAttachOperation* dequeue();
};
! class LinuxAttachOperation: public AttachOperation {
private:
// the connection to the client
int _socket;
public:
--- 98,111 ----
static int listener() { return _listener; }
// write the given buffer to a socket
static int write_fully(int s, char* buf, int len);
! static BsdAttachOperation* dequeue();
};
! class BsdAttachOperation: public AttachOperation {
private:
// the connection to the client
int _socket;
public:
*** 112,130 ****
void complete(jint res, bufferedStream* st);
void set_socket(int s) { _socket = s; }
int socket() const { return _socket; }
! LinuxAttachOperation(char* name) : AttachOperation(name) {
set_socket(-1);
}
};
// statics
! char LinuxAttachListener::_path[UNIX_PATH_MAX];
! bool LinuxAttachListener::_has_path;
! int LinuxAttachListener::_listener = -1;
// Supporting class to help split a buffer into individual components
class ArgumentIterator : public StackObj {
private:
char* _pos;
--- 112,130 ----
void complete(jint res, bufferedStream* st);
void set_socket(int s) { _socket = s; }
int socket() const { return _socket; }
! BsdAttachOperation(char* name) : AttachOperation(name) {
set_socket(-1);
}
};
// statics
! char BsdAttachListener::_path[UNIX_PATH_MAX];
! bool BsdAttachListener::_has_path;
! int BsdAttachListener::_listener = -1;
// Supporting class to help split a buffer into individual components
class ArgumentIterator : public StackObj {
private:
char* _pos;
*** 154,177 ****
extern "C" {
static void listener_cleanup() {
static int cleanup_done;
if (!cleanup_done) {
cleanup_done = 1;
! int s = LinuxAttachListener::listener();
if (s != -1) {
::close(s);
}
! if (LinuxAttachListener::has_path()) {
! ::unlink(LinuxAttachListener::path());
}
}
}
}
// Initialization - create a listener socket and bind it to a file
! int LinuxAttachListener::init() {
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
--- 154,177 ----
extern "C" {
static void listener_cleanup() {
static int cleanup_done;
if (!cleanup_done) {
cleanup_done = 1;
! int s = BsdAttachListener::listener();
if (s != -1) {
::close(s);
}
! if (BsdAttachListener::has_path()) {
! ::unlink(BsdAttachListener::path());
}
}
}
}
// Initialization - create a listener socket and bind it to a file
! int BsdAttachListener::init() {
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
*** 226,236 ****
// create an AttachOperation. As the socket is blocking there is potential
// for a denial-of-service if the peer does not response. However this happens
// after the peer credentials have been checked and in the worst case it just
// means that the attach listener thread is blocked.
//
! LinuxAttachOperation* LinuxAttachListener::read_request(int s) {
char ver_str[8];
sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
// The request is a sequence of strings so we first figure out the
// expected count and the maximum possible length of the request.
--- 226,236 ----
// create an AttachOperation. As the socket is blocking there is potential
// for a denial-of-service if the peer does not response. However this happens
// after the peer credentials have been checked and in the worst case it just
// means that the attach listener thread is blocked.
//
! BsdAttachOperation* BsdAttachListener::read_request(int s) {
char ver_str[8];
sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
// The request is a sequence of strings so we first figure out the
// expected count and the maximum possible length of the request.
*** 296,306 ****
char* name = args.next();
if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
return NULL;
}
! LinuxAttachOperation* op = new LinuxAttachOperation(name);
for (int i=0; i<AttachOperation::arg_count_max; i++) {
char* arg = args.next();
if (arg == NULL) {
op->set_arg(i, NULL);
--- 296,306 ----
char* name = args.next();
if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
return NULL;
}
! BsdAttachOperation* op = new BsdAttachOperation(name);
for (int i=0; i<AttachOperation::arg_count_max; i++) {
char* arg = args.next();
if (arg == NULL) {
op->set_arg(i, NULL);
*** 318,331 ****
}
// Dequeue an operation
//
! // In the Linux implementation there is only a single operation and clients
// cannot queue commands (except at the socket level).
//
! LinuxAttachOperation* LinuxAttachListener::dequeue() {
for (;;) {
int s;
// wait for client to connect
struct sockaddr addr;
--- 318,331 ----
}
// Dequeue an operation
//
! // In the Bsd implementation there is only a single operation and clients
// cannot queue commands (except at the socket level).
//
! BsdAttachOperation* BsdAttachListener::dequeue() {
for (;;) {
int s;
// wait for client to connect
struct sockaddr addr;
*** 335,362 ****
return NULL; // log a warning?
}
// get the credentials of the peer and check the effective uid/guid
// - check with jeff on this.
struct ucred cred_info;
socklen_t optlen = sizeof(cred_info);
if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
int res;
RESTARTABLE(::close(s), res);
continue;
}
uid_t euid = geteuid();
gid_t egid = getegid();
! if (cred_info.uid != euid || cred_info.gid != egid) {
int res;
RESTARTABLE(::close(s), res);
continue;
}
// peer credential look okay so we read the request
! LinuxAttachOperation* op = read_request(s);
if (op == NULL) {
int res;
RESTARTABLE(::close(s), res);
continue;
} else {
--- 335,374 ----
return NULL; // log a warning?
}
// get the credentials of the peer and check the effective uid/guid
// - check with jeff on this.
+ #ifdef _ALLBSD_SOURCE
+ uid_t puid;
+ gid_t pgid;
+ if (::getpeereid(s, &puid, &pgid) != 0) {
+ int res;
+ RESTARTABLE(::close(s), res);
+ continue;
+ }
+ #else
struct ucred cred_info;
socklen_t optlen = sizeof(cred_info);
if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
int res;
RESTARTABLE(::close(s), res);
continue;
}
+ uid_t puid = cred_info.uid;
+ gid_t pgid = cred_info.gid;
+ #endif
uid_t euid = geteuid();
gid_t egid = getegid();
! if (puid != euid || pgid != egid) {
int res;
RESTARTABLE(::close(s), res);
continue;
}
// peer credential look okay so we read the request
! BsdAttachOperation* op = read_request(s);
if (op == NULL) {
int res;
RESTARTABLE(::close(s), res);
continue;
} else {
*** 364,374 ****
}
}
}
// write the given buffer to the socket
! int LinuxAttachListener::write_fully(int s, char* buf, int len) {
do {
int n = ::write(s, buf, len);
if (n == -1) {
if (errno != EINTR) return -1;
} else {
--- 376,386 ----
}
}
}
// write the given buffer to the socket
! int BsdAttachListener::write_fully(int s, char* buf, int len) {
do {
int n = ::write(s, buf, len);
if (n == -1) {
if (errno != EINTR) return -1;
} else {
*** 386,396 ****
// non-responsive. For most operations this is a non-issue because the
// default send buffer is sufficient to buffer everything. In the future
// if there are operations that involves a very big reply then it the
// socket could be made non-blocking and a timeout could be used.
! void LinuxAttachOperation::complete(jint result, bufferedStream* st) {
JavaThread* thread = JavaThread::current();
ThreadBlockInVM tbivm(thread);
thread->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or
--- 398,408 ----
// non-responsive. For most operations this is a non-issue because the
// default send buffer is sufficient to buffer everything. In the future
// if there are operations that involves a very big reply then it the
// socket could be made non-blocking and a timeout could be used.
! void BsdAttachOperation::complete(jint result, bufferedStream* st) {
JavaThread* thread = JavaThread::current();
ThreadBlockInVM tbivm(thread);
thread->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or
*** 397,411 ****
// java_suspend_self() via check_and_wait_while_suspended()
// write operation result
char msg[32];
sprintf(msg, "%d\n", result);
! int rc = LinuxAttachListener::write_fully(this->socket(), msg, strlen(msg));
// write any result data
if (rc == 0) {
! LinuxAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
::shutdown(this->socket(), 2);
}
// done
RESTARTABLE(::close(this->socket()), rc);
--- 409,423 ----
// java_suspend_self() via check_and_wait_while_suspended()
// write operation result
char msg[32];
sprintf(msg, "%d\n", result);
! int rc = BsdAttachListener::write_fully(this->socket(), msg, strlen(msg));
// write any result data
if (rc == 0) {
! BsdAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
::shutdown(this->socket(), 2);
}
// done
RESTARTABLE(::close(this->socket()), rc);
*** 425,435 ****
thread->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or
// java_suspend_self() via check_and_wait_while_suspended()
! AttachOperation* op = LinuxAttachListener::dequeue();
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
return op;
--- 437,447 ----
thread->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or
// java_suspend_self() via check_and_wait_while_suspended()
! AttachOperation* op = BsdAttachListener::dequeue();
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
return op;
*** 441,451 ****
thread->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or
// java_suspend_self() via check_and_wait_while_suspended()
! int ret_code = LinuxAttachListener::init();
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
return ret_code;
--- 453,463 ----
thread->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or
// java_suspend_self() via check_and_wait_while_suspended()
! int ret_code = BsdAttachListener::init();
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
return ret_code;
*** 465,484 ****
// or /tmp then this is the trigger to start the attach mechanism
bool AttachListener::is_init_trigger() {
if (init_at_startup() || is_initialized()) {
return false; // initialized at startup or already initialized
}
! char fn[PATH_MAX+1];
! sprintf(fn, ".attach_pid%d", os::current_process_id());
int ret;
! struct stat64 st;
! RESTARTABLE(::stat64(fn, &st), ret);
! if (ret == -1) {
! snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
os::get_temp_directory(), os::current_process_id());
! RESTARTABLE(::stat64(fn, &st), ret);
! }
if (ret == 0) {
// simple check to avoid starting the attach mechanism when
// a bogus user creates the file
if (st.st_uid == geteuid()) {
init();
--- 477,493 ----
// or /tmp then this is the trigger to start the attach mechanism
bool AttachListener::is_init_trigger() {
if (init_at_startup() || is_initialized()) {
return false; // initialized at startup or already initialized
}
! char path[PATH_MAX + 1];
int ret;
! struct stat st;
!
! snprintf(path, PATH_MAX + 1, "%s/.attach_pid%d",
os::get_temp_directory(), os::current_process_id());
! RESTARTABLE(::stat(path, &st), ret);
if (ret == 0) {
// simple check to avoid starting the attach mechanism when
// a bogus user creates the file
if (st.st_uid == geteuid()) {
init();
src/os/bsd/vm/attachListener_bsd.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File