示例#1
0
int MClassAToString(

  mclass_t *C,      /* I */
  int       AIndex, /* I */
  char     *Buf,    /* O */ 
  int       Format, /* I */
  int       Mode)   /* I */

  {
  if ((C == NULL) || (Buf == NULL))
    {
    return(FAILURE);
    }

  Buf[0] = '\0';

  switch(AIndex)
    {
    case mclaOCNode:

      if (C->OCNodeName != NULL)
        strcpy(Buf,C->OCNodeName);

      break;

    case mclaOCDProcFactor:

      if (C->OCDProcFactor > 0.0)
        sprintf(Buf,"%0.2lf",C->OCDProcFactor);

      break;

    case mclaDefReqFeature:

      strcpy(Buf,MUMAList(eFeature,C->DefFBM,sizeof(C->DefFBM)));

      break;

    case mclaWCOverrun:

      if (C->F.Overrun != 0)
        strcpy(Buf,MULToTString(C->F.Overrun));

      break;

    default:

      /* NO-OP */

      return(FAILURE);

      /*NOTREACHED*/

      break;
    }  /* END switch(AIndex) */

  return(SUCCESS);
  }  /* END MClassAToString() */
示例#2
0
文件: MVMShow.c 项目: dhh1128/cbase
int MVMShow(

  mstring_t *Buffer, /* O (already initialized) */
  mvm_t     *V,
  mbool_t    Verbose,
  mbool_t    Indent)

  {
  int GIndex;
  mbool_t GMetricWritten = FALSE;

  if ((Buffer == NULL) || (V == NULL))
    {
    return(FAILURE);
    }

  /* Print the VMID, State, JobID, and Active OS */

  MStringAppendF(Buffer,"%sVM[%s]  State: %s  JobID: %s  ActiveOS: %s\n",
    (Indent == TRUE) ? "  " : "",
    V->VMID,
    MNodeState[V->State],
    V->JobID,
    MAList[meOpsys][V->ActiveOS]);

  if (bmisset(&V->Flags,mvmfUtilizationReported))
    {
    MStringAppendF(Buffer,"    Procs: %d/%d (CPULoad: %.2f/%.2f)  Mem: %d/%d MB Location: %d:%d\n",
      V->ARes.Procs,
      V->CRes.Procs,
      V->CPULoad,
      (double)V->LURes.Procs,
      V->ARes.Mem,
      V->CRes.Mem,
      V->Rack,
      V->Slot);
    }
  else
    {
    MStringAppendF(Buffer,"    Procs: %d  Mem: %d MB  Location: %d:%d\n",
      V->CRes.Procs,
      V->CRes.Mem,
      V->Rack,
      V->Slot);
    }

  if ((V->PowerState != mpowNONE) || (V->PowerSelectState != mpowNONE))
    {
    MStringAppendF(Buffer,"    PowerState: %s  PowerSelectState: %s\n",
      MPowerState[V->PowerState],
      MPowerState[V->PowerSelectState]);
    }

  if (V->LastActionDescription != NULL)
    {
    MStringAppendF(Buffer,"    Last operation %s completed %ld seconds ago (duration: %ld) - %s\n",
      MSysJobType[V->LastActionType],
      MSched.Time - V->LastActionEndTime,
      V->LastActionEndTime - V->LastActionStartTime,
      V->LastActionDescription);
    }

  /* CONTAINER NODE */

  if (Verbose)
    {
    if (V->N != NULL)
      {
      MStringAppendF(Buffer,"    Container node: %s\n",
        V->N->Name);
      }
    else
      {
      MStringAppendF(Buffer,"    ALERT: container node is NULL\n");
      }
    }

  /* VARIABLES */

  if (V->Variables.NumItems > 0)
    {
    mhashiter_t HTI;
    mbool_t VarFound = FALSE;
    char *VarName;
    char *VarVal;

    MUHTIterInit(&HTI);

    MStringAppendF(Buffer,"    Variables: ");

    while (MUHTIterate(&V->Variables,&VarName,(void **)&VarVal,NULL,&HTI) == SUCCESS)
      {
      if (VarFound)
        {
        MStringAppendF(Buffer," ");
        }

      MStringAppendF(Buffer,"%s",
        VarName);

      if (VarVal != NULL)
        {
        MStringAppendF(Buffer,"=\"%s\"",
          VarVal);
        }

      VarFound = TRUE;
      }

    MStringAppendF(Buffer,"\n");
    } /* END if (V->Variables.NumItems > 0) */

  /* TTL */

  if (V->EffectiveTTL > 0)
    {
    char TString[MMAX_LINE];
    char NCTime[MMAX_LINE];
    mulong tmpEndTime = V->StartTime + V->EffectiveTTL;

    MULToTString(V->EffectiveTTL,TString);
    MUSNCTime(&tmpEndTime,NCTime);

    MStringAppendF(Buffer,"    TTL: %s   %s%s\n",
      TString,
      (V->StartTime != 0) ? "Endtime: " : "",
      (V->StartTime != 0) ? NCTime : "");
    }

  /* STORAGE */

  if (V->Storage != NULL)
    {
    mln_t *StorePtr = NULL;
    mvm_storage_t *Storage = NULL;

    MStringAppendF(Buffer,"    Storage:\n");

    while (MULLIterate(V->Storage,&StorePtr) == SUCCESS)
      {
      Storage = (mvm_storage_t *)StorePtr->Ptr;

      MStringAppendF(Buffer,"         %s  %s:%d  MountPoint:%s",
        Storage->Name,
        Storage->Type,
        Storage->Size,
        Storage->MountPoint);

      if (!MUStrIsEmpty(Storage->MountOpts))
        {
        MStringAppendF(Buffer," MountOptions:%s",
          Storage->MountOpts);
        }

      MStringAppendF(Buffer,"\n");
      }
    } /* END if (V->Storage != NULL) */

  /* GEVENTS */

  if (MGEventGetItemCount(&V->GEventsList) > 0)
    {
    char            *GEName;
    mgevent_obj_t   *GEvent;
    mgevent_iter_t   GEIter;

    MStringAppendF(Buffer,"    GEvents: ");

    MGEventIterInit(&GEIter);
    while (MGEventItemIterate(&V->GEventsList,&GEName,&GEvent,&GEIter) == SUCCESS)
      {
      MStringAppendF(Buffer,"%s[%ld]='%s'",
        GEName,
        GEvent->GEventMTime,
        GEvent->GEventMsg);

      MStringAppendF(Buffer," ");
      }

    MStringAppendF(Buffer,"\n");
    } /* END if (V->GEvents.NumItems > 0) */

  /* GMETRICS */

  if (V->GMetric != NULL)
    {
    for (GIndex = 1;GIndex < MSched.M[mxoxGMetric];GIndex++)
      {
      if (V->GMetric[GIndex] == NULL)
        continue;

      if (MGMetric.Name[GIndex][0] == '\0')
        break;

      if (V->GMetric[GIndex]->SampleCount <= 0)
        continue;

      if (GMetricWritten == FALSE)
        {
        MStringAppendF(Buffer,"    GMetrics: %s:%.2f\n",
          MGMetric.Name[GIndex],
          V->GMetric[GIndex]->IntervalLoad);
  
        GMetricWritten = TRUE;
        }
      else
        {
        MStringAppendF(Buffer,"              %s:%.2f\n",
          MGMetric.Name[GIndex],
          V->GMetric[GIndex]->IntervalLoad);
        }
      } /* END for (GIndex = 1;... ) */
    } /* END if (V->GMetric != NULL) */

  /* ALIASES */

  if ((V->Aliases != NULL) && (V->Aliases->ListSize > 0))
    {
    mbitmap_t BM;

    char Aliases[MMAX_LINE];

    MStringAppendF(Buffer,"    Aliases: ");

    bmset(&BM,mcmUser);

    MVMAToString(V,NULL,mvmaAlias,Aliases,MMAX_LINE,&BM);
    MStringAppendF(Buffer,"%s",
      Aliases);

    MStringAppendF(Buffer,"\n");
    } /* END if (V->Aliases->ListSize > 0) */

  /* TRIGGERS */

  if ((Verbose) && (V->T != NULL))
    {
    mtrig_t *T;

    int tindex;

    char tmpTrig[MMAX_LINE];

    MStringAppendF(Buffer,"    Triggers:\n");

    for (tindex = 0;tindex < V->T->NumItems;tindex++)
      {
      T = (mtrig_t *)MUArrayListGetPtr(V->T,tindex);

      if (MTrigIsReal(T) == FALSE)
        continue;

      MTrigToAVString(T,',',tmpTrig,MMAX_LINE);

      MStringAppendF(Buffer,"       %s\n",
        tmpTrig);
      }
    } /* END if ((Verbose) && (V->T != NULL)) */

  if (V->TrackingJ != NULL)
    {
    MStringAppendF(Buffer,"    TrackingJob: %s\n",
      V->TrackingJ->Name);
    }

  return(SUCCESS);
  } /* END MVMShow() */
