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

« back to all changes in this revision

Viewing changes to src/server/svr_jobfunc.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:
89
89
 * job_set_wait()     - set event for when job's wait time ends
90
90
 * get_variable()     - get value of a single environ variable of a job
91
91
 * prefix_std_file()  - build the fully prefixed default name for std e/o
92
 
 * add_std_filename() - add the default name for std e/o
93
92
 * get_jobowner()     - get job owner name without @host suffix
94
93
 * set_resc_deflt()   - set unspecified resource_limit to default values
95
94
 * set_statechar()    - set the job state attribute character value
96
95
 *
97
96
 * Private functions
98
97
 * chk_svr_resc_limit() - check job requirements againt queue/server limits
99
 
 * default_std()    - make the default name for standard out/error
100
 
 * eval_chkpnt()    - insure job checkpoint .ge. queues min. time
 
98
 * default_std()      - make the default name for standard out/error
 
99
 * eval_checkpoint()  - insure job checkpoint .ge. queues min. time
101
100
 * set_deflt_resc()   - set unspecified resource_limit to default values
102
101
 * job_wait_over()    - event handler for job_set_wait()
103
102
 */
119
118
#include "resource.h"
120
119
#include "server.h"
121
120
#include "queue.h"
122
 
#include "job.h"
 
121
#include "pbs_job.h"
123
122
#include "work_task.h"
124
123
#include "pbs_error.h"
125
124
#include "log.h"
132
131
/* Private Functions */
133
132
 
134
133
static void default_std A_((job *, int key, char * to));
135
 
static void eval_chkpnt A_((attribute *j, attribute *q));
 
134
static void eval_checkpoint A_((attribute *j, attribute *q));
136
135
 
137
136
/* Global Data Items: */
138
137
 
250
249
  "RERUN1",                 /* job is rerun, stageout phase */
251
250
  "RERUN2",                 /* job is rerun, delete files stage */
252
251
  "RERUN3",                 /* job is rerun, mom delete job */
 
252
  "SUBSTATE64",
 
253
  "SUBSTATE65",
 
254
  "SUBSTATE66",
 
255
  "SUBSTATE67",
 
256
  "SUBSTATE68",
 
257
  "SUBSTATE69",
 
258
  "RETURNSTD",             /* returning stderr/stdout files to server spool */
253
259
  NULL
254
260
  };
255
261
 
285
291
  /* add job to server's 'all job' list and update server counts */
286
292
 
287
293
#ifndef NDEBUG
288
 
  sprintf(log_buffer,"enqueuing into %s, state %x hop %ld",
 
294
  sprintf(log_buffer, "enqueuing into %s, state %x hop %ld",
289
295
    pque->qu_qs.qu_name,
290
296
    pjob->ji_qs.ji_state,
291
297
    pjob->ji_wattr[(int)JOB_ATR_hopcount].at_val.at_long);
320
326
    /* link after 'current' job in server's list */
321
327
 
322
328
    insert_link(
323
 
      &pjcur->ji_alljobs, 
324
 
      &pjob->ji_alljobs, 
 
329
      &pjcur->ji_alljobs,
 
330
      &pjob->ji_alljobs,
325
331
      pjob,
326
332
      LINK_INSET_AFTER);
327
333
    }
349
355
    {
350
356
    /* link first in list */
351
357
 
352
 
    insert_link(&pque->qu_jobs,&pjob->ji_jobque,pjob,LINK_INSET_AFTER);
 
358
    insert_link(&pque->qu_jobs, &pjob->ji_jobque, pjob, LINK_INSET_AFTER);
353
359
    }
354
360
  else
355
361
    {
356
362
    /* link after 'current' job in list */
357
363
 
358
 
    insert_link(&pjcur->ji_jobque,&pjob->ji_jobque,pjob,LINK_INSET_AFTER);
 
364
    insert_link(&pjcur->ji_jobque, &pjob->ji_jobque, pjob, LINK_INSET_AFTER);
359
365
    }
360
366
 
361
367
  /* update counts: queue and queue by state */
386
392
 
387
393
    /* issue enqueued accounting record */
388
394
 
389
 
    sprintf(log_buffer,"queue=%s",
 
395
    sprintf(log_buffer, "queue=%s",
390
396
      pque->qu_qs.qu_name);
391
397
 
392
 
    account_record(PBS_ACCT_QUEUE,pjob,log_buffer);
 
398
    account_record(PBS_ACCT_QUEUE, pjob, log_buffer);
393
399
    }
394
400
 
395
401
  /*
397
403
   * first with queue defaults, then with server defaults
398
404
   */
399
405
 
400
 
  set_resc_deflt(pjob,NULL);
 
406
  set_resc_deflt(pjob, NULL);
401
407
 
402
408
  /* See if we need to do anything special based on type of queue */
403
409
 
414
420
 
415
421
    /* check the job checkpoint against the queue's min */
416
422
 
417
 
    eval_chkpnt(
418
 
      &pjob->ji_wattr[(int)JOB_ATR_chkpnt],
419
 
      &pque->qu_attr[(int)QE_ATR_ChkptMim]);
 
423
    eval_checkpoint(
 
424
      &pjob->ji_wattr[(int)JOB_ATR_checkpoint],
 
425
      &pque->qu_attr[(int)QE_ATR_checkpoint_min]);
420
426
 
421
427
    /* do anything needed doing regarding job dependencies */
422
428
 
438
444
      {
439
445
      pjob->ji_wattr[(int)JOB_ATR_etime].at_val.at_long = time_now;
440
446
      pjob->ji_wattr[(int)JOB_ATR_etime].at_flags |= ATR_VFLAG_SET;
441
 
 
442
 
      /* notify the scheduler we have a new job */
443
 
 
444
 
      svr_do_schedule = SCH_SCHEDULE_NEW;
445
447
      }
 
448
      
 
449
    /* notify the scheduler we have a new job */
 
450
    svr_do_schedule = SCH_SCHEDULE_NEW;
446
451
    }
447
452
  else if (pque->qu_qs.qu_type == QTYPE_RoutePush)
448
453
    {
767
772
 
768
773
 
769
774
/*
 
775
 * get_resource - find a resource (value) entry in the queue or server list
 
776
 *
 
777
 * Returns: pointer to struct resource or NULL
 
778
 */
 
779
 
 
780
resource *get_resource(
 
781
 
 
782
  attribute    *p_queattr,  /* I */
 
783
  attribute    *p_svrattr,  /* I */
 
784
  resource_def *rscdf,      /* I */
 
785
  int          *fromQueue)  /* O */
 
786
 
 
787
  {
 
788
  resource *pr;
 
789
 
 
790
  pr = find_resc_entry(p_queattr, rscdf);
 
791
 
 
792
  if ((pr == NULL) || ((pr->rs_value.at_flags & ATR_VFLAG_SET) == 0))
 
793
    {
 
794
    /* queue limit not set, check server's */
 
795
 
 
796
    pr = find_resc_entry(p_svrattr, rscdf);
 
797
 
 
798
    if ((pr != NULL) && (pr->rs_value.at_flags & ATR_VFLAG_SET))
 
799
      {
 
800
      *fromQueue = 0;
 
801
      }
 
802
    }
 
803
  else
 
804
    {
 
805
    /* queue limit is set, use it */
 
806
 
 
807
    *fromQueue = 1;
 
808
    }
 
809
 
 
810
  return(pr);
 
811
  }  /* END get_resource() */
 
812
 
 
813
 
 
814
 
 
815
 
 
816
/*
770
817
 * compare the job resource limit against the system limit
771
818
 * unless a queue limit exists, it takes priority
772
819
 *
777
824
static void chk_svr_resc_limit(
778
825
 
779
826
  attribute *jobatr, /* I */
780
 
  attribute *queatr, /* I */
781
 
  attribute *svratr, /* I */
782
 
  int      qtype,  /* I */
 
827
  pbs_queue *pque,   /* I */
 
828
  int       qtype,   /* I */
783
829
  char      *EMsg)   /* O (optional,minsize=1024) */
784
830
 
785
831
  {
801
847
  int       MPPWidth = 0;
802
848
  int       PPN = 0;
803
849
 
 
850
  long      mpp_nppn = 0;
 
851
  long      mpp_width = 0;
 
852
  long      mpp_nodect = 0;
 
853
  resource  *mppnodect_resource = NULL;
 
854
 
804
855
  static resource_def *noderesc     = NULL;
805
856
  static resource_def *needresc     = NULL;
806
857
  static resource_def *nodectresc   = NULL;
807
858
  static resource_def *mppwidthresc = NULL;
 
859
  static resource_def *mppnppn      = NULL;
808
860
 
809
861
  static time_t UpdateTime = 0;
810
862
  static time_t now;
822
874
 
823
875
    /* NOTE:  to optimize, only update once per 30 seconds */
824
876
 
825
 
    noderesc     = find_resc_def(svr_resc_def,"nodes",     svr_resc_size);
826
 
    needresc     = find_resc_def(svr_resc_def,"neednodes", svr_resc_size);
827
 
    nodectresc   = find_resc_def(svr_resc_def,"nodect",    svr_resc_size);
828
 
    mppwidthresc = find_resc_def(svr_resc_def,"mppwidth",  svr_resc_size);
 
877
    noderesc     = find_resc_def(svr_resc_def, "nodes",     svr_resc_size);
 
878
    needresc     = find_resc_def(svr_resc_def, "neednodes", svr_resc_size);
 
879
    nodectresc   = find_resc_def(svr_resc_def, "nodect",    svr_resc_size);
 
880
    mppwidthresc = find_resc_def(svr_resc_def, "mppwidth",  svr_resc_size);
 
881
    mppnppn      = find_resc_def(svr_resc_def, "mppnppn",   svr_resc_size);
829
882
 
830
883
    SvrNodeCt = 0;
831
884
 
867
920
 
868
921
    if ((jbrc->rs_value.at_flags & (ATR_VFLAG_SET | ATR_VFLAG_DEFLT)) == ATR_VFLAG_SET)
869
922
      {
870
 
      qurc = find_resc_entry(queatr, jbrc->rs_defin);
 
923
      qurc = find_resc_entry(&pque->qu_attr[QA_ATR_ResourceMax], jbrc->rs_defin);
871
924
 
872
 
      LimitIsFromQueue = 0;
873
925
      LimitName = jbrc->rs_defin->rs_name;
874
926
 
875
 
      if ((qurc == NULL) || ((qurc->rs_value.at_flags & ATR_VFLAG_SET) == 0))
 
927
      cmpwith = get_resource(&pque->qu_attr[QA_ATR_ResourceMax],
 
928
          &server.sv_attr[SRV_ATR_ResourceMax],
 
929
          jbrc->rs_defin,
 
930
          &LimitIsFromQueue);
 
931
 
 
932
      if (strcmp(LimitName,"mppnppn") == 0)
876
933
        {
877
 
        /* queue limit not set, check server's */
878
 
 
879
 
        svrc = find_resc_entry(svratr, jbrc->rs_defin);
880
 
 
881
 
        if ((svrc != NULL) && (svrc->rs_value.at_flags & ATR_VFLAG_SET))
882
 
          {
883
 
          cmpwith = svrc;
884
 
          }
 
934
        mpp_nppn = jbrc->rs_value.at_val.at_long;
885
935
        }
886
 
      else
 
936
      if (strcmp(LimitName,"mppwidth") == 0)
887
937
        {
888
 
        /* queue limit is set, use it */
889
 
 
890
 
        LimitIsFromQueue = 1;
891
 
 
892
 
        cmpwith = qurc;
 
938
        mpp_width = jbrc->rs_value.at_val.at_long;
893
939
        }
894
940
 
895
941
      if ((jbrc->rs_defin == noderesc) && (qtype == QTYPE_Execution))
896
942
        {
897
943
        /* NOTE:  process after loop so SvrNodeCt is loaded */
 
944
        /* can check pure nodes violation right here */
 
945
        int job_nodes;
 
946
        int queue_nodes;
898
947
 
899
948
        jbrc_nodes = jbrc;
 
949
        if ((jbrc_nodes != NULL) && 
 
950
            (qurc != NULL))
 
951
          {
 
952
          if ((isdigit(*(jbrc_nodes->rs_value.at_val.at_str))) &&
 
953
              (isdigit(*(qurc->rs_value.at_val.at_str))))
 
954
            {
 
955
            job_nodes   = atoi(jbrc_nodes->rs_value.at_val.at_str);
 
956
            queue_nodes = atoi(qurc->rs_value.at_val.at_str);
 
957
 
 
958
            if (queue_nodes < job_nodes)
 
959
              comp_resc_lt++;
 
960
            }
 
961
          }
900
962
        }
901
963
 
902
964
#ifdef NERSCDEV
909
971
        }
910
972
 
911
973
#endif /* NERSCDEV */
 
974
      else if ((strcmp(LimitName,"mppnodect") == 0)
 
975
          && (jbrc->rs_value.at_val.at_long == -1))
 
976
        {
 
977
        /*
 
978
         * mppnodect is a special attrtibute,  It gets set based upon the
 
979
         * values of mppwidth and mppnppn. -1 signifies the case where mppwidth
 
980
         * and mppnppn were not both specified for the job. We will need to
 
981
         * check mppnodect limits against queue/server defaults, if any.
 
982
         */
 
983
         
 
984
        mppnodect_resource = jbrc;
 
985
        }
912
986
      else if ((cmpwith != NULL) && (jbrc->rs_defin != needresc))
913
987
        {
914
988
        /* don't check neednodes */
923
997
          }
924
998
        else if (rc < 0)
925
999
          {
926
 
          if ((EMsg != NULL) && (EMsg[0] == '\0'))
 
1000
          /* only record if:
 
1001
           *     is_transit flag is not set
 
1002
           * or  is_transit is set, but not to true
 
1003
           * or  the value comes from queue limit
 
1004
           */
 
1005
          if ((!(pque->qu_attr[(int)QE_ATR_is_transit].at_flags & ATR_VFLAG_SET)) ||
 
1006
              (!pque->qu_attr[(int)QE_ATR_is_transit].at_val.at_long) ||
 
1007
              (LimitIsFromQueue))
927
1008
            {
928
 
            sprintf(EMsg,"cannot satisfy %s max %s requirement",
929
 
              (LimitIsFromQueue == 1) ? "queue" : "server",
930
 
              (LimitName != NULL) ? LimitName : "resource");
 
1009
            if ((EMsg != NULL) && (EMsg[0] == '\0'))
 
1010
              {
 
1011
              sprintf(EMsg, "cannot satisfy %s max %s requirement",
 
1012
                      (LimitIsFromQueue == 1) ? "queue" : "server",
 
1013
                      (LimitName != NULL) ? LimitName : "resource");
 
1014
              }
 
1015
 
 
1016
              comp_resc_lt++;
931
1017
            }
932
 
 
933
 
          comp_resc_lt++;
934
1018
          }
935
1019
        }
