~ubuntu-branches/ubuntu/precise/torque/precise-updates

« back to all changes in this revision

Viewing changes to src/resmom/linux/mom_mach.c

  • Committer: Bazaar Package Importer
  • Author(s): Dominique Belhachemi
  • Date: 2010-05-17 20:56:46 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100517205646-yjsoqs5r1s9xpnu9
Tags: upstream-2.4.8+dfsg
ImportĀ upstreamĀ versionĀ 2.4.8+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
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:
22
22
*
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
27
 
*
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
32
 
*    the Software.
33
 
*
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.
105
94
#include <syscall.h>
106
95
#include <ctype.h>
107
96
#include <string.h>
 
97
#include <csv.h>
108
98
 
109
99
#ifdef Q_6_5_QUOTAON
110
100
/* remap dqblk for SUSE 9.0 */
124
114
#include "server_limits.h"
125
115
#include "attribute.h"
126
116
#include "resource.h"
127
 
#include "job.h"
 
117
#include "pbs_job.h"
128
118
#include "log.h"
129
119
#include "mom_mach.h"
130
120
#include "mom_func.h"
169
159
extern char extra_parm[];
170
160
extern char no_parm[];
171
161
 
172
 
extern struct pbs_err_to_txt pbs_err_to_txt[];
173
162
extern time_t   time_now;
174
163
 
175
164
extern  int     LOGLEVEL;
176
 
extern  char    checkpoint_script_name[1024];
177
 
extern  char    restart_script_name[1024];
178
165
extern  char    PBSNodeMsgBuf[1024];
179
166
 
180
167
#define TBL_INC 200            /* initial proc table */
186
173
/*
187
174
** external functions and data
188
175
*/
189
 
 
190
 
extern struct config  *search A_((struct config *, char *));
191
 
 
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;
198
 
extern  int     ignvmem;
 
179
extern double   cputfactor;
 
180
extern double   wallfactor;
 
181
extern long     system_ncpus;
 
182
extern int      ignwalltime;
 
183
extern int      igncput;
 
184
extern int      ignvmem;
 
185
extern int      ignmem;
199
186
 
200
187
/*
201
188
** local functions and data
202
189
*/
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 *));
 
198
 
 
199
#ifndef mbool_t
 
200
#define mbool_t char
 
201
#endif /* mbool_t */
 
202
 
 
203
mbool_t ProcIsChild(char *,char *,char *);
211
204
 
212
205
extern char *loadave A_((struct rm_attribute *));
213
206
extern char *nullproc A_((struct rm_attribute *));
389
382
 
390
383
  lastbracket++;
391
384
 
392
 
  if (sscanf(readbuf, "%d (%[^\n]", &ps.pid, path) != 2)
 
385
  if (sscanf(readbuf,"%d (%[^\n]",&ps.pid,path) != 2) 
393
386
    {
394
387
    /* FAILURE */
395
388
 
399
392
    }
400
393
 
401
394
  /* see stat_str[] value for mapping 'stat' format */
