| It looks like the scheduler developers took out messages of MTYPE 5 and
6 somewhere along the line because they could get along without them by
getting the completion status directly from the scheduler database when
the GUI gets a job completion message (or so I guess). Fortunately, we
can do the same thing. I modified MSG_AST.BAS to call VSS$NUM_TO_NAME
when a job completes. This returns the job completion status (as well
as jobname, username, other things). The modified version will print
the completion status for you. Note that you need scheduler read access
to a job to see information about it.
To try this out, extract the new MSG_AST.BAS below, or copy it from
RUMOR::NSCHED$:MSG_AST.BAS. Then
$ basic MSG_AST
$ link sched_listen,msg_ast,nsched$:nsched_subs/lib,sys$library:vaxcrtl/lib
----------------------------------------------------------------------
SUB MSG_AST ( long OUR_PARAM, R0, R1, PC, PSL)
! Copyright 1989,1992 Digital Equipment Corporation
! DECscheduler V1.1A, T2.0
! Modified 7-29-96 by Lou Falek to get exit status of completed
! jobs, since scheduler apparently no longer sends messages of
! MTYPE=5 or 6
! Blocking AST for SCHED_LISTEN program.
! This program is UNSUPPORTED.
! It can be used to display in real time changes in the status of
! DECscheduler jobs.
! This blocking AST recieves VAXcluster broadcasts
! which are sent whenever a Scheduler changes the state of a job.
! It is triggered when the Scheduler calls TELL_GUIDO (in NSCHED_SUBS)
! to send a message. TELL_GUIDO puts a message in the GUIDO_MSG
! lock value block, then requests a lock on "GUIDO_SIGNAL" in EX-mode,
! We never actually give up our lock on GUIDO_SIGNAL, rather, we
! call $GETLKIW to get the info from the GUIDO_MSG lock value block.
! Note that this AST only receives the LATEST message sent.
! If messages are sent more quickly then they are read, they are
! over-written (not queued).
OPTION TYPE = EXPLICIT
external long function sys$getlkiw,sys$enqw,lib$wait,lib$date_time,&
sys$exit,lib$getjpi
external long constant msg_ast,ss$_valnotvalid
declare long constant &
lck$m_system=X'00000010'L, &
lck$m_valblk=X'00000001'L, &
lck$m_convert=X'00000002'L, &
lck$k_nlmode=X'00000000'L, &
lck$k_crmode=X'00000001'L, &
lck$k_exmode=X'00000005'L, &
lck$m_nodlckwt=X'00000200'L
declare word constant lki$_valblk=X'203'W, ! to request value block &
lki$_locks=X'208'W ! to request info on locks
declare long cstatus,flags,number_of_locks,i
declare string old,new, info_state,who,user
! SCHED_LISTEN.BAS (which we're linked with) uses same lock$block map
map (lock$block) word cond,word fill,long lock_id, string msg=16%, &
long s_lblk(1%),string current_time=20%
! description of lock status/value block fields for message lock
map(mbuf) string ret_buffer=16%,long buff_len ! for returned info
map(mbuf) long jobnum,string mtype=1%,string old_state=1%,&
new_state=1%,string fill$=3,string sender=6%
map(mbuf) long jobnum,string mtype=1%,string operation=1%,&
long pid,string sender=6%
map (mbuf) string signals_info=1024% ! info on all signal locks
! description of lock info returned by $GETLKIW for signal lock(s)
map(msignal) long s_lockid,long s_opid, long s_sid, &
byte s_reqmode, byte s_grmode, byte s_que, byte s_fill, &
long s_remid, long s_remsid
map(msignal) string one_lock=24% ! buffer for info about one signal lock
record item_list ! declare item_list structure
word buffer_len ! for system services
word item_code
long buff_addr
long ret_len_addr
long end_list
end record item_list
declare item_list items ! fill in the item list
DEF string long_to_hex(long inlong) ! longword to HEX string
! convert a longword to a hexadecimal string
external long function ots$cvt_l_tz
declare string hex_string
hex_string=space$(8%)
cstatus=ots$cvt_l_tz(inlong,hex_string,8% by value,4% by value)
long_to_hex=hex_string
END DEF
! Call SYS$GETLKIW to get the value block for the GUIDO_MSG lock
! fill in item list for call to $GETLKIW
items::item_code=lki$_valblk ! value block wanted
items::buffer_len=16% ! our buffer length
items::buff_addr=loc(ret_buffer) ! addr. of ret_buffer
items::ret_len_addr=loc(buff_len) ! addr of length of retd. info
items::end_list=0 ! terminator
cstatus=sys$getlkiw( ,! efn &
lock_id,! lock-id addr &
items, ! item list &
,,,)
if cstatus<>1% then ! error &
print "MSG_AST: GETLKIW error : ";cstatus
cstatus=sys$exit(cstatus by value) ! exit program
end if
! parse the value block
! The format is job_number (longword), mtype (byte) (changed in V1.1A)
! data for state change msg (mtype="0") :
! old_state (1 byte) new_state (1 byte) sender_node (6 bytes)
! data for create/modify msg (mtype="1") :
! operation (1 byte = "C" or "M"
! PID that did it (long)
! sender node (6 bytes)
! data for informational msg (mtype="2") : see code
cstatus=lib$date_time(current_time) ! get current time
if mtype="5" then ! local job success completion &
print current_time;" Job";jobnum; &
"completed with SUCCESS status on ";trm$(sender)
goto re_set
else
if mtype="6" then ! local job success completion &
print current_time;" Job";jobnum; &
"completed with FAILURE status on ";trm$(sender)
goto re_set
end if
end if
if mtype="0" then ! job state change &
! make understandable strings out of 1 byte states
select old_state
case = "S"
old="Scheduled"
case="J"
old="Job Slot Wait"
case="R"
old="Running"
case="D"
old="Job dependency wait"
case="H"
old="Holding"
case="Q"
old="Queued"
case else
old=old_state
end select
select new_state
case = "S"
new="Scheduled"
case="J"
new="Job Slot Wait"
case="R"
new="Running"
case="D"
new="Job dependency wait"
case="H"
new="Holding"
case="Q"
new="Queued"
case else
new=new_state
end select
print current_time;" Job";jobnum;"changed from "; &
old;" to ";new;" on ";trm$(sender)
! code added by LF 7-29-96 to get the completion status of jobs
external long function vss$num_to_name
! gets job name, username, state, compl. status from job number
declare string ret_name_and_username,job_status,ret_jobstate
declare long ret_jobstat
if old_state="R" and new_state<>"R" then &
! a job completed, get and print completion status
cstatus=vss$num_to_name(jobnum,"",ret_jobstat,&
ret_jobstate, ret_name_and_username)
if (cstatus <> 1) then &
print " Couldn't read completion status for job ";jobnum; " ";cstatus
else
job_status=long_to_hex(ret_jobstat) ! convert to hex string
if (ret_jobstat and 1%)=1% then &
print " Completion Status: Success (";job_status;")"
else
print " Completion Status: Failure (";job_status;")"
end if
end if
end if
goto re_set
end if
! end of new code to show completion status
if mtype="1" then ! user-interface command &
cstatus=lib$getjpi(X'202'L,pid,,,user,)! pid to user
who=" Username="+trm$(user)+", PID="+long_to_hex(pid)
print current_time;" Job";jobnum;
select operation
case="M"
print "Modified by";who
case="C"
print "Created by";who
case="D"
print "Delete Requested by";who
case="A"
print "Abort Requested by";who
case="H"
print "Hold Requested by";who
case="U"
print "Release Requested by";who
case="N"
print "Run Requested by";who
case="R"
print "Deleted from job database by server"
case else
print "Operation = ";operation
end select
goto re_set
end if
if mtype="2" then ! informational msg from NSCHED &
info_state = old_state+new_state
select info_state
case = "XR"
new="Exceeded maximum run-time"
case = "XS"
new="Exceeded maximum stall-time without starting"
case else
new="Unknown informational event"+" "+info_state
end select
print current_time;" Job";jobnum;new;" on ";trm$(sender)
goto re_set
end if
re_set:
! loop until sender has $deq'd lock request
! call $getlkiw until no more requestors are waiting
! fill in item list code for call to $GETLKIW
items::item_code=lki$_locks ! get info on all SIGNAL locks
items::buffer_len=1024% ! up to 1024 bytes total
items::buff_addr=loc(signals_info) ! addr. of ret_buffer
get_info:
cstatus=sys$getlkiw( ,! efn &
s_lblk(1%),! lock-id of SIGNAL lock &
items, ! item list &
,,,)
print "bad status from GETLKIW (signal) : ";cstatus if cstatus<>1%
number_of_locks=(buff_len and 65535%)/24% ! save returned info
for i=number_of_locks-1% to 0% step -1%
! backwards because EX requested lock is usually last
lset one_lock=seg$(signals_info,(i*24%)+1%,(i*24%)+24%)
if (s_reqmode=lck$k_exmode) then ! talker's still queued &
cstatus=lib$wait(0.1) ! wait 0.1 sec, save SCS
goto get_info
end if
next i
! convert GUIDO_SIGNAL lock from CR to CR to reset blocking AST
cstatus=sys$enqw ( , ! efn &
lck$k_crmode by value, ! lkmode &
s_lblk() by ref, ! status_block &
lck$m_system or lck$m_nodlckwt or lck$m_convert by value, &
"GUIDO_SIGNAL", ! resource name (ignored for converts) &
, ! parent id &
, ! ast addr &
, ! ast parm &
MSG_AST by value, ! blocking ast &
, ) ! access mode,null
if not cstatus and 1% then
print "MSG_AST: SIGNAL lock CR-CR ERROR: ";cstatus;
exit sub
end if
END SUB
|