Files
maui/src/server/OUserI.c
wightman 245cf417ee small patches for RM->EPort and MADMINHOSTS
git-svn-id: svn://opensvn.adaptivecomputing.com/maui/trunk@72 3f5042e3-fb1d-0410-be18-d6ca2573e517
2006-11-17 16:56:07 +00:00

1343 lines
28 KiB
C

/*
*/
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;
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 (!strcmp(MSched.AdminHost[index],S->Host))
{
hostcheck = TRUE;
break;
}
if (!strcmp(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(S->SBuffer,"%s%d ",
MCKeyword[mckStatusCode],
scFAILURE);
Align = (int)strlen(S->SBuffer) + (int)strlen(MCKeyword[mckArgs]);
sprintf(S->SBuffer,"%s%*s%s",
S->SBuffer,
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 ShowJobHold(
char *RBuffer, /* I */
char *Buffer, /* O */
int FLAGS, /* I */
char *Auth, /* I */
long *BufSize) /* I */
{
char Line[MAX_MLINE];
mjob_t *J;
const char *FName = "ShowJobHold";
DBG(2,fUI) DPrint("%s(RBuffer,Buffer,%d,%s,BufSize)\n",
FName,
FLAGS,
Auth);
sprintf(Buffer,"%ld\n",
MSched.Time);
for (J = MJob[0]->Next;(J != NULL) && (J != MJob[0]);J = J->Next)
{
if (J->Hold != 0)
{
DBG(2,fUI) DPrint("INFO: job '%s' added to hold list\n",
J->Name);
sprintf(Line,"%s %d\n",
J->Name,
J->Hold);
strcat(Buffer,Line);
}
} /* END for (index) */
DBG(2,fUI) DPrint("INFO: ShowJobHold() buffer size: %d bytes\n",
(int)strlen(Buffer));
return(SUCCESS);
} /* END ShowJobHold() */
int SetJobUserPrio(
char *RBuffer,
char *Buffer,
int FLAGS,
char *Auth,
long *BufSize)
{
char Name[MAX_MNAME];
int Priority;
mjob_t *J;
const char *FName = "SetJobUserPrio";
DBG(2,fUI) DPrint("%s(RBuffer,Buffer,%d,%s,BufSize)\n",
FName,
FLAGS,
Auth);
MUSScanF(RBuffer,"%x%s %d",
sizeof(Name),
Name,
&Priority);
if ((Priority < 0) || (Priority > 100))
{
strcpy(Buffer,"ERROR: user priority must be in the range 0 - 100\n");
return(FAILURE);
}
if (MJobFind(Name,&J,0) == FAILURE)
{
sprintf(Buffer,"Error: cannot locate job '%s'\n",
Name);
return(FAILURE);
}
/* security check */
if (!(FLAGS & ((1 << fAdmin1) | (1 << fAdmin2))))
{
if (strcmp(J->Cred.U->Name,Auth) != 0)
{
DBG(2,fUI) DPrint("INFO: user %s is not authorized to set user priority on job %s\n",
Auth,
J->Name);
sprintf(Buffer,"user %s is not authorized to set user priority on job %s\n",
Auth,
J->Name);
return(FAILURE);
}
}
J->UPriority = Priority;
DBG(2,fUI) DPrint("INFO: user priority on job '%s' set to %d\n",
Name,
Priority);
return(SUCCESS);
} /* END JobSetUserPrio() */
int UIShowGrid(
char *RBuffer, /* I */
char *Buffer, /* O */
int FLAGS, /* I */
char *Auth, /* I */
long *BufSize) /* I */
{
int sindex;
char GStat[MAX_MNAME];
const char *FName = "UIShowGrid";
DBG(3,fUI) DPrint("%s(RBuffer,Buffer,%d,%s,BufSize)\n",
FName,
FLAGS,
Auth);
MUSScanF(RBuffer,"%x%s",
sizeof(GStat),
GStat);
/* determine statistics type requested */
for (sindex = 0;MStatType[sindex] != 0;sindex++)
{
if (!strcmp(MStatType[sindex],GStat))
break;
} /* END for (sindex) */
if (MStatType[sindex] == NULL)
{
DBG(2,fUI) DPrint("INFO: invalid stat type '%s' requested\n",
GStat);
sprintf(Buffer,"ERROR: invalid statistics type requested\n");
strcat(Buffer,"\nvalid statistics types:\n");
for (sindex = 0;MStatType[sindex] != 0;sindex++)
{
strcat(Buffer,MStatType[sindex]);
strcat(Buffer,"\n");
} /* END for (sindex) */
return(FAILURE);
} /* END if (MStatType[sindex] == NULL) */
MStatBuildGrid(sindex,Buffer,0);
return(SUCCESS);
} /* END UIShowGrid() */
int ShowBackfillWindow(
char *RBuffer, /* I */
char *Buffer, /* O */
int FLAGS, /* I */
char *Auth, /* I */
long *BufSize) /* I */
{
int BFNodeCount;
int BFProcCount;
nodelist_t BFNodeList;
long BFTime;
long MinTime;
long RequiredTime;
long RequiredNodes;
long RequiredProcs;
char UserName[MAX_MNAME];
char GroupName[MAX_MNAME];
char AccountName[MAX_MNAME];
int Memory;
char MemCmp[MAX_MNAME];
int DMemory;
char PName[MAX_MNAME];
char CurrentPName[MAX_MNAME];
int index;
int pindex;
int mindex;
int nindex;
int ShowSMP; /* (boolean) */
char Affinity;
int Type;
int Flags;
char QOSName[MAX_MNAME];
char ClassString[MAX_MLINE];
char FeatureString[MAX_MLINE];
mnode_t *N;
mjob_t tmpJ;
mjob_t *J;
mreq_t tmpRQ;
mcres_t DRes;
mpar_t *P;
mpar_t *SP;
mrange_t ARange[MAX_MRANGE];
mrange_t RRange[2];
int NodeHeaderPrinted;
int PCount;
char tmpBuffer[MAX_MBUFFER];
const char *FName = "ShowBackfillWindow";
DBG(2,fUI) DPrint("%s(%s,Buffer,%d,%s,BufSize)\n",
FName,
RBuffer,
FLAGS,
Auth);
if (MUSScanF(RBuffer,"%x%s %x%s %x%s %x%s %ld %ld %ld %d %d %x%s %d %d %x%s %x%s %x%s",
sizeof(UserName),
UserName,
sizeof(GroupName),
GroupName,
sizeof(AccountName),
AccountName,
sizeof(PName),
PName,
&RequiredTime,
&RequiredNodes,
&RequiredProcs,
&DMemory,
&Memory,
sizeof(MemCmp),
MemCmp,
&ShowSMP,
&Flags,
sizeof(ClassString),
ClassString,
sizeof(FeatureString),
FeatureString,
sizeof(QOSName),
QOSName) == FAILURE)
{
/* invalid request string */
DBG(3,fUI) DPrint("INFO: cannot parse request\n");
sprintf(Buffer,"ERROR: cannot parse request\n");
return(FAILURE);
}
MParFind(PName,&SP);
DBG(4,fUI) DPrint("INFO: locating backfill window for u: %s g: %s a: %s p: %s c: %s f: %s (%ld:%ld:%d)\n",
UserName,
GroupName,
AccountName,
MAList[ePartition][(SP != NULL) ? SP->Index : 0],
ClassString,
FeatureString,
RequiredTime,
RequiredNodes,
Memory);
if (ShowSMP == FALSE) /* NON-SMP */
{
mindex = 0;
if (Memory > 0)
{
for (mindex = 0;MComp[mindex] != NULL;mindex++)
{
if (!strcmp(MComp[mindex],MemCmp))
break;
}
if (MComp[mindex] == NULL)
mindex = 0;
}
memset(&DRes,0,sizeof(DRes));
DRes.Procs = 1;
DRes.Mem = DMemory;
sprintf(Buffer,"backfill window (user: '%s' group: '%s' partition: %s) %s\n",
UserName,
GroupName,
PName,
MULToDString((mulong *)&MSched.Time));
PCount = 0;
for (pindex = 1;pindex < MAX_MPAR;pindex++)
{
if (MPar[pindex].ConfigNodes == 0)
continue;
PCount++;
}
index = 0;
for (pindex = 0;pindex < MAX_MPAR;pindex++)
{
P = &MPar[pindex];
if ((SP != NULL) && (SP != P))
continue;
if ((PCount == 1) && (SP == NULL) && (P->Index != 0))
break;
if (P->ConfigNodes == 0)
continue;
MinTime = 0;
DBG(7,fUI) DPrint("INFO: checking window in partition %s\n",
P->Name);
strcpy(CurrentPName,GLOBAL_MPARNAME);
index = 0;
while (MBFGetWindow(
&BFNodeCount,
&BFProcCount,
BFNodeList,
&BFTime,
MinTime,
P,
UserName,
GroupName,
AccountName,
mindex,
Memory,
MAX(1,RequiredTime),
&DRes,
ClassString,
FeatureString,
QOSName,
(Flags & (1 << mcmVerbose)) ?
tmpBuffer :
NULL) == SUCCESS)
{
DBG(4,fUI) DPrint("INFO: located backfill window [%03d nodes : %06ld seconds]\n",
BFNodeCount,
BFTime);
if ((BFTime >= RequiredTime) &&
(BFNodeCount >= RequiredNodes) &&
(BFProcCount >= RequiredProcs))
{
if (strcmp(P->Name,CurrentPName) != 0)
{
if ((strcmp(CurrentPName,GLOBAL_MPARNAME)) && (index == 0))
{
sprintf(Buffer,"%sno %s available\n",
Buffer,
(MSched.DisplayFlags & (1 << dfNodeCentric)) ? "nodes" : "procs");
}
strcpy(CurrentPName,P->Name);
sprintf(Buffer,"%s\npartition %s:\n",
Buffer,
P->Name);
index = 0;
}
if (MSched.DisplayFlags & (1 << dfNodeCentric))
{
/* node centric output */
if (BFNodeCount == 0)
{
sprintf(Buffer,"%sno nodes available\n",
Buffer);
}
else if (BFTime < 100000000)
{
sprintf(Buffer,"%s%3d node%s available for %11s\n",
Buffer,
BFNodeCount,
(BFNodeCount > 1) ? "s" : "",
MULToTString(BFTime));
}
else
{
sprintf(Buffer,"%s%3d node%s available with no timelimit\n",
Buffer,
BFNodeCount,
(BFNodeCount > 1) ? "s" : "");
}
}
else
{
/* proc centric output */
if (BFProcCount == 0)
{
sprintf(Buffer,"%sno procs available\n",
Buffer);
}
else if (BFTime < 100000000)
{
sprintf(Buffer,"%s%3d proc%s available for %11s\n",
Buffer,
BFProcCount,
(BFProcCount > 1) ? "s" : "",
MULToTString(BFTime));
}
else
{
sprintf(Buffer,"%s%3d proc%s available with no timelimit\n",
Buffer,
BFProcCount,
(BFProcCount > 1) ? "s" : "");
}
}
index++;
} /* END if (BFTime) */
MinTime = BFTime;
} /* END while (MBFGetWindow() == SUCCESS) */
if (Flags & (1 << mcmVerbose))
{
strcat(Buffer,"\n\n");
strcat(Buffer,tmpBuffer);
}
} /* END for (pindex) */
if (index == 0)
{
sprintf(Buffer,"%sno procs available\n",
Buffer);
}
strcat(Buffer,"\n\n");
} /* END if (ShowSMP == FALSE) */
else
{
/* SMP Mode */
RRange[0].StartTime = MSched.Time;
RRange[0].EndTime = MAX_MTIME;
RRange[1].EndTime = 0;
memset(&tmpJ,0,sizeof(tmpJ));
memset(&tmpRQ,0,sizeof(tmpRQ));
J = &tmpJ;
tmpRQ.DRes.Procs = 1;
tmpRQ.DRes.Mem = DMemory;
J->Req[0] = &tmpRQ;
if (MJobSetCreds(J,ALL,ALL,ALL) == FAILURE)
{
DBG(3,fUI) DPrint("INFO: cannot setup showbf job creds\n");
sprintf(Buffer,"ERROR: cannot determine available resources\n");
return(FAILURE);
}
if (MQOSFind(QOSName,&J->QReq) == FAILURE)
{
/* cannot locate requested QOS */
MQOSFind(DEFAULT,&J->QReq);
}
MJobSetQOS(J,J->QReq,0);
MJobBuildCL(J);
sprintf(Buffer,"%s%20s %5s %6s %7s %7s %14s\n",
Buffer,
"HostName",
"Procs",
"Memory",
"Disk",
"Swap",
"Time Available");
sprintf(Buffer,"%s%20s %5s %6s %7s %7s %14s\n",
Buffer,
"----------",
"-----",
"------",
"-------",
"-------",
"--------------");
for (nindex = 0;nindex < MAX_MNODE;nindex++)
{
N = MNode[nindex];
if ((N == NULL) || (N->Name[0] == '\0'))
break;
if (N->Name[0] == '\1')
continue;
if ((N->State != mnsActive) && (N->State != mnsIdle))
continue;
if ((SP != NULL) && (SP->Index != 0) && (N->PtIndex != SP->Index))
continue;
NodeHeaderPrinted = FALSE;
for (RRange[0].TaskCount = 1;RRange[0].TaskCount < N->CRes.Procs;RRange[0].TaskCount = ARange[0].TaskCount + 1)
{
if (MJobGetSNRange(
J,
J->Req[0],
N,
RRange,
1,
&Affinity,
&Type,
ARange,
&DRes,
NULL) == SUCCESS)
{
if (ARange[0].StartTime != MSched.Time)
{
/* resources not available immediately */
break;
}
if (NodeHeaderPrinted == FALSE)
{
strcat(Buffer,"\n");
NodeHeaderPrinted = TRUE;
}
sprintf(Buffer,"%s%20s %5d %6d %7d %7d %14s\n",
Buffer,
N->Name,
DRes.Procs,
DRes.Mem,
DRes.Disk,
DRes.Swap,
MULToTString(ARange[0].EndTime - MSched.Time));
}
else
{
/* resources not available */
break;
}
}
} /* END for (nindex) */
} /* END else (ShowSMP == FALSE) */
return(SUCCESS);
} /* END ShowBackfillWindow() */
int UINodeStatShow(
int Flags,
char *Buffer,
long *BufSize)
{
int nindex;
int JobLimit;
int cindex;
unsigned long totalworkload;
int totalnodes;
int averageload;
double Average;
double IAverage;
int mem;
unsigned long MemTotalUpTime;
unsigned long MemTotalTotalTime;
unsigned long MemTotalBusyTime;
int MemTotalNodeCount;
int MemTotalBusyCount;
int MemTotalUpCount;
unsigned long SystemTotalUpTime;
unsigned long SystemTotalTotalTime;
unsigned long SystemTotalBusyTime;
int SystemTotalNodeCount;
int SystemTotalBusyCount;
int SystemTotalUpCount;
int mode;
mnode_t *N;
const char *FName = "UINodeStatShow";
DBG(2,fUI) DPrint("%s(%d,Buffer,BufSize)\n",
FName,
Flags);
mode = Flags & 0x1;
JobLimit = Flags >> 1;
MStatBuildRClass(JobLimit,MRClass);
sprintf(Buffer,"Memory Requirement Breakdown:\n\n");
sprintf(Buffer,"%s%8s %5s %7s %9s %7s %10s %7s\n",
Buffer,
"Memory",
"Proc",
"Percent",
"InitialNH",
"Percent",
"ProcHours",
"Percent");
totalnodes = 0;
totalworkload = 0;
/* determine total node count/class workload */
for (cindex = 0;cindex < MAX_MRCLASS;cindex++)
{
totalnodes += MRClass[cindex].Nodes;
totalworkload += MRClass[cindex].Workload;
} /* END for (cindex) */
if (totalnodes == 0)
{
sprintf(Buffer,"No Nodes Detected\n");
return(FAILURE);
}
averageload = totalworkload / totalnodes;
/* loop thru all memory classes */
for (cindex = 0;cindex < MAX_MRCLASS;cindex++)
{
if (MRClass[cindex].Memory == 0)
break;
if ((MRClass[cindex].Nodes == 0) || (averageload == 0))
{
Average = 0.0;
IAverage = 0.0;
}
else
{
Average = (double)MRClass[cindex].Workload / MRClass[cindex].Nodes / averageload * 100.0;
IAverage = (double)MRClass[cindex].InitialWorkload / MRClass[cindex].Nodes / averageload * 100.0;
}
sprintf(Buffer,"%s%8d %5d %7.2f %9ld %7.2f %10ld %7.2f\n",
Buffer,
MRClass[cindex].Memory,
MRClass[cindex].Nodes,
(double)MRClass[cindex].Nodes / totalnodes * 100.0,
MRClass[cindex].InitialWorkload / 3600,
IAverage,
MRClass[cindex].Workload / 3600,
Average);
} /* END for (cindex) */
sprintf(Buffer,"%s%8s %5d %7.2f %9d %7.2f %10d %7.2f\n\n",
Buffer,
"TOTAL",
totalnodes,
100.0,
(int)(totalworkload / 3600),
100.0,
(int)(totalworkload / 3600),
100.0);
strcat(Buffer,"\nNode Statistics\n\n");
/* dump node statistics */
/* loop through all memory sizes */
SystemTotalUpTime = 0;
SystemTotalTotalTime = 0;
SystemTotalBusyTime = 0;
SystemTotalNodeCount = 0;
SystemTotalUpCount = 0;
SystemTotalBusyCount = 0;
for (cindex = 0;cindex < MAX_MRCLASS;cindex++)
{
if (MRClass[cindex].Memory == 0)
break;
mem = MRClass[cindex].Memory;
MemTotalUpTime = 0;
MemTotalTotalTime = 0;
MemTotalBusyTime = 0;
MemTotalNodeCount = 0;
MemTotalUpCount = 0;
MemTotalBusyCount = 0;
for (nindex = 0;nindex < MAX_MNODE;nindex++)
{
N = MNode[nindex];
if ((N == NULL) || (N->Name[0] == '\0'))
break;
if (N->Name[0] == '\1')
continue;
if (N->CRes.Mem == mem)
{
if (MemTotalNodeCount == 0)
{
/* create memory class header */
if (mode == 0)
{
sprintf(Buffer,"%s%4dMB Nodes\n",
Buffer,
mem);
sprintf(Buffer,"%s%20s %9s %9s %9s\n",
Buffer,
"NodeName",
"Available",
"Busy",
"NodeState");
}
}
/* record mem stats in seconds */
MemTotalUpTime += N->SUTime;
MemTotalTotalTime += N->STTime;
MemTotalBusyTime += N->SATime;
MemTotalNodeCount++;
if ((N->State == mnsIdle) || (N->State == mnsActive) || (N->State == mnsBusy))
MemTotalUpCount++;
if (N->State == mnsBusy)
MemTotalBusyCount++;
if (mode == 0)
{
if (N->SUTime != 0)
{
sprintf(Buffer,"%s%20s %8.2f%s %8.2f%s %9s\n",
Buffer,
N->Name,
(double)N->SUTime / N->STTime * 100.0,
"%",
(double)N->SATime / N->SUTime * 100.0,
"%",
MNodeState[N->State]);
}
else
{
sprintf(Buffer,"%s%20s %9.2f %9.2f %9s\n",
Buffer,
N->Name,
0.0,
0.0,
MNodeState[N->State]);
}
} /* END if (mode == 0) */
} /* END if (N->CRes.Mem == mem) */
} /* END for (nindex) */
SystemTotalUpTime += MemTotalUpTime;
SystemTotalTotalTime += MemTotalTotalTime;
SystemTotalBusyTime += MemTotalBusyTime;
SystemTotalNodeCount += MemTotalNodeCount;
SystemTotalUpCount += MemTotalUpCount;
SystemTotalBusyCount += MemTotalBusyCount;
/* create memory summary */
if (MemTotalNodeCount != 0)
{
sprintf(Buffer,"%sSummary: %3d %4dMB Nodes %6.2f%s Avail %6.2f%s Busy (Current: %6.2f%s Avail %6.2f%s Busy)\n",
Buffer,
MemTotalNodeCount,
mem,
(double)MemTotalUpTime / MemTotalTotalTime * 100.0,
"%",
(double)MemTotalBusyTime / MemTotalTotalTime * 100.0,
"%",
(double)MemTotalUpCount / MemTotalNodeCount * 100.0,
"%",
(double)MemTotalBusyCount / MemTotalNodeCount * 100.0,
"%");
if (mode == 0)
strcat(Buffer,"\n");
}
} /* for (cindex) */
/* create system summary */
if (SystemTotalTotalTime != 0)
{
sprintf(Buffer,"%sSystem Summary: %3d Nodes %6.2f%s Avail %6.2f%s Busy (Current: %6.2f%s Avail %6.2f%s Busy)\n",
Buffer,
SystemTotalNodeCount,
(double)SystemTotalUpTime / SystemTotalTotalTime * 100.0,
"%",
(double)SystemTotalBusyTime / SystemTotalTotalTime * 100.0,
"%",
(double)SystemTotalUpCount / SystemTotalNodeCount * 100.0,
"%",
(double)SystemTotalBusyCount / SystemTotalNodeCount * 100.0,
"%");
}
strcat(Buffer,"\n");
return(SUCCESS);
} /* END UINodeStatShow() */
/* END OUserI.c */