402
 
  if (sscanf(lastbracket, stat_str,
403
 
             &ps.state,     /* state (one of RSDZTW) */
404
 
             &ps.ppid,      /* ppid */
405
 
             &ps.pgrp,      /* pgrp */
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 */
 
395
 
 
396
  if (sscanf(lastbracket,stat_str, 
 
397
        &ps.state,     /* state (one of RSDZTW) */
 
398
        &ps.ppid,      /* ppid */
 
399
        &ps.pgrp,      /* pgrp */
 
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 */
415
409
    {
416
410
    /* FAILURE */
417
411
 
449
443
 
450
444
 
451
445
 
452
 
proc_mem_t *
453
 
get_proc_mem(void)
 
446
 
 
447
proc_mem_t *get_proc_mem(void)
454
448
 
455
449
  {
456
450
  static proc_mem_t   mm;
458
452
  char                str[32];
459
453
  unsigned long long  bfsz, casz;
460
454
 
461
 
  if ((fp = fopen("/proc/meminfo", "r")) == NULL)
462
 
    {
463
 
    return(NULL);
464
 
    }
465
 
 
466
 
  if (fscanf(fp, "%30s", str) != 1)
467
 
    {
468
 
    return(NULL);
469
 
    }
470
 
 
471
 
  if (!strncmp(str, "total:", sizeof(str)))
 
455
  if ((fp = fopen("/proc/meminfo","r")) == NULL)
 
456
    {
 
457
    return(NULL);
 
458
    }
 
459
 
 
460
  if (fscanf(fp,"%30s",str) != 1)
 
461
    {
 
462
    return(NULL);
 
463
    }
 
464
 
 
465
  if (!strncmp(str,"total:",sizeof(str)))
472
466
    {
473
467
    /* old format */
474
468
 
475
 
    if (fscanf(fp, "%*[^\n]%*c") != 0)     /* remove text header */
 
469
    if (fscanf(fp,"%*[^\n]%*c") != 0)     /* remove text header */
476
470
      {
477
471
      return(NULL);
478
472
      }
628
622
 
629
623
 
630
624
 
631
 
void
632
 
dep_initialize(void)
 
625
void dep_initialize(void)
633
626
 
634
627
  {
635
628
  char *id = "dep_initialize";
981
974
 
982
975
 
983
976
 
 
977
 
984
978
/*
985
979
 * Internal session workingset size function.
986
980
 */
1078
1072
  int   value)
1079
1073
 
1080
1074
  {
1081
 
  int  i = 0;
1082
1075
  char  *message;
1083
1076
 
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);
1089
 
 
1090
 
  do
1091
 
    {
1092
 
    if (pbs_err_to_txt[i].err_no == value)
1093
 
      break;
1094
 
    }
1095
 
  while (pbs_err_to_txt[++i].err_no != 0);
1096
 
 
1097
 
  assert(pbs_err_to_txt[i].err_txt != NULL);
1098
 
 
1099
 
  message = *pbs_err_to_txt[i].err_txt;
 
1079
 
 
1080
  message = pbse_to_txt(value);
1100
1081
 
1101
1082
  assert(message != NULL);
1102
 
 
1103
1083
  assert(*message != '\0');
1104
1084
 
1105
1085
  fprintf(stderr, msg_momsetlim, string, message);
1204
1184
 
1205
1185
    if (!strcmp(pname, "cput"))
1206
1186
      {
1207
 
      /* cpu time - check, if less than pcput use it */
1208
 
 
1209
 
      retval = gettime(pres, &value);
1210
 
 
1211
 
      if (retval != PBSE_NONE)
 
1187
      if (igncput == FALSE)
1212
1188
        {
1213
 
        sprintf(log_buffer, "cput gettime failed in %s",
1214
 
                id);
1215
 
 
1216
 
        return(error(pname, retval));
 
1189
        /* cpu time - check, if less than pcput use it */
 
1190
 
 
1191
        retval = gettime(pres, &value);
 
1192
 
 
1193
        if (retval != PBSE_NONE)
 
1194
          {
 
1195
          sprintf(log_buffer, "cput gettime failed in %s",id);
 
1196
 
 
1197
          return(error(pname, retval));
 
1198
          }
1217
1199
        }
1218
1200
      }
1219
1201
    else if (!strcmp(pname, "pcput"))
1220
1202
      {
1221
 
      if (set_mode == SET_LIMIT_SET)
 
1203
      if (igncput == FALSE)
1222
1204
        {
1223
 
        /* process cpu time - set */
1224
 
 
1225
 
        retval = gettime(pres, &value);
1226
 
 
1227
 
        if (retval != PBSE_NONE)
1228
 
          {
1229
 
          sprintf(log_buffer, "pcput gettime failed in %s",
1230
 
                  id);
1231
 
 
1232
 
          return(error(pname, retval));
1233
 
          }
1234
 
 
1235
 
        reslim.rlim_cur = reslim.rlim_max = (unsigned long)((double)value / cputfactor);
1236
 
 
1237
 
        if (LOGLEVEL >= 2)
1238
 
          {
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);
1242
 
 
1243
 
          log_record(PBSEVENT_SYSTEM, 0, id, log_buffer);
1244
 
 
1245
 
          log_buffer[0] = '\0';
1246
 
          }
1247
 
 
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 */
1250
 
 
1251
 
        if (setrlimit(RLIMIT_CPU, &reslim) < 0)
1252
 
          {
1253
 
          sprintf(log_buffer, "setrlimit for RLIMIT_CPU failed in %s, errno=%d (%s)",
1254
 
                  id,
1255
 
                  errno, strerror(errno));
1256
 
 
1257
 
          return(error("RLIMIT_CPU", PBSE_SYSTEM));
1258
 
          }
1259
 
        }    /* END if (set_mode == SET_LIMIT_SET) */
 
1205
        if (set_mode == SET_LIMIT_SET)
 
1206
          {
 
1207
          /* process cpu time - set */
 
1208
 
 
1209
          retval = gettime(pres, &value);
 
1210
 
 
1211
          if (retval != PBSE_NONE)
 
1212
            {
 
1213
            sprintf(log_buffer, "pcput gettime failed in %s",id);
 
1214
 
 
1215
            return(error(pname, retval));
 
1216
            }
 
1217
 
 
1218
          reslim.rlim_cur = reslim.rlim_max =
 
1219
            (unsigned long)((double)value / cputfactor);
 
1220
 
 
1221
          if (LOGLEVEL >= 2)
 
1222
            {
 
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);
 
1226
 
 
1227
            log_record(PBSEVENT_SYSTEM, 0, id, log_buffer);
 
1228
 
 
1229
            log_buffer[0] = '\0';
 
1230
            }
 
1231
 
 
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 */
 
1234
 
 
1235
          if (setrlimit(RLIMIT_CPU, &reslim) < 0)
 
1236
            {
 
1237
            sprintf(log_buffer, "setrlimit for RLIMIT_CPU failed in %s, errno=%d (%s)",
 
1238
              id,
 
1239
              errno, strerror(errno));
 
1240
 
 
1241
            return(error("RLIMIT_CPU", PBSE_SYSTEM));
 
1242
            }
 
1243
          }    /* END if (set_mode == SET_LIMIT_SET) */
 
1244
        }
1260
1245
      }
1261
1246
    else if (!strcmp(pname, "file"))
1262
1247
      {
1308
1293
      }
1309
1294
    else if (!strcmp(pname, "vmem"))
1310
1295
      {
1311
 
      /* check */
1312
 
 
1313
 
      retval = getsize(pres, &value);
1314
 
 
1315
 
      if (retval != PBSE_NONE)
1316
 
        {
1317
 
        sprintf(log_buffer, "getsize() failed for vmem in %s",
1318
 
                id);
1319
 
 
1320
 
        return(error(pname, retval));
1321
 
        }
1322
 
 
1323
 
      if ((vmem_limit == 0) || (value < vmem_limit))
1324
 
        vmem_limit = value;
1325
 
      }
1326
 
    else if (!strcmp(pname, "pvmem"))
1327
 
      {
1328
 
      /* set */
1329
 
 
1330
 
      if (set_mode == SET_LIMIT_SET)
1331
 
        {
 
1296
      if (ignvmem == FALSE)
 
1297
        {
 
1298
        /* check */
 
1299
 
1332
1300
        retval = getsize(pres, &value);
1333
1301
 
1334
1302
        if (retval != PBSE_NONE)
1335
1303
          {
1336
 
          sprintf(log_buffer, "getsize() failed for pvmem in %s",
1337
 
                  id);
 
1304
          sprintf(log_buffer, "getsize() failed for vmem in %s",id);
1338
1305
 
1339
1306
          return(error(pname, retval));
1340
1307
          }
1341
1308
 
1342
 
        if (value > ULONG_MAX)
1343
 
          {
1344
 
          log_buffer[0] = '\0';
1345
 
 
1346
 
          sprintf(log_buffer, "invalid value returned by getsize() for pvmem in %s",
1347
 
                  id);
1348
 
 
1349
 
          return(error(pname, PBSE_BADATVAL));
1350
 
          }
1351
 
 
1352
1309
        if ((vmem_limit == 0) || (value < vmem_limit))
1353
1310
          vmem_limit = value;
1354
1311
        }
1355
1312
      }
1356
 
    else if ((!strcmp(pname, "mem") && (pjob->ji_numnodes != 1)) ||
1357
 
             !strcmp(pname, "mppmem"))
 
1313
    else if (!strcmp(pname, "pvmem"))
 
1314
      {
 
1315
      if (ignvmem == FALSE)
 
1316
        {
 
1317
        /* set */
 
1318
 
 
1319
        if (set_mode == SET_LIMIT_SET)
 
1320
          {
 
1321
          retval = getsize(pres, &value);
 
1322
 
 
1323
          if (retval != PBSE_NONE)
 
1324
            {
 
1325
            sprintf(log_buffer, "getsize() failed for pvmem in %s",
 
1326
              id);
 
1327
 
 
1328
            return(error(pname, retval));
 
1329
            }
 
1330
 
 
1331
          if (value > ULONG_MAX)
 
1332
            {
 
1333
            log_buffer[0] = '\0';
 
1334
 
 
1335
            sprintf(log_buffer, "invalid value returned by getsize() for pvmem in %s",
 
1336
              id);
 
1337
 
 
1338
            return(error(pname, PBSE_BADATVAL));
 
1339
            }
 
1340
 
 
1341
          if ((vmem_limit == 0) || (value < vmem_limit))
 
1342
            vmem_limit = value;
 
1343
          }
 
1344
        }
 
1345
      }
 
1346
    else if ((!strcmp(pname,"mem") && (pjob->ji_numnodes != 1)) ||
 
1347
              !strcmp(pname,"mppmem"))
1358
1348
      {
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"))
1364
1354
      {
1365
 
      /* set */
1366
 
 
1367
 
      if (set_mode == SET_LIMIT_SET)
 
1355
      if (ignmem == FALSE)
1368
1356
        {
1369
 
        retval = getsize(pres, &value);
1370
 
 
1371
 
        if (retval != PBSE_NONE)
1372
 
          {
1373
 
          sprintf(log_buffer, "getsize() failed for mem/pmem in %s",
1374
 
                  id);
1375
 
 
1376
 
          return(error(pname, retval));
1377
 
          }
1378
 
 
1379
 
        reslim.rlim_cur = reslim.rlim_max = value;
1380
 
 
1381
 
        if (setrlimit(RLIMIT_DATA, &reslim) < 0)
1382
 
          {
1383
 
          sprintf(log_buffer, "cannot set data limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1384
 
                  reslim.rlim_max,
1385
 
                  pjob->ji_qs.ji_jobid,
1386
 
                  errno,
1387
 
                  strerror(errno));
1388
 
 
1389
 
          return(error("RLIMIT_DATA", PBSE_SYSTEM));
1390
 
          }
1391
 
 
1392
 
        if (setrlimit(RLIMIT_RSS, &reslim) < 0)
1393
 
          {
1394
 
          sprintf(log_buffer, "cannot set RSS limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1395
 
                  reslim.rlim_max,
1396
 
                  pjob->ji_qs.ji_jobid,
1397
 
                  errno,
1398
 
                  strerror(errno));
1399
 
 
1400
 
          return(error("RLIMIT_RSS", PBSE_SYSTEM));
1401
 
          }
 
1357
        /* set */
 
1358
 
 
1359
        if (set_mode == SET_LIMIT_SET)
 
1360
          {
 
1361
          retval = getsize(pres, &value);
 
1362
 
 
1363
          if (retval != PBSE_NONE)
 
1364
            {
 
1365
            sprintf(log_buffer, "getsize() failed for mem/pmem in %s",
 
1366
              id);
 
1367
 
 
1368
            return(error(pname, retval));
 
1369
            }
 
1370
 
 
1371
          reslim.rlim_cur = reslim.rlim_max = value;
 
1372
 
 
1373
          if (setrlimit(RLIMIT_DATA, &reslim) < 0)
 
1374
            {
 
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,
 
1378
              errno,
 
1379
              strerror(errno));
 
1380
 
 
1381
            return(error("RLIMIT_DATA", PBSE_SYSTEM));
 
1382
            }
 
1383
 
 
1384
          if (setrlimit(RLIMIT_RSS, &reslim) < 0)
 
1385
            {
 
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,
 
1389
              errno,
 
1390
              strerror(errno));
 
1391
 
 
1392
            return(error("RLIMIT_RSS", PBSE_SYSTEM));
 
1393
            }
1402
1394
 
1403
1395
#ifdef __GATECH
1404
 
        /* NOTE:  best patch may be to change to 'vmem_limit = value;' */
1405
 
 
1406
 
        if (setrlimit(RLIMIT_STACK, &reslim) < 0)
1407
 
          {
1408
 
          sprintf(log_buffer, "cannot set stack limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1409
 
                  reslim.rlim_max,
1410
 
                  pjob->ji_qs.ji_jobid,
1411
 
                  errno,
1412
 
                  strerror(errno));
1413
 
 
1414
 
          return(error("RLIMIT_STACK", PBSE_SYSTEM));
1415
 
          }
1416
 
 
1417
 
        /* set address space */
1418
 
 
1419
 
        if (setrlimit(RLIMIT_AS, &reslim) < 0)
1420
 
          {
1421
 
          sprintf(log_buffer, "cannot set AS limit to %ld for job %s (setrlimit failed w/errno=%d (%s) - check default user limits)",
1422
 
                  reslim.rlim_max,
1423
 
                  pjob->ji_qs.ji_jobid,
1424
 
                  errno,
1425
 
                  strerror(errno));
1426
 
 
1427
 
          return(error("RLIMIT_AS", PBSE_SYSTEM));
1428
 
          }
 
1396
          /* NOTE:  best patch may be to change to 'vmem_limit = value;' */
 
1397
 
 
1398
          if (setrlimit(RLIMIT_STACK, &reslim) < 0)
 
1399
            {
 
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,
 
1403
              errno,
 
1404
              strerror(errno));
 
1405
 
 
1406
            return(error("RLIMIT_STACK", PBSE_SYSTEM));
 
1407
            }
 
1408
 
 
1409
          /* set address space */
 
1410
 
 
1411
          if (setrlimit(RLIMIT_AS, &reslim) < 0)
 
1412
            {
 
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,
 
1416
              errno,
 
1417
              strerror(errno));
 
1418
 
 
1419
            return(error("RLIMIT_AS", PBSE_SYSTEM));
 
1420
            }
1429
1421
 
1430
1422
#endif /* __GATECH */
1431
1423
 
1432
 
        mem_limit = value;
1433
 
 
1434
 
        if (getrlimit(RLIMIT_STACK, &reslim) >= 0)
1435
 
          {
1436
 
          /* NOTE:  mem_limit no longer used with UMU patch in place */
1437
 
 
1438
 
          mem_limit = value + reslim.rlim_cur;
 
1424
          mem_limit = value;
 
1425
  
 
1426
          if (getrlimit(RLIMIT_STACK, &reslim) >= 0)
 
1427
            {
 
1428
            /* NOTE:  mem_limit no longer used with UMU patch in place */
 
1429
 
 
1430
            mem_limit = value + reslim.rlim_cur;
 
1431
            }
1439
1432
          }
1440
1433
        }
1441
1434
      }    /* END else if (!strcmp(pname,"mem") && ... */
1478
1471
 
1479
1472
      /* NO-OP */
1480
1473
      }
 
1474
    else if(!strcmp(pname, "prologue"))
 
1475
      {
 
1476
      }
 
1477
    else if(!strcmp(pname, "epilogue"))
 
1478
      {
 
1479
      }
1481
1480
    else if ((pres->rs_defin->rs_flags & ATR_DFLAG_RMOMIG) == 0)
1482
1481
      {
1483
1482
      /* don't recognize and not marked as ignore by mom */
1658
1657
 
1659
1658
 
1660
1659
 
1661
 
 
1662
1660
/*
1663
1661
 * Declare start of polling loop.
1664
1662
 *
1672
1670
 * This function is called from the main MOM loop once every "check_poll_interval"
1673
1671
 * seconds.
1674
1672
 *
1675
 
 * @see get_proc_stat()
 
1673
 * @see get_proc_stat() - child
1676
1674
 * @see mom_set_use() - Aggregates data collected here
1677
1675
 *
1678
1676
 * NOTE:  populates global 'proc_array[]' variable.
1807
1805
    assert(pname != NULL);
1808
1806
    assert(*pname != '\0');
1809
1807
 
1810
 
    if (strcmp(pname, "cput") == 0)
 
1808
    if ((igncput == FALSE) && (strcmp(pname, "cput") == 0))
1811
1809
      {
1812
1810
      retval = gettime(pres, &value);
1813
1811
 
1823
1821
        return(TRUE);
1824
1822
        }
1825
1823
      }
1826
 
    else if (strcmp(pname, "pcput") == 0)
 
1824
    else if ((igncput == FALSE) && (strcmp(pname, "pcput") == 0))
1827
1825
      {
1828
1826
      retval = gettime(pres, &value);
1829
1827
 
1873
1871
        return(TRUE);
1874
1872
        }
1875
1873
      }
1876
 
    else if (strcmp(pname, "walltime") == 0)
 
1874
    else if (ignwalltime == 0 && strcmp(pname, "walltime") == 0)
1877
1875
      {
 
1876
 
1878
1877
      /* no need to check walltime on sisters, MS will get it */
1879
 
 
1880
1878
      if ((pjob->ji_qs.ji_svrflags & JOB_SVFLG_HERE) == 0)
1881
1879
        continue;
1882
1880
 
1894
1892
                num,
1895
1893
                value);
1896
1894
 
1897
 
        if (ignwalltime == 0)
1898
 
          {
1899
 
          return(TRUE);
1900
 
          }
 
1895
        return(TRUE);
1901
1896
        }
1902
1897
      }
