10 pts.
 QINTER will not go down due to keyboard error
We shut down QINTER at 3:30 AM to do a quick backup. We have 5.4. When someone leaves a terminal or PC session on with a keyboard error (last night was an "invalid F key pressed") QINTER will not go down all the way! It sits there until the session is physically terminated at the device. Anyone else see this and/or solve it?

Software/Hardware used:
iSeries or AS/400
ASKED: December 9, 2010  3:13 PM
UPDATED: December 12, 2010  1:47 AM

Answer Wiki:
Do you use the command: <pre>ENDSBS SBS(QINTER) OPTION(*IMMED) </pre> If you simply enter the command ENDSBS QINTER, the default option is *DELAYED, with the time limit set to *NOMAX.
Last Wiki Answer Submitted:  December 9, 2010  4:39 pm  by  Rayj1031   325 pts.
All Answer Wiki Contributors:  Rayj1031   325 pts.
To see all answers submitted to the Answer Wiki: View Answer History.


Discuss This Question:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _


 

If a job in a subsystem won’t end, then you cannot end the subsystem. Subsystems will not end until all jobs in the subsystem have ended first. If you initiate ENDSBS while a job is in a state where it can’t end, then your subsystem is stuck until you can (1) get it to finish ending and (2) get the subsystem restarted. Because of that, it’s not a good idea to issue ENDSBS while jobs are still running in a subsystem.

When a job is stuck, you can try ENDJOB. After sufficient time has passed and the job has not ended, you can usually succeed with ENDJOBABN. And if that doesn’t work and you’ve already run ENDSBS, your subsystem will generally be unavailable until you can IPL the system.

Tom

 108,360 pts.

 

LarryKat,

Here’s a thought, assuming your “quick backup” is a CL program, if you were to do a WRKACTJOB to a file, then read thru that file looking for Jobs running in QINTER, you could use ENDJOB to end each of the active jobs in QINTER. If no jobs are found running in QINTER you can continue with your “quick backup”.

We use the TAATOOL/CVTWRKACT to do WRKACTJOB to a file.

Hope this helps,
Bill Poulin

 2,480 pts.

 

issue the commad Enddbd Qinter Option(*CNTRLD) Delay(120).

After 120 seconds any active job in the sub system will be ended and it will end.

 65 pts.

 

woops that should have been endsbs(qinter) option(*Cntrld) delay(120)

 65 pts.

 

Here is an example program that checks subsystem QPGMR for active jobs. If it’s all quiet, it simply returns. If *ACTIVE jobs are in there, it lists all jobs into a user space, loops through the list issuing ENDJOB for each one, then checks to see if any *ACTIVE jobs remain again.

If some haven’t ended yet, it waits 35 seconds before checking a final time. If any still remain, it sends an *ESCAPE message.

pgm

/* Identify a a subsystem to work over...                           */
   dcl   &SCHSBS      *char   10     value( 'QPGMR' )

   dcl   &SchJob      *char   26

/* Identify a *USRSPC name...                                       */
   dcl   &usrspc      *char   10     value( 'LSTACTJOBS' )
   dcl   &usrspclib   *char   10     value( 'QTEMP' )

   dcl   &qusrspc     *char   20

/* General fields from *usrspc header...                            */
   dcl   &offslst     *int
   dcl   &nbrlste     *int
   dcl   &sizlste     *int

/* Various work fields...                                           */
   dcl   &Sbs         *char   10

   dcl   &jobname     *char   10
   dcl   &jobusr      *char   10
   dcl   &jobnbr      *char    6
   dcl   &JobType     *char    1

   dcl   &qjob        *char   26
   dcl   &qSBSNam     *char   20

   dcl   &SBSActJobs  *int

   dcl   &SBSMON      *char    1     value( 'M' ) /* Sbs Monitor  */
   dcl   &SYSJOB      *char    1     value( 'S' ) /* System job   */
   dcl   &SPLWTR      *char    1     value( 'W' ) /* Spool writer */
   dcl   &SYSCPF      *char    1     value( 'X' ) /* SCPF job     */
   dcl   &SPLRDR      *char    1     value( 'R' ) /* Spool reader */

/* Various receiver variables...                                    */
   dcl   &us_hdr      *char  150
   dcl   &JOBL0100F   *char   56
   dcl   &JOBI0200F   *char   72

   dcl   &rcvvar      *char   76


   monmsg    ( cpf0000 mch0000 ) exec( goto Std_Err )


/* Check if things have ended...                             */

   chgvar    &qSBSNam      ( &SCHSBS *cat '*LIBL' )

   call       qwdrsbsd     ( +
                             &rcvvar          +
                             x'0000004C'      +
                             'SBSI0100'       +
                             &qSBSNam         +
                             x'00000000'      +
                           )

   chgvar    &SBSActJobs    %bin( &rcvvar     73   4 )

/* If the the &SCHSBS has no *ACTIVE jobs, return...         */

   if ( &SBSActJobs *le 0 )      do
      sndpgmmsg  msgid( CPF9897 ) msgf( QCPFMSG ) +
                   msgdta( 'No active jobs.' ) +
                   topgmq( *EXT ) +
                   msgtype( *COMP )
      return
   enddo


/*                                                                           */
/* Create *usrspc for the List Jobs APIs...                                  */
/*                                                                           */

   chgvar          &qusrspc               ( &usrspc *cat &usrspclib )

   call  QUSCRTUS         ( +
                            &qusrspc                +
                            'ACTJOB    '            +
                            x'00004000'             +
                            X'00'                   +
                            '*ALL      '            +
                  'List active jobs                                  ' +
                            '*YES      '            +
                            x'0000000000000000'     +
                          )


/* Set the qualified search-job name...                                      */

   chgvar          &SchJob                ( '*ALL      *ALL      *ALL  ' )


/*                                                                           */
/* List the *ACTIVE jobs into our *usrspc...                                 */
/*                                                                           */

   call  QUSLJOB          ( +
                            &qusrspc                +
                            'JOBL0100'              +
                            &SchJob                 +
                            '*ACTIVE   '            +
                            x'0000000000000000'     +
                            '*'                     +
                            x'00000000'             +
                            x'00000000'             +
                          )


/* Retrieve the *usrspc header...                                            */

   call  QUSRTVUS         ( +
                            &qusrspc                +
                            x'00000001'             +
                            x'00000096'             +
                            &us_hdr                 +
                          )

/*                                                           */
/* Get the offset to the list within the space, the number   */
/*   of list entries and size of each entry from the header. */
/*                                                           */
   chgvar          &offslst           %bin( &us_hdr    125 4 )
   chgvar          &nbrlste           %bin( &us_hdr    133 4 )
   chgvar          &sizlste           %bin( &us_hdr    137 4 )


/* If no entries, then get out of here...                    */

   if  ( &nbrlste *eq 0 )     do       /* Can't actually happen... */
      sndpgmmsg  msgid( CPF9897 ) msgf( QCPFMSG ) +
                   msgdta( 'No active jobs found.' ) +
                   topgmq( *EXT ) +
                   msgtype( *COMP )
      goto   End_Run
   enddo


/* Set the offset to the list within the space...            */

   chgvar          &offslst               ( &offslst + 1 )



   dowhile  ( &nbrlste *gt 0 )

/*    Retrieve one listed job entry from the list...                         */

      call  QUSRTVUS      ( +
                            &qusrspc                +
                            &offslst                +
                            &sizlste                +
                            &JOBL0100F              +
                          )

/* Bump our offset up by the size of a list entry...                         */
/* Decrement our loop counter and loop back if more...                       */

      chgvar       &offslst               ( &offslst + &sizlste )
      chgvar       &nbrlste               ( &nbrlste - 1 )


/* Skip any subsystem monitor, etc., job...                                  */

      chgvar       &JobType           %sst( &JOBL0100F 53  1 )

      if ( &JobType *eq &SBSMON  *or +
           &JobType *eq &SYSJOB  *or +
           &JobType *eq &SPLWTR  *or +
           &JobType *eq &SYSCPF  *or +
           &JobType *eq &SPLRDR )    +
         iterate


/* Get the qualified job name from the list entry...                         */

      chgvar       &qjob              %sst( &JOBL0100F  1 26 )

/* Get details of that job in order to find what subsystem it's in...        */

      call  QUSRJOBI      ( +
                            &JOBI0200F              +
                            x'00000048'             +
                            'JOBI0200'              +
                            &qjob                   +
                            '                '      +
                          )