示例#3
0
int ShowBackfillWindow(

  char *RBuffer,    /* I */
  char *Buffer,     /* O */
  int   FLAGS,      /* I */
  char *Auth,       /* I */
  long *BufSize)    /* I */

  {
  int  BFNodeCount;
  int  BFProcCount;
  nodelist_t BFNodeList;
  long BFTime;
  long MinTime;

  long RequiredTime;
  long RequiredNodes;
  long RequiredProcs;

  char UserName[MAX_MNAME];
  char GroupName[MAX_MNAME];
  char AccountName[MAX_MNAME];

  int  Memory;
  char MemCmp[MAX_MNAME];
  int  DMemory;

  char PName[MAX_MNAME];
  char CurrentPName[MAX_MNAME];

  int  index;
  int  pindex;
  int  mindex;
  int  nindex;

  int  ShowSMP;  /* (boolean) */

  char Affinity;
  int  Type;

  int  Flags;

  char QOSName[MAX_MNAME];

  char ClassString[MAX_MLINE];
  char FeatureString[MAX_MLINE];

  mnode_t     *N;

  mjob_t       tmpJ;
  mjob_t      *J;
  mreq_t       tmpRQ;

  mcres_t      DRes;
  mpar_t      *P;
  mpar_t      *SP;

  mrange_t     ARange[MAX_MRANGE];
  mrange_t     RRange[2];

  int          NodeHeaderPrinted;

  int          PCount;

  char         tmpBuffer[MAX_MBUFFER];

  const char *FName = "ShowBackfillWindow";

  DBG(2,fUI) DPrint("%s(%s,Buffer,%d,%s,BufSize)\n",
    FName,
    RBuffer,
    FLAGS,
    Auth);

  if (MUSScanF(RBuffer,"%x%s %x%s %x%s %x%s %ld %ld %ld %d %d %x%s %d %d %x%s %x%s %x%s",
       sizeof(UserName),
       UserName,
       sizeof(GroupName),
       GroupName,
       sizeof(AccountName),
       AccountName,
       sizeof(PName),
       PName,
       &RequiredTime,
       &RequiredNodes,
       &RequiredProcs,
       &DMemory,
       &Memory,
       sizeof(MemCmp),
       MemCmp,
       &ShowSMP,
       &Flags,
       sizeof(ClassString),
       ClassString,
       sizeof(FeatureString),
       FeatureString,
       sizeof(QOSName),
       QOSName) == FAILURE)
    {
    /* invalid request string */

    DBG(3,fUI) DPrint("INFO:     cannot parse request\n");
 
    sprintf(Buffer,"ERROR:    cannot parse request\n");
 
    return(FAILURE);
    }

  MParFind(PName,&SP);

  DBG(4,fUI) DPrint("INFO:     locating backfill window for u: %s  g: %s  a: %s  p: %s  c: %s  f: %s (%ld:%ld:%d)\n",
    UserName,
    GroupName,
    AccountName,
    MAList[ePartition][(SP != NULL) ? SP->Index : 0],
    ClassString,
    FeatureString,
    RequiredTime,
    RequiredNodes,
    Memory);

  if (ShowSMP == FALSE)  /* NON-SMP */
    {
    mindex = 0;

    if (Memory > 0)
      {
      for (mindex = 0;MComp[mindex] != NULL;mindex++)
        {
        if (!strcasecmp(MComp[mindex],MemCmp))
          break;
        }

      if (MComp[mindex] == NULL)
        mindex = 0;
      }

    memset(&DRes,0,sizeof(DRes));
    DRes.Procs = 1;
    DRes.Mem   = DMemory;
 
    sprintf(Buffer,"backfill window (user: '******' group: '%s' partition: %s) %s\n",
      UserName,
      GroupName,
      PName,
      MULToDString((mulong *)&MSched.Time));

    PCount = 0;

    for (pindex = 1;pindex < MAX_MPAR;pindex++)
      {
      if (MPar[pindex].ConfigNodes == 0)
        continue;

      PCount++;
      }

    index = 0;

    for (pindex = 0;pindex < MAX_MPAR;pindex++)
      {
      P = &MPar[pindex];

      if ((SP != NULL) && (SP != P))
        continue;

      if ((PCount == 1) && (SP == NULL) && (P->Index != 0))
        break;

      if (P->ConfigNodes == 0)
        continue;

      MinTime = 0;

      DBG(7,fUI) DPrint("INFO:     checking window in partition %s\n",
        P->Name);

      strcpy(CurrentPName,GLOBAL_MPARNAME);

      index = 0;
 
      while (MBFGetWindow(
               &BFNodeCount,
               &BFProcCount,
               BFNodeList,
               &BFTime,
               MinTime,
               P,
               UserName,
               GroupName,
               AccountName,
               mindex,
               Memory,
               MAX(1,RequiredTime),
               &DRes,
               ClassString,
               FeatureString,
               QOSName,
               (Flags & (1 << mcmVerbose)) ? 
                 tmpBuffer : 
                 NULL) == SUCCESS)
        {
        DBG(4,fUI) DPrint("INFO:     located backfill window [%03d nodes : %06ld seconds]\n",
          BFNodeCount,
          BFTime);

        if ((BFTime >= RequiredTime) && 
            (BFNodeCount >= RequiredNodes) && 
            (BFProcCount >= RequiredProcs))
          {
          if (strcasecmp(P->Name,CurrentPName) != 0)
            {
            if ((strcasecmp(CurrentPName,GLOBAL_MPARNAME)) && (index == 0))
              {
              sprintf(Buffer,"%sno %s available\n",
                Buffer,
                (MSched.DisplayFlags & (1 << dfNodeCentric)) ? "nodes" : "procs");
              }

            strcpy(CurrentPName,P->Name);

            sprintf(Buffer,"%s\npartition %s:\n",
              Buffer,
              P->Name);

            index = 0;
            }

          if (MSched.DisplayFlags & (1 << dfNodeCentric))
            {
            /* node centric output */

            if (BFNodeCount == 0)
              {
              sprintf(Buffer,"%sno nodes available\n",
                Buffer);
              }
            else if (BFTime < 100000000)
              {
              sprintf(Buffer,"%s%3d node%s available for   %11s\n",
                Buffer,
                BFNodeCount,
                (BFNodeCount > 1) ? "s" : "",
                MULToTString(BFTime));
              }
            else
              {
              sprintf(Buffer,"%s%3d node%s available with no timelimit\n",
                Buffer,
                BFNodeCount,
                (BFNodeCount > 1) ? "s" : "");
              }
            }
          else
            {
            /* proc centric output */

            if (BFProcCount == 0)
              {
              sprintf(Buffer,"%sno procs available\n",
                Buffer);
              }
            else if (BFTime < 100000000)
              {
              sprintf(Buffer,"%s%3d proc%s available for   %11s\n",
                Buffer,
                BFProcCount,
                (BFProcCount > 1) ? "s" : "",
                MULToTString(BFTime));
              }
            else
              {
              sprintf(Buffer,"%s%3d proc%s available with no timelimit\n",
                Buffer,
                BFProcCount,
                (BFProcCount > 1) ? "s" : "");
              }
            }

          index++;
          }   /* END if (BFTime) */

        MinTime = BFTime;
        }     /* END while (MBFGetWindow() == SUCCESS) */

      if (Flags & (1 << mcmVerbose))
        {
        strcat(Buffer,"\n\n");
        strcat(Buffer,tmpBuffer);
        }
      }    /* END for (pindex) */

    if (index == 0)
      {
      sprintf(Buffer,"%sno procs available\n",
        Buffer);
      }

    strcat(Buffer,"\n\n");
    }    /* END if (ShowSMP == FALSE) */
  else  
    {
    /* SMP Mode */

    RRange[0].StartTime = MSched.Time;
    RRange[0].EndTime   = MAX_MTIME;
    RRange[1].EndTime   = 0;

    memset(&tmpJ,0,sizeof(tmpJ));
    memset(&tmpRQ,0,sizeof(tmpRQ));

    J = &tmpJ;

    tmpRQ.DRes.Procs = 1;
    tmpRQ.DRes.Mem   = DMemory;

    J->Req[0] = &tmpRQ;

    if (MJobSetCreds(J,ALL,ALL,ALL) == FAILURE)
      {
      DBG(3,fUI) DPrint("INFO:     cannot setup showbf job creds\n");

      sprintf(Buffer,"ERROR:    cannot determine available resources\n");

      return(FAILURE);
      }

    if (MQOSFind(QOSName,&J->QReq) == FAILURE)
      {
      /* cannot locate requested QOS */

      MQOSFind(DEFAULT,&J->QReq);
      }

    MJobSetQOS(J,J->QReq,0);

    MJobBuildCL(J);

    sprintf(Buffer,"%s%20s %5s %6s %7s %7s   %14s\n",
      Buffer,
      "HostName",
      "Procs",
      "Memory",
      "Disk",
      "Swap",
      "Time Available");

    sprintf(Buffer,"%s%20s %5s %6s %7s %7s   %14s\n",
      Buffer,
      "----------",
      "-----",
      "------",
      "-------",
      "-------",
      "--------------");

    for (nindex = 0;nindex < MAX_MNODE;nindex++)
      {
      N = MNode[nindex];

      if ((N == NULL) || (N->Name[0] == '\0'))
        break;

      if (N->Name[0] == '\1')
         continue;

      if ((N->State != mnsActive) && (N->State != mnsIdle))
        continue;

      if ((SP != NULL) && (SP->Index != 0) && (N->PtIndex != SP->Index))
        continue;

      NodeHeaderPrinted = FALSE;

      for (RRange[0].TaskCount = 1;RRange[0].TaskCount < N->CRes.Procs;RRange[0].TaskCount = ARange[0].TaskCount + 1)
        {
        if (MJobGetSNRange(
              J,
              J->Req[0],
              N,
              RRange,
              1,
              &Affinity,
              &Type,
              ARange,
              &DRes,
              NULL) == SUCCESS)
          {
          if (ARange[0].StartTime != MSched.Time)
            {
            /* resources not available immediately */

            break;
            }

          if (NodeHeaderPrinted == FALSE)
            {
            strcat(Buffer,"\n");

            NodeHeaderPrinted = TRUE;
            }

          sprintf(Buffer,"%s%20s %5d %6d %7d %7d   %14s\n",
            Buffer,
            N->Name,
            DRes.Procs,
            DRes.Mem,
            DRes.Disk,
            DRes.Swap,
            MULToTString(ARange[0].EndTime - MSched.Time));
          }
        else
          {
          /* resources not available */

          break;
          }
        }
      }   /* END for (nindex)            */
    }     /* END else (ShowSMP == FALSE) */

  return(SUCCESS);
  }  /* END ShowBackfillWindow() */