1903
1898
    }  /* END for (pres) */
1921
1916
 * stats gathered by the mom_get_sample() function. This function
1922
1917
 * is often called by "im_request()" as a result of POLL_JOB query
1923
1918
 * from the mother superior.
1924
 
 *
1925
 
 * @return An error code if something goes wrong.
1926
 
 *
 
1919
 * 
1927
1920
 * @see im_request() - parent - respond to poll_job request from mother superior
1928
1921
 * @see examine_all_running_jobs() - parent - update local use on mother superior
1929
1922
 * @see TMomFinalizeJob1() - parent - update serial job immediately at job start
 
1923
 *
 
1924
 * @return An error code if something goes wrong.
1930
1925
 */
1931
1926
 
1932
1927
int mom_set_use(
1943
1938
  at = &pjob->ji_wattr[(int)JOB_ATR_resc_used];
1944
1939
  assert(at->at_type == ATR_TYPE_RESC);
1945
1940
 
 
1941
#ifdef USESAVEDRESOURCES
 
1942
  /* don't update jobs that are marked as recovery */
 
1943
  if (pjob->ji_flags & MOM_JOB_RECOVERY)
 
1944
    {
 
1945
    return(PBSE_NONE);
 
1946
    }
 
1947
#endif    /* USESAVEDRESOURCES */
 
1948
 
1946
1949
  at->at_flags |= ATR_VFLAG_MODIFY;
1947
1950
 
1948
1951
  if ((at->at_flags & ATR_VFLAG_SET) == 0)
2033
2036
  assert(pres != NULL);
2034
2037
 
2035
2038
  /* NOTE: starting jobs can come through here before stime is recorded */
2036
 
 
2037
2039
  if (pjob->ji_qs.ji_stime == 0)
2038
2040
    pres->rs_value.at_val.at_long = 0;
2039
2041
  else
2063
2065
 
2064
2066
 
2065
2067
 
2066
 
/*
 
2068
/**
2067
2069
 * Kill a task session.
2068
2070
 * Call with the task pointer and a signal number.
2069
 
 *   return number of tasks signalled (0 = failure)
 
2071
 *
 
2072
 * @return number of tasks signalled (0 = failure) 
 
2073
 *
 
2074
 * @see kill_job() - parent
 
2075
 *
 
2076
 * NOTE:  should support killpg() or killpidtree() - (NYI)
 
2077
 *        may be required for suspend/resume 
2070
2078
 */
2071
2079
 
2072
 
/* NOTE:  should support killpg() or killpidtree() (NYI)
2073
 
          may be required for suspend resume */
2074
 
 
2075
2080
int kill_task(
2076
2081
 
2077
2082
  task *ptask,  /* I */
2085
2090
  int            NumProcessesFound = 0; /* number of processes found with session ID */
2086
2091
 
2087
2092
  struct dirent *dent;
2088
 
  proc_stat_t *ps;
 
2093
  proc_stat_t   *ps;
2089
2094
  int            sesid;
2090
2095
  pid_t          mompid;
2091
2096
 
2095
2100
  if (LOGLEVEL >= 5)
2096
2101
    {
2097
2102
    sprintf(log_buffer, "%s: sending signal %d to task %d, session %d",
2098
 
            id,
2099
 
            sig,
2100
 
            ptask->ti_qs.ti_task,
2101
 
            sesid);
 
2103
      id,
 
2104
      sig,
 
2105
      ptask->ti_qs.ti_task,
 
2106
      sesid);
2102
2107
 
2103
2108
    log_record(
2104
2109
      PBSEVENT_JOB,
2112
2117
    if (LOGLEVEL >= 3)
2113
2118
      {
2114
2119
      sprintf(log_buffer, "cannot send signal %d to task (no session id)",
2115
 
              sig);
 
2120
        sig);
2116
2121
 
2117
2122
      log_record(
2118
2123
        PBSEVENT_ERROR,
2146
2151
        sprintf(log_buffer, "%s: get_proc_stat",
2147
2152
                dent->d_name);
2148
2153
 
2149
 
        log_err(errno, id, log_buffer);
 
2154
        log_err(errno,id,log_buffer);
2150
2155
        }
2151
2156
 
2152
2157
      continue;
2153
2158
      }
2154
2159
 
2155
 
    if (sesid == ps->session)
 
2160
    if ((sesid == ps->session) ||
 
2161
        (ProcIsChild(procfs,dent->d_name,ptask->ti_job->ji_qs.ji_jobid) == TRUE))
 
2162
 
2156
2163
      {
2157
2164
      NumProcessesFound++;
2158
2165
 
2201
2208
              log_buffer);
2202
2209
            }
2203
2210
 
 
2211
          if (LOGLEVEL >= 3)
 
2212
            {
 
2213
            sprintf(log_buffer, "%s: not killing process %d. Avoid sending signal because child task still has MOM's session id", id, ps->pid);
 
2214
 
 
2215
            log_record(
 
2216
              PBSEVENT_JOB,
 
2217
              PBS_EVENTCLASS_JOB,
 
2218
              ptask->ti_job->ji_qs.ji_jobid,
 
2219
              log_buffer);
 
2220
            }
 
2221
 
2204
2222
          continue;
2205
2223
          }  /* END if (ps->pid == mompid) */
