int MWikiSDUpdate( char *AString, /* I */ msdata_t *SD, /* I (modified) */ mrm_t *R) /* I */ { char *ptr; char *tail; char SDAttr[MMAX_BUFFER]; char EMsg[MMAX_LINE]; char tmpLine[MMAX_LINE]; const char *FName = "MWikiSDUpdate"; MDB(2,fWIKI) MLog("%s(AString,SD,%s)\n", FName, (R != NULL) ? R->Name : "NULL"); if ((SD == NULL) || (AString == NULL)) { return(FAILURE); } ptr = AString; /* FORMAT: <FIELD>=<VALUE> [<FIELD>=<VALUE>]... */ while (ptr[0] != '\0') { if ((tail = MUStrChr(ptr,' ')) != NULL) { strncpy(SDAttr,ptr,MIN(MMAX_BUFFER - 1,tail - ptr)); SDAttr[tail - ptr] = '\0'; } else { MUStrCpy(SDAttr,ptr,MMAX_BUFFER); } if (MWikiSDUpdateAttr(SDAttr,SD,R,EMsg) == FAILURE) { snprintf(tmpLine,sizeof(tmpLine),"info corrupt for staging-data '%s -> %s' - %s", SD->SrcLocation, SD->DstLocation, EMsg); MMBAdd(&R->MB,tmpLine,NULL,mmbtNONE,0,0,NULL); } if (tail == NULL) break; ptr = tail + 1; } /* END while ((tail = MUStrChr(ptr,';')) != NULL) */ return(SUCCESS); } /* END MWikiSDUpdate() */
int MClassAdd( char *CName, /* I */ mclass_t **C) /* O */ { int cindex; if ((CName == NULL) || (CName[0] == '\0')) { return(FAILURE); } /* NOTE: CA to Class mapping prevents use of class slot 0. */ for (cindex = 1;cindex < MAX_MCLASS;cindex++) { if (MClass[cindex].Name[0] == '\0') { /* emply class slot located */ memset(&MClass[cindex],0,sizeof(mclass_t)); MClass[cindex].Index = cindex; MClass[cindex].MTime = MSched.Time; MUStrCpy(MClass[cindex].Name,CName,sizeof(MClass[cindex].Name)); /* populate attrlist */ strcpy(MAList[eClass][cindex],CName); if (C != NULL) *C = &MClass[cindex]; return(SUCCESS); } if (!strcmp(MClass[cindex].Name,CName)) { if (C != NULL) *C = &MClass[cindex]; return(SUCCESS); } } /* END for (cindex) */ if (C != NULL) *C = NULL; return(FAILURE); } /* END MClassAdd() */
int MAcctInitialize( mgcred_t *A, char *AName) { if ((A == NULL) || (AName == NULL) || (AName[0] == '\0')) { return (FAILURE); } memset(A, 0, sizeof(mgcred_t)); MUStrCpy(A->Name, AName, sizeof(A->Name)); return (SUCCESS); } /* END MAcctInitialize() */
int MAcctFind( char *AccountName, mgcred_t **A) { /* If found, return success with A pointing to Account. */ /* If not found, return failure with A pointing to */ /* first free Account if available, A set to NULL otherwise */ int aindex; int Key; char AName[MAX_MNAME]; DBG(5, fSTRUCT) DPrint("MAcctFind(%s,A)\n", (AccountName == NULL) ? "NULL" : AccountName); if (A != NULL) *A = NULL; if ((AccountName == NULL) || (AccountName[0] == '\0')) strcpy(AName, NONE); else MUStrCpy(AName, AccountName, sizeof(AName)); Key = (int)(MUGetHash(AName) % MAX_MACCT); for (aindex = Key; aindex < MAX_MACCT + MAX_MHBUF; aindex++) { if (MAcct[aindex].Name[0] == '\0') { if (A != NULL) *A = &MAcct[aindex]; break; } if (strcmp(MAcct[aindex].Name, AName) != 0) continue; /* Account found */ if (A != NULL) *A = &MAcct[aindex]; return (SUCCESS); } /* END for (aindex) */ return (FAILURE); } /* END MAcctFind() */
int MGroupInitialize( mgcred_t *G, char *GName) { if ((G == NULL) || (GName == NULL) || (GName[0] == '\0')) { return(FAILURE); } memset(G,0,sizeof(mgcred_t)); MUStrCpy(G->Name,GName,sizeof(G->Name)); return(SUCCESS); } /* END MGroupInitialize() */
int MDISATest() { mrsv_t R; long StartTime = 1255984844; double Cost = 0.0; memset(&R,0,sizeof(R)); MUStrCpy(R.Name,"test-rsv",sizeof(R.Name)); R.StartTime = StartTime; MSched.Time = StartTime; R.AllocPC = 2; R.DRes.Mem = 2000; MHistoryAddEvent(&R,mxoRsv); MSched.Time = StartTime + 4 * MCONST_DAYLEN; R.AllocPC = 4; R.DRes.Mem = 4000; MHistoryAddEvent(&R,mxoRsv); MSched.Time = StartTime + 8 * MCONST_DAYLEN; R.EndTime = MSched.Time; MSched.Time = StartTime + 34 * MCONST_DAYLEN; MLocalRsvGetDISAAllocCost(&R,NULL,&Cost,TRUE,FALSE); return(SUCCESS); } /* END MDISATest() */
int MUGIDFromUser( int UID, /* I (optional,notset=-1) */ char *UName, /* I (optional) */ char *GName) /* O group name (optional minsize=MMAX_NAME) */ { struct passwd *bufptr = NULL; struct passwd buf; char pwbuf[MMAX_BUFFER]; #ifndef MNOREENTRANT int rc = 0; #else struct passwd *rcPasswd; #endif /* !MNOREENTRANT */ const char *FName = "MUGIDFromUser"; MDB(10,fSTRUCT) MLog("%s(%d,UName,GName)\n", FName, UID); if (GName != NULL) GName[0] = '\0'; pwbuf[0] = '\0'; if (MSched.OSCredLookup == mapNever) { return(-1); } if (UName != NULL) { /* getpwnam_r() will return positive value on FAILURE */ #ifndef MNOREENTRANT rc = getpwnam_r(UName,&buf,pwbuf,sizeof(pwbuf),&bufptr); if ((rc == 0) && (bufptr != NULL)) { if (GName != NULL) { MUGIDToName(bufptr->pw_gid,GName); } return(bufptr->pw_gid); } #else bufptr = getpwnam(UName); if (bufptr != NULL) /*If there is no error*/ { if (GName != NULL) { MUStrCpy(GName,MUGIDToName(bufptr->pw_gid,GName),MMAX_NAME); } return(bufptr->pw_gid); } #endif /* !MNOREENTRANT */ } else { /* getpwuid_r() will return positive value on FAILURE */ #ifndef MNOREENTRANT rc = getpwuid_r(UID,&buf,pwbuf,sizeof(pwbuf),&bufptr); if ((rc == 0) && (bufptr != NULL)) { if (GName != NULL) { MUGIDToName(bufptr->pw_gid,GName); } return(bufptr->pw_gid); } #else bufptr = getpwuid(UID); if (bufptr != NULL) /* If there is no error*/ { if (GName != NULL) { MUStrCpy(GName,MUGIDToName(bufptr->pw_gid,GName),MMAX_NAME); } return(bufptr->pw_gid); } #endif /* !MNOREENTRANT */ } return(-1); } /* END MUGIDFromUser() */
int MUMAGetIndex( enum MExpAttrEnum AIndex, /* I Attribute Type */ char const *Value, /* I Attribute Index */ enum MObjectSetModeEnum Mode) /* I Search Mode */ { /* determine index of up to MMAX_ATTR attribute values */ int index; int len; const char *FName = "MUMAGetIndex"; MDB(9,fSTRUCT) MLog("%s(%s,%s,%s)\n", FName, MAttrType[AIndex], (Value != NULL) ? Value : "NULL", MObjOpType[Mode]); if ((AIndex == meGRes) || (AIndex == meGMetrics)) { return(MUGenericGetIndex(AIndex,Value,Mode)); } if ((Value == NULL) || (Value[0] == '\0')) { /* FAILURE */ return(0); } len = sizeof(MAList[0][0]) - 1; for (index = 1;index < MMAX_ATTR;index++) { if (!strncasecmp(MAList[AIndex][index],Value,len)) { return(index); } if (MAList[AIndex][index][0] == '\0') break; } /* END for (index) */ if (Mode == mVerify) { /* didn't find value -- FAILURE */ return(0); } /* NOTE: GRes may be more constrained than MAList, return failure */ if ((AIndex == meGRes) && (Mode == mAdd)) { if (index >= MSched.M[mxoxGRes] + 1) { if (MSched.OFOID[mxoxGRes] == NULL) MUStrDup(&MSched.OFOID[mxoxGRes],Value); MDB(1,fCONFIG) MLog("ALERT: no empty slots for %s in MAList[%s] (increase MAXGRES)\n", Value, MAttrType[AIndex]); /* FAILURE */ return(0); } MSched.GResCount = MAX(MSched.GResCount,index); } /* END if ((AIndex == meGRes) && ...) */ /* add new value to table */ MUStrCpy(MAList[AIndex][index],Value,sizeof(MAList[0][0])); MDB(5,fCONFIG) MLog("INFO: adding MAList[%s][%d]: '%s'\n", MAttrType[AIndex], index, Value); /* SUCCESS */ return(index); } /* END MUMAGetIndex() */
int MRMJobValidate( mjob_t *J, /* I */ mrm_t *R, /* I */ char *EMsg, /* O (optional,minsize=MMAX_LINE) */ enum MJobCtlCmdEnum *FailureAction, /* I (optional) */ int *SC) /* O (optional) */ { enum MWJobAttrEnum aindex; enum MRMSubTypeEnum SType; int index; char SPath[MMAX_BUFFER]; char *BPtr; int BSpace; char *ptr; char *TokPtr; char *ptr2; char *TokPtr2; char tEMsg[MMAX_LINE]; enum MStatusCodeEnum tmpSC; mbool_t GRes = FALSE; const char *FName = "MRMJobValidate"; MDB(2,fRM) MLog("%s(%s,%s,EMsg,FailureAction,SC)\n", FName, (J != NULL) ? J->Name : "NULL", (R != NULL) ? R->Name : "NULL"); if (EMsg != NULL) EMsg[0] = '\0'; if (SC != NULL) *SC = 0; if (J == NULL) { return(FAILURE); } if (R->ND.URL[mrmXJobValidate] == NULL) { /* no job validate script specified */ return(SUCCESS); } MUSNInit(&BPtr,&BSpace,SPath,sizeof(SPath)); MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaUName], J->Credential.U->Name); if (J->EUser != NULL) { /* report execution user */ MUSNPrintF(&BPtr,&BSpace,"%s=%s ", "EUSER", J->EUser); } if (J->Credential.G != NULL) { MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaGName], J->Credential.G->Name); } if (J->SpecWCLimit[0] > 0) { MUSNPrintF(&BPtr,&BSpace,"%s=%ld ", MWikiJobAttr[mwjaWCLimit], J->SpecWCLimit[0]); } /* if (J->Request.TC > 0) { MUSNPrintF(&BPtr,&BSpace,"%s=%d ", MWikiJobAttr[mwjaTasks], J->Request.TC); } */ if (J->Credential.C != NULL) { MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaRClass], J->Credential.C->Name); } if (J->QOSRequested != NULL) { MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaQOS], J->QOSRequested->Name); } if (J->Env.Cmd != NULL) { char *ptr; char *TokPtr; char tmpLine[MMAX_LINE]; MUStrCpy(tmpLine,J->Env.Cmd,sizeof(tmpLine)); ptr = MUStrTok(tmpLine," ",&TokPtr); MUStringChop(ptr); MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaExec], ptr); } /* END if (J->E.Cmd != NULL) */ if (!bmisclear(&J->Req[0]->ReqFBM)) { char tmpLine[MMAX_LINE]; MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaRFeatures], MUNodeFeaturesToString(',',&J->Req[0]->ReqFBM,tmpLine)); } if (J->Variables.Table != NULL) { mstring_t tmp(MMAX_LINE); MJobAToMString(J,mjaVariables,&tmp); MUSNPrintF(&BPtr,&BSpace,"%s=%s ", MWikiJobAttr[mwjaVariables], tmp.c_str()); } /* display generic resources */ for (index = 1;index < MSched.M[mxoxGRes];index++) { if (MGRes.Name[index][0] == '\0') break; if (MSNLGetIndexCount(&J->Req[0]->DRes.GenericRes,index) == 0) continue; if (GRes == FALSE) { MUSNPrintF(&BPtr,&BSpace,"GRES=%s:%d", MGRes.Name[index], MSNLGetIndexCount(&J->Req[0]->DRes.GenericRes,index)); GRes = TRUE; } else { MUSNPrintF(&BPtr,&BSpace,",%s:%d", MGRes.Name[index], MSNLGetIndexCount(&J->Req[0]->DRes.GenericRes,index)); } } /* END for (index) */ /* send this off to JOBVALIDATEURL */ SType = R->ND.NatType; R->ND.NatType = mrmstX1E; mstring_t Response(MMAX_LINE); /* NOTE: should we pass-in Job Validate specific timeout, ie 2 seconds? (NYI) */ if (MNatDoCommand( &R->ND, SPath, mrmXJobValidate, R->ND.Protocol[mrmXJobValidate], FALSE, NULL, NULL, &Response, tEMsg, /* O */ &tmpSC) == FAILURE) { R->ND.NatType = SType; /* make failure action configurable */ if ((ptr = strstr(tEMsg,"ACTION=")) != NULL) { ptr += strlen("ACTION="); ptr2 = MUStrTok(ptr," \n\t",&TokPtr); if (FailureAction != NULL) *FailureAction = (enum MJobCtlCmdEnum)MUGetIndexCI(ptr2,MJobCtlCmds,FALSE,mjcmNONE); } if (EMsg != NULL) MUStrCpy(EMsg,tEMsg,MMAX_LINE); if (SC != NULL) *SC = (int)tmpSC; return(FAILURE); } if (SC != NULL) *SC = (int)tmpSC; R->ND.NatType = SType; for (index = 0;Response[index] != '\0';index++) { if (Response[index] == '\n') Response[index] = ' '; } mstring_t tmpString(MMAX_LINE); MWikiFromAVP(NULL,Response.c_str(),&tmpString); /* Need a char array that can be modified, not the immutable tmpString */ char *mutableResponse = NULL; MUStrDup(&mutableResponse,tmpString.c_str()); ptr = MUStrTok(mutableResponse,";",&TokPtr); int rc = SUCCESS; /* NYI: change other job attributes such as NodeCount RMXString User/Group */ while (ptr != NULL) { ptr2 = MUStrTok(ptr,"=",&TokPtr2); aindex = (enum MWJobAttrEnum)MUGetIndexCI(ptr2,MWikiJobAttr,FALSE,mwjaNONE); switch (aindex) { case mwjaAccount: if ((J->Credential.A == NULL) || (strcmp(TokPtr2,J->Credential.A->Name))) { if (MRMJobModify( J, "Account_Name", NULL, TokPtr2, mSet, "account modified by jobvalidate interface", tEMsg, /* O */ NULL) != SUCCESS) { MDB(2,fSCHED) MLog("INFO: cannot set account on job %s to '%s' - invalid account - %s\n", J->Name, TokPtr2, tEMsg); if (EMsg != NULL) strcpy(EMsg,"cannot set account"); rc = FAILURE; goto cleanupExit; } MAcctAdd(TokPtr2,&J->Credential.A); bmset(&J->IFlags,mjifAccountLocked); } break; case mwjaRClass: if ((J->Credential.C == NULL) || (strcmp(TokPtr2,J->Credential.C->Name))) { mclass_t *C; if (MClassFind(TokPtr2,&C) == FAILURE) { MDB(2,fSCHED) MLog("INFO: cannot set class on job %s to '%s' - invalid class\n", J->Name, TokPtr2); if (EMsg != NULL) strcpy(EMsg,"cannot locate class"); rc = FAILURE; goto cleanupExit; } if (MJobSetClass(J,C,TRUE,tEMsg) == FAILURE) { MDB(2,fSCHED) MLog("INFO: cannot set class on job %s to '%s' - %s\n", J->Name, C->Name, tEMsg); if (EMsg != NULL) strcpy(EMsg,"cannot set class"); rc = FAILURE; goto cleanupExit; } bmset(&J->IFlags,mjifClassLocked); } /* END if ((J->Cred.C == NULL) || ...) */ break; case mwjaQOS: /* bypass qos checks and put qos directly onto job */ J->QOSRequested = NULL; if (MQOSFind(TokPtr2,&J->Credential.Q) != SUCCESS) { MDB(2,fSCHED) MLog("INFO: cannot set qos on job %s to '%s' - invalid QoS\n", J->Name, TokPtr2); if (EMsg != NULL) strcpy(EMsg,"cannot locate qos"); rc = FAILURE; goto cleanupExit; } bmset(&J->IFlags,mjifQOSLocked); break; case mwjaRFeatures: MReqSetAttr(J,J->Req[0],mrqaReqNodeFeature,(void **)TokPtr2,mdfString,mSet); break; case mwjaWCLimit: if (MRMJobModify( J, "Resource_List", "walltime", TokPtr2, mSet, "walltime modified by jobvalidate interface", tEMsg, NULL) == FAILURE) { MDB(2,fSCHED) MLog("INFO: cannot modify walltime for rm job %s - '%s'\n", J->Name, tEMsg); if (EMsg != NULL) strcpy(EMsg,"cannot modify walltime"); rc = FAILURE; goto cleanupExit; } break; case mwjaVariables: MJobSetAttr(J,mjaVariables,(void **)TokPtr2,mdfString,mAdd); break; default: /* NO-OP */ break; } /* END switch (aindex) */ ptr = MUStrTok(NULL,";",&TokPtr); } /* END while (ptr != NULL) */ cleanupExit: MUFree(&mutableResponse); return(rc); } /* END MRMJobValidate() */
int MVMCRFromXML( mvm_req_create_t *VMCR, /* I (modified) */ mxml_t *E) /* I */ { int aindex; if ((VMCR == NULL) || (E == NULL)) { return(FAILURE); } for (aindex = 0;aindex < E->ACount;aindex++) { if (!strcmp("ID",E->AName[aindex])) { MUStrCpy(VMCR->VMID,E->AVal[aindex],sizeof(VMCR->VMID)); } else if (!strcmp("VARS",E->AName[aindex])) { MUStrCpy(VMCR->Vars,E->AVal[aindex],sizeof(VMCR->Vars)); } else if (!strcmp("STORAGE",E->AName[aindex])) { MUStrCpy(VMCR->Storage,E->AVal[aindex],sizeof(VMCR->Storage)); } else if (!strcmp("ALIAS",E->AName[aindex])) { MUStrCpy(VMCR->Aliases,E->AVal[aindex],sizeof(VMCR->Aliases)); } else if (!strcmp("TRIGGER",E->AName[aindex])) { MUStrCpy(VMCR->Triggers,E->AVal[aindex],sizeof(VMCR->Triggers)); } else if (!strcmp("HYPERVISOR",E->AName[aindex])) { /* Find node for hypervisor */ MNodeFind(E->AVal[aindex],&VMCR->N); } else if (!strcmp("TEMPLATE",E->AName[aindex])) { MJobFind(E->AVal[aindex],&VMCR->JT,mjsmExtended); } else if (!strcmp("OWNERJOB",E->AName[aindex])) { MJobFind(E->AVal[aindex],&VMCR->OwnerJob,mjsmExtended); } else if (!strcmp("IMAGE",E->AName[aindex])) { VMCR->OSIndex = MUMAGetIndex(meOpsys,E->AVal[aindex],mAdd); } else if (!strcmp("WALLTIME",E->AName[aindex])) { VMCR->Walltime = strtol(E->AVal[aindex],NULL,10); } else if (!strcmp("SOVEREIGN",E->AName[aindex])) { VMCR->IsSovereign = MUBoolFromString(E->AName[aindex],FALSE); } else if (!strcmp("ISONETIMEUSE",E->AName[aindex])) { VMCR->IsOneTimeUse = MUBoolFromString(E->AName[aindex],FALSE); } else if (!strcmp("DISK",E->AName[aindex])) { VMCR->CRes.Disk = (int)strtol(E->AVal[aindex],NULL,10); } else if (!strcmp("MEM",E->AName[aindex])) { VMCR->CRes.Mem = (int)strtol(E->AVal[aindex],NULL,10); } else if (!strcmp("PROCS",E->AName[aindex])) { VMCR->CRes.Procs = (int)strtol(E->AVal[aindex],NULL,10); } else if (!strcmp("TRACKINGJ",E->AName[aindex])) { MUStrCpy(VMCR->TrackingJ,E->AVal[aindex],sizeof(VMCR->TrackingJ)); } } /* END for (aindex = 0;aindex < E->ACount;aindex++) */ return(SUCCESS); } /* END MVMCRFromXML() */
int MVMToPendingActionXML( mvm_t *V, /* I */ mxml_t **VEP) /* O (alloc) */ { char tmpLine[MMAX_LINE]; mxml_t *PE; mxml_t *CE; mulong JDuration = 0; mbool_t GEventsSpecified = FALSE; enum MSystemJobTypeEnum PendingActionType = msjtNONE; char PendingActionTypeStr[MMAX_LINE]; if (VEP == NULL) { return(FAILURE); } *VEP = NULL; if (V == NULL) { return(FAILURE); } PE = NULL; /* See if there are any GEvents */ if (MGEventGetItemCount(&V->GEventsList) > 0) { GEventsSpecified = TRUE; } /* NOTE: do not change pending actions strings w/o coordinating with MCM team */ if ((V->NextOS != 0) && (V->NextOS != V->ActiveOS)) { PendingActionType = msjtOSProvision; MUStrCpy(PendingActionTypeStr,(char *)MPendingActionType[mpatVMOSProvision],sizeof(PendingActionTypeStr)); } else if (((V->PowerSelectState == mpowOn) || (V->PowerSelectState == mpowOff)) && (V->PowerState != V->PowerSelectState) && (MSched.Time - V->PowerMTime < MCONST_HOURLEN)) { if (V->PowerSelectState == mpowOn) { PendingActionType = msjtPowerOn; MUStrCpy(PendingActionTypeStr,(char *)MPendingActionType[mpatVMPowerOn],sizeof(PendingActionTypeStr)); } else if (V->PowerSelectState == mpowOff) { PendingActionType = msjtPowerOff; MUStrCpy(PendingActionTypeStr,(char *)MPendingActionType[mpatVMPowerOff],sizeof(PendingActionTypeStr)); } } else { PendingActionType = msjtNONE; } if (PendingActionType == msjtNONE) { /* has no action on it to report as a pending action */ return(FAILURE); } /* create common elements */ if (MXMLCreateE(&PE,(char *)MXO[mxoxPendingAction]) == FAILURE) { return(FAILURE); } snprintf(tmpLine,sizeof(tmpLine),"%s-%ld", V->VMID, V->LastOSModRequestTime); MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaPendingActionID],(void *)tmpLine,mdfString); MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaSched],(void *)MSched.Name,mdfString); if (PendingActionType != msjtNONE) { MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaType],(void *)PendingActionTypeStr,mdfString); if (V->LastOSModRequestTime > 0) { /* Viewpoint only wants positive starttimes reported */ MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaStartTime],(void *)&V->LastOSModRequestTime,mdfLong); } if (MSched.DefProvDuration > 0) JDuration = MSched.DefProvDuration; else JDuration = MDEF_PROVDURATION; MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaMaxDuration],(void *)&JDuration,mdfLong); if (V->N != NULL) MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaHostlist],(void *)V->N->Name,mdfString); MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaState],(void *)MJobState[mjsRunning],mdfString); if (V->LastSubState != NULL) { MXMLSetAttr(PE,(char *)MPendingActionAttr[mpaaSubState],(void *)V->LastSubState,mdfString); } /* now set action specific data */ switch (PendingActionType) { case msjtOSProvision: /* handle re-provisioning of VM's */ MXMLAddChild(PE,PendingActionTypeStr,NULL,&CE); MXMLSetAttr(CE,(char *)MPendingActionAttr[mpaaVMID],(void *)V->VMID,mdfString); MXMLSetAttr(CE,(char *)MPendingActionAttr[mpaaTargetOS],(void *)MAList[meOpsys][V->NextOS],mdfString); break; case msjtPowerOn: case msjtPowerOff: /* handle start/stop */ MXMLAddChild(PE,PendingActionTypeStr,NULL,&CE); MXMLSetAttr(CE,(char *)MPendingActionAttr[mpaaVMID],(void *)V->VMID,mdfString); break; default: /* NO-OP */ break; } /* END switch (PendingActionType) */ } /* END if (PendingActionType != msjtNONE) */ if (GEventsSpecified != FALSE) { mxml_t *GEE; if (MVMFailuresToXML(V,NULL,&GEE) == SUCCESS) MXMLAddE(PE,GEE); } /* END if (GEventsSpecified != FALSE) */ *VEP = PE; return(SUCCESS); } /* END MVMToPendingActionXML() */
int MVMSetAttr( mvm_t *VM, /* I * (modified) */ enum MVMAttrEnum AIndex, /* I */ void const *Value, /* I */ enum MDataFormatEnum Format, /* I */ enum MObjectSetModeEnum Mode) /* I */ { const char *FName = "MVMSetAttr"; char const *ValAsString = (char const *)Value; MDB(6,fSTRUCT) MLog("%s(%s,%s,Value,%s,%s)\n", FName, (VM != NULL) ? VM->VMID : "NULL", MVMAttr[AIndex], MFormatMode[Format], MObjOpType[Mode]); if (VM == NULL) { return(FAILURE); } switch (AIndex) { case mvmaActiveOS: { int OS = MUMAGetIndex(meOpsys,ValAsString,mSet); if (OS != 0) VM->ActiveOS = OS; /*TODO: what if OS is not in VM's OSList? */ } break; case mvmaADisk: VM->ARes.Disk = strtol(ValAsString,NULL,0); break; case mvmaAlias: { if (Mode != mClear) { mvoid_t *Element; if (MUHTGet(&MNetworkAliasesHT,ValAsString,NULL,NULL) == SUCCESS) { /* Specified alias is already in use. Do not allow */ return(FAILURE); } /* Add to table now */ /* Done as mvoid_t so that node aliases work as well */ Element = (mvoid_t *)MUCalloc(1,sizeof(mvoid_t)); Element->Ptr = (void *)VM; Element->PtrType = mxoxVM; MUStrCpy(Element->Name,VM->VMID,sizeof(Element->Name)); MUHTAdd(&MNetworkAliasesHT,ValAsString,(void *)Element,NULL,MUFREE); } if ((Mode == mSet) || (Mode == mClear)) { /* Clear list, remove from global table */ mln_t *freePtr = NULL; while (MULLIterate(VM->Aliases,&freePtr) == SUCCESS) { MUHTRemove(&MNetworkAliasesHT,freePtr->Name,MUFREE); } /* TODO: send out signal to outside system to free alias */ MULLFree(&VM->Aliases,MUFREE); } if ((Mode == mSet) || (Mode == mAdd)) { /* Set has already been cleared, treat as add */ /* These must be added one at a time */ if (VM->Aliases == NULL) { MULLCreate(&VM->Aliases); } if (MULLAdd(&VM->Aliases,ValAsString,NULL,NULL,MUFREE) == FAILURE) return(FAILURE); /* TODO: send out signal to outside system to set alias */ } } /* END BLOCK mvmaAlias */ break; case mvmaAMem: VM->ARes.Mem = strtol(ValAsString,NULL,0); break; case mvmaAProcs: /* NOTE: set ARes.Procs to 0 if VM is not available */ if (MNSISUP(VM->State) && (VM->State != mnsUnknown)) { VM->ARes.Procs = strtol(ValAsString,NULL,0); } else { VM->ARes.Procs = 0; } break; case mvmaCDisk: VM->CRes.Disk = strtol(ValAsString,NULL,0); break; case mvmaCMem: VM->CRes.Mem = strtol(ValAsString,NULL,0); break; case mvmaCProcs: VM->CRes.Procs = strtol(ValAsString,NULL,0); break; case mvmaCPULoad: VM->CPULoad = strtod(ValAsString,NULL); break; case mvmaDescription: MUStrDup(&VM->Description,ValAsString); break; case mvmaEffectiveTTL: VM->EffectiveTTL = strtol(ValAsString,NULL,10); break; case mvmaFlags: bmfromstring((char *)Value,MVMFlags,&VM->Flags); break; case mvmaGMetric: { char *GMTok; char *GMName; char *GMVal; char *TokPtr = NULL; char *TokPtr2 = NULL; int gmindex; /* generic metrics */ /* FORMAT: <GMETRIC>{:=}<VAL>[,<GMETRIC>{:=}<VAL>]... */ GMTok = MUStrTok((char *)Value,", \t\n",&TokPtr); while (GMTok != NULL) { GMName = MUStrTok(GMTok,"=:",&TokPtr2); GMVal = MUStrTok(NULL,"=:",&TokPtr2); GMTok = MUStrTok(NULL,", \t\n",&TokPtr); if ((GMName == NULL) || (GMVal == NULL)) { /* mal-formed value, ignore */ continue; } gmindex = MUMAGetIndex(meGMetrics,GMName,mAdd); if ((gmindex <= 0) || (gmindex >= MSched.M[mxoxGMetric])) continue; /* valid gmetric located */ MVMSetGMetric(VM,gmindex,GMVal); } /* END while (GMTok != NULL) */ } /* END BLOCK (case mvmaGMetric) */ break; case mvmaID: MUStrCpy(VM->VMID,ValAsString,sizeof(VM->VMID)); break; case mvmaLastMigrateTime: VM->LastMigrationTime = (mulong)strtol(ValAsString,NULL,10); break; case mvmaLastSubState: MUStrDup(&VM->LastSubState,ValAsString); break; case mvmaLastSubStateMTime: VM->LastSubStateMTime = (mulong)strtol(ValAsString,NULL,10); break; case mvmaMigrateCount: VM->MigrationCount = (int)strtol(ValAsString,NULL,10); break; case mvmaNextOS: { int OS = MUMAGetIndex(meOpsys,ValAsString,mSet); if (OS != 0) VM->NextOS = OS; /*TODO: what if OS is not in VM's OSList? */ } case mvmaNodeTemplate: case mvmaOSList: case mvmaSlotIndex: case mvmaState: break; case mvmaSovereign: { mbool_t WasSovereign = bmisset(&VM->Flags,mvmfSovereign); mbool_t NewVal = MUBoolFromString(ValAsString,FALSE); if (NewVal == TRUE) bmset(&VM->Flags,mvmfSovereign); else bmunset(&VM->Flags,mvmfSovereign); if ((!bmisset(&VM->Flags,mvmfSovereign)) && (WasSovereign == TRUE)) { if (VM->J != NULL) { /* is this how to handle previously sovereign VMs correctly? */ bmset(&VM->J->IFlags,mjifCancel); } } } break; case mvmaSpecifiedTTL: VM->SpecifiedTTL = strtol(ValAsString,NULL,10); break; case mvmaStartTime: VM->StartTime = (mulong)strtol(ValAsString,NULL,10); break; case mvmaSubState: if (ValAsString == NULL) { MUFree(&VM->SubState); } else { MUStrDup(&VM->SubState,(char *)ValAsString); } break; case mvmaStorageRsvNames: MUStrDup(&VM->StorageRsvNames,(char *)ValAsString); break; case mvmaVariables: if (Mode == mSet) { /* Clear the current attrs */ MUHTClear(&VM->Variables,TRUE,(mfree_t)MUFree); } /* FORMAT: attr:value[+attr:value]... */ /* value is a string (alphanumeric and '_') */ if ((Mode == mAdd) || (Mode == mSet)) { char *ptr; char *TokPtr = NULL; char *TokPtr2 = NULL; ptr = MUStrTok((char *)ValAsString,"+",&TokPtr); while (ptr != NULL) { char *AName; char *AVal; char *MallocVal = NULL; char ANameNoQuotes[MMAX_LINE]; AName = MUStrTok(ptr,":",&TokPtr2); AVal = MUStrTok(NULL,":",&TokPtr2); MUStrReplaceStr(AName,"\"","",ANameNoQuotes,sizeof(ANameNoQuotes)); if (AVal != NULL) { int AValLen = (strlen(AVal) * sizeof(char)) + 1; MallocVal = (char *)MUMalloc(AValLen); MUStrReplaceStr(AVal,"\"","",MallocVal,strlen(AVal) + 1); } MUHTAdd(&VM->Variables,ANameNoQuotes,(void *)MallocVal,NULL,MUFREE); ptr = MUStrTok(NULL,"+",&TokPtr); } /* END while (ptr != NULL) */ } /* END if ((Mode == mAdd) || (Mode == mSet)) */ break; case mvmaTrigger: if (Format == mdfString) { mtrig_t *T; marray_t TList; int tindex; MUArrayListCreate(&TList,sizeof(mtrig_t *),10); if (MTrigLoadString( &VM->T, (char *)Value, TRUE, FALSE, mxoxVM, VM->VMID, &TList, NULL) == FAILURE) { return(FAILURE); } for (tindex = 0; tindex < TList.NumItems;tindex++) { T = (mtrig_t *)MUArrayListGetPtr(&TList,tindex); if (MTrigIsValid(T) == FALSE) continue; MTrigInitialize(T); MOAddTrigPtr(&VM->T,T); } /* END for (tindex) */ return(SUCCESS); } /* END if (Format == mdfString) */ /* END BLOCK mvmaTrigger */ break; case mvmaNONE: case mvmaLAST: default: break; } /* END switch (AIndex) */ return(SUCCESS); } /* END MVMSetAttr() */
int MGroupAdd( char *GName, /* I */ mgcred_t **GP) /* O (optional) */ { int gindex; unsigned long hashkey; mgcred_t *Gtmp; const char *FName = "MGroupAdd"; DBG(6,fSTRUCT) DPrint("%s(%s,%s)\n", FName, (GName != NULL) ? "GName" : "NULL", (GP != NULL) ? "GP" : "NULL"); if ((GName == NULL) || (GName[0] == '\0')) { return(FAILURE); } if (GP != NULL) *GP = NULL; hashkey = MAX(1,MUGetHash(GName) % MAX_MGROUP); for (gindex = hashkey; gindex < MAX_MGROUP + MAX_MHBUF; gindex++) { Gtmp = &MGroup[gindex]; /* if group already in hash table */ if (hashkey == Gtmp->Key) { if (!strcmp(Gtmp->Name,GName)) { if (GP != NULL) *GP = Gtmp; return(SUCCESS); } } /* if empty slot found */ if (Gtmp->Key == 0) { /* setup new record */ if (GP != NULL) *GP = Gtmp; Gtmp->Key = hashkey; Gtmp->Index = gindex; MUStrCpy(Gtmp->Name,GName,sizeof(Gtmp->Name)); if (strcmp(GName,ALL) && strcmp(GName,NONE)) { /* update group record */ if (MSched.Mode != msmSim) MCPRestore(mcpGroup,GName,(void *)Gtmp); Gtmp->OID = MUGIDFromName(Gtmp->Name); DBG(5,fSTRUCT) DPrint("INFO: group %s added\n", GName); } else { /* NYI */ } return(SUCCESS); } } /* END for (gindex) */ /* end of table reached */ DBG(1,fSTRUCT) DPrint("ALERT: group table overflow. cannot add %s\n", GName); return(FAILURE); } /* END MGroupAdd() */
char *MGroupShow( mgcred_t *G, /* I */ char *SBuffer, /* O (optional) */ long *SBufSize, /* I */ long Mode) /* I */ { static char Line[MAX_MLINE]; char FlagLine[MAX_MLINE]; char QALLine[MAX_MLINE]; char QALChar; char GLLine[MAX_MLINE]; char *Head; char *BPtr; int BSpace; const char *FName = "MGroupShow"; DBG(3,fUI) DPrint("%s(%s,Buf,BufSize,%ld)\n", FName, (G != NULL) ? G->Name : "NULL", Mode); if (SBuffer != NULL) { BPtr = SBuffer; BSpace = *SBufSize; } else { BPtr = Line; BSpace = sizeof(Line); } BPtr[0] = '\0'; Head = BPtr; if (G == NULL) { /* build header */ /* NAME PRI FLAG QDEF QLST * PLST TRG LIMITS */ MUSNPrintF(&BPtr,&BSpace,"%-12s %8s %12s %12s %12s%s %20s %6s %7s\n\n", "Name", "Priority", "Flags", "QDef", "QOSList", "*", "PartitionList", "Target", "Limits"); } else { /* build job info line */ MUBMToString(G->F.JobFlags,MJobFlags,':',FlagLine,NONE); MUStrCpy(QALLine,MQOSBMToString(G->F.QAL),sizeof(QALLine)); if (G->F.QALType == qalAND) QALChar = '&'; else if (G->F.QALType == qalONLY) QALChar = '^'; else QALChar = ' '; MUStrCpy(GLLine, MCredShowAttrs(&G->L.AP,G->L.IP,NULL,NULL,NULL,&G->F,0,(1 << mcsLimits)),sizeof(GLLine)); /* NAME PRIO FLAG QDEF QLST * PLST FSTARG LIMITS */ MUSNPrintF(&BPtr,&BSpace,"%-12s %8ld %12s %12s %12s%c %20s %6.2lf %7s\n", G->Name, G->F.Priority, FlagLine, ((mqos_t *)G->F.QDef) != NULL ? ((mqos_t *)G->F.QDef)->Name : NONE, (QALLine[0] != '\0') ? QALLine : NONE, QALChar, (G->F.PAL[0] == 0) ? NONE : MUListAttrs(ePartition,G->F.PAL[0]), G->F.FSTarget, (GLLine[0] != '\0') ? GLLine : NONE); /* add group attributes */ if (G->L.APC != NULL) { int cindex; for (cindex = 0; cindex < MAX_MCLASS; cindex++) { if (G->L.APC[cindex].SLimit[mptMaxProc][0] > 0) { MUSNPrintF(&BPtr,&BSpace," MAXPROC[CLASS:%s]=%d,%d\n", MClass[cindex].Name, G->L.APC[cindex].SLimit[mptMaxProc][0], G->L.APC[cindex].HLimit[mptMaxProc][0]); } } /* END for (cindex) */ } /* END if (G->L.APC != NULL) */ if (G->L.APQ != NULL) { int cindex; for (cindex = 0; cindex < MAX_MQOS; cindex++) { if (G->L.APQ[cindex].SLimit[mptMaxProc][0] > 0) { MUSNPrintF(&BPtr,&BSpace," MAXPROC[QOS:%s]=%d,%d\n", MQOS[cindex].Name, G->L.APQ[cindex].SLimit[mptMaxProc][0], G->L.APQ[cindex].HLimit[mptMaxProc][0]); } } /* END for (cindex) */ } /* END if (G->L.APQ != NULL) */ if (Mode & (1 << mcmVerbose)) { char tmpLine[MAX_MLINE]; /* display additional attributes */ MCredConfigLShow( (void *)G, mxoGroup, TRUE, -1, tmpLine); if (tmpLine[0] != '\0') { MUSNPrintF(&BPtr,&BSpace," %s\n", tmpLine); } } /* END if (Mode == Verbose) */ } /* END else (G == NULL) */ return(Head); } /* END MGroupShow() */
int MCPCreate( char *CPFile) { int count; mckpt_t *CP; char tmpCPFileName[MAX_MLINE]; char tmpBuf[MAX_MBUFFER]; const char *FName = "MCPCreate"; DBG(3,fCKPT) DPrint("%s(%s)\n", FName, (CPFile != NULL) ? CPFile : "NULL"); if ((CPFile == NULL) || (CPFile[0] == '\0')) return(FAILURE); CP = &MCP; /* load old checkpoint file */ if (MCPIsSupported(CP,CP->DVersion) == TRUE) { if ((CP->OBuffer = MFULoad(CPFile,1,macmRead,&count,NULL)) == NULL) { DBG(1,fCKPT) DPrint("WARNING: cannot load checkpoint file '%s'\n", CPFile); } } else { CP->OBuffer = NULL; } MUStrCpy(tmpCPFileName,CPFile,sizeof(tmpCPFileName)); MUStrCat(tmpCPFileName,".tmp",sizeof(tmpCPFileName)); /* open checkpoint file */ if ((CP->fp = fopen(tmpCPFileName,"w+")) == NULL) { DBG(1,fCKPT) DPrint("WARNING: cannot open checkpoint file '%s'. errno: %d (%s)\n", CPFile, errno, strerror(errno)); return(FAILURE); } /* checkpoint scheduler, job, reservation, and node state information */ MSchedToString(&MSched,tmpBuf); MCPStoreObj(CP->fp,mcpSched,"sched",tmpBuf); MSysToString(&MSched,tmpBuf,TRUE); MCPStoreObj(CP->fp,mcpSys,"sys",tmpBuf); MCPStoreQueue(CP,MJob); MCPStoreResList(CP,MRes); MCPStoreSRList(CP,SRes); MCPStoreCluster(CP,MNode); MCPStoreUserList(CP,MUser); MCPStoreGroupList(CP,MGroup); MCPStoreAcctList(CP,MAcct); MCPWriteGridStats(CP->fp); MCPWriteSystemStats(CP->fp); fclose(CP->fp); MUStrCpy(tmpCPFileName,CPFile,sizeof(tmpCPFileName)); MUStrCat(tmpCPFileName,".1",sizeof(tmpCPFileName)); if (rename(CPFile,tmpCPFileName) == -1) { DBG(0,fCORE) DPrint("ERROR: cannot rename checkpoint file '%s' to '%s' errno: %d (%s)\n", CPFile, tmpCPFileName, errno, strerror(errno)); } MUStrCpy(tmpCPFileName,CPFile,sizeof(tmpCPFileName)); MUStrCat(tmpCPFileName,".tmp",sizeof(tmpCPFileName)); if (rename(tmpCPFileName,CPFile) == -1) { DBG(0,fCORE) DPrint("ERROR: cannot rename checkpoint file '%s' to '%s' errno: %d (%s)\n", tmpCPFileName, CPFile, errno, strerror(errno)); } return(SUCCESS); } /* END MCPCreate() */
long MUTimeFromString( char *TString) { long val; char *ptr1; char *ptr2; char *ptr3; char *ptr4; char *TokPtr; char Line[MAX_MLINE]; const char *FName = "MUTimeFromString"; DBG(2,fCONFIG) DPrint("%s(%s)\n", FName, (TString != NULL) ? TString : "NULL"); if (TString == NULL) return(0); if (!strcmp(TString,"INFINITY")) return(MAX_MTIME); if (strchr(TString,':') == NULL) { /* line specified as 'raw' seconds */ val = strtol(TString,NULL,0); DBG(4,fCONFIG) DPrint("INFO: string '%s' specified as seconds\n", TString); return(val); } else if (strchr(TString,'_') != NULL) { /* line specified as 'absolute' time */ MUStringToE(TString,&val); DBG(4,fCONFIG) DPrint("INFO: string '%s' specified as absolute time\n", TString); return(val); } /* line specified in 'military' time */ MUStrCpy(Line,TString,sizeof(Line)); ptr1 = NULL; ptr2 = NULL; ptr3 = NULL; ptr4 = NULL; if ((ptr1 = MUStrTok(Line,":",&TokPtr)) != NULL) { if ((ptr2 = MUStrTok(NULL,":",&TokPtr)) != NULL) { if ((ptr3 = MUStrTok(NULL,":",&TokPtr)) != NULL) { ptr4 = MUStrTok(NULL,":",&TokPtr); } } } if (ptr1 == NULL) { DBG(4,fCONFIG) DPrint("INFO: cannot read string '%s'\n", TString); return(0); } if (ptr4 == NULL) { /* adjust from HH:MM:SS to DD:HH:MM:SS notation */ ptr4 = ptr3; ptr3 = ptr2; ptr2 = ptr1; ptr1 = NULL; } val = (((ptr1 != NULL) ? atoi(ptr1) : 0) * 86400) + (((ptr2 != NULL) ? atoi(ptr2) : 0) * 3600) + (((ptr3 != NULL) ? atoi(ptr3) : 0) * 60) + (((ptr4 != NULL) ? atoi(ptr4) : 0) * 1); DBG(4,fCONFIG) DPrint("INFO: string '%s' -> %ld\n", TString, val); return(val); } /* END MUTimeFromString() */
double MLocalApplyCosts( mulong Duration, /* I */ int TC, /* I */ char *VarList) /* I */ { char tmpLine[MMAX_LINE]; char *ptr; char *TokPtr; int aindex; int tmpI; double Cost; char ValLine[MMAX_LINE]; const char *VName[] = { NONE, "collection", "querytype", NULL }; enum { mlvlNONE = 0, mlvlCollection, mlvlQueryType }; if ((Duration == 0) || (TC == 0) || (VarList == NULL) || (VarList[0] == '\0')) { return(0.0); } Cost = 0.0; MUStrCpy(tmpLine,VarList,sizeof(tmpLine)); /* FORMAT: <ATTR>=<VAL>[,<ATTR>=<VAL>]... */ ptr = MUStrTok(tmpLine,", \t\n",&TokPtr); while (ptr != NULL) { if (MUGetPair( ptr, /* I */ (const char **)VName, &aindex, /* O (attribute) */ NULL, FALSE, &tmpI, /* O (relative comparison) */ ValLine, /* O (value) */ sizeof(ValLine)) == FAILURE) { /* cannot parse value pair */ MDB(2,fSCHED) MLog("ALERT: cannot parse env variable '%s'\n", ptr); ptr = MUStrTok(NULL," \t\n",&TokPtr); continue; } switch (aindex) { case mlvlCollection: if (!strcasecmp(ValLine,"master")) Cost += 5000; else if (!strcasecmp(ValLine,"basic")) Cost += 1000; break; case mlvlQueryType: if (!strcasecmp(ValLine,"full")) Cost += 2000; else if (!strcasecmp(ValLine,"basic")) Cost += 400; break; default: /* ignore variable */ /* NO-OP */ break; } /* END switch (aindex) */ ptr = MUStrTok(NULL," \t\n",&TokPtr); } /* END while (ptr != NULL) */ return(Cost); } /* END MLocalApplyCosts() */
int MVMAToString( mvm_t *V, mnode_t *N, enum MVMAttrEnum AIndex, char *Buf, int BufSize, mbitmap_t *DModeBM) { if (BufSize <= 0) BufSize = MMAX_LINE; if (Buf == NULL) { return(FAILURE); } Buf[0] = '\0'; if (V == NULL) { return(FAILURE); } switch (AIndex) { case mvmaActiveOS: if (V->ActiveOS != 0) strcpy(Buf,MAList[meOpsys][V->ActiveOS]); break; case mvmaADisk: if ((V->ARes.Disk >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->ARes.Disk); } break; case mvmaAlias: { char *BPtr; int BSpace; mln_t *Alias = NULL; mbool_t AliasPrinted = FALSE; MUSNInit(&BPtr,&BSpace,Buf,BufSize); while (MULLIterate(V->Aliases,&Alias) == SUCCESS) { if (AliasPrinted) MUSNPrintF(&BPtr,&BSpace,","); MUSNPrintF(&BPtr,&BSpace,"%s", Alias->Name); AliasPrinted = TRUE; } } break; case mvmaAMem: if ((V->ARes.Mem >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->ARes.Mem); } break; case mvmaAProcs: if ((V->ARes.Procs >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->ARes.Procs); } break; case mvmaCDisk: if ((V->CRes.Disk >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->CRes.Disk); } break; case mvmaCPULoad: sprintf(Buf,"%f", V->CPULoad); break; case mvmaCMem: if ((V->CRes.Mem >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->CRes.Mem); } break; case mvmaCProcs: if ((V->CRes.Procs >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->CRes.Procs); } break; case mvmaContainerNode: if (V->N != NULL) { snprintf(Buf,BufSize,"%s",V->N->Name); } break; case mvmaDDisk: if ((V->DRes.Disk >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->DRes.Disk); } break; case mvmaDMem: if ((V->DRes.Mem >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->DRes.Mem); } break; case mvmaDProcs: if ((V->DRes.Procs >= 0) || (bmisset(DModeBM,mcmVerbose))) { sprintf(Buf,"%d", V->DRes.Procs); } break; case mvmaDescription: if ((V->Description != NULL) && (V->Description[0] != '\0')) { strcpy(Buf,V->Description); } break; case mvmaEffectiveTTL: { sprintf(Buf,"%ld",V->EffectiveTTL); } break; case mvmaFlags: { mstring_t tmp(MMAX_LINE); bmtostring(&V->Flags,MVMFlags,&tmp); MUStrCpy(Buf,tmp.c_str(),BufSize); } /* END BLOCK (case mvmaFlags) */ break; case mvmaGMetric: { MVMGMetricAToString(V->GMetric,Buf,BufSize,DModeBM); #if 0 char *BPtr; int BSpace; int gmindex; /* FORMAT: GMETRIC=<GMNAME>:<VAL>[,<GMNAME>:<VAL>]... */ MUSNInit(&BPtr,&BSpace,Buf,BufSize); if (V->GMetric != NULL) { for (gmindex = 1;gmindex < MSched.M[mxoxGMetric];gmindex++) { if (V->GMetric[gmindex] == NULL) { continue; } if (MGMetric.Name[gmindex][0] == '\0') break; if (V->GMetric[gmindex]->SampleCount <= 0) continue; if (Buf[0] != '\0') MUSNCat(&BPtr,&BSpace,","); if (bmisset(DModeBM,mcmUser)) { /* NOTE: 0th entry in MAList is always "NONE" */ MUSNPrintF(&BPtr,&BSpace,"%s=%.2f", MGMetric.Name[gmindex], V->GMetric[gmindex]->IntervalLoad); } else { MUSNPrintF(&BPtr,&BSpace,"%s:%.2f", MGMetric.Name[gmindex], V->GMetric[gmindex]->IntervalLoad); } } /* END for (gmindex) */ } /* END if (V->GMetric != NULL) */ #endif } /* END BLOCK (case mvmaGMetric) */ break; case mvmaID: if (V->VMID[0] != '\0') strcpy(Buf,V->VMID); break; case mvmaJobID: if (V->JobID[0] != '\0') strcpy(Buf,V->JobID); break; case mvmaLastMigrateTime: if (V->LastMigrationTime > 0) sprintf(Buf,"%lu",V->LastMigrationTime); break; case mvmaLastSubState: if (V->LastSubState != NULL) MUStrCpy(Buf,V->LastSubState,BufSize); break; case mvmaLastSubStateMTime: if (V->LastSubStateMTime > 0) sprintf(Buf,"%lu",V->LastSubStateMTime); break; case mvmaLastUpdateTime: if (V->UpdateTime <= 0) { /* What happens in this case? */ } else { sprintf(Buf,"%lu",V->UpdateTime); } break; case mvmaMigrateCount: if (V->MigrationCount > 0) sprintf(Buf,"%d",V->MigrationCount); break; case mvmaNextOS: if ((V->NextOS > 0) && (V->NextOS != V->ActiveOS)) { strcpy(Buf,MAList[meOpsys][V->NextOS]); } break; case mvmaNetAddr: if (V->NetAddr != NULL) MUStrCpy(Buf,V->NetAddr,BufSize); break; case mvmaOSList: if (V->OSList != NULL) { char *BPtr; int BSpace; int osindex; MUSNInit(&BPtr,&BSpace,Buf,BufSize); for (osindex = 0;V->OSList[osindex].AIndex > 0;osindex++) { if (Buf[0] != '\0') { MUSNPrintF(&BPtr,&BSpace,",%s", MAList[meOpsys][V->OSList[osindex].AIndex]); } else { MUSNCat(&BPtr,&BSpace,MAList[meOpsys][V->OSList[osindex].AIndex]); } } /* END for (osindex) */ } /* END if (V->OSList != NULL) */ break; case mvmaPowerIsEnabled: { mbool_t IsOn = TRUE; switch (V->PowerState) { case mpowOff: IsOn = FALSE; break; default: break; } strcpy(Buf,MBool[IsOn]); } /* END BLOCK */ break; case mvmaPowerState: if (V->PowerState != mpowNONE) { strcpy(Buf,MPowerState[V->PowerState]); } break; case mvmaProvData: { mstring_t tmp(MMAX_LINE); /* sync with MNodeSetAttr#mnaProvData */ mnode_t tmpN; memset(&tmpN,0,sizeof(tmpN)); tmpN.ActiveOS = V->ActiveOS; tmpN.NextOS = V->NextOS; tmpN.LastOSModRequestTime = V->LastOSModRequestTime; tmpN.OSList = (V->N == NULL) ? NULL : V->N->VMOSList; if (tmpN.OSList == NULL) { tmpN.OSList = MSched.DefaultN.VMOSList; if (tmpN.OSList == NULL) /* No valid OS information */ break; } MNodeAToString(&tmpN,mnaProvData,&tmp,DModeBM); MUStrCpy(Buf,tmp.c_str(),BufSize); } /* END BLOCK */ break; case mvmaRackIndex: if (V->Rack >= 0) { sprintf(Buf,"%d", V->Rack); } break; case mvmaSlotIndex: if (V->Slot >= 0) { sprintf(Buf,"%d", V->Slot); } break; case mvmaSpecifiedTTL: { sprintf(Buf,"%ld",V->SpecifiedTTL); } break; case mvmaStartTime: { sprintf(Buf,"%lu",V->StartTime); } break; case mvmaState: if (V->State != mnsNONE) { strcpy(Buf,MNodeState[V->State]); } break; case mvmaSubState: if ((bmisset(&V->Flags,mvmfInitializing)) && (V->SubState != NULL) && (strstr(V->SubState,"pbs"))) { strcpy(Buf,"rminitializing"); } else if (V->SubState != NULL) { MUStrCpy(Buf,V->SubState,BufSize); } break; case mvmaStorageRsvNames: if (V->StorageRsvs != NULL) { char *BPtr; int BSpace; mln_t *LLIter = NULL; MUSNInit(&BPtr,&BSpace,Buf,BufSize); while (MULLIterate(V->StorageRsvs,&LLIter) == SUCCESS) { if (Buf[0] != '\0') MUSNPrintF(&BPtr,&BSpace,","); MUSNPrintF(&BPtr,&BSpace,"%s", ((mrsv_t *)LLIter->Ptr)->Name); } } /* END case mvmaStorageRsvNames */ break; case mvmaTrackingJob: if ((V->TrackingJ != NULL) && (V->TrackingJ->Name != NULL)) MUStrCpy(Buf,V->TrackingJ->Name,BufSize); break; case mvmaVariables: if (V->Variables.NumItems > 0) { char *BPtr; int BSpace; char *VarName; char *VarValue; mhashiter_t VarIter; MUHTIterInit(&VarIter); MUSNInit(&BPtr,&BSpace,Buf,BufSize); while (MUHTIterate(&V->Variables,&VarName,(void **)&VarValue,NULL,&VarIter) == SUCCESS) { if (Buf[0] != '\0') { MUSNPrintF(&BPtr,&BSpace,"+%s", VarName); } else { MUSNPrintF(&BPtr,&BSpace,"%s", VarName); } /* Add the value, if its not null */ if (VarValue != NULL) { MUSNCat(&BPtr,&BSpace,":"); MUSNCat(&BPtr,&BSpace,VarValue); } } /* END while (MUHTIterate(...) == SUCCESS) */ } /* END case mvmaAttrs */ break; default: /* NO-OP */ break; } /* END switch (AIndex) */ return(SUCCESS); } /* END MVMAToString() */
char *MUUIDToName( int UID, /* I */ char *NameBuf) /* O */ { struct passwd *bufptr = NULL; struct passwd buf; char pwbuf[MMAX_BUFFER]; #ifndef MNOREENTRANT int rc = 0; #endif /* !MNOREENTRANT */ const char *FName = "MUUIDToName"; MDB(10,fSTRUCT) MLog("%s(%d,NameBuf)\n", FName, UID); if (NameBuf == NULL) { return(NULL); } if (UID == -1) { strcpy(NameBuf,NONE); return(NameBuf); } pwbuf[0] = '\0'; errno = 0; /* getpwuid_r() will return positive value on FAILURE */ #ifndef MNOREENTRANT rc = getpwuid_r(UID,&buf,pwbuf,sizeof(pwbuf),&bufptr); if ((rc != 0) || (bufptr == NULL)) { snprintf(NameBuf,MMAX_NAME,"UID%d", UID); } else { MUStrCpy(NameBuf,bufptr->pw_name,MMAX_NAME); } #else bufptr = getpwuid(UID); if (bufptr == NULL) { sprintf(NameBuf,"UID%d", UID); } else { strcpy(NameBuf,bufptr->pw_name); } #endif /* !MNOREENTRANT */ return(NameBuf); } /* END MUUIDToName() */
int MTraceLoadResource( char *Buffer, /* I */ int *TraceLen, /* I */ mnode_t *N, /* O (modified) */ int *Version) /* O (optional) */ { char Line[MAX_MLINE]; char *ptr; char *tail; char *head; int rc; int RType; enum { mrtNONE = 0, mrtComputeNode, mrtNetwork, mrtHSM }; const char *FName = "MTraceLoadResource"; DBG(5,fSIM) DPrint("%s(Buffer,TraceLen,N,%d)\n", FName, (Version != NULL) ? *Version : -1); if ((Buffer == NULL) || (N == NULL)) { return(FAILURE); } head = Buffer; if ((tail = strchr(head,'\n')) == NULL) { tail = head + strlen(head); if (tail - head < 20) { if (TraceLen != NULL) *TraceLen = 0; return(FAILURE); } } if (TraceLen != NULL) *TraceLen = (tail - head) + 1; for (ptr = head;*ptr != '\0';ptr++) { /* remove leading whitespace */ if (!isspace(*ptr)) break; } /* END for (ptr) */ if (ptr >= tail) { return(FAILURE); } MUStrCpy(Line,ptr,MIN(sizeof(Line),tail - ptr + 1)); /* eliminate comments */ if ((ptr = strchr(Line,'#')) != NULL) { DBG(5,fSIM) DPrint("INFO: detected trace comment line, '%s'\n", Line); *ptr = '\0'; } if (strlen(Line) == 0) { return(FAILURE); } /* look for version settings */ if (!strncmp(Line,TRACE_RESOURCE_VERSION_MARKER,strlen(TRACE_RESOURCE_VERSION_MARKER))) { if (MTraceGetResourceVersion(Line,Version) == FAILURE) { DBG(0,fSIM) DPrint("ALERT: cannot determine resource trace version\n"); /* assume default version */ if (Version != NULL) *Version = DEFAULT_RESOURCE_TRACE_VERSION; } else { DBG(3,fSIM) DPrint("INFO: resource trace version %d detected\n", (Version != NULL) ? *Version : -1); } return(FAILURE); } DBG(5,fSIM) DPrint("INFO: parsing line '%s' (len: %d)\n", Line, *TraceLen); { int VIndex; if (Version != NULL) VIndex = *Version; else VIndex = -1; switch (VIndex) { case 230: default: if (!strncmp(Line,"COMPUTENODE",strlen("COMPUTENODE"))) RType = mrtComputeNode; else if (!strncmp(Line,"NETWORK",strlen("NETWORK"))) RType = mrtNetwork; else if (!strncmp(Line,"HSM",strlen("HSM"))) RType = mrtHSM; else RType = mrtComputeNode; break; } /* END switch (VIndex) */ switch(RType) { case mrtComputeNode: rc = MTraceLoadComputeNode(Line,N,VIndex); break; case mrtNetwork: rc = MTraceLoadNetwork(Line,N,VIndex); break; case mrtHSM: rc = MTraceLoadHSM(Line,N,VIndex); break; default: rc = FAILURE; break; } /* END switch (RType) */ } /* END BLOCK */ return(rc); } /* END MTraceLoadResource() */
int MUUIDFromName( char *Name, /* I */ char *HomeDir, /* O (optional,minsize=MMAX_LINE) */ char *EMsg) /* O (optional,minzise=MMAX_LINE) */ { #define UTILUIDHEADER "UID" struct passwd *bufptr = NULL; struct passwd buf; char pwbuf[MMAX_BUFFER]; #ifndef MNOREENTRANT int rc = 0; #endif /* !MNOREENTRANT */ const char *FName = "MUUIDFromName"; MDB(10,fSTRUCT) MLog("%s(%s,HomeDir,EMsg)\n", FName, (Name != NULL) ? Name : "NULL"); if (EMsg != NULL) EMsg[0] = '\0'; if (HomeDir != NULL) HomeDir[0] = '\0'; if ((Name == NULL) || !strcmp(Name,NONE) || !strcmp(Name,ALL) || !strcmp(Name,"ALL")) { if (EMsg != NULL) sprintf(EMsg,"user name '%s' is invalid", (Name != NULL) ? Name : ""); return(-1); } #ifndef MNOREENTRANT /* getpwnam_r() will return positive value on FAILURE */ rc = getpwnam_r(Name,&buf,pwbuf,sizeof(pwbuf),&bufptr); if ((rc != 0) || (bufptr == NULL)) { /* look for UID??? format */ if (!strncmp(Name,UTILUIDHEADER,strlen(UTILUIDHEADER))) { return(atoi(Name + strlen(UTILUIDHEADER))); } if (EMsg != NULL) snprintf(EMsg,MMAX_LINE,"cannot lookup user '%s' - errno=%d %s", Name, errno, strerror(errno)); MDB(3,fSTRUCT) MLog("cannot lookup user '%s' - errno=%d %s\n", Name, errno, strerror(errno)); return(-1); } #else bufptr = getpwnam(Name); if (bufptr == NULL) { /* look for UID??? format */ if (!strncmp(Name,UTILUIDHEADER,strlen(UTILUIDHEADER))) { return(atoi(Name + strlen(UTILUIDHEADER))); } if (EMsg != NULL) snprintf(EMsg,MMAX_LINE,"cannot lookup user '%s' - errno=%d %s", Name, errno, strerror(errno)); MDB(3,fSTRUCT) MLog("cannot lookup user '%s' - errno=%d %s\n", Name, errno, strerror(errno)); return(-1); } #endif /* !MNOREENTRANT */ if (HomeDir != NULL) { MUStrCpy(HomeDir,bufptr->pw_dir,MMAX_LINE); MDB(7,fSTRUCT) MLog("setting user %s's home dir to '%s'\n", (Name != NULL) ? Name : "NULL", HomeDir); } return(bufptr->pw_uid); } /* END MUUIDFromName() */
int MTraceLoadComputeNode( char *NodeLine, /* I */ mnode_t *N, /* O */ int Version) /* I */ { char *tok; char *TokPtr; char tmpLine[MAX_MLINE]; char tmpNLine[MAX_MLINE]; char ResourceType[MAX_MNAME]; char EventType[MAX_MNAME]; long ETime; char Name[MAX_MNAME]; char OpsysString[MAX_MNAME]; char ArchString[MAX_MNAME]; char FeatureString[MAX_MLINE]; char ClassString[MAX_MLINE]; char NetworkString[MAX_MLINE]; char GResString[MAX_MLINE]; char tmpSwapBuf[MAX_MNAME]; char tmpMemBuf[MAX_MNAME]; char tmpDiskBuf[MAX_MNAME]; int SlotsUsed; char RMName[MAX_MNAME]; int FIndex; int SIndex; int cindex; int rc; /* set default resource attributes */ memset(N,0,sizeof(mnode_t)); N->Load = 0.0; N->Speed = 1.0; N->PtIndex = 0; switch(Version) { case 230: if (strchr(NodeLine,';') != NULL) { sprintf(tmpNLine,"IFS-;%.*s", MAX_MLINE, NodeLine); } else { MUStrCpy(tmpNLine,NodeLine,sizeof(tmpNLine)); } /* FORMAT: <RESOURCETYPE> <EVENTTYPE> <EVENTTIME> <NAME> <RMINDEX> <SWAP> <MEMORY> <DISK> <MAXPROCS> <SLOTSUSED> <FRAMEINDEX> <SLOTINDEX> <OPSYS> <ARCH> [<FEATURE>]* [<CLASS>]* [<NETWORK>]* [<GRES>]* <RES1> <RES2> <RES3> */ rc = MUSScanF(tmpNLine,"%x%s %x%s %ld %x%s %x%s %x%s %x%s %x%s %d %d %d %d %x%s %x%s %x%s %x%s %x%s %x%s %x%s %x%s %x%s %x%s", MAX_MNAME, ResourceType, MAX_MNAME, EventType, &ETime, MAX_MNAME, Name, MAX_MNAME, RMName, MAX_MNAME, tmpSwapBuf, MAX_MNAME, tmpMemBuf, MAX_MNAME, tmpDiskBuf, &N->CRes.Procs, &FIndex, &SIndex, &SlotsUsed, MAX_MNAME, OpsysString, MAX_MNAME, ArchString, MAX_MLINE, FeatureString, MAX_MLINE, ClassString, MAX_MLINE, NetworkString, MAX_MLINE, GResString, MAX_MLINE, tmpLine, /* RES1 */ MAX_MLINE, tmpLine, /* RES2 */ MAX_MLINE, tmpLine, /* RES3 */ MAX_MLINE, tmpLine /* check for too many lines */ ); if ((rc == EOF) || (rc != 21)) { DBG(3,fSIM) DPrint("ALERT: resource tracefile corruption (%d of %d fields detected) on line '%s'\n", rc, 21, NodeLine); return(FAILURE); } /* process node attributes */ N->CRes.Swap = MURSpecToL(tmpSwapBuf,mvmMega,mvmMega); N->CRes.Mem = MURSpecToL(tmpMemBuf,mvmMega,mvmMega); N->CRes.Disk = MURSpecToL(tmpDiskBuf,mvmMega,mvmMega); if (!strcmp(RMName,NONE)) MRMAdd(RMName,&N->RM); else MRMAdd(DEFAULT,&N->RM); /* load Opsys */ if (strstr(OpsysString,MAList[eOpsys][0]) == NULL) N->ActiveOS = MUMAGetIndex(eOpsys,OpsysString,mAdd); /* load Arch */ if (strstr(ArchString,MAList[eArch][0]) == NULL) N->Arch = MUMAGetIndex(eArch,ArchString,mAdd); memcpy(&N->ARes,&N->CRes,sizeof(N->ARes)); strcpy(N->Name,MNodeAdjustName(Name,0)); /* load classes */ if (MSim.Flags & ((1 << msimfIgnClass) | (1 << msimfIgnAll))) { mclass_t *C; /* ignore specified classes */ MClassAdd("DEFAULT",&C); N->CRes.PSlot[0].count = N->CRes.Procs; N->CRes.PSlot[C->Index].count = N->CRes.Procs; } else { MUNumListFromString(N->CRes.PSlot,ClassString,eClass); for (cindex = 1;cindex < MAX_MCLASS;cindex++) { if (N->CRes.PSlot[cindex].count > 0) MClassAdd(MAList[eClass][cindex],NULL); } } memcpy(N->ARes.PSlot,N->CRes.PSlot,sizeof(N->ARes.PSlot)); break; default: DBG(4,fSIM) DPrint("ALERT: cannot load version %d resource trace record\n", Version); return(FAILURE); /*NOTREACHED*/ break; } /* END switch(Version) */ if ((MSim.Flags & ((1 << msimfIgnFrame) | (1 << msimfIgnAll))) || (FIndex < 0)) { N->FrameIndex = -1; N->SlotIndex = -1; } else { MFrameAddNode(&MFrame[FIndex],N,SIndex); if ((N->FrameIndex > 0) && (N->FrameIndex < MAX_MFRAME) && (N->SlotIndex > 0) && (N->SlotIndex <= MAX_MSLOTPERFRAME)) { mhost_t *S; int nindex; S = &MSys[N->FrameIndex][N->SlotIndex]; S->SlotsUsed = SlotsUsed; for (nindex = 0;nindex < MAX_MNETTYPE;nindex++) strcpy(S->NetName[nindex],N->Name); if (!strstr(ClassString,"NONE")) S->Attributes |= (1 << attrBatch); S->MTime = MSched.Time; } /* END if ((N->FrameIndex > 0) ... ) */ } /* END else if (MSim.Flags & ((1 << msimfIgnFrame) | ...)) */ /* initialize statistics */ N->STTime = 0; N->SUTime = 0; N->SATime = 0; /* load state */ if (N->CRes.Procs <= 0) { N->State = mnsNone; } else { if (!strcmp(EventType,"AVAILABLE")) N->State = mnsIdle; else if (!strcmp(EventType,"DEFINED")) N->State = mnsDown; else if (!strcmp(EventType,"DRAINED")) N->State = mnsDrained; else N->State = mnsNONE; } /* END else (N->CRes.Procs <= 0) */ N->EState = N->State; memcpy(&N->ARes,&N->CRes,sizeof(N->ARes)); /* load features */ if (strstr(FeatureString,MAList[eFeature][0]) == NULL) { tok = MUStrTok(FeatureString,"[]",&TokPtr); do { MNodeProcessFeature(N,tok); DBG(6,fSIM) DPrint("INFO: feature '%s' added (%s)\n", tok, MUMAList(eFeature,N->FBM,sizeof(N->FBM))); } while ((tok = MUStrTok(NULL,"[]",&TokPtr)) != NULL); } /* load network adapters */ if (strstr(NetworkString,MAList[eNetwork][0]) == NULL) { tok = MUStrTok(NetworkString,"[]",&TokPtr); do { N->Network |= MUMAGetBM(eNetwork,tok,mAdd); DBG(6,fSIM) DPrint("INFO: network '%s' added (%s)\n", tok, MUListAttrs(eNetwork,N->Network)); } while ((tok = MUStrTok(NULL,"[]",&TokPtr)) != NULL); } /* load generic resources */ if (!strcmp(GResString,NONE) != 0) { MUNumListFromString(N->CRes.GRes,GResString,eGRes); } DBG(4,fSIM) DPrint("INFO: node '%s' F:%d/S:%d %06d %04d %06d %02d %02d %10s %10s %20s %20s\n", N->Name, N->FrameIndex, N->SlotIndex, N->CRes.Swap, N->CRes.Mem, N->CRes.Disk, N->CRes.Procs, SlotsUsed, OpsysString, ArchString, FeatureString, MUCAListToString(N->CRes.PSlot,NULL,NULL)); return(SUCCESS); } /* END MTraceLoadComputeNode() */
int MCPRestore( int CKIndex, /* I */ char *OName, /* I */ void *O) /* I (modified) */ { int count; char *ptr; char *tmp; char Line[MAX_MLINE]; const char *FName = "MCPRestore"; DBG(4,fCKPT) DPrint("%s(%s,%s,Optr)\n", FName, MCPType[CKIndex], OName); if ((O == NULL) || (OName == NULL)) { return(FAILURE); } /* load checkpoint file */ if (MCP.Buffer == NULL) { if ((MCP.Buffer = MFULoad(MCP.CPFileName,1,macmWrite,&count,NULL)) == NULL) { DBG(1,fCKPT) DPrint("WARNING: cannot load checkpoint file '%s'\n", MCP.CPFileName); return(FAILURE); } } /* NOTE: CP version should be verified */ /* create header */ sprintf(Line,"%-9s %20s ", MCPType[CKIndex], OName); if ((ptr = strstr(MCP.Buffer,Line)) == NULL) { /* no checkpoint entry for object */ DBG(5,fCKPT) DPrint("INFO: no checkpoint entry for object '%s'\n", Line); return(SUCCESS); } /* terminate line */ if (((tmp = strchr(ptr,'\n')) != NULL) && (tmp - ptr < MAX_MLINE)) { MUStrCpy(Line,ptr,MIN(sizeof(Line),(tmp - ptr + 1))); } else { DBG(1,fCKPT) DPrint("WARNING: cannot read checkpoint line '%s'\n", Line); return(FAILURE); } switch(CKIndex) { case mcpJob: MJobLoadCP((mjob_t *)O,Line); break; case mcpNode: MNodeLoadCP((mnode_t *)O,Line); break; case mcpUser: MUserLoadCP((mgcred_t *)O,Line); break; case mcpGroup: MGroupLoadCP((mgcred_t *)O,Line); break; case mcpAcct: MAcctLoadCP((mgcred_t *)O,Line); break; case mcpSched: MCPLoadSched(&MCP,Line,(msched_t *)O); break; case mcpSys: MCPLoadSys(&MCP,Line,(msched_t *)O); break; case mcpSRes: /* NYI */ break; default: DBG(1,fCKPT) DPrint("ERROR: unexpected checkpoint type, %d, detected in %s()\n", CKIndex, FName); break; } /* END switch (CKIndex) */ return(SUCCESS); } /* END MCPRestore() */
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() */
int UIProcessCommand( msocket_t *S) /* I */ { char SBuffer[MAX_SBUFFER]; char Message[MAX_MLINE]; int HeadSize; int index; int sindex; int FLAGS; int hostcheck; char ServiceType[MAX_MLINE]; char Auth[MAX_MNAME]; char Passwd[MAX_MNAME]; int scode; int Align; char *ptr; char *ptr2; char *args; char *TokPtr; int rc; long tmpL; char tmpLine[MMAX_LINE]; const char *FName = "UIProcessCommand"; DBG(3,fUI) DPrint("%s(S)\n", FName); if (S == NULL) { return(FAILURE); } if (MSURecvData(S,MAX_SOCKETWAIT,TRUE,NULL,NULL) == FAILURE) { DBG(3,fSOCK) DPrint("ALERT: cannot read client packet\n"); return(FAILURE); } switch(S->WireProtocol) { case mwpXML: rc = MUISProcessRequest(S,Message); return(rc); /*NOTREACHED*/ break; default: break; } /* END switch(S->WireProtocol) */ memset(SBuffer,0,sizeof(SBuffer)); S->SBuffer = SBuffer; strcpy(CurrentHostName,S->Host); /* NOTE: not very threadsafe :) */ if ((X.XUIHandler != (int (*)())0) && ((*X.XUIHandler)(X.xd,S,MSched.DefaultCSKey,0) == SUCCESS)) { /* service handled externally */ return(SUCCESS); } if (MUISProcessRequest(S,Message) == SUCCESS) { /* new style client request received and processed */ return(SUCCESS); } /* locate/process args */ if ((args = strstr(S->RBuffer,MCKeyword[mckArgs])) == NULL) { DBG(3,fSOCK) DPrint("ALERT: cannot locate command arg\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate command args"); S->SBufSize = strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } *args = '\0'; args += strlen(MCKeyword[mckArgs]); /* get service */ ServiceType[0] = '\0'; if ((ptr = strstr(S->RBuffer,MCKeyword[mckCommand])) == NULL) { DBG(3,fSOCK) DPrint("ALERT: cannot locate command\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate command"); S->SBufSize = strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } ptr += strlen(MCKeyword[mckCommand]); MUStrCpy(ServiceType,ptr,sizeof(ServiceType)); for (ptr2 = &ServiceType[0];*ptr2 != '\0';ptr2++) { if (isspace(*ptr2)) { *ptr2 = '\0'; break; } } /* END for (ptr2) */ /* get authentication */ if ((ptr = strstr(S->RBuffer,MCKeyword[mckAuth])) == NULL) { DBG(3,fSOCK) DPrint("ALERT: cannot locate authentication\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate authentication"); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } ptr += strlen(MCKeyword[mckAuth]); MUStrCpy(Auth,ptr,sizeof(Auth)); /* FORMAT: <USERNAME>[:<PASSWORD>] */ for (ptr2 = &Auth[0];*ptr2 != '\0';ptr2++) { if (isspace(*ptr2)) { *ptr2 = '\0'; break; } } if ((ptr2 = MUStrTok(Auth,":",&TokPtr)) != NULL) { MUStrCpy(Passwd,ptr2,sizeof(Passwd)); } else { Passwd[0] = '\0'; } /* determine service */ if ((sindex = MUGetIndex(ServiceType,MService,0,0)) == 0) { DBG(3,fUI) DPrint("INFO: service '%s' not handled in %s\n", ServiceType, FName); sprintf(Message,"ERROR: cannot support service '%s'", ServiceType); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } DBG(3,fUI) DPrint("INFO: client '%s' read (%ld bytes) initiating service call for '%s' (Auth: %s)\n", S->Name, S->SBufSize, MService[sindex], Auth); /* fail if name is not recognized */ if (Auth[0] == '\0') { DBG(2,fUI) DPrint("WARNING: client id '%s' is unknown\n", Auth); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot authenticate client"); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } ServerGetAuth(Auth,&tmpL); FLAGS = (int)tmpL; switch(sindex) { /* admin1 functions */ case svcResetStats: case svcSched: case svcSetJobDeadline: case svcReleaseJobDeadline: case svcChangeParameter: case svcMigrateJob: case svcBNFQuery: case svcMGridCtl: case svcMJobCtl: case svcMNodeCtl: if (!(FLAGS & (1 << fAdmin1))) { sprintf(Message,"ERROR: user '%s' is not authorized to run command '%s'\n", Auth, MService[sindex]); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } hostcheck = FALSE; for (index = 0;index < MAX_MADMINHOSTS;index++) { if (MSched.AdminHost[index][0] == '\0') break; if (!strcasecmp(MSched.AdminHost[index],S->Host)) { hostcheck = TRUE; break; } if (!strcasecmp(MSched.AdminHost[index],"ALL")) { hostcheck = TRUE; break; } } /* END for (index) */ if (hostcheck == FALSE) { sprintf(Message,"ERROR: command '%s' cannot be executed from host '%s'\n", MService[sindex], S->Host); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } /* admin1 or admin2 function */ case svcSetJobSystemPrio: case svcRunJob: if (!(FLAGS & ((1 << fAdmin1) | (1 << fAdmin2)))) { sprintf(Message,"ERROR: user '%s' is not authorized to execute command '%s'\n", Auth, MService[sindex]); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } /* admin1, admin2, or admin3 functions */ case svcShowStats: case svcDiagnose: case svcShowJobDeadline: case svcShowConfig: case svcNodeShow: case svcShowEstimatedStartTime: case svcShowGrid: case svcClusterShow: if (!(FLAGS & ((1 << fAdmin1) | (1 << fAdmin2) | (1 << fAdmin3)))) { sprintf(Message,"ERROR: user '%s' is not authorized to execute command '%s'\n", Auth, MService[sindex]); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } /* global functions or case specific functions */ case svcResCreate: case svcResShow: case svcSetJobQOS: case svcCancelJob: case svcSetJobUserPrio: case svcJobShow: case svcShowQ: case svcSetJobHold: case svcReleaseJobHold: case svcResDestroy: case svcShowJobHold: case svcShowEarliestDeadline: case svcShowBackfillWindow: case svcMBal: if (sindex == svcMGridCtl) strcpy(Auth,S->Name); S->SBufSize = (long)sizeof(SBuffer); sprintf(tmpLine,"%s%d ", MCKeyword[mckStatusCode], scFAILURE); Align = (int)strlen(tmpLine) + (int)strlen(MCKeyword[mckArgs]); sprintf(S->SBuffer,"%s%*s%s", tmpLine, 16 - (Align % 16), " ", MCKeyword[mckArgs]); HeadSize = (int)strlen(SBuffer); S->SBufSize -= HeadSize + 1; if (Function[sindex] != NULL) scode = (*Function[sindex])(args,S->SBuffer + HeadSize,FLAGS,Auth,&S->SBufSize); else scode = FAILURE; ptr = S->SBuffer + strlen(MCKeyword[mckStatusCode]); *ptr = scode + '0'; S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); break; default: DBG(2,fUI) DPrint("WARNING: unexpected service (%d) requested (ignoring request)\n", sindex); sprintf(Message,"ERROR: service '%s' (%d) not implemented\n", ServiceType, sindex); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); break; } /* END switch(sindex) */ fflush(mlog.logfp); return(SUCCESS); } /* END UIProcessCommand() */
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() */
int MTraceLoadNetwork( char *NodeLine, /* I */ mnode_t *N, /* I/O */ int Version) /* I */ { char ResourceType[MAX_MNAME]; char EventType[MAX_MNAME]; char Name[MAX_MNAME]; long ETime; char ResType[MAX_MNAME]; char ResData[MAX_MNAME]; char tmpLine[MAX_MLINE]; int rindex; int rc; xres_t *R; if ((NodeLine == NULL) || (N == NULL)) { return(FAILURE); } switch (Version) { default: /* FORMAT: <RESOURCETYPE> <EVENTTYPE> <EVENTTIME> <NAME> <RESTYPE> <RESDATA> */ rc = MUSScanF(NodeLine,"%x%s %x%s %ld %x%s %x%s %x%s", MAX_MNAME, ResourceType, MAX_MNAME, EventType, &ETime, MAX_MNAME, Name, MAX_MNAME, ResType, MAX_MNAME, ResData); /* locate available X res slot */ for (rindex = 0;rindex < MAX_MNODE;rindex++) { R = &MPar[0].XRes[rindex]; if ((R->Name[0] != '\0') && (R->Name[0] != '\1')) { continue; } /* load xres driver */ MASGetDriver((void **)&R->Func,ResType,msdResource); /* create and initialize resource */ sprintf(tmpLine,"NAME=%s;STATE=ACTIVE;%s", Name, ResData); rc = (*R->Func)(&R->Data,mascCreate,tmpLine,NULL); MUStrCpy(R->Name,Name,sizeof(R->Name)); /* FIXME */ R->Type = msdResource; break; } break; } /* END switch(Version) */ return(rc); } /* END MTraceLoadNetwork() */
int MUIRsvCtl( msocket_t *S, /* I */ mbitmap_t *AFlags, /* I credential flags (bitmap of enum MRoleEnum) */ char *Auth) /* I */ { char Command[MMAX_NAME]; char RsvExp[MMAX_LINE]; char FlagString[MMAX_LINE]; char ArgString[MMAX_LINE]; marray_t RsvList; char tmpLine[MMAX_LINE << 3]; char tmpName[MMAX_LINE]; char tmpVal[MMAX_LINE]; enum MRsvCtlCmdEnum CIndex; enum MRsvAttrEnum AIndex; int rc; mrsv_t *R; mrm_t *RM; mgcred_t *U = NULL; mbool_t IsAdmin; mxml_t *RE = NULL; mxml_t *WE = NULL; mxml_t *DE = NULL; int rindex; mbitmap_t Flags; mbool_t UseUIndex = FALSE; mbool_t UseGName = FALSE; mbool_t AppendRsvExp = FALSE; mgcred_t *RU = NULL; mgcred_t *RG = NULL; mgcred_t *RA = NULL; mqos_t *RQ = NULL; enum MFormatModeEnum DFormat = mfmNONE; const char *FName = "MUIRsvCtl"; MDB(2,fUI) MLog("%s(S,%s)\n", FName, (Auth != NULL) ? Auth : "NULL"); if (S == NULL) { return(FAILURE); } /* NOTE: support create, destroy, list, modify */ /* initialize values */ S->WireProtocol = mwpS32; RsvExp[0] = '\0'; /* process request */ switch (S->WireProtocol) { case mwpXML: case mwpS32: { int WTok; /* FORMAT: <Request action="X" object="Y"><Where/></Request> */ char *ptr; if (S->RDE != NULL) { RE = S->RDE; } else if ((S->RPtr != NULL) && ((ptr = strchr(S->RPtr,'<')) != NULL) && (MXMLFromString(&RE,ptr,NULL,NULL) == FAILURE)) { MDB(3,fUI) MLog("WARNING: corrupt command '%100.100s' received\n", S->RBuffer); MUISAddData(S,"ERROR: corrupt command received\n"); return(FAILURE); } S->RDE = RE; if (MXMLGetAttr(RE,MSAN[msanAction],NULL,Command,sizeof(Command)) == FAILURE) { MDB(3,fUI) MLog("WARNING: cannot locate command '%100.100s'\n", S->RBuffer); MUISAddData(S,"ERROR: cannot locate command\n"); return(FAILURE); } WTok = -1; while (MS3GetWhere( RE, &WE, &WTok, tmpName, /* O */ sizeof(tmpName), tmpVal, /* O */ sizeof(tmpVal)) == SUCCESS) { /* process 'where' constraints */ AIndex = (enum MRsvAttrEnum)MUGetIndexCI(tmpName,MRsvAttr,FALSE,mraNONE); if ((AIndex == mraName) || (AIndex == mraUIndex) || (AIndex == mraRsvGroup)) { if (AppendRsvExp == TRUE) { MUStrCat(RsvExp,",",sizeof(RsvExp)); MUStrCat(RsvExp,tmpVal,sizeof(RsvExp)); } else { MUStrCpy(RsvExp,tmpVal,sizeof(RsvExp)); AppendRsvExp = TRUE; } if (AIndex == mraUIndex) UseUIndex = TRUE; else if (AIndex == mraRsvGroup) UseGName = TRUE; } else { switch (AIndex) { case mraAAccount: if (MAcctFind(tmpVal,&RA) == FAILURE) { MUISAddData(S,"ERROR: cannot locate requested account\n"); return(FAILURE); } break; case mraAGroup: if (MGroupFind(tmpVal,&RG) == FAILURE) { MUISAddData(S,"ERROR: cannot locate requested group\n"); return(FAILURE); } break; case mraAQOS: if (MQOSFind(tmpVal,&RQ) == FAILURE) { MUISAddData(S,"ERROR: cannot locate requested qos\n"); return(FAILURE); } break; case mraAUser: if (MUserFind(tmpVal,&RU) == FAILURE) { MUISAddData(S,"ERROR: cannot locate requested user\n"); return(FAILURE); } break; default: MUISAddData(S,"ERROR: incorrect reservation attribute\n"); return(FAILURE); /* NOTREACHED */ break; } /* END switch (AIndex) */ } /* END else */ } /* END while (MXMLGetChild() == SUCCESS) */ if (MXMLGetAttr(RE,MSAN[msanFlags],NULL,FlagString,sizeof(FlagString)) == SUCCESS) { bmfromstring(FlagString,MClientMode,&Flags); if (bmisset(&Flags,mcmXML)) { DFormat = mfmXML; } else { DFormat = mfmNONE; } } MXMLGetAttr(RE,MSAN[msanArgs],NULL,ArgString,sizeof(ArgString)); } /* END BLOCK (case mwpXML/mwpS3) */ break; default: /* not supported */ MUISAddData(S,"ERROR: corrupt command received\n"); return(FAILURE); /*NOTREACHED*/ break; } /* END switch (S->WireProtocol) */ /* process data */ if ((CIndex = (enum MRsvCtlCmdEnum)MUGetIndexCI( Command, MRsvCtlCmds, FALSE, mrcmNONE)) == mrcmNONE) { MDB(3,fUI) MLog("WARNING: unexpected subcommand '%s' received\n", Command); sprintf(tmpLine,"ERROR: unexpected subcommand '%s'\n", Command); MUISAddData(S,tmpLine); return(FAILURE); } MUserAdd(Auth,&U); S->SBuffer[0] = '\0'; switch (CIndex) { case mrcmCreate: { marray_t RList; char Buffer[MMAX_BUFFER]; int rc; Buffer[0] = 0; /* check for unauthorized peers exporting rsv */ if ((Auth != NULL) && (!strncasecmp(Auth,"peer:",strlen("peer:")))) { if (MRMFind(&Auth[strlen("peer:")],&RM) == FAILURE) { /* NYI */ } else if (!bmisset(&RM->Flags,mrmfRsvImport)) { MUISAddData(S,"rsv import not enabled for peer"); return(FAILURE); } } MUArrayListCreate(&RList,sizeof(mrsv_t *),50); rc = MUIRsvCreate( RE, Auth, Buffer, /* O */ sizeof(Buffer), TRUE, FALSE, FALSE, &RList); if (DFormat == mfmXML) { if (MXMLCreateE(&S->SDE,(char *)MSON[msonData]) == FAILURE) { rc = FAILURE; MUISAddData(S,"ERROR: internal error, cannot create response\n"); } else if (rc == SUCCESS) { mrsv_t *R; int rindex; mxml_t *RE; DE = S->SDE; for (rindex = 0;rindex < RList.NumItems;rindex++) { R = (mrsv_t *)MUArrayListGetPtr(&RList,rindex); RE = NULL; MXMLCreateE(&RE,(char *)MXO[mxoRsv]); MXMLSetVal(RE,R->Name,mdfString); MXMLAddE(DE,RE); } } else { MUISAddData(S,Buffer); } } /* END if (DFormat == mfmXML) */ else { MUISAddData(S,Buffer); } MUArrayListFree(&RList); return(rc); } /* END case mrcmCreate: */ case mrcmFlush: { msrsv_t *SR; if (MSRFind(RsvExp,&SR,NULL) == SUCCESS) { int sindex; for (sindex = 0;sindex < MMAX_SRSV_DEPTH;sindex++) { SR->DisabledTimes[sindex] = 0; } snprintf(tmpLine,sizeof(tmpLine),"SR[%s] successfully cleared disabled times\n", SR->Name); MUISAddData(S,tmpLine); return(SUCCESS); } } case mrcmQuery: bmset(&S->Flags,msftReadOnlyCommand); if (!strcasecmp(ArgString,"profile")) { mxml_t *DE; if ((S->SDE == NULL) && (MXMLCreateE(&S->SDE,(char *)MSON[msonData]) == FAILURE)) { MUISAddData(S,"ERROR: cannot create response\n"); return(FAILURE); } DE = S->SDE; return(__MUIRsvProfShow(S,U,RsvExp,&DE,NULL)); } case mrcmList: bmset(&S->Flags,msftReadOnlyCommand); break; default: break; } /* end switch(CIndex) */ MUArrayListCreate(&RsvList,sizeof(mrsv_t *),1); if (UseUIndex == TRUE) { char *ptr; char *TokPtr; /* locate by unique index */ /* FORMAT: <ID>[,<ID>]... */ /* NOTE: rsv id in format '<NAME>.<UID>' */ ptr = MUStrTok(RsvExp,", \t\n:",&TokPtr); while (ptr != NULL) { if (MRsvFind(ptr,&R,mraUIndex) == SUCCESS) { MUArrayListAppendPtr(&RsvList,R); MDB(6,fUI) MLog("INFO: reservation '%s' located by index\n", R->Name); } else { snprintf(tmpLine,sizeof(tmpLine),"ERROR: cannot locate reservation %s\n", ptr); MUISAddData(S,tmpLine); } ptr = MUStrTok(NULL,", \t\n:",&TokPtr); } /* END while (ptr != NULL) */ } /* END if (UseUIndex == TRUE) */ else if (UseGName == TRUE) { rsv_iter RTI; char *ptr; char *TokPtr; /* allow multiple group selection */ /* FORMAT: <GID>[,<GID>]... */ ptr = MUStrTok(RsvExp,", \t:",&TokPtr); while (ptr != NULL) { MRsvIterInit(&RTI); while (MRsvTableIterate(&RTI,&R) == SUCCESS) { if (R->RsvGroup == NULL) continue; if (strcmp(R->RsvGroup,ptr)) continue; MUArrayListAppendPtr(&RsvList,R); MDB(6,fUI) MLog("INFO: reservation '%s' located by group '%s'\n", R->Name, ptr); } /* END while (MRsvTableIterate()) */ ptr = MUStrTok(NULL,", \t:",&TokPtr); } /* END while (ptr != NULL) */ } /* END if (UseGName == TRUE) */ else { if (RsvExp[0] == '\0') { /* no reservation name received */ snprintf(tmpLine,sizeof(tmpLine),"ERROR: no reservation specified\n"); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } else if ((MUStringIsRE(RsvExp) == TRUE) || (!strcmp(RsvExp,"ALL"))) { /* regular expression or special expression received */ char tmpBuf[MMAX_BUFFER]; tmpBuf[0] = '\0'; if (MUREToList( RsvExp, mxoRsv, NULL, &RsvList, FALSE, tmpBuf, sizeof(tmpBuf)) == FAILURE) { snprintf(tmpLine,sizeof(tmpLine),"ERROR: invalid expression '%s' : %s\n", RsvExp, tmpBuf); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } } else { /* single reservation specified */ mrsv_t *tmpR = NULL; if (MRsvFind(RsvExp,&tmpR,mraNONE) == FAILURE) { snprintf(tmpLine,sizeof(tmpLine),"ERROR: invalid reservation specified '%s'\n", RsvExp); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } else { MUArrayListAppendPtr(&RsvList,tmpR); } } /* END else */ if (RsvList.NumItems == 0) { if (!strcmp(RsvExp,"ALL")) { MUArrayListFree(&RsvList); return(SUCCESS); } else { char tmpLine[MMAX_LINE]; snprintf(tmpLine,sizeof(tmpLine),"ERROR: '%s' does not match any reservations\n", RsvExp); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } } /* END if (RsvList.NumItems == 0) */ } /* END else (UseUIndex == TRUE) */ MDB(2,fUI) MLog("INFO: performing '%s' operation on rsv expression '%s' (%d matches)\n", MRsvCtlCmds[CIndex], RsvExp, RsvList.NumItems); if (RsvList.NumItems <= 0) { /* no reservations found */ sprintf(tmpLine,"ERROR: could not locate any matching reservations\n"); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } rc = SUCCESS; for (rindex = 0;rindex < RsvList.NumItems;rindex++) { R = (mrsv_t *)MUArrayListGetPtr(&RsvList,rindex); /* if (((RA != NULL) && (J->Cred.A != RA)) || ((RG != NULL) && (J->Cred.G != RG)) || ((RQ != NULL) && (J->Cred.Q != RQ)) || ((RU != NULL) && (J->Cred.U != RU))) { continue; } */ /* get authorization */ if (MUICheckAuthorization( U, NULL, (void *)R, mxoRsv, mcsMRsvCtl, CIndex, &IsAdmin, tmpLine, sizeof(tmpLine)) == FAILURE) { /* NOTE: if rsv list is requested, do not report - 'not authorized' message for each rsv. */ if ((CIndex != mrcmList) && (CIndex != mrcmQuery)) { MUISAddData(S,tmpLine); MUISAddData(S,"\n"); /* allow errno to be set on the command line to indicate error */ rc = FAILURE; } /* If the final request failed, return failure otherwise continue to the next request */ if (RsvList.NumItems - 1 == rindex) { MUArrayListFree(&RsvList); /* last request failed */ if (CIndex == mrcmQuery) { /* Failed just means no reservations reported */ return(SUCCESS); } return(FAILURE); } else { /* failure is recorded but entire request hasn't failed */ continue; } } switch (CIndex) { case mrcmAlloc: { char EMsg[MMAX_LINE] = {0}; char tmpName[MMAX_NAME]; char tmpVal[MMAX_NAME]; char GResType[MMAX_NAME]; int len; GResType[0] = '\0'; /* allocate additional requested resources to specified rsv */ /* FORMAT: mrsvctl -A gres.type=dvd vpc.3 */ /* parse request */ if (MS3GetSet( RE, NULL, NULL, tmpName, sizeof(tmpName), tmpVal, sizeof(tmpVal)) == FAILURE) { sprintf(tmpLine,"ERROR: no allocation resource specified\n"); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } if (!strcasecmp(tmpName,"resource")) { len = strlen("gres.type="); if (!strncasecmp(tmpVal,"gres.type=",len)) { MUStrCpy(GResType,&tmpVal[len],sizeof(GResType)); } } if (GResType[0] == '\0') { sprintf(tmpLine,"ERROR: no allocation resource specified\n"); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(FAILURE); } /* create pseudo job */ rc = MRsvAllocateGResType(R,GResType,EMsg); MUISAddData(S,EMsg); MUArrayListFree(&RsvList); return(rc); } /* END case mrcmAlloc */ /*NOTREACHED*/ break; case mrcmCreate: { /* should not be reached (handled above) */ rc = FAILURE; sprintf(tmpLine,"ERROR: create failed - internal error\n"); MUISAddData(S,tmpLine); MUArrayListFree(&RsvList); return(rc); } /* END case mrcmCreate */ /*NOTREACHED*/ break; case mrcmDestroy: { char tmpName[MMAX_NAME]; if (bmisset(&R->Flags,mrfStatic)) { sprintf(tmpLine,"ERROR: cannot release 'static' reservation %s\n", R->Name); MUISAddData(S,tmpLine); continue; } if (bmisset(&R->Flags,mrfParentLock)) { sprintf(tmpLine,"ERROR: cannot release 'locked' reservation %s - must remove parent object\n", R->Name); MUISAddData(S,tmpLine); continue; } MUStrCpy(tmpName,R->Name,sizeof(tmpName)); R->CancelIsPending = TRUE; if (bmisset(&R->Flags,mrfStanding)) { int sindex; msrsv_t *SR = NULL; /* set enabletime to the end of this reservation */ if (MSRFind(R->RsvParent,&SR,NULL) == SUCCESS) { for (sindex = 0;sindex < MMAX_SRSV_DEPTH;sindex++) { if ((SR->DisabledTimes[sindex] == 0) || (SR->DisabledTimes[sindex] == 1)) { if (R->EndTime == MMAX_TIME - 1) SR->DisabledTimes[sindex] = MMAX_TIME; else SR->DisabledTimes[sindex] = R->EndTime; break; } } /* END for (sindex) */ } /* END if (MSRFind(R->RsvGroup,&SR) == SUCCESS) */ else { sprintf(tmpLine,"WARNING: cannot locate rsv parent\n"); MUISAddData(S,tmpLine); MDB(3,fUI) MLog("WARNING: cannot locate parent '%s' for rsv '%s'\n", (R->RsvGroup != NULL) ? R->RsvGroup : "NULL", R->Name); } } /* END if (bmisset(&R->Flags,mrfStanding)) */ R->EndTime = MSched.Time - 1; R->ExpireTime = 0; snprintf(tmpLine,sizeof(tmpLine),"reservation %s destroyed by %s", tmpName, Auth); MOWriteEvent(R,mxoRsv,mrelRsvCancel,tmpLine,MStat.eventfp,NULL); if ((long)R->StartTime <= MUIDeadLine) { /* adjust UI phase wake up time */ if (MSched.AdminEventAggregationTime >= 0) MUIDeadLine = MIN(MUIDeadLine,(long)MSched.Time + MSched.AdminEventAggregationTime); } /* remove reservation */ if ((R->Type = mrtJob) && (R->J != NULL)) { /* Expiring job reservations are not released in MRsvCheckStatus(), they are extended. So to remove the reservation you must do it outside MRsvCheckStatus() */ MJobReleaseRsv(R->J,TRUE,TRUE); R = NULL; } else { MRsvCheckStatus(NULL); } MOSSyslog(LOG_INFO,tmpLine); sprintf(tmpLine,"reservation %s successfully released\n", tmpName); } /* END case mrcmDestroy */ MUISAddData(S,tmpLine); continue; /*NOTREACHED*/ break; case mrcmFlush: { msrsv_t *SR; int sindex; if (MSRFind(R->RsvGroup,&SR,NULL) == FAILURE) { sprintf(tmpLine,"reservation '%s' does not belong to a standing reservation\n", R->Name); MUISAddData(S,tmpLine); rc = FAILURE; break; } for (sindex = 0;sindex < MMAX_SRSV_DEPTH;sindex++) { SR->DisabledTimes[0] = 0; } sprintf(tmpLine,"SR[%s] successfully cleared disabled times\n", SR->Name); MUISAddData(S,tmpLine); } break; case mrcmJoin: { char EMsg[MMAX_LINE] = {0}; mrsv_t *CR = NULL; if (MRsvFind(ArgString,&CR,mraNONE) == SUCCESS) { rc = MRsvJoin(R,CR,EMsg); if (rc == FAILURE) { sprintf(tmpLine,"could not join rsv '%s' to rsv '%s' -- %s\n", R->Name, ArgString, EMsg); MUISAddData(S,tmpLine); } else { sprintf(tmpLine,"successfully joined rsv '%s' to rsv '%s'\n", ArgString, R->Name); MHistoryAddEvent(R,mxoRsv); MUISAddData(S,tmpLine); } } else { sprintf(tmpLine,"invalid reservation '%s'\n", ArgString); MUISAddData(S,tmpLine); } } /* END case mrcmJoin */ break; case mrcmSignal: { enum MTrigTypeEnum Signal = (enum MTrigTypeEnum)MUGetIndexCI(ArgString,MTrigType,FALSE,mttNONE); if (Signal == mttNONE) { sprintf(tmpLine,"invalid signal '%s' for rsv '%s'\n", ArgString, R->Name); MUISAddData(S,tmpLine); } else { MOReportEvent((void *)R,NULL,mxoRsv,Signal,MSched.Time,TRUE); sprintf(tmpLine,"signal '%s' successfully sent to rsv '%s'\n", MTrigType[Signal], R->Name); MUISAddData(S,tmpLine); } } /* END BLOCK (case mrcmSignal) */ break; case mrcmList: /* NOTE: only add matching reservations */ /* NOTE: global list handled outside of loop */ MUISAddData(S,R->Name); MUISAddData(S," "); break; case mrcmMigrate: { char EMsg[MMAX_LINE] = {0}; mrsv_t *CR = NULL; if (MRsvFind(ArgString,&CR,mraNONE) == SUCCESS) { rc = MRsvMigrate(R,CR,EMsg); if (rc == FAILURE) { sprintf(tmpLine,"could not migrate rsv '%s' to rsv '%s' -- %s\n", R->Name, ArgString, EMsg); MUISAddData(S,tmpLine); } else { sprintf(tmpLine,"successfully migrated rsv '%s' to rsv '%s'\n", ArgString, R->Name); MHistoryAddEvent(R,mxoRsv); MUISAddData(S,tmpLine); } } else { sprintf(tmpLine,"invalid reservation '%s'\n", ArgString); MUISAddData(S,tmpLine); } } /* END case mrcmJoin */ break; break; case mrcmModify: { char EMsg[MMAX_LINE] = {0}; rc = MUIRsvCtlModify(R,RE,EMsg); MUISAddData(S,EMsg); if (rc == FAILURE) { MUArrayListFree(&RsvList); return rc; } } /* END BLOCK (case mrcmModify) */ break; case mrcmQuery: /* NOTE: "profile" handled above */ bmset(&S->Flags,msftReadOnlyCommand); if (!strcmp(ArgString,"resources")) { /* list allocated resources */ if (!MNLIsEmpty(&R->NL)) { MNLToString( &R->NL, bmisset(&Flags,mcmVerbose), ",", '\0', tmpLine, sizeof(tmpLine)); MUISAddData(S,tmpLine); } MUArrayListFree(&RsvList); return(SUCCESS); } /* END if (!strcmp(ArgString,"resources")) */ else if (!strcmp(ArgString,"export")) { mxml_t *DE; if ((S->SDE == NULL) && (MXMLCreateE(&S->SDE,(char *)MSON[msonData]) == FAILURE)) { MUISAddData(S,"ERROR: cannot create response\n"); MUArrayListFree(&RsvList); return(FAILURE); } DE = S->SDE; if (MUIExportRsvQuery( R, NULL, Auth, DE, 0) == FAILURE) { MUArrayListFree(&RsvList); return(FAILURE); } } else if (!strcmp(ArgString,"wiki")) { mstring_t String(MMAX_LINE); MRsvToWikiString(R,NULL,&String); MUISAddData(S,String.c_str()); } /* END if (!strcmp(ArgString,"wiki")) */ else { /* diagnose/display rsv state/config */ char DiagOpt[MMAX_NAME]; mxml_t *DE = NULL; mxml_t *RE = NULL; const enum MRsvAttrEnum RAList[] = { mraName, mraAAccount, mraAGroup, mraAUser, mraAQOS, mraAllocNodeCount, mraAllocNodeList, mraAllocProcCount, mraAllocTaskCount, mraComment, mraEndTime, mraExpireTime, mraFlags, mraGlobalID, mraHostExp, mraLabel, mraLogLevel, mraOwner, mraPartition, mraProfile, mraReqArch, mraReqFeatureList, mraReqMemory, mraReqNodeCount, mraReqNodeList, mraReqOS, mraReqTaskCount, mraResources, mraRsvGroup, mraRsvParent, mraSID, mraStartTime, mraStatCAPS, mraStatCIPS, mraStatTAPS, mraStatTIPS, mraSubType, mraTrigger, mraType, mraVariables, mraVMList, mraNONE }; MUStrCpy(DiagOpt,R->Name,sizeof(DiagOpt)); /* check to see if the socket's return data xml is initialized */ if (S->SDE == NULL) { if (MXMLCreateE(&S->SDE,(char *)MSON[msonData]) == FAILURE) { MUISAddData(S,"ERROR: cannot create response\n"); MUArrayListFree(&RsvList); return(FAILURE); } } DE = S->SDE; MXMLCreateE(&RE,(char *)MXO[mxoRsv]); MXMLAddE(DE,RE); MRsvToXML(R,&RE,(enum MRsvAttrEnum *)RAList,NULL,TRUE,mcmNONE); /* NOTE: do not return, append data to buffer and continue */ } /* END else() */ break; default: /* NO-OP */ break; } /* END switch (CIndex) */ } /* END for (rindex) */ MUArrayListFree(&RsvList); return(rc); } /* END MUIRsvCtl() */
int MTraceLoadWorkload( char *Buffer, /* I */ int *TraceLen, /* I (optional,modified) */ mjob_t *J, /* O */ int Mode, /* I */ int *Version) /* O */ { char *tail; char *head; char *ptr; char *ptr2; char *tok; char *TokPtr; char Line[MAX_MLINE << 4]; char tmpLine[MAX_MLINE]; char MHostName[MAX_MNAME]; char MReqHList[MAX_MLINE << 2]; char Reservation[MAX_MNAME]; char tmpTaskRequest[MAX_MLINE]; char tmpSpecWCLimit[MAX_MLINE]; char tmpState[MAX_WORD]; char tmpOpsys[MAX_WORD]; char tmpArch[MAX_WORD]; char tmpNetwork[MAX_WORD]; char tmpMemCmp[MAX_WORD]; char tmpDiskCmp[MAX_WORD]; char tmpReqNFList[MAX_MLINE]; char tmpClass[MAX_MLINE]; char tmpRMName[MAX_MLINE]; char tmpCmd[MAX_MLINE]; char tmpRMXString[MAX_MLINE >> 2]; char tmpParName[MAX_MNAME]; char tmpJFlags[MAX_MLINE]; char tmpQReq[MAX_WORD]; char tmpASString[MAX_MLINE]; char tmpRMemBuf[MAX_MNAME]; char tmpRDiskBuf[MAX_MNAME]; char tmpDSwapBuf[MAX_MNAME]; char tmpDMemBuf[MAX_MNAME]; char tmpDDiskBuf[MAX_MNAME]; char UName[MAX_MNAME]; char GName[MAX_MNAME]; char AName[MAX_MNAME]; char SetString[MAX_MLINE]; unsigned long tmpQTime; unsigned long tmpDTime; unsigned long tmpSTime; unsigned long tmpCTime; unsigned long tmpSQTime; unsigned long tmpSDate; unsigned long tmpEDate; int TPN; int TasksAllocated; int index; int rc; int tindex; int nindex; mqos_t *QDef; mreq_t *RQ[MAX_MREQ_PER_JOB]; mnode_t *N; long ReqProcSpeed; const char *FName = "MTraceLoadWorkload"; DBG(5,fSIM) DPrint("%s(Buffer,TraceLen,J,%d,%d)\n", FName, Mode, (Version != NULL) ? *Version : -1); if (J == NULL) { DBG(5,fSIM) DPrint("ALERT: NULL job pointer passed in %s()\n", FName); return(FAILURE); } if (Buffer == NULL) { return(FAILURE); } if ((tail = strchr(Buffer,'\n')) == NULL) { /* assume line is '\0' terminated */ if (TraceLen != NULL) tail = Buffer + *TraceLen; else tail = Buffer + strlen(Buffer); } head = Buffer; MUStrCpy(Line,head,MIN(tail - head + 1,sizeof(Line))); DBG(6,fSIM) DPrint("INFO: parsing trace line '%s'\n", Line); if (TraceLen != NULL) *TraceLen = (tail - head) + 1; /* eliminate comments */ if ((ptr = strchr(Line,'#')) != NULL) { DBG(5,fSIM) DPrint("INFO: detected trace comment line, '%s'\n", Line); *ptr = '\0'; } if (Line[0] == '\0') { return(FAILURE); } /* look for VERSION settings */ if (!strncmp(Line,TRACE_WORKLOAD_VERSION_MARKER,strlen(TRACE_WORKLOAD_VERSION_MARKER))) { if (MTraceGetWorkloadVersion(Line,Version) == FAILURE) { DBG(0,fSIM) DPrint("ALERT: cannot determine workload trace version\n"); /* assume default version */ if (Version != NULL) *Version = DEFAULT_WORKLOAD_TRACE_VERSION; } else { DBG(3,fSIM) DPrint("INFO: workload trace version %d detected\n", (Version != NULL) ? *Version : -1); } return(FAILURE); } /* END if (!strncmp(Line,TRACE_WORKLOAD_VERSION_MARKER)) */ /* set default workload attributes */ memset(J,0,sizeof(mjob_t)); if (MReqCreate(J,NULL,&J->Req[0],FALSE) == FAILURE) { DBG(0,fSIM) DPrint("ALERT: cannot create job req\n"); return(FAILURE); } MRMJobPreLoad(J,NULL,0); RQ[0] = J->Req[0]; RQ[0]->Index = 0; J->StartCount = 0; J->R = NULL; switch(*Version) { case 230: /* Name NR TReq User Grop WClk Stat Clss QUT DST STT CMT netw Arch Opsy MemC RMem DskC RDsk Feat SQT TA TPN QO MO AC CM CC BP PU Part DPrc DMem DDisk DSwap STARTDATE ENDDATE MNODE RM HL RES RES1 RES2 RES3 OVERFLOW */ rc = sscanf(Line,"%64s %d %64s %64s %64s %64s %64s %64s %lu %lu %lu %lu %64s %64s %64s %64s %64s %64s %64s %64s %lu %d %d %64s %1024s %64s %1024s %1024s %d %lf %64s %d %64s %64s %64s %lu %lu %1024s %64s %1024s %64s %64s %1024s %s %s", J->Name, &J->Request.NC, tmpTaskRequest, UName, GName, tmpSpecWCLimit, tmpState, tmpClass, &tmpQTime, &tmpDTime, &tmpSTime, &tmpCTime, tmpNetwork, tmpArch, tmpOpsys, tmpMemCmp, tmpRMemBuf, tmpDiskCmp, tmpRDiskBuf, tmpReqNFList, &tmpSQTime, /* SystemQueueTime */ &TasksAllocated, /* allocated task count */ &TPN, tmpQReq, tmpJFlags, AName, tmpCmd, tmpRMXString, /* RM extension string */ &J->Bypass, /* Bypass */ &J->PSUtilized, /* PSUtilized */ tmpParName, /* partition used */ &RQ[0]->DRes.Procs, tmpDMemBuf, tmpDDiskBuf, tmpDSwapBuf, &tmpSDate, &tmpEDate, MHostName, tmpRMName, MReqHList, Reservation, SetString, /* resource sets required by job */ tmpASString, /* application simulator name */ tmpLine, /* RES1 */ tmpLine /* check for too many fields */ ); /* fail if all fields not read in */ switch (rc) { case 43: strcpy(MHostName,NONE); J->RM = &MRM[0]; break; case 44: /* canonical 230 trace */ if (isdigit(tmpRMName[0])) J->RM = &MRM[(int)strtol(tmpRMName,NULL,0)]; else J->RM = &MRM[0]; break; default: DBG(1,fSIM) DPrint("ALERT: version %d workload trace is corrupt '%s' (%d of %d fields read) ignoring line\n", *Version, Line, rc, 44); MJobDestroy(&J); return(FAILURE); /*NOTREACHED*/ break; } /* END switch(rc) */ RQ[0]->RequiredMemory = MURSpecToL(tmpRMemBuf,mvmMega,mvmMega); RQ[0]->RequiredDisk = MURSpecToL(tmpRDiskBuf,mvmMega,mvmMega); RQ[0]->DRes.Mem = MURSpecToL(tmpDMemBuf,mvmMega,mvmMega); RQ[0]->DRes.Swap = MURSpecToL(tmpDSwapBuf,mvmMega,mvmMega); RQ[0]->DRes.Disk = MURSpecToL(tmpDDiskBuf,mvmMega,mvmMega); if (Mode != msmProfile) { ptr = NULL; ptr2 = NULL; if (strcmp(tmpASString,NONE)) { if ((ptr = MUStrTok(tmpASString,":",&TokPtr)) != NULL) { ptr2 = MUStrTok(NULL,"|",&TokPtr); } } if (MASGetDriver((void **)&J->ASFunc,ptr,msdApplication) == SUCCESS) { (*J->ASFunc)(J,mascCreate,ptr2,NULL); } } /* END if (Mode != msmProfile) */ /* obtain job step number from LL based job name */ /* FORMAT: <FROM_HOST>.<CLUSTER>.<PROC> */ MUStrCpy(tmpLine,J->Name,sizeof(tmpLine)); if ((ptr = MUStrTok(tmpLine,".",&TokPtr)) != NULL) { MUStrCpy(J->SubmitHost,ptr,sizeof(J->SubmitHost)); if ((ptr = MUStrTok(NULL,".",&TokPtr)) != NULL) { J->Cluster = (int)strtol(ptr,NULL,0); if ((ptr = MUStrTok(NULL,".",&TokPtr)) != NULL) { J->Proc = (int)strtol(ptr,NULL,0); } } } /* adjust job flags */ if (Mode == msmProfile) { MUStrDup(&J->MasterHostName,MHostName); /* NOTE: flags may be specified as string or number */ if ((J->SpecFlags = strtol(tmpJFlags,NULL,0)) == 0) { MUBMFromString(tmpJFlags,MJobFlags,&J->SpecFlags); } } else { /* simulation mode */ if ((MSim.Flags & (1 << msimfIgnMode)) || (MSim.Flags & (1 << msimfIgnAll))) { J->SpecFlags = 0; } else { /* NOTE: flags may be specified as string or number */ if ((J->SpecFlags = strtol(tmpJFlags,NULL,0)) == 0) { MUBMFromString(tmpJFlags,MJobFlags,&J->SpecFlags); } if (J->SysFlags & (1 << mjfBackfill)) J->SysFlags ^= (1 << mjfBackfill); if ((J->SpecFlags & (1 << mjfHostList)) && (MSim.Flags & (1 << msimfIgnHostList))) { J->SpecFlags ^= (1 << mjfHostList); } } } /* END else (Mode == msmProfile) */ /* extract arbitrary job attributes */ /* FORMAT: JATTR:<ATTR>[=<VALUE>] */ { char *ptr; char *TokPtr; ptr = MUStrTok(tmpJFlags,"[]",&TokPtr); while (ptr != NULL) { if (!strncmp(ptr,"JATTR:",strlen("JATTR:"))) { MJobSetAttr(J,mjaGAttr,(void **)(ptr + strlen("JATTR:")),0,mSet); } ptr = MUStrTok(NULL,"[]",&TokPtr); } /* END while (ptr != NULL) */ } /* END BLOCK */ /* set default flags, remove set 'ignore' flags */ J->SpecFlags |= MSim.TraceDefaultJobFlags; for (index = 0;index < M64.INTBITS;index++) { if (!(MSim.TraceIgnoreJobFlags & (1 << index))) continue; if (!(J->SpecFlags & (1 << index))) continue; J->SpecFlags ^= (1 << index); } /* END for (index) */ /* load task info */ if (!strncmp(tmpTaskRequest,"PBS=",strlen("PBS="))) { char tmpLine[MAX_MLINE]; tpbsa_t tmpA; short TaskList[MAX_MTASK]; memset(&tmpA,0,sizeof(tmpA)); sprintf(tmpLine,"Resource_List,nodes,%s", &tmpTaskRequest[strlen("PBS=")]); MPBSJobSetAttr(J,NULL,tmpLine,&tmpA,TaskList,0); MPBSJobAdjustResources(J,&tmpA,J->RM); } else { ptr = MUStrTok(tmpTaskRequest,",",&TokPtr); tindex = 1; while (ptr != NULL) { if (strchr(ptr,'-') != NULL) { /* NOTE: not handled */ } else { RQ[0]->TaskRequestList[tindex] = atoi(ptr); tindex++; } ptr = MUStrTok(NULL,",",&TokPtr); } RQ[0]->TaskRequestList[tindex] = 0; RQ[0]->TaskRequestList[0] = RQ[0]->TaskRequestList[1]; RQ[0]->TaskCount = RQ[0]->TaskRequestList[0]; J->Request.TC = RQ[0]->TaskRequestList[0]; RQ[0]->TasksPerNode = MAX(0,TPN); if (MPar[0].JobNodeMatch & (1 << nmExactNodeMatch)) { RQ[0]->NodeCount = RQ[0]->TaskCount; J->Request.NC = RQ[0]->TaskCount; } if (MPar[0].JobNodeMatch & (1 << nmExactProcMatch)) { if (RQ[0]->TasksPerNode >= 1) { RQ[0]->RequiredProcs = RQ[0]->TasksPerNode; RQ[0]->ProcCmp = mcmpEQ; } if (RQ[0]->TasksPerNode > J->Request.TC) { RQ[0]->TasksPerNode = 0; } } } /* END BLOCK */ /* process WCLimit constraints */ ptr = MUStrTok(tmpSpecWCLimit,",:",&TokPtr); tindex = 1; while (ptr != NULL) { if (strchr(ptr,'-') != NULL) { /* NOTE: not handled */ } else { J->SpecWCLimit[tindex] = strtol(ptr,NULL,0); tindex++; } ptr = MUStrTok(NULL,",:",&TokPtr); } /* END while (ptr != NULL) */ J->SpecWCLimit[tindex] = 0; J->SpecWCLimit[0] = J->SpecWCLimit[1]; J->SubmitTime = tmpQTime; J->DispatchTime = MAX(tmpDTime,tmpSTime); J->StartTime = MAX(tmpDTime,tmpSTime); J->CompletionTime = tmpCTime; J->SystemQueueTime = tmpSQTime; J->SpecSMinTime = tmpSDate; J->CMaxTime = tmpEDate; /* determine required reservation */ if (strcmp(Reservation,NONE) && strcmp(Reservation,J->Name)) { J->SpecFlags |= (1 << mjfAdvReservation); if (strcmp(Reservation,ALL) != 0) { strcpy(J->ResName,Reservation); } } /* determine job class */ if ((MSim.Flags & (1 << msimfIgnClass)) || (MSim.Flags & (1 << msimfIgnAll))) { mclass_t *C; MClassAdd("DEFAULT",&C); /* ignore specified classes */ RQ[0]->DRes.PSlot[0].count = 1; RQ[0]->DRes.PSlot[C->Index].count = 1; } else { int cindex; MUNumListFromString(RQ[0]->DRes.PSlot,tmpClass,eClass); for (cindex = 1;cindex < MAX_MCLASS;cindex++) { if (RQ[0]->DRes.PSlot[cindex].count > 0) { MClassAdd(MAList[eClass][cindex],NULL); } } /* END for (cindex) */ } if (Mode != msmProfile) { if ((strcmp(MReqHList,NONE) != 0) && !(MSim.Flags & (1 << msimfIgnHostList)) && !(MSim.Flags & (1 << msimfIgnAll))) { J->SpecFlags |= (1 << mjfHostList); ptr = MUStrTok(MReqHList,":",&TokPtr); nindex = 0; if (J->ReqHList == NULL) J->ReqHList = (mnalloc_t *)calloc(1,sizeof(mnalloc_t) * (MAX_MNODE_PER_JOB + 1)); J->ReqHList[0].N = NULL; while (ptr != NULL) { if (MNodeFind(ptr,&N) == FAILURE) { if (MSched.DefaultDomain[0] != '\0') { if ((tail = strchr(ptr,'.')) != NULL) { /* try short name */ MUStrCpy(MReqHList,ptr,MIN(sizeof(MReqHList),(tail - ptr + 1))); } else { /* append default domain */ if (MSched.DefaultDomain[0] == '.') { sprintf(MReqHList,"%s%s", ptr, MSched.DefaultDomain); } else { sprintf(MReqHList,"%s.%s", ptr, MSched.DefaultDomain); } } if (MNodeFind(MReqHList,&N) != SUCCESS) { DBG(1,fUI) DPrint("ALERT: cannot locate node '%s' for job '%s' hostlist\n", ptr, J->Name); N = NULL; } } else { DBG(1,fUI) DPrint("ALERT: cannot locate node '%s' for job '%s' hostlist\n", ptr, J->Name); N = NULL; } } /* END if (MNodeFind() == FAILURE) */ if (N != NULL) { if (J->ReqHList[nindex].N == N) { J->ReqHList[nindex].TC++; } else { if (J->ReqHList[nindex].N != NULL) nindex++; J->ReqHList[nindex].N = N; J->ReqHList[nindex].TC = 1; } } ptr = MUStrTok(NULL,":",&TokPtr); } /* END while (ptr != NULL) */ J->ReqHList[nindex + 1].N = NULL; } /* END if (strcmp(MReqHList,NONE)) */ else if ((J->SpecFlags & (1 << mjfHostList)) && (J->ReqHList == NULL)) { DBG(1,fSIM) DPrint("ALERT: job %s requests hostlist but has no hostlist specified\n", J->Name); J->SpecFlags ^= (1 << mjfHostList); } } /* END if (MODE != msmProfile) */ break; default: DBG(4,fSIM) DPrint("ALERT: cannot load version %d workload trace record\n", *Version); MJobDestroy(&J); return(FAILURE); /*NOTREACHED*/ break; } /* END switch(*Version) */ if (!strcmp(AName,NONE) || !strcmp(AName,"0")) { AName[0] = '\0'; } if ((strcmp(tmpRMXString,NONE) != 0) && (strcmp(tmpRMXString,"0") != 0)) { MJobSetAttr(J,mjaRMXString,(void **)tmpRMXString,mdfString,0); } if (RQ[0]->DRes.Procs == 0) RQ[0]->DRes.Procs = 1; if (J->SpecWCLimit[0] == (unsigned long)-1) J->SpecWCLimit[0] = MAX_MTIME; MUStrDup(&J->E.Cmd,tmpCmd); if (Mode == msmSim) { J->State = mjsIdle; J->EState = mjsIdle; J->Bypass = 0; J->PSUtilized = 0.0; J->SystemQueueTime = J->SubmitTime; J->SimWCTime = MAX(1,J->CompletionTime - J->StartTime); J->StartTime = 0; J->DispatchTime = 0; J->CompletionTime = 0; J->WCLimit = J->SpecWCLimit[0]; } else { /* profile mode */ int tmpI; tmpI = (int)strtol(tmpParName,NULL,0); if (tmpI > 0) { RQ[0]->PtIndex = tmpI; } else { mpar_t *P; MParFind(tmpParName,&P); RQ[0]->PtIndex = P->Index; } J->TaskCount = TasksAllocated; J->PSDedicated = MJobGetProcCount(J) * (J->CompletionTime - J->StartTime); J->WCLimit = J->SpecWCLimit[0]; for (index = 0;MJobState[index] != NULL;index++) { if (!strcmp(tmpState,MJobState[index])) { J->State = index; J->EState = index; break; } } /* END for (index) */ } if (J->State == mjsNotRun) { DBG(3,fSIM) DPrint("ALERT: ignoring job '%s' (job never ran, state '%s')\n", J->Name, MJobState[J->State]); MJobDestroy(&J); return(FAILURE); } /* check for timestamp corruption */ if (Mode == msmProfile) { /* profiler mode */ if (MSched.TraceFlags & (1 << tfFixCorruption)) { if (J->StartTime < J->DispatchTime) { DBG(2,fSIM) DPrint("WARNING: fixing job '%s' with corrupt dispatch/start times (%ld < %ld)\n", J->Name, J->DispatchTime, J->StartTime); J->DispatchTime = J->StartTime; } if (J->SubmitTime > J->StartTime) { DBG(2,fSIM) DPrint("WARNING: fixing job '%s' with corrupt queue/start times (%ld > %ld)\n", J->Name, J->SubmitTime, J->StartTime); if (J->SystemQueueTime > 0) J->SubmitTime = MIN(J->StartTime,J->SystemQueueTime); else J->SubmitTime = J->StartTime; } if (J->SystemQueueTime > J->DispatchTime) { DBG(2,fSIM) DPrint("WARNING: fixing job '%s' with corrupt system queue/dispatch times (%ld > %ld)\n", J->Name, J->SystemQueueTime, J->DispatchTime); J->SystemQueueTime = J->DispatchTime; } if (J->SystemQueueTime < J->SubmitTime) { DBG(2,fSIM) DPrint("WARNING: fixing job '%s' with corrupt system queue/queue time (%ld < %ld)\n", J->Name, J->SystemQueueTime, J->SubmitTime); J->SystemQueueTime = J->SubmitTime; } } /* END if (MSched.TraceFlags & (1 << tfFixCorruption)) */ if ((J->SubmitTime > J->DispatchTime) || (J->DispatchTime > J->CompletionTime)) { DBG(1,fSIM) DPrint("ALERT: ignoring job '%s' with corrupt queue/start/completion times (%ld > %ld > %ld)\n", J->Name, J->SubmitTime, J->DispatchTime, J->CompletionTime); MJobDestroy(&J); return(FAILURE); } } /* END if (Mode != msmSim) */ if (MJobSetCreds(J,UName,GName,AName) == FAILURE) { DBG(1,fSTRUCT) DPrint("ALERT: ignoring job '%s' with invalid authentication info (%s:%s:%s)\n", J->Name, UName, GName, AName); MJobDestroy(&J); return(FAILURE); } /* determine network */ if (strstr(tmpNetwork,MAList[eNetwork][0]) == NULL) { RQ[0]->Network = MUMAGetIndex(eNetwork,tmpNetwork,mAdd); } if (strstr(tmpOpsys,MAList[eOpsys][0]) == NULL) { if ((RQ[0]->Opsys = MUMAGetIndex(eOpsys,tmpOpsys,mAdd)) == FAILURE) { DBG(0,fSIM) DPrint("WARNING: cannot add opsys '%s' for job '%s'\n", tmpOpsys, J->Name); } } if (strstr(tmpArch,MAList[eArch][0]) == NULL) { if ((RQ[0]->Arch = MUMAGetIndex(eArch,tmpArch,mAdd)) == FAILURE) { DBG(0,fSIM) DPrint("WARNING: cannot add arch '%s' for job '%s'\n", tmpArch, J->Name); } } /* load feature values */ if ((MSched.ProcSpeedFeatureHeader[0] != '\0') && (MSched.ReferenceProcSpeed > 0)) { sprintf(tmpLine,"[%s", MSched.ProcSpeedFeatureHeader); if ((ptr = strstr(tmpReqNFList,tmpLine)) != NULL) { ReqProcSpeed = strtol(ptr + strlen(tmpLine),NULL,0); J->SimWCTime *= (long)((double)ReqProcSpeed / MSched.ReferenceProcSpeed); } } if ((MSched.Mode != msmSim) || !(MSim.Flags & (1 << msimfIgnFeatures))) { if (!strstr(tmpReqNFList,MAList[eFeature][0])) { tok = MUStrTok(tmpReqNFList,"[]",&TokPtr); do { MUGetMAttr(eFeature,tok,mAdd,RQ[0]->ReqFBM,sizeof(RQ[0]->ReqFBM)); } while ((tok = MUStrTok(NULL,"[]",&TokPtr)) != NULL); } } RQ[0]->MemCmp = MUCmpFromString(tmpMemCmp,NULL); RQ[0]->DiskCmp = MUCmpFromString(tmpDiskCmp,NULL); RQ[0]->NAccessPolicy = MSched.DefaultNAccessPolicy; RQ[0]->TaskCount = J->Request.TC; RQ[0]->NodeCount = J->Request.NC; MJobProcessExtensionString(J,J->RMXString); if ((MSim.Flags & (1 << msimfIgnQOS))) { tmpQReq[0] = '\0'; } { char *ptr; char *TokPtr; ptr = MUStrTok(tmpQReq,":",&TokPtr); if ((ptr != NULL) && (ptr[0] != '\0') && strcmp(ptr,"-1") && strcmp(ptr,"0") && strcmp(ptr,NONE) && strcmp(ptr,DEFAULT)) { if (MQOSAdd(ptr,&J->QReq) == FAILURE) { /* cannot locate requested QOS */ MQOSFind(DEFAULT,&J->QReq); } if (Mode == msmProfile) { if ((ptr = MUStrTok(NULL,":",&TokPtr)) != NULL) { MQOSAdd(ptr,&J->Cred.Q); } } } /* END if ((ptr != NULL) && ...) */ } /* END BLOCK */ if (Mode == msmSim) { if ((MQOSGetAccess(J,J->QReq,NULL,&QDef) == FAILURE) || (J->QReq == NULL) || (J->QReq == &MQOS[0])) { MJobSetQOS(J,QDef,0); } else { MJobSetQOS(J,J->QReq,0); } } /* END if (Mode == msmSim) */ if ((SetString[0] != '0') && (strcmp(SetString,NONE))) { /* FORMAT: ONEOF,FEATURE[,X:Y:Z] */ if ((ptr = MUStrTok(SetString,",: \t",&TokPtr)) != NULL) { /* determine selection type */ RQ[0]->SetSelection = MUGetIndex(ptr,(const char **)MResSetSelectionType,0,mrssNONE); if ((ptr = MUStrTok(NULL,",: \t",&TokPtr)) != NULL) { /* determine set attribute */ RQ[0]->SetType = MUGetIndex(ptr,(const char **)MResSetAttrType,0,mrstNONE); index = 0; if ((ptr = MUStrTok(NULL,", \t",&TokPtr)) != NULL) { /* determine set list */ while (ptr != NULL) { MUStrDup(&RQ[0]->SetList[index],ptr); index++; ptr = MUStrTok(NULL,", \t",&TokPtr); } } RQ[0]->SetList[index] = NULL; } /* END if ((ptr = MUStrTok(NULL)) != NULL) */ } /* END if ((ptr = MUStrTok(SetString)) != NULL) */ } /* END if ((SetString[0] != '0') && (strcmp(SetString,NONE))) */ if (MJobEval(J) == FAILURE) { /* job not properly formed */ DBG(1,fSTRUCT) DPrint("ALERT: ignoring job '%s' with corrupt configuration\n", J->Name); MJobDestroy(&J); return(FAILURE); } DBG(6,fSIM) DPrint("INFO: job '%s' loaded. class: %s opsys: %s arch: %s\n", J->Name, MUCAListToString(RQ[0]->DRes.PSlot,NULL,NULL), MAList[eOpsys][RQ[0]->Opsys], MAList[eArch][RQ[0]->Arch]); return(SUCCESS); } /* END MTraceLoadWorkload() */
int MTrigLaunchInternalAction( mtrig_t *T, /* I (optional) */ char *ActionString, /* I */ mbool_t *Complete, /* O */ char *Msg) /* O (optional,minsize=MMAX_LINE) */ { /* FORMAT: <OTYPE>:<OID>:<ACTION>:<context information> */ char *ptr = NULL; char *TokPtr = NULL; char *tmpAString = NULL; char ArgLine[MMAX_LINE*10]; char OID[MMAX_BUFFER]; char Action[MMAX_LINE*10]; enum MXMLOTypeEnum OType; const char *FName = "MTrigLaunchInternalAction"; MDB(4,fSCHED) MLog("%s(%s,%s,Msg)\n", FName, ((T != NULL) && (T->TName != NULL)) ? T->TName : "NULL", (ActionString != NULL) ? ActionString : "NULL"); if (Msg != NULL) Msg[0] = '\0'; if (Complete != NULL) *Complete = TRUE; if (ActionString == NULL) { if (Msg != NULL) strcpy(Msg,"internal error"); return(FAILURE); } MUStrDup(&tmpAString,ActionString); /* NOTE: this format and parsing is duplicated in MTrigCheckInternalAction() any update here must be copied to that routine */ ptr = MUStrTok(tmpAString,":",&TokPtr); if (ptr == NULL) { MDB(4,fSCHED) MLog("ERROR: invalid action"); if (Msg != NULL) strcpy(Msg,"invalid action"); MUFree(&tmpAString); return(FAILURE); } OType = (enum MXMLOTypeEnum)MUGetIndexCI(ptr,MXO,FALSE,mxoNONE); if (OType == mxoNONE) { MDB(4,fSCHED) MLog("ERROR: invalid object type '%s' in %s\n", ptr, FName); if (Msg != NULL) strcpy(Msg,"invalid object type"); MUFree(&tmpAString); return(FAILURE); } ptr = MUStrTok(NULL,":",&TokPtr); if (ptr == NULL) { MDB(4,fSCHED) MLog("ERROR: cannot extract object ID in %s\n", FName); if (Msg != NULL) strcpy(Msg,"invalid object id"); MUFree(&tmpAString); return(FAILURE); } MUStrCpy(OID,ptr,sizeof(OID)); ptr = MUStrTok(NULL,":",&TokPtr); if (ptr == NULL) { MDB(4,fSCHED) MLog("ERROR: cannot parse action in %s\n", FName); if (Msg != NULL) strcpy(Msg,"cannot locate action"); MUFree(&tmpAString); return(FAILURE); } MUStrCpy(Action,ptr,sizeof(Action)); if ((TokPtr != NULL) && (TokPtr[0] != '\0')) MUStrCpy(ArgLine,TokPtr,sizeof(ArgLine)); else ArgLine[0] = '\0'; MUFree(&tmpAString); switch (OType) { case mxoJob: { mjob_t *J; char *JID; char *TokPtr; /* OID FORMAT: <JID>[+<JID>]... */ mbool_t FailureDetected; enum MJobCtlCmdEnum atype; atype = (enum MJobCtlCmdEnum)MUGetIndexCI(Action,MJobCtlCmds,FALSE,mjcmNONE); if (atype == mjcmNONE) { MDB(4,fSCHED) MLog("ERROR: cannot parse job action '%s' in %s\n", Action, FName); return(FAILURE); } FailureDetected = FALSE; JID = MUStrTok(OID,"+",&TokPtr); while (JID != NULL) { if (!strcmp(JID,"-")) { if (T == NULL) return(FAILURE); J = (mjob_t *)T->O; } else if (MJobFind(JID,&J,mjsmExtended) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot locate job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } switch (atype) { case mjcmCancel: { char *CCodeCheck; char UpperArgLine[MMAX_LINE]; MDB(7,fSCHED) MLog(" INFO: Job flaged for cancel by trigger action. '%s' in %s\n", JID, FName); bmset(&J->IFlags, mjifCancel); MUStrToUpper(ArgLine,UpperArgLine,MMAX_LINE); /* If specified, allow trigger to set the completion code of the job */ if ((CCodeCheck = strstr(UpperArgLine,"CCODE=")) != NULL) { CCodeCheck += strlen("CCODE="); /* Skip the "CCODE:" part */ if (CCodeCheck[0] != '\0') { J->CompletionCode = strtol(CCodeCheck,NULL,10); } } else { J->CompletionCode = 273; /* Completion code for a canceled job in TORQUE */ } } /* END case mjcmCancel */ break; case mjcmComplete: { char *CCodeCheck; char UpperArgLine[MMAX_LINE]; if ((!bmisset(&J->Flags,mjfSystemJob) && !bmisset(&J->Flags,mjfNoRMStart))) { MDB(4,fSCHED) MLog("ERROR: job %s in bad state for complete in %s\n", J->Name, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } /* the next three lines set the WCLimit to the exact runtime * this also causes MS3WorkloadQuery to remove the job */ J->SpecWCLimit[0] = MSched.Time - J->StartTime; J->SpecWCLimit[1] = MSched.Time - J->StartTime; J->WCLimit = MSched.Time - J->StartTime; if (MJOBISACTIVE(J) == TRUE) { MRsvJCreate(J,NULL,J->StartTime,mjrActiveJob,NULL,FALSE); /* just removes active rsv? */ } MUStrToUpper(ArgLine,UpperArgLine,MMAX_LINE); if ((CCodeCheck = strstr(UpperArgLine,"CCODE=")) != NULL) { CCodeCheck += strlen("CCODE="); /* Skip the "CCODE:" part */ if (CCodeCheck[0] != '0') { J->CompletionCode = strtol(CCodeCheck,NULL,10); } } /* MSched.TrigCompletedJob = TRUE; -- not sure why we wanted to skip the UI phase here... */ } /* END BLOCK (case mjcmComplete) */ break; case mjcmModify: { char *TokPtr; char *Attr = NULL; char *Value = NULL; char *Msg = NULL; enum MJobAttrEnum aindex; enum MObjectSetModeEnum Op; if (strstr(ArgLine,"+=")) Op = mAdd; else if (strstr(ArgLine,"-=")) Op = mDecr; else Op = mSet; Attr = MUStrTok(ArgLine,"+-=",&TokPtr); Value = MUStrTok(NULL,"=: \t\n",&TokPtr); Msg = MUStrTok(NULL,":\t\n",&TokPtr); /* extract message */ aindex = (enum MJobAttrEnum)MUGetIndexCI(Attr,MJobAttr,FALSE,mnaNONE); switch (aindex) { case mjaHold: if (MJobSetAttr(J,mjaHold,(Value != NULL) ? (void **)Value : (void **)"batch",mdfString,mSet) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot hold job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } if (Msg != NULL) { /* attach provided message */ MMBAdd( &J->MessageBuffer, Msg, NULL, mmbtHold, 0, 0, NULL); } if (MJOBISACTIVE(J)) { /* Set to idle but don't clear DRM and DRMJID */ MJobToIdle(J,FALSE,FALSE); J->SubState = mjsstNONE; } /* checkpoint change (make this configurable at this point?) */ MOCheckpoint(mxoJob,(void *)J,FALSE,NULL); break; case mjaVariables: { char tmpLine[MMAX_LINE*2]; snprintf(tmpLine,sizeof(tmpLine),"%s=%s", Value, Msg); if (MJobSetAttr(J,mjaVariables,(void **)tmpLine,mdfString,Op) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot set trigvar job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } } /* END BLOCK */ break; default: if (!strcasecmp(Attr,"gres")) { if ((Op == mAdd) && (MJobAddRequiredGRes( J, Value, 1, mxaGRes, FALSE, FALSE) == SUCCESS)) { /* SUCCESS - NO-OP */ } else if ((Op == mDecr) && (MJobRemoveGRes(J,Value,TRUE) == SUCCESS)) { /* SUCCESS -- Do Nothing */ } else { MDB(4,fSCHED) MLog("ERROR: cannot adjust gres for job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } } else { MDB(4,fSCHED) MLog("ERROR: cannot modify attribute '%s' for job '%s' in %s\n", Attr, JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } break; } } /* END BLOCK (case mjcmModify) */ break; case mjcmSignal: { char EMsg[MMAX_LINE]; int SC; if (MRMJobSignal(J,-1,ArgLine,EMsg,&SC) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot send signal '%s' to job '%s' in %s\n", ArgLine, JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } } /* END BLOCK (case mjcmSignal) */ break; case mjcmStart: /* FIXME: check reservation, check allocation */ { J->SubState = mjsstNONE; /* set "copy-tasklist" flag */ bmset(&J->IFlags,mjifCopyTaskList); if (MRMJobStart(J,NULL,NULL) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot start job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } J->State = mjsRunning; } /* END BLOCK (case mjcmStart) */ break; case mjcmRequeue: /* FIXME: check reservation, check allocation */ { char EMsg[MMAX_LINE]; J->SubState = mjsstNONE; /* set "copy-tasklist" flag */ if (MJobRequeue(J,NULL,"workflow failure",EMsg,NULL) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot requeue job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } J->State = mjsIdle; } /* END BLOCK (case mjcmStart) */ default: MDB(4,fSCHED) MLog("ERROR: action '%s' not handled in %s\n", Action, FName); return(FAILURE); /*NOTREACHED*/ break; } /* END switch (atype) */ JID = MUStrTok(NULL,"+",&TokPtr); } /* END while (JID != NULL) */ if (FailureDetected == TRUE) { return(FAILURE); } } /* END BLOCK (case mxoJob) */ break; case mxoNode: { enum MNodeCtlCmdEnum atype; char *rsvProfile = NULL; atype = (enum MNodeCtlCmdEnum)MUGetIndexCI(Action,MNodeCtlCmds,FALSE,mncmNONE); if (!strcasecmp(Action,"reserve")) { char tmpLine[MMAX_LINE]; snprintf(tmpLine,sizeof(tmpLine),"auto-trigger-rsv.%s", T->TName); if (ArgLine[0] != '\0') { char *Attr = MUStrTok(ArgLine,"=",&TokPtr); char *Value = MUStrTok(NULL,"= \t\n",&TokPtr); if ((Attr != NULL) && (strncasecmp(Attr,"rsvprofile",strlen("rsvprofile")) == 0)) rsvProfile = Value; } if (T->OType != mxoRsv) { MNodeReserve( (mnode_t *)T->O, MCONST_EFFINF, tmpLine, rsvProfile, "Reservation created by trigger"); return(SUCCESS); } else { return(FAILURE); } } else if ((!strcasecmp(Action,"evacvms")) && (MSched.AllowVMMigration == TRUE)) { /* Evacuate all vms on nodes held by this reservation */ char tmpMsg[MMAX_LINE]; int rc = SUCCESS; mnl_t NL; MNLInit(&NL); MNLFromString(OID,&NL,1,FALSE); rc = MNodeEvacVMsMultiple(&NL); MNLFree(&NL); /* Write out events */ snprintf(tmpMsg,sizeof(tmpMsg),"attempting to migrate vms from node '%s' for evacvms reservation '%s' (TID: %s)", OID, ((mrsv_t *)T->O)->Name, (T->TName != NULL) ? T->TName : "NULL"); MDB(5,fSTRUCT) MLog("INFO: %s\n", tmpMsg); return(rc); } /* END if (!strcasecmp(Action,"evacvms")) */ if (atype == mncmNONE) { return(FAILURE); } switch (atype) { case mncmModify: if (MSched.AggregateNodeActions == FALSE) { char *ptr; char *TokPtr; mnode_t *N; char *Attr; char *Value; enum MNodeAttrEnum aindex; /* always look on the bright side of life */ mbool_t NodeModifySuccessDetected; /* FORMAT: <ARG>=<VALUE> */ Attr = MUStrTok(ArgLine,"=",&TokPtr); Value = MUStrTok(NULL,"= \t\n",&TokPtr); aindex = (enum MNodeAttrEnum)MUGetIndexCI(Attr,MNodeAttr,FALSE,mnaNONE); NodeModifySuccessDetected = FALSE; /* FORMAT: OID = node[,node]... */ ptr = MUStrTok(OID,",",&TokPtr); if ((ptr == NULL) || (aindex == mnaNONE)) { MDB(4,fSCHED) MLog("ERROR: unknown attribute to modify on node '%s'\n", Attr); return(FAILURE); } while (ptr != NULL) { if (MNodeFind(ptr,&N) == FAILURE) { ptr = MUStrTok(NULL,",",&TokPtr); continue; } switch (aindex) { case mnaOS: { char EMsg[MMAX_LINE]; if (!strcmp(Value,MAList[meOpsys][0])) { if ((N->PowerSelectState == mpowOff) && (MNodeSetAttr(N,mnaPowerIsEnabled,(void **)"true",mdfString,mVerify) == FAILURE)) { if (Msg != NULL) MUStrCpy(Msg,EMsg,MMAX_LINE); /* do not return failure just because one provisioning job fails */ } } else if (MNodeProvision(N,NULL,NULL,Value,TRUE,EMsg,NULL) == FAILURE) { if (Msg != NULL) MUStrCpy(Msg,EMsg,MMAX_LINE); /* do not return failure just because one provisioning job fails */ } else { NodeModifySuccessDetected = TRUE; } } break; case mnaPowerIsEnabled: /* NOTE: do not return failure just because node modify fails * the routine will fail if all node modifies fail */ if (!strcmp(Value,"on")) { /* power node on */ if (MNodeSetAttr(N,mnaPowerIsEnabled,(void **)"true",mdfString,mVerify) == SUCCESS) { NodeModifySuccessDetected = TRUE; } } else if (!strcasecmp(Value,"off")) { /* power node off */ if (MNodeSetAttr(N,mnaPowerIsEnabled,(void **)"false",mdfString,mVerify) == SUCCESS) { NodeModifySuccessDetected = TRUE; } } else if (!strcasecmp(Value,"reset")) { char EMsg[MMAX_LINE]; /* reset node */ if (MNodeReboot(N,NULL,EMsg,NULL) == FAILURE) { if (Msg != NULL) MUStrCpy(Msg,EMsg,MMAX_LINE); } else { NodeModifySuccessDetected = TRUE; } } else if (!strcasecmp(Value,"on+")) { /* power node on, but trigger isn't finished until action is complete */ if (Complete != NULL) *Complete = FALSE; if (T != NULL) MUStrDup(&T->CompleteAction,ActionString); MNodeSetAttr(N,mnaPowerIsEnabled,(void **)"true",mdfString,mVerify); T->PID = 1; } else if (!strcasecmp(Value,"off+")) { /* power node off, but trigger isn't finished until action is complete */ if (T != NULL) MUStrDup(&T->CompleteAction,ActionString); if (Complete != NULL) *Complete = FALSE; MNodeSetAttr(N,mnaPowerIsEnabled,(void **)"false",mdfString,mVerify); T->PID = 1; } break; default: return(FAILURE); /*NOTREACHED*/ break; } /* END switch (aindex) */ ptr = MUStrTok(NULL,",",&TokPtr); } /* END while (ptr != NULL) */ /* if none of the node modify requests (non-aggregating) succeeded, then return failure. (success just means it was submitted at this stage) */ if ((aindex == mnaOS) && (NodeModifySuccessDetected == FALSE)) { return (FAILURE); } } /* END if (MSched.AggregateNodeActions == FALSE) */ else { mnl_t NL; char *Attr; char *Value; enum MNodeAttrEnum aindex; int nindex; /* FORMAT: <ARG>=<VALUE> */ Attr = MUStrTok(ArgLine,"=",&TokPtr); Value = MUStrTok(NULL,"= \t\n",&TokPtr); aindex = (enum MNodeAttrEnum)MUGetIndexCI(Attr,MNodeAttr,FALSE,mnaNONE); /* FORMAT: OID = node[,node]... */ if (aindex == mnaNONE) { return(FAILURE); } MNLInit(&NL); MNLFromString(OID,&NL,-1,FALSE); /* NOTE: in the node aggregating case, return failure when there is an error * performing node modify operations (e.g. communicating with the RM) */ switch (aindex) { case mnaNodeState: { enum MStatusCodeEnum SC; char EMsg[MMAX_LINE]; if (MNodeModify(NULL,OID,mnaNodeState,Value,EMsg,&SC) == FAILURE) { MDB(2,fRM) MLog("WARNING: cannot modify state of '%s' = %s\n", OID, EMsg); return(FAILURE); } } /* END case mnaNodeState */ break; case mnaOS: { char EMsg[MMAX_LINE]; if (MNLGetemReady(&NL,Value,EMsg) == FAILURE) { /* NYI: append EMsg to Msg */ if (Msg != NULL) MUStrCpy(Msg,EMsg,MMAX_LINE); MNLFree(&NL); return (FAILURE); } } /* END BLOCK case mnaOS */ break; case mnaPowerIsEnabled: { mnode_t *N; for (nindex = 0;MNLGetNodeAtIndex(&NL,nindex,&N) == SUCCESS;nindex++) { if (N == MSched.GN) continue; if ((!strcasecmp(Value,"on")) || (!strcasecmp(Value,"on+"))) { /* power node on */ if ((N->PowerSelectState == mpowOn) || (MNodeGetSysJob(N,msjtPowerOn,MBNOTSET,NULL) == SUCCESS)) { /* skip this node */ MDB(5,fSCHED) MLog("INFO: not powering node '%s' on--power select state is already 'ON'\n", N->Name); MNLRemove(&NL,N); continue; } } else if ((!strcasecmp(Value,"off")) || (!strcasecmp(Value,"off+"))) { /* power node off */ if ((N->PowerSelectState == mpowOff) || (MNodeGetSysJob(N,msjtPowerOff,TRUE,NULL) == SUCCESS)) { /* skip this node */ MDB(5,fSCHED) MLog("INFO: not powering node '%s' off--power select state is already 'OFF'\n", N->Name); MNLRemove(&NL,N); continue; } } } /* END for (nindex) */ } /* END BLOCK */ if (!strcmp(Value,"on")) { /* power node on */ if (MNLSetAttr(&NL,mnaPowerIsEnabled,(void **)"true",mdfString,mVerify) == FAILURE) { MNLFree(&NL); return (FAILURE); } } else if (!strcasecmp(Value,"off")) { /* power node off */ if (MNLSetAttr(&NL,mnaPowerIsEnabled,(void **)"false",mdfString,mVerify) == FAILURE) { MNLFree(&NL); return (FAILURE); } } else if (!strcasecmp(Value,"reset")) { char EMsg[MMAX_LINE]; /* reset node */ if (MNodeReboot(NULL,&NL,EMsg,NULL) == FAILURE) { MNLFree(&NL); /* NYI: append EMsg to Msg */ if (Msg != NULL) MUStrCpy(Msg,EMsg,MMAX_LINE); return (FAILURE); } } else if (!strcasecmp(Value,"on+")) { /* power node on, but trigger isn't finished until action is complete */ if (MNLSetAttr(&NL,mnaPowerIsEnabled,(void **)"true",mdfString,mVerify) == FAILURE) { MNLFree(&NL); if (Complete != NULL) *Complete = TRUE; return(FAILURE); } if (Complete != NULL) *Complete = FALSE; if (T != NULL) MUStrDup(&T->CompleteAction,ActionString); T->PID = 1; } else if (!strcasecmp(Value,"off+")) { /* power node off, but trigger isn't finished until action is complete */ if (MNLSetAttr(&NL,mnaPowerIsEnabled,(void **)"false",mdfString,mVerify) == FAILURE) { MNLFree(&NL); if (Complete != NULL) *Complete = TRUE; return(FAILURE); } if (Complete != NULL) *Complete = FALSE; if (T != NULL) MUStrDup(&T->CompleteAction,ActionString); T->PID = 1; } break; default: MNLFree(&NL); return (FAILURE); /*NOTREACHED*/ break; } /* END switch (aindex) */ } /* END else */ break; case mncmCreate: { int rc; mnode_t *N; char EMsg[MMAX_LINE]; char tmpLine[MMAX_LINE*10]; /* FORMAT: COUNT:OS */ if (MNodeFind(OID,&N) == FAILURE) { if (Msg != NULL) snprintf(Msg,MMAX_LINE,"cannot locate hostlist '%s'",OID); return(FAILURE); } /* FORMAT: COUNT:OS */ snprintf(tmpLine,sizeof(tmpLine),"%s:%s%s%s", N->Name, ArgLine, ((T->OType == mxoJob) && ((mjob_t *)T->O != NULL)) ? ":operationid=" : "", ((T->OType == mxoJob) && ((mjob_t *)T->O != NULL)) ? ((mjob_t *)T->O)->Name : ""); mstring_t Output(MMAX_LINE); rc = MRMVMCreate(tmpLine,&Output,EMsg,NULL); if (rc == FAILURE) { if (Msg != NULL) MUStrCpy(Msg,EMsg,MMAX_LINE); MUStrCpy(Msg,Output.c_str(),MMAX_LINE); } return(rc); } /* END BLOCK (case mncmCreate) */ break; case mncmMigrate: { int rc; char *TokPtr = ArgLine; char *VMName; char *SrcNodeName; char *DestNodeName; mnode_t *SrcNode; mnode_t *DestNode; mln_t *VMLink; char *VMList[2]; mnl_t DestNL; /* FORMAT: <VM>:<DestNode>,... */ TokPtr = ArgLine; VMName = MUStrTok(NULL,":=",&TokPtr); DestNodeName = MUStrTok(NULL,":=",&TokPtr); SrcNodeName = OID; if ((DestNodeName == NULL) || (VMName == NULL) ||(SrcNodeName) == NULL) { return(FAILURE); } if (MNodeFind(SrcNodeName,&SrcNode) == FAILURE) { return(FAILURE); } if (MNodeFind(DestNodeName,&DestNode) == FAILURE) { return(FAILURE); } if (MULLCheck(SrcNode->VMList,VMName,&VMLink) == FAILURE) { /* Should we be checking this here? */ /* return(FAILURE); */ } MNLInit(&DestNL); VMList[0] = VMName; MNLSetNodeAtIndex(&DestNL,0,DestNode); MNLSetTCAtIndex(&DestNL,0,1); MNLTerminateAtIndex(&DestNL,1); VMList[1] = NULL; rc = MRMJobMigrate((mjob_t *)T->O,VMList,&DestNL,Msg,NULL); MNLFree(&DestNL); return(rc); } /* END BLOCK (case mncmMigrateVM) */ break; default: return(FAILURE); /*NOTREACHED*/ break; } } /* END BLOCK (case mxoNode) */ break; case mxoxJobGroup: { job_iter JTI; marray_t JArray; int jindex; mjob_t *J; char *JID; char *ptr; char *TokPtr; /* OID FORMAT: <JID>[+<JID>]... */ mbool_t FailureDetected; enum MJobCtlCmdEnum atype; char *Attr = NULL; char *Value = NULL; char *Msg = NULL; enum MJobAttrEnum aindex = mjaNONE; atype = (enum MJobCtlCmdEnum)MUGetIndexCI(Action,MJobCtlCmds,FALSE,mjcmNONE); if (atype == mjcmNONE) { MDB(4,fSCHED) MLog("ERROR: cannot parse job action '%s' in %s\n", Action, FName); return(FAILURE); } if (atype == mjcmModify) { char *TokPtr; Attr = MUStrTok(ArgLine,"+-=",&TokPtr); Value = MUStrTok(NULL,"=: \t\n",&TokPtr); Msg = MUStrTok(NULL,":\t\n",&TokPtr); /* extract message */ aindex = (enum MJobAttrEnum)MUGetIndexCI(Attr,MJobAttr,FALSE,mnaNONE); } FailureDetected = FALSE; JID = MUStrTok(OID,"+",&TokPtr); while (JID != NULL) { MUArrayListCreate(&JArray,sizeof(mjob_t *),1); if (!strcmp(JID,"-")) { if (T == NULL) return(FAILURE); ptr = T->OID; } else { ptr = JID; } MJobIterInit(&JTI); while (MJobTableIterate(&JTI,&J) == SUCCESS) { if ((J->JGroup != NULL) && (J->JGroup->Name != NULL) && (!strcmp(ptr,J->JGroup->Name))) { MUArrayListAppend(&JArray,&J); } } if (MUArrayListGet(&JArray,0) == NULL) { MDB(4,fSCHED) MLog("ERROR: cannot locate job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } for (jindex = 0;jindex < JArray.NumItems;jindex++) { J = *(mjob_t **)MUArrayListGet(&JArray,jindex); if (J == NULL) continue; switch (atype) { case mjcmCancel: { char *CCodeCheck; char UpperArgLine[MMAX_LINE]; if (MJobCancel(J,NULL,FALSE,Msg,NULL) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot cancel job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } MUStrToUpper(ArgLine,UpperArgLine,MMAX_LINE); /* If specified, allow trigger to set the completion code of the job */ if ((CCodeCheck = strstr(UpperArgLine,"CCODE=")) != NULL) { CCodeCheck += strlen("CCODE="); /* Skip the "CCODE:" part */ if (CCodeCheck[0] != '\0') { J->CompletionCode = strtol(CCodeCheck,NULL,10); } } else { J->CompletionCode = 273; /* Completion code for a canceled job in TORQUE */ } } /* END case mjcmCancel */ break; case mjcmModify: switch (aindex) { case mjaHold: if (MJobSetAttr( J, mjaHold, (Value != NULL) ? (void **)Value : (void **)"batch", mdfString, mSet) == FAILURE) { MDB(4,fSCHED) MLog("ERROR: cannot hold job '%s' in %s\n", JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } if (Msg != NULL) { /* attach provided message */ MMBAdd( &J->MessageBuffer, Msg, NULL, mmbtHold, 0, 0, NULL); } if (J->SubState == mjsstProlog) { J->SubState = mjsstNONE; } /* checkpoint change (make this configurable at this point?) */ MOCheckpoint(mxoJob,(void *)J,FALSE,NULL); break; default: MDB(4,fSCHED) MLog("ERROR: cannot modify attribute '%s' for job '%s' in %s\n", Attr, JID, FName); JID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; break; } /* END switch (aindex) */ break; default: MDB(4,fSCHED) MLog("ERROR: action '%s' not handled in %s\n", Action, FName); return(FAILURE); /*NOTREACHED*/ break; } /* END switch (atype) */ } /* END for (jindex) */ JID = MUStrTok(NULL,"+",&TokPtr); MUArrayListFree(&JArray); } /* END while (JID != NULL) */ if (FailureDetected == TRUE) { return(FAILURE); } } /* END BLOCK (case mxoxJobGroup) */ break; case mxoSched: { enum MSchedCtlCmdEnum atype; atype = (enum MSchedCtlCmdEnum)MUGetIndexCI(Action,MSchedCtlCmds,FALSE,msctlNONE); switch (atype) { case msctlVMMigrate: { enum MVMMigrationPolicyEnum aindex; aindex = (enum MVMMigrationPolicyEnum)MUGetIndexCI(ArgLine,MVMMigrationPolicy,FALSE,mvmmmNONE); return(MUIVMCtlPlanMigrations(aindex,FALSE,FALSE,NULL)); } default: return(FAILURE); } /* END switch (atype) */ } /* END case mxoSched */ break; case mxoTrig: { enum MSchedCtlCmdEnum atype; atype = (enum MSchedCtlCmdEnum)MUGetIndexCI(Action,MSchedCtlCmds,FALSE,msctlNONE); if (atype == msctlNONE) { return(FAILURE); } switch (atype) { case msctlModify: { char *TokPtr; mtrig_t *T; char *Attr; char *Value; enum MTrigAttrEnum aindex; Attr = MUStrTok(ArgLine,"=",&TokPtr); Value = MUStrTok(NULL,"\"",&TokPtr); /* FORMAT: OID = trigid */ aindex = (enum MTrigAttrEnum)MUGetIndexCI(Attr,MTrigAttr,FALSE,mtaNONE); if ((OID == NULL) || (OID[0] == '\0') || (aindex == mtaNONE)) { return(FAILURE); } if (MTrigFind(OID,&T) == FAILURE) { return(FAILURE); } switch (aindex) { case mtaActionData: if (MTrigSetAttr(T,aindex,Value,mdfString,mSet) == FAILURE) { return(FAILURE); } break; default: return(FAILURE); /*NOTREACHED*/ break; } /* END switch (aindex) */ break; } /* END case msctlModify */ default: return(FAILURE); /*NOTREACHED*/ break; } /* END switch (atype) */ } /* END BLOCK (case mxoTrig) */ break; case mxoRM: { mrm_t *R = NULL; char *RMID; char *TokPtr; mbool_t FailureDetected; enum MRMCtlCmdEnum atype; atype = (enum MRMCtlCmdEnum)MUGetIndexCI(Action,MRMCtlCmds,FALSE,mrmctlNONE); if (atype == mrmctlNONE) { MDB(4,fSCHED) MLog("ERROR: cannot parse rm action '%s' in %s\n", Action, FName); return(FAILURE); } FailureDetected = FALSE; RMID = MUStrTok(OID,"+",&TokPtr); while (RMID != NULL) { if (!strcmp(RMID, "-")) { if (T == NULL) return(FAILURE); R = (mrm_t *)T->O; } else if (MRMFind(RMID,&R) == FAILURE) { if (Msg != NULL) strcpy(Msg,"cannot locate specified RM"); RMID = MUStrTok(NULL,"+",&TokPtr); FailureDetected = TRUE; continue; } switch (atype) { case mrmctlModify: { char *TokPtr; enum MRMAttrEnum aindex; char *Attr; char *Value; /* FORMAT: <attr>=<value> */ Attr = MUStrTok(ArgLine,"=",&TokPtr); Value = MUStrTok(NULL,"\"",&TokPtr); aindex = (enum MRMAttrEnum)MUGetIndexCI(Attr,MRMAttr,FALSE,mrmaNONE); switch (aindex) { case mrmaState: return(MRMSetAttr(R,aindex,(void **)Value,mdfString,mSet)); break; default: if (Msg != NULL) strcpy(Msg,"cannot modify specified attribute"); return(FAILURE); /* NOTREACHED */ break; } /* END switch (aindex) */ } /* END BLOCK (case mrmctlModify) */ break; case mrmctlDestroy: MDB(3,fUI) MLog("WARNING: cannot destroy static RM\n"); if (Msg != NULL) strcpy(Msg,"WARNING: cannot destroy static RM\n"); return(FAILURE); /* NOTREACHED */ break; case mrmctlPurge: return(MRMPurge(R)); break; default: if (Msg != NULL) strcpy(Msg,"action not supported for RM object"); return(FAILURE); /*NOTREACHED*/ break; } /* END switch (atype) */ RMID = MUStrTok(NULL,"+",&TokPtr); } /* END while (RMID != NULL */ if (FailureDetected == TRUE) { return(FAILURE); } } /* END BLOCK (case mxoRM) */ break; case mxoRsv: { enum MRsvCtlCmdEnum atype; atype = (enum MRsvCtlCmdEnum)MUGetIndexCI(Action,MRsvCtlCmds,FALSE,mrcmNONE); if (atype == mrcmNONE) { return(FAILURE); } switch (atype) { case mrcmModify: { char *ptr; char *TokPtr; enum MRsvAttrEnum attr; mrsv_t *R; if (!strcmp(OID,"-")) { if (T == NULL) return(FAILURE); R = (mrsv_t *)T->O; } else if (MRsvFind(OID,&R,mraNONE) == FAILURE) { return(FAILURE); } ptr = MUStrTok(ArgLine,":",&TokPtr); attr = (enum MRsvAttrEnum)MUGetIndexCI(ptr,MRsvAttr,FALSE,mraNONE); switch (attr) { case mraACL: { enum MObjectSetModeEnum Mode; if (MUStrIsEmpty(TokPtr)) Mode = mSet; else if (strstr(TokPtr,"-=") != NULL) Mode = mDecr; else if (strstr(TokPtr,"+=") != NULL) Mode = mAdd; else Mode = mSet; MRsvSetAttr(R,mraACL,(void *)TokPtr,mdfString,Mode); } break; default: return(FAILURE); /*NOTREACHED*/ break; } } /* END case mrcmModify */ break; case mrcmDestroy: { mrsv_t *R; if (!strcmp(OID,"-")) { if (T == NULL) return(FAILURE); R = (mrsv_t *)T->O; } else if (MRsvFind(OID,&R,mraNONE) == FAILURE) { return(FAILURE); } R->CancelIsPending = TRUE; R->EndTime = MSched.Time - 1; R->ExpireTime = 0; /* remove reservation */ MRsvCheckStatus(NULL); if ((long)R->StartTime <= MUIDeadLine) { /* adjust UI phase wake up time */ if (MSched.AdminEventAggregationTime >= 0) MUIDeadLine = MIN(MUIDeadLine,(long)MSched.Time + MSched.AdminEventAggregationTime); } } /* END case mrcmDestroy */ break; case mrcmOther: { mrsv_t *R; if (!strcmp(OID,"-")) { if (T == NULL) { return(FAILURE); } R = (mrsv_t *)T->O; } else if (MRsvFind(OID,&R,mraNONE) == FAILURE) { return(FAILURE); } /* parse argline */ if (strstr(ArgLine,"submit") != NULL) { MJobSubmitFromJSpec(R->SpecJ,NULL,Msg); } /* END if (strstr(ArgLine,"submit") != NULL) */ } /* END BLOCK (case mrcmOther) */ break; default: return(FAILURE); /*NOTREACHED*/ break; } /* END switch (atype) */ } /* END BLOCK (case mxoRsv) */ break; case mxoxVPC: { mpar_t *VPC; MVPCFind(OID,&VPC,TRUE); if (!strcasecmp(Action,"destroy")) { MVPCDestroy(&VPC,ArgLine); } else { return(FAILURE); } } /* END case mxoxVPC */ break; default: if (Msg != NULL) strcpy(Msg,"unsupported trigger object type"); return(FAILURE); /* NOTREACHED */ break; } /* END switch (OType) */ /*NOTE: return may (and does) return in above switch statement */ return(SUCCESS); } /* END MTrigLaunchInternalAction() */