From 1682a72d34c9d856f54ecedde4541bc8daa4f05a Mon Sep 17 00:00:00 2001
From: Ralph Castain <rhc@open-mpi.org>
Date: Mon, 23 Apr 2007 18:53:47 +0000
Subject: [PATCH] Add ability to read system limits on number of children, open
 files, and file size from the local OS - to be used in failed-to-start
 scenarios

This commit was SVN r14476.
---
 opal/runtime/opal_init.c |   6 +++
 opal/util/Makefile.am    |   2 +
 opal/util/sys_limits.c   | 108 +++++++++++++++++++++++++++++++++++++++
 opal/util/sys_limits.h   |  56 ++++++++++++++++++++
 4 files changed, 172 insertions(+)
 create mode 100644 opal/util/sys_limits.c
 create mode 100644 opal/util/sys_limits.h

diff --git a/opal/runtime/opal_init.c b/opal/runtime/opal_init.c
index efccc9907a..ed155c166b 100644
--- a/opal/runtime/opal_init.c
+++ b/opal/runtime/opal_init.c
@@ -45,6 +45,7 @@
 #include "opal/util/error.h"
 #include "opal/util/stacktrace.h"
 #include "opal/util/keyval_parse.h"
+#include "opal/util/sys_limits.h"
 
 
 bool opal_init_only = true;
@@ -189,6 +190,11 @@ opal_init_util(void)
         goto return_error;
     }
 
+    if (OPAL_SUCCESS != (ret = opal_util_init_sys_limits())) {
+        error = "opal_util_init_sys_limits";
+        goto return_error;
+    }
+    
     return OPAL_SUCCESS;
 
  return_error:
diff --git a/opal/util/Makefile.am b/opal/util/Makefile.am
index 699bc08f20..fab5d43ab5 100644
--- a/opal/util/Makefile.am
+++ b/opal/util/Makefile.am
@@ -54,6 +54,7 @@ headers = \
         show_help_lex.h \
         stacktrace.h \
         strncpy.h \
+        sys_limits.h \
         trace.h
 
 libopalutil_la_SOURCES = \
@@ -84,6 +85,7 @@ libopalutil_la_SOURCES = \
         show_help_lex.l \
         stacktrace.c \
         strncpy.c \
+        sys_limits.c \
         trace.c
 libopalutil_la_LIBADD = \
 	keyval/libopalutilkeyval.la