2206
2224
 
2211
2229
          req.tv_sec = 0;
2212
2230
          req.tv_nsec = 250000000;  /* .25 seconds */
2213
2231
 
2214
 
          /* give the process some time to quit gracefully first (up to 5 seconds) */
 
2232
          /* give the process some time to quit gracefully first (up to .25*20=5 seconds) */
2215
2233
 
2216
2234
          sprintf(log_buffer, "%s: killing pid %d task %d gracefully with sig %d",
2217
2235
                  id,
2277
2295
              {
2278
2296
              /* kill process hard */
2279
2297
 
 
2298
              /* why is this not killing with SIGKILL? */
 
2299
 
2280
2300
              sprintf(log_buffer, "%s: killing pid %d task %d with sig %d",
2281
2301
                      id,
2282
2302
                      ps->pid,
2294
2314
              else
2295
2315
                killpg(ps->pid, sig);
2296
2316
              }
2297
 
            }
2298
 
          }    /* END if (i >= 20) */
 
2317
            }    /* END if ((ps = get_proc_stat(ps->pid)) != NULL) */
 
2318
          }      /* END if (i >= 20) */
2299
2319
 
2300
2320
        ++ct;
2301
2321
        }  /* END else ((ps->state == 'Z') || (ps->pid == 0)) */