/* Get the subsystem name from the receiver variable...                      */

      chgvar       &Sbs               %sst( &JOBI0200F 63 10 )

      if ( &Sbs *eq &SCHSBS )  do

         chgvar    &jobname           %sst( &JOBI0200F  9 10 )
         chgvar    &jobusr            %sst( &JOBI0200F 19 10 )
         chgvar    &jobnbr            %sst( &JOBI0200F 29  6 )

         endjob   job( &jobnbr/&jobusr/&jobname )
         monmsg ( cpf0000 mch0000 )

         sndpgmmsg  msgid( CPF9897 ) msgf( QCPFMSG ) +
                      msgdta( 'Ended' *bcat &jobname ) +
                      topgmq( *EXT ) msgtype( *STATUS )

      enddo

   /* This ELSE code can be removed... */
      else  +
         sndpgmmsg  msgid( CPF9897 ) msgf( QCPFMSG ) +
                      msgdta( 'Found' *bcat &Sbs ) +
                      topgmq( *EXT ) msgtype( *STATUS )

   enddo


End_Run:

   dltusrspc   &usrspclib/&usrspc  /* Cleanup */

/* Check if things have ended...                             */

   call       qwdrsbsd     ( +
                             &rcvvar          +
                             x'0000004C'      +
                             'SBSI0100'       +
                             &qSBSNam         +
                             x'00000000'      +
                           )

   chgvar    &SBSActJobs    %bin( &rcvvar     73   4 )

/* If all *ACTIVE jobs have ended, return...                        */

   if ( &SBSActJobs *le 0 )      do
      sndpgmmsg  msgid( CPF9897 ) msgf( QCPFMSG ) +
                   msgdta( 'No active jobs.' ) +
                   topgmq( *EXT ) +
                   msgtype( *COMP )
      return
   enddo


/* Check if things have ended...                             */

   sndpgmmsg  msgid( CPF9898 ) msgf( QCPFMSG ) +
                msgdta( 'Waiting 35 seconds for any jobs to end..' ) +
                topgmq( *EXT ) msgtype( *STATUS )
   dlyjob    35

   call       qwdrsbsd     ( +
                             &rcvvar          +
                             x'0000004C'      +
                             'SBSI0100'       +
                             &qSBSNam         +
                             x'00000000'      +
                           )

   chgvar    &SBSActJobs    %bin( &rcvvar     73   4 )

/* If the the &SCHSBS still has *ACTIVE jobs...???                  */

   if ( &SBSActJobs *gt 0 )      do
      sndpgmmsg  msgid( CPF9897 ) msgf( QCPFMSG ) +
                   msgdta( 'Not all jobs ended.' ) +
                   topgmq( *PRV ) +
                   msgtype( *ESCAPE )
   enddo

   return


 Std_Err:

   /* Move any *DIAG messages up the stack...        */

   Qsys/call       QSYS/QMHMOVPM       ( +
                                         '    '          +
                                         '*DIAG     '    +
                                         x'00000001'     +
                                         '*         '    +
                                         x'00000001'     +
                                         x'00000000'     +
                                       )
   Qsys/monmsg     ( CPF0000 MCH0000 )

   /* Resend any *ESCAPE messages up the stack...     */

   Qsys/call       QSYS/QMHRSNEM       ( +
                                         '    '          +
                                         x'00000000'     +
                                       )
   Qsys/monmsg     ( CPF0000 MCH0000 )

   return


endpgm

It can be changed to accept a subsystem name as a parm. An ENDSBS should not be entered for the subsystem until this program returns to its caller normally.

The program is sufficient for most systems. Larger systems possibly shouldn’t use the List Job (QUSLJOB) API for this. The Open List of Jobs (QGYOLJOB) API is probably a better choice. It doesn’t use a user space, so the additional programming if all jobs can’t fit in a space wouldn’t be needed. (Not included in example.)

Also, the list could be customized to return only jobs in the chosen subsystem(s). The list in the example will include all *ACTIVE jobs in the system. A user space can hold more than a quarter million job entries, so there’s little chance of complication.

Note that it can take time to do work. Jobs might end before reaching them in the list. New jobs may start before finishing the list. That’s when it can get fun.

Tom

 108,360 pts.

 

BTW, the program can be tested by submitting a DLYJOB 600 command to run in QPGMR. Call the program after the DLYJOB starts. The program should get to the end of the list in a couple seconds and wait until enough time has passed for the submitted job to end.

Tom

 108,360 pts.