星期四, 11月 02, 2023

2002-07-01 如何讓 AS/400 全系統備份自動化?


如何讓 AS/400 全系統備份自動化?

AS/400 全系統備份需要在專屬模式(restrictive state)下及需要在中控台(console)
上執行備份指令才能完成,由於專屬模式下,所有的使用者作業及所有子系統均已被停止
,只有系統作業及從中控台進入系統(SignOn)的線上即時作業可以正常執行,所以我們
可以利用中控台上的線上即時作業(interactive job)自動執行全系統備份作業。

做法是:
1:從中控台進入系統(SignOn),執行下列的指令,在程式中會從訊息佇列
  (message queue)中讀取訊息,訊息佇列若沒有訊息時,程式會等待有訊息時才讀取,並判斷是否執行全系統備份作業。
2:於排程作業中設定某時間傳送訊息至訊息佇列,以啟動或終止備份作業。


File  : QCLSRC
Member: FULSAVC
Type  : CLP
Usage : 
        1. 新增訊息佇列 SAVSYSMSGQ: Yourlib - 指定您自己的 Library

           CRTMSGQ MSGQ(Yourlib/SAVSYSMSGQ) TEXT('Message Queue for Unattended full save')

    2. 修改程式中 Yourlib - 指定您自己的 Library 及 console DSP01 --指定您自己的 console 名稱
           CRTCLPGM FULSAVC
           CRTCMD   CMD(FULSAV) PGM(Yourlib/FULSAVC)

        3. 新增自動工作排程傳送啟動備份訊息 Yourlib - 指定您自己的 Library
           此範例指定,此作業於每個星期天 16:55 執行:

           ADDJOBSCDE JOB(BIGSAV) CMD(SNDMSG MSG('STRSAVSYS') TOMSGQ(Yourlib/SAVSYSMSGQ))
         FRQ(*WEEKLY) SCDDATE(*NONE) SCDDAY(*SUN) SCDTIME('16:55:00') JOBQ(QGPL/QBASE)
         USER(QSECOFR) TEXT('Send a message to start full system save.')

           如果要取消份作業,上述指令 CMD 參數更改如下:
           SNDMSG MSG( 'ENDSAVSYS' ) TOMSGQ( Yourlib/SAVSYSMSGQ)

        4. 於星期五下班前,從 Console Sign On 進入系統,於命令列輸入 FULSAV,系統即進入等待上述啟動備份訊息
           當每個星期天 16:55 時間到達時,系統會收到訊息判斷是否啟動備份作業。

        附註:
           由於資料量及磁帶容量與磁帶機設備不同,所以有可能需要一卷以上的磁帶做備份,若由於設備不足,您還是
           要由人工換磁帶。使用此範例前,請先測試無問題後,在正式實施。





/*  *****************************************************************        */
/*  *                                                               *        */
/*  *                                                               *        */
/*  *  TITLE........: Weekly Savsys & Full Nonsys Save (FULSAVC)    *        */
/*  *                                                               *        */
/*  *                                                               *        */
/*  *****************************************************************        */
/*  *                                                               *        */
/*  *  To run an unattended SAVSYS, you can add a job scheduler     *        */
/*  *  entry as follows:                                            *        */
/*  *                                                               *        */
/*  *     SNDMSG MSG( 'STRSAVSYS' ) TOMSGQ( Yourlib/SAVSYSMSGQ)     *        */
/*  *                                                               *        */
/*  *  Specify the date and time you want the message to be sent.   *        */
/*  *  You should call this program from the console, and when the  *        */
/*  *  job scheduler sends the message the program will continue    *        */
/*  *  and perform the SAVSYS & full *NONSYS save followed by IPL.  *        */
/*  *                                                               *        */
/*  * Note that by sending message ENDSAVSYS you can cause this     *        */
/*  * program to end without performing the SAVSYS etc.             *        */
/*  *                                                               *        */
/*  *****************************************************************        */
             PGM