示例#4
0
文件: Net1.c 项目: BradleyMorgan/maui
int MASNet1Show(

  masnet1_t *N,
  char      *Buffer)

  {
  int tindex;

  masnet1trans_t *T;

  char tmpString[MAX_MNAME];

  /* display state, configuration, statistics, and activity */

  if ((N == NULL) || (Buffer == NULL))
    {
    return(FAILURE);
    }

  Buffer[0] = '\0';

  sprintf(Buffer,"%sResource %s  Type:  %s\n\n",
    Buffer,
    N->Name,
    "Network");

  sprintf(Buffer,"%sState:  %s\n\n",
    Buffer,
    (N->State == 1) ? "Active" : "Down");

  sprintf(Buffer,"%sBandwidth:  %d MB/s\n",
    Buffer,
    N->Bandwidth);

  sprintf(Buffer,"%sUpTime:  %s    Data Transferred:  %d MB   Transfers Completed: %d\n",
    Buffer,
    MULToTString(N->Duration),
    N->MBTransferred,
    N->TransfersCompleted);
  
  sprintf(Buffer,"%sAvg Effective BW/Job: %6.2lf   Avg Delay/Job: %6.2lf\n",
    Buffer,
    (N->TransfersCompleted > 0) ? N->AvgTransferBW / N->TransfersCompleted : 0.0,
    (N->TransfersCompleted > 0) ? (double)N->AvgTransferDelay / N->TransfersCompleted : 0.0);

  strcat(Buffer,"\n");

  for (tindex = 0;tindex < MAX_MNODE;tindex++)
    {
    /* display transaction information */

    T = N->ActiveList[tindex];

    if (T == NULL)
      break;

    if (T == (masnet1trans_t *)1)
      continue;

    if ((T->CompletionTime != NULL) && (*T->CompletionTime > 0))
      {
      strcpy(tmpString,MULToTString(*T->CompletionTime - MSched.Time));
      }
    else
      {
      strcpy(tmpString,"N/A");
      }

    sprintf(Buffer,"%s  Transaction[%d]  %s  %d of %d KB   %s -> %s\n",
      Buffer,
      tindex,
      T->FileName,
      T->DataStaged,     
      T->FileSize,
      MULToTString((T->StartTime > 0) ? T->StartTime - MSched.Time : 0),
      tmpString);
    }  /* END for tindex) */

  strcat(Buffer,"\n");            

  return(SUCCESS);
  }  /* MASNet1Show() */
