From 19ced982847f9d9b6f3923432eab34ed35612b03 Mon Sep 17 00:00:00 2001
From: Tim Wickberg <tim@schedmd.com>
Date: Mon, 29 Apr 2019 19:39:05 -0600
Subject: [PATCH] Add in rlimits_maximize_nofiles() to workaround setrlimit()
 restrictions on macOS.

Rather than repeat the #ifdef block through five locations, use a common
function to handle this and print a consistent error message if there
is an issue.

From getrlimit(2):
	setrlimit() now returns with errno set to EINVAL in places that
	historically succeeded. It no longer accepts "rlim_cur =
	RLIM_INFINITY" for RLIM_NOFILE. Use "rlim_cur = min(OPEN_MAX,
	rlim_max)".

(This was causing spurious error messages to appear for sbatch/srun.)
---
 src/common/slurm_rlimits_info.c | 19 +++++++++++++++++++
 src/common/slurm_rlimits_info.h |  7 +++++++
 src/sbatch/sbatch.c             |  9 +--------
 src/slurmctld/controller.c      |  6 ++----
 src/slurmd/slurmd/slurmd.c      |  7 +++----
 src/slurmdbd/slurmdbd.c         |  6 ++----
 src/srun/libsrun/srun_job.c     |  9 +--------
 7 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/src/common/slurm_rlimits_info.c b/src/common/slurm_rlimits_info.c
index e498c80db5b..26320dc5863 100644
--- a/src/common/slurm_rlimits_info.c
+++ b/src/common/slurm_rlimits_info.c
@@ -35,6 +35,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <sys/param.h>	/* for OPEN_MAX on macOS */
 #include <sys/time.h>
 #include <sys/resource.h>
 
@@ -197,3 +198,21 @@ extern void print_rlimits(void)
 		}
 	}
 }
+
+extern void rlimits_maximize_nofile(void)
+{
+	struct rlimit rlim;
+
+	if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
+		error("getrlimit(RLIMIT_NOFILE): %m");
+
+	if (rlim.rlim_cur < rlim.rlim_max) {
+#if defined(__APPLE__)
+		rlim.rlim_cur = MIN(OPEN_MAX, rlim.rlim_max);
+#else
+		rlim.rlim_cur = rlim.rlim_max;
+#endif
+		if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
+			error("Unable to increase maximum number of open files: %m");
+	}
+}
diff --git a/src/common/slurm_rlimits_info.h b/src/common/slurm_rlimits_info.h
index cb54c0dfb09..57562ae5b97 100644
--- a/src/common/slurm_rlimits_info.h
+++ b/src/common/slurm_rlimits_info.h
@@ -60,4 +60,11 @@ extern int parse_rlimits( char *rlimits_str, int propagate_flag );
 
 extern void print_rlimits( void );
 
+/*
+ * Max out the RLIMIT_NOFILE setting.
+ *
+ * Handled through this so cross-platform issues can be isolated.
+ */
+extern void rlimits_maximize_nofile(void);
+
 #endif /*__SLURM_RLIMITS_INFO_H__*/
diff --git a/src/sbatch/sbatch.c b/src/sbatch/sbatch.c
index 56b787af595..db11e08707d 100644
--- a/src/sbatch/sbatch.c
+++ b/src/sbatch/sbatch.c
@@ -1059,14 +1059,7 @@ static int _set_rlimit_env(void)
 	/*
 	 *  Now increase NOFILE to the max available for this srun
 	 */
-	if (getrlimit (RLIMIT_NOFILE, rlim) < 0)
-		return (error ("getrlimit (RLIMIT_NOFILE): %m"));
-
-	if (rlim->rlim_cur < rlim->rlim_max) {
-		rlim->rlim_cur = rlim->rlim_max;
-		if (setrlimit (RLIMIT_NOFILE, rlim) < 0)
-			return (error("Unable to increase max no. files: %m"));
-	}
+	rlimits_maximize_nofile();
 
 	return rc;
 }
diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index a73117a9c11..3d5fa057624 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -84,6 +84,7 @@
 #include "src/common/slurm_priority.h"
 #include "src/common/slurm_protocol_api.h"
 #include "src/common/slurm_protocol_interface.h"
+#include "src/common/slurm_rlimits_info.h"
 #include "src/common/slurm_route.h"
 #include "src/common/slurm_topology.h"
 #include "src/common/switch.h"
@@ -948,10 +949,7 @@ static void  _init_config(void)
 {
 	struct rlimit rlim;
 
-	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
-		rlim.rlim_cur = rlim.rlim_max;
-		(void) setrlimit(RLIMIT_NOFILE, &rlim);
-	}
+	rlimits_maximize_nofile();
 	if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
 		rlim.rlim_cur = rlim.rlim_max;
 		(void) setrlimit(RLIMIT_CORE, &rlim);
diff --git a/src/slurmd/slurmd/slurmd.c b/src/slurmd/slurmd/slurmd.c
index c0c32d4ed7e..e6522b0ef02 100644
--- a/src/slurmd/slurmd/slurmd.c
+++ b/src/slurmd/slurmd/slurmd.c
@@ -93,6 +93,7 @@
 #include "src/common/slurm_jobacct_gather.h"
 #include "src/common/slurm_mcs.h"
 #include "src/common/slurm_protocol_api.h"
+#include "src/common/slurm_rlimits_info.h"
 #include "src/common/slurm_route.h"
 #include "src/common/slurm_topology.h"
 #include "src/common/stepd_api.h"
@@ -1692,15 +1693,13 @@ _slurmd_init(void)
 		}
 	}
 
-	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
-		rlim.rlim_cur = rlim.rlim_max;
-		setrlimit(RLIMIT_NOFILE, &rlim);
-	}
 	if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
 		rlim.rlim_cur = rlim.rlim_max;
 		setrlimit(RLIMIT_CORE, &rlim);
 	}
 
+	rlimits_maximize_nofile();
+
 	/*
 	 * Create a context for verifying slurm job credentials
 	 */
diff --git a/src/slurmdbd/slurmdbd.c b/src/slurmdbd/slurmdbd.c
index 9549fdf56f9..43b8c43bd20 100644
--- a/src/slurmdbd/slurmdbd.c
+++ b/src/slurmdbd/slurmdbd.c
@@ -60,6 +60,7 @@
 #include "src/common/read_config.h"
 #include "src/common/slurm_accounting_storage.h"
 #include "src/common/slurm_auth.h"
+#include "src/common/slurm_rlimits_info.h"
 #include "src/common/slurm_time.h"
 #include "src/common/uid.h"
 #include "src/common/xmalloc.h"
@@ -398,10 +399,7 @@ static void  _init_config(void)
 {
 	struct rlimit rlim;
 
-	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
-		rlim.rlim_cur = rlim.rlim_max;
-		(void) setrlimit(RLIMIT_NOFILE, &rlim);
-	}
+	rlimits_maximize_nofile();
 	if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
 		rlim.rlim_cur = rlim.rlim_max;
 		(void) setrlimit(RLIMIT_CORE, &rlim);
diff --git a/src/srun/libsrun/srun_job.c b/src/srun/libsrun/srun_job.c
index 2a6d1b989a8..b4f9748a007 100644
--- a/src/srun/libsrun/srun_job.c
+++ b/src/srun/libsrun/srun_job.c
@@ -1978,14 +1978,7 @@ static int _set_rlimit_env(void)
 	/*
 	 *  Now increase NOFILE to the max available for this srun
 	 */
-	if (getrlimit (RLIMIT_NOFILE, rlim) < 0)
-		return (error ("getrlimit (RLIMIT_NOFILE): %m"));
-
-	if (rlim->rlim_cur < rlim->rlim_max) {
-		rlim->rlim_cur = rlim->rlim_max;
-		if (setrlimit (RLIMIT_NOFILE, rlim) < 0)
-			return (error ("Unable to increase max no. files: %m"));
-	}
+	rlimits_maximize_nofile();
 
 	return rc;
 }
-- 
GitLab