32607528da47324047452ccebe5c1c6c991f37db
galt
  Tue Oct 9 20:38:32 2012 -0700
Fix parasol to correctly enforce memory limits.
diff --git src/parasol/paraNode/paraNode.c src/parasol/paraNode/paraNode.c
index f23fd16..040eaf5 100644
--- src/parasol/paraNode/paraNode.c
+++ src/parasol/paraNode/paraNode.c
@@ -349,51 +349,63 @@
     errnoAbort("can't open job stdout file %s", out);
 if (dup2(newStdout, STDOUT_FILENO) < 0)
     errnoAbort("can't dup2 stdout");
 }
 
 void execProc(char *managingHost, char *jobIdString, char *reserved,
 	char *user, char *dir, char *in, char *out, char *err, long long memLimit,
 	char *exe, char **params)
 /* This routine is the child process of doExec.
  * It spawns a grandchild that actually does the
  * work and waits on it.  It sends message to the
  * main message loop here when done. */
 {
 if ((grandChildId = forkOrDie()) == 0)
     {
+    // use rlimit to limit RAM available to process so it will not hog the machine unfairly.
+    if (sizeof(long) == 4 && memLimit > 4294967295LL)  // 4GB is max value on 32-bit platform.
+	{
+	logWarn("memLimit %lld exceeds address space on 32-bit machine, treating it as 4GB limit", memLimit);
+	memLimit = 4294967295LL;
+	}
+    struct rlimit rlim;
+    rlim.rlim_cur = rlim.rlim_max = memLimit;
+    if (setrlimit(RLIMIT_DATA, &rlim) < 0)
+	logWarn("setrlimit failed with RLIMIT_DATA rlim_cur=%lld rlim_max=%lld"
+	    , (long long) rlim.rlim_cur , (long long) rlim.rlim_max); 
+    // although RLIMIT_AS is not supported/enforced on all platforms,
+    // it is useful for linux and some other unix OSes. 
+    if (setrlimit(RLIMIT_AS, &rlim) < 0)
+	logWarn("setrlimit failed with RLIMIT_AS rlim_cur=%lld rlim_max=%lld"
+	    , (long long) rlim.rlim_cur , (long long) rlim.rlim_max); 
+
     char *homeDir = "";
 
     /* Change to given user (if root) */
     changeUid(user, &homeDir);
 
     /* create output files just after becoming user so that errors in the rest
      * of this proc will go to the err file and be available via para
      * problems */
     setupProcStdio(in, out, err);
 
     if (chdir(dir) < 0)
         errnoAbort("can't chdir to %s", dir);
     setsid();
     // setpgid(0,0);
     umask(umaskVal); 
 
-    struct rlimit rlim;
-    rlim.rlim_cur = rlim.rlim_max = memLimit;
-    if(setrlimit(RLIMIT_CORE, &rlim) < 0)
-    perror("setrlimit"); 
-
 
     /* Update environment. */
         {
 	struct hash *hash = environToHash(environ);
 	hashUpdate(hash, "JOB_ID", jobIdString);
 	hashUpdate(hash, "USER", user);
 	hashUpdate(hash, "HOME", homeDir);
 	hashUpdate(hash, "HOST", hostName);
 	hashUpdate(hash, "PARASOL", "7");
 	updatePath(hash, userPath, homeDir, sysPath);
         addEnvExtras(hash);
 	environ = hashToEnviron(hash);
 	freeHashAndVals(&hash);
 	}