示例#5
0
int MRsvAdjust(

  mrsv_t *RS,         /* I (optional) */
  long    StartTime,  /* I earliest allowed starttime (optional, -1 = not specified) */
  int     TC,         /* I (optional, -1 = not specified) */
  mbool_t TimeLock)   /* I (rsv time may not be adjusted) */

  {
  mrsv_t  *R;

  rsv_iter RTI;

  long     BestStartTime;

  long     Delta;

  char    *NodeMap = NULL;

  mrange_t GRange[MMAX_RANGE];

  mnl_t  *MNodeList[MMAX_REQ_PER_JOB];

  mjob_t *J = NULL;

  enum MNodeAllocPolicyEnum NAPolicy;

  const char *FName = "MRsvAdjust";

  MDB(2,fSCHED) MLog("%s(%s,%ld,%d,%s)\n",
    FName,
    (RS != NULL) ? RS->Name : "NULL",
    StartTime,
    TC,
    MBool[TimeLock]);

  /* initialize 'rsv-map' pseudo-job */

  MNodeMapInit(&NodeMap);

  MNLMultiInit(MNodeList);

  MJobMakeTemp(&J);

  J->RsvAList = (char **)MUCalloc(1,sizeof(char *) * MMAX_PJOB);

  MRsvIterInit(&RTI);

  if (RS != NULL)
    {
    /* target reservation explicitly specified - go directly to operation */

    R = RS;

    goto RShortCut;
    }

  /* locate rsvs to migrate */

  while (MRsvTableIterate(&RTI,&R) == SUCCESS)
    {
    if (bmisset(&R->Flags,mrfIsVPC))
      {
      /* VPCs are adjusted only when directly called with RS */

      continue;
      }

    if (RS == NULL)
      {
      if (!bmisset(&R->Flags,mrfTimeFlex))
        {
        /* reservation is not adjustable */

        continue;
        }

      if (R->StartTime <= MSched.Time)
        {
        /* reservation is already active */

        continue;
        }
      }
    else
      {
      if (R != RS)
        {
        /* reservation not specified */

        continue;
        }
      }    /* END else (RS == NULL) */

RShortCut:

    MDB(1,fCORE) MLog("INFO:     evaluating reservation %s\n",
      R->Name);

    /* maintain existing reservation */

    if (MRsvToJob(R,J) == FAILURE)
      {
      continue;
      }

    MJobAddAccess(J,R->Name,FALSE);

    if (TC > 0)
      MReqSetAttr(J,J->Req[0],mrqaTCReqMin,(void **)&TC,mdfInt,mSet);

    if (TimeLock == FALSE)
      {
      mbitmap_t BM;

      if (StartTime > 0)
        {
        BestStartTime = StartTime;
        }
      else
        {
        BestStartTime = R->StartTime;
        }

      bmset(&BM,mrtcStartEarliest);
      if (MJobGetRange(
           J,
           J->Req[0],
           NULL,
           &MPar[0],
           MSched.Time,
           FALSE,
           GRange,       /* O */
           NULL,
           NULL,
           NodeMap,
           &BM,
           MSched.SeekLong,
           NULL,
           NULL) == FAILURE)
        {
        /* cannot locate available resources */

        if (RS != NULL)
          break;

        continue;
        }

      if (StartTime > 0)
        {
        if ((long)GRange[0].STime != StartTime)
          {
          MDB(2,fSCHED) MLog("INFO:     cannot obtain desired starttime (%ld != %ld)\n",
            GRange[0].STime,
            StartTime);

          if (RS != NULL)
            break;

          continue;
          }
        }
      else if (bmisset(&R->Flags,mrfIsVPC))
        {
        /* always move vpcs? */

        /* NO-OP */
        }
      else if ((long)(GRange[0].STime + 60) >= BestStartTime)
        {
        /* new reservation is not significantly better */

        if (RS != NULL)
          break;

        continue;
        }

      BestStartTime = GRange[0].STime;
      }  /* END if (TimeLock == FALSE) */
    else
      {
      BestStartTime = R->StartTime;
      }  /* END else (TimeLock == FALSE) */

    /* select resources */

    if (MJobGetRange(
         J,
         J->Req[0],
         NULL,
         &MPar[0],
         BestStartTime,
         FALSE,
         GRange,
         MNodeList, /* O */
         NULL,
         NodeMap,
         0,
         MSched.SeekLong,
         NULL,
         NULL) == FAILURE)
      {
      /* cannot locate new resources */

      if (RS != NULL)
        break;

      continue;
      }

    NAPolicy = (J->Req[0]->NAllocPolicy != mnalNONE) ?
      J->Req[0]->NAllocPolicy :
      MPar[0].NAllocPolicy;

    if (MJobAllocMNL(
          J,
          MNodeList,  /* I */
          NodeMap,
          MNodeList,  /* O */
          NAPolicy, 
          MSched.Time,
          NULL,
          NULL) == FAILURE)
      {
      MDB(2,fSCHED) MLog("INFO:     cannot allocate nodes for rsv '%s'\n",
        R->Name);

      if (RS != NULL)
        break;

      continue;
      }

    MRsvDeallocateResources(R,&R->NL);

    if (TimeLock == FALSE)
      {
      char TString[MMAX_LINE];

      Delta = R->StartTime - BestStartTime;

      R->StartTime -= Delta;
      R->EndTime   -= Delta;

      MULToTString(Delta,TString);

      MDB(1,fCORE) MLog("INFO:     timeframe for reservation %s adjusted forward by %s seconds\n",
        R->Name,
        TString);
      }  /* END if (TimeLock == FALSE) */

    if (MRsvAllocate(R,MNodeList[0]) == FAILURE)
      {
      MDB(1,fCORE) MLog("ALERT:    cannot adjust reservation %s (reservation empty)\n",
        R->Name);

      if (RS != NULL)
        break;

      continue;
      }

    /* reservation adjustment was successful */

    if (RS != NULL)
      break;
    }  /* END for (rindex) */

  MJobFreeTemp(&J);

  MUFree(&NodeMap);
  MNLMultiFree(MNodeList);

  return(SUCCESS);
  }  /* END MRsvAdjust() */
示例#6
0
int MCPStoreCluster(
 
  mckpt_t  *CP,
  mnode_t **NL)
 
  {
  int     nindex;
 
  mnode_t *N;
 
  char   *ptr;
  char   *tail;
  char    tmpLine[MAX_MLINE];
  char    Name[MAX_MNAME];
 
  long    CheckPointTime;
 
  const char *FName = "MCPStoreCluster";
 
  DBG(3,fCKPT) DPrint("%s(CP,NL)\n",
    FName);
 
  /* store active node info */
 
  for (nindex = 0;nindex < MAX_MNODE;nindex++)
    {
    N = NL[nindex];
 
    if ((N == NULL) || (N->Name[0] == '\0'))
      break;
 
    if (N->Name[0] == '\1')
      continue;
 
    DBG(4,fCKPT) DPrint("INFO:     checkpointing node '%s'\n",
      N->Name);
 
    MNodeToString(N,tmpLine);
 
    MCPStoreObj(CP->fp,mcpNode,N->Name,tmpLine);
    }  /* END for (nindex) */
 
  /* maintain old node CP info */
 
  if (CP->OBuffer != NULL)
    {
    ptr = CP->OBuffer;
 
    while ((ptr = strstr(ptr,MCPType[mcpNode])) != NULL)
      {
      sscanf(ptr,"%s %s %ld",
        tmpLine,
        Name, 
        &CheckPointTime);
 
      if ((MSched.Time - CheckPointTime) > CP->CPExpirationTime)
        {
        DBG(2,fCKPT) DPrint("INFO:     expiring checkpoint data for node %s.  not updated in %s\n",
          Name,
          MULToTString(MSched.Time - CheckPointTime));
 
        ptr += strlen(MCPType[mcpNode]);
 
        continue;
        }
 
      if (MNodeFind(Name,&N) == SUCCESS)
        {
        /* current node info already stored */
 
        ptr += strlen(MCPType[mcpNode]);
 
        continue;
        }
 
      if ((tail = strchr(ptr,'\n')) == NULL)
        {
        DBG(1,fCKPT) DPrint("ALERT:    checkpoint file corruption at offset %d\n",
          (int)(ptr - CP->OBuffer));
 
        ptr += strlen(MCPType[mcpNode]);
 
        continue;
        }
 
      /* copy old data */
 
      MUStrCpy(tmpLine,ptr,MIN(sizeof(tmpLine),tail - ptr + 1));
 
      fprintf(CP->fp,"%s\n",
        tmpLine);
 
      ptr = tail;
      }  /* END while (ptr = strstr()) */
    }    /* END if (Buffer != NULL)    */
 
  fflush(CP->fp);
 
  return(SUCCESS);
  }  /* END MCPStoreCluster() */