936
1020
      }    /* END if () */
938
1022
    jbrc = (resource *)GET_NEXT(jbrc->rs_link);
939
1023
    }  /* END while (jbrc != NULL) */
940
1024
 
 
1025
  if (mppnodect_resource != NULL)
 
1026
    {
 
1027
    /*
 
1028
     * special case where mppnodect was not specified for the job, we need to
 
1029
     * check max against recalculated value using queue/server resources_defaults
 
1030
     */
 
1031
     
 
1032
    if (mpp_nppn == 0)
 
1033
      {     
 
1034
      /* get queue/server default value */
 
1035
      
 
1036
      if (mppnppn != NULL)
 
1037
        {
 
1038
        cmpwith = get_resource(&pque->qu_attr[QA_ATR_ResourceDefault],
 
1039
            &server.sv_attr[SRV_ATR_resource_deflt],
 
1040
            mppnppn,
 
1041
            &LimitIsFromQueue);
 
1042
          
 
1043
        if (cmpwith != NULL)
 
1044
          {
 
1045
          mpp_nppn = cmpwith->rs_value.at_val.at_long;
 
1046
          }
 
1047
        }
 
1048
      }
 
1049
 
 
1050
    if (mpp_width == 0)
 
1051
      {
 
1052
      /* get queue/server default value */
 
1053
 
 
1054
      if (mppwidthresc != NULL)
 
1055
        {
 
1056
        cmpwith = get_resource(&pque->qu_attr[QA_ATR_ResourceDefault],
 
1057
            &server.sv_attr[SRV_ATR_resource_deflt],
 
1058
            mppwidthresc,
 
1059
            &LimitIsFromQueue);
 
1060
          
 
1061
        if (cmpwith != NULL)
 
1062
          {
 
1063
          mpp_width = cmpwith->rs_value.at_val.at_long;
 
1064
          }
 
1065
        }
 
1066
      }
 
1067
 
 
1068
    /* Uses same way of calculating as set_mppnodect */
 
1069
    /* Check for width less than a node */
 
1070
 
 
1071
    if ((mpp_width) && (mpp_width < mpp_nppn))
 
1072
      {
 
1073
      mpp_nppn = mpp_width;
 
1074
      }
 
1075
 
 
1076
    /* Compute an estimate for the number of nodes needed */
 
1077
 
 
1078
    mpp_nodect = mpp_width;
 
1079
    if (mpp_nppn > 1)
 
1080
      {
 
1081
      mpp_nodect = (mpp_nodect + mpp_nppn - 1) / mpp_nppn;
 
1082
      }
 
1083
 
 
1084
    LimitIsFromQueue = 0;
 
1085
    LimitName = mppnodect_resource->rs_defin->rs_name;
 
1086
    
 
1087
    cmpwith = get_resource(&pque->qu_attr[QA_ATR_ResourceMax],
 
1088
        &server.sv_attr[SRV_ATR_ResourceMax],
 
1089
        mppnodect_resource->rs_defin,
 
1090
        &LimitIsFromQueue);
 
1091
 
 
1092
    if (cmpwith != NULL)
 
1093
      {
 
1094
      long nodect_orig;
 
1095
 
 
1096
      if (LOGLEVEL >= 7)
 
1097
        {
 
1098
        sprintf(log_buffer,
 
1099
            "chk_svr_resc_limit: comparing calculated mppnodect %ld, %s limit %s %ld\n",
 
1100
            mpp_nodect,
 
1101
            (LimitIsFromQueue == 1) ? "queue" : "server",
 
1102
            LimitName,
 
1103
            cmpwith->rs_value.at_val.at_long);
 
1104
 
 
1105
        log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, msg_daemonname,
 
1106
                  log_buffer);
 
1107
        }
 
1108
 
 
1109
      nodect_orig = mppnodect_resource->rs_value.at_val.at_long;
 
1110
      mppnodect_resource->rs_value.at_val.at_long = mpp_nodect;
 
1111
      
 
1112
      rc = mppnodect_resource->rs_defin->rs_comp(
 
1113
              &cmpwith->rs_value,
 
1114
              &mppnodect_resource->rs_value);
 
1115
 
 
1116
      mppnodect_resource->rs_value.at_val.at_long = nodect_orig;
 
1117
 
 
1118
      if (rc > 0)
 
1119
        {
 
1120
        comp_resc_gt++;
 
1121
        }
 
1122
      else if (rc < 0)
 
1123
        {
 
1124
        /* only record if:
 
1125
         *     is_transit flag is not set
 
1126
         * or  is_transit is set, but not to true
 
1127
         * or  the value comes from queue limit
 
1128
         */
 
1129
        if ((!(pque->qu_attr[(int)QE_ATR_is_transit].at_flags & ATR_VFLAG_SET)) ||
 
1130
            (!pque->qu_attr[(int)QE_ATR_is_transit].at_val.at_long) ||
 
1131
            (LimitIsFromQueue))
 
1132
          {
 
1133
          if ((EMsg != NULL) && (EMsg[0] == '\0'))
 
1134
            {
 
1135
            sprintf(EMsg, "cannot satisfy %s max %s requirement",
 
1136
                    (LimitIsFromQueue == 1) ? "queue" : "server",
 
1137
                    (LimitName != NULL) ? LimitName : "resource");
 
1138
            }
 
1139
 
 
1140
          comp_resc_lt++;
 
1141
          }
 
1142
        }
 
1143
      }
 
