20
20
* are permitted provided that all of the following conditions are met.
21
21
* After December 31, 2001, only conditions 3-6 must be met:
23
* 1. Commercial and/or non-commercial use of the Software is permitted
24
* provided a current software registration is on file at www.OpenPBS.org.
25
* If use of this software contributes to a publication, product, or
26
* service, proper attribution must be given; see www.OpenPBS.org/credit.html
28
* 2. Redistribution in any form is only permitted for non-commercial,
29
* non-profit purposes. There can be no charge for the Software or any
30
* software incorporating the Software. Further, there can be no
31
* expectation of revenue generated as a consequence of redistributing
34
23
* 3. Any Redistribution of source code must retain the above copyright notice
35
24
* and the acknowledgment contained in paragraph 6, this list of conditions
36
25
* and the disclaimer contained in paragraph 7.
187
174
** external functions and data
190
extern struct config *search A_((struct config *, char *));
192
extern struct rm_attribute *momgetattr A_((char *));
176
extern struct config *search A_((struct config *,char *));
177
extern struct rm_attribute *momgetattr A_((char *));
193
178
extern int rm_errno;
194
extern double cputfactor;
195
extern double wallfactor;
196
extern long system_ncpus;
197
extern int ignwalltime;
179
extern double cputfactor;
180
extern double wallfactor;
181
extern long system_ncpus;
182
extern int ignwalltime;
201
188
** local functions and data
203
static char *resi A_((struct rm_attribute *));
204
static char *totmem A_((struct rm_attribute *));
190
static char *resi A_((struct rm_attribute *));
191
static char *totmem A_((struct rm_attribute *));
205
192
static char *availmem A_((struct rm_attribute *));
206
static char *physmem A_((struct rm_attribute *));
207
static char *ncpus A_((struct rm_attribute *));
193
static char *physmem A_((struct rm_attribute *));
194
static char *ncpus A_((struct rm_attribute *));
208
195
static char *walltime A_((struct rm_attribute *));
209
static char *quota A_((struct rm_attribute *));
210
static char *netload A_((struct rm_attribute *));
196
static char *quota A_((struct rm_attribute *));
197
static char *netload A_((struct rm_attribute *));
203
mbool_t ProcIsChild(char *,char *,char *);
212
205
extern char *loadave A_((struct rm_attribute *));
213
206
extern char *nullproc A_((struct rm_attribute *));
401
394
/* see stat_str[] value for mapping 'stat' format */
402
if (sscanf(lastbracket, stat_str,
403
&ps.state, /* state (one of RSDZTW) */
406
&ps.session, /* session id */
407
&ps.flags, /* flags - kernel flags of the process, see the PF_* in <linux/sched.h> */
408
&ps.utime, /* utime - jiffies that this process has been scheduled in user mode */
409
&ps.stime, /* stime - jiffies that this process has been scheduled in kernel mode */
410
&ps.cutime, /* cutime - jiffies that this processās waited-for children have been scheduled in user mode */
411
&ps.cstime, /* cstime - jiffies that this processās waited-for children have been scheduled in kernel mode */
412
&jstarttime, /* starttime */
413
&ps.vsize, /* vsize */
414
&ps.rss) != 12) /* rss */
396
if (sscanf(lastbracket,stat_str,
397
&ps.state, /* state (one of RSDZTW) */
400
&ps.session, /* session id */
401
&ps.flags, /* flags - kernel flags of the process, see the PF_* in <linux/sched.h> */
402
&ps.utime, /* utime - jiffies that this process has been scheduled in user mode */
403
&ps.stime, /* stime - jiffies that this process has been scheduled in kernel mode */
404
&ps.cutime, /* cutime - jiffies that this processās waited-for children have been scheduled in user mode */
405
&ps.cstime, /* cstime - jiffies that this processās waited-for children have been scheduled in kernel mode */
406
&jstarttime, /* starttime */
407
&ps.vsize, /* vsize */
408
&ps.rss) != 12) /* rss */
459
453
unsigned long long bfsz, casz;
461
if ((fp = fopen("/proc/meminfo", "r")) == NULL)
466
if (fscanf(fp, "%30s", str) != 1)
471
if (!strncmp(str, "total:", sizeof(str)))
455
if ((fp = fopen("/proc/meminfo","r")) == NULL)
460
if (fscanf(fp,"%30s",str) != 1)
465
if (!strncmp(str,"total:",sizeof(str)))
475
if (fscanf(fp, "%*[^\n]%*c") != 0) /* remove text header */
469
if (fscanf(fp,"%*[^\n]%*c") != 0) /* remove text header */
1084
1077
assert(string != NULL);
1085
1078
assert(*string != '\0');
1086
assert(value > PBSE_); /* minimum PBS error number */
1087
assert(value <= PBSE_NOSYNCMSTR); /* maximum PBS error number */
1088
assert(pbs_err_to_txt[i].err_no != 0);
1092
if (pbs_err_to_txt[i].err_no == value)
1095
while (pbs_err_to_txt[++i].err_no != 0);
1097
assert(pbs_err_to_txt[i].err_txt != NULL);
1099
message = *pbs_err_to_txt[i].err_txt;
1080
message = pbse_to_txt(value);
1101
1082
assert(message != NULL);
1103
1083
assert(*message != '\0');
1105
1085
fprintf(stderr, msg_momsetlim, string, message);
1205
1185
if (!strcmp(pname, "cput"))
1207
/* cpu time - check, if less than pcput use it */
1209
retval = gettime(pres, &value);
1211
if (retval != PBSE_NONE)
1187
if (igncput == FALSE)
1213
sprintf(log_buffer, "cput gettime failed in %s",
1216
return(error(pname, retval));
1189
/* cpu time - check, if less than pcput use it */
1191
retval = gettime(pres, &value);
1193
if (retval != PBSE_NONE)
1195
sprintf(log_buffer, "cput gettime failed in %s",id);
1197
return(error(pname, retval));
1219
1201
else if (!strcmp(pname, "pcput"))
1221
if (set_mode == SET_LIMIT_SET)
1203
if (igncput == FALSE)
1223
/* process cpu time - set */
1225
retval = gettime(pres, &value);
1227
if (retval != PBSE_NONE)
1229
sprintf(log_buffer, "pcput gettime failed in %s",
1232
return(error(pname, retval));
1235
reslim.rlim_cur = reslim.rlim_max = (unsigned long)((double)value / cputfactor);
1239
sprintf(log_buffer, "setting cpu time limit to %ld for job %s",
1240
(long int)reslim.rlim_cur,
1241
pjob->ji_qs.ji_jobid);
1243
log_record(PBSEVENT_SYSTEM, 0, id, log_buffer);
1245
log_buffer[0] = '\0';
1248
/* NOTE: some versions of linux have a bug which causes the parent
1249
process to receive a SIGKILL if the child's cpu limit is exceeded */
1251
if (setrlimit(RLIMIT_CPU, &reslim) < 0)
1253
sprintf(log_buffer, "setrlimit for RLIMIT_CPU failed in %s, errno=%d (%s)",
1255
errno, strerror(errno));
1257
return(error("RLIMIT_CPU", PBSE_SYSTEM));
1259
} /* END if (set_mode == SET_LIMIT_SET) */
1205
if (set_mode == SET_LIMIT_SET)
1207
/* process cpu time - set */
1209
retval = gettime(pres, &value);
1211
if (retval != PBSE_NONE)
1213
sprintf(log_buffer, "pcput gettime failed in %s",id);
1215
return(error(pname, retval));
1218
reslim.rlim_cur = reslim.rlim_max =
1219
(unsigned long)((double)value / cputfactor);
1223
sprintf(log_buffer, "setting cpu time limit to %ld for job %s",
1224
(long int)reslim.rlim_cur,
1225
pjob->ji_qs.ji_jobid);
1227
log_record(PBSEVENT_SYSTEM, 0, id, log_buffer);
1229
log_buffer[0] = '\0';
1232
/* NOTE: some versions of linux have a bug which causes the parent
1233
process to receive a SIGKILL if the child's cpu limit is exceeded */
1235
if (setrlimit(RLIMIT_CPU, &reslim) < 0)
1237
sprintf(log_buffer, "setrlimit for RLIMIT_CPU failed in %s, errno=%d (%s)",
1239
errno, strerror(errno));
1241
return(error("RLIMIT_CPU", PBSE_SYSTEM));
1243
} /* END if (set_mode == SET_LIMIT_SET) */
1261
1246
else if (!strcmp(pname, "file"))
1309
1294
else if (!strcmp(pname, "vmem"))
1313
retval = getsize(pres, &value);
1315
if (retval != PBSE_NONE)
1317
sprintf(log_buffer, "getsize() failed for vmem in %s",
1320
return(error(pname, retval));
1323
if ((vmem_limit == 0) || (value < vmem_limit))
1326
else if (!strcmp(pname, "pvmem"))
1330
if (set_mode == SET_LIMIT_SET)
1296
if (ignvmem == FALSE)
1332
1300
retval = getsize(pres, &value);
1334
1302
if (retval != PBSE_NONE)
1336
sprintf(log_buffer, "getsize() failed for pvmem in %s",
1304
sprintf(log_buffer, "getsize() failed for vmem in %s",id);
1339
1306
return(error(pname, retval));
1342
if (value > ULONG_MAX)
1344
log_buffer[0] = '\0';
1346
sprintf(log_buffer, "invalid value returned by getsize() for pvmem in %s",
1349
return(error(pname, PBSE_BADATVAL));
1352
1309
if ((vmem_limit == 0) || (value < vmem_limit))
1353
1310
vmem_limit = value;
1356
else if ((!strcmp(pname, "mem") && (pjob->ji_numnodes != 1)) ||
1357
!strcmp(pname, "mppmem"))
1313
else if (!strcmp(pname, "pvmem"))
1315
if (ignvmem == FALSE)
1319
if (set_mode == SET_LIMIT_SET)
1321
retval = getsize(pres, &value);
1323
if (retval != PBSE_NONE)
1325
sprintf(log_buffer, "getsize() failed for pvmem in %s",
1328
return(error(pname, retval));
1331
if (value > ULONG_MAX)
1333
log_buffer[0] = '\0';
1335
sprintf(log_buffer, "invalid value returned by getsize() for pvmem in %s",
1338
return(error(pname, PBSE_BADATVAL));
1341
if ((vmem_limit == 0) || (value < vmem_limit))
1346
else if ((!strcmp(pname,"mem") && (pjob->ji_numnodes != 1)) ||
1347
!strcmp(pname,"mppmem"))
1359
1349
/* ignore. If we ever get rid of support for the UNICOS OS then we can
1360
1350
remove the ATR_DFLAG_MOM | ATR_DFLAG_ALTRUN flags from mppmem */
1362
1352
else if ((!strcmp(pname, "mem") && (pjob->ji_numnodes == 1)) ||
1363
1353
!strcmp(pname, "pmem"))
1367
if (set_mode == SET_LIMIT_SET)
1355
if (ignmem == FALSE)
1369
retval = getsize(pres, &value);
1371
if (retval != PBSE_NONE)
1373
sprintf(log_buffer, "getsize() failed for mem/pmem in %s",
1376
return(error(pname, retval));
1379
reslim.rlim_cur = reslim.rlim_max = value;
1381
if (setrlimit(RLIMIT_DATA, &reslim) < 0)
1383
sprintf(log_buffer, "cannot set data limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1385
pjob->ji_qs.ji_jobid,
1389
return(error("RLIMIT_DATA", PBSE_SYSTEM));
1392
if (setrlimit(RLIMIT_RSS, &reslim) < 0)
1394
sprintf(log_buffer, "cannot set RSS limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1396
pjob->ji_qs.ji_jobid,
1400
return(error("RLIMIT_RSS", PBSE_SYSTEM));
1359
if (set_mode == SET_LIMIT_SET)
1361
retval = getsize(pres, &value);
1363
if (retval != PBSE_NONE)
1365
sprintf(log_buffer, "getsize() failed for mem/pmem in %s",
1368
return(error(pname, retval));
1371
reslim.rlim_cur = reslim.rlim_max = value;
1373
if (setrlimit(RLIMIT_DATA, &reslim) < 0)
1375
sprintf(log_buffer, "cannot set data limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1376
(long int)reslim.rlim_max,
1377
pjob->ji_qs.ji_jobid,
1381
return(error("RLIMIT_DATA", PBSE_SYSTEM));
1384
if (setrlimit(RLIMIT_RSS, &reslim) < 0)
1386
sprintf(log_buffer, "cannot set RSS limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1387
(long int)reslim.rlim_max,
1388
pjob->ji_qs.ji_jobid,
1392
return(error("RLIMIT_RSS", PBSE_SYSTEM));
1403
1395
#ifdef __GATECH
1404
/* NOTE: best patch may be to change to 'vmem_limit = value;' */
1406
if (setrlimit(RLIMIT_STACK, &reslim) < 0)
1408
sprintf(log_buffer, "cannot set stack limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1410
pjob->ji_qs.ji_jobid,
1414
return(error("RLIMIT_STACK", PBSE_SYSTEM));
1417
/* set address space */
1419
if (setrlimit(RLIMIT_AS, &reslim) < 0)
1421
sprintf(log_buffer, "cannot set AS limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1423
pjob->ji_qs.ji_jobid,
1427
return(error("RLIMIT_AS", PBSE_SYSTEM));
1396
/* NOTE: best patch may be to change to 'vmem_limit = value;' */
1398
if (setrlimit(RLIMIT_STACK, &reslim) < 0)
1400
sprintf(log_buffer, "cannot set stack limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1401
(long int)reslim.rlim_max,
1402
pjob->ji_qs.ji_jobid,
1406
return(error("RLIMIT_STACK", PBSE_SYSTEM));
1409
/* set address space */
1411
if (setrlimit(RLIMIT_AS, &reslim) < 0)
1413
sprintf(log_buffer, "cannot set AS limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1414
(long int)reslim.rlim_max,
1415
pjob->ji_qs.ji_jobid,
1419
return(error("RLIMIT_AS", PBSE_SYSTEM));
1430
1422
#endif /* __GATECH */
1434
if (getrlimit(RLIMIT_STACK, &reslim) >= 0)
1436
/* NOTE: mem_limit no longer used with UMU patch in place */
1438
mem_limit = value + reslim.rlim_cur;
1426
if (getrlimit(RLIMIT_STACK, &reslim) >= 0)
1428
/* NOTE: mem_limit no longer used with UMU patch in place */
1430
mem_limit = value + reslim.rlim_cur;
1441
1434
} /* END else if (!strcmp(pname,"mem") && ... */
2439
2456
int mach_checkpoint(
2458
task *ptask, /* I */
2443
2460
int abort) /* I */
2446
char *id = "mach_checkpoint";
2453
#define SET_ARG(x) (((x) == NULL) || (*(x) == 0))?"-":(x)
2455
/* if a checkpoint script is defined launch it */
2457
if (checkpoint_script_name[0] == '\0')
2459
log_err(-1, id, "No checkpoint script defined");
2463
/* launch the script and return success */
2469
/* parent: pid = child's pid */
2471
/* NO-OP, but may need to waitpid() the child (NYI) */
2477
/* child: execv the script */
2480
ptask->ti_job->ji_wattr[(int)JOB_ATR_session_id].at_val.at_long);
2482
arg[0] = checkpoint_script_name;
2484
arg[2] = SET_ARG(ptask->ti_job->ji_qs.ji_jobid);
2485
arg[3] = SET_ARG(ptask->ti_job->ji_wattr[(int)JOB_ATR_euser].at_val.at_str);
2486
arg[4] = SET_ARG(ptask->ti_job->ji_wattr[(int)JOB_ATR_chkptdir].at_val.at_str);
2487
arg[5] = SET_ARG(ptask->ti_job->ji_wattr[(int)JOB_ATR_chkptname].at_val.at_str);
2488
arg[6] = (abort) ? "15" /*abort*/ : "0" /*run/continue*/;
2491
strcpy(buf, "checkpoint args:");
2493
for (ap = arg; *ap; ap++)
2499
log_err(-1, id, buf);
2503
/* NOTE: The right way to do this is to put the job into some sort
2504
* of waiting state before returning, and the monitor the
2505
* the child to see what it's exit status is. We are delaying
2506
* the full implementation for now. NYI
2508
} /* END if (pid == 0) */
2512
2464
} /* END mach_checkpoint() */
2530
char *id = "mach_restart";
2536
/* if a restart script is defined launch it */
2538
if (restart_script_name[0] == '\0')
2540
log_record(PBSEVENT_DEBUG, 0, id, "No restart script defined");
2544
/* launch the script and return success */
2550
/* parent: pid = child's pid */
2552
/* NO-OP, but may need to waitpid() the child (NYI) */
2559
/* child: execv the script */
2562
ptask->ti_job->ji_wattr[(int)JOB_ATR_session_id].at_val.at_long);
2564
arg[0] = restart_script_name;
2566
arg[2] = ptask->ti_job->ji_qs.ji_jobid;
2567
arg[3] = ptask->ti_job->ji_wattr[(int)JOB_ATR_euser].at_val.at_str;
2572
/* NOTE: The right way to do this is to put the job into some sort
2573
* of waiting state before returning, and the monitor the
2574
* the child to see what it's exit status is. We are delaying
2575
* the full implementation for now. NYI
2577
} /* END if (pid == 0) */