示例#7
0
文件: MSysCheck.c 项目: dhh1128/cbase
int MSysCheck()

  {
  job_iter JTI;

  int      nindex;

  mjob_t  *J;

  mnode_t *N;

  mrm_t   *RM;

  char Message[MMAX_LINE];

  enum MAllocResFailurePolicyEnum ARFPolicy;

  enum MNodeStateEnum State;

  const char *FName = "MSysCheck";

  MDB(4,fCORE) MLog("%s()\n",
    FName);

  MLimitEnforceAll(&MPar[0]);

  MJobIterInit(&JTI);

  /* locate jobs with various issues */

  while (MJobTableIterate(&JTI,&J) == SUCCESS)
    {
    if ((MSched.LimitedJobCP == TRUE) && (MSched.EnableHighThroughput == FALSE))
      {
      /* in high-throughput only transition on <events>, never at a regular interval */
      MJobTransition(J,TRUE,FALSE);
      }

    if (MJOBISACTIVE(J))
      {
      RM = (J->SubmitRM != NULL) ? J->SubmitRM : &MRM[0];

      /* locate jobs which have allocated 'down' nodes */
   
      if ((long)(MSched.Time - J->StartTime) > (long)MPar[0].MaxJobStartTime)
        {
        if (RM->Type == mrmtPBS)
          {
          if ((J->State == mjsIdle) &&
             ((J->EState == mjsStarting) || (J->EState == mjsRunning)))
            {
            char tmpLine[MMAX_LINE];
            char TString[MMAX_LINE];

            MULToTString(MSched.Time - J->StartTime,TString);

            MDB(2,fCORE) MLog("ALERT:    PBS job '%s' in state '%s' was started %s ago.  assuming prolog hang and cancelling job\n",
              J->Name,
              MJobState[J->State],
              TString);
   
            sprintf(tmpLine,"%s:  job cannot start\n",
              MSched.MsgInfoHeader);
   
            MJobCancel(J,tmpLine,FALSE,NULL,NULL);
            }
          }
	      }
   
      if (J->System != NULL)
        {
	      continue;
	      }

      for (nindex = 0;MNLGetNodeAtIndex(&J->NodeList,nindex,&N) == SUCCESS;nindex++)
        {
        State = mnsActive;

        if (((MNodeGetRMState(N,mrmrtCompute,&State) == FAILURE) &&
             (MNodeGetRMState(N,mrmrtAny,&State) == FAILURE)) ||
            (State == mnsDown))
          {
          mbool_t ARFOnMaster = FALSE;
          char tmpLine[MMAX_LINE];
 
          if ((int)(MSched.Time - N->StateMTime) < MSched.ARFDuration)
            {
            continue;
            }

          /* job will not necessarily be cancelled */
          MDB(1,fCORE) MLog("ALERT:    job '%s' has been in state '%s' for %ld seconds.  node '%s' is in state '%s' \n",
            J->Name,
            MJobState[J->State],
            MSched.Time - J->StartTime,
            N->Name,
            MNodeState[N->State]);
 
          sprintf(Message,"JOBCORRUPTION:  job '%s' (user %s) has been in state '%s' for %ld seconds.  node '%s' is in state '%s' \n",
            J->Name,
            J->Credential.U->Name,
            MJobState[J->State],
            MSched.Time - J->StartTime,
            N->Name,
            MNodeState[N->State]);
 
          MSysRegEvent(Message,mactNONE,1);
 
          sprintf(tmpLine,"%s:  job has 'DOWN' node allocated\n",
            MSched.MsgErrHeader);


          /* precedence:  job, class, partition, scheduler */

          if (J->ResFailPolicy != marfNONE)
            {
            ARFPolicy = J->ResFailPolicy;
            }
          else if ((J->Credential.C != NULL) && (J->Credential.C->ARFPolicy != marfNONE))
            {
            ARFPolicy = J->Credential.C->ARFPolicy;
            ARFOnMaster = J->Credential.C->ARFOnMasterTaskOnly;
            }
          else if (MPar[N->PtIndex].ARFPolicy != marfNONE)
            {
            ARFPolicy = MPar[N->PtIndex].ARFPolicy;
            }
          else if (MPar[0].ARFPolicy != marfNONE) /* look on the default partition for this policy */
            {
            ARFPolicy = MPar[0].ARFPolicy;
            }
          else
            {
            ARFPolicy = MSched.ARFPolicy;
            ARFOnMaster = MSched.ARFOnMasterTaskOnly;
            }

          if ((ARFOnMaster == FALSE) || (MNLReturnNodeAtIndex(&J->Req[0]->NodeList,0) == N))
            {
            switch (ARFPolicy)
              {
              case marfCancel:

                MJobPreempt(J,NULL,NULL,NULL,"node failure",mppCancel,TRUE,NULL,NULL,NULL);

                MDB(1,fRM) MLog("ALERT:    job '%s' cancelled (allocated node %s has failed)\n",
                  J->Name,
                  N->Name);

                break;

              case marfFail:

                MDB(1,fRM) MLog("ALERT:    job '%s' is being marked as failed (allocated node %s has failed)\n",
                  J->Name,
                  N->Name);

                MJobFail(J,MDEF_NODE_FAILURE_CCODE);

                return(SUCCESS);

                /*NOTREACHED*/

                break;

              case marfRequeue:

                bmset(&J->IFlags,mjifFailedNodeAllocated);

                MJobPreempt(J,NULL,NULL,NULL,"node failure",mppRequeue,TRUE,NULL,NULL,NULL);

                MDB(1,fRM) MLog("ALERT:    job '%s' requeued (allocated node %s has failed)\n",
                  J->Name,
                  N->Name);

                break;

              case marfHold:

                bmset(&J->IFlags,mjifFailedNodeAllocated);

                MJobPreempt(J,NULL,NULL,NULL,"node failure",mppRequeue,TRUE,NULL,NULL,NULL);

                MDB(1,fRM) MLog("ALERT:    job '%s' requeued and held (allocated node %s has failed)\n",
                  J->Name,
                  N->Name);

                MJobSetHold(J,mhBatch,0,mhrRMReject,NULL);

                break;

              case marfNotify:

                /* only send one notification per failure */

                if (N->State != N->OldState)
                  {
                  MSysSendMail(
                    MSysGetAdminMailList(1),
                    NULL,
                    NULL,
                    NULL,
                    NULL);
                  }

                break;

              default:

                /* NO-OP */

                break;
              }  /* END switch (ARFPolicy) */
            }    /* END if ((ARFOnMaster == FALSE) || (J->Req[0]->NodeList[0].N == N)) */
          }    /* END if (((N->State == mnsIdle) || ...)) */
        }      /* END for (nindex) */
      }          /* END if (MJOBISACTIVE(J)) */

    if (MJOBISIDLE(J) == TRUE)
      {
      if ((J->Credential.Q != NULL) && (J->Credential.Q->TList != NULL))
        {
        /* verify trigger thresholds */

        /* MJobCheckCredTriggers(J); */
        }
      }

    if (!MJOBISACTIVE(J))
      {
      if ((!bmisclear(&J->Hold)) && (MSched.MaxJobHoldTime > 0) &&
          (((J->HoldTime != 0) && 
            (MSched.Time - J->HoldTime > (unsigned int)MSched.MaxJobHoldTime)) ||
          ((J->HoldTime == 0) && 
            (MSched.Time - J->SubmitTime > (unsigned int)MSched.MaxJobHoldTime))))
        {
        MJobCancel(J,"job violates JOBMAXHOLDTIME",FALSE,NULL,NULL);
        }
      }
    }        /* END for (jindex) */

  if (bmisset(&MSched.Flags,mschedfAlwaysUpdateCache))
    {
    MSysRefreshCache();
    }  /* END if (bmisset(&MSched.Flags,mschedfAlwaysUpdateCache)) */

  /* Harvest any old VCs */

  MVCHarvestVCs();

  /* clear all defunct child processes */

  MUClearChild(NULL);

  if (MAM[0].Type != mamtNONE)
    {
    /* check health of primary accounting manager */

    if (MAM[0].State == mrmsDown)
      {
      MAMInitialize(&MAM[0]);
      }
    }    /* END if (MAM[0].Type != mamtNONE) */

  return(SUCCESS);
  }  /* END MSysCheck() */