1144
    }  /* END if (mppnodect_resource != NULL) */
 
1145
 
941
1146
  if (jbrc_nodes != NULL)
942
1147
    {
943
1148
    int tmpI;
975
1180
            &dummy,
976
1181
            &dummy) == -1)
977
1182
        {
978
 
        if ((EMsg != NULL) && (EMsg[0] == '\0'))
979
 
          strcpy(EMsg, "cannot locate feasible nodes");
 
1183
        /* only record if:
 
1184
         *     is_transit flag is not set
 
1185
         * or  is_transit is set, but not to true
 
1186
         */
 
1187
        if ((!(pque->qu_attr[(int)QE_ATR_is_transit].at_flags & ATR_VFLAG_SET)) ||
 
1188
            (!pque->qu_attr[(int)QE_ATR_is_transit].at_val.at_long))
 
1189
          {
 
1190
          if ((EMsg != NULL) && (EMsg[0] == '\0'))
 
1191
            strcpy(EMsg, "cannot locate feasible nodes");
980
1192
 
981
 
        comp_resc_lt++;
 
1193
          comp_resc_lt++;
 
1194
          }
982
1195
        }
983
1196
      }
984
1197
    }    /* END if (jbrc_nodes != NULL) */
1038
1251
 
1039
1252
  chk_svr_resc_limit(
1040
1253
    pattr,
1041
 
    &pque->qu_attr[QA_ATR_ResourceMax],
1042
 
    &server.sv_attr[SRV_ATR_ResourceMax],
 
1254
    pque,
1043
1255
    pque->qu_qs.qu_type,
1044
1256
    EMsg);
1045
1257
 
1103
1315
    {
1104
1316
    /* 1a. if not already set, set up execution uid/gid/name */
1105
1317
 
1106
 
    if (!(pjob->ji_wattr[(int)JOB_ATR_euser].at_flags & ATR_VFLAG_SET))
 
1318
    if (!(pjob->ji_wattr[(int)JOB_ATR_euser].at_flags & ATR_VFLAG_SET) ||
 
1319
        !(pjob->ji_wattr[(int)JOB_ATR_egroup].at_flags & ATR_VFLAG_SET))
1107
1320
      {
1108
1321
      if ((i = set_jobexid(pjob, pjob->ji_wattr, EMsg)) != 0)
1109
1322
        {
1217
1430
 
1218
1431
          return(PBSE_NONONRERUNABLE);
1219
1432
          }
 
1433
        if (strcmp(Q_DT_fault_tolerant,
 
1434
                   pque->qu_attr[QA_ATR_DisallowedTypes].at_val.at_arst->as_string[i]) == 0
 
1435
            && ((pjob->ji_wattr[(int)JOB_ATR_fault_tolerant].at_flags & ATR_VFLAG_SET) &&
 
1436
                pjob->ji_wattr[(int)JOB_ATR_fault_tolerant].at_val.at_long != 0))
 
1437
          {
 
1438
          if (EMsg)
 
1439
            snprintf(EMsg, 1024,
 
1440
              "fault_tolerant jobs are not allowed for queue: user %s, queue %s",
 
1441
              pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str,
 
1442
              pque->qu_qs.qu_name);
 
1443
 
 
1444
          return(PBSE_NOFAULTTOLERANT);
 
1445
          }
 
1446
          
 
1447
        if (strcmp(Q_DT_fault_intolerant,
 
1448
                   pque->qu_attr[QA_ATR_DisallowedTypes].at_val.at_arst->as_string[i]) == 0
 
1449
            && (!(pjob->ji_wattr[(int)JOB_ATR_fault_tolerant].at_flags & ATR_VFLAG_SET) ||
 
1450
                pjob->ji_wattr[(int)JOB_ATR_fault_tolerant].at_val.at_long == 0))
 
1451
          {
 
1452
          if (EMsg)
 
1453
            snprintf(EMsg, 1024,
 
1454
              "only fault_tolerant jobs are allowed for queue: user %s, queue %s",
 
1455
              pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str,
 
1456
              pque->qu_qs.qu_name);
 
1457
 
 
1458
          return(PBSE_NOFAULTINTOLERANT);
 
1459
          }
 
1460
        if (strcmp(Q_DT_job_array,
 
1461
                   pque->qu_attr[QA_ATR_DisallowedTypes].at_val.at_arst->as_string[i]) == 0
 
1462
            && (pjob->ji_wattr[(int)JOB_ATR_job_array_request].at_flags & ATR_VFLAG_SET))
 
1463
          {
 
1464
          if (EMsg)
 
1465
            snprintf(EMsg, 1024,
 
1466
              "job arrays are not allowed for queue: queue %s",
 
1467
              pque->qu_qs.qu_name);
 
1468
          return(PBSE_NOJOBARRAYS);
 
1469
          }
 
1470
          
1220
1471
        }
1221
1472
      }    /* END if (pque->qu_attr[QA_ATR_DisallowedTypes].at_flags & ATR_VFLAG_SET) */
1222
1473
 
1324
1575
 
1325
1576
    if (pque->qu_attr[QA_ATR_Enabled].at_val.at_long == 0)
1326
1577
      {
1327
 
      if (EMsg) snprintf(EMsg, 1024,
1328
 
                           "queue is disabled: user %s, queue %s",
1329
 
                           pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str,
1330
 
                           pque->qu_qs.qu_name);
 
1578
      if (EMsg)
 
1579
        snprintf(EMsg, 1024,
 
1580
          "queue is disabled: user %s, queue %s",
 
1581
          pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str,
 
1582
          pque->qu_qs.qu_name);
1331
1583
 
1332
1584
      return(PBSE_QUNOENB);
1333
1585
      }
1335
1587
    if ((pque->qu_attr[QA_ATR_MaxJobs].at_flags & ATR_VFLAG_SET) &&
1336
1588
        ((pque->qu_numjobs - pque->qu_numcompleted) >= pque->qu_attr[QA_ATR_MaxJobs].at_val.at_long))
