Skip to content

Commit 20f563c

Browse files
committed
Use system limit on file descriptors for soft limit
If user tries to set the soft limit of file descriptors to unlimited on MacOS, use the system limit instead. Add unit test. Add diagnostics output to test. Clean up incorrect return values. Fixes eclipse-omr/omr#3579 Signed-off-by: Peter Bain <[email protected]> Signed-off-by: Peter Bain <[email protected]>
1 parent 53fdb04 commit 20f563c

File tree

2 files changed

+62
-8
lines changed

2 files changed

+62
-8
lines changed

fvtest/porttest/si.cpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -806,9 +806,10 @@ TEST(PortSysinfoTest, sysinfo_test_sysinfo_set_limit_CORE_FILE)
806806
{
807807
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
808808
const char *testName = "omrsysinfo_test_sysinfo_set_limit_FILE_DESCRIPTORS";
809-
intptr_t rc = -1;
809+
uint32_t rc = OMRPORT_LIMIT_UNKNOWN;
810810
uint64_t originalSoftLimit = 0;
811811
uint64_t finalSoftLimit = 0;
812+
uint64_t softSetToHardLimit = 0;
812813
uint64_t originalHardLimit = 0;
813814
uint64_t currentLimit = 0;
814815
const uint64_t descriptorLimit = 256;
@@ -822,6 +823,7 @@ TEST(PortSysinfoTest, sysinfo_test_sysinfo_set_limit_CORE_FILE)
822823
reportTestExit(OMRPORTLIB, testName);
823824
return;
824825
}
826+
portTestEnv->log(LEVEL_ERROR, "originalSoftLimit=%llu\n", originalSoftLimit);
825827
finalSoftLimit = originalSoftLimit;
826828

827829
rc = omrsysinfo_set_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, descriptorLimit);
@@ -854,18 +856,54 @@ TEST(PortSysinfoTest, sysinfo_test_sysinfo_set_limit_CORE_FILE)
854856
reportTestExit(OMRPORTLIB, testName);
855857
return;
856858
}
859+
portTestEnv->log(LEVEL_ERROR, "originalHardLimit=%llu\n", originalHardLimit);
860+
861+
/* set soft limit to hard limit */
862+
rc = omrsysinfo_set_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, originalHardLimit);
863+
if (0 != rc) {
864+
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_set_limit soft = hard FAILED rc=%d\n", rc);
865+
reportTestExit(OMRPORTLIB, testName);
866+
return;
867+
}
868+
869+
/* get new soft limit */
870+
rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, &softSetToHardLimit);
871+
if (OMRPORT_LIMIT_UNKNOWN == rc) {
872+
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_limit FAILED: OMRPORT_LIMIT_UNKNOWN\n");
873+
reportTestExit(OMRPORTLIB, testName);
874+
return;
875+
}
876+
portTestEnv->log(LEVEL_ERROR, "soft set to hard limit=%llu\n", softSetToHardLimit);
877+
878+
/* set soft limit to old value */
879+
rc = omrsysinfo_set_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS, originalSoftLimit);
880+
if (0 != rc) {
881+
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_set_limit reset soft FAILED rc=%d\n", rc);
882+
reportTestExit(OMRPORTLIB, testName);
883+
return;
884+
}
885+
886+
rc = omrsysinfo_get_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS | OMRPORT_LIMIT_HARD, &currentLimit);
887+
if (currentLimit != originalHardLimit) {
888+
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_limit FAILED: hard limit changed\n");
889+
reportTestExit(OMRPORTLIB, testName);
890+
return;
891+
}
857892