2302
2322
      }    /* END if (sesid == ps->session) */
2303
2323
    }      /* END while ((dent = readdir(pdir)) != NULL) */
2304
2324
 
 
2325
  /* NOTE:  to fix bad state situations resulting from a hard crash, the logic
 
2326
            below should be triggered any time no processes are found (NYI) */ 
 
2327
            
2305
2328
  if (IS_ADOPTED_TASK(ptask->ti_qs.ti_task) && (NumProcessesFound == 0))
2306
2329
    {
2307
2330
    /* no process was found, but for an adopted task this is OK (we don't find
2311
2334
 
2312
2335
    ct++;
2313
2336
 
2314
 
    /* do code to mark task as finished (borrowed from Linux scan_for_terminating())... */
 
2337
    /* do code to mark task as finished (borrowed from Linux scan_for_terminated())... */
2315
2338
 
2316
2339
    ptask->ti_qs.ti_exitstat = 0;  /* assume successful completion */
2317
2340
    ptask->ti_qs.ti_status   = TI_STATE_EXITED;
2338
2361
 
2339
2362
    ct++;
2340
2363
 
2341
 
    /* do code to mark task as finished (borrowed from Linux scan_for_terminating())... */
 
2364
    /* do code to mark task as finished (borrowed from Linux scan_for_terminated())... */
2342
2365
 
2343
2366
    ptask->ti_qs.ti_exitstat = 0;  /* assume successful completion */
2344
2367
    ptask->ti_qs.ti_status   = TI_STATE_EXITED;
2412
2435
 
2413
2436
 
2414
2437
 
2415
 
 
2416
2438
/*
2417
 
 * mom_does_chkpnt - return 1 if mom supports checkpoint
2418
 
 *       0 if not
 
2439
 * mom_does_checkpoint
 
2440
 *
 
2441
 * @returns CST values as described in resmon.h.
2419
2442
 */
2420
2443
 
2421
2444
int
2422
 
mom_does_chkpnt(void)
2423
 
 
 
2445
mom_does_checkpoint(void)
2424
2446
  {
2425
 
  if (checkpoint_script_name[0] != '\0')
2426
 
    {
2427
 
    return(1);
2428
 
    }
2429
 
 
2430
 
  return(0);
 
2447
  return(CST_BLCR); /* Use the BLCR checkpointing system. */
2431
2448
  }
2432
2449
 
2433
2450
/*
2438
2455
 
2439
2456
int mach_checkpoint(
2440
2457
 
2441
 
  task *ptask,
2442
 
  char *file,
 
2458
  task *ptask,  /* I */
 
2459
  char *file,  /* I */
2443
2460
  int  abort)  /* I */