示例#8
0
文件: MMB.c 项目: dhh1128/cbase
char *MMBPrintMessages(

  mmb_t               *Head,        /* I (optional) */
  enum MFormatModeEnum DFormat,     /* I */
  mbool_t              ShowVerbose, /* I */
  int                  MinPrio,     /* I (only display messages of this priority or higher) */
  char                *Buf,         /* O (optional,char * or mxml_t *) */
  int                  BufSize)     /* I */

  {
  mmb_t *mptr;

  char *BPtr = NULL;
  int   BSpace;

  char *hptr = NULL;

  static char tmpMBuf[MMAX_BUFFER];

  char  tmpLine[MMAX_LINE << 2];
  char  tmpLine2[MMAX_LINE << 2];

  if (Buf != NULL)
    {
    BPtr = Buf;
    BSpace = BufSize;
    }
  else
    {
    BPtr = tmpMBuf;
    BSpace = sizeof(tmpMBuf);
    }

  hptr = BPtr;

  switch (DFormat)
    {
    case mfmXML:
    case mfmAVP:  /* KLUDGE - use AVP to create packed XML data */

      {
      mxml_t *DE;
      mxml_t *CE;
      mxml_t *UE;

      int     count = 0;

      DE = (mxml_t *)Buf;

      if (DE == NULL)
        break;

      if (Head == NULL)
        {
        /* header not required in XML */

        break;
        }  /* END if (Head == NULL) */

      if (DFormat == mfmAVP)
        {
        /* initialize temporary parent XML element */

        UE = NULL;
        }
    
      for (mptr = Head;mptr != NULL;mptr = mptr->Next)
        {
        if (mptr->Priority < MinPrio)
          continue;

        CE = NULL;

        MXMLCreateE(&CE,"message");

        MXMLSetAttr(CE,"index",(void *)&count,mdfInt);
        MXMLSetAttr(CE,(char *)MMBAttr[mmbaCTime],(void *)&mptr->CTime,mdfLong);

        if (mptr->Owner != NULL)
          MXMLSetAttr(CE,(char *)MMBAttr[mmbaOwner],(void *)mptr->Owner,mdfString);

        MXMLSetAttr(CE,(char *)MMBAttr[mmbaPriority],(void *)&mptr->Priority,mdfInt);
        MXMLSetAttr(CE,(char *)MMBAttr[mmbaCount],(void *)&mptr->Count,mdfInt);
        MXMLSetAttr(CE,(char *)MMBAttr[mmbaExpireTime],(void *)&mptr->ExpireTime,mdfLong);
        MXMLSetAttr(CE,(char *)MMBAttr[mmbaType],(void *)MMBType[mptr->Type],mdfString);

        if (mptr->Data != NULL)
          {
          if (strchr(mptr->Data,'\n') != NULL)
            {
            char tmpData[MMAX_BUFFER];

            MUStrCpy(tmpData,mptr->Data,sizeof(tmpData));

            MUStrReplaceChar(tmpData,'\n',' ',FALSE);

            MXMLSetAttr(CE,(char *)MMBAttr[mmbaData],(void *)tmpData,mdfString);
            }
          else
            { 
            MXMLSetAttr(CE,(char *)MMBAttr[mmbaData],(void *)mptr->Data,mdfString);
            }
          }

        if (mptr->Label != NULL)
          MXMLSetAttr(CE,(char *)MMBAttr[mmbaLabel],(void *)mptr->Label,mdfString);

        if (DFormat == mfmAVP)
          {
          /* create/update temporary XML */

          if (UE == NULL)
            MXMLCreateE(&UE,(char*) MSON[msonData]);

          MXMLAddE(UE,CE);
          }
        else
          {
          MXMLAddE(DE,CE);
          }

        count++;
        }  /* END for (mptr) */

      if ((DFormat == mfmAVP) && (UE != NULL))
        {
        /* NOTE:  Buf is mxml_t *, do not populate */

        MUSNInit(&BPtr,&BSpace,tmpMBuf,sizeof(tmpMBuf));

        hptr = BPtr;

        MXMLToString(UE,tmpLine,sizeof(tmpLine),NULL,TRUE);

        MXMLDestroyE(&UE);

        MUStringPack(tmpLine,tmpLine2,sizeof(tmpLine2));

        MUSNCat(&BPtr,&BSpace,tmpLine2);
        }
      }    /* END BLOCK */

      break;

    case mfmHuman:
    default:

      {
      int count = 0;

      char tmpBuf[MMAX_NAME];
      char label[MMAX_NAME];

      if (Buf != NULL)
        MUSNInit(&BPtr,&BSpace,Buf,BufSize);
      else
        MUSNInit(&BPtr,&BSpace,tmpMBuf,sizeof(tmpMBuf));

      hptr = BPtr;

      if (Head == NULL)
        {
        if (ShowVerbose == TRUE)
          {
          MUSNPrintF(&BPtr,&BSpace,"%-7s %10s %10s %8.8s %4.4s %3.3s %s\n",
            "Label",
            "CreateTime",
            "ExpireTime",
            "Owner",
            "Prio",
            "Num",
            "Message");
          }

        break;
        }  /* END if (Head == NULL) */

      for (mptr = Head;mptr != NULL;mptr = mptr->Next)
        {
        if (mptr->Priority < MinPrio)
          continue;

        if (mptr->Label != NULL)
          {
          strncpy(label,mptr->Label,sizeof(label));
          }
        else
          {
          sprintf(label,"%d",
            count);
          }

        count++;

        if (ShowVerbose == TRUE)
          {
          char TString[MMAX_LINE];
          /* display w/relative time */

          MULToTString(mptr->CTime - MSched.Time,TString);

          strcpy(tmpBuf,TString);

          MULToTString(mptr->ExpireTime - MSched.Time,TString);

          MUSNPrintF(&BPtr,&BSpace,"%-8.8s %10s %10s %8.8s %4d %3d %s\n",
            label,
            tmpBuf,
            TString,
            (mptr->Owner != NULL) ? mptr->Owner : "N/A",
            mptr->Priority,
            mptr->Count,
            (mptr->Data != NULL) ? mptr->Data : "-");
          }
        else
          {
          if (mptr->Source != NULL)
            {
            MUSNPrintF(&BPtr,&BSpace,"Message[%.8s] (from %s) %s\n",
              label,
              mptr->Source,
              (mptr->Data != NULL) ? mptr->Data : "-");
            }
          else
            {
            MUSNPrintF(&BPtr,&BSpace,"Message[%.8s] %s\n",
              label,
              (mptr->Data != NULL) ? mptr->Data : "-");
            }
          }
        }  /* END for (mptr) */
      }    /* END BLOCK (case mfmHuman) */

      break;
    }  /* END switch (DFormat) */

  return(hptr);
  }  /* END MMBPrintMessages() */