diff --git a/opal/util/sys_limits.c b/opal/util/sys_limits.c
new file mode 100644
index 0000000000..e6cea6e5d7
--- /dev/null
+++ b/opal/util/sys_limits.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
+ *                         University Research and Technology
+ *                         Corporation.  All rights reserved.
+ * Copyright (c) 2004-2005 The University of Tennessee and The University
+ *                         of Tennessee Research Foundation.  All rights
+ *                         reserved.
+ * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 
+ *                         University of Stuttgart.  All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ *                         All rights reserved.
+ * $COPYRIGHT$
+ * 
+ * Additional copyrights may follow
+ * 
+ * $HEADER$
+ *
+ * This file is only here because some platforms have a broken strncpy
+ * (e.g., Itanium with RedHat Advanced Server glibc).
+ */
+
+#include "opal_config.h"
+
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include "opal/mca/base/mca_base_param.h"
+
+#include "opal/util/sys_limits.h"
+
+
+/*
+ * Create and initialize storage for the system limits
+ */
+OPAL_DECLSPEC opal_sys_limits_t opal_sys_limits = {
+    /* initialized = */     false,
+    /* num_files   = */     -1,
+    /* num_procs   = */     -1,
+    /* file_size   = */      0
+};
+
+int opal_util_init_sys_limits(void)
+{
+    struct rlimit rlim;
+    int value;
+    bool set_lims;
+
+    mca_base_param_reg_int_name("opal", "set_max_sys_limits", 
+                                "Set to non-zero to automatically set any system-imposed limits to the maximum allowed",
+                                false, false, (int)false, &value);
+    set_lims = OPAL_INT_TO_BOOL(value);
+
+#ifdef __WINDOWS__
+    /* George: please insert whatever is needed here someday */
+#else
+    /* get/set the system limits on number of files we can have open */
+    if (getrlimit (RLIMIT_NOFILE, &rlim) < 0) {
+        opal_output(0, "getrlimit (RLIMIT_NOFILE) failed: %s\n", strerror(errno));
+    } else {
+        if (set_lims) {
+            rlim.rlim_cur = rlim.rlim_max;
+            if (setrlimit (RLIMIT_NOFILE, &rlim) < 0) {
+                opal_output(0, "setrlimit (RLIMIT_NOFILE) failed: %s\n", strerror(errno));
+            }
+        }
+        opal_sys_limits.num_files = rlim.rlim_cur;
+    }
+    
+    /* get/set the system limits on number of child procs we can have open */
+    if (getrlimit (RLIMIT_NPROC, &rlim) < 0) {
+        opal_output(0, "getrlimit (RLIMIT_NPROC) failed: %s\n", strerror(errno));
+    } else {
+        if (set_lims) {
+            rlim.rlim_cur = rlim.rlim_max;
+            if (setrlimit (RLIMIT_NPROC, &rlim) < 0) {
+                opal_output(0, "setrlimit (RLIMIT_NPROC) failed: %s\n", strerror(errno));
+            }
+        }
+        opal_sys_limits.num_procs = rlim.rlim_cur;
+    }
+    
+    /* get/set the system limits on max file size we can create */
+    if (getrlimit (RLIMIT_FSIZE, &rlim) < 0) {
+        opal_output(0, "getrlimit (RLIMIT_FSIZE) failed: %s\n", strerror(errno));
+    } else {
+        if (set_lims) {
+            rlim.rlim_cur = rlim.rlim_max;
+            if (setrlimit (RLIMIT_FSIZE, &rlim) < 0) {
+                opal_output(0, "setrlimit (RLIMIT_FSIZE) failed: %s\n", strerror(errno));
+            }
+        }
+        opal_sys_limits.file_size = rlim.rlim_cur;
+    }
+    
+    /* indicate we initialized the limits structure */
+    opal_sys_limits.initialized = true;
+#endif
+
+  return OPAL_SUCCESS;
+}
diff --git a/opal/util/sys_limits.h b/opal/util/sys_limits.h
new file mode 100644
index 0000000000..0c63c0c6b9
--- /dev/null
+++ b/opal/util/sys_limits.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
+ *                         University Research and Technology
+ *                         Corporation.  All rights reserved.
+ * Copyright (c) 2004-2006 The University of Tennessee and The University
+ *                         of Tennessee Research Foundation.  All rights
+ *                         reserved.
+ * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 
+ *                         University of Stuttgart.  All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ *                         All rights reserved.
+ * $COPYRIGHT$
+ * 
+ * Additional copyrights may follow
+ * 
+ * $HEADER$
+ */
+
+#ifndef OPAL_SYS_LIMITS_H
+#define OPAL_SYS_LIMITS_H
+
+#include "opal_config.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C" {
+#endif
+
+/* define a structure to hold the various limits we find
+ * so that users can neatly access them
+ */
+typedef struct opal_sys_limits_t {
+    bool initialized;
+    int num_files;
+    int num_procs;
+    size_t file_size;
+} opal_sys_limits_t;
+
+/* since we only want to do this once, we will store the
+ * values in the following locations - provide access here
+ */
+OPAL_DECLSPEC extern opal_sys_limits_t opal_sys_limits;
+    
+/* Get the system resource limits and, if requested, set
+ * them to the max allowed
+ */
+OPAL_DECLSPEC int opal_util_init_sys_limits(void);
+
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* OPAL_STRNCPY_H */