< prev index next >

src/os/aix/vm/attachListener_aix.cpp

Print this page
rev 10248 : 8150232: AIX cleanup: Integrate changes of 7178026 and others
   1 /*
   2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2012, 2015 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.
  23  *


 208   }
 209   if (n >= (int)UNIX_PATH_MAX) {
 210     return -1;
 211   }
 212 
 213   // create the listener socket
 214   listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
 215   if (listener == -1) {
 216     return -1;
 217   }
 218 
 219   // bind socket
 220   struct sockaddr_un addr;
 221   memset((void *)&addr, 0, sizeof(addr));
 222   addr.sun_family = AF_UNIX;
 223   strcpy(addr.sun_path, initial_path);
 224   ::unlink(initial_path);
 225   // We must call bind with the actual socketaddr length. This is obligatory for AS400.
 226   int res = ::bind(listener, (struct sockaddr*)&addr, SUN_LEN(&addr));
 227   if (res == -1) {
 228     RESTARTABLE(::close(listener), res);
 229     return -1;
 230   }
 231 
 232   // put in listen mode, set permissions, and rename into place
 233   res = ::listen(listener, 5);
 234   if (res == 0) {
 235       RESTARTABLE(::chmod(initial_path, (S_IREAD|S_IWRITE) & ~(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)), res);
 236       if (res == 0) {
 237           res = ::rename(initial_path, path);
 238       }
 239   }
 240   if (res == -1) {
 241     RESTARTABLE(::close(listener), res);
 242     ::unlink(initial_path);
 243     return -1;
 244   }
 245   set_path(path);
 246   set_listener(listener);
 247   set_shutdown(false);
 248 
 249   return 0;
 250 }
 251 
 252 // Given a socket that is connected to a peer we read the request and
 253 // create an AttachOperation. As the socket is blocking there is potential
 254 // for a denial-of-service if the peer does not response. However this happens
 255 // after the peer credentials have been checked and in the worst case it just
 256 // means that the attach listener thread is blocked.
 257 //
 258 AixAttachOperation* AixAttachListener::read_request(int s) {
 259   char ver_str[8];
 260   sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
 261 


 383     struct peercred_struct cred_info;
 384     socklen_t optlen = sizeof(cred_info);
 385     if (::getsockopt(s, SOL_SOCKET, SO_PEERID, (void*)&cred_info, &optlen) == -1) {
 386       int res;
 387       RESTARTABLE(::close(s), res);
 388       continue;
 389     }
 390     uid_t euid = geteuid();
 391     gid_t egid = getegid();
 392 
 393     if (cred_info.euid != euid || cred_info.egid != egid) {
 394       int res;
 395       RESTARTABLE(::close(s), res);
 396       continue;
 397     }
 398 
 399     // peer credential look okay so we read the request
 400     AixAttachOperation* op = read_request(s);
 401     if (op == NULL) {
 402       int res;
 403       RESTARTABLE(::close(s), res);
 404       continue;
 405     } else {
 406       return op;
 407     }
 408   }
 409 }
 410 
 411 // write the given buffer to the socket
 412 int AixAttachListener::write_fully(int s, char* buf, int len) {
 413   do {
 414     int n = ::write(s, buf, len);
 415     if (n == -1) {
 416       if (errno != EINTR) return -1;
 417     } else {
 418       buf += n;
 419       len -= n;
 420     }
 421   }
 422   while (len > 0);
 423   return 0;


 435   JavaThread* thread = JavaThread::current();
 436   ThreadBlockInVM tbivm(thread);
 437 
 438   thread->set_suspend_equivalent();
 439   // cleared by handle_special_suspend_equivalent_condition() or
 440   // java_suspend_self() via check_and_wait_while_suspended()
 441 
 442   // write operation result
 443   char msg[32];
 444   sprintf(msg, "%d\n", result);
 445   int rc = AixAttachListener::write_fully(this->socket(), msg, strlen(msg));
 446 
 447   // write any result data
 448   if (rc == 0) {
 449     // Shutdown the socket in the cleanup function to enable more than
 450     // one agent attach in a sequence (see comments to listener_cleanup()).
 451     AixAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
 452   }
 453 
 454   // done
 455   RESTARTABLE(::close(this->socket()), rc);
 456 
 457   // were we externally suspended while we were waiting?
 458   thread->check_and_wait_while_suspended();
 459 
 460   delete this;
 461 }
 462 
 463 
 464 // AttachListener functions
 465 
 466 AttachOperation* AttachListener::dequeue() {
 467   JavaThread* thread = JavaThread::current();
 468   ThreadBlockInVM tbivm(thread);
 469 
 470   thread->set_suspend_equivalent();
 471   // cleared by handle_special_suspend_equivalent_condition() or
 472   // java_suspend_self() via check_and_wait_while_suspended()
 473 
 474   AttachOperation* op = AixAttachListener::dequeue();
 475 


   1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2012, 2016 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.
  23  *


 208   }
 209   if (n >= (int)UNIX_PATH_MAX) {
 210     return -1;
 211   }
 212 
 213   // create the listener socket
 214   listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
 215   if (listener == -1) {
 216     return -1;
 217   }
 218 
 219   // bind socket
 220   struct sockaddr_un addr;
 221   memset((void *)&addr, 0, sizeof(addr));
 222   addr.sun_family = AF_UNIX;
 223   strcpy(addr.sun_path, initial_path);
 224   ::unlink(initial_path);
 225   // We must call bind with the actual socketaddr length. This is obligatory for AS400.
 226   int res = ::bind(listener, (struct sockaddr*)&addr, SUN_LEN(&addr));
 227   if (res == -1) {
 228     ::close(listener);
 229     return -1;
 230   }
 231 
 232   // put in listen mode, set permissions, and rename into place
 233   res = ::listen(listener, 5);
 234   if (res == 0) {
 235       RESTARTABLE(::chmod(initial_path, (S_IREAD|S_IWRITE) & ~(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)), res);
 236       if (res == 0) {
 237           res = ::rename(initial_path, path);
 238       }
 239   }
 240   if (res == -1) {
 241     ::close(listener);
 242     ::unlink(initial_path);
 243     return -1;
 244   }
 245   set_path(path);
 246   set_listener(listener);
 247   set_shutdown(false);
 248 
 249   return 0;
 250 }
 251 
 252 // Given a socket that is connected to a peer we read the request and
 253 // create an AttachOperation. As the socket is blocking there is potential
 254 // for a denial-of-service if the peer does not response. However this happens
 255 // after the peer credentials have been checked and in the worst case it just
 256 // means that the attach listener thread is blocked.
 257 //
 258 AixAttachOperation* AixAttachListener::read_request(int s) {
 259   char ver_str[8];
 260   sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
 261 


 383     struct peercred_struct cred_info;
 384     socklen_t optlen = sizeof(cred_info);
 385     if (::getsockopt(s, SOL_SOCKET, SO_PEERID, (void*)&cred_info, &optlen) == -1) {
 386       int res;
 387       RESTARTABLE(::close(s), res);
 388       continue;
 389     }
 390     uid_t euid = geteuid();
 391     gid_t egid = getegid();
 392 
 393     if (cred_info.euid != euid || cred_info.egid != egid) {
 394       int res;
 395       RESTARTABLE(::close(s), res);
 396       continue;
 397     }
 398 
 399     // peer credential look okay so we read the request
 400     AixAttachOperation* op = read_request(s);
 401     if (op == NULL) {
 402       int res;
 403       ::close(s);
 404       continue;
 405     } else {
 406       return op;
 407     }
 408   }
 409 }
 410 
 411 // write the given buffer to the socket
 412 int AixAttachListener::write_fully(int s, char* buf, int len) {
 413   do {
 414     int n = ::write(s, buf, len);
 415     if (n == -1) {
 416       if (errno != EINTR) return -1;
 417     } else {
 418       buf += n;
 419       len -= n;
 420     }
 421   }
 422   while (len > 0);
 423   return 0;


 435   JavaThread* thread = JavaThread::current();
 436   ThreadBlockInVM tbivm(thread);
 437 
 438   thread->set_suspend_equivalent();
 439   // cleared by handle_special_suspend_equivalent_condition() or
 440   // java_suspend_self() via check_and_wait_while_suspended()
 441 
 442   // write operation result
 443   char msg[32];
 444   sprintf(msg, "%d\n", result);
 445   int rc = AixAttachListener::write_fully(this->socket(), msg, strlen(msg));
 446 
 447   // write any result data
 448   if (rc == 0) {
 449     // Shutdown the socket in the cleanup function to enable more than
 450     // one agent attach in a sequence (see comments to listener_cleanup()).
 451     AixAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
 452   }
 453 
 454   // done
 455   ::close(this->socket());
 456 
 457   // were we externally suspended while we were waiting?
 458   thread->check_and_wait_while_suspended();
 459 
 460   delete this;
 461 }
 462 
 463 
 464 // AttachListener functions
 465 
 466 AttachOperation* AttachListener::dequeue() {
 467   JavaThread* thread = JavaThread::current();
 468   ThreadBlockInVM tbivm(thread);
 469 
 470   thread->set_suspend_equivalent();
 471   // cleared by handle_special_suspend_equivalent_condition() or
 472   // java_suspend_self() via check_and_wait_while_suspended()
 473 
 474   AttachOperation* op = AixAttachListener::dequeue();
 475 


< prev index next >