Skip to content

Commit c58a066

Browse files
committed
8286030: Avoid JVM crash when containers share the same /tmp dir
Reviewed-by: phh Backport-of: d52e18c92d307f5f6e9e649d410a54bef3a910da
1 parent 43a0015 commit c58a066

File tree

5 files changed

+387
-163
lines changed

5 files changed

+387
-163
lines changed

src/hotspot/os/aix/perfMemory_aix.cpp

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,6 @@ static char* create_standard_memory(size_t size) {
7474
return mapAddress;
7575
}
7676

77-
// delete the PerfData memory region
78-
//
79-
static void delete_standard_memory(char* addr, size_t size) {
80-
81-
// there are no persistent external resources to cleanup for standard
82-
// memory. since DestroyJavaVM does not support unloading of the JVM,
83-
// cleanup of the memory resource is not performed. The memory will be
84-
// reclaimed by the OS upon termination of the process.
85-
//
86-
return;
87-
}
88-
8977
// save the specified memory region to the given file
9078
//
9179
// Note: this function might be called from signal handler (by os::abort()),
@@ -749,15 +737,15 @@ static void remove_file(const char* path) {
749737
}
750738
}
751739

752-
// Cleanup stale shared memory resources
740+
// Cleanup stale shared memory files
753741
//
754742
// This method attempts to remove all stale shared memory files in
755743
// the named user temporary directory. It scans the named directory
756-
// for files matching the pattern ^$[0-9]*$. For each file found, the
757-
// process id is extracted from the file name and a test is run to
758-
// determine if the process is alive. If the process is not alive,
759-
// any stale file resources are removed.
760-
static void cleanup_sharedmem_resources(const char* dirname) {
744+
// for files matching the pattern ^$[0-9]*$.
745+
//
746+
// This directory should be used only by JVM processes owned by the
747+
// current user to store PerfMemory files. Any other files found
748+
static void cleanup_sharedmem_files(const char* dirname) {
761749

762750
int saved_cwd_fd;
763751
// Open the directory.
@@ -768,47 +756,54 @@ static void cleanup_sharedmem_resources(const char* dirname) {
768756
}
769757

770758
// For each entry in the directory that matches the expected file
771-
// name pattern, determine if the file resources are stale and if
772-
// so, remove the file resources. Note, instrumented HotSpot processes
773-
// for this user may start and/or terminate during this search and
774-
// remove or create new files in this directory. The behavior of this
775-
// loop under these conditions is dependent upon the implementation of
776-
// opendir/readdir.
759+
// name pattern, remove the file if it's determine to be stale
760+
// Note, instrumented HotSpot processes for this user may start and/or
761+
// terminate during this search and remove or create new files in this
762+
// directory. The behavior of this loop under these conditions is dependent
763+
// upon the implementation of opendir/readdir.
777764
struct dirent* entry;
778765
errno = 0;
779766
while ((entry = os::readdir(dirp)) != NULL) {
780767

781-
pid_t pid = filename_to_pid(entry->d_name);
768+
const char* filename = entry->d_name;
769+
pid_t pid = filename_to_pid(filename);
782770

783771
if (pid == 0) {
784772

785-
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
773+
if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) {
786774

787775
// Attempt to remove all unexpected files, except "." and "..".
788-
unlink(entry->d_name);
776+
unlink(filename);
789777
}
790778

791779
errno = 0;
792780
continue;
793781
}
794782

795-
// We now have a file name that converts to a valid integer
796-
// that could represent a process id . if this process id
797-
// matches the current process id or the process is not running,
798-
// then remove the stale file resources.
799-
//
800-
// Process liveness is detected by sending signal number 0 to
801-
// the process id (see kill(2)). if kill determines that the
802-
// process does not exist, then the file resources are removed.
803-
// if kill determines that that we don't have permission to
804-
// signal the process, then the file resources are assumed to
805-
// be stale and are removed because the resources for such a
806-
// process should be in a different user specific directory.
807-
if ((pid == os::current_process_id()) ||
808-
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
809-
810-
unlink(entry->d_name);
783+
// The following code assumes that pid must be in the same
784+
// namespace as the current process.
785+
bool stale = false;
786+
787+
if (pid == os::current_process_id()) {
788+
// The file was created by a terminated process that happened
789+
// to have the same pid as the current process.
790+
stale = true;
791+
} else if (kill(pid, 0) == OS_ERR) {
792+
if (errno == ESRCH) {
793+
// The target process does not exist.
794+
stale = true;
795+
} else if (errno == EPERM) {
796+
// The file was created by a terminated process that happened
797+
// to have the same pid as a process not owned by the current user.
798+
stale = true;
799+
}
800+
}
801+
802+
if (stale) {
803+
log_info(perf, memops)("Remove stale file %s/%s", dirname, filename);
804+
unlink(filename);
811805
}
806+
812807
errno = 0;
813808
}
814809

@@ -851,13 +846,13 @@ static bool make_user_tmp_dir(const char* dirname) {
851846
return true;
852847
}
853848

854-
// create the shared memory file resources
849+
// create the shared memory file
855850
//
856851
// This method creates the shared memory file with the given size
857852
// This method also creates the user specific temporary directory, if
858853
// it does not yet exist.
859854
//
860-
static int create_sharedmem_resources(const char* dirname, const char* filename, size_t size) {
855+
static int create_sharedmem_file(const char* dirname, const char* filename, size_t size) {
861856

862857
// make the user temporary directory
863858
if (!make_user_tmp_dir(dirname)) {
@@ -1013,12 +1008,13 @@ static char* mmap_create_shared(size_t size) {
10131008
}
10141009

10151010
// cleanup any stale shared memory files
1016-
cleanup_sharedmem_resources(dirname);
1011+
cleanup_sharedmem_files(dirname);
10171012

10181013
assert(((size > 0) && (size % os::vm_page_size() == 0)),
10191014
"unexpected PerfMemory region size");
10201015

1021-
fd = create_sharedmem_resources(dirname, short_filename, size);
1016+
log_info(perf, memops)("Trying to open %s/%s", dirname, short_filename);
1017+
fd = create_sharedmem_file(dirname, short_filename, size);
10221018

10231019
FREE_C_HEAP_ARRAY(char, user_name);
10241020
FREE_C_HEAP_ARRAY(char, dirname);
@@ -1051,6 +1047,8 @@ static char* mmap_create_shared(size_t size) {
10511047
// It does not go through os api, the operation has to record from here.
10521048
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
10531049

1050+
log_info(perf, memops)("Successfully opened");
1051+
10541052
return mapAddress;
10551053
}
10561054

@@ -1076,10 +1074,10 @@ static char* create_shared_memory(size_t size) {
10761074
//
10771075
static void delete_shared_memory(char* addr, size_t size) {
10781076

1079-
// cleanup the persistent shared memory resources. since DestroyJavaVM does
1080-
// not support unloading of the JVM, unmapping of the memory resource is
1077+
// Remove the shared memory file. Since DestroyJavaVM does
1078+
// not support unloading of the JVM, unmapping of the memory region is
10811079
// not performed. The memory will be reclaimed by the OS upon termination of
1082-
// the process. The backing store file is deleted from the file system.
1080+
// the process.
10831081

10841082
assert(!PerfDisableSharedMem, "shouldn't be here");
10851083

@@ -1290,10 +1288,7 @@ void PerfMemory::delete_memory_region() {
12901288
save_memory_to_file(start(), capacity());
12911289
}
12921290

1293-
if (PerfDisableSharedMem) {
1294-
delete_standard_memory(start(), capacity());
1295-
}
1296-
else {
1291+
if (!PerfDisableSharedMem) {
12971292
delete_shared_memory(start(), capacity());
12981293
}
12991294
}

src/hotspot/os/bsd/perfMemory_bsd.cpp

Lines changed: 50 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,6 @@ static char* create_standard_memory(size_t size) {
7373
return mapAddress;
7474
}
7575

76-
// delete the PerfData memory region
77-
//
78-
static void delete_standard_memory(char* addr, size_t size) {
79-
80-
// there are no persistent external resources to cleanup for standard
81-
// memory. since DestroyJavaVM does not support unloading of the JVM,
82-
// cleanup of the memory resource is not performed. The memory will be
83-
// reclaimed by the OS upon termination of the process.
84-
//
85-
return;
86-
}
87-
8876
// save the specified memory region to the given file
8977
//
9078
// Note: this function might be called from signal handler (by os::abort()),
@@ -656,16 +644,17 @@ static void remove_file(const char* path) {
656644
}
657645

658646

659-
// cleanup stale shared memory resources
647+
// cleanup stale shared memory files
660648
//
661649
// This method attempts to remove all stale shared memory files in
662650
// the named user temporary directory. It scans the named directory
663-
// for files matching the pattern ^$[0-9]*$. For each file found, the
664-
// process id is extracted from the file name and a test is run to
665-
// determine if the process is alive. If the process is not alive,
666-
// any stale file resources are removed.
651+
// for files matching the pattern ^$[0-9]*$.
667652
//
668-
static void cleanup_sharedmem_resources(const char* dirname) {
653+
// This directory should be used only by JVM processes owned by the
654+
// current user to store PerfMemory files. Any other files found
655+
// in this directory may be removed.
656+
//
657+
static void cleanup_sharedmem_files(const char* dirname) {
669658

670659
int saved_cwd_fd;
671660
// open the directory and set the current working directory to it
@@ -675,50 +664,56 @@ static void cleanup_sharedmem_resources(const char* dirname) {
675664
return;
676665
}
677666

678-
// for each entry in the directory that matches the expected file
679-
// name pattern, determine if the file resources are stale and if
680-
// so, remove the file resources. Note, instrumented HotSpot processes
681-
// for this user may start and/or terminate during this search and
682-
// remove or create new files in this directory. The behavior of this
683-
// loop under these conditions is dependent upon the implementation of
684-
// opendir/readdir.
667+
// For each entry in the directory that matches the expected file
668+
// name pattern, remove the file if it's determine to be stale
669+
// Note, instrumented HotSpot processes for this user may start and/or
670+
// terminate during this search and remove or create new files in this
671+
// directory. The behavior of this loop under these conditions is dependent
672+
// upon the implementation of opendir/readdir.
685673
//
686674
struct dirent* entry;
687675
errno = 0;
688676
while ((entry = os::readdir(dirp)) != NULL) {
689677

690-
pid_t pid = filename_to_pid(entry->d_name);
678+
const char* filename = entry->d_name;
679+
pid_t pid = filename_to_pid(filename);
691680

692681
if (pid == 0) {
693682

694-
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
683+
if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) {
695684

696685
// attempt to remove all unexpected files, except "." and ".."
697-
unlink(entry->d_name);
686+
unlink(filename);
698687
}
699688

700689
errno = 0;
701690
continue;
702691
}
703692

704-
// we now have a file name that converts to a valid integer
705-
// that could represent a process id . if this process id
706-
// matches the current process id or the process is not running,
707-
// then remove the stale file resources.
708-
//
709-
// process liveness is detected by sending signal number 0 to
710-
// the process id (see kill(2)). if kill determines that the
711-
// process does not exist, then the file resources are removed.
712-
// if kill determines that that we don't have permission to
713-
// signal the process, then the file resources are assumed to
714-
// be stale and are removed because the resources for such a
715-
// process should be in a different user specific directory.
716-
//
717-
if ((pid == os::current_process_id()) ||
718-
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
693+
// The following code assumes that pid must be in the same
694+
// namespace as the current process.
695+
bool stale = false;
696+
697+
if (pid == os::current_process_id()) {
698+
// The file was created by a terminated process that happened
699+
// to have the same pid as the current process.
700+
stale = true;
701+
} else if (kill(pid, 0) == OS_ERR) {
702+
if (errno == ESRCH) {
703+
// The target process does not exist.
704+
stale = true;
705+
} else if (errno == EPERM) {
706+
// The file was created by a terminated process that happened
707+
// to have the same pid as a process not owned by the current user.
708+
stale = true;
709+
}
710+
}
719711

720-
unlink(entry->d_name);
712+
if (stale) {
713+
log_info(perf, memops)("Remove stale file %s/%s", dirname, filename);
714+
unlink(filename);
721715
}
716+
722717
errno = 0;
723718
}
724719

@@ -764,13 +759,13 @@ static bool make_user_tmp_dir(const char* dirname) {
764759
return true;
765760
}
766761

767-
// create the shared memory file resources
762+
// create the shared memory file
768763
//
769764
// This method creates the shared memory file with the given size
770765
// This method also creates the user specific temporary directory, if
771766
// it does not yet exist.
772767
//
773-
static int create_sharedmem_resources(const char* dirname, const char* filename, size_t size) {
768+
static int create_sharedmem_file(const char* dirname, const char* filename, size_t size) {
774769

775770
// make the user temporary directory
776771
if (!make_user_tmp_dir(dirname)) {
@@ -934,12 +929,13 @@ static char* mmap_create_shared(size_t size) {
934929
}
935930

936931
// cleanup any stale shared memory files
937-
cleanup_sharedmem_resources(dirname);
932+
cleanup_sharedmem_files(dirname);
938933

939934
assert(((size > 0) && (size % os::vm_page_size() == 0)),
940935
"unexpected PerfMemory region size");
941936

942-
fd = create_sharedmem_resources(dirname, short_filename, size);
937+
log_info(perf, memops)("Trying to open %s/%s", dirname, short_filename);
938+
fd = create_sharedmem_file(dirname, short_filename, size);
943939

944940
FREE_C_HEAP_ARRAY(char, user_name);
945941
FREE_C_HEAP_ARRAY(char, dirname);
@@ -972,6 +968,8 @@ static char* mmap_create_shared(size_t size) {
972968
// it does not go through os api, the operation has to record from here
973969
MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
974970

971+
log_info(perf, memops)("Successfully opened");
972+
975973
return mapAddress;
976974
}
977975

@@ -993,10 +991,10 @@ static char* create_shared_memory(size_t size) {
993991
//
994992
static void delete_shared_memory(char* addr, size_t size) {
995993

996-
// cleanup the persistent shared memory resources. since DestroyJavaVM does
997-
// not support unloading of the JVM, unmapping of the memory resource is
994+
// Remove the shared memory file. Since DestroyJavaVM does
995+
// not support unloading of the JVM, unmapping of the memory region is
998996
// not performed. The memory will be reclaimed by the OS upon termination of
999-
// the process. The backing store file is deleted from the file system.
997+
// the process.
1000998

1001999
assert(!PerfDisableSharedMem, "shouldn't be here");
10021000

@@ -1196,10 +1194,7 @@ void PerfMemory::delete_memory_region() {
11961194
save_memory_to_file(start(), capacity());
11971195
}
11981196

1199-
if (PerfDisableSharedMem) {
1200-
delete_standard_memory(start(), capacity());
1201-
}
1202-
else {
1197+
if (!PerfDisableSharedMem) {
12031198
delete_shared_memory(start(), capacity());
12041199
}
12051200
}

0 commit comments

Comments
 (0)