2444
2461
 
2445
2462
  {
2446
 
  char *id = "mach_checkpoint";
2447
 
  int   pid;
2448
 
  char  sid[20];
2449
 
  char  *arg[20];
2450
 
  char  buf[1024];
2451
 
  char  **ap;
2452
 
 
2453
 
#define SET_ARG(x) (((x) == NULL) || (*(x) == 0))?"-":(x)
2454
 
 
2455
 
  /* if a checkpoint script is defined launch it */
2456
 
 
2457
 
  if (checkpoint_script_name[0] == '\0')
2458
 
    {
2459
 
    log_err(-1, id, "No checkpoint script defined");
2460
 
    }
2461
 
  else
2462
 
    {
2463
 
    /* launch the script and return success */
2464
 
 
2465
 
    pid = fork();
2466
 
 
2467
 
    if (pid > 0)
2468
 
      {
2469
 
      /* parent: pid = child's pid */
2470
 
 
2471
 
      /* NO-OP, but may need to waitpid() the child (NYI) */
2472
 
 
2473
 
      return(0);
2474
 
      }
2475
 
    else if (pid == 0)
2476
 
      {
2477
 
      /* child: execv the script */
2478
 
 
2479
 
      sprintf(sid, "%ld",
2480
 
              ptask->ti_job->ji_wattr[(int)JOB_ATR_session_id].at_val.at_long);
2481
 
 
2482
 
      arg[0] = checkpoint_script_name;
2483
 
      arg[1] = sid;
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*/;
2489
 
      arg[7] = NULL;
2490
 
 
2491
 
      strcpy(buf, "checkpoint args:");
2492
 
 
2493
 
      for (ap = arg; *ap; ap++)
2494
 
        {
2495
 
        strcat(buf, " ");
2496
 
        strcat(buf, *ap);
2497
 
        }
2498
 
 
2499
 
      log_err(-1, id, buf);
2500
 
 
2501
 
      execv(arg[0], arg);
2502
 
 
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
2507
 
       */
2508
 
      }  /* END if (pid == 0) */
2509
 
    }
2510
 
 
2511
2463
  return(-1);
2512
2464
  }  /* END mach_checkpoint() */