/*  *****************************************************************        */
/*  Declare Program Variables                                       *        */
/*  *****************************************************************        */

    DCL        VAR(&MSG)   TYPE(*CHAR) LEN(9)            /* Message          */
    DCL        VAR(&JOB)   TYPE(*CHAR) LEN(10)           /* This Job         */
    DCL        VAR(&COUNT) TYPE(*DEC)  LEN(4 0) VALUE(0) /* Retry            */


/*  *****************************************************************        */
/*  Main Processing                                                 *        */
/*  *****************************************************************        */

/*    Allocate the message queue to this job so it has exclusive   '         */
/*    use of the message queue so we can receive and remove       '          */
/*    messages from the queue. If we're unable to obtain the      '          */
/*    exclusive lock, then another job is using the queue and      '         */
/*    this job will cancel.                                        '         */
             ALCOBJ     OBJ((Yourlib/SAVSYSMSGQ *MSGQ *EXCL)) WAIT(0)
             MONMSG     MSGID(CPF0000) EXEC(SNDPGMMSG MSGID(CPF9897) +
                          MSGF(QCPFMSG) MSGDTA('Unable to allocate +
                          SAVSYS message queue.') TOUSR(*SYSOPR) +
                          MSGTYPE(*ESCAPE))

/*    Make sure that we are running on DSP01 (The Console)'                  */
/*    If we're not, this job will end when we do ENDSBS *ALL *IMMED!         */
             RTVJOBA    JOB(&JOB)
             IF         COND(&JOB *NE 'DSP01     ') THEN(SNDPGMMSG +
                          MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('DO +
                          IT ON THE CORRECT SCREEN YOU MUPPET!!!!') +
                          MSGTYPE(*ESCAPE))

/*    Remove any old messages from message queue                             */
             RMVMSG     MSGQ(Yourlib/SAVSYSMSGQ) CLEAR(*ALL)

/*    Change this job's message queues to *Hold so we don't get any.         */
             CHGJOB     LOGCLPGM(*YES) BRKMSG(*NOTIFY)
             CHGMSGQ    MSGQ(*USRPRF) DLVRY(*HOLD)
             MONMSG     MSGID(CPF2451)
             CHGMSGQ    MSGQ(*WRKSTN) DLVRY(*NOTIFY)


/*    Receive messages in the queue. WAIT(*MAX) tells the system             */
/*    to wait for a message forever if no messages are in the                */
/*    queue. Once the message is received, it will be removed.               */

Loop:

             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Waiting for somebody to tell me +
                          to start save of entire system........') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             RCVMSG     MSGQ(Yourlib/SAVSYSMSGQ) MSGTYPE(*ANY) +
                          WAIT(*MAX) RMV(*YES) MSG(&MSG)
             CHGJOB     STSMSG(*SYSVAL)

/*    If the message is neither STRSAVSYS or ENDSAVSYS, ignore               */
             IF         COND((&MSG *NE 'STRSAVSYS') *AND (&MSG *NE +
                          'ENDSAVSYS')) THEN(GOTO CMDLBL(LOOP))

/*    If the message is STRSAVSYS, continue with Saves                       */
             IF         COND(&MSG *EQ 'STRSAVSYS') THEN(DO)

/*    Send Start of wait Message to Qsysopr                                  */
             SNDPGMMSG  MSG(SAVSYS starting in 5 mins.) +
                          TOMSGQ(*SYSOPR)

/*    Send message to all users telling them to sign off                     */
             SNDPGMMSG  +                                              
                        MSG('                                       -
      ****** The Backups for tonight will start in 5 minutes...   +     
                      Please sign off the AS/400 +                 
                      Immediately.        *******') TOUSR(*ALLACT) 

/*  Delay job for next five minutes                                          */
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Waiting for five minutes while  +
                          users sign off........................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             DLYJOB     DLY(300)
             CHGJOB     STSMSG(*SYSVAL)


/*    End all the subsystems                                                 */
Loop3:       SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Ending all the subsystems.....') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)




             ENDSBS     SBS(*ALL) OPTION(*IMMED)

/*  Delay job for next four minutes                                          */
             CHGJOB     STSMSG(*SYSVAL)
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Waiting for four minutes while  +
                          Subsystems are ended..................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             DLYJOB     DLY(240)

/*    Start SAVSYS                                                           */
             CHGJOB     STSMSG(*SYSVAL)
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Saving the system (SAVSYS)... +
                          ......................................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
/*  Loop 2 tries to do a savsys.  If the system is not yet in                */
/*  restricted state, a count is incremented, and the program waits          */
/*  another two minutes and tries again.                                     */
 LOOP2:      SAVSYS     DEV(TAP03) ENDOPT(*LEAVE) OUTPUT(*PRINT) +
                          CLEAR(*ALL)
             MONMSG     MSGID(CPF3785) EXEC(DO)
               CHGVAR     VAR(&COUNT) VALUE(&COUNT + 1)

/*  If we have retried 12 times (24 minutes), NYCOMSGR is started and        */
/*  a message is sent to QSYSOPR to be paged out.  The program then          */
/*  loops to LOOP3 to attempt Endsbs *all *immed again.                      */
               IF         COND(&COUNT *GE 12) THEN(DO)
                 STRSBS     SBSD(NYCOMSGR)
                 DLYJOB     DLY(120)
                 SNDMSG     MSG('The system wont go down on me!!') +
                              TOUSR(*SYSOPR)
                 GOTO       CMDLBL(LOOP3)
               ENDDO

               DLYJOB     DLY(120)
               GOTO       CMDLBL(LOOP2)
             ENDDO

             CHGJOB     STSMSG(*SYSVAL)

/*    Start SAVLIB *NONSYS                                                   */
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Saving all the user libraries +
                          (SAVLIB *NONSYS).....................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             SAVLIB     LIB(*NONSYS) DEV(TAP03) ENDOPT(*LEAVE) +
                          CLEAR(*AFTER) ACCPTH(*YES) OUTPUT(*PRINT)
             MONMSG     MSGID(CPF3777) EXEC(SNDMSG MSG('Not All +
                          objects Saved On Sunday Night!!!! Look at +
                          log of job DSP01') TOMSGQ(GSKELTON +
                          ACUSWORTH JBARRY DCOLAM DSTEER))
             CHGJOB     STSMSG(*SYSVAL)

/*    Start SAVDLO                                                           */
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Saving all Document libraries +
                          (SAVDLO DLO(*ALL)....................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             SAVDLO     DLO(*ALL) FLR(*ANY) DEV(TAP03) +
                          ENDOPT(*LEAVE) OUTPUT(*PRINT) CLEAR(*AFTER)
             CHGJOB     STSMSG(*SYSVAL)

/*    Start save of all directory objects                                    */
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Saving all Directory objects (SAV +
                          OBJ((''/*'')......................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             SAV        DEV('/QSYS.LIB/TAP03.DEVD') OBJ(('/*') +
                          ('/QSYS.LIB' *OMIT) ('/QDLS' *OMIT)) +
                          OUTPUT(*PRINT) ENDOPT(*UNLOAD) +
                          UPDHST(*YES) CLEAR(*AFTER)
             CHGJOB     STSMSG(*SYSVAL)

/*    Apply PTFs permanently                                                 */
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Applying PTFs.................... +
                          ..................................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             APYPTF     LICPGM(*ALL) APY(*PERM) DELAYED(*YES)
             MONMSG     MSGID(CPF3660)
             CHGJOB     STSMSG(*SYSVAL)


/*    Power Down the System                                                  */
             SNDPGMMSG  MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
                          MSGDTA('Powering down the system......... +
                          ..................................') +
                          TOPGMQ(*EXT) MSGTYPE(*STATUS)
             CHGJOB     STSMSG(*NONE)
             PWRDWNSYS  OPTION(*IMMED) RESTART(*YES)
             CHGJOB     STSMSG(*SYSVAL)

             ENDDO

/*    The program would not normally get to this point.  If it does,         */
/*    it is because the message 'ENDSAVSYS' has been received.               */
/*    The job will now sign off for security.                                */

             SIGNOFF    LOG(*LIST)

             ENDPGM
/*  *****************************************************************        */



沒有留言: