ANYPARM job=![""] # Version B.07 # The ABORTJ script aborts one or more jobs based on one or more user IDs # and/or job IDs. User IDs can be wildcarded and a list of jobs to exclude can # be specified. The job or session executing this script is not aborted. The # ABORTJ script verifies the job(s) were really aborted and tries a few tricks # to abort the job if it didn't get aborted. # # Syntax: # ABORTJ [jobID ... userID ... jobID...] [- jobID - userID...] # [;JOBQ=qname] [;DEV=ldev] [;IP=nn.nn.nn.nn] # [;EXEC] [;SCHED] [;WAIT] [;SUSP] # [;DOIT | VERIFY] # # See 'help' text below for parameter descriptions. # By convention, if an entry point is used the entry name is the last arg. # # An NSCONTROL KILLSESS= is done for sessions prior to the abortjob to # reduce the chances of ghost sessions. # # Author: Jeff Vance, CSY, July 1998. # if "!job" = "" or pos('entry=',"!job") = 0 then # main entry if '!job' = '' or '!job' = '?' then echo echo Usage: ![word(hpfile,'.')] [jobIDs userIDs...] & [- jobIDs - userIDs...] echo [;JOBQ= qname] [;DEV=ldev] [;IP=ip_addr] echo [;EXEC] [;SCHED] [;WAIT] [;SUSP] echo [;DOIT | VERIFY] echo where: jobID :: [#]J|Snnn echo userID :: [@J|S:][jobname,]username[.acctname] or echo @ or @J or @S echo qname :: the name of a job queue (jobs only). echo ldev :: a valid LDEV nmumber (pattern ok). echo ip_addr :: an IP address in dotted form (pattern ok). echo EXEC = abort only executing jobs that match. echo SCHED = abort only scheduled jobs that match. echo WAIT = abort only waiting jobs that match. echo SUSP = abort only suspended jobs that match. echo EXEC, SCHED, WAIT, SUSP can be combined. echo VERIFY = display matching jobs but don't abort them. echo DOIT = default, try to abort all matching jobs. echo echo The default is to abort all job/sessions that match the jobID echo specifications, regardless of their state (wait, exec, susp, sched) echo or job queue. If jobID is omitted '@' is assumed. echo echo Note: jobname, username, acctname, qname, ldev and ip address can echo be wildcarded. echo Note: the @S|J: format means to match only jobs or only sessions echo for the supplied user.acct. echo echo Jobs/sessions matching IDs after a minus ('-') are skipped and thus echo not aborted. echo echo Multiple jobIDs and userIDs can *only* be separated by a space echo since a comma is part of the userID specification. echo return endif setvar _abj_job ups("!job") if setvar(_abj_pos,pos(';',_abj_job)) > 0 then # remove spaces beyond the 1st semicolon for easier parsing setvar _abj_job repl(_abj_job,' ','',,_abj_pos) endif # initialze counters for # of jobs and sessions aborted setvar _abj_cnt 0 setvar _abj_j_cnt 0 setvar _abj_s_cnt 0 setvar _abj_NM_cap pos('NM',hpusercapf) > 0 # indicate that 'alt_abortjob' entry has not been called recursively if bound(_abj_recurse) then deletevar _abj_recurse endif # parse out DOIT | VERIFY setvar _abj_verify false if setvar(_abj_pos,pos(';VERIFY',_abj_job)) > 0 and & word(_abj_job,,,,_abj_pos+1) = 'VERIFY' then echo ***************************************************** echo *** VERIFY mode. No jobs/sessions will be aborted *** echo ***************************************************** echo setvar _abj_verify true # remove filter option setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif if setvar(_abj_pos,pos(';DOIT',_abj_job)) > 0 and & word(_abj_job,,,,_abj_pos+1) = 'DOIT' then setvar _abj_verify false # remove filter option setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif # parse out JOBQ= setvar _abj_jobq_filter '' if setvar(_abj_pos,pos(';JOBQ=',_abj_job)) > 0 then setvar _abj_jobq_filter word(_abj_job,,2,,_abj_pos+1) # remove jobq= and queuename setvar _abj_job xword(_abj_job,,,,_abj_pos+1) setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif # parse out DEV= (or LDEV=) setvar _abj_ldev_filter '' if (setvar(_abj_pos,pos(';DEV=',_abj_job)) > 0) or & (setvar(_abj_pos,pos(';LDEV=',_abj_job)) > 0) then setvar _abj_ldev_filter word(_abj_job,,2,,_abj_pos+1) # remove dev= and ldev number setvar _abj_job xword(_abj_job,,,,_abj_pos+1) setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif # parse out IP= setvar _abj_ip_filter '' if setvar(_abj_pos,pos(';IP=',_abj_job)) > 0 then setvar _abj_ip_filter word(_abj_job,,2,,_abj_pos+1) # remove ip= and ip address setvar _abj_job xword(_abj_job,,,,_abj_pos+1) setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif # parse out ;EXEC ;SCHED... filter options setvar _abj_state_filter '' if setvar(_abj_pos,pos(';SCHED',_abj_job)) > 0 and & word(_abj_job,,,,_abj_pos+1) = 'SCHED' then setvar _abj_state_filter _abj_state_filter + 'SCHED ' # remove filter option setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif if setvar(_abj_pos,pos(';WAIT',_abj_job)) > 0 and & word(_abj_job,,,,_abj_pos+1) = 'WAIT' then setvar _abj_state_filter _abj_state_filter + 'WAIT ' # remove filter option setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif if setvar(_abj_pos,pos(';SUSP',_abj_job)) > 0 and & word(_abj_job,,,,_abj_pos+1) = 'SUSP' then setvar _abj_state_filter _abj_state_filter + 'SUSP ' # remove filter option setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif if setvar(_abj_pos,pos(';EXEC',_abj_job)) > 0 and & word(_abj_job,,,,_abj_pos+1) = 'EXEC' then setvar _abj_state_filter _abj_state_filter + 'EXEC EXEC* ' # remove filter option setvar _abj_job xword(_abj_job,,,,_abj_pos+1) endif # at this point in the parsing there should be no more ;keyword[=value] if setvar(_abj_pos,pos(';',_abj_job)) > 0 and _abj_pos < len(_abj_job) then echo Unknown keyword: ![word(_abj_job,,,,_abj_pos+1)] return endif # see if any jobs are being skipped (minus list) and don't abort yourself! setvar _abj_skip_jobID "#!hpjobtype!hpjobnum" setvar _abj_skip_userID '' if setvar(_abj_pos,pos('-',_abj_job)) > 0 then # create separate lists of just jobIDs and just userIDs to be skipped setvar _abj_i 1 while setvar(_abj_j,& word(_abj_job,'-',setvar(_abj_i,_abj_i+1),,_abj_pos)) <> "" do if setvar(_abj_char,lft(_abj_j,1)) = '#' or & ((_abj_char='J' or _abj_char='S') and numeric(rht(_abj_j,-2))) then # have a jobID setvar _abj_skip_jobID _abj_skip_jobID+" #"+(_abj_j-'#') else # assume a [jobname,]user[.acct] or @s or @j or @ setvar _abj_skip_userID _abj_skip_userID + " " + _abj_j endif endwhile setvar _abj_job lft(_abj_job,_abj_pos-1) endif # if after all of the above parsing and extracting there is nothing left # set the jobID to '@' as the default if _abj_job = '' then setvar _abj_job '@' endif # parse target jobIDs and userIDs (non-skipped list) # abort each target jobID setvar _abj_i 0 while setvar(_abj_j,word(_abj_job,' ',setvar(_abj_i,_abj_i+1))) <> "" do errclear if setvar(_abj_char,lft(_abj_j,1)) = '#' or & ((_abj_char='J' or _abj_char='S') and numeric(rht(_abj_j,-2))) then # have a job or session id, verify it exists setvar _abj_j '#' + (_abj_j-'#') setvar _abj_do_it jinfo(_abj_j,'exists',cierror) if cierror = 0 then if _abj_do_it then # job exists, so abort it continue xeq !hpfile !_abj_j entry=alt_abortjob else # job does not exist setvar cierror 3042 endif endif if cierror <> 0 then echo !hpcierrmsg escape !cierror endif elseif numeric(_abj_j) then # common syntax error, skip this one setvar cierror 1509 echo "!_abj_j": !hpcierrmsg ... or, setvar cierror 3080 echo ![rpt(" ",len(_abj_j)+3)] !hpcierrmsg else # have '[@S|@J:][jobname,]user[.acct]' or '@s' or '@j' or '@' # execute this script recursively to abort each matching job setvar _abj_jobcnt 1 setvar _abj_list_cnt 0 while _abj_jobcnt > _abj_list_cnt do if setvar(_abj_jobcnt,jobcnt(_abj_j,_abj_list)) > 0 then setvar _abj_listx 0 while setvar(_abj_j,& word(_abj_list,,setvar(_abj_listx,_abj_listx+1))) <> '' do # abort each target job (_abj_j) continue xeq !hpfile #!_abj_j entry=alt_abortjob endwhile # loop again if _abj_list didn't contain all jobs found by jobcnt() setvar _abj_list_cnt wordcnt(_abj_list) endif endwhile endif endwhile # display final stats echo echo !_abj_cnt jobs and/or sessions matched... if _abj_cnt > 0 then echo Number of sessions aborted: !_abj_s_cnt echo Number of jobs aborted: !_abj_j_cnt endif echo # cleanup deletevar _abj_@ return else # alternate entry points setvar _abj_entry word('!job',,-1) # remove entry=name from parm line setvar _abj_parm lft('!job',pos('entry=','!job')-1) #### 'alt_abortjob' entry ### if _abj_entry = 'alt_abortjob' then # Syntax: arg1 = target job (#J|Snnn) to abort - # is always present. # Returns: _abj_cnt, _abj_j_cnt and _abj_s_cnt. # Redirection: none. # This entry is used to abort the target job passed in as arg1. First the # the job cannot be in the skipped jobID list nor in the skipped userID # list. The JOBQ= queuename, if any, is handled. If the uer specified # 1 or more of the ;SCHED, SUSP, EXEC or WAIT options, this job state match # is enforced. NSCONTROL killsess is done for sessions prior to an # ABORTJOB, since, if an ABORTJOB is done first and fails the session can # become a 'ghost' session. # setvar _abj_arg1 word(_abj_parm) setvar _abj_do_it true if not bound(_abj_recurse) then # first time in this entry with target job # skip job based on job number? if pos(_abj_arg1+' ',_abj_skip_jobID+' ') > 0 then # jobID skipped echo ...skipping !_abj_arg1 by number return endif # Skip job based on the userID skip list? if len(_abj_skip_userID) > 0 then # user specified userIDs to skip setvar _abj_skipx 0 while _abj_do_it and setvar(_abj_skip,word(_abj_skip_userID,' ',& setvar(_abj_skipx,_abj_skipx+1)))<>'' do setvar_abj_do_it (jobcnt(_abj_skip,_abj_skip_list) = 0) or & (pos(_abj_arg1-'#'+' ',_abj_skip_list) = 0) endwhile endif if not _abj_do_it then # userID skipped echo ...skipping !_abj_arg1 matching user ID "!_abj_skip" return endif # see if skipping based on command filters... # (Programming note: do not try to optimize these filters by doing some # for jobs only and others for sessions only. This approach fails when # the jobID is defaulted to '@', e.g. :abortj ;ip=15.@ ) # ;JOBQ= ? if _abj_jobq_filter <> '' then setvar _abj_jobq jinfo(_abj_arg1,'jobq',cierror) if cierror <> 0 then # assume job gone, no need to abort it. return endif if not pmatch(_abj_jobq_filter,_abj_jobq) then echo ...skipping !_abj_arg1 in job queue "!_abj_jobq" return endif endif # ;SCHED ; WAIT ;etc. ? if _abj_state_filter <> '' then setvar _abj_state jinfo(_abj_arg1,'jobstate',cierror) if cierror <> 0 then # assume job gone, no need to abort it. return endif if pos(_abj_state,_abj_state_filter) = 0 then echo ...skipping !_abj_arg1 in job state "!_abj_state" return endif endif # ;IP= ? if _abj_ip_filter <> '' then setvar _abj_ip jinfo(_abj_arg1,'ipaddr',cierror) if cierror <> 0 then # assume session gone, no need to abort it. return endif if not pmatch(_abj_ip_filter,_abj_ip) then echo ...skipping !_abj_arg1 with IP addr "!_abj_ip" return endif endif # ;DEV= ? if _abj_ldev_filter <> '' then setvar _abj_devin decimal(jinfo(_abj_arg1,'ldevin',cierror)) if cierror <> 0 then # assume job/sess gone, no need to abort it. return endif if not pmatch(_abj_ldev_filter,_abj_devin) then echo ...skipping !_abj_arg1 with DEV "!_abj_devin" return endif endif endif # target job is not being skipped, so abort it -- unless ;verify errclear setjcw dserr %177777 ## use :setjcw since NSCONTROL seems to call PUTJCW if bound(_abj_recurse) then echo :abortjob !_abj_arg1 ...AGAIN! else # first attempt to abort this job setvar _abj_cnt _abj_cnt + 1 if _abj_verify then echo :COMMENT :abortjob !_abj_arg1 return else echo :abortjob !_abj_arg1 endif endif if str(_abj_arg1,2,1) = 'S' and _abj_NM_cap then # assume a remote connection. killsess the target session. setjcw dserr 0 continue nscontrol killsess=!_abj_arg1 >$null endif # execute the real abortjob for all selected jobs, or if nscontrol failed. if dserr <> 0 then continue abortjob !_abj_arg1 if cierror = 3047 then echo ***You need to ALLOW the ABORTJOB command to & !hpuser.!hpaccount*** # give up on all job/sessions escape 3047 endif endif # check if job was aborted. pause 2 if not jinfo(_abj_arg1,'exists') then # job was successfully aborted if str(_abj_arg1,2,1) = 'J' then setvar _abj_j_cnt _abj_j_cnt + 1 else setvar _abj_s_cnt _abj_s_cnt + 1 endif elseif not bound(_abj_recurse) then # job not killed or aborted # try a few abortios and then execute this entire entry once more. # avoid more than one recursive call to this entry... setvar _abj_recurse true setvar _abj_io 0 setvar _abj_ldev jinfo(_abj_arg1,'ldevin') errclear while cierror = 0 and setvar(_abj_io,_abj_io+1) <= 7 do continue abortio !_abj_ldev >$null endwhile # invoke same entry recursively continue xeq !hpfile !_abj_arg1 entry=alt_abortjob else # 2nd pass thru and still could not be abort the job! echo *** !_abj_arg1 could not be aborted *** endif deletevar _abj_recurse >$null return endif endif # Version History: B.07 JV 07/25/05 added ;verify option to supress the actual aborting. Also tightened up the keyword parsing so that ;WAITT is an error. Also increased pause time from 1 to 2 seconds. B.06 JV 04/25/02 fixed bug in b.05 related to removing a line that deleted the _abj_recurse var. B.05 JV 06/18/01 set DSERR as a JCW since NSCONTROL does that, prevent spurious CIERRORs from being returned, related to _abj_recurse. B.04 JV 05/17/00 Minor improvement in jobID syntax checking. B.03 JV 12/20/99 Made the jobID optional and fixed bug where jobs are aborted when just ;ip=xxxx is specified. B.02 JV 12/17/99 Added DEV= and IP= filtering. B.01 JV 10/22/99 Simplify by using JOBCNT and JINFO functions. Also added the WAIT, SCHED, SUSP and EXEC options and the JOBQ= parm. A.05 JV 9/20/98 fixed bug where SCHED jobs were not verified correctly since showjob's output differs for a SCHED job vs non-sched. A.04 JV 8/21/98 added support for SCHED jobs. added @S|@J in front of a user name. Count # of job and sessions aborted. Nscontrol killsess= done for remote connections. Added the 'verify' entry to verify that the abortjob worked. A.03 JV 7/29/98 cleanup up some of the ugly 'skip' while loop in 'showjob' entry. A.02 JV 7/28/98 added minus lists to skip certain jobs, echo target job #, echo jobs that are skipped. A.01 JV 7/25/98 Initial version *** end of ABORTJ script ***