2513
2465
 
2527
2479
  char *file)
2528
2480
 
2529
2481
  {
2530
 
  char *id = "mach_restart";
2531
 
  int   pid;
2532
 
  char  sid[20];
2533
 
  char  *arg[20];
2534
 
 
2535
 
 
2536
 
  /* if a restart script is defined launch it */
2537
 
 
2538
 
  if (restart_script_name[0] == '\0')
2539
 
    {
2540
 
    log_record(PBSEVENT_DEBUG, 0, id, "No restart script defined");
2541
 
    }
2542
 
  else
2543
 
    {
2544
 
    /* launch the script and return success */
2545
 
 
2546
 
    pid = fork();
2547
 
 
2548
 
    if (pid > 0)
2549
 
      {
2550
 
      /* parent: pid = child's pid */
2551
 
 
2552
 
      /* NO-OP, but may need to waitpid() the child (NYI) */
2553
 
 
2554
 
      return(0);
2555
 
      }
2556
 
 
2557
 
    if (pid == 0)
2558
 
      {
2559
 
      /* child: execv the script */
2560
 
 
2561
 
      sprintf(sid, "%ld",
2562
 
              ptask->ti_job->ji_wattr[(int)JOB_ATR_session_id].at_val.at_long);
2563
 
 
2564
 
      arg[0] = restart_script_name;
2565
 
      arg[1] = sid;
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;
2568
 
      arg[4] = NULL;
2569
 
 
2570
 
      execv(arg[0], arg);
2571
 
 
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
2576
 
       */
2577
 
      }  /* END if (pid == 0) */
2578
 
    }
2579
 
 
2580
 
 
2581
2482
  return(-1);
2582
2483
  }
2583
2484
 
2643
2544
    }
2644
2545
 
2645
2546
  sprintf(ret_string, "%.2f",
2646
 
    cputime * cputfactor);
 
2547
 
 
2548
          cputime * cputfactor);
2647
2549
 
2648
2550
  return(ret_string);
2649
2551
  }  /* END cput_job() */
2944
2846
  pid_t pid)
2945
2847
 