示例#9
0
int MRsvJCreate(

  mjob_t                 *J,            /* I  job reserving nodes */
  mnl_t                 **MNodeList,    /* I  nodes to be reserved (optional) */
  long                    StartTime,    /* I  time reservation starts */
  enum MJRsvSubTypeEnum   RsvSType,     /* I  reservation subtype  */
  mrsv_t                **RP,           /* O  reservation pointer (optional) */
  mbool_t                 NoRsvTransition) /* I  don't transition */

  {
  int   rqindex;
  int   rqindex2;

  int   nindex;

  mrsv_t  *R;
  mnode_t *N;
  mreq_t  *RQ;

  int     RC;

  double  NPFactor;

  int     TaskCount;

  const char *FName = "MRsvJCreate";

  char TString[MMAX_LINE];

  MULToTString(StartTime - MSched.Time,TString);

  MDB(3,fSTRUCT) MLog("%s(%s,MNodeList,%s,%s,RP)\n",
    FName,
    (J != NULL) ? J->Name : "NULL",
    TString,
    MJRType[RsvSType]);

  if ((J == NULL) || (J->Req[0] == NULL))
    {
    MDB(1,fSTRUCT) MLog("ERROR:    invalid job passed to %s()\n",
      FName);

    return(FAILURE);
    }

  if (bmisset(&J->Flags,mjfRsvMap))
    {
    return(SUCCESS);
    }

  if (J->Rsv != NULL)
    {
    MDB(0,fSTRUCT) MLog("ERROR:    reservation created for reserved job '%s' (existing reservation '%s' deleted)\n",
      J->Name,
      J->Rsv->Name);

    MJobReleaseRsv(J,TRUE,FALSE);
    }

  rqindex2 = 0; /* So valgrind won't complain */

  /* NOTE:  must create per req rsv if task resource definitions differ */

  for (rqindex = 0;rqindex < MMAX_REQ_PER_JOB;rqindex++)
    {
    R = NULL;

    RQ = J->Req[rqindex];

    if (RQ == NULL)
      break;

    /* verify nodelist */

    if ((MNodeList == NULL) &&
        ((RQ == NULL) || (MNLIsEmpty(&RQ->NodeList))))
      {
      MDB(1,fSTRUCT) MLog("ERROR:    invalid nodelist passed to %s()\n",
        FName);

      return(FAILURE);
      }

    MRsvInitialize(&R);

    R->HostExpIsSpecified = TRUE;

    R->CTime = MSched.Time;

    R->CIteration = MSched.Iteration;

    if (rqindex == 0)
      {
      /* NOTE:  returned rsv pointer and J->R only point to req 0 rsv */

      if (RP != NULL)
        *RP = R;

      /* link job to reservation */

      J->Rsv = R;
      }  /* END if (rqindex == 0) */

    RQ->R = R;

    R->J    = J;  /* all req reservations point to J */
    R->Mode = 0;

    /* build reservation */

    if (rqindex > 0)
      {
      snprintf(R->Name,MMAX_NAME,"%s.%d",
        J->Name,
        rqindex);
      }
    else
      {
      MUStrCpy(R->Name,J->Name,MMAX_NAME);
      }

    MRsvTableInsert(R->Name,R);

    if (bmisset(&J->Flags,mjfMeta) &&
        bmisset(&J->Flags,mjfSystemJob) &&
        bmisset(&J->Flags,mjfNoRMStart))
      {
      R->Type = mrtMeta;
      R->SubType = mrsvstMeta;
      }
    else
      {
      R->Type    = mrtJob;
      R->SubType = mrsvstJob;
      }

    /* get partition number from first node */

    R->StartTime = StartTime;

    NPFactor = MNODESPEEDNOTSET;

    /* NOTE:  all rsv's of multi-req job must be scaled by same factor resulting in same duration */

    if (MNodeList != NULL)
      {
      double tmpD;

      /* get partition number from first node */

      if (MNLGetNodeAtIndex(MNodeList[rqindex],0,&N) == SUCCESS)
        {
        R->PtIndex = N->PtIndex;

        MDB(7,fSTRUCT) MLog("INFO:     job '%s' reservation partition set to %s from first node in node list\n",
          J->Name,
          MPar[R->PtIndex].Name);
        }
      else
        {
        R->PtIndex = 0;

        MDB(7,fSTRUCT) MLog("INFO:     job '%s' reservation partition set to %s since node in nodelist is NULL\n",
          J->Name,
          MPar[R->PtIndex].Name);
        }

      for (rqindex2 = 0;MNLGetNodeAtIndex(MNodeList[rqindex2],0,&N) == SUCCESS;rqindex2++)
        {
        if (MUNLGetMinAVal(
             &MNodeList[rqindex2][0],
             mnaSpeed,
             NULL,
             (void **)&tmpD) == SUCCESS)
          {
          NPFactor = MIN(NPFactor,tmpD);
          }
        }  /* END for (rqindex2) */

      if (NPFactor == MNODESPEEDNOTSET)
        {
        /* speed not set */

        NPFactor = 1.0;
        }
      }    /* END if (MNodeList != NULL) */
    else
      {
      double  tmpD;
      mreq_t *tRQ;

      /* get partition number from first node */

      if (MNLGetNodeAtIndex(&RQ->NodeList,0,&N) == SUCCESS)
        {
        R->PtIndex = N->PtIndex;

        MDB(7,fSTRUCT) MLog("INFO:     job '%s' reservation partition set to %s from first node in requested node list\n",
          J->Name,
          MPar[R->PtIndex].Name);
        }
      else
        {
        R->PtIndex = MCONST_DEFAULTPARINDEX;

        MDB(7,fSTRUCT) MLog("INFO:     job '%s' reservation partition set to %s since first node in requested node list is NULL\n",
          J->Name,
          MPar[R->PtIndex].Name);
        }

      for (rqindex2 = 0;J->Req[rqindex2] != NULL;rqindex2++)
        {
        tRQ = J->Req[rqindex2];

        if (!MNLIsEmpty(&tRQ->NodeList))
          {
          if (MUNLGetMinAVal(
              &tRQ->NodeList,
              mnaSpeed,
              NULL,
              (void **)&tmpD) == FAILURE)
            {
            continue;
            }

          NPFactor = MIN(NPFactor,tmpD);
          }
        }  /* END for (rqindex2) */
      }    /* END else (MNodeList != NULL) */

    /* record rsv nodelist */

    if (!MNLIsEmpty(&RQ->NodeList))
      {
      MNLCopy(&R->NL,&RQ->NodeList);
      }
    else if (MNodeList != NULL)
      {
      /* NOTE: idle jobs with rsv will not have RQ->NodeList populated */

      /* NOTE:  R->NL may be to small if J allocation is dynamic */

      MNLCopy(&R->NL,MNodeList[RQ->Index]);
      } 

    if ((NPFactor <= 0.0001) || (NPFactor >= MNODESPEEDNOTSET - 1))
      {
      NPFactor = 1.0;
      }

    R->EndTime = MAX(
                   StartTime + (long)((double)J->SpecWCLimit[0] / NPFactor),
                   (long)MSched.Time + 1);

    R->EndTime = MIN(R->EndTime,MMAX_TIME - 1);

    if (J->SubState == mjsstPreempted)
      {
      /* NOTE:  Job was just preempted -- preempted resources will not be 
                available to preemptor this iteration.  Maintain reservation 
                for MSched.JobRsvRetryInterval to prevent preemptor from using 
                resources immediately. This will enable him to create a 
                reservation in the future. */

      R->EndTime = MIN(R->EndTime,MSched.Time + MSched.JobRsvRetryInterval);
      }

    if (StartTime == 0)
      {
      MDB(0,fSTRUCT) MLog("ERROR:    invalid StartTime specified for reservation on job rsv '%s'\n",
        R->Name);

      StartTime = 1;
      }

    /* link nodes to reservation */

    MDB(6,fSTRUCT) MLog("INFO:     linking nodes to reservation '%s'\n",
      R->Name);

    R->AllocNC = 0;
    R->AllocTC = 0;
    R->AllocPC = MReqGetPC(J,RQ);

    /* copy ACL/CL info */

    if (!MACLIsEmpty(J->Credential.ACL))
      {
      MACLCopy(&R->ACL,J->Credential.ACL);
      }
    else
      {
      MACLFreeList(&R->ACL);
      }

    if (!MACLIsEmpty(J->Credential.CL))
      {
      MACLCopy(&R->CL,J->Credential.CL);
      }
    else
      {
      MACLFreeList(&R->CL);
      }

    MACLSet(&R->ACL,maJob,J->Name,mcmpSEQ,mnmNeutralAffinity,0,0);

    /* copy DRes info */

    MCResCopy(&R->DRes,&RQ->DRes);

    /* make each job a member of an rsv group with the job name */

    MUStrDup(&R->RsvGroup,J->Name);

    /* if this is a remote req must export reservation */

    if ((RQ->RemoteR == NULL) &&
        (MNLGetNodeAtIndex(&R->NL,0,&N) == SUCCESS) &&
        (N->RM != NULL) &&
        (N->RM->Type == mrmtMoab) &&
        bmisset(&N->RM->Flags,mrmfRsvExport))
      {
      char tmpRsvName[MMAX_NAME];

      enum MStatusCodeEnum SC;

      if (MRMRsvCtl(
            R,
            N->RM,
            mrcmCreate,
            (void **)tmpRsvName,
            NULL,
            &SC) == SUCCESS)
        {
        MOAddRemoteRsv((void *)R,mxoRsv,N->RM,tmpRsvName);
        MOAddRemoteRsv((void *)RQ,mxoReq,N->RM,tmpRsvName);
        }
      }
    else if ((RQ->RemoteR != NULL) &&
             (MNLGetNodeAtIndex(&R->NL,0,&N) == SUCCESS) && 
             (N->RM != NULL) &&
             (N->RM->Type == mrmtMoab) &&
             bmisset(&N->RM->Flags,mrmfRsvExport))
      {
      MOAddRemoteRsv((void *)R,mxoRsv,N->RM,RQ->RemoteR->Name);
      }
    }  /* END for (rqindex) */

  nindex  = 0;
  rqindex = 0;

  while (1)
    {
    RQ = J->Req[rqindex];

    /* NYI : must handle class ACL management for multi-req jobs */

    if (MNodeList == NULL)
      {
      if ((RQ == NULL) ||
          (MNLIsEmpty(&RQ->NodeList)) ||
          (rqindex >= MMAX_REQ_PER_JOB))
        {
        break;
        }

      if ((MNLGetNodeAtIndex(&RQ->NodeList,nindex,NULL) == FAILURE) ||
          (MNLGetTCAtIndex(&RQ->NodeList,nindex) == 0))
        {
        rqindex++;

        nindex = 0;

        continue;
        }

      MNLGetNodeAtIndex(&RQ->NodeList,nindex,&N);
      TaskCount = MNLGetTCAtIndex(&RQ->NodeList,nindex);

      nindex++;
      }
    else
      {
      if ((RQ == NULL) ||
          (rqindex >= MMAX_REQ_PER_JOB))
        {
        break;
        }

      if ((MNLGetNodeAtIndex(MNodeList[rqindex],0,NULL) == FAILURE) ||
          (MNLGetTCAtIndex(MNodeList[rqindex],0) == 0))
        {
        break;
        }

      if ((MNLGetNodeAtIndex(MNodeList[rqindex],nindex,NULL) == FAILURE) ||
          (MNLGetTCAtIndex(MNodeList[rqindex],nindex) == 0))
        {
        rqindex++;

        nindex = 0;

        continue;
        }

      MNLGetNodeAtIndex(MNodeList[rqindex],nindex,&N);
      TaskCount = MNLGetTCAtIndex(MNodeList[rqindex],nindex);

      nindex++;
      }  /* END else (MNodeList == NULL) */

    if ((N->Name[0] == '\0') || (N->Name[0] == '\1'))
      {
      MDB(0,fSTRUCT) MLog("ERROR:    job '%s' rsv nodelist contains invalid node at index %d\n",
        J->Name,
        nindex - 1);

      MJobReleaseRsv(J,FALSE,FALSE);

      return(FAILURE);
      }      /* END if ((N->Name[0] == '\0') || (N->Name[0] == '\1')) */

    if ((N->PtIndex != RQ->R->PtIndex) &&
        (N->PtIndex != 0) &&
        !bmisset(&J->Flags,mjfCoAlloc))
      {
      MDB(0,fSTRUCT) MLog("ERROR:    job '%s' reservation spans partitions (node %s: %d)\n",
        J->Name,
        N->Name,
        N->PtIndex);

      MJobReleaseRsv(J,FALSE,FALSE);

      return(FAILURE);
      }

    if ((RQ->NAccessPolicy == mnacSingleJob) ||
        (RQ->NAccessPolicy == mnacSingleTask))
      {
      /* node is dedicated - allocate all node procs */

      MCResClear(&RQ->R->DRes);

      RQ->R->DRes.Procs = -1;

      RC = 1;
      }
    else if (MJOBREQUIRESVMS(J))
      {
      mvm_t *V;

      /* locate associated VM */

      if (MJobFindNodeVM(J,N,&V) == SUCCESS)
        {
        MCResCopy(&RQ->R->DRes,&V->CRes);
        }
      else
        {
        /* cannot locate associated VM - use job's DRes */

        MCResCopy(&RQ->R->DRes,&RQ->DRes);
        }

      RC = 1;
      }
    else
      {
      /* normal job - use job's DRes */

      MCResCopy(&RQ->R->DRes,&RQ->DRes);

      RC = TaskCount;
      }

    RQ->R->AllocNC ++;
    RQ->R->AllocTC += RC;

    /* RC is always a positive number */

    if (MRsvAdjustNode(RQ->R,N,RC,0,FALSE) == FAILURE)
      {
      MJobReleaseRsv(J,FALSE,FALSE);

      return(FAILURE);
      }

    if (RQ->R->StartTime > MSched.Time)
      {
      MUStrDup(&RQ->R->RsvGroup,"idle");
      }
    }     /* END while (1) */

  J->RType = RsvSType;

  if (!NoRsvTransition)
    MRsvTransition(R,FALSE);

#if 0
  MSysJobUpdateRsvFlags(J);
#endif

  MRsvTableDumpToLog(__FUNCTION__,__LINE__);

  return(SUCCESS);
  }  /* END MRsvJCreate() */