1337
1589
      {
1338
 
      if (EMsg) 
 
1590
      if (EMsg)
1339
1591
        snprintf(EMsg, 1024,
1340
1592
          "total number of jobs in queue exceeds the queue limit: "
1341
1593
          "user %s, queue %s",
1349
1601
        (pque->qu_attr[QA_ATR_MaxUserJobs].at_val.at_long >= 0))
1350
1602
      {
1351
1603
      /* count number of jobs user has in queue */
 
1604
 
1352
1605
      user_jobs = 0;
 
1606
 
1353
1607
      pj = (job *)GET_NEXT(pque->qu_jobs);
1354
1608
 
1355
 
      while (pj)
 
1609
      while (pj != NULL)
1356
1610
        {
1357
1611
        if ((pj->ji_qs.ji_state <= JOB_STATE_RUNNING) &&
1358
1612
            (!strcmp(pj->ji_wattr[JOB_ATR_job_owner].at_val.at_str,
1366
1620
 
1367
1621
      if (user_jobs >= pque->qu_attr[QA_ATR_MaxUserJobs].at_val.at_long)
1368
1622
        {
1369
 
        if (EMsg) 
 
1623
        if (EMsg)
1370
1624
          snprintf(EMsg, 1024,
1371
1625
            "total number of current user's jobs exceeds the queue limit: "
1372
1626
            "user %s, queue %s",
1384
1638
      {
1385
1639
      if (mtype == MOVE_TYPE_Move)  /* ok if not plain user */
1386
1640
        {
1387
 
        if (EMsg) 
 
1641
        if (EMsg)
1388
1642
          snprintf(EMsg, 1024,
1389
1643
            "queue accepts only routed jobs, no direct submission: "
1390
1644
            "user %s, queue %s",
1406
1660
      {
1407
1661
      if (acl_check(&pque->qu_attr[QA_ATR_AclHost], hostname, ACL_Host) == 0)
1408
1662
        {
1409
 
        if (EMsg) 
 
1663
        if (EMsg)
1410
1664
          snprintf(EMsg, 1024,
1411
1665
            "host ACL rejected the submitting host: user %s, queue %s, host %s",
1412
1666
            pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str,
1413
 
            pque->qu_qs.qu_name, 
 
1667
            pque->qu_qs.qu_name,
1414
1668
            hostname);
1415
1669
 
1416
1670
        return(PBSE_BADHOST);
1441
1695
        else
1442
1696
          {
1443
1697
          /* no group acl, fail immediately */
1444
 
 
1445
 
          if (EMsg) 
 
1698
          if (EMsg)
1446
1699
            snprintf(EMsg, 1024,
1447
1700
              "user ACL rejected the submitting user: user %s, queue %s",
1448
1701
              pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str,
1691
1944
 
1692
1945
  if (qsubhost != NULL)
1693
1946
    {
 
1947
 
 
1948
    /* If just the host name portion was specified
 
1949
     * then we use it instead of qsubhost
 
1950
     */
 
1951
    
 
1952
    if ((key == (int)'e') &&
 
1953
        (pjob->ji_wattr[(int)JOB_ATR_errpath].at_flags & ATR_VFLAG_SET) &&
 
1954
        (pjob->ji_wattr[(int)JOB_ATR_errpath].at_val.at_str[strlen(pjob->ji_wattr[(int)JOB_ATR_errpath].at_val.at_str) - 1] == ':'))
 
1955
      {
 
1956
      
 
1957
      pjob->ji_wattr[(int)JOB_ATR_errpath].at_val.at_str[strlen(pjob->ji_wattr[(int)JOB_ATR_errpath].at_val.at_str) - 1] = '\0';
 
1958
      qsubhost = pjob->ji_wattr[(int)JOB_ATR_errpath].at_val.at_str;
 
1959
      
 
1960
      }
 
1961
    else if ((key == (int)'o') && 
 
1962
        (pjob->ji_wattr[(int)JOB_ATR_outpath].at_flags & ATR_VFLAG_SET) &&
 
1963
        (pjob->ji_wattr[(int)JOB_ATR_outpath].at_val.at_str[strlen(pjob->ji_wattr[(int)JOB_ATR_outpath].at_val.at_str) - 1] == ':'))
 
1964
      {
 
1965
      
 
1966
      pjob->ji_wattr[(int)JOB_ATR_outpath].at_val.at_str[strlen(pjob->ji_wattr[(int)JOB_ATR_outpath].at_val.at_str) - 1] = '\0';
 
1967
      qsubhost = pjob->ji_wattr[(int)JOB_ATR_outpath].at_val.at_str;
 
1968
      
 
1969
      }
 
1970
 
1694
1971
    len = strlen(qsubhost) +
1695
1972
          strlen(pjob->ji_wattr[(int)JOB_ATR_jobname].at_val.at_str) +
1696
1973
          PBS_MAXSEQNUM +
1758
2035
 
1759
2036
 
1760
2037
 
1761
 
 
1762
2038
/*
1763
2039
 * get_jobowner - copy the basic job owner's name, without the @host suffix.
1764
2040
 * The "to" buffer must be large enought (PBS_MAXUSER+1).
1887
2163
 
1888
2164
  /* apply queue defaults first since they take precedence */
1889
2165
 
1890
 
  set_deflt_resc(ja,&pque->qu_attr[(int)QA_ATR_ResourceDefault]);
 
2166
  set_deflt_resc(ja, &pque->qu_attr[(int)QA_ATR_ResourceDefault]);
1891
2167
 
1892
2168
  /* server defaults will only be applied to attributes which have
1893
2169
     not yet been set */
1894
2170
 
1895
 
  set_deflt_resc(ja,&server.sv_attr[(int)SRV_ATR_resource_deflt]);
 
2171
  set_deflt_resc(ja, &server.sv_attr[(int)SRV_ATR_resource_deflt]);
1896
2172
 
1897
2173
  /* apply queue max limits first since they take precedence */
1898
2174
 
1899
 
#ifndef RESOURCEMAXNOTDEFAULT
1900
 
  set_deflt_resc(ja,&pque->qu_attr[(int)QA_ATR_ResourceMax]);
 
2175
#ifdef RESOURCEMAXDEFAULT
 
2176
  set_deflt_resc(ja, &pque->qu_attr[(int)QA_ATR_ResourceMax]);
1901
2177
 
1902
2178
  /* server max limits will only be applied to attributes which have
1903
2179
     not yet been set */
1904
2180
 
1905
 
  set_deflt_resc(ja,&server.sv_attr[(int)SRV_ATR_ResourceMax]);
 
2181
  set_deflt_resc(ja, &server.sv_attr[(int)SRV_ATR_ResourceMax]);
1906
2182
 
1907
2183
#endif
1908
2184
 
1912
2188
 
1913
2189
    if ((pjob->ji_wattr[i].at_flags & ATR_VFLAG_SET) && (pdef->at_action))
1914
2190
      {
1915
 
      if ((rc = pdef->at_action(&pjob->ji_wattr[i],pjob,ATR_ACTION_NEW)) != 0)
 
2191
      if ((rc = pdef->at_action(&pjob->ji_wattr[i], pjob, ATR_ACTION_NEW)) != 0)
1916
2192
        {
1917
2193
        /* FIXME: return an actual error */
1918
2194
 
1969
2245
 
1970
2246
 
1971
2247
/*
1972
 
 * eval_chkpnt - if the job's checkpoint attribute is "c=nnnn" and
 
2248
 * eval_checkpoint - if the job's checkpoint attribute is "c=nnnn" and
1973
2249
 *  nnnn is less than the queue' minimum checkpoint time, reset
1974
2250
 * to the queue min time.
1975
2251
 */
1976
2252
 
1977
 
static void eval_chkpnt(
 
2253
static void eval_checkpoint(
1978
2254
 
1979
2255
  attribute *jobckp, /* job's checkpoint attribute */
1980
2256
  attribute *queckp) /* queue's checkpoint attribute */
2011
2287
    }
2012
2288
 
2013
2289
  return;
2014
 
  }  /* END eval_chkpnt() */
 
2290
  }  /* END eval_checkpoint() */
2015
2291
 
2016
2292
 
2017
2293
 
2052
2328
    server.sv_jobstates[i] = 0;
2053
2329
    }
2054
2330
 
2055
 
  if (pqj)
 
2331
  if (pqj != NULL)
2056
2332
    {
2057
2333
    pc = log_buffer + strlen(log_buffer);
2058
2334
 
2074
2350
 
2075
2351
            log_buffer);
2076
2352
 
2077
 
  for (pque = (pbs_queue *)GET_NEXT(svr_queues);pque;
 
2353
  for (pque = (pbs_queue *)GET_NEXT(svr_queues);
 
2354
       pque != NULL;
2078
2355
       pque = (pbs_queue *)GET_NEXT(pque->qu_link))
2079
2356
    {
2080
2357
    pque->qu_numjobs = 0;
2084
2361
      pque->qu_njstate[i] = 0;
2085
2362
    }
2086
2363
 
2087
 
  for (pjob = (job *)GET_NEXT(svr_alljobs);pjob != NULL;
 
2364
  for (pjob = (job *)GET_NEXT(svr_alljobs);
 
2365
       pjob != NULL;
2088
2366
       pjob = (job *)GET_NEXT(pjob->ji_alljobs))
2089
2367
    {
2090
2368
    server.sv_qs.sv_numjobs++;
2091
2369
 
2092
2370
    server.sv_jobstates[pjob->ji_qs.ji_state]++;
2093
2371
 
2094
 
    (pjob->ji_qhdr)->qu_numjobs++;
2095
 
    (pjob->ji_qhdr)->qu_njstate[pjob->ji_qs.ji_state]++;
 
2372
    pque = pjob->ji_qhdr;
 
2373
    if (pque == NULL)
 
2374
      pque = find_queuebyname(pjob->ji_qs.ji_queue);
2096
2375
 
2097
 
    if (pjob->ji_qs.ji_state == JOB_STATE_COMPLETE)
 
2376
    if (pque != NULL)
2098
2377
      {
2099
 
      pque = pjob->ji_qhdr;
2100
 
      if (pque == NULL)
2101
 
        {
2102
 
        pque = find_queuebyname(pjob->ji_qs.ji_queue);
2103
 
        }
2104
 
      if (pque != NULL)
 
2378
      pque->qu_numjobs++;
 
2379
      pque->qu_njstate[pjob->ji_qs.ji_state]++;
 
2380
 
 
2381
      if (pjob->ji_qs.ji_state == JOB_STATE_COMPLETE)
2105
2382
        pque->qu_numcompleted++;
 
2383
 
 
2384
      pjob->ji_qhdr = pque;
2106
2385
      }
2107
2386
 
2108
2387
    }  /* END for (pjob) */