2946
2848
  {
2947
 
  char  *id = "resi_proc";
 
2849
  char        *id = "resi_proc";
2948
2850
  proc_stat_t *ps;
2949
2851
 
2950
2852
  if ((ps = get_proc_stat(pid)) == NULL)
3074
2976
    if ((jobid = ps->session) == 0)
3075
2977
      continue;
3076
2978
 
3077
 
    if (LOGLEVEL >= 6)
 
2979
    if (LOGLEVEL >= 7)
3078
2980
      {
3079
2981
      sprintf(log_buffer, "%s[%d]: pid %d sid %d",
3080
2982
              id,
3320
3222
    if ((uid = ps->uid) == 0)
3321
3223
      continue;
3322
3224
 
3323
 
    if (LOGLEVEL >= 6)
 
3225
    if (LOGLEVEL >= 7)
3324
3226
      {
3325
3227
      sprintf(log_buffer, "%s[%d]: pid %d uid %d",
3326
3228
              id,
3746
3648
 
3747
3649
 
3748
3650
 
3749
 
 
3750
 
 
3751
3651
/*
3752
3652
 * For a recovering (-p) mom, look through existing tasks in existing
3753
3653
 * jobs for things that have exited that are not owned by us through a
3762
3662
 
3763
3663
  job *job;
3764
3664
  extern tlist_head svr_alljobs;
 
3665
  static int first_time = TRUE;
3765
3666
 
3766
3667
  DIR *pdir;  /* use local pdir to prevent race conditions associated w/global pdir (VPAC) */
3767
3668
 
3777
3678
      struct dirent *dent;
3778
3679
      int found;
3779
3680
 
 
3681
      /*
 
3682
       * Check for tasks that were exiting when mom went down, set back to
 
3683
       * running so we can reprocess them and send the obit
 
3684
       */
 
3685
      if ((first_time) && (task->ti_qs.ti_sid != 0) &&
 
3686
         ((task->ti_qs.ti_status == TI_STATE_EXITED) ||
 
3687
         (task->ti_qs.ti_status == TI_STATE_DEAD)))
 
3688
        {
 
3689
 
 
3690
        if (LOGLEVEL >= 7)
 
3691
          {
 
3692
          sprintf(log_buffer, "marking task %d as TI_STATE_RUNNING was %d",
 
3693
              task->ti_qs.ti_task,
 
3694
              task->ti_qs.ti_status);
 
3695
 
 
3696
          LOG_EVENT(
 
3697
            PBSEVENT_DEBUG,
 
3698
            PBS_EVENTCLASS_JOB,
 
3699
            job->ji_qs.ji_jobid,
 
3700
            log_buffer);
 
3701
          }
 
3702
        task->ti_qs.ti_status = TI_STATE_RUNNING;
 
3703
        }
 
3704
 
3780
3705
      /* only check on tasks that we think should still be around */
3781
3706
 
3782
3707
      if (task->ti_qs.ti_status != TI_STATE_RUNNING)
3841
3766
 
3842
3767
        task_save(task);
3843
3768
 
 
3769
#ifdef USESAVEDRESOURCES
 
3770
        if (first_time)
 
3771
          {
 
3772
          job->ji_flags |= MOM_JOB_RECOVERY;
 
3773
          if (LOGLEVEL >= 7)
 
3774
            {
 
3775
            sprintf(buf, "marking job as MOM_JOB_RECOVERY for task %d",
 
3776
                task->ti_qs.ti_task);
 
3777
 
 
3778
            LOG_EVENT(
 
3779
              PBSEVENT_DEBUG,
 
3780
              PBS_EVENTCLASS_JOB,
 
3781
              job->ji_qs.ji_jobid,
 
3782
              buf);
 
3783
            }
 
3784
          }
 
3785
#endif    /* USESAVEDRESOURCES */
 
3786
 
3844
3787
        exiting_tasks = 1;
3845
3788
        }
3846
3789
      }
3847
3790
    }    /* END for (job = GET_NEXT(svr_alljobs)) */
3848
3791
 
3849
3792
  closedir(pdir);
 
3793
  
 
3794
  first_time = FALSE;
3850
3795
 
3851
3796
  return;
3852
3797
  }  /* END scan_non_child_tasks() */
4468
4413
      /*
4469
4414
      if (strncmp(interfaceName[interface],"eth",3) == 0)
4470
4415
        {
4471
 
          rc = sscanf(interfaceName[interface],"eth%d",
4472
 
            &ethNum);
 
4416
        rc = sscanf(interfaceName[interface],"eth%d",
 
4417
          &ethNum);
4473
4418
        }
4474
4419
      */
4475
4420
 
4490
4435
  return(ret_string);
4491
4436
  }  /* END netload() */
4492
4437
 
 
4438
 
 
4439
 
 
4440
 
 
4441
 
 
4442
mbool_t ProcIsChild(
 
4443
 
 
4444
  char *Dir,    /* I */
 
4445
  char *PID,    /* I */
 
4446
  char *JobID)  /* I */
 
4447
 
 
4448
  {
 
4449
  return(FALSE);
 
4450
  }  /* END ProcIsChild() */
 
4451
 
4493
4452
/* END mom_mach.c */
4494
4453
 
4495
4454