858893
/* lowering the hard limit is irreversible unless privileged */
859894
if (0 != geteuid()) { /* normal user */
860895
/* setting the hard limit from unlimited to a finite value has unpredictable results:
861896
* the actual value may be much smaller than requested.
862-
* In that case, just try setting it to the same value.
897+
* In that case, just try setting it to its current value (softSetToHardLimit) or a value slightly lower.
898+
* Ensure that we don't try to set the hard limit to a value less than the current soft limit
899+
* (i.e. originalSoftLimit).
863900
*/
864-
uint64_t newHardLimit = (OMRPORT_LIMIT_UNLIMITED == rc) ? originalHardLimit: originalHardLimit - 1;
901+
uint64_t newHardLimit = ((OMRPORT_LIMIT_UNLIMITED == rc) || (originalSoftLimit == softSetToHardLimit))
902+
? softSetToHardLimit: softSetToHardLimit - 1;
865903

866904
rc = omrsysinfo_set_limit(OMRPORT_RESOURCE_FILE_DESCRIPTORS | OMRPORT_LIMIT_HARD, newHardLimit);
867905
if (0 != rc) {
868-
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_set_limit set hard limit FAILED rc=%d\n", rc);
906+
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_set_limit set hard limit=%lld FAILED rc=%d\n", rc, newHardLimit);
869907
reportTestExit(OMRPORTLIB, testName);
870908
return;
871909
}

port/unix/omrsysinfo.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,7 +2375,7 @@ omrsysinfo_set_limit(struct OMRPortLibrary *portLibrary, uint32_t resourceID, ui
23752375
#if !defined(OMRZTPF)
23762376
resource = RLIMIT_CORE;
23772377
#else /* !defined(OMRZTPF) */
2378-
rc = -1;
2378+
rc = OMRPORT_LIMIT_UNKNOWN;
23792379
#endif /* !defined(OMRZTPF) */
23802380
break;
23812381
default:
@@ -2400,6 +2400,22 @@ omrsysinfo_set_limit(struct OMRPortLibrary *portLibrary, uint32_t resourceID, ui
24002400
if (hardLimitRequested) {
24012401
lim.rlim_max = limit;
24022402
} else {
2403+
#if defined(OSX)
2404+
/* MacOS doesn't allow the soft file limit to be unlimited */
2405+
if ((OMRPORT_RESOURCE_FILE_DESCRIPTORS == resourceRequested)
2406+
&& (RLIM_INFINITY == limit)) {
2407+
int32_t maxFiles = 0;
2408+
size_t resultSize = sizeof(maxFiles);
2409+
int name[] = {CTL_KERN, KERN_MAXFILESPERPROC};
2410+
rc = sysctl(name, 2, &maxFiles, &resultSize, NULL, 0);
2411+
if (-1 == rc) {
2412+
portLibrary->error_set_last_error(portLibrary, errno, findError(errno));
2413+
Trc_PRT_sysinfo_setrlimit_error(resource, limit, findError(errno));
2414+
} else {
2415+
limit = maxFiles;
2416+
}
2417+
}
2418+
#endif
24032419
lim.rlim_cur = limit;
24042420
}
24052421

@@ -2409,7 +2425,7 @@ omrsysinfo_set_limit(struct OMRPortLibrary *portLibrary, uint32_t resourceID, ui
24092425
Trc_PRT_sysinfo_setrlimit_error(resource, limit, findError(errno));
24102426
}
24112427
#else /* !defined(OMRZTPF) */
2412-
rc = -1;
2428+
rc = OMRPORT_LIMIT_UNKNOWN;
24132429
#endif /* !defined(OMRZTPF) */
24142430
break;
24152431
}
@@ -2426,14 +2442,14 @@ omrsysinfo_set_limit(struct OMRPortLibrary *portLibrary, uint32_t resourceID, ui
24262442
}
24272443
#else
24282444
/* unsupported so return error */
2429-
rc = -1;
2445+
rc = OMRPORT_LIMIT_UNKNOWN;
24302446
#endif
24312447
break;
24322448
}
24332449

24342450
default:
24352451
Trc_PRT_sysinfo_setLimit_unrecognised_resourceID(resourceID);
2436-
rc = -1;
2452+
rc = OMRPORT_LIMIT_UNKNOWN;
24372453
}
24382454
}
24392455

0 commit comments

Comments
 (0)