/****************************************************************************
  module      : vkb38
  author      : JuergenA,UweH,MartinB
  responsible : UweH
  special area: backup / restore - data / log / autosave
  see also    :
  description : That's the headmaster for direct parallel saving.
                The duties of the direct save headmaster are:
                  - To allocate the memory
                  - To open the tapes
                  - To create and activate the children (= copy tasks)
                  - To wait for a child's return
                  - To communicate with utility
               The headmaster module contains service routines, too.
 
 .nf
 
    ========== licence begin  GPL
    Copyright (c) 2001-2005 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo
 
 
*****************************************************************************/
 
.tt 1 $SAP$LiveCache$VKB38$
.tt 3 $UweH$KB_headmaster$1999-07-20$
 
Module  : KB_headmaster
 
Define  :
 
        PROCEDURE
              k38allocate (
                    pid        : tsp00_TaskId;
                    VAR b_err  : tgg00_BasisError);
 
        PROCEDURE
              k38dump_headmaster (
                    VAR hostfile : tgg00_VfFileref;
                    VAR buf      : tsp00_Page;
                    VAR out_pno  : tsp00_Int4;
                    VAR out_pos  : integer;
                    VAR host_err : tsp00_VfReturn;
                    VAR errtext  : tsp00_ErrText);
 
        FUNCTION
              k38GetMaxServerTasks : tsp00_Int4;
 
        FUNCTION
              k38GetTaskIdOfCurrentBackup (taskid : tsp00_TaskId) : tsp00_TaskId;
 
        PROCEDURE
              k38get_state (
                    buf_size         : tsp00_Int4;
                    VAR buf_len      : tsp00_Int4;
                    VAR buffer       : tsp00_MoveObj);
 
        PROCEDURE
              k38headmaster (VAR m : tgg00_MessBlock);
 
        PROCEDURE
              k38history_error_write (
                    taskId         : tsp00_TaskId;
                    VAR utilcmd_id : tgg00_UtilCmdId;
                    save_type1 : tgg00_MessType;
                    save_type2 : tgg00_MessType2;
                    is_cold    : boolean;
                    backup_no  : tsp00_Int4;
                    err_reason : tgg00_BasisError);
 
        PROCEDURE
              k38history_lost_write (taskId : tsp00_TaskId);
 
        FUNCTION
              k38is_backup_running : boolean;
 
        PROCEDURE
              k38init_restore (
                    VAR m         : tgg00_MessBlock;
                    is_check_save : boolean);
 
        PROCEDURE
              k38init_save (
                    VAR m                  : tgg00_MessBlock;
                    is_cold                : boolean;
                    complete_log           : boolean;
                    destructive_tape_check : boolean);
 
        PROCEDURE
              k38ReserveBackupServerTasks (VAR trans : tgg00_TransContext);
 
        PROCEDURE
              k38restore_config (VAR mblock : tgg00_MessBlock);
 
        PROCEDURE
              k38set_not_generated;
 
        PROCEDURE
              k38sh_autosave_show (VAR m : tgg00_MessBlock);
 
        PROCEDURE
              k38st_autosave_start (VAR trans : tgg00_TransContext);
 
        PROCEDURE
              k38UtilIdGet (VAR UtilIdStr : tgg00_UtilCmdId);
 
        PROCEDURE
              k38UtilIdSaveLineNo (VAR UtilId : tgg00_UtilCmdId);
              (*ptocExport hkb38_1.h*)
 
        PROCEDURE
              k38e_autosave_end (VAR t : tgg00_TransContext; is_quick : boolean);
 
        PROCEDURE
              k38get_autosave_medianame (
                    TaskId         : tsp00_TaskId;
                    VAR media_name : tsp00_C64);
 
        PROCEDURE
              k38i_autosave_init (VAR m : tgg00_MessBlock);
 
        FUNCTION
              k38is_on_autosave (
                    VAR t     : tgg00_TransContext;
                    in_region : boolean) : boolean;
 
        PROCEDURE
              k38trigger_autosave (
                    VAR t     : tgg00_TransContext;
                    in_region : boolean);
              (*ptocExport hkb38_2.h*)
 
        PROCEDURE
              k38closeasyn (
                    VAR t         : tgg00_TransContext;
                    glob          : tkb3_save_static_ptr;
                    is_auto_load  : boolean;
                    force_rewind  : boolean;
                    tape_no       : tsp00_Int2;
                    VAR is_open   : boolean;
                    closefno      : tsp00_Int4);
 
        PROCEDURE
              k38tapeopen_one (
                    VAR t             : tgg00_TransContext;
                    glob              : tkb3_save_static_ptr;
                    tape_no           : tsp00_Int2;
                    is_for_writing    : boolean;
                    is_for_readlabel  : boolean);
 
        PROCEDURE
              k38current_msg_label (
                    glob          : tkb3_save_static_ptr;
                    VAR msg_label : tsp00_C8);
 
        PROCEDURE
              k38err_to_vtrace (
                    VAR t             : tgg00_TransContext;
                    glob              : tkb3_save_static_ptr;
                    msg               : tsp00_Sname;
                    VAR errtext       : tsp00_ErrText);
 
        PROCEDURE
              k38get_global (
                    mess_type : tgg00_MessType;
                    VAR glob : tkb3_save_static_ptr);
 
        PROCEDURE
              k38mdf_medium_def_write (
                    glob       : tkb3_save_static_ptr;
                    taskId     : tsp00_TaskId;
                    tape_no    : tsp00_Int2;
                    version_no : tsp00_Int4);
 
        PROCEDURE
              k38sys_msg (
                    glob     : tkb3_save_static_ptr;
                    msg_type : tsp3_msg_type;
                    mess_no  : tsp00_Int4;
                    errtxt   : tsp00_ErrText;
                    bad_int  : tsp00_Int4);
&       ifdef TRACE
 
        PROCEDURE
              k38show_monitor (glob : tkb3_save_static_ptr);
 
        PROCEDURE
              k38view_into_saveregion (
                    glob   : tkb3_save_static_ptr;
                    txt    : tsp00_Name;
                    q_only : boolean);
&       endif
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              AK_error_handling : VAK071;
 
        FUNCTION
              a071_return_code (b_err : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              KB_Check : VKB03;
 
        VAR
              kb03Check : tkb00_Check;
 
      ------------------------------ 
 
        FROM
              KB_backup_tasks : VKB39;
 
        PROCEDURE
              k39config_restartrec_from_first_tape (
                    VAR t        : tgg00_TransContext;
                    glob         : tkb3_save_static_ptr;
                    msg2type     : tgg00_MessType2;
                    tape_no      : tsp00_Int2;
                    block        : tkb3_block_ptr;
                    bIsClustered : boolean );
 
        FUNCTION
              k39pages_for_first_info (blocksize : tsp00_Int4) : tsp00_Int4;
 
        PROCEDURE
              k39read_label (
                    VAR t       : tgg00_TransContext;
                    glob        : tkb3_save_static_ptr;
                    tape_no     : tsp00_Int2;
                    VAR my_info : tkb3_info_stuff);
 
        PROCEDURE
              k39restore_config (
                    VAR t      : tgg00_TransContext;
                    glob       : tkb3_save_static_ptr;
                    VAR dbname : tsp00_DbName);
 
        PROCEDURE
              k39run_backup_task (
                    VAR trans   : tgg00_TransContext;
                    forAutosave : boolean;
                    in_region   : boolean);
 
        PROCEDURE
              k39wakeup_all (
                    glob       : tkb3_save_static_ptr;
                    process_id : tsp00_TaskId);
 
        PROCEDURE
              k39write_extra_block (
                    VAR t       : tgg00_TransContext;
                    glob        : tkb3_save_static_ptr;
                    tape_no     : integer;
                    what_page   : tgg00_PageType2;
                    VAR my_info : tkb3_info_stuff);
 
      ------------------------------ 
 
        FROM
              KB_LogSaveIterator : VKB391;
 
        PROCEDURE
              kb391InitLogSaveIterator (
                    VAR trans    : tgg00_TransContext;
                    maxToBeRead  : tsp00_Int2;
                    dbIsCold     : boolean;
                    forAutosave  : boolean;
                    completeLog  : boolean;
                    repeatable   : boolean);
 
        PROCEDURE
              kb391FreeLog (taskId           : tsp00_TaskId;
                    VAR trError              : tgg00_BasisError);
 
        PROCEDURE
              kb391GetSaveIterInfo(
                    VAR startTime   : tsp00_Int4  (*ptocSynonym Kernel_Time& *);
                    VAR startDate   : tsp00_Int4  (*ptocSynonym Kernel_Date& *);
                    VAR endTime     : tsp00_Int4  (*ptocSynonym Kernel_Time& *);
                    VAR endDate     : tsp00_Int4  (*ptocSynonym Kernel_Date& *);
                    VAR startIOSeq  : tsp00_Int4 (*ptocSynonym Log_IOSequenceNo& *);
                    VAR endIOSeq    : tsp00_Int4 (*ptocSynonym Log_IOSequenceNo& *);
                    VAR pageCount   : tsp00_Int4 (*ptocSynonym Log_RawDeviceOffset& *);
                    VAR backupCount : tsp00_Int4 );
 
        PROCEDURE
              kb391GetNumOfPagesLeftForSegment (
                    VAR numOfUnsavedPages : tsp00_Uint4);
 
        PROCEDURE
              kb391GetNumOfPagesLeftForLogDev (
                    VAR numOfUnsavedPages : tsp00_Uint4);
 
        PROCEDURE
              kb391InvalidateSaveIterator ;
 
        PROCEDURE
              kb391AppendTapeErrorToMessageList (
                    taskid           : tsp00_TaskId;
                    isInfo           : boolean;
                    writeImmediately : boolean;
                    mediano          : tsp00_Int4;
                    VAR medianame    : tsp00_VFilename;
                    VAR errortext    : tsp00_ErrText );
 
        PROCEDURE
              kb391InputParameters (
                    VAR mblock : tgg00_MessBlock;
                    glob       : tkb3_save_static_ptr);
 
      ------------------------------ 
 
        FROM
              KB_Logging : VKB560;
 
        PROCEDURE
              kb560GetFirstKnownIOSeqBeforeRestoreLog(
                    VAR FirstIOSeq: tsp00_Uint4;
                    VAR firstIOSeqIsValid : boolean);
 
        PROCEDURE
              k560check_logsave_allowed (
                    TaskId         : tsp00_TaskId;
                    VAR BasisError : tgg00_BasisError);
 
        PROCEDURE
              kb560GetLogDBIdent ( VAR dbident : tsp00_Line);
 
        PROCEDURE
              kb560SetDeviceStateOkay (
                    taskid      : tsp00_TaskId;
                    VAR TrError : tgg00_BasisError);
 
        PROCEDURE
              kb560InvalidateIOSeq (VAR ioSeq : tsp00_Uint4);
 
        FUNCTION
              kb560IsValidIOSeq (VAR  ioSeq : tsp00_Uint4) : boolean;
 
      ------------------------------ 
 
        FROM
              KB_restart_record : VKB57;
 
        VAR
              k57frozen_restartrec : tkb00_PagePtr;
              k57restartrec        : tkb00_PagePtr;
 
        FUNCTION
              k57calc_checksum (VAR logpage : tkb00_Page): tsp00_Int4;
 
        PROCEDURE
              k57save_restartrecord (TaskId : tsp00_TaskId);
 
      ------------------------------ 
 
        FROM
              KB_ServerTasks : VKB900;
 
        FUNCTION
              kb900CreateBackupServer (
                    VAR pSrvTasks_BackupServer : tsp00_Addr (*ptocSynonym void* &*);
                    forAutosave : boolean;
                    maxMedias   : tsp00_Int4;
                    maxVolumes  : tsp00_Int4;
                    taskid      : tsp00_TaskId;
                    errorlist   : tgg00_VoidPtr) : boolean;
 
        PROCEDURE
              kb900ExecuteBackupJob (
                    VAR trans   : tgg00_TransContext (*ptocSynonym Trans_Context&*);
                    pSrvTasks_BackupServer : tsp00_Addr (*ptocSynonym void* *);
                    region      : tsp00_Int4;
                    forAutosave : boolean;
                    task_no     : tsp00_Int2;
                    media_no    : tsp00_Int4;
                    vol_no      : tsp00_Int4);
 
        PROCEDURE
              kb900WaitForAnyBackupJobFinished (
                    VAR trans    : tgg00_TransContext (*ptocSynonym Trans_Context&*);
                    pSrvTasks_BackupServer : tsp00_Addr (*ptocSynonym void* *);
                    region       : tsp00_Int4;
                    VAR task_no  : tsp00_Int2;
                    VAR joberror : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1: VBD01 ;
 
        VAR
              b01blankfilename  : tsp00_VFilename;
 
        PROCEDURE
              b01end_read_only (VAR t : tgg00_TransContext);
 
        FUNCTION
              b01no_of_data_devs : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              pagestore: VBD10;
 
        PROCEDURE
              bd10EndSave (
                    TaskId           : tsp00_TaskId;
                    bBackUpSuccessful : boolean);
 
        FUNCTION
              b10bup_data_page_cnt (pid : tsp00_TaskId) : tsp00_Int4;
 
        PROCEDURE
              bd10FinishRestoreUsedPageNos (TaskId : tsp00_TaskId);
 
        PROCEDURE
              bd10ShutdownConverter (TaskId : tsp00_TaskId);
 
        FUNCTION
              bd10CheckBackup( taskId: tsp00_TaskId ) : boolean;
 
      ------------------------------ 
 
        FROM
              free_block_management : VBD11;
 
        FUNCTION
              b11_has_clustered_blocks_for_backup ( taskid : tsp00_TaskId ) : boolean ;
 
      ------------------------------ 
 
        FROM
              Trace : VBD120;
 
        PROCEDURE
              b120InsertTrace (
                    VAR t        : tgg00_TransContext;
                    trace_layer  : tgg00_Debug;
                    trace_object : tgg00_VtraceType;
                    body_len     : tsp00_Int2;
                    trace_body   : tsp00_Addr);
 
      ------------------------------ 
 
        FROM
              backup_and_restore : VBD14;
 
        PROCEDURE
              bd14ShutdownFileSystemAfterRestore (
                    VAR Trans           : tgg00_TransContext;
                    bRestoreSuccessfull : boolean);
 
      ------------------------------ 
 
        FROM
              BD_Wrapper : VBD999;
 
        PROCEDURE
              bd999DetachAllArchiveLogs( TaskId : tsp00_TaskId );
 
        FUNCTION
              bd999GetNextDataVolumeNameForBackup(
                    VAR  PhysDevNo : tsp00_Int2;
                    VAR  DevName   : tsp00_VFilename;
                    isForWriting   : boolean) : boolean;
 
        PROCEDURE
              bd999CreateAllDataVolumes(
                    TaskId        : tsp00_TaskId;
                    VAR TrError   : tgg00_BasisError);
 
        PROCEDURE
              bd999DetachAllDataVolumes( TaskId : tsp00_TaskId );
 
        PROCEDURE
              bd999AttachAllDataVolumes(
                    TaskId      : tsp00_TaskId;
                    VAR TrError : tgg00_BasisError);
 
        FUNCTION
              bd999MaxConfigurableDataVolumes : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter: VGG01;
 
        VAR
              g01vtrace             : tgg00_VtraceState;
              g01log_backup_to_pipe : boolean; (* PTS 1108438 UH 2000-11-22 *)
              g01serverdb_ident     : tgg04_ServerdbIdent; (* PTS 1113051 E.Z. *)
 
        FUNCTION
              g01align (val : tsp00_Int4): tsp00_Int4;
 
        PROCEDURE
              g01allocate_msg (
                    msg_label  : tsp00_C8;
                    msg_text   : tsp00_C24;
                    alloc_size : tsp00_Int4);
 
        FUNCTION
              g01backup_block_count : tsp00_Int4;
 
        PROCEDURE
              g01check (
                    msg_no     : tsp00_Int4;
                    msg_label  : tsp00_C8;
                    msg_text   : tsp00_C24;
                    bad_value  : tsp00_Int4;
                    constraint : boolean);
 
        PROCEDURE
              g01event_init (VAR new_event : tsp31_event_description);
 
        PROCEDURE
              g01new_dump_page (
                    VAR hostfile : tgg00_VfFileref;
                    VAR buf      : tsp00_Page;
                    VAR out_pno  : tsp00_Int4;
                    VAR out_pos  : integer;
                    VAR host_err : tsp00_VfReturn;
                    VAR errtext  : tsp00_ErrText);
 
        FUNCTION
              g01no_of_backup_devs : tsp00_Int4;
 
        PROCEDURE
              g01opmsg (
                    msg_prio  : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    msg_value : tsp00_Int4);
 
        PROCEDURE
              g01optextmsg (
                    msg_prio  : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C40);
 
        FUNCTION
              g01is_archive : boolean;
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : vgg06;
 
        PROCEDURE
              gg06UInt4toLine(
                    int       : tsp00_Int4;
                    int_len   : integer;
                    VAR ln    : tsp00_Line);
 
      ------------------------------ 
 
        FROM
              Regions_and_Longwaits: VGG08;
 
        VAR
              g08savepoint       : tsp00_RegionId;
              g08save0     : tsp00_RegionId;
 
        PROCEDURE
              g08check_excl (region : tsp00_RegionId);
 
        PROCEDURE
              g08excl_check (
                    pid          : tsp00_TaskId;
                    region       : tsp00_RegionId);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id   : tsp00_C6;
                    mod_num  : tsp00_Int4;
                    obj_upb  : tsp00_Int4;
                    obj      : tsp00_MoveObjPtr;
                    obj_pos  : tsp00_Int4;
                    length   : tsp00_Int4;
                    fillchar : char;
                    VAR e    : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id     : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              Kernel-Version: VGG11;
 
        PROCEDURE
              g11kernel_version  (VAR vers : tsp00_Version);
 
      ------------------------------ 
 
        FROM
              GG_edit_routines : VGG17;
 
        PROCEDURE
              g17int4to_line (
                    int       : tsp00_Int4;
                    with_zero : boolean;
                    int_len   : integer;
                    ln_pos    : integer;
                    VAR ln    : tsp00_Line);
 
        PROCEDURE
              g17intdate_time (
                    int_date     : tsp00_Int4;
                    int_time     : tsp00_Int4;
                    VAR str_date : tsp00_Date;
                    VAR str_time : tsp00_Time);
 
        PROCEDURE
              g17trimint4_to_line (
                    int        : tsp00_Int4;
                    VAR ln_len : integer;
                    VAR ln     : tsp00_ErrText);
 
        PROCEDURE
              g17vftype (
                    ft         : tsp00_VfType;
                    VAR ln_len : tsp00_Int4;
                    VAR ln     : tsp00_Line);
 
      ------------------------------ 
 
        FROM
              KernelAdministration_Interface : VGG999;
 
        PROCEDURE
              gg999AbortRedoLogByRestoreComponent(taskid : tsp00_TaskId;
                    abortReason : tgg00_BasisError);
 
        PROCEDURE
              gg999GetNewCommandId (
                    taskid : tsp00_TaskId;
                    VAR id : tgg00_UtilCmdId);
 
        PROCEDURE
              gg999NewDBIdentIfHistoryLost (taskid : tsp00_TaskId);
 
        PROCEDURE
              gg999Offline (error : tgg00_BasisError);
 
        PROCEDURE
              gg999BroadcastBackupHistoryEntry(
                    taskid : tsp00_TaskId;
                    VAR backup_info : tsp00_Buf;
                    info_len    : tsp00_Int4);
 
        PROCEDURE
              gg999BroadcastBackupMediumDefEntry(
                    taskid : tsp00_TaskId;
                    VAR backup_info : tsp00_Buf;
                    info_len    : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20: VSP20;
 
        PROCEDURE
              s20int4_to_buf (
                    val      : tsp00_Int4;
                    VAR dest : tsp00_Page;
                    di       : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30: VSP30;
 
        FUNCTION
              s30lnr (
                    VAR str   : tsp00_VFilename;
                    skip_val  : char;
                    start_pos : tsp00_Int4;
                    length    : tsp00_Int4) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              PUT-Conversions : VSP41;
 
        PROCEDURE
              s41p4int (
                    VAR buf : tsp00_ResNum;
                    pos     : tsp00_Int4;
                    source  : tsp00_Int4;
                    VAR res : tsp00_NumError);
 
        PROCEDURE
              s41pluns (
                    VAR buf : tsp00_ResNum;
                    pos     : tsp00_Int4;
                    len     : integer;
                    frac    : integer;
                    source  : tsp00_Int4;
                    VAR res : tsp00_NumError);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures: VTA01;
 
        PROCEDURE
              t01bool (
                    debug     : tgg00_Debug;
                    nam       : tsp00_Sname;
                    curr_bool : boolean);
 
        PROCEDURE
              t01bool2 (
                    debug : tgg00_Debug;
                    nam1 : tsp00_Sname;
                    boo1 : boolean;
                    nam2 : tsp00_Sname;
                    boo2 : boolean);
 
        PROCEDURE
              t01basis_error (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
 
        PROCEDURE
              t01vftype (
                    debug : tgg00_Debug;
                    nam : tsp00_Sname;
                    ft  : tsp00_VfType);
 
        PROCEDURE
              t01p2int4 (
                    debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
 
        PROCEDURE
              t01name (debug : tgg00_Debug; nam  : tsp00_Name);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        FUNCTION
              t01trace (debug : tgg00_Debug) : boolean;
 
        PROCEDURE
              t01vffn (
                    debug : tgg00_Debug;
                    nam : tsp00_Sname;
                    fn  : tsp00_VFilename);
&       endif
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vallocat (
                    length     : tsp00_Int4;
                    VAR p      : tsp00_ObjAddr;
                    VAR ok     : boolean);
 
        PROCEDURE
              vasynclose (
                    hostfileno             : tsp00_Int4;
                    rewind                 : boolean;
                    nxt_in_autoloader      : boolean;
                    VAR nxt_tape_available : tsp00_VaReturn;
                    VAR returncode         : tsp00_VaReturn;
                    VAR errtext            : tsp00_ErrText);
 
        PROCEDURE
              vasyninit_tape (
                    hostfileno     : tsp00_Int4;
                    destructive    : boolean;
                    VAR filetype   : tsp00_VfType;
                    VAR returncode : tsp00_VaReturn;
                    VAR errtext    : tsp00_ErrText);
 
        PROCEDURE
              vasynopen (
                    VAR hostfile      : tsp00_VFilename;
                    is_devspace       : boolean;
                    for_writing       : boolean;
                    filetype          : tsp00_VfType;
                    block_size        : tsp00_Int4;
                    cancel_pointer    : tsp00_BoolAddr;
                    VAR max_blockcnt  : tsp00_Int4;
                    VAR hostfileno    : tsp00_Int4;
                    VAR returncode    : tsp00_VaReturn;
                    VAR errtext       : tsp00_ErrText);
 
        PROCEDURE
              vbackup_info (
                    VAR backup_info : tsp00_Buf;
                    info_len    : tsp00_Int4;
                    VAR error   : tsp00_VfReturn;
                    VAR errtext : tsp00_ErrText);
 
        PROCEDURE
              vbackup_medium_def (
                    VAR backup_medium_def : tsp00_Buf;
                    info_len     : tsp00_Int4;
                    VAR error    : tsp00_VfReturn;
                    VAR errtext  : tsp00_ErrText);
 
        PROCEDURE
              vbegexcl (
                    pid    : tsp00_TaskId;
                    region : tsp00_RegionId);
 
        PROCEDURE
              vdattime (
                    VAR dat     : tsp00_Date;
                    VAR tim     : tsp00_Time);
 
        PROCEDURE
              vendexcl (
                    pid    : tsp00_TaskId;
                    region : tsp00_RegionId);
 
        PROCEDURE
              vinsert_event ( VAR event : tsp31_event_description );
 
        PROCEDURE
              vmessage (
                    prio         : tsp3_priority;
                    msg_type     : tsp3_msg_type;
                    msg_no       : tsp00_Int4;
                    msg_label    : tsp00_C8;
                    VAR msg_line : tsp00_C40);
 
        PROCEDURE
              vnewbuf (
                    count         : tsp00_Int4;
                    VAR available : tsp00_Int4;
                    VAR p         : tsp00_PageAddr;
                    VAR ok        : boolean);
 
        PROCEDURE
              vresume (pid : tsp00_TaskId);
 
        PROCEDURE
              vsleep (
                    pid   : tsp00_TaskId;
                    limit : tsp00_Int2);
 
        PROCEDURE
              vsuspend (
                    pid            : tsp00_TaskId;
                    suspend_reason : tsp00_Int2);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b120InsertTrace;
 
              tgg11_VtraceBodyPtr tsp00_Addr
 
        PROCEDURE
              g17trimint4_to_line;
 
              tsp00_Line tsp00_ErrText
 
        PROCEDURE
              s20int4_to_buf;
 
              tsp00_MoveObj tsp00_Page
 
        FUNCTION
              s30lnr;
 
              tsp00_MoveObj tsp00_VFilename;
 
        PROCEDURE
              s41p4int;
 
              tsp00_MoveObj tsp00_ResNum
 
        PROCEDURE
              s41pluns;
 
              tsp00_MoveObj tsp00_ResNum
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1993-06-21
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-11-23
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.sp;.nf
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      CSEP               = '|';
      SEP_LEN            =  1;
      LABEL_LEN          = 13;
      SAVE_KIND_LEN      =  9;
      TIME_STAMP_LEN     = 19;
      NUM_LEN            = 10; (* NUMBER_MXSP00 *)
      (* *)
      POS_UTILCMD        = 1;
      POS_LABEL          = POS_UTILCMD       + 12             + SEP_LEN;
      POS_SAVE_KIND      = POS_LABEL         + LABEL_LEN      + SEP_LEN;
      POS_DBSTAMP1       = POS_SAVE_KIND     + SAVE_KIND_LEN  + SEP_LEN;
      POS_DBSTAMP2       = POS_DBSTAMP1      + TIME_STAMP_LEN + SEP_LEN;
      POS_START_DATE     = POS_DBSTAMP2      + TIME_STAMP_LEN + SEP_LEN;
      POS_END_DATE       = POS_START_DATE    + TIME_STAMP_LEN + SEP_LEN;
      POS_FIRST_IOSEQUENCE     = POS_END_DATE      + TIME_STAMP_LEN + SEP_LEN;
      POS_LAST_IOSEQUENCE      = POS_FIRST_IOSEQUENCE    + NUM_LEN        + SEP_LEN;
      POS_LOG_NEEDED     = POS_LAST_IOSEQUENCE     + NUM_LEN        + SEP_LEN;
      POS_MEDIA_NAME     = POS_LOG_NEEDED    + 3              + SEP_LEN; (* 'YES'|'NO ' *)
      POS_TRANSF_PAGES   = POS_MEDIA_NAME    + 64             + SEP_LEN;
      POS_MAX_VOL_COUNT  = POS_TRANSF_PAGES  + NUM_LEN        + SEP_LEN;
      POS_RETURN_CODE    = POS_MAX_VOL_COUNT + NUM_LEN        + SEP_LEN;
      POS_ERRTEXT        = POS_RETURN_CODE   + NUM_LEN        + SEP_LEN;
      MAX_HIST_ENTRY_LEN = POS_ERRTEXT       + 40             + SEP_LEN;
      (* *)
      c_sep                      = '|'; (* PTS 1000355 UH *)
      c_num_len                  = 10;  (* PTS 1000355 UH *)
      c_kern_label_len           = 13;  (* PTS 1000355 UH *)
      (**)
      c_min_pages_to_change_tape = 500;
      c_max_log_restore_tapes    = 1;
      c_queue_factor             = 2;
      (**)
      c_in_not_eq_out            = 1;
      c_not_all_free             = 2;
      c_child_running            = 3;
      c_fbm_error                = 4;
      (**)
      c_auto_load         = true;
      c_check_new_tape    = true;
      c_backup_successful = true;
      c_complete_log      = true; (* PTS 1000360 UH *)
      c_for_writing       = true;
      c_for_readlabel     = true;
      c_for_autosave      = true; (* PTS 1000360 UH *)
      c_force_rewind      = true;
      c_in_region         = true;
      c_is_auto_load      = true;
      c_is_devspace       = true;
      c_is_get_state      = true; (* PTS 1000397 UH *)
      c_is_quick          = true;
      c_label_handling    = true;
      c_rewind            = true;
      c_show_q_only       = true;
      c_with_zeros        = true;
      c_RestoreSuccessful = true;
      (**)
      c_autosave_reader_no   = 1;
      c_autosave_writer_no   = 2;
      c_autosave_log_device  = 1;
      c_autosave_tape_device = 1;
      c_autosave_mirr_device = c_autosave_tape_device + 1;
      (**)
      c_autosave_blocksize   = 8;
      c_autosave_maxdatadevs = 1;
      c_autosave_num_tapes   = 1;
      (**)
      c_undef_fill           = ' ';
      (**)
      c_aborted              =
            'abort, current save is incomplete       ';
      c_wait_for_completion  =
            'end, wait for completion                ';
      c_standby_off =
            'standby mode off                        ';
      c_standby_on =
            'standby mode on                         ';
      c_beginning =
            'started                                 ';
      c_continue =
            'continued                               ';
      c_cannot_send       = '*error* cannot send     ';
      c_type_not_allowed  = 'Filetype NOT allowed    ';
      (**)
      c_allocate_failed =
            'allocate failed                         ' ;
      c_closeerr =
            'close error                             ' ;
      c_devsp_surprising_blockcnt =
            'devspace: surprising blk cnt:           ' ;
      c_fbm1_check_failed  =
            'FBM blocks still in use                 ' ;
      c_filetype_mismatch =
            'mismatch: checked and expected type     ' ;
      c_flush_error =
            'flush error                             ' ;
      c_fversion_not_allowed =
            'auto numbering only with files          ' ;
      c_invalid_call =
            'invalid command, msgtype                ' ;
      c_invalid_filetype =
            'this filetype is not allowed            ' ;
      c_invalid_tape_age =
            'tape label is too young                 ' ;
      c_is_error =
            'error occured, basis_err                ' ;
      c_is_ok =
            'ready                                   ' ;
      c_is_tapeswap =
            'new tape required                       ' ;
      c_too_many_log_tapes =
            'currently only 1 tape allowed           ' ;
      c_tape_missing =
            'backup incomplete, next volume required ' ;
      c_qsize_const_err =
            'xparam: inv block/pool size             ' ;
      c_tape_surprising_blockcnt =
            'tape: surprising blockcount             ' ;
 
TYPE
      tkb38_EventType =
            (Started_ekb38,
            Stopped_ekb38,
            StandbyOn_ekb38,
            StandbyOff_ekb38,
            BackupSuccessfull_ekb38);
 
VAR
      k38globals     : tkb3_static_array;
 
 
(*------------------------------*) 
 
PROCEDURE
      kb38append_to_backup_history (
            taskId : tsp00_TaskId;
            VAR backup_info : tsp00_Buf;
            info_len    : tsp00_Int4;
            VAR error   : tsp00_VfReturn;
            VAR errtext : tsp00_ErrText);
      (* NEW with PTS 1129960 MB 2004-06-10 as wrapper in order to assure braodcast to standbys *)
 
BEGIN
vbackup_info ( backup_info, info_len, error, errtext);
gg999BroadcastBackupHistoryEntry( taskId, backup_info , info_len);
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38append_to_mediumdef (
            taskId : tsp00_TaskId;
            VAR backup_medium_def : tsp00_Buf;
            info_len     : tsp00_Int4;
            VAR error    : tsp00_VfReturn;
            VAR errtext  : tsp00_ErrText);
      (* NEW with PTS 1129960 MB 2004-06-10 as wrapper in order to assure braodcast to standbys *)
 
BEGIN
vbackup_medium_def ( backup_medium_def, info_len, error, errtext);
gg999BroadcastBackupMediumDefEntry(taskId, backup_medium_def , info_len );
END;
 
(*------------------------------*) 
 
FUNCTION
      k38GetMaxServerTasks : tsp00_Int4;
 
BEGIN
k38GetMaxServerTasks := g01no_of_backup_devs + bd999MaxConfigurableDataVolumes + 2 (*autosave*);
END;
 
(*------------------------------*) 
 
FUNCTION
      k38GetTaskIdOfCurrentBackup (taskid : tsp00_TaskId) : tsp00_TaskId;
 
VAR
      glob               : tkb3_save_static_ptr;
      coordinator_taskid : tsp00_TaskId;
 
BEGIN
(* PTS 1134753 UH 2005-04-11 new *)
k38get_global (m_save_parallel, glob);
vbegexcl (taskid, g08save0 + glob^.sta_region);
coordinator_taskid := glob^.sta_coordinator_taskid;
vendexcl (taskid, g08save0 + glob^.sta_region);
k38GetTaskIdOfCurrentBackup := coordinator_taskid;
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38allocate (
            pid        : tsp00_TaskId;
            VAR b_err  : tgg00_BasisError);
 
VAR
      ok               : boolean ;
      i                : integer ;
      task_list_bytes  : tsp00_Int4 ;
      tape_list_bytes  : tsp00_Int4 ;
      devsp_list_bytes : tsp00_Int4 ;
      srr_queue_bytes  : tsp00_Int4 ;
      available        : tsp00_Int4 ;
      block_count      : tsp00_Int4;
      univ_addr        : tkb3_univ_addr;
      glob             : tkb3_save_static_ptr;
 
BEGIN
(* outside region *)
b_err     := e_ok ;
ok        := true ;
available := 0 ;
k38get_global (m_save_parallel, glob);
WITH glob^ DO
    BEGIN
    block_count   := g01backup_block_count;
    sta_max_tasks := g01no_of_backup_devs + bd999MaxConfigurableDataVolumes;
    IF  (g01no_of_backup_devs > bd999MaxConfigurableDataVolumes)
    THEN
        sta_queue_size := c_queue_factor *
              (g01no_of_backup_devs + c_queue_factor)
    ELSE
        sta_queue_size := c_queue_factor *
              (bd999MaxConfigurableDataVolumes + c_queue_factor);
    (*ENDIF*) 
    ok := (block_count >= ckb3_min_pages_per_block)
          AND
          (sta_queue_size >= c_queue_factor);
    IF  NOT ok
    THEN
        BEGIN
        b_err := e_invalid_configuration;
        k38sys_msg (glob, sp3m_error, kb38InvalidQueueSize_csp03,
              c_qsize_const_err, sta_queue_size)
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
IF  ok
THEN
    WITH glob^ DO
        BEGIN
&       ifdef TRACE
        t01p2int4 (kb_save, 'queue_size  ', sta_queue_size
              ,             'max_tasks   ', sta_max_tasks);
&       endif
        (* --- restart rec (copy) --- *)
        vnewbuf (1, available, univ_addr.buf, ok);
        g01allocate_msg (csp3_n_dyndata, 'BACKUP RESTART REC (8K):', 1);
        IF  ok
        THEN
            BEGIN
            sta_data_rst_rec := univ_addr.log;
            (* --- task list --- *)
            task_list_bytes := sta_max_tasks * sizeof (tkb3_task_desc);
            vallocat (task_list_bytes, univ_addr.obj, ok);
            g01allocate_msg (csp3_n_dynpool, 'BACKUP TASK LIST       :',
                  g01align (task_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
            END;
        (*ENDIF*) 
        IF  ok
        THEN
            BEGIN
            sta_task := univ_addr.task;
            (* --- tape list --- *)
            tape_list_bytes  := g01no_of_backup_devs *
                  sizeof (tkb3_tape_desc);
            vallocat (tape_list_bytes, univ_addr.obj, ok);
            g01allocate_msg (csp3_n_dynpool, 'BACKUP TAPE LIST       :',
                  g01align (tape_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
            END;
        (*ENDIF*) 
        IF  ok
        THEN
            BEGIN
            sta_tape := univ_addr.tape;
            (* --- devsp list --- *)
            devsp_list_bytes := bd999MaxConfigurableDataVolumes *
                  sizeof (tkb3_devsp_desc);
            vallocat (devsp_list_bytes, univ_addr.obj, ok);
            g01allocate_msg (csp3_n_dynpool, 'BACKUP DEVSP LIST      :',
                  g01align (devsp_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
            END;
        (*ENDIF*) 
        IF  ok
        THEN
            BEGIN
            sta_devsp := univ_addr.devsp;
            (* --- volume index --- *)
            devsp_list_bytes := bd999MaxConfigurableDataVolumes *
                  sizeof (tsp00_Int2);
            vallocat (devsp_list_bytes, univ_addr.obj, ok);
            g01allocate_msg (csp3_n_dynpool, 'BACKUP VOL IDX LIST    :',
                  g01align (devsp_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
            END;
        (*ENDIF*) 
        IF  ok
        THEN
            BEGIN
            sta_vol_idx := univ_addr.volidx;
            (* --- queue --- *)
            (*                       queue element 0 contains extra block *)
            srr_queue_bytes := (1 + sta_queue_size) * sizeof(tkb3_srr_elem);
            vallocat (srr_queue_bytes, univ_addr.obj, ok);
            g01allocate_msg (csp3_n_dynpool, 'BACKUP SRR QUEUE       :',
                  g01align (srr_queue_bytes));
            g01allocate_msg (csp3_n_dynpool, 'DYNP_K38_SAVE_GLOB     :',
                  g01align (task_list_bytes ) +
                  g01align (tape_list_bytes ) +
                  g01align (devsp_list_bytes) +
                  g01align (srr_queue_bytes )) (* PTS 1104176 JA 1999-10-12 *)
            END;
        (*ENDIF*) 
        IF  ok
        THEN
            BEGIN
            sta_queue := univ_addr.srr;
            (* --- pages pool --- *)
            (*                   block 0 contains extra block *)
            (*                   + 1 restart record           *)
            g01allocate_msg (csp3_n_dyndata, 'DYND_K38_SAVE          :',
                  (1 + glob^.sta_queue_size) * block_count +1)
            END;
        (*ENDIF*) 
        i := 0;
        WHILE ok AND (i <= sta_queue_size) DO
            BEGIN
            vnewbuf (block_count, available, univ_addr.buf,ok);
            sta_queue^[i].sre_block := univ_addr.block;
            i := i + 1
            END;
        (*ENDWHILE*) 
        glob^.sta_backup_server := NIL;
        IF  NOT ok
        THEN
            BEGIN
            b_err := e_sysbuf_storage_exceeded;
            k38sys_msg (glob, sp3m_error, kbAllocateFailed_csp03,
                  c_allocate_failed, 0)
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
&ifdef TRACE
(*ENDIF*) 
t01basis_error (kb_save, 'end k38alloc', b_err) ;
&endif
IF  b_err = e_ok
THEN
    BEGIN
    vbegexcl (pid, g08save0 + glob^.sta_region);
    kb38glob_init (glob, m_nil, mm_nil);
    vendexcl (pid, g08save0 + glob^.sta_region)
    END;
(*ENDIF*) 
IF  b_err = e_ok
THEN
    BEGIN
    k38get_global (m_autosave, glob);
    kb38alloc_autosave (pid, glob, b_err);
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38closeasyn (
            VAR t         : tgg00_TransContext;
            glob          : tkb3_save_static_ptr;
            is_auto_load  : boolean;
            force_rewind  : boolean;
            tape_no       : tsp00_Int2;
            VAR is_open   : boolean;
            closefno      : tsp00_Int4);
 
VAR
      is_tape_dev   : boolean;
      for_writing   : boolean;
      rewind        : boolean;
      vaerr         : tsp00_VaReturn;
      load_err      : tsp00_VaReturn;
      aux_err       : tgg00_BasisError;
      etxt          : tsp00_ErrText;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
aux_err        := t.trError_gg00;
t.trError_gg00 := e_ok;
vaerr          := va_ok;
load_err       := va_ok;
IF  is_open
THEN
    BEGIN
    is_open     := false;
    is_tape_dev := tape_no <> ckb3_nil_tape_no;
    IF  is_tape_dev
    THEN
        rewind :=                          (* PTS 1140550 mb 2006-03-13 *)
              ((glob^.sta_tape^ [tape_no].tpd_type <> vf_t_tape_norew)
              AND (glob^.sta_tape^ [tape_no].tpd_type <> vf_t_file)
              AND (glob^.sta_tape^ [tape_no].tpd_type <> vf_t_pipe))
              OR force_rewind
    ELSE
        rewind := false;
    (*ENDIF*) 
    IF  NOT (glob^.sta_is_remote AND is_tape_dev)
    THEN
        BEGIN
        vendexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
        vasynclose (closefno, rewind, is_auto_load,load_err,vaerr,etxt);
        vbegexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region)
        END
    ELSE
        WITH glob^.sta_remote [tape_no] DO
            BEGIN
            IF  kb3rc_pid <> cgg_nil_pid
            THEN
                BEGIN
                kb3rc_length := 0;
&               ifdef TRACE
                t01int4 (kb_save, 'resume:     ', kb3rc_pid) ;
&               endif
                vresume (kb3rc_pid);
                kb3rc_pid    := cgg_nil_pid
                END
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
&   ifdef TRACE
    t01p2int4 (kb_save, 'aclose err  ', ord(vaerr)
          ,             '         fno', closefno);
    t01int4   (kb_save, '  load err  ', ord(load_err));
&   endif
    IF  vaerr <> va_ok
    THEN
        BEGIN
        t.trError_gg00 := e_hostfile_error;
        k38sys_msg (glob, sp3m_error, kbCloseError_csp03, c_closeerr,
              ord(vaerr));
        k38err_to_vtrace (t, glob, 'ASYNCLOSE   ', etxt);
        IF  tape_no > 0
        THEN
            glob^.sta_tape^ [tape_no].tpd_errtext := etxt
        (*ENDIF*) 
        END
    ELSE
        IF  is_auto_load AND (load_err = va_ok)
        THEN
            BEGIN
            WITH glob^.sta_tape^[tape_no] DO
                BEGIN
                tpd_is_open         := false;
                tpd_is_full         := false;
                tpd_volume_no       := 0;
                tpd_fno             := 0;
                tpd_cnt_pages       := 0;
                (* tpd_total_cnt_pages := 0; *)
                tpd_errtext         := bsp_c40;
                (* TEST: tpd_name [2] := chr (ord (tpd_name [2]) + 1);*)
                tpd_xp_size         := 0;
                tpd_xp_read         := 0;
                tpd_xp_pages        := 0;
                (* tpd_type         same as before *)
                tpd_err             := e_ok;
                (* tpd_mirror_index same as before *)
                END;
            (*ENDWITH*) 
            for_writing := (glob^.sta_msgtype = m_save_parallel) OR
                  (         glob^.sta_msgtype = m_autosave     );
            k38tapeopen_one (t, glob, tape_no, for_writing,
                  NOT c_for_readlabel);
            is_open := glob^.sta_tape^ [tape_no].tpd_is_open;
            IF  t.trError_gg00 <> e_ok
            THEN
                (* try again *)
                t.trError_gg00 := e_ok (* e_wrong_hostfile   PTS 1002139 JA 1999-03-10  *)
            ELSE
                BEGIN
                glob^.sta_tape^[tape_no].tpd_is_replaced := true;
                IF  for_writing
                THEN
                    k39write_extra_block (t, glob, tape_no,
                          pt2VolumeFirstInfo_egg00, glob^.sta_info)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  t.trError_gg00 = e_ok
THEN
    t.trError_gg00 := aux_err
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38current_msg_label (
            glob          : tkb3_save_static_ptr;
            VAR msg_label : tsp00_C8);
 
BEGIN
CASE glob^.sta_msgtype OF
    m_save_parallel:
        msg_label := csp3_n_save;
    m_restore_parallel:
        msg_label := csp3_n_restore;
    m_autosave:
        msg_label := csp3_n_autosave;
    OTHERWISE
        msg_label := csp3_n_save;
    END;
(*ENDCASE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38dump_headmaster (
            VAR hostfile : tgg00_VfFileref;
            VAR buf      : tsp00_Page;
            VAR out_pno  : tsp00_Int4;
            VAR out_pos  : integer;
            VAR host_err : tsp00_VfReturn;
            VAR errtext  : tsp00_ErrText);
 
BEGIN
kb38dump_headmaster
      (hostfile, buf, out_pno, out_pos, host_err, errtext);
kb38dump_autosave_log
      (hostfile, buf, out_pno, out_pos, host_err, errtext);
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38e_autosave_end (VAR t : tgg00_TransContext;
            is_quick : boolean);
 
VAR
      aux_err : tgg00_BasisError;
      glob    : tkb3_save_static_ptr;
 
BEGIN
glob           := @k38globals [ckb3_region_autosave];
aux_err        := e_ok;
t.trError_gg00 := e_ok;
vbegexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  k38is_on_autosave (t, true)
THEN
    WITH glob^, sta_tape^ [c_autosave_tape_device],
         sta_task^ [c_autosave_writer_no] DO
        BEGIN
        IF  is_quick
        THEN
            (* AUTOSAVE CANCEL *)
            BEGIN
            sta_system_state := sta_system_state + [sy_knockoffwork];
            IF  (tsd_state <> ts_none) AND (sta_task_for_conttape > 0)
            THEN
                (* must be suspended in 216 *)
                BEGIN
                g01optextmsg (sp3p_console, sp3m_warning,
                      kbCancelAutoSave_csp03, csp3_n_autosave, c_aborted);
                (*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
                vresume (tsd_task_pid);
                (*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
                END;
            (*ENDIF*) 
            k39wakeup_all (glob, t.trTaskId_gg00);
            vsleep (t.trTaskId_gg00, 0); (* reschedule *)
            END
        ELSE
            (* AUTOSAVE END *)
            BEGIN
            IF  tpd_is_full
            THEN
                t.trError_gg00 := e_invalid_command;
            (*ENDIF*) 
            IF  (t.trError_gg00 = e_ok)
                AND
                (sta_wait_pid = cgg_nil_pid)
                AND
                (tsd_state <> ts_none)
                AND
                (sta_task_for_conttape = 0)
            THEN
                (* wait for completion until current segment is saved *)
                BEGIN
                g01optextmsg (sp3p_console, sp3m_info,
                      kbEndAutoSave_csp03, csp3_n_autosave,
                      c_wait_for_completion);
                sta_wait_pid := t.trTaskId_gg00;
                vendexcl (t.trTaskId_gg00, g08save0 + sta_region);
                (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
                vsuspend (t.trTaskId_gg00, 202);
                (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
                vbegexcl (t.trTaskId_gg00, g08save0 + sta_region);
                sta_wait_pid := cgg_nil_pid;
                END;
            (*ENDIF*) 
            IF  tpd_is_full
            THEN
                (* during suspend the tape becomes full => no end *)
                t.trError_gg00 := e_invalid_command
            ELSE
                (* wakeup all server, which are still running *)
                BEGIN
                IF  (tsd_state <> ts_none)
                    OR
                    (sta_task^ [c_autosave_reader_no].tsd_state
                    <> ts_none)
                THEN
                    BEGIN
                    k39wakeup_all (glob, t.trTaskId_gg00);
                    vsleep (t.trTaskId_gg00, 0)
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        kb38discard_outstanding_tasks (t, glob, t.trError_gg00); (* PTS 1135036 mb 2005-04-20 *)
        kb391InvalidateSaveIterator; (* PTS 1133376 mb 2005-01-14 *)
        IF  t.trError_gg00 = e_ok
        THEN
            BEGIN
            k38closeasyn (t, glob, NOT c_auto_load, NOT c_force_rewind,
                  c_autosave_tape_device, tpd_is_open, tpd_fno);
            IF  tpd_mirror_index > 0
            THEN
                BEGIN
                IF  t.trError_gg00 <> e_ok
                THEN
                    BEGIN
                    aux_err  := t.trError_gg00;
                    t.trError_gg00 := e_ok
                    END;
                (*ENDIF*) 
                k38closeasyn (t, glob, NOT c_auto_load,
                      NOT c_force_rewind, tpd_mirror_index,
                      sta_tape^ [tpd_mirror_index].tpd_is_open,
                      sta_tape^ [tpd_mirror_index].tpd_fno);
                t.trError_gg00 := aux_err;
                END;
            (*ENDIF*) 
            sta_system_state := sta_system_state - [sy_bup_working]
            END;
        (*ENDIF*) 
        IF  is_quick
        THEN
            sta_system_state := sta_system_state - [sy_bup_working];
        (*ENDIF*) 
        IF  t.trError_gg00 <> e_invalid_command
        THEN
            BEGIN
            g01optextmsg (sp3p_console, sp3m_info, kbCancelAutoSave_csp03,
                  csp3_n_autosave, c_standby_off);
            kb38SendEventAutosave (StandbyOff_ekb38, tpd_name)
            END;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
vendexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
t01basis_error (kb_save, 'end k38e_aut', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38err_to_vtrace (
            VAR t             : tgg00_TransContext;
            glob              : tkb3_save_static_ptr;
            msg               : tsp00_Sname;
            VAR errtext       : tsp00_ErrText);
 
VAR
      b_err : tsp00_IntMapC2;
      pos   : integer;
      ln    : tsp00_Line;
 
BEGIN
(* outside region *)
b_err.mapInt_sp00 := t.trError_gg00;
ln [1] := chr (ord (kb38rte_errtext));
ln [2] := b_err.mapC2_sp00 [1];
ln [3] := b_err.mapC2_sp00 [2];
pos    := 4;
SAPDB_PascalMove ('VKB38 ',   1,    
      sizeof (msg), sizeof (ln), @msg, 1, @ln, pos, sizeof (msg), t.trError_gg00);
pos := pos + sizeof (msg);
SAPDB_PascalMove ('VKB38 ',   2,    
      sizeof (errtext), sizeof (ln),
      @errtext, 1, @ln, pos, sizeof (errtext), t.trError_gg00);
pos := pos + sizeof (errtext);
IF  glob^.sta_msgtype = m_restore_parallel
THEN
    b120InsertTrace (t, kb, kb38restore_parallel, pos-1, @ln)
ELSE
    (* save parallel OR label handling *)
    b120InsertTrace (t, kb, kb38save_parallel, pos-1, @ln);
(*ENDIF*) 
t.trError_gg00 := b_err.mapInt_sp00
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38get_autosave_medianame (
            TaskId         : tsp00_TaskId;
            VAR media_name : tsp00_C64);
 
VAR
      glob : tkb3_save_static_ptr;
 
BEGIN
glob := @k38globals [ckb3_region_autosave];
vbegexcl (TaskId, g08save0 + glob^.sta_region);
IF  sy_bup_working in glob^.sta_system_state
THEN
    media_name := glob^.sta_media_name
ELSE
    media_name := bsp_c64;
(*ENDIF*) 
vendexcl (TaskId, g08save0 + glob^.sta_region)
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38get_global (
            mess_type : tgg00_MessType;
            VAR glob : tkb3_save_static_ptr);
 
BEGIN
k38globals [ckb3_region_normal].sta_region   := ckb3_region_normal;
k38globals [ckb3_region_autosave].sta_region := ckb3_region_autosave;
IF  mess_type = m_autosave
THEN
    BEGIN
    glob := @k38globals [ckb3_region_autosave];
    IF  kb03Check.chkBackup_kb00 (* PTS 1103957 JA 1999-10-11 *)
    THEN
        g01check (kbInvalidRegion_csp03, csp3_n_autosave,
              'region number is invalid',
              glob^.sta_region,
              glob^.sta_region = ckb3_region_autosave);
    (*ENDIF*) 
    END
ELSE
    BEGIN
    glob := @k38globals [ckb3_region_normal];
    IF  kb03Check.chkBackup_kb00 (* PTS 1103957 JA 1999-10-11 *)
    THEN
        g01check (kbInvalidRegion_csp03, csp3_n_save,
              'region number is invalid',
              ckb3_region_normal,
              ckb3_region_normal = glob^.sta_region);
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38get_state (
            buf_size         : tsp00_Int4;
            VAR buf_len      : tsp00_Int4;
            VAR buffer       : tsp00_MoveObj);
 
VAR
      glob : tkb3_save_static_ptr;
      aux  : tsp00_BufAddr;
 
BEGIN
(* PTS 1000397 UH *)
glob := @k38globals [ckb3_region_normal];
aux  := @buffer;
kb38build_userinfo (cgg_nil_pid, glob,
      c_is_get_state, NOT c_label_handling,
      ckb3_nil_tape_no, ckb3_nil_tape_no, glob^.sta_info,
      aux^, buf_size, buf_len)
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38headmaster (VAR m : tgg00_MessBlock);
 
VAR
      glob                : tkb3_save_static_ptr;
      restoreLogIsAborted : boolean; (* PTS 1123675 UH 2003-08-20 *)
 
BEGIN
m.mb_trns^.trError_gg00 := e_ok;
k38get_global (m.mb_type, glob);
IF  glob^.sta_msgtype = m_nil       (* PTS 1001678 UH 04-11-1998 *)
THEN
    glob^.sta_msgtype := m.mb_type; (* PTS 1001678 UH 04-11-1998 *)
(*ENDIF*) 
restoreLogIsAborted := (* PTS 1123675 UH 2003-08-20 *)
      (m.mb_type2 = mm_abort)
      AND
      (glob^.sta_msgtype  = m_restore_parallel)
      AND
      (glob^.sta_msg2type = mm_log);
IF  (m.mb_type2 <> mm_fread)
    AND
    NOT (sy_bup_working in glob^.sta_system_state)
THEN
    (* PTS 1108479 UH 2000-11-27 *)
    m.mb_trns^.trError_gg00 := e_backup_not_running
ELSE
    CASE m.mb_type2 OF
        mm_abort:
            IF  glob^.sta_coordinator_taskid <> m.mb_trns^.trTaskId_gg00
            THEN
                m.mb_trns^.trError_gg00 := e_dbm_command_not_possible (* PTS 1134753 UH 2005-04-07 *)
            ELSE
                WITH glob^ DO
                    BEGIN
                    vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
                    sta_to_cancel := @m.mb_trns^.trRteCommPtr_gg00^.to_cancel;
                    m.mb_trns^.trError_gg00 := e_cancelled; (* PTS 1123675 UH 2003-08-20 *)
                    IF  (sta_msgtype  = m_restore_parallel)
                        AND
                        (sta_msg2type = mm_log)
                    THEN
                        sta_system_state := sta_system_state +
                              [sy_error, sy_knockoffwork];
                    (*ENDIF*) 
                    kb38abort_handling (m.mb_trns^, glob);
                    (* clear all states *)
                    kb38glob_init (glob, glob^.sta_msgtype, glob^.sta_msg2type);
                    vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + sta_region);
                    m.mb_trns^.trError_gg00 := e_ok; (* PTS 1123676 UH 2003-08-25 *)
                    m.mb_struct := mbs_nil;
                    m.mb_type   := m_return_result;
                    m.mb_type2  := mm_nil
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
        mm_database, mm_pages, mm_log,
        mm_ignore, mm_newtape:
            IF  glob^.sta_coordinator_taskid <> m.mb_trns^.trTaskId_gg00
            THEN
                m.mb_trns^.trError_gg00 := e_dbm_command_not_possible (* PTS 1134753 UH 2005-04-07 *)
            ELSE
                kb38parallel_backup (m, glob);
            (*ENDIF*) 
        mm_fread:
            kb38label_handling (m, glob);
        OTHERWISE
            BEGIN
            k38sys_msg (glob, sp3m_error, kbInvalidCall_csp03,
                  c_invalid_call, ord (m.mb_type2));
            m.mb_trns^.trError_gg00 := e_invalid
            END
        END;
    (*ENDCASE*) 
(*ENDIF*) 
IF  restoreLogIsAborted (* PTS 1123675 UH 2003-08-20 *)
THEN
    (* An user-aborted restore is no error. I.e. the user expects an OK as result *)
    (* PTS 1136948 mb 2005-07-28 *)
    gg999Offline (e_ok);
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38history_write (
            glob             : tkb3_save_static_ptr;
            taskId           : tsp00_TaskId;
            errtext_tape_no  : tsp00_Int2;
            err              : tgg00_BasisError);
 
CONST
      c_sep     = '|';
      c_minus   = '-';
      c_one     = '1';
      c_num_len = 10 (* NUMBER_MXSP00 *);
 
TYPE
 
      t_aux_str = RECORD
            CASE integer OF
                1:
                    (err         : tsp00_ErrText);
                2:
                    (ln          : tsp00_Line);
                3:
                    (restoreKind : tsp00_C10);
                4:
                    (tapeLabel   : tsp00_C14);
                5:
                    (consistent  : tsp00_C10);
                END;
            (*ENDCASE*) 
 
 
VAR
      aux_err    : tgg00_BasisError;
      verr       : tsp00_VfReturn;
      entry_len  : tsp00_Int4;
      aux        : t_aux_str;
      curr_entry : tsp00_Buf;
 
BEGIN
IF  err <> e_no_log_to_save
THEN
    BEGIN
    IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
    THEN
        g08check_excl (g08save0 + glob^.sta_region);
    (*ENDIF*) 
    aux_err   := err;
    err       := e_ok;
    entry_len := sizeof (glob^.sta_utilcmd_id.utidId_gg00);         (* PTS 1000431 UH *)
    SAPDB_PascalMove ('VKB38 ',   3,    
          sizeof (glob^.sta_utilcmd_id.utidId_gg00), sizeof (curr_entry),
          @glob^.sta_utilcmd_id.utidId_gg00, 1, @curr_entry, 1,
          entry_len , err);                             (* PTS 1000431 UH *)
    entry_len              := sizeof (glob^.sta_utilcmd_id.utidId_gg00) + 1; (* PTS 1000431 UH *)
    curr_entry [entry_len] := c_sep;                    (* PTS 1000431 UH *)
    kb38set_label (glob^.sta_msg2type, glob^.sta_info.inf_file_version, aux.tapeLabel, err);
    SAPDB_PascalMove ('VKB38 ',   4,    
          sizeof (aux.tapeLabel), sizeof (curr_entry),
          @aux.tapeLabel, 1, @curr_entry, entry_len + 1,
          c_kern_label_len, err);                       (* PTS 1000431 UH *)
    entry_len              := entry_len + c_kern_label_len + 1; (* PTS 1000431 UH *)
    curr_entry [entry_len] := c_sep;
    (**)
    WITH  glob^, sta_info DO
        BEGIN
        kb38save_restore_kind (sta_msgtype, sta_is_cold, aux.restoreKind);
        SAPDB_PascalMove ('VKB38 ',   5,    
              sizeof (aux.restoreKind), sizeof (curr_entry),
              @aux.restoreKind, 1, @curr_entry, entry_len + 1, 9, err);
        entry_len              := entry_len + 9 + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        kb38his_date_write (inf_dbstamp1_date, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := ' ';
        kb38his_time_write (inf_dbstamp1_time, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        kb38his_date_write (inf_dbstamp2_date, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := ' ';
        kb38his_time_write (inf_dbstamp2_time, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        kb38his_date_write (inf_start_date, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := ' ';
        kb38his_time_write (inf_start_time, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        IF  (sta_msgtype = m_restore_parallel)
            OR
            (inf_end_date = bsp_date) (* PTS 1104918 UH 09-12-1999 *)
        THEN
            vdattime (inf_end_date, inf_end_time);
        (*ENDIF*) 
        kb38his_date_write (inf_end_date, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := ' ';
        kb38his_time_write (inf_end_time, entry_len, curr_entry);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        IF  kb560IsValidIOSeq(inf_first_iosequence)
        THEN
            BEGIN
            gg06UInt4toLine(inf_first_iosequence, c_num_len, aux.ln);(* PTS 1124724 mb 2003-11-06 *)
            SAPDB_PascalMove ('VKB38 ',   6,    
                  sizeof (aux.ln), sizeof (curr_entry),
                  @aux.ln, 1, @curr_entry, entry_len + 1, c_num_len, err);
            entry_len              := entry_len + c_num_len + 1;
            curr_entry [entry_len] := c_sep;
            END
        ELSE
            BEGIN
            SAPDB_PascalFill ('VKB38 ',   7,    
                  sizeof (curr_entry), @curr_entry, entry_len+ 1, c_num_len, ' ', err);
            entry_len              := entry_len + c_num_len + 1;
            IF  sta_msg2type <> mm_log
            THEN(* PTS 1129712 mb 2004-05-21 *)
                BEGIN
                curr_entry [entry_len-2] := c_minus;
                curr_entry [entry_len-1] := c_one
                END;
            (*ENDIF*) 
            curr_entry [entry_len] := c_sep
            END;
        (*ENDIF*) 
        IF  (sta_msg2type = mm_log) AND kb560IsValidIOSeq(inf_last_iosequence)
        THEN
            BEGIN
            gg06UInt4toLine(inf_last_iosequence, c_num_len, aux.ln);(* PTS 1124724 mb 2003-11-06 *)
            SAPDB_PascalMove ('VKB38 ',   8,    
                  sizeof (aux.ln), sizeof (curr_entry), @aux.ln, 1,
                  @curr_entry, entry_len + 1, c_num_len, err);
            entry_len              := entry_len + c_num_len + 1;
            curr_entry [entry_len] := c_sep
            END
        ELSE
            BEGIN
            SAPDB_PascalFill ('VKB38 ',   9,    
                  sizeof (curr_entry), @curr_entry, entry_len+ 1, c_num_len, ' ', err);
            entry_len              := entry_len + c_num_len + 1;
            curr_entry [entry_len] := c_sep
            END;
        (*ENDIF*) 
        (**)
        IF  sta_msg2type = mm_log
        THEN
            aux.consistent     := '          '
        ELSE
            BEGIN
            IF  inf_is_consistent
            THEN
                aux.consistent := 'NO        '
            ELSE
                aux.consistent := 'YES       '
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        SAPDB_PascalMove ('VKB38 ',  10,    
              sizeof (aux.consistent), sizeof (curr_entry),
              @aux.consistent, 1, @curr_entry, entry_len + 1, 3, err);
        entry_len              := entry_len + 3 + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        kb38his_media_write (glob, entry_len, curr_entry, err);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        g17int4to_line (sta_pages_transferred, NOT c_with_zeros,
              c_num_len, 1, aux.ln);
        SAPDB_PascalMove ('VKB38 ',  11,    
              sizeof (aux.ln), sizeof (curr_entry), @aux.ln, 1,
              @curr_entry, entry_len + 1, c_num_len, err);
        entry_len              := entry_len + c_num_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        g17int4to_line (inf_max_volume_no, NOT c_with_zeros,
              c_num_len, 1, aux.ln);
        SAPDB_PascalMove ('VKB38 ',  12,    
              sizeof (aux.ln), sizeof (curr_entry), @aux.ln, 1,
              @curr_entry, entry_len + 1, c_num_len, err);
        entry_len              := entry_len + c_num_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        g17int4to_line (a071_return_code (aux_err, sqlm_internal),
              NOT c_with_zeros, c_num_len, 1, aux.ln);
        SAPDB_PascalMove ('VKB38 ',  13,    
              sizeof (aux.ln), sizeof (curr_entry), @aux.ln, 1,
              @curr_entry, entry_len + 1, c_num_len, err);
        entry_len              := entry_len + c_num_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        kb38his_errtext_write (glob, entry_len, curr_entry, errtext_tape_no,err);
        entry_len              := entry_len + 1;
        curr_entry [entry_len] := c_sep;
        (**)
        END;
    (*ENDWITH*) 
    verr    := vf_ok;
    aux.err := bsp_errtext;
    kb38append_to_backup_history (taskId, curr_entry, entry_len, verr, aux.err);
&   ifdef TRACE
    t01int4 (kb_save, 'kb38wrbckhis', ord(verr));
&   endif
    IF  aux_err <> e_ok
    THEN
        err := aux_err
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38history_error_write (
            taskId         : tsp00_TaskId;
            VAR utilcmd_id : tgg00_UtilCmdId;
            save_type1 : tgg00_MessType;
            save_type2 : tgg00_MessType2;
            is_cold    : boolean;
            backup_no  : tsp00_Int4;
            err_reason : tgg00_BasisError);
 
VAR
      AuxErr       : tgg00_BasisError;
      SrcBufferLen : tsp00_Int4;
      VErr         : tsp00_VfReturn;
      pLine        : ^tsp00_Line;
      pShortString : ^tsp00_C14;
      pRestoreKind : ^tsp00_C10;
      pSrcBuffer   : tsp00_BufAddr;
      Buffer       : tsp00_Buf;
      AuxErrText   : tsp00_ErrText;
 
BEGIN
AuxErr := e_ok;
SAPDB_PascalFill ('VKB38 ',  14,    
      sizeof (Buffer), @Buffer, 1, MAX_HIST_ENTRY_LEN, ' ', AuxErr);
Buffer [POS_LABEL          -1] := CSEP;
Buffer [POS_SAVE_KIND      -1] := CSEP;
Buffer [POS_DBSTAMP1       -1] := CSEP;
Buffer [POS_DBSTAMP2       -1] := CSEP;
Buffer [POS_START_DATE     -1] := CSEP;
Buffer [POS_END_DATE       -1] := CSEP;
Buffer [POS_FIRST_IOSEQUENCE     -1] := CSEP;
Buffer [POS_LAST_IOSEQUENCE      -1] := CSEP;
Buffer [POS_LOG_NEEDED     -1] := CSEP;
Buffer [POS_MEDIA_NAME     -1] := CSEP;
Buffer [POS_TRANSF_PAGES   -1] := CSEP;
Buffer [POS_MAX_VOL_COUNT  -1] := CSEP;
Buffer [POS_RETURN_CODE    -1] := CSEP;
Buffer [POS_ERRTEXT        -1] := CSEP;
Buffer [MAX_HIST_ENTRY_LEN -1] := CSEP;
(* --------- *)
pSrcBuffer   := @utilcmd_id;
SrcBufferLen := sizeof (utilcmd_id.utidId_gg00); (* PTS 1113171 *)
SAPDB_PascalMove ('VKB38 ',  15,    
      SrcBufferLen, MAX_HIST_ENTRY_LEN,
      @pSrcBuffer^, 1, @Buffer, POS_UTILCMD, SrcBufferLen, AuxErr);
(* --------- *)
pShortString := @Buffer[POS_LABEL];
kb38set_label (save_type2, backup_no, pShortString^, AuxErr);
Buffer [POS_SAVE_KIND - 1] := CSEP;
(* --------- *)
pRestoreKind := @Buffer[POS_SAVE_KIND];
kb38save_restore_kind (save_type1, is_cold, pRestoreKind^);
Buffer [POS_DBSTAMP1 - 1] := CSEP;
(* --------- *)
pLine        := @Buffer[POS_RETURN_CODE];
g17int4to_line (a071_return_code (err_reason, sqlm_internal), NOT c_with_zeros, NUM_LEN, 1, pLine^);
(* --------- *)
IF  AuxErr = e_ok
THEN
    BEGIN
    VErr       := vf_ok;
    AuxErrText := bsp_errtext;
    kb38append_to_backup_history (taskId, Buffer, MAX_HIST_ENTRY_LEN, VErr, AuxErrText)
    END;
&ifdef TRACE
(*ENDIF*) 
t01int4 (kb_save, 'vbackup_erro', ord(VErr));
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38history_lost_write (taskId : tsp00_TaskId);
 
VAR
      UtilIdStr    : tgg00_UtilCmdId;
      AuxErr       : tgg00_BasisError;
      SrcBufferLen : tsp00_Int4;
      VErr         : tsp00_VfReturn;
      pLine        : ^tsp00_Line;
      pShortString : ^tsp00_C10;
      pSrcBuffer   : tsp00_BufAddr;
      Buffer       : tsp00_Buf;
      AuxErrText   : tsp00_ErrText;
      start_date   : tsp00_Date;
      start_time   : tsp00_Time;
 
BEGIN
(* PTS 1105284 UH 17-01-2000 new *)
AuxErr := e_ok;
SAPDB_PascalFill ('VKB38 ',  16,    
      sizeof (Buffer), @Buffer, 1, MAX_HIST_ENTRY_LEN, ' ', AuxErr);
Buffer [POS_LABEL          -1] := CSEP;
Buffer [POS_SAVE_KIND      -1] := CSEP;
Buffer [POS_DBSTAMP1       -1] := CSEP;
Buffer [POS_DBSTAMP2       -1] := CSEP;
Buffer [POS_START_DATE     -1] := CSEP;
Buffer [POS_END_DATE       -1] := CSEP;
Buffer [POS_FIRST_IOSEQUENCE     -1] := CSEP;
Buffer [POS_LAST_IOSEQUENCE      -1] := CSEP;
Buffer [POS_LOG_NEEDED     -1] := CSEP;
Buffer [POS_MEDIA_NAME     -1] := CSEP;
Buffer [POS_TRANSF_PAGES   -1] := CSEP;
Buffer [POS_MAX_VOL_COUNT  -1] := CSEP;
Buffer [POS_RETURN_CODE    -1] := CSEP;
Buffer [POS_ERRTEXT        -1] := CSEP;
Buffer [MAX_HIST_ENTRY_LEN -1] := CSEP;
(* --------- *)
gg999GetNewCommandId (taskId, UtilIdStr);
pSrcBuffer   := @UtilIdStr.utidId_gg00;
SrcBufferLen := sizeof (UtilIdStr.utidId_gg00);
SAPDB_PascalMove ('VKB38 ',  17,    
      SrcBufferLen, MAX_HIST_ENTRY_LEN,
      @pSrcBuffer^, 1, @Buffer, POS_UTILCMD, SrcBufferLen, AuxErr);
(* --------- *)
pShortString  := @Buffer[POS_SAVE_KIND];
pShortString^ := 'HISTLOST  ';
Buffer [POS_DBSTAMP1 - 1] := CSEP;
(* --------- *)
vdattime (start_date, start_time);
SrcBufferLen := POS_START_DATE-1;
kb38his_date_write (start_date, SrcBufferLen, Buffer);
SrcBufferLen := SrcBufferLen + 1;
kb38his_time_write (start_time, SrcBufferLen, Buffer);
(* --------- *)
pLine := @Buffer[POS_RETURN_CODE];
g17int4to_line (a071_return_code (e_ok, sqlm_internal), NOT c_with_zeros, NUM_LEN, 1, pLine^);
(* --------- *)
IF  AuxErr = e_ok
THEN
    BEGIN
    VErr       := vf_ok;
    AuxErrText := bsp_errtext;
    kb38append_to_backup_history (taskId, Buffer, MAX_HIST_ENTRY_LEN, VErr, AuxErrText)
    END;
&ifdef TRACE
(*ENDIF*) 
t01int4 (kb_save, 'vbackup_erro', ord(VErr));
&endif
END;
 
(*------------------------------*) 
 
FUNCTION
      k38is_backup_running : boolean;
 
VAR
      glob : tkb3_save_static_ptr;
 
BEGIN
(* PTS 1106632 UH 20000517 new *)
k38get_global (m_save_parallel, glob);
(* outside region *)
k38is_backup_running := sy_bup_working in glob^.sta_system_state;
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38ReserveBackupServerTasks (VAR trans : tgg00_TransContext);
 
VAR
      glob : tkb3_save_static_ptr;
 
BEGIN
trans.trError_gg00 := e_ok;
k38get_global (m_save_parallel, glob);
vbegexcl (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  glob^.sta_backup_server = NIL
THEN
    IF  NOT kb900CreateBackupServer (glob^.sta_backup_server,
        false, g01no_of_backup_devs, bd999MaxConfigurableDataVolumes,
        trans.trTaskId_gg00, trans.trErrorList_gg00)
    THEN
        trans.trError_gg00 := e_start_server_task_error;
    (*ENDIF*) 
(*ENDIF*) 
vendexcl (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  trans.trError_gg00 = e_ok
THEN
    BEGIN
    k38get_global (m_autosave, glob);
    vbegexcl (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
    IF  glob^.sta_backup_server = NIL
    THEN
        IF  NOT kb900CreateBackupServer (glob^.sta_backup_server,
            true, 1, c_autosave_maxdatadevs, trans.trTaskId_gg00, trans.trErrorList_gg00)
        THEN
            trans.trError_gg00 := e_start_server_task_error;
        (*ENDIF*) 
    (*ENDIF*) 
    vendexcl (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38i_autosave_init (VAR m  : tgg00_MessBlock);
 
CONST
      c_num_tapes = 1;
 
VAR
      tape_was_full : boolean;
      tape_pid      : tsp00_TaskId;
      glob          : tkb3_save_static_ptr;
      aux_errtext   : tsp00_ErrText;
 
BEGIN
m.mb_trns^.trError_gg00 := e_ok;
tape_was_full           := false;
k560check_logsave_allowed (m.mb_trns^.trTaskId_gg00,m.mb_trns^.trError_gg00);
k38get_global (m.mb_type, glob);
glob^.sta_tape^[c_autosave_tape_device].tpd_errtext  := bsp_c40;
vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    (glob^.sta_backup_server = NIL)
THEN
    IF  NOT kb900CreateBackupServer (glob^.sta_backup_server,
        true, 1, c_autosave_maxdatadevs,
        m.mb_trns^.trTaskId_gg00, m.mb_trns^.trErrorList_gg00)
    THEN
        m.mb_trns^.trError_gg00 := e_internal_error;
    (*ENDIF*) 
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    IF  sy_bup_working in glob^.sta_system_state
    THEN
        BEGIN
        IF  glob^.sta_task_for_conttape > 0
        THEN
            BEGIN
&           ifdef TRACE
            t01int4 (kb_save, 'Continue:   ', glob^.sta_conttape);
&           endif
            tape_was_full := true
            END
        ELSE
            m.mb_trns^.trError_gg00 := e_autosave_running
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        kb38glob_init (glob, m_autosave, mm_log);
        kb38info_init (glob, glob^.sta_info);
        WITH glob^.sta_info DO
            BEGIN
            inf_mess_type  := m_autosave;
            inf_mess2_type := mm_log;
            inf_tapes_used := c_num_tapes
            END
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    kb391InputParameters(m,glob);
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    WITH glob^, m.mb_qual^.msave_restore DO
        BEGIN
        (* Initialization of the following tape operations *)
        sta_system_state := sta_system_state + [sy_bup_working];
        sta_is_auto_load := sripIsAutoLoad_gg00;
        sta_blocksize    := m.mb_qual^.msave_restore.sripBlocksize_gg00;
        sta_num_devsp    := ckb3_log_devsp_no;
        sta_num_tapes    := c_num_tapes;
        IF  sripUntilDate_gg00 <> bsp_date
        THEN
            sta_until_date := sripUntilDate_gg00;
        (*ENDIF*) 
        IF  sripMedianame_gg00 <> bsp_c64
        THEN
            sta_media_name := sripMedianame_gg00;
        (*ENDIF*) 
        WITH sta_tape^ [c_autosave_tape_device] DO
            BEGIN
            tpd_fno               := 0;
            tpd_volume_no         := 0;
            IF  tape_was_full
            THEN
                tpd_volume_no     := tpd_volume_no + 1
            ELSE
                tpd_volume_no     := 0;
            (*ENDIF*) 
            tpd_total_cnt_pages   := 0;
            tpd_is_open           := false;
            tpd_is_full           := false;
            tpd_is_replaced       := false; (* PTS 1109736 mb 2002-09-23 *)
            tpd_is_clustered      := sta_info.inf_is_clustered;
            tpd_type              := sripHostFiletypes_gg00 [1];
            tpd_check_destructive := true; (* PTS 1000360 UH *)
            tpd_max_pages         := sripHostTapecount_gg00 [1]; (* PTS 1109213 UH 2001-02-05 *)
            tpd_name              := sripHostTapenames_gg00 [1];
            tpd_err               := e_ok;
            (* tpd_errtext initialized before because History_Write needs it allways *)
            tpd_mirror_index      := 0;
            IF  tpd_type = vf_t_file
            THEN
                BEGIN
                IF  NOT tape_was_full
                THEN
                    sta_file_version := MAX_INT4_SP00;
                (* ELSE sta_file_version is the old one *)
                (*ENDIF*) 
                kb38add_version_to_filename (tpd_name, sta_file_version,
                      m.mb_trns^.trError_gg00)
                END
            ELSE
                sta_file_version := 0
            (*ENDIF*) 
            END
        (*ENDWITH*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    ((glob^.sta_tape^ [c_autosave_tape_device].tpd_type <> vf_t_file)
    OR tape_was_full)
THEN
    kb38open_autosave_tape (m.mb_trns^, glob, c_autosave_tape_device);
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    (m.mb_qual^.msave_restore.sripHostTapeNum_gg00 > 1)
THEN
    (* init the mirror tape *)
    WITH glob^, m.mb_qual^.msave_restore,
         sta_tape^ [c_autosave_mirr_device] DO
        BEGIN
        tpd_name := sripHostTapenames_gg00 [2];
        tpd_type := sripHostFiletypes_gg00 [2];
        IF  sta_file_version > 0
        THEN
            kb38add_version_to_filename (tpd_name, sta_file_version,
                  m.mb_trns^.trError_gg00);
        (*ENDIF*) 
        IF  (m.mb_trns^.trError_gg00 = e_ok)
            AND
            ((tpd_type <> vf_t_file) OR tape_was_full)
        THEN
            kb38open_autosave_tape (m.mb_trns^, glob,
                  c_autosave_mirr_device);
        (*ENDIF*) 
        IF  m.mb_trns^.trError_gg00 = e_ok
        THEN
            sta_tape^ [c_autosave_tape_device].tpd_mirror_index :=
                  c_autosave_mirr_device
        ELSE
            sta_tape^ [c_autosave_tape_device].tpd_errtext :=
                  tpd_errtext;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_ok) AND NOT tape_was_full
THEN
    BEGIN
    g01optextmsg (sp3p_console, sp3m_info, kb38InitAutoSave_csp03,
          csp3_n_autosave, c_standby_on);
    kb38SendEventAutosave (StandbyOn_ekb38, glob^.sta_tape^ [c_autosave_tape_device].tpd_name)
    END;
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    WITH glob^ DO
        BEGIN
        IF  tape_was_full AND (sta_task_for_conttape > 0)
        THEN
            BEGIN
            tape_pid := sta_task^[sta_task_for_conttape].tsd_task_pid;
            IF  tape_pid <> cgg_nil_pid
            THEN
                BEGIN
&               ifdef TRACE
                t01int4 (kb_save, 'resume:     ', tape_pid) ;
&               endif
                (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
                vresume (tape_pid);
                (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
                END
            ELSE
                m.mb_trns^.trError_gg00 := e_invalid
            (*ENDIF*) 
            END
        ELSE
            k38trigger_autosave (m.mb_trns^, c_in_region)
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 <> e_ok)
    AND
    (m.mb_trns^.trError_gg00 <> e_autosave_running)
    AND
    NOT tape_was_full
THEN
    WITH glob^.sta_tape^ [c_autosave_tape_device] DO
        BEGIN
        kb38history_write (glob,m.mb_trns^.trTaskId_gg00, c_autosave_tape_device,
              m.mb_trns^.trError_gg00);
        aux_errtext := tpd_errtext;
        (* clear all states - tapes are already closed if error *)
        kb38glob_init (glob, m_autosave, mm_log);
        tpd_errtext := aux_errtext;
        tpd_is_full := tape_was_full;
        tpd_err     := m.mb_trns^.trError_gg00
        END;
    (*ENDWITH*) 
(*ENDIF*) 
vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
t01basis_error (kb_save, 'end auto ini', m.mb_trns^.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38init_restore (
            VAR m         : tgg00_MessBlock;
            is_check_save : boolean);
 
VAR
      i    : integer;
      glob : tkb3_save_static_ptr;
 
BEGIN
m.mb_trns^.trError_gg00 := e_ok;
k38get_global (m.mb_type, glob);
vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    (glob^.sta_backup_server = NIL)
THEN
    IF  NOT kb900CreateBackupServer (glob^.sta_backup_server,
        false, g01no_of_backup_devs, bd999MaxConfigurableDataVolumes,
        m.mb_trns^.trTaskId_gg00, m.mb_trns^.trErrorList_gg00)
    THEN
        m.mb_trns^.trError_gg00 := e_internal_error;
    (*ENDIF*) 
(*ENDIF*) 
glob^.sta_msgtype := m.mb_type;
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    (* reset all states *)
    kb38glob_init (glob, m.mb_type, m.mb_type2);
    kb391InputParameters (m, glob);
    kb38info_init (glob, glob^.sta_info);
    END;
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    WITH glob^, m.mb_qual^.msave_restore DO
        BEGIN
        sta_check_save     := is_check_save;
&       ifdef TRACE
        t01bool (kb_save, 'CHECK SAVE  ', sta_check_save);
&       endif
        sta_msgtype          := m.mb_type;
        sta_msg2type         := m.mb_type2;
        sta_vtr_direction    := kb38restore_parallel;
        sta_until_date       := sripUntilDate_gg00;
        sta_until_time       := sripUntilTime_gg00;
        sta_until_iosequence := sripUntilIOSequence_gg00;
        sta_is_auto_load     := sripIsAutoLoad_gg00;
        sta_is_cold          := true;
        sta_utilcmd_id       := sripUtilCmdId_gg00; (* PTS 1104845 UH 02-12-1999 *)
        sta_coordinator_taskid := m.mb_trns^.trTaskId_gg00; (* PTS 1134753 UH 2005-04-07 *)
        sta_blocksize        := sripBlocksize_gg00;
        sta_num_tapes        := sripHostTapeNum_gg00;
        CASE sta_msg2type OF
            mm_log:
                BEGIN
                sta_num_devsp := ckb3_log_devsp_no;
                IF  sta_num_tapes > c_max_log_restore_tapes
                THEN
                    BEGIN
                    m.mb_trns^.trError_gg00 := e_invalid_configuration;
                    g01optextmsg (sp3p_console, sp3m_error,
                          kb38InvalidConfig_csp03, (* PTS 1000283 UH *)
                          csp3_n_restore, c_too_many_log_tapes)
                    END;
                (*ENDIF*) 
                END;
            mm_database, mm_pages:
                BEGIN
                sta_tape_label := sripTapeLabel_gg00; (* PTS 1128100 mb 2004-03-01 *)
                sta_num_devsp  := b01no_of_data_devs;
                END
            END;
        (*ENDCASE*) 
        FOR i := 1 TO sta_num_tapes DO
            WITH sta_tape^[i] DO
                BEGIN
                tpd_name := sripHostTapenames_gg00 [i];
                tpd_type := sripHostFiletypes_gg00 [i] (* PTS 1000615 UH *)
                END;
            (*ENDWITH*) 
        (*ENDFOR*) 
        IF  sripMedianame_gg00 <> bsp_c64
        THEN
            sta_media_name := sripMedianame_gg00;
        (*ENDIF*) 
        sta_system_state := sta_system_state + [sy_bup_working]
        END;
    (*ENDWITH*) 
(*ENDIF*) 
vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38init_save (
            VAR m                  : tgg00_MessBlock;
            is_cold                : boolean;
            complete_log           : boolean;
            destructive_tape_check : boolean);
 
VAR
      i         : integer;
      tape_no   : tsp00_Int2;
      glob      : tkb3_save_static_ptr;
      errortext : tsp00_ErrText;
 
BEGIN
m.mb_trns^.trError_gg00 := e_ok;
m.mb_type := m_save_parallel;
k38get_global (m.mb_type, glob);
vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    (sy_bup_working in glob^.sta_system_state)
THEN
    (* PTS 1108479 UH 2000-11-27 *)
    m.mb_trns^.trError_gg00 := e_backup_is_running;
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    (glob^.sta_backup_server = NIL)
THEN
    IF  NOT kb900CreateBackupServer (glob^.sta_backup_server,
        false, g01no_of_backup_devs, bd999MaxConfigurableDataVolumes,
        m.mb_trns^.trTaskId_gg00, m.mb_trns^.trErrorList_gg00)
    THEN
        m.mb_trns^.trError_gg00 := e_internal_error;
    (*ENDIF*) 
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_ok)
    AND
    NOT (sy_initialized in glob^.sta_system_state)
THEN
    kb38glob_init (glob, m_nil, mm_nil);
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    kb391InputParameters (m, glob);
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    WITH glob^ DO
        BEGIN
        sta_msgtype        := m_save_parallel;
        sta_msg2type       := m.mb_type2;
        sta_vtr_direction  := kb38save_parallel;
        sta_is_cold        := is_cold;
        END;
    (*ENDWITH*) 
    WITH glob^, sta_info, m.mb_trns^, m.mb_qual^.msave_restore DO
        BEGIN
        sta_coordinator_taskid := m.mb_trns^.trTaskId_gg00; (* PTS 1134753 UH 2005-04-07 *)
        sta_utilcmd_id     := sripUtilCmdId_gg00; (* PTS 1104845 UH 02-12-1999 *)
        sta_is_auto_load   := sripIsAutoLoad_gg00;
        sta_blocksize      := sripBlocksize_gg00;
        sta_no_release_log := sripNoReleaseLog_gg00; (* PTS 1128703 mb 2004-05-05 *)
        (* *)
        kb38info_init (glob, glob^.sta_info);
        (* *)
        inf_mess_type      := m_save_parallel;
        inf_mess2_type     := m.mb_type2;
        CASE sta_msg2type OF
            mm_log:
                kb38init_log_save (m.mb_trns^, glob,
                      sripOnlyCompleteSegments_gg00, (* PTS 1131132 UH 2004-09-01 *)
                      complete_log); (* PTS 1000360 UH *)
            mm_database, mm_pages:
                BEGIN
                sta_write_bitmap_pages := sta_msg2type = mm_pages;
                sta_write_conv_pages   := (sta_msg2type = mm_database) AND ( g01is_archive );
                sta_num_devsp          := b01no_of_data_devs;
                vendexcl (trTaskId_gg00, g08save0 + sta_region);
                IF  sta_msg2type = mm_database
                THEN
                    gg999NewDBIdentIfHistoryLost (trTaskId_gg00)
                ELSE
                    (* PTS 1118565 mb 2002-10-31 reset the Devicestate for SAVE PAGES *)
                    kb560SetDeviceStateOkay (trTaskId_gg00, trError_gg00);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    inf_is_clustered := b11_has_clustered_blocks_for_backup(trTaskId_gg00);
                    IF  inf_is_clustered
                        AND
                        (sta_blocksize < g01backup_block_count)
                        (* AND +++ then in vkb39 there must be A write loop to tape +++
                              ((g01backup_block_count MOD sta_blocksize) > 0) *)
                    THEN
                        BEGIN
                        errortext := 'Cluster info is lost                    ';
                        kb391AppendTapeErrorToMessageList (trTaskId_gg00, false, false, 1,
                              sripHostTapenames_gg00[1], errortext);
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                vbegexcl (trTaskId_gg00, g08save0 + sta_region);
                IF  m.mb_trns^.trError_gg00 = e_ok
                THEN
                    BEGIN
                    IF  sta_is_cold
                    THEN
                        sta_data_rst_rec^ := k57restartrec^
                    ELSE
                        BEGIN
                        k57frozen_restartrec^.rstDbIdent_kb00 := k57restartrec^.rstDbIdent_kb00;
                        sta_data_rst_rec^ := k57frozen_restartrec^;
                        END;
                    (*ENDIF*) 
                    WITH sta_data_rst_rec^ DO
                        BEGIN
                        pageCheck_kb00    := chckChecksumLogInfo_egg00;
                        pageChecksum_kb00 := k57calc_checksum (sta_data_rst_rec^);
                        pageTrailer_kb00  := pageHeader_kb00
                        END;
                    (*ENDWITH*) 
                    WITH sta_data_rst_rec^, rstLastSavept_kb00 DO
                        BEGIN
                        rstCurrBackupVersion_kb00 := rstConverterVersion_kb00;
                        IF  (sta_msg2type = mm_database)
                        THEN
                            rstPrevBackupVersion_kb00 := rstConverterVersion_kb00;
&                       ifdef TRACE
                        (*ENDIF*) 
                        t01int4 (kb_save, 'frozen convv',
                              rstConverterVersion_kb00);
&                       endif
                        inf_is_consistent  := true;
                        inf_first_iosequence     := svpIOsequence_kb00;
                        kb560InvalidateIOSeq( inf_last_iosequence ); (* PTS 1116063 mb 2002-06-13 *)
                        inf_file_version   := rstDataBackupCnt_kb00;
                        inf_db_ident       := rstDbIdent_kb00; (* PTS 1000449 UH 19980909 *)
                        g17intdate_time (svpDate_kb00, svpTime_kb00,
                              inf_dbstamp1_date, inf_dbstamp1_time);
                        inf_dbstamp2_date  := inf_dbstamp1_date;
                        inf_dbstamp2_time  := inf_dbstamp1_time;
                        inf_max_used_data_pno := 0;(* not used anymore TS *)
                        END
                    (*ENDWITH*) 
                    END;
                (*ENDIF*) 
                END;
            END;
        (*ENDCASE*) 
        IF  m.mb_trns^.trError_gg00 = e_ok
        THEN
            BEGIN
            kb38set_label (sta_msg2type, inf_file_version,
                  inf_label, m.mb_trns^.trError_gg00);
            sta_num_tapes := 0
            END;
        (*ENDIF*) 
        i := 1;
        WHILE (i <= sripHostTapeNum_gg00) AND (m.mb_trns^.trError_gg00 = e_ok) DO
            BEGIN
            (* search labeled tape OR select next free tape *)
            kb38get_tape_no (glob, sripHostTapenames_gg00 [i], tape_no);
            IF  tape_no <= 0
            THEN
                m.mb_trns^.trError_gg00 := e_wrong_hostfile
            ELSE
                BEGIN
                IF  tape_no > sta_num_tapes
                THEN
                    sta_num_tapes := tape_no;
                (*ENDIF*) 
                WITH sta_tape^[tape_no] DO
                    BEGIN
                    tpd_is_open         := false;
                    tpd_is_full         := false;
                    tpd_is_clustered    := inf_is_clustered;
                    tpd_volume_no       := 0;
                    tpd_fno             := 0;
                    tpd_max_pages       := sripHostTapecount_gg00 [i];
                    tpd_cnt_pages       := 0;
                    tpd_total_cnt_pages := 0;
                    tpd_name            := sripHostTapenames_gg00 [i];
                    tpd_err             := e_ok;
                    tpd_errtext         := bsp_c40;
                    (* user suggested type *)
                    tpd_type            := sripHostFiletypes_gg00 [i];
                    IF  (sta_msg2type = mm_log)
                        AND
                        NOT complete_log (* PTS 1000360 UH *)
                    THEN
                        (* PTS 1000360 UH *)
                        BEGIN
                        tpd_check_destructive := destructive_tape_check;
                        CASE tpd_type OF
                            vf_t_file:
                                BEGIN
                                sta_file_version := inf_file_version; (* PTS 1108809 UH 2000-12-21 *)
                                kb38add_version_to_filename (tpd_name,
                                      inf_file_version, m.mb_trns^.trError_gg00);
                                END;
                            vf_t_tape_norew:
                                BEGIN
                                END;
                            vf_t_pipe:
                                (* PTS 1108438 UH 2000-11-22 *)
                                BEGIN
                                END;
                            OTHERWISE
                                BEGIN
                                g01opmsg (sp3p_console, sp3m_error,
                                      kb38FileTypeInvalid_csp03,
                                      csp3_n_save,
                                      c_type_not_allowed,
                                      ord(tpd_type) );
                                m.mb_trns^.trError_gg00 := e_hostfile_error
                                END
                            END;
                        (*ENDCASE*) 
                        END
                    ELSE
                        IF  m.mb_qual^.msave_restore.sripFileVersion_gg00 = 1
                        THEN
                            IF  tpd_type = vf_t_file
                            THEN
                                kb38add_version_to_filename (tpd_name,
                                      inf_file_version, m.mb_trns^.trError_gg00)
                            ELSE
                                BEGIN
                                m.mb_trns^.trError_gg00 := e_invalid;
                                g01optextmsg (sp3p_console, sp3m_error,
                                      kb38NoFversion_csp03, (* PTS 1000283 UH *)
                                      csp3_n_save, c_fversion_not_allowed)
                                END
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            i := i + 1
            END;
        (*ENDWHILE*) 
        IF  m.mb_trns^.trError_gg00 = e_ok
        THEN
            BEGIN
            IF  sripMedianame_gg00 <> bsp_c64
            THEN
                sta_media_name := sripMedianame_gg00;
            (*ENDIF*) 
            IF  sta_num_tapes > sripHostTapeNum_gg00
            THEN
                (* tapes labeled, but not in hosttape list *)
                m.mb_trns^.trError_gg00 := e_wrong_hostfile
            ELSE
                glob^.sta_info.inf_tapes_used := sta_num_tapes;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (m.mb_trns^.trError_gg00 = e_ok) AND (sta_msg2type = mm_log)
        THEN
            BEGIN
            IF  sta_num_tapes > c_max_log_restore_tapes
            THEN
                BEGIN
                m.mb_trns^.trError_gg00 := e_invalid_configuration;
                g01optextmsg (sp3p_console, sp3m_error,
                      kb38InvalidConfig2_csp03, (* PTS 1000283 UH *)
                      csp3_n_save, c_too_many_log_tapes)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDWITH*) 
    END;
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    WITH glob^ DO
        sta_system_state := sta_system_state + [sy_bup_working];
    (*ENDWITH*) 
(*ENDIF*) 
vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
END;
 
(*------------------------------*) 
 
FUNCTION
      k38is_on_autosave (
            VAR t     : tgg00_TransContext;
            in_region : boolean) : boolean;
 
VAR
      is_on : boolean;
 
BEGIN
is_on := false;
IF  in_region
THEN
    BEGIN
    IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
    THEN
        g08excl_check (t.trTaskId_gg00, g08save0 + ckb3_region_autosave)
    (*ENDIF*) 
    END
ELSE
    vbegexcl (t.trTaskId_gg00, g08save0 + ckb3_region_autosave);
(*ENDIF*) 
WITH k38globals [ckb3_region_autosave] DO
    is_on := (sy_bup_working in sta_system_state);
(*ENDWITH*) 
IF  NOT in_region
THEN
    vendexcl (t.trTaskId_gg00, g08save0 + ckb3_region_autosave);
(*ENDIF*) 
k38is_on_autosave := is_on;
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38restore_config (VAR mblock : tgg00_MessBlock);
 
CONST
      c_tape_no = 1;
 
VAR
      aux_err : tgg00_BasisError;
      glob    : tkb3_save_static_ptr;
 
BEGIN
(* PTS 1103756 UH 1999-09-02 new *)
k38get_global (mblock.mb_type, glob);
WITH mblock, mb_trns^, mb_qual^.msave_restore, glob^, sta_tape^[1] DO
    BEGIN
    trError_gg00 := e_ok;
    (**)
    vbegexcl (trTaskId_gg00, g08save0 + glob^.sta_region);
    (**)
    kb38glob_init (glob, mb_type, mb_type2);
    kb391InputParameters (mblock, glob);
    (**)
    sta_vtr_direction  := kb38restore_parallel;
    sta_is_cold        := true;
    sta_blocksize      := sripBlocksize_gg00;
    sta_num_tapes      := sripHostTapeNum_gg00;
    (**)
    tpd_name           := sripHostTapenames_gg00 [c_tape_no];
    tpd_type           := sripHostFiletypes_gg00 [c_tape_no];
    (**)
    kb38info_init (glob, sta_info);
    (**)
    IF  trError_gg00 = e_ok
    THEN
        k38tapeopen_one (mb_trns^, glob, c_tape_no, NOT c_for_writing, c_for_readlabel);
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        k39restore_config (mb_trns^, glob, sripConfigDbName_gg00);
    (*ENDIF*) 
    IF  tpd_is_open
    THEN
        BEGIN
        aux_err := trError_gg00;
        k38closeasyn (mb_trns^, glob, NOT c_auto_load, c_force_rewind, c_tape_no, tpd_is_open, tpd_fno);
        IF  aux_err <> e_ok
        THEN
            trError_gg00 := aux_err
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        kb38put_errtext (trTaskId_gg00, glob, c_tape_no);
    (**)
    (*ENDIF*) 
    mb_data_len := 0;
    mb_type2    := mm_nil;
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        kb38build_userinfo (trTaskId_gg00, glob,
              NOT c_is_get_state, c_label_handling,
              c_tape_no, c_tape_no, sta_info,
              mb_qual^.buf, mb_qual_size, mb_qual_len);
        mb_struct   := mbs_buf;
        mb_type     := m_return_result
        END
    ELSE
        BEGIN
        mb_qual_len := 0;
        mb_struct   := mbs_nil;
        mb_type     := m_return_error
        END;
    (*ENDIF*) 
    (**)
    kb38glob_init (glob, m_nil, mm_nil);
    (**)
    vendexcl (trTaskId_gg00, g08save0 + glob^.sta_region);
    (**)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38set_not_generated;
 
BEGIN
(* outside region *)
k38globals [ckb3_region_normal  ].sta_system_state := [ ];
k38globals [ckb3_region_normal  ].sta_msgtype      := m_nil;
k38globals [ckb3_region_autosave].sta_system_state := [ ];
k38globals [ckb3_region_autosave].sta_msgtype      := m_nil;
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38sh_autosave_show (VAR m : tgg00_MessBlock);
 
VAR
      glob : tkb3_save_static_ptr;
 
BEGIN
glob := @k38globals [ckb3_region_autosave];
vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  sy_bup_working in glob^.sta_system_state
THEN
    BEGIN
    kb38build_userinfo (m.mb_trns^.trTaskId_gg00, glob, (* PTS 1000397 UH *)
          NOT c_is_get_state, NOT c_label_handling,
          c_autosave_tape_device, c_autosave_tape_device, glob^.sta_info,
          m.mb_qual^.buf, m.mb_qual_size, m.mb_qual_len);
    m.mb_data_len := 0;               (* PTS 1000397 UH *)
    m.mb_struct   := mbs_buf;         (* PTS 1000397 UH *)
    m.mb_type     := m_return_result; (* PTS 1000397 UH *)
    m.mb_trns^.trError_gg00 :=
          glob^.sta_tape^ [c_autosave_tape_device].tpd_err;
    END
ELSE
    m.mb_trns^.trError_gg00 := e_key_not_found;
(*ENDIF*) 
vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
END;
 
&ifdef TRACE
(*------------------------------*) 
 
PROCEDURE
      k38show_monitor (glob : tkb3_save_static_ptr);
 
VAR
      i : integer;
 
BEGIN
IF  t01trace (kb_save)
THEN
    FOR i:=1 TO glob^.sta_max_tasks DO
        WITH glob^.sta_task^[i] DO
            BEGIN
            t01p2int4 (kb_save, 'task        ', ord (tsd_task_kind)
                  ,             'PID         ', tsd_task_pid) ;
            CASE tsd_state OF
                ts_none:
                    t01name (kb_save, 'INITIALIZED       ') ;
                ts_started:
                    t01name (kb_save, 'STARTED           ') ;
                ts_running:
                    t01name (kb_save, 'RUNNING           ') ;
                ts_stopped:
                    t01name (kb_save, 'STOPPED           ') ;
                OTHERWISE ;
                END ;
            (*ENDCASE*) 
            t01int4 (kb_save, '  tape-index', tsd_tape_index) ;
            t01name   (kb_save, '---               ') ;
            END
        (*ENDWITH*) 
    (*ENDFOR*) 
(*ENDIF*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      k38st_autosave_start (VAR trans : tgg00_TransContext);
 
VAR
      at_least_one_to_save : boolean;
      segments_found       : boolean;
      tape_was_changed     : boolean;
      glob                 : tkb3_save_static_ptr;
 
BEGIN
glob := @k38globals [ckb3_region_autosave];
segments_found       := false;
at_least_one_to_save := false;
tape_was_changed     := false;
trans.trError_gg00    := e_ok;
vbegexcl (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  (    sy_error        in glob^.sta_system_state) OR
    NOT (sy_bup_working  in glob^.sta_system_state)
THEN
    (* autosave aborted in meantime *)
    trans.trError_gg00 := e_write_task_crash
ELSE
    glob^.sta_try_again := true;
(*ENDIF*) 
WHILE (trans.trError_gg00 = e_ok)
      AND
      (glob^.sta_wait_pid = cgg_nil_pid)
      AND
      (segments_found OR glob^.sta_try_again) DO
    BEGIN
    glob^.sta_try_again := false;
    IF  NOT tape_was_changed
    THEN
        BEGIN
        kb38init_log_save (trans, glob, c_for_autosave, NOT c_complete_log); (* PTS 1000360 UH *)
        segments_found := trans.trError_gg00 = e_ok;
        IF  trans.trError_gg00 = e_incomplete_logsegm
        THEN
            trans.trError_gg00 := e_ok;
        (*ENDIF*) 
        IF  (    sy_error         in glob^.sta_system_state) OR
            NOT (sy_bup_working   in glob^.sta_system_state)
        THEN
            trans.trError_gg00 := e_write_task_crash;
        (*ENDIF*) 
        IF  (trans.trError_gg00 = e_ok)
            AND
            NOT at_least_one_to_save AND segments_found
        THEN
            BEGIN
            at_least_one_to_save := true;
            g01optextmsg (sp3p_console, sp3m_info,
                  kbRunAutoSave_csp03, csp3_n_autosave, c_beginning)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  segments_found
    THEN
        BEGIN
        IF  trans.trError_gg00 = e_ok
        THEN
            kb38prep_autosave_work (trans, glob, tape_was_changed);
        (*ENDIF*) 
        IF  trans.trError_gg00 = e_ok
        THEN
            BEGIN
            kb38SendEventAutosave (Started_ekb38, glob^.sta_tape^ [c_autosave_tape_device].tpd_name);
            kb38w_autosave_work (trans, glob, tape_was_changed);
            END;
        (*ENDIF*) 
        tape_was_changed := false;
        IF  trans.trError_gg00 = e_ok
        THEN
            BEGIN
            kb38post_autosave_work (trans, glob);
            kb38SendEventAutosave (BackupSuccessfull_ekb38, glob^.sta_tape^[c_autosave_tape_device].tpd_name)
            END;
        (*ENDIF*) 
        IF  (glob^.sta_tape^[c_autosave_tape_device].tpd_type <> vf_t_file)
            (* PTS 1103227 UH 1999-07-07 *)
            AND
            (trans.trError_gg00 = e_new_hostfile_required)
            AND
            (glob^.sta_wait_pid = cgg_nil_pid)
        THEN
            BEGIN
            trans.trError_gg00          := e_ok;
            glob^.sta_conttape          := c_autosave_tape_device;
            glob^.sta_task_for_conttape := c_autosave_writer_no;
            g01optextmsg (sp3p_console, sp3m_info, kbEndAutoSave_csp03,
                  csp3_n_autosave, c_is_tapeswap);
            vendexcl (trans.trTaskId_gg00, g08save0+glob^.sta_region);
            (*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
            vsuspend (trans.trTaskId_gg00, 216);
            (*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
            vbegexcl (trans.trTaskId_gg00, g08save0+glob^.sta_region);
            glob^.sta_conttape          := 0;
            glob^.sta_task_for_conttape := 0;
            IF  (    sy_error         in glob^.sta_system_state) OR
                NOT (sy_bup_working   in glob^.sta_system_state)
            THEN
                trans.trError_gg00 := e_write_task_crash
            ELSE
                WITH glob^, sta_tape^ [c_autosave_tape_device] DO
                    BEGIN
                    tape_was_changed := NOT tpd_is_full AND tpd_is_open;
                    IF  tape_was_changed
                    THEN
                        g01optextmsg (sp3p_console, sp3m_info,
                              kbRunAutoSave_csp03, csp3_n_autosave,
                              c_continue)
                    ELSE
                        trans.trError_gg00 := e_new_hostfile_required;
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
            END
        ELSE
            (* PTS 1000355 UH *)
            kb38history_write (glob,trans.trTaskId_gg00, c_autosave_tape_device, trans.trError_gg00)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
WITH glob^ DO
    BEGIN
    sta_task^ [c_autosave_writer_no].tsd_state := ts_none;
    IF  at_least_one_to_save AND (trans.trError_gg00 = e_ok)
    THEN
        BEGIN
        g01optextmsg (sp3p_console, sp3m_info, kbEndAutoSave_csp03,
              csp3_n_autosave, c_is_ok);
        kb38SendEventAutosave (Stopped_ekb38, sta_tape^ [c_autosave_tape_device].tpd_name)
        END;
    (*ENDIF*) 
    IF  sta_wait_pid <> cgg_nil_pid
    THEN
        BEGIN
&       ifdef TRACE
        t01int4 (kb_save, 'resume:     ', sta_wait_pid) ;
&       endif
        (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
        vresume (sta_wait_pid);
        (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
        sta_wait_pid := cgg_nil_pid;
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* PTS 1000355 UH *)
vendexcl (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
t01basis_error (kb_save, 'end autosave', trans.trError_gg00);
&endif
IF  (trans.trError_gg00 <> e_ok) AND at_least_one_to_save
THEN
    WITH glob^.sta_tape^[c_autosave_tape_device] DO
        BEGIN
        kb391AppendTapeErrorToMessageList (trans.trTaskId_gg00, false, true,
              c_autosave_tape_device,
              tpd_name,
              tpd_errtext);
        trans.trError_gg00 := e_ok;                (* PTS 1000437 UH *)
        k38e_autosave_end (trans, c_is_quick);
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38sys_msg (
            glob       : tkb3_save_static_ptr;
            msg_type   : tsp3_msg_type;
            mess_no    : tsp00_Int4;
            errtxt     : tsp00_ErrText;
            bad_int    : tsp00_Int4);
 
CONST
      c_max_digits = 11;
 
VAR
      msg_label : tsp00_C8;
      len       : tsp00_Int4;
      i_errtxt  : tsp00_ErrText;
 
BEGIN
(* outside region *)
(* we need internal errtxt, because of changing by g17 *)
i_errtxt := errtxt;
k38current_msg_label (glob, msg_label);
IF  bad_int <> 0
THEN
    BEGIN
    len := sizeof (i_errtxt);
    WHILE (len > 1) AND (i_errtxt [len] = ' ') DO
        len := len - 1;
    (*ENDWHILE*) 
    len := len + 1;
    IF  len + c_max_digits <= sizeof (i_errtxt)
    THEN
        g17trimint4_to_line (bad_int, len, i_errtxt)
    (*ENDIF*) 
    END;
(*ENDIF*) 
vmessage (sp3p_console, msg_type, mess_no, msg_label, i_errtxt);
END;
 
&ifdef TRACE
(*------------------------------*) 
 
PROCEDURE
      k38view_into_saveregion (
            glob   : tkb3_save_static_ptr;
            txt    : tsp00_Name;
            q_only : boolean);
 
VAR
      i : integer;
 
BEGIN
IF  t01trace (kb_save)
THEN
    WITH glob^ DO
        BEGIN
        t01name (kb_save, txt) ;
        t01int4 (kb_save, 'tape_pagecnt', sta_pages_transferred) ;
        IF  NOT q_only
        THEN
            BEGIN
            t01name   (kb_save, 'save-region STATIC') ;
            t01p2int4 (kb_save, 'first_read  ', sta_queue_first_read
                  ,             'first_free  ', sta_queue_first_free);
            t01int4   (kb_save, 'last_read   ', sta_queue_last_read);
            t01p2int4 (kb_save, 'into-count  ', sta_into_count
                  ,             'out-count   ', sta_out_count);
            t01p2int4 (kb_save, 'Q-into-count', sta_queue_into_count
                  ,             'Q-out-count ', sta_queue_out_count);
            t01p2int4 (kb_save, 'read_waits  ', sta_read_tasks_waiting
                  ,             'write_waits ', sta_write_tasks_waiting)
            END ;
        (*ENDIF*) 
        t01name   (kb_save, 'save-region QUEUE ') ;
        FOR i:=1 TO glob^.sta_queue_size DO
            WITH glob^.sta_queue^[i] DO
                BEGIN
                t01p2int4 (kb_save, '          no', i
                      ,          '   1. pno   ', sre_block^[1].the_pno);
                t01p2int4 (kb_save, 'sre_prev    ', sre_prev
                      ,             'sre_next    ', sre_next);
                t01int4 (kb_save, 'sre_state   ', ord (sre_state))
                END
            (*ENDWITH*) 
        (*ENDFOR*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      k38trigger_autosave (VAR t : tgg00_TransContext;
            in_region : boolean);
 
VAR
      glob : tkb3_save_static_ptr;
 
BEGIN
k38get_global (m_autosave, glob);
IF  in_region
THEN
    BEGIN
    IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
    THEN
        g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
    (*ENDIF*) 
    END
ELSE
    vbegexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
IF  (sy_initialized in glob^.sta_system_state)
    AND
    NOT (sy_error in glob^.sta_system_state)
    AND
    k38is_on_autosave (t, true)
    AND
    (glob^.sta_task_for_conttape = 0)
THEN
    BEGIN
    IF  glob^.sta_task^ [c_autosave_writer_no].tsd_state <> ts_none
    THEN
        glob^.sta_try_again := true
    ELSE
        BEGIN
        kb38i_run_task_init (t, glob, task_twt, c_autosave_writer_no,
              c_autosave_tape_device);
        (* leave region in next function *)
        kb900ExecuteBackupJob (t, glob^.sta_backup_server, glob^.sta_region, true,
              c_autosave_writer_no, c_autosave_tape_device, ckb3_nil_devsp_no);
&       ifdef TRACE
        t01basis_error (kb_save, 'Execute ERR:', t.trError_gg00);
&       endif
        IF  t.trError_gg00 <> e_ok
        THEN
            g01opmsg (sp3p_console, sp3m_error, kbSendError_csp03,
                  csp3_n_autosave, c_cannot_send,
                  ord (t.trError_gg00));
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  NOT in_region
THEN
    vendexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
(*ENDIF*) 
t01basis_error (kb_save, 'end trig aut', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38UtilIdGet (VAR UtilIdStr : tgg00_UtilCmdId);
 
BEGIN
(* PTS 1104845 UH 02-12-1999 new *)
(* outside region *)
UtilIdStr := k38globals [ckb3_region_normal].sta_utilcmd_id;
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38UtilIdSaveLineNo (VAR UtilId : tgg00_UtilCmdId);
 
BEGIN
(* PTS 1108625 UH 11-12-2000 new *)
(* outside region *)
k38globals [ckb3_region_normal].sta_utilcmd_id.utidLineNo_gg00 := UtilId.utidLineNo_gg00;
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38abort_handling (
            VAR t : tgg00_TransContext;
            glob : tkb3_save_static_ptr);
 
VAR
      aux_err  : tgg00_BasisError;
      dummy_no : tsp00_Int2;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
aux_err        := t.trError_gg00;  (* PTS 1108964 UH 2001-01-12 *)
t.trError_gg00 := e_ok;
IF  sy_initialized in glob^.sta_system_state
THEN
    WITH glob^ DO
        BEGIN
        IF  (sta_msgtype = m_restore_parallel) AND
            (sta_msg2type = mm_log) (* PTS 1109736 mb 2002-10-10 *)
        THEN
            gg999AbortRedoLogByRestoreComponent(t.trTaskId_gg00, aux_err);
        (*ENDIF*) 
        k39wakeup_all (glob, t.trTaskId_gg00);
        kb38discard_outstanding_tasks (t, glob, aux_err); (* PTS 1108964 UH 2001-01-12 *)
        t.trError_gg00 := e_ok;
        kb38closeall (t, glob, dummy_no);
        t.trError_gg00 := e_ok;
        IF  (sta_msgtype = m_save_parallel)
        THEN
            CASE sta_msg2type OF
                mm_pages, mm_database:
                    bd10EndSave (t.trTaskId_gg00, NOT c_backup_successful);
                mm_log:
                    kb391InvalidateSaveIterator;
                END;
            (*ENDCASE*) 
        (*ENDIF*) 
        IF  sta_is_cold AND NOT glob^.sta_check_save
        THEN
            BEGIN
            IF  sta_msg2type in [ mm_pages, mm_database ]
            THEN
                BEGIN
                IF  (sta_msgtype = m_save_parallel)
                THEN
                    BEGIN
                    bd10ShutdownConverter( t.trTaskId_gg00 );
                    bd999DetachAllDataVolumes( t.trTaskId_gg00 )
                    END
                ELSE
                    bd14ShutdownFileSystemAfterRestore( t, NOT c_RestoreSuccessful )
                (*ENDIF*) 
                END
            ELSE
                IF  sta_msg2type = mm_log
                THEN
                    BEGIN
                    bd999DetachAllArchiveLogs(t.trTaskId_gg00);
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(* clear all states *)
(* PTS 1108964 UH 2001-01-12 *)
(*ENDIF*) 
IF  aux_err <> e_ok
THEN
    t.trError_gg00 := aux_err;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38add_count_to_label (
            VAR new_label : tsp00_C14;
            VAR label_len : tsp00_Int4;
            cnt           : tsp00_Int4;
            VAR err       : tgg00_BasisError);
 
CONST
      c_label_digits = 9;
      c_label_upb    = 100000000; (* 10 ** 9 *)
 
VAR
      cnt_length : tsp00_Int4;
      aux_cnt    : tsp00_Int4;
      ln         : tsp00_Line;
      aux_str    : tsp00_C14;
 
BEGIN
IF  label_len + c_label_digits <= sizeof (tsp00_C14)
THEN
    IF  cnt <= 0
    THEN
        BEGIN
        aux_str  := '000000000     ';
        SAPDB_PascalMove ('VKB38 ',  18,    
              sizeof (aux_str), sizeof (new_label),
              @aux_str, 1, @new_label, label_len + 1, 9, err);
        label_len := label_len + 9
        END
    ELSE
        BEGIN
        cnt_length := 0;
        IF  cnt > 0
        THEN
            BEGIN
            aux_cnt := cnt MOD c_label_upb;
            REPEAT
                cnt_length := cnt_length + 1;
                aux_cnt    := aux_cnt DIV 10;
            UNTIL
                aux_cnt <= 0;
            (*ENDREPEAT*) 
            END
        ELSE
            IF  cnt = 0
            THEN
                cnt_length := 1;
            (*ENDIF*) 
        (*ENDIF*) 
        aux_cnt := label_len;
        IF  (cnt_length > 0) AND (cnt_length <= c_label_digits)
            AND
            (aux_cnt + cnt_length <= sizeof (new_label))
        THEN
            BEGIN
            g17int4to_line (cnt, c_with_zeros, c_label_digits, 1, ln);
            SAPDB_PascalMove ('VKB38 ',  19,    
                  sizeof (ln), sizeof (new_label),
                  @ln, 1, @new_label, aux_cnt + 1, c_label_digits, err);
            label_len := label_len + c_label_digits
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38add_version_to_filename (
            VAR fn   : tsp00_VFilename;
            fversion : tsp00_Int4;
            VAR err  : tgg00_BasisError);
 
CONST
      c_min_digits = 3;
 
VAR
      fn_len   : tsp00_Int4;
      vers_len : tsp00_Int4;
      aux_vers : tsp00_Int4;
      ln       : tsp00_Line;
 
BEGIN
vers_len := 0;
IF  fversion > 0
THEN
    BEGIN
    aux_vers := fversion;
    REPEAT
        vers_len := vers_len + 1;
        aux_vers := aux_vers DIV 10;
    UNTIL
        aux_vers <= 0;
    (*ENDREPEAT*) 
    END
ELSE
    IF  fversion = 0
    THEN
        vers_len := 1;
    (*ENDIF*) 
(*ENDIF*) 
;
(* PTS 1106425 UH 20000516 begin *)
IF  vers_len <= c_min_digits
THEN
    vers_len := c_min_digits;
(*ENDIF*) 
IF  vers_len > 0
THEN
    BEGIN
    fn_len := s30lnr (fn, ' ', 1, sizeof(fn));
    fn_len := fn_len + 1;
    IF  (fn_len + vers_len) <= sizeof (fn)
    THEN
        BEGIN
        fn [fn_len] := '.';
        g17int4to_line (fversion, vers_len <= c_min_digits,
              vers_len, 1, ln);
        SAPDB_PascalMove ('VKB38 ',  20,    
              sizeof (ln), sizeof (fn), @ln, 1, @fn,
              fn_len + 1, vers_len, err);
        END
    ELSE
        err := e_invalid_datalength
    (*ENDIF*) 
    END;
(*ENDIF*) 
;
(* PTS 1106425 UH 20000516 end *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38alloc_autosave (
            pid        : tsp00_TaskId;
            glob       : tkb3_save_static_ptr;
            VAR b_err  : tgg00_BasisError);
 
VAR
      ok               : boolean ;
      i                : integer ;
      task_list_bytes  : tsp00_Int4 ;
      tape_list_bytes  : tsp00_Int4 ;
      devsp_list_bytes : tsp00_Int4 ;
      srr_queue_bytes  : tsp00_Int4 ;
      available        : tsp00_Int4 ;
      block_count      : tsp00_Int4;
      univ_addr        : tkb3_univ_addr;
 
BEGIN
b_err     := e_ok ;
available := 0 ;
ok        := true;
WITH glob^ DO
    BEGIN
    block_count    := g01backup_block_count;
    sta_max_tasks  := 1 + c_autosave_maxdatadevs;
    sta_queue_size := 4; (* ++++ *)
&   ifdef TRACE
    t01p2int4 (kb_save, 'queue_size  ', sta_queue_size
          ,             'max_tasks   ', sta_max_tasks);
&   endif
    (* --- restart rec (copy) --- *)
    vnewbuf (1, available, univ_addr.buf, ok);
    g01allocate_msg (csp3_n_dyndata, 'BACKUP RESTART REC (8K):', 1);
    IF  ok
    THEN
        BEGIN
        sta_data_rst_rec := univ_addr.log;
        (* --- task list --- *)
        task_list_bytes := sta_max_tasks * sizeof (tkb3_task_desc);
        vallocat (task_list_bytes, univ_addr.obj, ok);
        g01allocate_msg (csp3_n_dynpool, 'BACKUP TASK LIST       :',
              g01align (task_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
        END;
    (*ENDIF*) 
    IF  ok
    THEN
        BEGIN
        sta_task := univ_addr.task;
        (* --- tape list --- *)
        tape_list_bytes  := 2 * sizeof (tkb3_tape_desc);
        vallocat (tape_list_bytes, univ_addr.obj, ok);
        g01allocate_msg (csp3_n_dynpool, 'BACKUP TAPE LIST       :',
              g01align (tape_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
        END;
    (*ENDIF*) 
    IF  ok
    THEN
        BEGIN
        sta_tape := univ_addr.tape;
        (* --- devsp list --- *)
        devsp_list_bytes := c_autosave_maxdatadevs *
              sizeof (tkb3_devsp_desc);
        vallocat (devsp_list_bytes, univ_addr.obj, ok);
        g01allocate_msg (csp3_n_dynpool, 'BACKUP DEVSP LIST      :',
              g01align (devsp_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
        END;
    (*ENDIF*) 
    IF  ok
    THEN
        BEGIN
        sta_devsp := univ_addr.devsp;
        (* --- volume index --- *)
        devsp_list_bytes := bd999MaxConfigurableDataVolumes *
              sizeof (tsp00_Int2);
        vallocat (devsp_list_bytes, univ_addr.obj, ok);
        g01allocate_msg (csp3_n_dynpool, 'BACKUP VOL IDX LIST    :',
              g01align (devsp_list_bytes)) (* PTS 1104176 JA 1999-10-12 *)
        END;
    (*ENDIF*) 
    IF  ok
    THEN
        BEGIN
        sta_vol_idx := univ_addr.volidx;
        (* --- queue --- *)
        (*                  queue element 0 contains extra block *)
        srr_queue_bytes :=
              (1 + sta_queue_size) * sizeof (tkb3_srr_elem);
        vallocat (srr_queue_bytes, univ_addr.obj, ok);
        g01allocate_msg (csp3_n_dynpool, 'BACKUP SRR QUEUE       :',
              g01align (srr_queue_bytes)); (* PTS 1104176 JA 1999-10-12 *)
        g01allocate_msg (csp3_n_dynpool, 'DYNP_K38_AUTOSAVE      :',
              g01align (task_list_bytes ) +
              g01align (tape_list_bytes ) +
              g01align (devsp_list_bytes) +
              g01align (srr_queue_bytes )) (* PTS 1104176 JA 1999-10-12 *)
        END;
    (*ENDIF*) 
    IF  ok
    THEN
        BEGIN
        sta_queue := univ_addr.srr;
        (* --- pages pool --- *)
        (*                   block 0 contains extra block *)
        (*                   + 1 restart record           *)
        g01allocate_msg (csp3_n_dyndata, 'DYND_K38_AUTOSAVE      :',
              (1 + sta_queue_size) * block_count +1)
        END;
    (*ENDIF*) 
    i := 0;
    WHILE ok AND (i <= sta_queue_size) DO
        BEGIN
        vnewbuf (block_count, available, univ_addr.buf,ok);
        sta_queue^[i].sre_block := univ_addr.block;
        i := i + 1
        END;
    (*ENDWHILE*) 
    glob^.sta_backup_server := NIL;
    IF  NOT ok
    THEN
        BEGIN
        b_err := e_sysbuf_storage_exceeded;
        k38sys_msg (glob, sp3m_error, csp3_sysbuf_storage_exceeded,
              c_allocate_failed, 0)
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
&ifdef TRACE
IF  b_err <> e_ok
THEN
    t01basis_error (kb_save, 'end kb38allo', b_err) ;
&endif
(*ENDIF*) 
IF  ok AND (b_err = e_ok)
THEN
    BEGIN
    vbegexcl (pid, g08save0 + glob^.sta_region);
    kb38glob_init (glob, m_autosave, mm_log);
    kb38info_init (glob, glob^.sta_info);
    WITH glob^.sta_info DO
        BEGIN
        inf_mess_type  := m_autosave;
        inf_mess2_type := mm_log
        END;
    (*ENDWITH*) 
    vendexcl (pid, g08save0 + glob^.sta_region)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38build_userinfo (
            pid               : tsp00_TaskId;
            glob              : tkb3_save_static_ptr;
            is_get_state      : boolean;
            is_label_handling : boolean;
            tape_no           : tsp00_Int2;
            errtext_tape_no   : tsp00_Int2;
            VAR my_info       : tkb3_info_stuff;
            VAR buffer        : tsp00_Buf;
            buf_size          : tsp00_Int4;
            VAR buf_len       : tsp00_Int4);
 
CONST
      c_string_def_byte = bsp_c1;
 
VAR
      doit             : boolean;
      b_err            : tgg00_BasisError;
      dummy_err        : tsp00_NumError;
      pages_left       : tsp00_Int4;
      backup_result    : tkb3_backup_result;
      pagesTransferred : tsp00_Int4;
 
BEGIN
(* PTS 1000397 UH *)
IF  NOT is_get_state AND kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
b_err := e_ok;
SAPDB_PascalFill ('VKB38 ',  21,    
      sizeof (backup_result), @backup_result, 1,
      sizeof (backup_result), bsp_c1, b_err);
WITH backup_result DO
    BEGIN
    bdef_date                  := csp_undef_byte;
    bdef_time                  := csp_undef_byte;
    bdef_serverdb              := csp_undef_byte;
    bdef_servernode            := csp_undef_byte;
    bdef_kernel_version        := csp_undef_byte;
    bcol_pages_transferred [1] := csp_undef_byte;
    bcol_pages_left        [1] := csp_undef_byte;
    bcol_no_of_volumes     [1] := csp_undef_byte;
    bdef_media_name            := csp_undef_byte;
    bdef_tape_name             := csp_undef_byte;
    bdef_tape_errortext        := csp_undef_byte;
    bdef_tape_label            := csp_undef_byte;
    bdef_is_consistent         := csp_undef_byte;
    bcol_first_iosequence        [1] := csp_undef_byte;
    bcol_last_iosequence         [1] := csp_undef_byte;
    bdef_dbstamp1_date         := csp_undef_byte;
    bdef_dbstamp1_time         := csp_undef_byte;
    bdef_dbstamp2_date         := csp_undef_byte;
    bdef_dbstamp2_time         := csp_undef_byte;
    bcol_bd_page_count     [1] := csp_undef_byte;
    bcol_tapes_used        [1] := csp_undef_byte;
    bdef_db_ident              := csp_undef_byte; (* PTS 1000449 UH 19980909 *)
    bcol_max_used_data_pno [1] := csp_undef_byte; (* PTS 1105071 UH 17-01-2000 *)
    bcol_conv_page_count   [1] := csp_undef_byte; (* PTS 1129689 TS 2004-05-18 *)
    END;
(*ENDWITH*) 
IF  is_get_state
THEN
    doit := sy_bup_working in glob^.sta_system_state
ELSE
    doit := true;
(*ENDIF*) 
IF  doit
THEN
    WITH my_info, backup_result DO
        BEGIN
        bdef_date           := c_string_def_byte;
        bcol_date           := inf_start_date;
        bdef_time           := c_string_def_byte;
        bcol_time           := inf_start_time;
        bdef_serverdb       := c_string_def_byte;
        bcol_serverdb       := inf_serverdb;
        bdef_servernode     := c_string_def_byte;
        bcol_servernode     := inf_servernode;
        bdef_kernel_version := csp_defined_byte;
        bcol_kernel_version := inf_curr_knlvers;
        pagesTransferred := glob^.sta_pages_transferred;
        IF  is_get_state OR NOT is_label_handling
        THEN
            BEGIN
            bcol_pages_transferred [1] := csp_defined_byte;
            s41p4int (bcol_pages_transferred, 2,
                  pagesTransferred, dummy_err);
            (*
                  pagesTransferred := 99;
                  bcol_pages_transferred [1] := csp_defined_byte;
                  s41p4int (bcol_pages_transferred, 2,
                  pagesTransferred, dummy_err);
                  t01int4 (kb_save, 'mb get state', pagesTransferred) ;
                  *)
            END;
        (*ENDIF*) 
        IF  NOT is_label_handling
        THEN
            (* set bcol_pages_left *)
            IF  is_get_state
            THEN
                (* pid is cgg_nil_pid *)
                BEGIN
                bcol_pages_left [1]  := csp_defined_byte;
                IF  (glob^.sta_msgtype = m_save_parallel)
                    AND  (glob^.sta_msg2type = mm_log)
                THEN              (* PTS1112109 mb 2001-10-25 *)
                    kb391GetNumOfPagesLeftForLogDev(pages_left)
                ELSE
                    BEGIN
                    pages_left := inf_bd_page_count - pagesTransferred;
                    IF  pages_left < 0
                    THEN
                        pages_left := 0;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                s41p4int (bcol_pages_left, 2, pages_left, dummy_err);
                END
            ELSE
                BEGIN
                bcol_pages_left [ 1 ] := csp_defined_byte;
                CASE glob^.sta_msgtype OF
                    m_restore_parallel, m_restore:
                        (* changed to be equal to GetState UH 2002-06-05 *)
                        IF  glob^.sta_msg2type = mm_log
                        THEN
                            BEGIN
                            pages_left := 0; (* PTS 1116243 mb 2002-06-20 *)
                            END
                        ELSE
                            BEGIN
                            pages_left := inf_bd_page_count - pagesTransferred;
                            IF  pages_left < 0
                            THEN
                                pages_left := 0;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    m_save_parallel:
                        IF  inf_pt2 = pt2EndSaveInfo_egg00
                        THEN
                            pages_left := 0
                        ELSE
                            kb38save_pages_left (pid, glob,inf_volume_no, pages_left);
                        (*ENDIF*) 
                    m_autosave:
                        IF  (glob^.sta_task^ [c_autosave_writer_no].tsd_state
                            = ts_none)
                            AND NOT
                            glob^.sta_tape^ [c_autosave_tape_device].tpd_is_full
                        THEN
                            pages_left := 0
                        ELSE
                            kb38save_pages_left (pid, glob,
                                  inf_volume_no, pages_left)
                        (*ENDIF*) 
                    END;
                (*ENDCASE*) 
                s41p4int (bcol_pages_left, 2, pages_left, dummy_err);
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        IF  inf_max_volume_no > 0
        THEN
            BEGIN
            bcol_no_of_volumes [1] := csp_defined_byte;
            s41p4int (bcol_no_of_volumes, 2, inf_max_volume_no, dummy_err);
            END;
        (*ENDIF*) 
        IF  NOT is_get_state
        THEN
            BEGIN
            IF  NOT is_label_handling AND (glob^.sta_media_name <> bsp_c64)
            THEN
                BEGIN
                bdef_media_name := c_string_def_byte;
                bcol_media_name := glob^.sta_media_name
                END;
            (*ENDIF*) 
            IF  tape_no > 0
            THEN
                BEGIN
                bdef_tape_name := c_string_def_byte;
                bcol_tape_name := glob^.sta_tape^[tape_no].tpd_name
                END;
            (*ENDIF*) 
            IF  errtext_tape_no > 0
            THEN
                WITH glob^.sta_tape^[errtext_tape_no] DO
                    BEGIN
                    bdef_tape_errortext := c_string_def_byte;
                    bcol_tape_errortext := tpd_errtext;
                    kb391AppendTapeErrorToMessageList (pid,
                          (tpd_err = e_ok) OR (tpd_err = e_new_hostfile_required), false,
                          errtext_tape_no, tpd_name, tpd_errtext);
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            IF  inf_label <> bsp_c14
            THEN
                BEGIN
                bdef_tape_label := c_string_def_byte;
                bcol_tape_label := inf_label
                END;
            (*ENDIF*) 
            IF  (inf_mess2_type = mm_database)
                OR
                (inf_mess2_type = mm_pages)
            THEN
                BEGIN
                bdef_is_consistent := csp_defined_byte;
                bcol_is_consistent := chr (inf_is_consistent)
                END;
            (*ENDIF*) 
            IF  kb560IsValidIOSeq(inf_first_iosequence) (* PTS 1116063 mb 2002-06-13 *)
            THEN
                BEGIN
                bcol_first_iosequence [1] := csp_defined_byte;
                s41pluns (bcol_first_iosequence, 2, 10, 0, inf_first_iosequence, dummy_err);
                END;
            (* *)
            (*ENDIF*) 
            IF  kb560IsValidIOSeq(inf_last_iosequence) (* PTS 1116063 mb 2002-06-13 *)
            THEN
                BEGIN
                bcol_last_iosequence [1] := csp_defined_byte;
                s41pluns (bcol_last_iosequence, 2, 10, 0, inf_last_iosequence, dummy_err)
                END;
            (* *)
            (*ENDIF*) 
            IF  inf_dbstamp1_date <> bsp_date
            THEN
                BEGIN
                bdef_dbstamp1_date  := c_string_def_byte;
                bcol_dbstamp1_date  := inf_dbstamp1_date
                END;
            (*ENDIF*) 
            IF  inf_dbstamp1_time <> bsp_time
            THEN
                BEGIN
                bdef_dbstamp1_time  := c_string_def_byte;
                bcol_dbstamp1_time  := inf_dbstamp1_time
                END;
            (*ENDIF*) 
            IF  inf_mess2_type = mm_log
            THEN
                BEGIN
                bdef_dbstamp2_date := c_string_def_byte;
                bcol_dbstamp2_date := inf_dbstamp2_date;
                bdef_dbstamp2_time := c_string_def_byte;
                bcol_dbstamp2_time := inf_dbstamp2_time
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  inf_bd_page_count > 0
        THEN
            BEGIN
            bcol_bd_page_count [1] := csp_defined_byte;
            s41p4int (bcol_bd_page_count, 2, inf_bd_page_count, dummy_err);
            END;
        (* *)
        (*ENDIF*) 
        IF  inf_tapes_used > 0
        THEN
            BEGIN
            bcol_tapes_used [1] := csp_defined_byte;
            s41p4int (bcol_tapes_used, 2, inf_tapes_used, dummy_err);
            END;
        (*ENDIF*) 
        IF  inf_db_ident [1] <> chr (0) (* PTS 1000449 UH 19980909 *)
        THEN
            BEGIN
            bdef_db_ident := c_string_def_byte;
            bcol_db_ident := inf_db_ident
            END;
        (* PTS 1105071 UH 17-01-2000 begin *)
        (*ENDIF*) 
        IF  inf_max_used_data_pno <> NIL_PAGE_NO_GG00
        THEN
            BEGIN
            bcol_max_used_data_pno [1] := csp_defined_byte;
            s41p4int (bcol_max_used_data_pno , 2, inf_max_used_data_pno, dummy_err);
            END;
        (* PTS 1105071 UH 17-01-2000 end *)
        (* PTS 1129689 TS 2004-05-18 *)
        (*ENDIF*) 
        IF  inf_conv_page_count > 0
        THEN
            BEGIN
            bcol_conv_page_count [1] := csp_defined_byte;
            s41p4int (bcol_conv_page_count , 2, inf_conv_page_count, dummy_err);
            END;
        (* PTS 1129689 *)
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
buf_len := sizeof (backup_result);
SAPDB_PascalMove ('VKB38 ',  22,    
      sizeof (backup_result), buf_size,
      @backup_result, 1, @buffer, 1, sizeof (backup_result), b_err)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38change_version_in_filename (
            VAR file_name : tsp00_VFilename;
            file_version : tsp00_Int4;
            VAR err      : tgg00_BasisError);
 
VAR
      dot_found   : boolean;
      pos         : tsp00_Int4;
      name_length : tsp00_Int4;
      aux_name    : tsp00_VFilename;
 
BEGIN
aux_name    := file_name;
name_length := s30lnr (file_name, ' ', 1, sizeof (file_name));
pos         := name_length;
dot_found   := false;
WHILE (pos >= 1) AND NOT dot_found DO
    BEGIN
    dot_found := file_name [pos] = '.';
    file_name [pos] := ' ';
    pos := pos - 1;
    END;
(*ENDWHILE*) 
IF  NOT dot_found
THEN
    file_name := aux_name;
(*ENDIF*) 
kb38add_version_to_filename (file_name, file_version, err)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38closeall (
            VAR tr              : tgg00_TransContext;
            glob                : tkb3_save_static_ptr;
            VAR errtext_tape_no : tsp00_Int2);
 
VAR
      i   : tsp00_Int2 ;
      err : tgg00_BasisError;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (tr.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
err       := tr.trError_gg00;
tr.trError_gg00 := e_ok;
glob^.sta_is_auto_load := false;
i := 1;
WITH glob^ DO
    BEGIN
    REPEAT
        WITH sta_tape^[i] DO
            BEGIN
&           ifdef TRACE
            t01int4 (kb_save, '  tape-index', i);
&           endif
            IF  tpd_is_open
            THEN
                BEGIN
                k38closeasyn (tr, glob, NOT c_auto_load,
                      NOT c_force_rewind, i, tpd_is_open, tpd_fno);
                IF  tr.trError_gg00 <> e_ok
                THEN
                    errtext_tape_no := i;
&               ifdef TRACE
                (*ENDIF*) 
                t01bool (kb_save, 't-closed ok ', tr.trError_gg00 = e_ok);
&               endif
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        i := i + 1
    UNTIL
        i > g01no_of_backup_devs;
    (*ENDREPEAT*) 
    IF  (sta_msg2type in [ mm_pages, mm_database ])
        AND NOT glob^.sta_check_save
    THEN
        BEGIN
        i := 1 ;
        REPEAT
            WITH sta_devsp^[i] DO
                BEGIN
&               ifdef TRACE
                t01int4 (kb_save, ' devsp-index', i);
&               endif
                IF  dvd_is_open
                THEN
                    BEGIN
                    k38closeasyn (tr, glob, NOT c_auto_load,
                          NOT c_force_rewind, ckb3_nil_tape_no,
                          dvd_is_open, dvd_fno);
&                   ifdef TRACE
                    t01bool (kb_save, 'd-closed ok ', tr.trError_gg00 = e_ok);
&                   endif
                    END;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            i := i + 1
        UNTIL
            i > bd999MaxConfigurableDataVolumes;
        (*ENDREPEAT*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
IF  (tr.trError_gg00 = e_ok)
THEN
    tr.trError_gg00 := err;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38d_open_devspaces (
            VAR t : tgg00_TransContext;
            glob : tkb3_save_static_ptr);
 
VAR
      volume_no     : tsp00_Int2;
      volume_index  : tsp00_Int2;
      volume_found  : boolean;
      volume_name   : tsp00_VFilename;
      is_for_writing : boolean;
 
BEGIN
is_for_writing := glob^.sta_msgtype = m_restore_parallel;
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
volume_index := 1;
volume_no := 0; (* incremented by bd999getnext... *)
volume_found := bd999GetNextDataVolumeNameForBackup (volume_no, volume_name, is_for_writing);
WHILE (volume_found) AND (t.trError_gg00 = e_ok) DO
    BEGIN
    IF  glob^.sta_devsp^ [volume_index].dvd_is_open
    THEN
        t.trError_gg00 := e_invalid
    ELSE
        kb38devspaceopen_one (t, glob, volume_index, volume_no, volume_name );
    (*ENDIF*) 
    volume_index := volume_index + 1;
    volume_found := bd999GetNextDataVolumeNameForBackup (volume_no, volume_name, is_for_writing)
    END;
(*ENDWHILE*) 
&ifdef TRACE
t01basis_error (kb_save, 'end d_open_d', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38devspaceopen_one (
            VAR t         : tgg00_TransContext;
            glob          : tkb3_save_static_ptr;
            volume_index  : tsp00_Int2;
            VAR volume_no : tsp00_Int2;
            VAR volume_name : tsp00_VFilename);
 
VAR
      is_for_writing : boolean;
      vaerr          : tsp00_VaReturn;
      act_block_cnt  : tsp00_Int4;
      etxt           : tsp00_ErrText;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^ DO
    BEGIN
    act_block_cnt  := sta_blocksize ;
    is_for_writing := sta_msgtype = m_restore_parallel;
    vendexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
    sta_devsp^[volume_index].dvd_volno := volume_no;
    sta_vol_idx^[volume_no] := volume_index; (* reverse mapping *)
&   ifdef TRACE
    t01vffn   (kb_save, 'open devspac', volume_name);
    t01bool   (kb_save, 'for_writing ', is_for_writing);
    t01p2int4 (kb_save, 'volume_index', volume_index
          ,             'act_blockcnt', act_block_cnt);
    t01int4 (kb_save,   'voluem_no   ', volume_no);
&   endif
    vasynopen (volume_name, c_is_devspace, is_for_writing,
          vf_t_unknown, sizeof (tsp00_Page), NIL, act_block_cnt,
          sta_devsp^[volume_index].dvd_fno, vaerr, etxt);
    vbegexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
&   ifdef TRACE
    t01p2int4 (kb_save, 'dev open err', ord (vaerr)
          ,             '         fno', sta_devsp^[volume_index].dvd_fno);
&   endif
    IF  (vaerr = va_ok)
    THEN
        sta_devsp^[volume_index].dvd_is_open := true
    ELSE
        BEGIN
        IF  (act_block_cnt <> sta_blocksize)
        THEN
            k38sys_msg (glob, sp3m_error,
                  kbSurprisingBlockCnt_csp03,
                  c_devsp_surprising_blockcnt, act_block_cnt);
        (*ENDIF*) 
        t.trError_gg00 := e_hostfile_error;
        k38err_to_vtrace (t, glob, 'ASYNOPEN DEV', etxt)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      kb38is_important_error ( errorNo : tgg00_BasisError) : boolean;
 
BEGIN
kb38is_important_error :=
      (errorNo <> e_ok)
      AND
      (errorNo <> e_write_task_crash)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38discard_outstanding_tasks (
            VAR t               : tgg00_TransContext;
            glob                : tkb3_save_static_ptr;
            VAR important_error : tgg00_BasisError);
 
VAR
      any_child_running : boolean;
      curr_task         : tsp00_Int2;
      joberror          : tgg00_BasisError;
 
BEGIN
(* important_error must not be reset, because it is and IN/OUT *)
(* parameter.                        PTS 1133625 mb 2005-01-27 *)
t.trError_gg00  := e_ok;
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
REPEAT
    any_child_running := false;
    curr_task         := 1;
    WHILE (curr_task <= glob^.sta_num_tapes + glob^.sta_num_devsp)
          AND NOT any_child_running DO
        IF  glob^.sta_task^[curr_task].tsd_state <> ts_none
        THEN
            any_child_running := true
        ELSE
            curr_task := curr_task + 1;
        (*ENDIF*) 
    (*ENDWHILE*) 
    IF  any_child_running
    THEN
        BEGIN
        t.trError_gg00 := e_ok;
        curr_task := ckb3_nil_task_no;
        (* leave region in next function *)
        kb900WaitForAnyBackupJobFinished (t, glob^.sta_backup_server,
              glob^.sta_region, curr_task, joberror);
        glob^.sta_task^[curr_task].tsd_state := ts_none;
        (* PTS 1108964 UH 2001-01-12 *)
        (* PTS 1133528 UH 2005-01-21 error handling was wrong - not waiting for all tasks *)
        IF  (NOT kb38is_important_error (important_error))
            AND
            kb38is_important_error (joberror)
        THEN
            important_error := joberror
        (*ENDIF*) 
        END
    (*ENDIF*) 
UNTIL
    NOT any_child_running OR (t.trError_gg00 <> e_ok);
(*ENDREPEAT*) 
IF  important_error <> e_ok
THEN
    t.trError_gg00 := important_error;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38dump_autosave_log (
            VAR hostfile : tgg00_VfFileref;
            VAR buf      : tsp00_Page;
            VAR out_pno  : tsp00_Int4;
            VAR out_pos  : integer;
            VAR host_err : tsp00_VfReturn;
            VAR errtext  : tsp00_ErrText);
 
CONST
      mark_k38undef  = 'K38AUNDE';
      code_k38undef  = 1159;
      mark_k38glob   = 'K38AGLOB';
      code_k38glob   = 1160;
      mark_k38task   = 'K38ATASK';
      code_k38task   = 1161;
      mark_k38tape   = 'K38ATAPE';
      code_k38tape   = 1162;
      mark_k38devsp  = 'K38ADEVS';
      code_k38devsp  = 1163;
      mark_k38queue  = 'K38AQUEU';
      code_k38queue  = 1164;
      (**)
      mx_page_header = 8;
 
VAR
      glob        : tkb3_save_static_ptr;
      i2          : tsp00_IntMapC2;
      i           : integer;
      curr_page   : integer;
      backup_devs : tsp00_Int4;
      err         : tgg00_BasisError;
 
BEGIN
glob := @k38globals [ckb3_region_autosave];
(* CRASH: outside g08save0 + glob^.sta_region region *)
IF  NOT (sy_allocated in glob^.sta_system_state)
    AND (host_err = vf_ok)
THEN
    (* ---  queue not allocated  --- *)
    kb38dump_header (hostfile, 0, mark_k38undef, code_k38undef,
          buf, out_pno, out_pos, host_err, errtext, err);
(*ENDIF*) 
IF  (sy_allocated in glob^.sta_system_state)
    AND (host_err = vf_ok)
THEN
    (* ---  K 3 8 G L O B  --- *)
    BEGIN
    (* sizeof (buf) ==> new page *)
    kb38dump_header (hostfile, sizeof (buf),
          mark_k38glob, code_k38glob,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        SAPDB_PascalMove ('VKB38 ',  23,    
              sizeof (glob^), sizeof (buf),
              @glob^, 1, @buf, out_pos, sizeof (glob^), err);
        out_pos := out_pos + sizeof (glob^)
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
i := 1;
WHILE (i <= glob^.sta_max_tasks)
      AND (host_err = vf_ok)
      AND (sy_allocated in glob^.sta_system_state) DO
    (* *)
    (* ---  K 3 8 T A S K  --- *)
    BEGIN
    kb38dump_header (hostfile, 2 + sizeof (glob^.sta_task^[i]),
          mark_k38task, code_k38task,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00      := i;
        buf [out_pos  ] := i2.mapC2_sp00 [1];
        buf [out_pos+1] := i2.mapC2_sp00 [2];
        out_pos         := out_pos + 2;
        SAPDB_PascalMove ('VKB38 ',  24,    
              sizeof (glob^.sta_task^[i]), sizeof (buf),
              @glob^.sta_task^[i], 1,
              @buf, out_pos,  sizeof (glob^.sta_task^[i]), err);
        out_pos := out_pos + sizeof (glob^.sta_task^[i])
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
i := 1;
backup_devs := 2;
WHILE (i <= backup_devs)
      AND (host_err = vf_ok)
      AND (sy_allocated in glob^.sta_system_state) DO
    (* *)
    (* ---  K 3 8 T A P E  --- *)
    BEGIN
    kb38dump_header (hostfile, 2 + sizeof (glob^.sta_tape^[i]),
          mark_k38tape, code_k38tape,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00      := i;
        buf [out_pos  ] := i2.mapC2_sp00 [1];
        buf [out_pos+1] := i2.mapC2_sp00 [2];
        out_pos         := out_pos + 2;
        SAPDB_PascalMove ('VKB38 ',  25,    
              sizeof (glob^.sta_tape^[i]), sizeof (buf),
              @glob^.sta_tape^[i], 1,
              @buf, out_pos,  sizeof (glob^.sta_tape^[i]), err);
        out_pos := out_pos + sizeof (glob^.sta_tape^[i])
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
i := 1;
WHILE (i <= c_autosave_maxdatadevs)
      AND (host_err = vf_ok)
      AND (sy_allocated in glob^.sta_system_state) DO
    (* *)
    (* ---  K 3 8 D E V S P  --- *)
    BEGIN
    kb38dump_header (hostfile, 2 + sizeof (glob^.sta_devsp^[i]),
          mark_k38devsp, code_k38devsp,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00      := i;
        buf [out_pos  ] := i2.mapC2_sp00 [1];
        buf [out_pos+1] := i2.mapC2_sp00 [2];
        out_pos         := out_pos + 2;
        SAPDB_PascalMove ('VKB38 ',  26,    
              sizeof (glob^.sta_devsp^[i]), sizeof (buf),
              @glob^.sta_devsp^[i], 1,
              @buf, out_pos,  sizeof (glob^.sta_devsp^[i]), err);
        out_pos := out_pos + sizeof (glob^.sta_devsp^[i])
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
IF  sy_allocated in glob^.sta_system_state
THEN
    (* ---  K 3 8 Q U E U E  --- *)
    BEGIN
    i := 0;
    WHILE (i <= glob^.sta_queue_size) AND (host_err = vf_ok) DO
        BEGIN
        kb38dump_header (hostfile,
              2 + sizeof (glob^.sta_queue^[i])
              + mx_page_header * g01backup_block_count,
              mark_k38queue, code_k38queue,
              buf, out_pno, out_pos, host_err, errtext, err);
        IF  host_err = vf_ok
        THEN
            BEGIN
            i2.mapInt_sp00      := i;
            buf [out_pos  ] := i2.mapC2_sp00 [1];
            buf [out_pos+1] := i2.mapC2_sp00 [2];
            out_pos         := out_pos + 2;
            SAPDB_PascalMove ('VKB38 ',  27,    
                  sizeof (glob^.sta_queue^[i]), sizeof (buf),
                  @glob^.sta_queue^[i], 1,
                  @buf, out_pos,  sizeof (glob^.sta_queue^[i]), err);
            out_pos := out_pos + sizeof (glob^.sta_queue^[i]);
            s20int4_to_buf (g01backup_block_count, buf,out_pos);
            out_pos := out_pos + 4;
            FOR curr_page := 1 TO g01backup_block_count DO
                BEGIN
                WITH glob^.sta_queue^[i].sre_block^[curr_page] DO
                    SAPDB_PascalMove ('VKB38 ',  28,    
                          sizeof (the_page), sizeof (buf),
                          @the_page, 1, @buf, out_pos,mx_page_header,err);
                (*ENDWITH*) 
                out_pos := out_pos + mx_page_header
                END
            (*ENDFOR*) 
            END;
        (*ENDIF*) 
        i := i + 1
        END
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
IF  host_err = vf_ok
THEN
    g01new_dump_page (hostfile, buf, out_pno, out_pos, host_err, errtext)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38dump_headmaster (
            VAR hostfile : tgg00_VfFileref;
            VAR buf      : tsp00_Page;
            VAR out_pno  : tsp00_Int4;
            VAR out_pos  : integer;
            VAR host_err : tsp00_VfReturn;
            VAR errtext  : tsp00_ErrText);
 
CONST
      mark_k38undef  = 'K38UNDEF';
      code_k38undef  = 1149;
      mark_k38glob   = 'K38GLOB ';
      code_k38glob   = 1150;
      mark_k38task   = 'K38TASK ';
      code_k38task   = 1151;
      mark_k38tape   = 'K38TAPE ';
      code_k38tape   = 1152;
      mark_k38devsp  = 'K38DEVSP';
      code_k38devsp  = 1153;
      mark_k38queue  = 'K38QUEUE';
      code_k38queue  = 1154;
 
VAR
      glob      : tkb3_save_static_ptr;
      i2        : tsp00_IntMapC2;
      i         : integer;
      err       : tgg00_BasisError;
 
BEGIN
glob := @k38globals [ckb3_region_normal];
(* CRASH: outside g08save0 + glob^.sta_region region *)
IF  NOT (sy_allocated in glob^.sta_system_state)
    AND (host_err = vf_ok)
THEN
    (* ---  queue not allocated  --- *)
    kb38dump_header (hostfile, 0, mark_k38undef, code_k38undef,
          buf, out_pno, out_pos, host_err, errtext, err);
(*ENDIF*) 
IF  (sy_allocated in glob^.sta_system_state)
    AND (host_err = vf_ok)
THEN
    (* ---  K 3 8 G L O B  --- *)
    BEGIN
    (* sizeof (buf) ==> new page *)
    kb38dump_header (hostfile, sizeof (buf),
          mark_k38glob, code_k38glob,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        SAPDB_PascalMove ('VKB38 ',  29,    
              sizeof (glob^), sizeof (buf),
              @glob^, 1, @buf, out_pos, sizeof (glob^), err);
        out_pos := out_pos + sizeof (glob^)
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
i := 1;
WHILE (i <= glob^.sta_max_tasks)
      AND (host_err = vf_ok)
      AND (sy_allocated in glob^.sta_system_state) DO
    (* *)
    (* ---  K 3 8 T A S K  --- *)
    BEGIN
    kb38dump_header (hostfile, 2 + sizeof (glob^.sta_task^[i]),
          mark_k38task, code_k38task,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00      := i;
        buf [out_pos  ] := i2.mapC2_sp00 [1];
        buf [out_pos+1] := i2.mapC2_sp00 [2];
        out_pos         := out_pos + 2;
        SAPDB_PascalMove ('VKB38 ',  30,    
              sizeof (glob^.sta_task^[i]), sizeof (buf),
              @glob^.sta_task^[i], 1,
              @buf, out_pos,  sizeof (glob^.sta_task^[i]), err);
        out_pos := out_pos + sizeof (glob^.sta_task^[i])
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
i := 1;
WHILE (i <= g01no_of_backup_devs)
      AND (host_err = vf_ok)
      AND (sy_allocated in glob^.sta_system_state) DO
    (* *)
    (* ---  K 3 8 T A P E  --- *)
    BEGIN
    kb38dump_header (hostfile, 2 + sizeof (glob^.sta_tape^[i]),
          mark_k38tape, code_k38tape,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00      := i;
        buf [out_pos  ] := i2.mapC2_sp00 [1];
        buf [out_pos+1] := i2.mapC2_sp00 [2];
        out_pos         := out_pos + 2;
        SAPDB_PascalMove ('VKB38 ',  31,    
              sizeof (glob^.sta_tape^[i]), sizeof (buf),
              @glob^.sta_tape^[i], 1,
              @buf, out_pos,  sizeof (glob^.sta_tape^[i]), err);
        out_pos := out_pos + sizeof (glob^.sta_tape^[i])
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
i := 1;
WHILE (i <= bd999MaxConfigurableDataVolumes)
      AND (host_err = vf_ok)
      AND (sy_allocated in glob^.sta_system_state) DO
    (* *)
    (* ---  K 3 8 D E V S P  --- *)
    BEGIN
    kb38dump_header (hostfile, 2 + sizeof (glob^.sta_devsp^[i]),
          mark_k38devsp, code_k38devsp,
          buf, out_pno, out_pos, host_err, errtext, err);
    IF  host_err = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00      := i;
        buf [out_pos  ] := i2.mapC2_sp00 [1];
        buf [out_pos+1] := i2.mapC2_sp00 [2];
        out_pos         := out_pos + 2;
        SAPDB_PascalMove ('VKB38 ',  32,    
              sizeof (glob^.sta_devsp^[i]), sizeof (buf),
              @glob^.sta_devsp^[i], 1,
              @buf, out_pos,  sizeof (glob^.sta_devsp^[i]), err);
        out_pos := out_pos + sizeof (glob^.sta_devsp^[i])
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
IF  sy_allocated in glob^.sta_system_state
THEN
    (* ---  K 3 8 Q U E U E  --- *)
    BEGIN
    i := 0;
    WHILE (i <= glob^.sta_queue_size) AND (host_err = vf_ok) DO
        BEGIN
        kb38dump_header (hostfile,
              2 + sizeof (glob^.sta_queue^[i]),
              mark_k38queue, code_k38queue,
              buf, out_pno, out_pos, host_err, errtext, err);
        IF  host_err = vf_ok
        THEN
            BEGIN
            i2.mapInt_sp00      := i;
            buf [out_pos  ] := i2.mapC2_sp00 [1];
            buf [out_pos+1] := i2.mapC2_sp00 [2];
            out_pos         := out_pos + 2;
            SAPDB_PascalMove ('VKB38 ',  33,    
                  sizeof (glob^.sta_queue^[i]), sizeof (buf),
                  @glob^.sta_queue^[i], 1,
                  @buf, out_pos,  sizeof (glob^.sta_queue^[i]), err);
            out_pos := out_pos + sizeof (glob^.sta_queue^[i]);
            s20int4_to_buf (g01backup_block_count, buf,out_pos);
            out_pos := out_pos + 4;
            END;
        (*ENDIF*) 
        i := i + 1
        END
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
IF  host_err = vf_ok
THEN
    g01new_dump_page (hostfile, buf, out_pno, out_pos, host_err, errtext)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38dump_header (
            VAR hostfile : tgg00_VfFileref;
            dump_len     : integer;
            dump_mark    : tsp00_C8;
            dump_code    : tsp00_Int2;
            VAR buf      : tsp00_Page;
            VAR out_pno  : tsp00_Int4;
            VAR out_pos  : integer;
            VAR host_err : tsp00_VfReturn;
            VAR errtext  : tsp00_ErrText;
            VAR err      : tgg00_BasisError);
 
CONST
      c_header = 10; (* dump_label + dump_code *)
 
VAR
      i2 : tsp00_IntMapC2;
 
BEGIN
IF  (out_pos-1 + c_header + dump_len > sizeof (buf)) (* PTS 1132022 UH 2004-10-19 *)
    AND
    (host_err = vf_ok)
THEN
    g01new_dump_page (hostfile, buf, out_pno, out_pos, host_err, errtext);
(*ENDIF*) 
IF  host_err = vf_ok
THEN
    BEGIN
    SAPDB_PascalMove ('VKB38 ',  34,    
          sizeof (dump_mark), sizeof (buf),
          @dump_mark, 1, @buf, out_pos, sizeof (dump_mark), err);
    out_pos         := out_pos + sizeof (dump_mark);
    i2.mapInt_sp00  := dump_code;
    buf [out_pos  ] := i2.mapC2_sp00 [1];
    buf [out_pos+1] := i2.mapC2_sp00 [2];
    out_pos         := out_pos + 2
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38end_incopy (
            VAR t : tgg00_TransContext;
            glob : tkb3_save_static_ptr);
 
BEGIN
CASE glob^.sta_msg2type OF
    mm_pages, mm_database:
        BEGIN
        t.trError_gg00 := e_ok;
        IF  (glob^.sta_msg2type =  mm_pages)
        THEN
            bd10FinishRestoreUsedPageNos (t.trTaskId_gg00);
        (* PTS 1124994 UH 2004-01-26 begin *)
        (*ENDIF*) 
        IF  NOT glob^.sta_check_save
        THEN
            BEGIN
            k57restartrec^.rstConfigParam_kb00.crPrevDataRecoveryWasIncomplete_kb00 := false;
            k57save_restartrecord (t.trTaskId_gg00);
            END;
        (* PTS 1124994 UH 2004-01-26 end *)
        (*ENDIF*) 
        bd14ShutdownFileSystemAfterRestore (t, c_RestoreSuccessful);
        END;
    mm_log:
        BEGIN
        END;
    END;
(*ENDCASE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38end_outcopy (
            VAR t : tgg00_TransContext;
            glob : tkb3_save_static_ptr);
 
BEGIN
t.trError_gg00 := e_ok;
CASE glob^.sta_msg2type OF
    mm_log:
        (* PTS 1108438 UH 2000-11-22 *)
        (* PTS 1128703 mb 2004-04-26 *)
        IF    ((glob^.sta_tape^[1].tpd_type =  vf_t_pipe) AND g01log_backup_to_pipe)
            OR (glob^.sta_tape^[1].tpd_type <> vf_t_pipe)
        THEN
            kb391FreeLog ( t.trTaskId_gg00 , t.trError_gg00 );
        (*ENDIF*) 
    mm_pages, mm_database:
        BEGIN
        WITH glob^ DO
            BEGIN
            t.trError_gg00 := e_ok;
            (* PTS 1113190 UH 2001-12-19 kb560SetDeviceStateOkay added *)
            kb560SetDeviceStateOkay (t.trTaskId_gg00, t.trError_gg00);
            (* ignore the error in case the log devices could not be attached *)
            t.trError_gg00 := e_ok;
            IF  (glob^.sta_msg2type = mm_database)
            THEN
                k57restartrec^.rstLastSaveDataSuccessful_kb00 := true;
            (*ENDIF*) 
            IF  sta_is_cold
            THEN
                BEGIN
                vbegexcl (t.trTaskId_gg00, g08savepoint);
                k57restartrec^.rstSetEndReadOnly_kb00 := true;
                k57save_restartrecord (t.trTaskId_gg00);
                vendexcl (t.trTaskId_gg00, g08savepoint);
                END
            ELSE
                b01end_read_only (t);
            (*ENDIF*) 
            IF  t.trError_gg00 = e_ok
            THEN
                BEGIN
                vbegexcl (t.trTaskId_gg00, g08savepoint);
                k57restartrec^.rstCurrBackupVersion_kb00 := sta_data_rst_rec^.rstCurrBackupVersion_kb00;
                k57restartrec^.rstPrevBackupVersion_kb00 := sta_data_rst_rec^.rstPrevBackupVersion_kb00;
                k57restartrec^.rstLastDataBackup_kb00    := sta_data_rst_rec^.rstLastSavept_kb00.svpIOsequence_kb00;
                k57save_restartrecord (t.trTaskId_gg00);
                vendexcl (t.trTaskId_gg00, g08savepoint)
                END
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        IF  t.trError_gg00 = e_ok
        THEN
            bd10EndSave (t.trTaskId_gg00,  c_backup_successful);
        (*ENDIF*) 
        IF  glob^.sta_is_cold
        THEN
            BEGIN
            bd10ShutdownConverter( t.trTaskId_gg00 );
            bd999DetachAllDataVolumes( t.trTaskId_gg00 )
            END
        (*ENDIF*) 
        END
    END;
(*ENDCASE*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      kb38free_tape_pages (glob : tkb3_save_static_ptr) : tsp00_Int4;
 
VAR
      free_pages : tsp00_Int4;
      i          : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
free_pages := 0;
i          := 1;
WHILE i <= glob^.sta_num_tapes + glob^.sta_num_devsp DO
    BEGIN
    WITH glob^.sta_task^[i] DO
        IF  (tsd_state <> ts_none) AND (tsd_tape_index > 0)
        THEN
            WITH glob^.sta_tape^[tsd_tape_index] DO
                IF  NOT tpd_is_full
                THEN
                    IF  MAX_INT4_SP00 - free_pages -
                        (tpd_max_pages - tpd_cnt_pages -
                        tpd_total_cnt_pages) > 0
                    THEN
                        free_pages := free_pages
                              + (tpd_max_pages - tpd_cnt_pages
                              -  tpd_total_cnt_pages)
                              - glob^.sta_blocksize
                              (*last block filler*)
                    ELSE
                        free_pages := MAX_INT4_SP00;
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDWITH*) 
        (*ENDIF*) 
    (*ENDWITH*) 
    i := i + 1
    END;
(*ENDWHILE*) 
&ifdef TRACE
t01int4 (kb_save, 'free_pages  ', free_pages);
&endif
kb38free_tape_pages := free_pages
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38get_tape_no (
            glob            : tkb3_save_static_ptr;
            VAR tape_name   : tsp00_VFilename;
            VAR tape_no     : tsp00_Int2);
 
VAR
      found : boolean;
      free  : integer;
      i     : integer;
 
BEGIN
tape_no := 0;
found   := false;
free    := 0;
i       := 1;
WHILE (i <= g01no_of_backup_devs) AND (tape_no = 0) DO
    IF  glob^.sta_tape^[i].tpd_name = tape_name
    THEN
        tape_no := i
    ELSE
        BEGIN
        IF  (free = 0) AND
            (glob^.sta_tape^[i].tpd_name = b01blankfilename)
        THEN
            free := i;
        (*ENDIF*) 
        i := i + 1
        END;
    (*ENDIF*) 
(*ENDWHILE*) 
IF  (tape_no = 0) AND (free > 0)
THEN
    tape_no := free
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38glob_init (
            glob       : tkb3_save_static_ptr;
            mess_type  : tgg00_MessType;
            mess_type2 : tgg00_MessType2);
 
VAR
      backup_devs      : tsp00_Int4;
      maxdatadevspaces : tsp00_Int4;
      i                : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
IF  glob^.sta_region = ckb3_region_autosave
THEN
    BEGIN
    backup_devs      := 2;
    maxdatadevspaces := c_autosave_maxdatadevs;
    END
ELSE
    BEGIN
    backup_devs      := g01no_of_backup_devs;
    maxdatadevspaces := bd999MaxConfigurableDataVolumes;
    END;
(*ENDIF*) 
WITH glob^ DO
    BEGIN
    sta_system_state       := [sy_allocated, sy_initialized];
    sta_pages_transferred  := 0;
    sta_into_count         := 0;
    sta_out_count          := 0;
    sta_queue_into_count   := 0;
    sta_queue_out_count    := 0;
    sta_blocksize          := 0;
    sta_num_devsp          := 0;
    sta_devsp_ready_cnt    := 0;
    sta_num_tapes          := 0;
    sta_tapes_ready_cnt    := 0;
    sta_tapes_start_cnt    := 0;
    sta_conttape           := 0;
    sta_task_for_conttape  := 0;
    sta_queue_first_free   := 1; (* first queue element *)
    sta_queue_first_read   := 0;
    sta_queue_last_read    := 0;
    sta_read_tasks_waiting := 0;
    sta_write_tasks_waiting:= 0;
    sta_is_auto_load       := false;
    sta_is_cold            := false;
    sta_msgtype            := mess_type;
    sta_msg2type           := mess_type2;
    sta_vtr_direction      := kb38save_parallel;
    sta_until_date         := bsp_date;
    sta_until_time         := bsp_time;
    kb560InvalidateIOSeq(sta_until_iosequence);
    sta_info.inf_pt        := ptNil_egg00;
    sta_info.inf_pt2       := pt2Nil_egg00;
    kb560InvalidateIOSeq(sta_data_rst_rec^.pageLpno_kb00); (* PTS 1116063 mb 2002-06-13 *)
    sta_wait_pid           := cgg_nil_pid;
    sta_try_again          := false;
    sta_file_version       := 0;
    sta_check_save         := false;
    sta_write_bitmap_pages := false;
    sta_write_conv_pages   := false;
    sta_locked_queue_index := 0;
    kb560InvalidateIOSeq(sta_last_lpno_wanted); (* PTS 1116063 mb 2002-06-13 *)
    sta_trt_eof_wait_pid   := cgg_nil_pid;
    sta_to_cancel          := NIL;
    sta_lwt_perform_redo   := true;                         (* PTS 1115315 mb 2002-04-18 *)
    sta_is_remote          := false;
    sta_tape_label         := bsp_c14;
    sta_no_release_log     := false;
    sta_media_name         := bsp_c64;
    sta_utilcmd_id.utidId_gg00 := bsp_c12; (* PTS 1108625 UH 11-12-2000,PTS 1000431 UH *)
    sta_utilcmd_id.utidLineNo_gg00 := 0; (* PTS 1108625 UH 11-12-2000 *)
    sta_filler1            := false;
    sta_coordinator_taskid := cgg_nil_pid; (* PTS 1134753 UH 2005-04-07 *)
    sta_filler2            := 0; (* PTS 1134753 UH 2005-04-07 *)
    FOR i := 1 TO MAX_TAPES_GG00 DO
        WITH sta_remote [i] DO
            BEGIN
            kb3rc_buffer  := NIL;
            kb3rc_size    := 0;
            kb3rc_length  := 0;
            kb3rc_pid     := cgg_nil_pid;
            kb3rc_filler1 := 0
            END;
        (*ENDWITH*) 
    (*ENDFOR*) 
    FOR i:=1 TO sta_max_tasks DO
        WITH sta_task^[i] DO
            BEGIN
            tsd_task_pid    := cgg_nil_pid;
            tsd_tape_index  := ckb3_nil_tape_no;
            tsd_state       := ts_none;
            tsd_task_kind   := task_nil;
            END;
        (*ENDWITH*) 
    (*ENDFOR*) 
    FOR i:=1 TO backup_devs DO
        BEGIN
        WITH sta_tape^[i] DO
            BEGIN
            tpd_is_open           := false;
            tpd_is_full           := false;
            tpd_volume_no         := 0;
            tpd_fno               := 0;
            tpd_max_pages         := MAX_INT4_SP00;
            tpd_cnt_pages         := 0;
            tpd_total_cnt_pages   := 0;
            tpd_name              := b01blankfilename;
            tpd_errtext           := bsp_c40;
            tpd_xp_size           := 0;
            tpd_xp_read           := 0;
            tpd_xp_pages          := 0;
            tpd_type              := vf_t_unknown;
            tpd_check_destructive := false;     (* PTS 1000360 UH *)
            tpd_mirror_index      := 0;
            tpd_err               := e_ok;
            tpd_is_replaced       := false;
            tpd_is_clustered      := false;
            END
        (*ENDWITH*) 
        END;
    (*ENDFOR*) 
    FOR i:=1 TO maxdatadevspaces DO
        BEGIN
        WITH sta_devsp^[i] DO
            BEGIN
            dvd_is_open    := false;
            dvd_filler1    := false;
            dvd_fno        := 0;
            dvd_volno      := 0;
            END;
        (*ENDWITH*) 
        sta_vol_idx^[i] := 0;
        END;
    (*ENDFOR*) 
    FOR i := 1 TO ckb3_max_bool_list DO
        sta_volume_started [i] := false;
    (*ENDFOR*) 
    FOR i := 0 TO sta_queue_size DO
        BEGIN
        WITH glob^.sta_queue^[i] DO
            BEGIN
            sre_state           := sres_free;
            sre_pages_per_block := 0;
            sre_next            := 0;
            sre_prev            := 0;
            sre_task_no_into    := ckb3_nil_task_no;
            sre_is_clustered    := false;
            sre_filler2         := 0;
            sre_filler3         := 0
            END
        (*ENDWITH*) 
        END;
    (*ENDFOR*) 
    FOR i := sta_queue_first_free TO sta_queue_size - 1 DO
        BEGIN
        glob^.sta_queue^[i].sre_next := i + 1;
        glob^.sta_queue^[i].sre_prev := 0
        END;
    (*ENDFOR*) 
    FOR i := 1 TO MAX_TAPES_GG00 DO
        glob^.sta_trt_into_queue [i] := 0;
    (*ENDFOR*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38his_errtext_write (
            glob            : tkb3_save_static_ptr;
            VAR len         : tsp00_Int4;
            VAR ln          : tsp00_Buf;
            errtext_tape_no : tsp00_Int2;
            VAR err         : tgg00_BasisError);
 
VAR
      errtext_len : tsp00_Int4;
 
BEGIN
IF  errtext_tape_no <> ckb3_nil_tape_no
THEN
    BEGIN
    WITH glob^.sta_tape^ [errtext_tape_no] DO
        IF  len + sizeof (tpd_errtext) <= sizeof (ln)
        THEN
            BEGIN
            SAPDB_PascalMove ('VKB38 ',  35,    
                  sizeof (tpd_errtext), sizeof (ln), @tpd_errtext,
                  1, @ln, len + 1, sizeof (tpd_errtext), err);
            errtext_len := sizeof (tpd_errtext)
            END
        ELSE
            errtext_len := 0
        (*ENDIF*) 
    (*ENDWITH*) 
    END
ELSE
    BEGIN
    IF  glob^.sta_num_tapes >= 1
    THEN
        errtext_len := sizeof (glob^.sta_tape^ [1].tpd_errtext)
    ELSE
        errtext_len := sizeof (tsp00_ErrText);
    (*ENDIF*) 
    IF  len + errtext_len <= sizeof (ln)
    THEN
        SAPDB_PascalFill ('VKB38 ',  36,    
              sizeof (ln), @ln, len + 1, errtext_len,
              c_undef_fill, err);
    (*ENDIF*) 
    END;
(*ENDIF*) 
len := len + errtext_len;
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38his_date_write (
            VAR date : tsp00_Date;
            VAR len : tsp00_Int4;
            VAR ln  : tsp00_Buf);
 
BEGIN
IF  len + sizeof (date) <= sizeof (ln)
THEN
    IF  date <> bsp_date
    THEN
        BEGIN
        ln [len+1] := date [1];
        ln [len+2] := date [2];
        ln [len+3] := date [3];
        ln [len+4] := date [4];
        ln [len+5] := '-';
        ln [len+6] := date [5];
        ln [len+7] := date [6];
        ln [len+8] := '-';
        ln [len+9] := date [7];
        ln [len+10]:= date [8]
        END
    ELSE
        BEGIN
        ln [len+1] := '?';
        ln [len+2] := ' ';
        ln [len+3] := ' ';
        ln [len+4] := ' ';
        ln [len+5] := ' ';
        ln [len+6] := ' ';
        ln [len+7] := ' ';
        ln [len+8] := ' ';
        ln [len+9] := ' ';
        ln [len+10]:= ' '
        END;
    (*ENDIF*) 
(*ENDIF*) 
len := len + sizeof (date) + 2
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38his_media_write (
            glob       : tkb3_save_static_ptr;
            VAR len    : tsp00_Int4;
            VAR ln     : tsp00_Buf;
            VAR err    : tgg00_BasisError);
 
BEGIN
WITH glob^ DO
    BEGIN
    IF  len + sizeof (tgg00_MediaName) <= sizeof (ln)
    THEN
        SAPDB_PascalMove ('VKB38 ',  37,    
              sizeof (sta_media_name), sizeof (ln),
              @sta_media_name, 1, @ln, len + 1,
              sizeof (tgg00_MediaName), err)
    ELSE
        SAPDB_PascalFill ('VKB38 ',  38,    
              sizeof (ln), @ln, len + 1,
              sizeof (tgg00_MediaName),
              c_undef_fill, err);
    (*ENDIF*) 
    len := len + sizeof (tgg00_MediaName)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38mdf_medium_def_write (
            glob       : tkb3_save_static_ptr;
            taskId     : tsp00_TaskId;
            tape_no    : tsp00_Int2;
            version_no : tsp00_Int4);
 
VAR
      berr         : tgg00_BasisError;
      verr         : tsp00_VfReturn;
      buf_len      : tsp00_Int4;
      ln_len       : tsp00_Int4;
      count        : tsp00_Int4;
      total_length : tsp00_Int4;
      ln_ptr       : ^tsp00_Line;
      k_label      : tsp00_C14;
      dummy_errtxt : tsp00_ErrText;
      buf          : tsp00_Buf;
 
BEGIN
(* PTS 1104316 UH 25-10-1999 changed to external name *)
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
berr    := e_ok;
verr    := vf_ok;
k_label := bsp_c14;
kb38set_label (glob^.sta_msg2type, version_no, k_label, berr);
total_length :=
      sizeof (glob^.sta_utilcmd_id.utidId_gg00) + 1 +
      sizeof (k_label)              + 1 +
      sizeof (tgg00_MediaName)      + 1 +
      sizeof (glob^.sta_tape^ [1].tpd_name) + 2;
IF  (berr = e_ok) AND (tape_no <> ckb3_nil_tape_no)
    AND
    (total_length <= sizeof (buf))
THEN
    WITH glob^, sta_tape^ [tape_no] DO
        BEGIN
        (* *)
        SAPDB_PascalMove ('VKB38 ',  39,    
              sizeof (glob^.sta_utilcmd_id.utidId_gg00), sizeof (buf),
              @glob^.sta_utilcmd_id.utidId_gg00, 1, @buf, 1,
              sizeof (glob^.sta_utilcmd_id.utidId_gg00), berr);     (* PTS 1000431 UH *)
        buf_len := sizeof (glob^.sta_utilcmd_id.utidId_gg00) + 1;   (* PTS 1000431 UH *)
        buf [buf_len] := c_sep;                         (* PTS 1000431 UH *)
        (* *)
        SAPDB_PascalMove ('VKB38 ',  40,    
              sizeof (k_label), sizeof (buf),
              @k_label, 1, @buf, buf_len + 1,
              c_kern_label_len, berr);                   (* PTS 1000431 UH *)
        buf_len       := buf_len + c_kern_label_len + 1; (* PTS 1000431 UH *)
        buf [buf_len] := c_sep;
        (* *)
        kb38his_media_write (glob, buf_len, buf, berr);  (* PTS 1000678 UH *)
        buf_len       := buf_len + 1;                    (* PTS 1000678 UH *)
        buf [buf_len] := c_sep;                          (* PTS 1000678 UH *)
        (* *)
        ln_ptr := @buf [buf_len+1];                      (* PTS 1000678 UH *)
        ln_len := 0;                                     (* PTS 1000678 UH *)
        g17vftype (tpd_type, ln_len, ln_ptr^);           (* PTS 1000678 UH *)
        buf_len       := buf_len + ln_len + 1;           (* PTS 1000678 UH *)
        buf [buf_len] := c_sep;                          (* PTS 1000678 UH *)
        (* *)
        IF  sta_file_version > 0                         (* PTS 1000678 UH *)
        THEN
            BEGIN
            buf [buf_len+1] := 'Y';                      (* PTS 1000678 UH *)
            buf [buf_len+2] := 'E';                      (* PTS 1000678 UH *)
            buf [buf_len+3] := 'S';                      (* PTS 1000678 UH *)
            END
        ELSE
            BEGIN
            buf [buf_len+1] := 'N';                      (* PTS 1000678 UH *)
            buf [buf_len+2] := 'O';                      (* PTS 1000678 UH *)
            buf [buf_len+3] := ' ';                      (* PTS 1000678 UH *)
            END;
        (*ENDIF*) 
        buf_len       := buf_len + 4;                    (* PTS 1000678 UH *)
        buf [buf_len] := c_sep;                          (* PTS 1000678 UH *)
        (* *)
        ln_ptr := @buf [buf_len+1];                      (* PTS 1000678 UH *)
        IF  tpd_max_pages = csp_maxint4                  (* PTS 1000678 UH *)
        THEN
            count := 0
        ELSE
            count := tpd_max_pages;
        (*ENDIF*) 
        g17int4to_line (count, NOT c_with_zeros,
              c_num_len, 1, ln_ptr^);                    (* PTS 1000678 UH *)
        buf_len       := buf_len + c_num_len + 1;        (* PTS 1000678 UH *)
        buf [buf_len] := c_sep;                          (* PTS 1000678 UH *)
        (* *)
        ln_ptr := @buf [buf_len+1];                      (* PTS 1000678 UH *)
        g17int4to_line (sta_blocksize, NOT c_with_zeros,
              c_num_len, 1, ln_ptr^);                    (* PTS 1000678 UH *)
        buf_len       := buf_len + c_num_len + 1;        (* PTS 1000678 UH *)
        buf [buf_len] := c_sep;                          (* PTS 1000678 UH *)
        (* *)
        (* PTS 1102775 UH 19990527 begin *)
        IF  tpd_is_replaced            (* PTS 1109736 mb 2002-09-23 *)
        THEN
            buf [buf_len+1]     := 'R'  (* replaced device *)
        ELSE
            IF  sta_num_tapes > 1
            THEN
                buf [buf_len+1] := 'M'  (* multiple devices medium *)
            ELSE
                buf [buf_len+1] := 'S'; (* single   device  medium *)
            (*ENDIF*) 
        (*ENDIF*) 
        buf_len       := buf_len + 2;
        buf [buf_len] := c_sep;
        (* PTS 1102775 UH 19990527 end *)
        (* *)
        SAPDB_PascalMove ('VKB38 ',  41,    
              sizeof (tpd_name), sizeof (buf),
              @tpd_name, 1, @buf, buf_len + 1, sizeof (tpd_name), berr);
        (* *)
        IF  berr = e_ok
        THEN
            BEGIN
            buf_len := buf_len + sizeof (tpd_name);
            kb38append_to_mediumdef (taskId, buf, buf_len, verr, dummy_errtxt);
&           ifdef TRACE
            t01p2int4 (kb_save, 'tape_no     ', tape_no
                  ,             'vbackup_medi', ord(verr));
&           endif
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38his_time_write (
            VAR time : tsp00_Time;
            VAR len : tsp00_Int4;
            VAR ln  : tsp00_Buf);
 
BEGIN
IF  len + sizeof (time) <= sizeof (ln)
THEN
    IF  time <> bsp_time
    THEN
        BEGIN
        ln [len+1] := time [3];
        ln [len+2] := time [4];
        ln [len+3] := ':';
        ln [len+4] := time [5];
        ln [len+5] := time [6];
        ln [len+6] := ':';
        ln [len+7] := time [7];
        ln [len+8] := time [8]
        END
    ELSE
        BEGIN
        ln [len+1] := '?';
        ln [len+2] := ' ';
        ln [len+3] := ' ';
        ln [len+4] := ' ';
        ln [len+5] := ' ';
        ln [len+6] := ' ';
        ln [len+7] := ' ';
        ln [len+8] := ' '
        END;
    (*ENDIF*) 
(*ENDIF*) 
len := len + sizeof (time)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38hm_task_creation (
            VAR parent_t : tgg00_TransContext;
            glob         : tkb3_save_static_ptr;
            err_tape_no  : tsp00_Int2);
 
VAR
      tape_task    : tkb3_savetasks;
      devsp_task   : tkb3_savetasks;
      curr_devsp   : integer;
      curr_tape    : integer;
      curr_task    : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (parent_t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^ DO
    BEGIN
    IF  sta_msgtype = m_save_parallel
    THEN
        BEGIN
        tape_task  := task_twt;
        devsp_task := task_drt
        END
    ELSE
        BEGIN
        tape_task  := task_trt;
        devsp_task := task_dwt
        END;
    (*ENDIF*) 
    curr_task  := 1;
    curr_devsp := 1;
    curr_tape  := 1;
    WHILE (curr_tape <= sta_num_tapes)
          AND
          (parent_t.trError_gg00 = e_ok) DO
        BEGIN
        IF  curr_tape <> err_tape_no
        THEN
            kb38run_task (parent_t, glob, tape_task, curr_task,
                  ckb3_nil_devsp_no, curr_tape)
        ELSE
            sta_task_for_conttape := curr_task;
        (*ENDIF*) 
        curr_tape := curr_tape + 1;
        curr_task := curr_task + 1
        END;
    (*ENDWHILE*) 
    WHILE (curr_devsp <= sta_num_devsp)
          AND
          (parent_t.trError_gg00 = e_ok) DO
        BEGIN
        kb38run_task (parent_t, glob, devsp_task, curr_task,
              curr_devsp, ckb3_nil_tape_no);
        curr_task  := curr_task  + 1;
        curr_devsp := curr_devsp + 1
        END;
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
&ifdef TRACE
t01basis_error (kb_save, 'end hm_task ', parent_t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38i_run_task_init (
            VAR trans       : tgg00_TransContext;
            glob            : tkb3_save_static_ptr;
            which_task      : tkb3_savetasks;
            task_no         : tsp00_Int2;
            tape_no         : tsp00_Int2);
 
VAR
      i2 : tsp00_IntMapC2;
      ln : tsp00_Line;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
(*ENDIF*) 
t01int4 (kb_save, 'task_no     ', task_no);
t01int4 (kb_save, 'tape_no     ', tape_no);
&endif
trans.trError_gg00 := e_ok;
WITH glob^.sta_task^ [task_no] DO
    BEGIN
    tsd_task_pid    := cgg_nil_pid;
    tsd_tape_index  := tape_no;
    tsd_state       := ts_started;
    tsd_task_kind   := which_task
    END;
(*ENDWITH*) 
IF  g01vtrace.vtrAll_gg00
THEN
    BEGIN
    ln [1]         := chr (ord (kb38run_save));
    ln [2]         := chr (ord (which_task  ));
    i2.mapInt_sp00 := task_no;
    ln [3]         := i2.mapC2_sp00 [1];
    ln [4]         := i2.mapC2_sp00 [2];
    IF  tape_no = ckb3_nil_tape_no
    THEN
        i2.mapInt_sp00 := ckb3_nil_devsp_no
    ELSE
        i2.mapInt_sp00 := tape_no;
    (*ENDIF*) 
    ln [5] := i2.mapC2_sp00 [1];
    ln [6] := i2.mapC2_sp00 [2];
    b120InsertTrace (trans, kb, glob^.sta_vtr_direction, 6, @ln)
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38init_log_save (
            VAR t        : tgg00_TransContext;
            glob         : tkb3_save_static_ptr;
            for_autosave : boolean;
            complete_log : boolean);
 
VAR
      first_offset  : tsp00_PageNo;
      first_iosequence    : tsp00_PageNo;
      last_iosequence     : tsp00_PageNo;
      file_version  : tsp00_Int4;
      int1_date     : tsp00_Int4;
      int1_time     : tsp00_Int4;
      int2_date     : tsp00_Int4;
      int2_time     : tsp00_Int4;
      aux_id        : tsp00_Line; (* PTS 1000449 UH 19980909 *)
      pageCount     : tsp00_Int4; (* PTS 1138588 mb 2005-11-01 *)
 
BEGIN
(*vendexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);*)
first_offset      := NIL_PAGE_NO_GG00;
first_iosequence  := NIL_PAGE_NO_GG00;
last_iosequence   := NIL_PAGE_NO_GG00;
file_version      := -1;
WITH glob^ DO
    BEGIN
    k560check_logsave_allowed ( t.trTaskId_gg00, t.trError_gg00);
    IF  t.trError_gg00 = e_ok
    THEN
        BEGIN
        kb391InitLogSaveIterator ( t,
              sta_blocksize,
              sta_is_cold,
              for_autosave,
              complete_log,
              sta_no_release_log);
        IF  t.trError_gg00 = e_ok
        THEN
            BEGIN
            kb391GetSaveIterInfo(
                  int1_time,int1_date, (* starttime startdate *)
                  int2_time,int2_date, (* endtime enddate *)
                  first_iosequence, last_iosequence,
                  pageCount,            (* PTS 1138588 mb 2005-11-01 *)
                  file_version );
            first_offset := 0 (* not used anymore, but initialized *)
            END; (* IF *)
        (*ENDIF*) 
        kb560GetLogDBIdent(aux_id); (* PTS 1113550 mb 2002-03-22 *)
        (*vendexcl (t.trTaskId_gg00, g08savepoint);*)
        (*vbegexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);*)
        IF  t.trError_gg00 = e_ok
        THEN
            WITH sta_info, sta_devsp^[ckb3_log_devsp_no] DO
                BEGIN
                sta_num_devsp      := ckb3_log_devsp_no;
                inf_first_iosequence     := first_iosequence;
                inf_last_iosequence      := last_iosequence;
                inf_bd_page_count    := pageCount;
                inf_file_version   := file_version;
                inf_db_ident       := aux_id; (* PTS 1000449 UH 19980909 *)
                g17intdate_time (int1_date, int1_time,
                      inf_dbstamp1_date, inf_dbstamp1_time);
                g17intdate_time (int2_date, int2_time,
                      inf_dbstamp2_date, inf_dbstamp2_time)
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END; (* WITH *)
(*ENDWITH*) 
IF  (t.trError_gg00 <> e_ok) AND
    (NOT (for_autosave AND (t.trError_gg00 = e_incomplete_logsegm)))
THEN
    kb38history_write (glob, t.trTaskId_gg00, ckb3_nil_tape_no, t.trError_gg00);
&ifdef TRACE
(*ENDIF*) 
t01basis_error (kb_save, 'end ini savl', t.trError_gg00);
t01p2int4      (kb_save, 'first_ioseq ', first_iosequence
      ,                  'last_ioseq  ', last_iosequence);
t01p2int4      (kb_save, 'file version', file_version
      ,                  'first_offset', first_offset);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38info_init (
            glob          : tkb3_save_static_ptr;
            VAR my_info   : tkb3_info_stuff);
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^, my_info DO
    BEGIN
    vdattime (inf_start_date, inf_start_time);
    g11kernel_version (inf_curr_knlvers);
    g11kernel_version (inf_knlvers);
    inf_pno            := 0;
    inf_pt             := ptSave_egg00;
    inf_pt2            := pt2Nil_egg00;
    inf_check          := chckNil_egg00;
    inf_filler1        := false;
    inf_mess_type      := m_nil;
    inf_mess2_type     := mm_nil;
    (* UWE REIHENFOLGE ! *)
    inf_volume_no      := 0;
    inf_max_volume_no  := 0;
    inf_page_count     := 0;
    inf_save_blocksize := sta_blocksize;
    inf_end_date       := bsp_date;
    inf_end_time       := bsp_time;
    inf_dbstamp1_date  := bsp_date;
    inf_dbstamp1_time  := bsp_time;
    inf_dbstamp2_date  := bsp_date;
    inf_dbstamp2_time  := bsp_time;
    inf_serverdb       := g01serverdb_ident.svServerdb_gg04;
    inf_servernode     := g01serverdb_ident.svServernode_gg04;
    kb560InvalidateIOSeq( inf_first_iosequence ); (* PTS 1116063 mb 2002-06-13 *)
    kb560InvalidateIOSeq( inf_last_iosequence ); (* PTS 1116063 mb 2002-06-13 *)
    inf_is_consistent  := true;
    inf_is_clustered   := false;
    inf_vol_page_cnt   := 0;
    inf_swap_check     := ckb3_swap_check_no;
    inf_bd_page_count  := 0;
    inf_file_version   := 0;
    inf_tapes_used     := 0;
    inf_label          := bsp_c14;
    inf_filler3        := bsp_c2;  (* PTS 1000449 UH 19980909 *)
    (*inf_db_ident     := bsp_line    PTS 1000449 UH 19980909 *)
    inf_max_used_data_pno := NIL_PAGE_NO_GG00; (* PTS 1105071 UH 17-01-2000 *)
    inf_conv_page_count   := 0;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      kb38is_tape_missing (glob : tkb3_save_static_ptr) : boolean;
 
VAR
      is_save    : boolean;
      is_restore : boolean;
      tape_found : boolean;
      i          : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^ DO
    BEGIN
    is_restore := sta_msgtype in [m_restore_parallel, m_restore];
    IF  is_restore AND (sta_msg2type = mm_log)
    THEN
        kb38is_tape_missing := false
    ELSE
        BEGIN
        tape_found := false;
        i          := 1;
        REPEAT
            IF  (sta_task^[i].tsd_state     <> ts_none) AND
                (sta_task^[i].tsd_tape_index > 0      )
            THEN
                tape_found := true
            ELSE
                i := i + 1
            (*ENDIF*) 
        UNTIL
            (i > sta_num_tapes + sta_num_devsp) OR tape_found;
        (*ENDREPEAT*) 
        is_save    :=
              (sta_msgtype = m_save_parallel) OR
              (sta_msgtype = m_autosave     );
        kb38is_tape_missing := NOT tape_found
              AND (
              (sta_read_tasks_waiting  > 0)
              OR
              (sta_write_tasks_waiting > 0)
              OR
              (is_save    AND (sta_queue_first_read > 0))
              OR
              (is_restore AND NOT(sy_knockoffwork in sta_system_state)))
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38label_handling (
            VAR m : tgg00_MessBlock;
            glob : tkb3_save_static_ptr);
 
VAR
      tape_no : tsp00_Int2;
      aux_err : tgg00_BasisError;
      my_info : tkb3_info_stuff;
 
BEGIN
m.mb_trns^.trError_gg00 := e_ok;
tape_no := 0;
vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
glob^.sta_to_cancel := NIL;
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    IF  NOT (sy_initialized in glob^.sta_system_state)
    THEN
        kb38glob_init (glob, m.mb_type, m.mb_type2);
    (*ENDIF*) 
    IF  glob^.sta_conttape > 0
    THEN
        tape_no := glob^.sta_conttape
    ELSE
        kb38get_tape_no (glob,
              m.mb_qual^.msave_restore.sripHostTapenames_gg00 [1], tape_no);
    (*ENDIF*) 
    IF  tape_no > 0
    THEN
        WITH glob^.sta_tape^ [tape_no], m.mb_qual^.msave_restore DO
            BEGIN
            tpd_is_open         := false;
            tpd_is_full         := false;
            tpd_volume_no       := 0;
            tpd_fno             := 0;
            tpd_max_pages       := MAX_INT4_SP00;
            tpd_cnt_pages       := 0;
            tpd_total_cnt_pages := 0;
            tpd_name            := sripHostTapenames_gg00 [1];
            tpd_type            := sripHostFiletypes_gg00 [1];
            tpd_errtext         := bsp_c40;
            tpd_xp_size         := 0;
            tpd_xp_read         := 0;
            tpd_xp_pages        := 0;
            tpd_mirror_index    := 0;
            tpd_err             := e_ok;
            END
        (*ENDWITH*) 
    ELSE
        m.mb_trns^.trError_gg00 := e_wrong_hostfile;
    (*ENDIF*) 
    IF  m.mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        kb391InputParameters (m, glob);
        glob^.sta_blocksize := m.mb_qual^.msave_restore.sripBlocksize_gg00;
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    CASE m.mb_type2 OF
        mm_fread:
            BEGIN
            k38tapeopen_one (m.mb_trns^, glob, tape_no,
                  NOT c_for_writing, c_for_readlabel);
            IF  m.mb_trns^.trError_gg00 = e_ok
            THEN
                k39read_label (m.mb_trns^, glob, tape_no, my_info);
            (*ENDIF*) 
            m.mb_data_len := 0;
            m.mb_struct   := mbs_buf;
            IF  m.mb_trns^.trError_gg00 = e_ok
            THEN
                (* PTS 1000397 UH *)
                BEGIN
                kb38build_userinfo (m.mb_trns^.trTaskId_gg00, glob,
                      NOT c_is_get_state, c_label_handling,
                      tape_no, tape_no, my_info,
                      m.mb_qual^.buf, m.mb_qual_size, m.mb_qual_len);
                m.mb_type := m_return_result
                END
            ELSE (* CR 1000053 UH *)
                BEGIN
                m.mb_qual_len := 0;
                m.mb_type     := m_return_error
                END
            (*ENDIF*) 
            END;
        OTHERWISE
            m.mb_trns^.trError_gg00 := e_invalid
        END;
    (*ENDCASE*) 
(*ENDIF*) 
IF  (tape_no > 0) AND (m.mb_type2 = mm_fread)
THEN
    WITH glob^.sta_tape^[tape_no] DO
        IF  tpd_is_open
        THEN
            BEGIN
            aux_err := m.mb_trns^.trError_gg00;
            k38closeasyn (m.mb_trns^, glob, NOT c_auto_load,
                  c_force_rewind, tape_no, tpd_is_open, tpd_fno);
            IF  aux_err <> e_ok
            THEN
                m.mb_trns^.trError_gg00 := aux_err
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 <> e_ok) AND (tape_no > 0)
THEN
    kb38put_errtext (m.mb_trns^.trTaskId_gg00, glob, tape_no);
(*ENDIF*) 
IF  NOT (sy_bup_working in glob^.sta_system_state)
THEN
    (* clear all states *)
    kb38glob_init (glob, glob^.sta_msgtype, glob^.sta_msg2type);
(*ENDIF*) 
glob^.sta_to_cancel := NIL;
vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
IF  (m.mb_type2 <> mm_fread) OR (m.mb_trns^.trError_gg00 <> e_ok)
THEN
    BEGIN
    m.mb_struct    := mbs_nil;
    m.mb_type      := m_return_error;
    m.mb_qual_len  := 0;
    m.mb_data_len  := 0
    END;
(*ENDIF*) 
m.mb_type2 := mm_nil
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38log_restore_end_check (
            VAR t               : tgg00_TransContext;
            glob                : tkb3_save_static_ptr;
            check_new_tape      : boolean;
            handling_type       : tgg00_MessType2;
            VAR stop_headmaster : boolean);
 
VAR
      i                   : tsp00_Int2;
      first_lpno_on_disk  : tsp00_PageNo;
      first_lpno_is_valid : boolean;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
t.trError_gg00        := e_ok;
stop_headmaster := false;
WITH glob^ DO
    BEGIN
    IF  sy_knockoffwork in sta_system_state
    THEN
        (* log-writer finished or user wanted ignore *)
        BEGIN
        stop_headmaster := true;
        i               := 1;
        WHILE stop_headmaster
              AND (i <= sta_num_tapes + sta_num_devsp) DO
            IF  sta_task^[i].tsd_state <> ts_none
            THEN
                stop_headmaster := false
            ELSE
                i := i + 1
            (*ENDIF*) 
        (*ENDWHILE*) 
        END
    ELSE
        IF  check_new_tape
        THEN
            BEGIN
            kb560GetFirstKnownIOSeqBeforeRestoreLog(first_lpno_on_disk,first_lpno_is_valid);
            IF  ( (NOT first_lpno_is_valid) AND
                (handling_type      <> mm_ignore )
                )
                OR
                ( first_lpno_is_valid ) (* PTS 1127636 mb 2004-02-09  PTS 1116063 mb 2002-06-13 *)
            THEN
                BEGIN
                stop_headmaster := true;
                t.trError_gg00        := e_new_hostfile_required
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
&ifdef TRACE
t01basis_error (kb_save, 'end check lo', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38t_allowed_for_autosave (
            VAR t   : tgg00_TransContext;
            glob    : tkb3_save_static_ptr;
            tape_no : tsp00_Int2);
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^, sta_tape^ [tape_no] DO
    IF  (tpd_type = vf_t_raw)
        OR
        (tpd_type = vf_t_tape_rew)
        OR
        (tpd_type = vf_t_pipe)
        OR
        ((tpd_type = vf_t_file) AND (sta_file_version <= 0))
        OR
        (tpd_type = vf_t_unknown)
    THEN
        BEGIN
        k38closeasyn (t, glob, NOT c_auto_load, NOT c_force_rewind,
              tape_no, tpd_is_open, tpd_fno);
        tpd_errtext    := c_invalid_filetype;
        t.trError_gg00 := e_not_implemented
        END;
&   ifdef TRACE
    (*ENDIF*) 
(*ENDWITH*) 
t01basis_error (kb_save, 'end allowed ', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38open_autosave_tape (
            VAR t   : tgg00_TransContext;
            glob    : tkb3_save_static_ptr;
            tape_no : tsp00_Int2);
 
BEGIN
WITH glob^, sta_tape^ [tape_no] DO
    BEGIN
    IF  sta_file_version > 0
    THEN
        kb38change_version_in_filename (tpd_name, sta_file_version,
              t.trError_gg00);
    (*ENDIF*) 
    IF  (t.trError_gg00 = e_ok)
        AND
        (tpd_type = vf_t_tape_norew) (* PTS 1000422 UH *)
    THEN
        kb38t_check_tape_age (t, glob, tape_no, sta_until_date);
    (*ENDIF*) 
    IF  t.trError_gg00 = e_ok
    THEN
        k38tapeopen_one (t, glob, tape_no, c_for_writing,
              NOT c_for_readlabel)
    ELSE
        g01optextmsg (sp3p_console, sp3m_warning,
              kb38InitAutoSave_csp03,
              csp3_n_autosave, c_invalid_tape_age);
    (*ENDIF*) 
    IF  t.trError_gg00 = e_ok
    THEN
        kb38t_allowed_for_autosave (t, glob, c_autosave_tape_device)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38init_continue_tape (
            VAR m               : tgg00_MessBlock;
            glob                : tkb3_save_static_ptr);
 
VAR
      max_pages : tsp00_Int4;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
IF  glob^.sta_msgtype = m_save_parallel
THEN
    max_pages := m.mb_qual^.msave_restore.sripHostTapecount_gg00 [1]
ELSE
    max_pages := MAX_INT4_SP00;
(*ENDIF*) 
IF  glob^.sta_conttape <= 0
THEN
    m.mb_trns^.trError_gg00 := e_wrong_hostfile
ELSE
    WITH glob^, sta_tape^[glob^.sta_conttape], m.mb_qual^.msave_restore
         DO
        BEGIN
        tpd_is_open         := false;
        tpd_is_full         := false;
        tpd_volume_no       := 0;
        tpd_fno             := 0;
        tpd_is_replaced     := true;
        tpd_cnt_pages       := 0;
        tpd_total_cnt_pages := 0;
        tpd_errtext         := bsp_c40;
        tpd_xp_size         := 0;
        tpd_xp_read         := 0;
        tpd_xp_pages        := 0;
        tpd_type            := sripHostFiletypes_gg00 [1];
        tpd_err             := e_ok;
        tpd_mirror_index    := 0;
        tpd_name            := sripHostTapenames_gg00[1];
        IF  sta_msgtype = m_save_parallel
        THEN
            tpd_max_pages  := max_pages;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
&ifdef TRACE
t01basis_error (kb_save, 'end open_ini', m.mb_trns^.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38parallel_backup (
            VAR m     : tgg00_MessBlock;
            glob      : tkb3_save_static_ptr);
 
VAR
      is_restore_log   : boolean;
      stop_headmaster  : boolean;
      errtext_tape_no  : tsp00_Int2;
      vtr_count        : tsp00_IntMapC2;
      i2               : tsp00_IntMapC2;
      msgtxt           : tsp00_ErrText;
      ln               : tsp00_Line;
      do_glob_init     : boolean; (* PTS 1108964 UH 2001-01-12 *)
      task_no          : tsp00_Int2;
      joberror         : tgg00_BasisError;
      task_type        : tkb3_savetasks;
 
BEGIN
do_glob_init            := true; (* PTS 1108964 UH 2001-01-12 *)
m.mb_trns^.trError_gg00 := e_ok;
errtext_tape_no         := ckb3_nil_tape_no;
task_no                 := ckb3_nil_task_no;
vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
glob^.sta_to_cancel := @m.mb_trns^.trRteCommPtr_gg00^.to_cancel;
is_restore_log :=
      (glob^.sta_msgtype  = m_restore_parallel)
      AND
      (glob^.sta_msg2type = mm_log);
IF  (m.mb_type <> glob^.sta_msgtype)
    OR
    (glob^.sta_blocksize < ckb3_min_pages_per_block)
THEN
    BEGIN
    m.mb_trns^.trError_gg00 := e_invalid;
    k38sys_msg (glob, sp3m_error, kbInvalidCall_csp03,
          c_invalid_call, ord (m.mb_type))
    END
ELSE
    CASE m.mb_type2 OF
        mm_database, mm_pages:
            BEGIN
            IF  NOT glob^.sta_check_save
            THEN
                BEGIN
                IF  (glob^.sta_msgtype  = m_restore_parallel)
                THEN
                    IF  (glob^.sta_msg2type = mm_database)
                    THEN
                        BEGIN
                        bd999CreateAllDataVolumes (m.mb_trns^.trTaskId_gg00, m.mb_trns^.trError_gg00);
                        IF  m.mb_trns^.trError_gg00 <> e_ok
                        THEN
                            bd999DetachAllDataVolumes (m.mb_trns^.trTaskId_gg00)
                        (*ENDIF*) 
                        END
                    ELSE  (* mm_pages *)
                        BEGIN
                        bd999AttachAllDataVolumes( m.mb_trns^.trTaskId_gg00, m.mb_trns^.trError_gg00 )
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  m.mb_trns^.trError_gg00 = e_ok
                THEN
                    kb38d_open_devspaces (m.mb_trns^, glob);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  m.mb_trns^.trError_gg00 = e_ok
            THEN
                kb38hm_task_creation (m.mb_trns^, glob,ckb3_nil_tape_no)
            (*ENDIF*) 
            END;
        mm_log:
            BEGIN
            IF  m.mb_type = m_restore_parallel
            THEN
                BEGIN
                k38tapeopen_one (m.mb_trns^,glob,c_max_log_restore_tapes, NOT c_for_writing, NOT c_for_readlabel);
                IF  (m.mb_trns^.trError_gg00 = e_ok)
                THEN
                    BEGIN
                    k39config_restartrec_from_first_tape (m.mb_trns^,
                          glob,
                          mm_log,
                          c_max_log_restore_tapes,
                          glob^.sta_queue^[ckb3_extra_block].sre_block,
                          glob^.sta_queue^[ckb3_extra_block].sre_is_clustered);
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  m.mb_trns^.trError_gg00 = e_ok
            THEN
                kb38hm_task_creation (m.mb_trns^,glob,errtext_tape_no);
            (*ENDIF*) 
            END;
        mm_newtape:
            BEGIN
            kb38init_continue_tape (m, glob); (* PTS1109736 mb 2002-08-04 *)
            IF  m.mb_trns^.trError_gg00 = e_ok
            THEN
                WITH glob^ DO
                    BEGIN
                    IF  sta_msgtype = m_save_parallel
                    THEN
                        task_type := task_twt
                    ELSE
                        task_type := task_trt;
                    (*ENDIF*) 
                    kb38run_task (m.mb_trns^, glob, task_type,
                          sta_task_for_conttape, ckb3_nil_devsp_no, sta_conttape);
                    sta_task_for_conttape := 0;
                    sta_conttape          := 0
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
            END;
        mm_ignore:
            WITH glob^ DO
                IF  is_restore_log
                THEN
                    BEGIN
                    kb38log_restore_end_check (m.mb_trns^, glob,
                          c_check_new_tape, mm_ignore, stop_headmaster);
                    IF  m.mb_trns^.trError_gg00 = e_new_hostfile_required
                    THEN
                        BEGIN
                        m.mb_trns^.trError_gg00 := e_wrong_hostfile;
                        errtext_tape_no   := glob^.sta_conttape;
                        glob^.sta_tape^[errtext_tape_no].tpd_errtext
                              := c_tape_missing
                        END
                    ELSE
                        k39wakeup_all (glob, m.mb_trns^.trTaskId_gg00)
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDWITH*) 
        OTHERWISE ;
        END;
    (*ENDCASE*) 
(*ENDIF*) 
vtr_count.mapInt_sp00 := 0;
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    IF  is_restore_log
    THEN
        kb38log_restore_end_check (m.mb_trns^, glob,
              NOT c_check_new_tape, mm_nil, stop_headmaster)
    ELSE
        kb38ready_check (glob, stop_headmaster)
    (*ENDIF*) 
    END
ELSE
    stop_headmaster := true;
(*ENDIF*) 
WHILE (m.mb_trns^.trError_gg00 = e_ok) AND NOT stop_headmaster DO
    (* headmaster activity loop *)
    BEGIN
    IF  kb38is_tape_missing (glob)
    THEN
        BEGIN
        m.mb_trns^.trError_gg00 := e_wrong_hostfile;
        errtext_tape_no   := glob^.sta_conttape;
        glob^.sta_tape^[errtext_tape_no].tpd_errtext := c_tape_missing
        END
    ELSE
        BEGIN
        IF  g01vtrace.vtrAll_gg00
        THEN
            BEGIN
            ln [1] := chr (ord (kb38hm_wait));
            IF  vtr_count.mapInt_sp00 >= MAX_INT2_SP00
            THEN
                vtr_count.mapInt_sp00 := 0
            ELSE
                vtr_count.mapInt_sp00 := vtr_count.mapInt_sp00 + 1;
            (*ENDIF*) 
            ln [2] := vtr_count.mapC2_sp00 [1];
            ln [3] := vtr_count.mapC2_sp00 [2];
            b120InsertTrace (m.mb_trns^, kb,
                  glob^.sta_vtr_direction, 3, @ln)
            END;
        (* leave region in next function *)
        (*ENDIF*) 
        kb900WaitForAnyBackupJobFinished (m.mb_trns^, glob^.sta_backup_server,
              glob^.sta_region, task_no, joberror);
        IF  m.mb_trns^.trError_gg00 = e_cancelled
        THEN
            k39wakeup_all (glob, m.mb_trns^.trTaskId_gg00);
        (*ENDIF*) 
        IF  (m.mb_trns^.trError_gg00 = e_ok) AND g01vtrace.vtrAll_gg00
            AND
            (task_no <> cgg_nil_child)
        THEN
            WITH glob^.sta_task^ [task_no] DO
                BEGIN
                ln [1] := chr (ord (kb38end_save ));
                ln [2] := chr (ord (tsd_task_kind));
                i2.mapInt_sp00 := task_no;
                ln [3] := i2.mapC2_sp00 [1];
                ln [4] := i2.mapC2_sp00 [2];
                IF  tsd_tape_index = ckb3_nil_tape_no
                THEN
                    i2.mapInt_sp00 := ckb3_nil_devsp_no
                ELSE
                    i2.mapInt_sp00 := tsd_tape_index;
                (*ENDIF*) 
                ln [5] := i2.mapC2_sp00 [1];
                ln [6] := i2.mapC2_sp00 [2];
                i2.mapInt_sp00 := joberror;
                ln [7] := i2.mapC2_sp00 [1];
                ln [8] := i2.mapC2_sp00 [2];
                b120InsertTrace (m.mb_trns^,kb,glob^.sta_vtr_direction,8, @ln)
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (m.mb_trns^.trError_gg00 = e_ok)
        AND
        (task_no <> cgg_nil_child)
    THEN
        BEGIN
        glob^.sta_task^ [task_no].tsd_state := ts_none;
        IF  joberror <> e_ok
        THEN
            m.mb_trns^.trError_gg00 := joberror
        ELSE
            IF  is_restore_log
            THEN
                kb38log_restore_end_check (m.mb_trns^, glob,
                      c_check_new_tape, mm_nil, stop_headmaster)
            ELSE
                kb38treat_received_stuff (m.mb_trns^, glob,
                      task_no, stop_headmaster);
            (*ENDIF*) 
        (*ENDIF*) 
        WITH glob^, sta_task^ [task_no] DO
            IF  (tsd_task_kind = task_trt) OR
                (tsd_task_kind = task_twt)
            THEN
                BEGIN
                sta_conttape          := tsd_tape_index;
                sta_task_for_conttape := task_no;
                IF  m.mb_trns^.trError_gg00 <> e_ok
                THEN
                    errtext_tape_no := sta_conttape
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDWITH*) 
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
&ifdef TRACE
IF  sy_initialized in glob^.sta_system_state
THEN
    BEGIN
    k38view_into_saveregion (glob,
          'VIEW when FINISH  ', NOT c_show_q_only);
    k38show_monitor (glob)
    END;
&endif
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    WITH glob^ DO
        BEGIN
        IF  (sta_msgtype  <> m_restore_parallel)
            OR
            (sta_msg2type <> mm_log)
        THEN
            kb38queue_check (m.mb_trns^, glob)
        ELSE
            BEGIN
            IF  (sta_read_tasks_waiting  <> 0)
                OR
                (sta_write_tasks_waiting <> 0)
            THEN
                BEGIN
                m.mb_trns^.trError_gg00 := e_queue_mismatch;
                IF  g01vtrace.vtrAll_gg00
                THEN
                    BEGIN
                    ln [1] := chr(ord(kb38que_state));
                    ln [2] := chr (c_child_running);
                    b120InsertTrace (m.mb_trns^, kb, sta_vtr_direction, 2, @ln)
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    IF  glob^.sta_msgtype = m_save_parallel
    THEN
        kb38write_eof_block_to_open_tapes (m.mb_trns^, glob,
              errtext_tape_no);
    (*ENDIF*) 
    IF  m.mb_trns^.trError_gg00 = e_ok
    THEN
        kb38closeall (m.mb_trns^, glob, errtext_tape_no);
    (*ENDIF*) 
    IF  m.mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
        IF  glob^.sta_msgtype = m_restore_parallel
        THEN
            BEGIN
            IF  NOT glob^.sta_check_save
            THEN
                kb38end_incopy (m.mb_trns^, glob)
            (*ENDIF*) 
            END
        ELSE
            kb38end_outcopy (m.mb_trns^, glob);
        (*ENDIF*) 
        vbegexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region)
        END
    (*ENDIF*) 
    END;
(* PTS 1108964 UH 2001-01-12 removed *)
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_ok                   )
    OR
    (m.mb_trns^.trError_gg00 = e_new_hostfile_required)
    OR
    (m.mb_trns^.trError_gg00 = e_wrong_hostfile       )
    OR
    (m.mb_trns^.trError_gg00 = e_save_skipped         )
    OR
    (m.mb_trns^.trError_gg00 = e_incompatible_log     )
    OR
    (m.mb_trns^.trError_gg00 = e_invalid_label        )
    (* PTS 1124310 mb 2003-09-19 errors, which can be solved by changing the tape *)
THEN
    BEGIN
    kb38build_userinfo (m.mb_trns^.trTaskId_gg00, glob, (* PTS 1000397 UH *)
          NOT c_is_get_state, NOT c_label_handling,
          glob^.sta_conttape, errtext_tape_no, glob^.sta_info,
          m.mb_qual^.buf, m.mb_qual_size, m.mb_qual_len);
    m.mb_data_len := 0;               (* PTS 1000397 UH *)
    m.mb_struct   := mbs_buf;         (* PTS 1000397 UH *)
    m.mb_type     := m_return_result; (* PTS 1000397 UH *)
    IF  m.mb_trns^.trError_gg00 = e_ok
    THEN
        (* PTS 1108964 UH 2001-01-12 *)
        msgtxt := c_is_ok
    ELSE
        BEGIN
        msgtxt := c_is_tapeswap;
        do_glob_init  := false; (* PTS 1108964 UH 2001-01-12 *)
        END;
    (*ENDIF*) 
    END
ELSE
    BEGIN
    IF  errtext_tape_no > 0
    THEN
        kb38put_errtext (m.mb_trns^.trTaskId_gg00, glob, errtext_tape_no);
    (*ENDIF*) 
    kb38abort_handling (m.mb_trns^, glob);
    msgtxt        := c_is_error;
    m.mb_struct   := mbs_nil;
    m.mb_type     := m_return_error;
    m.mb_qual_len := 0;
    m.mb_data_len := 0
    END;
(*ENDIF*) 
(* PTS 1108964 UH 2001-01-12 added *)
IF  (m.mb_trns^.trError_gg00 <> e_save_skipped         )
    AND
    (m.mb_trns^.trError_gg00 <> e_no_data_on_tape      )
THEN
    IF  m.mb_trns^.trError_gg00 = e_new_hostfile_required
    THEN
        (* PTS 1104593 UH 11-11-1999 *)
        BEGIN
        IF  is_restore_log (* PTS 1104174 UH 25-10-1999 *)
        THEN
            kb38history_write (glob,m.mb_trns^.trTaskId_gg00, errtext_tape_no, e_ok)
        (*ENDIF*) 
        END
    ELSE
        kb38history_write (glob,m.mb_trns^.trTaskId_gg00, errtext_tape_no, m.mb_trns^.trError_gg00);
    (*ENDIF*) 
(*ENDIF*) 
;
(* PTS 1108964 UH 2001-01-12 *)
IF  do_glob_init
THEN
    (* clear all states *)
    kb38glob_init (glob, glob^.sta_msgtype, glob^.sta_msg2type);
(*ENDIF*) 
vendexcl (m.mb_trns^.trTaskId_gg00, g08save0 + glob^.sta_region);
CASE m.mb_trns^.trError_gg00 OF
    e_ok, e_new_hostfile_required, e_incompatible_log,
    e_save_skipped, e_no_data_on_tape:
        k38sys_msg (glob, sp3m_info, kbEndHeadMaster_csp03,
              msgtxt, ord(m.mb_trns^.trError_gg00));
    e_wrong_hostfile:
        k38sys_msg (glob, sp3m_warning, kbEndHeadMaster_csp03,
              msgtxt, ord(m.mb_trns^.trError_gg00));
    OTHERWISE
        k38sys_msg (glob, sp3m_error, kbEndHeadMaster_csp03,
              msgtxt, ord(m.mb_trns^.trError_gg00));
    END;
(*ENDCASE*) 
m.mb_type2 := mm_nil;
&ifdef TRACE
t01basis_error (kb_save, 'end headmast', m.mb_trns^.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38post_autosave_work (
            VAR t : tgg00_TransContext;
            glob : tkb3_save_static_ptr);
 
VAR
      aux_err       : tgg00_BasisError;
      dummy_errtext : tsp00_Int2;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
dummy_errtext := ckb3_nil_tape_no;
kb38write_eof_block_to_open_tapes (t, glob, dummy_errtext);
IF  t.trError_gg00 = e_ok
THEN
    BEGIN
    WITH glob^, sta_tape^ [c_autosave_tape_device],
         sta_devsp^[c_autosave_log_device] DO
        CASE tpd_type OF
            vf_t_tape_norew:
                BEGIN
                kb38tape_flush (t, glob, tpd_fno, tpd_name,tpd_errtext);
                IF  t.trError_gg00 <> e_ok
                THEN
                    tpd_is_open := false;
                (*ENDIF*) 
                IF  (tpd_mirror_index > 0)
                    AND
                    (t.trError_gg00 = e_ok)
                THEN
                    BEGIN
                    t.trError_gg00 := e_ok;
                    kb38tape_flush (t, glob,
                          sta_tape^ [tpd_mirror_index].tpd_fno,
                          sta_tape^ [tpd_mirror_index].tpd_name,
                          sta_tape^ [tpd_mirror_index].tpd_errtext);
                    IF  t.trError_gg00 <> e_ok
                    THEN
                        BEGIN
                        sta_tape^ [tpd_mirror_index].tpd_is_open
                              := false;
                        tpd_errtext :=
                              sta_tape^ [tpd_mirror_index].tpd_errtext;
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  t.trError_gg00 = e_ok
                THEN
                    BEGIN
                    tpd_total_cnt_pages :=
                          tpd_total_cnt_pages + tpd_cnt_pages;
                    tpd_cnt_pages := 0;
                    tpd_volume_no := 1; (* write no new first_info *)
                    END;
                (*ENDIF*) 
                END;
            vf_t_file:
                BEGIN
                k38closeasyn (t, glob, sta_is_auto_load,
                      NOT c_force_rewind, c_autosave_tape_device,
                      tpd_is_open, tpd_fno);
                IF  tpd_mirror_index > 0
                THEN
                    BEGIN
                    aux_err  := t.trError_gg00;
                    t.trError_gg00 := e_ok;
                    k38closeasyn (t, glob,
                          sta_is_auto_load AND (aux_err = e_ok),
                          NOT c_force_rewind, tpd_mirror_index,
                          sta_tape^ [tpd_mirror_index].tpd_is_open,
                          sta_tape^ [tpd_mirror_index].tpd_fno);
                    IF  aux_err <> e_ok
                    THEN
                        t.trError_gg00 := aux_err
                    ELSE
                        BEGIN
                        IF  t.trError_gg00 <> e_ok
                        THEN
                            tpd_errtext := sta_tape^ [tpd_mirror_index].tpd_errtext;
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                tpd_total_cnt_pages :=
                      tpd_total_cnt_pages + tpd_cnt_pages;
                END;
            vf_t_unknown,
            vf_t_pipe,
            vf_t_raw,
            vf_t_tape_rew:
                (* k38i_autosave_init should avoid this *)
                IF  kb03Check.chkBackup_kb00 (* PTS 1103957 JA 1999-10-11 *)
                THEN
                    g01check (kb38FileTypeInvalid_csp03,
                          csp3_n_autosave, 'Filetype NOT allowed    ',
                          ord(tpd_type), false);
                (*ENDIF*) 
            END;
        (*ENDCASE*) 
    (*ENDWITH*) 
    IF  t.trError_gg00 = e_ok
    THEN
        BEGIN
        vendexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
        kb38end_outcopy (t, glob);
        vbegexcl (t.trTaskId_gg00, g08save0 + glob^.sta_region);
        (* PTS 1000355 UH *)
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38prep_autosave_work (
            VAR trans        : tgg00_TransContext;
            glob             : tkb3_save_static_ptr;
            tape_was_changed : boolean);
 
CONST
      c_num_tapes = 1;
 
VAR
      file_version  : tsp00_Int4;
      first_iosequence    : tsp00_PageNo;
      last_iosequence     : tsp00_PageNo;
      dbstamp1_date : tsp00_Date;
      dbstamp2_date : tsp00_Date;
      dbstamp1_time : tsp00_Time;
      dbstamp2_time : tsp00_Time;
      db_ident      : tsp00_Line; (* PTS 1000449 UH 19980909 *)
      page_count    : tsp00_Int4; (* PTS 1138588 mb 2005-11-01 *)
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^, sta_info, sta_tape^[c_autosave_tape_device] DO
    BEGIN
    IF  NOT tape_was_changed
    THEN
        BEGIN
        (* init static data *)
        kb38re_init_autosave (glob);
        gg999GetNewCommandId (trans.trTaskId_gg00, sta_utilcmd_id); (* PTS 1104845 UH 02-12-1999 *)
        (* save already computed values *)
        first_iosequence     := inf_first_iosequence;
        last_iosequence      := inf_last_iosequence;
        page_count           := inf_bd_page_count; (* PTS 1138588 mb 2005-11-01 *)
        file_version         := inf_file_version;
        dbstamp1_date        := inf_dbstamp1_date;
        dbstamp1_time        := inf_dbstamp1_time;
        dbstamp2_date        := inf_dbstamp2_date;
        dbstamp2_time        := inf_dbstamp2_time;
        db_ident             := inf_db_ident; (* PTS 1000449 UH 19980909 *)
        (* init info page *)
        kb38info_init (glob, sta_info);
        inf_mess_type        := m_autosave;
        inf_mess2_type       := mm_log;
        inf_filler1          := false;
        (* restore values *)
        inf_first_iosequence := first_iosequence;
        inf_last_iosequence  := last_iosequence;
        inf_bd_page_count    := page_count; (* PTS 1138588 mb 2005-11-01 *)
        inf_file_version     := file_version;
        inf_dbstamp1_date    := dbstamp1_date;
        inf_dbstamp1_time    := dbstamp1_time;
        inf_dbstamp2_date    := dbstamp2_date;
        inf_dbstamp2_time    := dbstamp2_time;
        inf_tapes_used       := c_num_tapes;
        inf_db_ident         := db_ident; (* PTS 1000449 UH 19980909 *)
        kb38set_label (glob^.sta_msg2type, glob^.sta_info.inf_file_version,
              inf_label, trans.trError_gg00);
        IF  sta_file_version > 0
        THEN
            sta_file_version := inf_file_version;
        (*ENDIF*) 
        CASE tpd_type OF
            vf_t_file:
                BEGIN
                IF  kb03Check.chkBackup_kb00 (* PTS 1103957 JA 1999-10-11 *)
                THEN
                    g01check (kb38FileTypeInvalid_csp03,
                          csp3_n_autosave, 'Only FILE with Versions ',
                          sta_file_version, sta_file_version > 0);
                (*ENDIF*) 
                IF  NOT tpd_is_open
                THEN
                    (* if not already open (caused by k38i_auto) *)
                    BEGIN
                    tpd_cnt_pages       := 0;
                    kb38open_autosave_tape (trans, glob, c_autosave_tape_device);
                    IF  (tpd_mirror_index > 0)
                        AND
                        (trans.trError_gg00 = e_ok)
                    THEN
                        BEGIN
                        kb38open_autosave_tape (trans, glob, c_autosave_mirr_device);
                        IF  trans.trError_gg00 <> e_ok
                        THEN
                            tpd_errtext := sta_tape^ [tpd_mirror_index].tpd_errtext;
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            vf_t_pipe,
            vf_t_raw,
            vf_t_tape_rew:
                (* k38i_autosave_init should avoid this *)
                IF  kb03Check.chkBackup_kb00 (* PTS 1103957 JA 1999-10-11 *)
                THEN
                    g01check (kb38FileTypeInvalid_csp03,
                          csp3_n_autosave, 'Filetype NOT allowed    ',
                          ord(tpd_type), false);
                (*ENDIF*) 
            vf_t_unknown:
                BEGIN
                g01opmsg (sp3p_console, sp3m_error,
                      kb38FileTypeInvalid_csp03, csp3_n_autosave,
                      c_type_not_allowed, ord(tpd_type) );
                trans.trError_gg00 := e_hostfile_error
                END;
            vf_t_tape_norew:
                BEGIN
                (* is opened on close (kb38post_autosave_work) *)
                END;
            END;
        (*ENDCASE*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38put_errtext (
            taskid          : tsp00_TaskId;
            glob            : tkb3_save_static_ptr;
            errtext_tape_no : tsp00_Int2);
 
BEGIN
IF  kb03Check.chkRegion_kb00
THEN
    g08excl_check (taskid, g08save0 + glob^.sta_region);
(*ENDIF*) 
IF  errtext_tape_no > 0
THEN
    WITH glob^.sta_tape^[errtext_tape_no] DO
        IF  tpd_errtext <> bsp_c40
        THEN
            kb391AppendTapeErrorToMessageList (taskid,
                  (tpd_err = e_ok) OR (tpd_err = e_new_hostfile_required), false,
                  errtext_tape_no, tpd_name, tpd_errtext)
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38queue_check (
            VAR t : tgg00_TransContext;
            glob : tkb3_save_static_ptr);
 
VAR
      ok  : boolean;
      err : char;
      i   : integer;
      ln  : tsp00_Line;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
t.trError_gg00 := e_ok;
ok       := true;
WITH glob^ DO
    BEGIN
    err := chr (c_in_not_eq_out);
    ok  := (sta_out_count = sta_into_count);
    IF  ok
    THEN
        BEGIN
        err := chr (c_not_all_free);
        i   := 1;
        REPEAT
            ok := (glob^.sta_queue^[i].sre_state = sres_free);
            i  := i + 1
        UNTIL
            (i > sta_queue_size) OR NOT ok
        (*ENDREPEAT*) 
        END;
    (*ENDIF*) 
    IF  ok
    THEN
        BEGIN
        err:= chr (c_child_running);
        ok := (sta_read_tasks_waiting  = 0) AND
              (sta_write_tasks_waiting = 0)
        END;
    (*ENDIF*) 
    IF  ok AND (sta_msgtype = m_save_parallel)
    THEN
        IF  (sta_msg2type = mm_pages) OR (sta_msg2type = mm_database)
        THEN
            BEGIN
            err := chr (c_fbm_error);
            ok  := bd10CheckBackup(t.trTaskId_gg00);
            IF  NOT ok
            THEN
                k38sys_msg (glob, sp3m_error, kbFbmCheckFailed_csp03,
                      c_fbm1_check_failed, 0);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  NOT ok
    THEN
        BEGIN
        t.trError_gg00 := e_queue_mismatch;
        IF  g01vtrace.vtrAll_gg00
        THEN
            BEGIN
            ln [1] := chr(ord(kb38que_state));
            ln [2] := err;
            b120InsertTrace (t, kb, sta_vtr_direction, 2, @ln)
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38re_init_autosave (glob : tkb3_save_static_ptr);
 
VAR
      i : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^, sta_tape^[c_autosave_tape_device] DO
    BEGIN
    sta_msgtype             := m_autosave;
    sta_msg2type            := mm_log;
    sta_vtr_direction       := kb38save_parallel;
    sta_is_cold             := false;
    (*    sta_blocksize           := c_autosave_blocksize;*)
    sta_num_tapes           := c_autosave_num_tapes;
    sta_num_devsp           := ckb3_log_devsp_no;
    sta_system_state        :=
          [sy_allocated, sy_initialized, sy_bup_working];
    sta_pages_transferred   := 0;
    sta_into_count          := 0;
    sta_out_count           := 0;
    sta_queue_into_count    := 0;
    sta_queue_out_count     := 0;
    sta_queue_first_free    := 1; (* first queue element *)
    sta_queue_first_read    := 0;
    sta_queue_last_read     := 0;
    sta_read_tasks_waiting  := 0;
    sta_write_tasks_waiting := 0;
    sta_devsp_ready_cnt     := 0;
    sta_write_bitmap_pages  := false;
    sta_write_conv_pages    := false;
    (* WRITER TASK (TAPE) *)
    tpd_volume_no           := 0;
    (* QUEUE *)
    FOR i := 0 TO sta_queue_size DO
        BEGIN
        WITH glob^.sta_queue^[i] DO
            BEGIN
            sre_state           := sres_free;
            sre_pages_per_block := 0;
            sre_next            := 0;
            sre_prev            := 0;
            sre_task_no_into    := ckb3_nil_task_no;
            sre_is_clustered    := false;
            sre_filler2         := 0;
            sre_filler3         := 0
            END
        (*ENDWITH*) 
        END;
    (*ENDFOR*) 
    FOR i := sta_queue_first_free TO sta_queue_size - 1 DO
        BEGIN
        glob^.sta_queue^[i].sre_next := i + 1;
        glob^.sta_queue^[i].sre_prev := 0
        END
    (*ENDFOR*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38ready_check (
            glob         : tkb3_save_static_ptr;
            VAR is_ready : boolean);
 
VAR
      i : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08check_excl (g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^ DO
    BEGIN
    is_ready  := sta_queue_first_read <= 0;
    i         := 1;
    WHILE is_ready AND (i <= sta_num_tapes + sta_num_devsp) DO
        IF  sta_task^[i].tsd_state <> ts_none
        THEN
            is_ready := false
        ELSE
            i := i + 1
        (*ENDIF*) 
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38run_task (
            VAR trans  : tgg00_TransContext;
            glob       : tkb3_save_static_ptr;
            which_task : tkb3_savetasks;
            task_no    : tsp00_Int2;
            volume_index : tsp00_Int2;
            tape_no    : tsp00_Int2);
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (trans.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
kb38i_run_task_init (trans, glob, which_task, task_no, tape_no);
IF  trans.trError_gg00 = e_ok
THEN
    (* leave region in next function *)
    kb900ExecuteBackupJob (trans, glob^.sta_backup_server, glob^.sta_region,
          glob^.sta_msgtype = m_autosave, task_no, tape_no, volume_index);
(*ENDIF*) 
IF  trans.trError_gg00 <> e_ok (* PTS 1140873 mb 2006-03-29 *)
THEN
    glob^.sta_task^ [task_no].tsd_state := ts_none;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38save_restore_kind (
            mtype   : tgg00_MessType;
            is_cold : boolean;
            VAR str : tsp00_C10);
 
BEGIN
IF  (mtype = m_save_parallel) OR (mtype = m_autosave)
THEN
    IF  is_cold
    THEN
        str := 'SAVE COLD '
    ELSE
        str := 'SAVE WARM '
    (*ENDIF*) 
ELSE
    str     := 'RESTORE   ';
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38SendEventAutosave (
            EventType    : tkb38_EventType;
            VAR TapeName : tsp00_VFilename);
 
VAR
      berr  : tgg00_BasisError;
      event : tsp31_event_description;
 
BEGIN
g01event_init (event);
WITH event DO
    BEGIN
    sp31ed_ident      := sp31ei_autosave;
    sp31ed_priority   := sp31ep_low;
    sp31ed_value_1    := ord(EventType);
    IF  (EventType = Started_ekb38)
        OR
        (EventType = BackupSuccessfull_ekb38)
    THEN
        BEGIN
        sp31ed_text_len   := sizeof(TapeName);
        SAPDB_PascalMove ('VKB38 ',  42,    
              sizeof (tsp00_VFilename), sizeof (tsp31_event_text),
              @TapeName, 1, @sp31ed_text_value, 1,
              sizeof (tsp00_VFilename), berr)
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
vinsert_event (event);
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38set_label (
            msg2type          : tgg00_MessType2;
            backup_version    : tsp00_Int4;
            VAR new_label     : tsp00_C14;
            VAR err           : tgg00_BasisError);
 
VAR
      aux_len : tsp00_Int4;
 
BEGIN
IF  err = e_ok
THEN
    BEGIN
    CASE msg2type OF
        mm_database:
            new_label := 'DAT_          ';
        mm_pages:
            new_label := 'PAG_          ';
        mm_log:
            new_label := 'LOG_          ';
        OTHERWISE
            new_label := '???_          ';
        END;
    (*ENDCASE*) 
    aux_len := 4;
    kb38add_count_to_label (new_label, aux_len, backup_version, err)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38show_file_type (
            glob     : tkb3_save_static_ptr;
            filetype : tsp00_VfType;
            VAR err  : tgg00_BasisError);
 
VAR
      aux_label : tsp00_C8;
      aux_str   : tsp00_C24;
      msg       : tsp00_C40;
 
BEGIN
msg       := bsp_c40;
aux_str   := 'Filetype:               ';
SAPDB_PascalMove ('VKB38 ',  43,    
      sizeof (tsp00_C24), sizeof (tsp00_C40),
      @aux_str, 1, @msg, 1, sizeof (tsp00_C24), err);
CASE glob^.sta_msgtype OF
    m_save_parallel:
        aux_label := csp3_n_save;
    m_restore_parallel, m_restore:
        aux_label := csp3_n_restore;
    m_autosave:
        aux_label := csp3_n_autosave;
    OTHERWISE
        aux_label := csp3_n_save
    END;
(*ENDCASE*) 
CASE filetype OF
    vf_t_unknown:
        aux_str := 'unknown                 ';
    vf_t_file:
        aux_str := 'file                    ';
    vf_t_pipe:
        aux_str := 'pipe                    ';
    vf_t_raw:
        aux_str := 'raw                     ';
    vf_t_tape_norew:
        aux_str := 'tape (norewind)         ';
    vf_t_tape_rew:
        aux_str := 'tape (rewind)           ';
    OTHERWISE
        aux_str := '*** invalid ***         '
    END;
(*ENDCASE*) 
SAPDB_PascalMove ('VKB38 ',  44,    
      sizeof (tsp00_C24), sizeof (tsp00_C40),
      @aux_str, 1, @msg, 11, sizeof (tsp00_C24), err);
g01optextmsg (sp3p_knldiag, sp3m_info, kb38CheckedFileType_csp03,
      aux_label, msg)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38save_pages_left (
            process_id     : tsp00_TaskId;
            glob           : tkb3_save_static_ptr;
            used_volumes   : tsp00_Int2;
            VAR pages_left : tsp00_Int4);
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (process_id, g08save0 + glob^.sta_region);
(*ENDIF*) 
CASE glob^.sta_msg2type OF
    mm_pages, mm_database:
        BEGIN
        (*  3*blocksize: header, nil filler (last data block), trailer*)
        pages_left :=
              b10bup_data_page_cnt (process_id) +
              used_volumes * 2 * glob^.sta_blocksize +
              used_volumes*k39pages_for_first_info (glob^.sta_blocksize)
              - glob^.sta_pages_transferred;
&       ifdef TRACE
        t01int4 (kb_save, 'data pages: ',
              b10bup_data_page_cnt(process_id));
&       endif
        END;
    mm_log:
        kb391GetNumOfPagesLeftForSegment(pages_left);
    OTHERWISE
        pages_left := 0;
    END;
(*ENDCASE*) 
&ifdef TRACE
t01int4 (kb_save, 'pages_left  ', pages_left);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38save_pages_left_for_parallel_backup (
            VAR t : tgg00_TransContext;
            glob           : tkb3_save_static_ptr;
            used_volumes   : tsp00_Int2;
            VAR pages_left : tsp00_Int4);
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
CASE glob^.sta_msg2type OF
    mm_pages, mm_database:
        BEGIN
        (*  3*blocksize: header, nil filler (last data block), trailer*)
        pages_left :=
              b10bup_data_page_cnt (t.trTaskId_gg00) +
              used_volumes * 2 * glob^.sta_blocksize +
              used_volumes*k39pages_for_first_info (glob^.sta_blocksize)
              - glob^.sta_pages_transferred;
&       ifdef TRACE
        t01int4 (kb_save, 'data pages: ',
              b10bup_data_page_cnt(t.trTaskId_gg00));
&       endif
        END;
    mm_log:
        BEGIN
        kb391GetNumOfPagesLeftForSegment(pages_left);
        END;
    OTHERWISE
        pages_left := 0;
    END;
(*ENDCASE*) 
&ifdef TRACE
t01int4 (kb_save, 'pages_leftbp', pages_left)
&     endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38t_check_tape_age (
            VAR t                 : tgg00_TransContext;
            glob                  : tkb3_save_static_ptr;
            tape_no               : tsp00_Int2;
            before_date           : tsp00_Date);
 
VAR
      tape_info  : tkb3_info_stuff;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
WITH glob^, sta_tape^ [tape_no] DO
    IF  (before_date <> bsp_date) AND (tpd_type <> vf_t_pipe)
    THEN
        BEGIN
        k38tapeopen_one (t, glob, tape_no, NOT c_for_writing,
              c_for_readlabel);
        IF  t.trError_gg00 = e_ok
        THEN
            kb38t_allowed_for_autosave (t, glob, tape_no);
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok) AND (tpd_type <> vf_t_pipe)
        THEN
            BEGIN
            tape_info.inf_start_date := bsp_date;
            k39read_label (t, glob, tape_no, tape_info);
            IF  (t.trError_gg00 = e_ok)
                AND
                (tape_info.inf_start_date <> bsp_date)
            THEN
                BEGIN
                IF  tape_info.inf_start_date >= before_date
                THEN
                    BEGIN
                    t.trError_gg00    := e_wrong_hostfile;
                    tpd_errtext := c_invalid_tape_age
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  t.trError_gg00 = e_wrong_hostfile
            THEN
                BEGIN
                t.trError_gg00 := e_ok;
                k38closeasyn (t, glob, NOT c_auto_load,
                      c_force_rewind, tape_no, tpd_is_open,tpd_fno);
                t.trError_gg00 := e_wrong_hostfile;
                END
            ELSE
                BEGIN
                t.trError_gg00 := e_ok;
                k38closeasyn (t, glob, NOT c_auto_load,
                      c_force_rewind, tape_no, tpd_is_open,tpd_fno);
                tpd_is_full    := false;
                t.trError_gg00 := e_ok
                END;
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            tpd_errtext    := bsp_c40;
            t.trError_gg00 := e_ok;
            END;
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
(*ENDWITH*) 
t01basis_error (kb_save, 'end t_check ', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38tape_flush (
            VAR t   : tgg00_TransContext;
            glob    : tkb3_save_static_ptr;
            fno     : tsp00_Int4;
            fname   : tsp00_VFilename;
            errtext : tsp00_ErrText);
 
CONST
      c_max_retry_open = 10;
 
VAR
      vaerr           : tsp00_VaReturn;
      load_err        : tsp00_VaReturn;
      act_block_count : tsp00_Int4;
      retry           : tsp00_Int4;
 
BEGIN
(* outside region *)
t.trError_gg00 := e_ok;
vaerr          := va_ok;
load_err       := va_ok;
vasynclose (fno, NOT c_rewind, NOT c_is_auto_load,
      load_err, vaerr, errtext);
IF  vaerr = va_ok
THEN
    BEGIN
    act_block_count := glob^.sta_blocksize;
    retry           := 1;
    REPEAT
        BEGIN
        vasynopen (fname, NOT c_is_devspace, c_for_writing,
              vf_t_unknown, (* type is not interesting *)
              sizeof (tsp00_Buf), NIL, act_block_count, fno, vaerr, errtext);
        IF  vaerr = va_notok
        THEN
            vsleep (t.trTaskId_gg00, 1);
        (*ENDIF*) 
        END
    UNTIL
        (retry > c_max_retry_open) OR (vaerr = va_ok);
    (*ENDREPEAT*) 
    END;
(*ENDIF*) 
IF  vaerr <> va_ok
THEN
    BEGIN
    t.trError_gg00 := e_hostfile_error;
    k38sys_msg (glob, sp3m_error, kbCloseError_csp03,
          c_flush_error, ord(vaerr));
    k38err_to_vtrace (t, glob, 'FLUSH       ', errtext);
    END;
&ifdef TRACE
(*ENDIF*) 
t01p2int4 (kb_save, 'end flush er', ord(vaerr)
      ,             '         fno', fno);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k38tapeopen_one (
            VAR t             : tgg00_TransContext;
            glob              : tkb3_save_static_ptr;
            tape_no           : tsp00_Int2;
            is_for_writing    : boolean;
            is_for_readlabel  : boolean);
 
VAR
      expected_filetype : tsp00_VfType;
      vaerr             : tsp00_VaReturn;
      act_block_cnt     : tsp00_Int4;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
(*ENDIF*) 
t01vffn (kb_save, '     open fn', glob^.sta_tape^[tape_no].tpd_name);
&endif
vaerr := va_ok;
WITH glob^, sta_tape^ [tape_no] DO
    BEGIN
    act_block_cnt     := sta_blocksize;
    expected_filetype := tpd_type;
    IF  NOT sta_is_remote
    THEN
        BEGIN
        vendexcl (t.trTaskId_gg00, g08save0 + sta_region);
        vasynopen (tpd_name, NOT c_is_devspace, is_for_writing,
              tpd_type, sizeof (tsp00_Page), sta_to_cancel, act_block_cnt, tpd_fno,
              vaerr, tpd_errtext);
        vbegexcl (t.trTaskId_gg00, g08save0 + sta_region)
        END;
&   ifdef TRACE
    (*ENDIF*) 
    t01p2int4 (kb_save, 'tap open err', ord (vaerr)
          ,             '         fno', tpd_fno);
&   endif
    IF  (vaerr <> va_ok)
        AND
        (vaerr <> va_eof)
        AND
        (act_block_cnt <> sta_blocksize)
        AND
        NOT is_for_writing
        AND
        is_for_readlabel
    THEN
        (* +++ do not change blocksize during recovery +++ *)
        (* +++ must only be in use, if reading a label +++ *)
        BEGIN
        k38sys_msg (glob, sp3m_info, kbSurprisingBlockCnt_csp03,
              c_tape_surprising_blockcnt, act_block_cnt);
        IF  act_block_cnt > ckb3_min_pages_per_block
        THEN
            BEGIN
            IF  NOT sta_is_remote
            THEN
                BEGIN
                vendexcl (t.trTaskId_gg00, g08save0 + sta_region);
                vasynopen (tpd_name, NOT c_is_devspace,
                      NOT c_for_writing,
                      tpd_type, sizeof (tsp00_Page), sta_to_cancel, act_block_cnt,
                      tpd_fno, vaerr, tpd_errtext);
                vbegexcl (t.trTaskId_gg00, g08save0 + sta_region)
                END;
&           ifdef TRACE
            (*ENDIF*) 
            t01p2int4 (test_kb, 'tap2open err', ord (vaerr)
                  ,             '         fno', tpd_fno);
&           endif
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (vaerr = va_ok) AND NOT sta_is_remote
    THEN
        BEGIN
        vasyninit_tape (tpd_fno, tpd_check_destructive, (* PTS 1000360 UH *)
              tpd_type, vaerr, tpd_errtext);
&       ifdef TRACE
        t01vftype (kb_save, 'vasyninit   ', tpd_type);
        t01int4   (kb_save, '      err   ', ord(vaerr));
&       endif
        IF  vaerr <> va_ok
        THEN
            BEGIN
            tpd_is_open := true;
            k38closeasyn (t, glob, NOT c_auto_load, NOT c_force_rewind,
                  tape_no, tpd_is_open, tpd_fno);
            t.trError_gg00 := e_hostfile_error
            END
        ELSE
            kb38show_file_type (glob, tpd_type, t.trError_gg00);
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok)
            AND
            NOT tpd_check_destructive (* PTS 1000360 UH *)
            AND
            (tpd_type = vf_t_unknown)
        THEN
            (* if not autosave and lzu cannot determine type *)
            (* take controls/users info                      *)
            tpd_type := expected_filetype;
        (*ENDIF*) 
        IF  (t.trError_gg00 = e_ok)
            AND
            (expected_filetype <> vf_t_unknown)
            AND
            (expected_filetype <> tpd_type)
        THEN
            BEGIN
            tpd_is_open := true;
            k38closeasyn (t, glob, NOT c_auto_load, NOT c_force_rewind,
                  tape_no, tpd_is_open, tpd_fno);
            tpd_errtext := c_filetype_mismatch;
            t.trError_gg00    := e_hostfile_error
            END
        (*ENDIF*) 
        END;
    (* PTS 1104316 UH 25-10-1999 *)
    (* k38mdf_medium_def_write removed *)
    (*ENDIF*) 
    IF  vaerr = va_ok
    THEN
        tpd_is_open := true
    ELSE
        BEGIN
        IF  (vaerr = va_eof) AND NOT is_for_writing
        THEN
            t.trError_gg00 := e_no_data_on_tape
        ELSE
            t.trError_gg00 := e_hostfile_error;
        (*ENDIF*) 
        k38err_to_vtrace (t, glob, 'ASYNOPENTAPE', tpd_errtext)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38treat_received_stuff (
            VAR t               : tgg00_TransContext;
            glob                : tkb3_save_static_ptr;
            runindex            : tsp00_Int2;
            VAR stop_headmaster : boolean);
 
VAR
      aux_no     : tsp00_Int4;
      pages_left : tsp00_Int4;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
&ifdef TRACE
(*ENDIF*) 
t01int4 (kb_save, 'runindex    ', runindex);
&endif
t.trError_gg00  := e_ok;
stop_headmaster := false;
WITH glob^ DO
    BEGIN
    IF  sta_task^[runindex].tsd_task_kind = task_twt
    THEN
        BEGIN
        IF  sy_knockoffwork in sta_system_state
        THEN
            (* devspace_read_tasks finished *)
            kb38ready_check (glob, stop_headmaster);
        (* stop_headmaster = true                           *)
        (* -->  all data pages transferred                  *)
        (* -->  check tape space to write end_of_save block *)
        (*ENDIF*) 
        aux_no := sta_task^[runindex].tsd_tape_index;
        IF  sta_tape^[aux_no].tpd_is_full
        THEN
            (* this volume is full *)
            BEGIN
            IF  (sta_devsp_ready_cnt  < sta_num_devsp) OR
                (sta_queue_first_read > 0            )
            THEN
                (* continue save  -->  new tape necessary ?? *)
                BEGIN
                kb38save_pages_left_for_parallel_backup (t, glob,
                      sta_info.inf_volume_no, pages_left);
                IF  (pages_left > c_min_pages_to_change_tape) OR
                    (pages_left > kb38free_tape_pages (glob))
                THEN
                    BEGIN
                    stop_headmaster := true;
                    t.trError_gg00        := e_new_hostfile_required
                    END
                (*ENDIF*) 
                END
            ELSE
                (* save finished *)
                IF  kb38free_tape_pages (glob) < sta_blocksize
                THEN
                    BEGIN
                    stop_headmaster := true;
                    t.trError_gg00        := e_new_hostfile_required
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        (* other tasks: devpspace read/write, tape read *)
        BEGIN
        IF  sy_knockoffwork in sta_system_state
        THEN
            (* devspace_read_tasks or tape_read_tasks finished *)
            kb38ready_check (glob, stop_headmaster)
        ELSE
            IF  (sta_task^[runindex].tsd_task_kind = task_trt)
                AND
                ((sta_info.inf_pt2           <> pt2EndSaveInfo_egg00)
                OR
                ( sta_info.inf_max_volume_no  > sta_tapes_ready_cnt))
            THEN
                (* do not know OR not all tapes started *)
                BEGIN
                stop_headmaster := true;
                t.trError_gg00  := e_new_hostfile_required
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
&   ifdef TRACE
    IF  t01trace (kb_save)
    THEN
        CASE sta_task^[runindex].tsd_task_kind OF
            task_drt:
                t01int4 (kb_save, 'DRTready cnt', sta_devsp_ready_cnt);
            task_dwt:
                t01int4 (kb_save, 'DWTready cnt', sta_devsp_ready_cnt);
            task_twt:
                t01int4 (kb_save, 'TWTready    ',
                      sta_task^[runindex].tsd_tape_index);
            task_trt:
                BEGIN
                t01p2int4 (kb_save, 'TRTready cnt', sta_tapes_ready_cnt,
                      ' tape-index ',
                      sta_task^[runindex].tsd_tape_index);
                t01bool2 (kb_save, 'trt knockoff',
                      (sy_knockoffwork in sta_system_state),
                      'queue empty ', (sta_out_count = sta_into_count));
                END
            END;
        (*ENDCASE*) 
&   endif
    (*ENDIF*) 
    END;
(*ENDWITH*) 
&ifdef TRACE
t01basis_error (kb_save, 'end treat   ', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38w_autosave_work (
            VAR trans         : tgg00_TransContext;
            glob              : tkb3_save_static_ptr;
            tape_was_changed  : boolean);
 
VAR
      task_no        : tsp00_Int2;
      importantError : tgg00_BasisError;
      joberror       : tgg00_BasisError;
 
BEGIN
IF  NOT tape_was_changed
THEN
    kb38run_task (trans, glob, task_drt, c_autosave_reader_no,
          c_autosave_log_device, ckb3_nil_tape_no);
(*ENDIF*) 
IF  trans.trError_gg00 = e_ok
THEN
    BEGIN
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
    k39run_backup_task (trans, true, c_in_region);
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
    importantError     := trans.trError_gg00;
    trans.trError_gg00 := e_ok;
    IF  ((    sy_error         in glob^.sta_system_state) OR
        NOT (sy_bup_working   in glob^.sta_system_state))
        AND
        (importantError = e_ok)
    THEN
        importantError := e_write_task_crash;
    (*ENDIF*) 
    IF  importantError = e_ok
    THEN
        BEGIN
        glob^.sta_task^ [c_autosave_writer_no].tsd_state := ts_started;
        IF  glob^.sta_tape^ [c_autosave_tape_device].tpd_is_full
        THEN
            BEGIN
            importantError := e_new_hostfile_required;
            (* store error in tape-record for autosave-show *)
            glob^.sta_tape^[c_autosave_tape_device].tpd_err
                  := e_new_hostfile_required;
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  importantError = e_ok
    THEN
        BEGIN
        task_no  := ckb3_nil_task_no;
        joberror := e_ok;
&       ifdef TRACE
        t01name (kb_save, 'Receiving Reader..') ;
&       endif
        (* leave region in next function *)
        kb900WaitForAnyBackupJobFinished (trans, glob^.sta_backup_server,
              glob^.sta_region, task_no, joberror);
        IF  trans.trError_gg00 <> e_ok
        THEN
            BEGIN
            importantError     := trans.trError_gg00;
            trans.trError_gg00 := e_ok;
            END;
        (*ENDIF*) 
        IF  (importantError = e_ok) AND (joberror <> e_ok)
        THEN
            BEGIN
            importantError     := joberror;
            trans.trError_gg00 := e_ok;
            END;
        (*ENDIF*) 
        glob^.sta_task^ [task_no].tsd_state := ts_none;
        IF  ((    sy_error         in glob^.sta_system_state) OR
            NOT (sy_bup_working   in glob^.sta_system_state))
            AND
            (importantError = e_ok)
        THEN
            importantError := e_write_task_crash;
        (*ENDIF*) 
        IF  kb03Check.chkBackup_kb00 (* PTS 1103957 JA 1999-10-11 *)
        THEN
            g01check (kbRunIndexInvalid_csp03, csp3_n_autosave,
                  'invalid runindex        ', task_no,
                  task_no = c_autosave_reader_no);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  importantError <> e_ok
    THEN
        WITH glob^, sta_tape^ [c_autosave_tape_device] DO
            BEGIN
            k38closeasyn (trans, glob, NOT c_auto_load,
                  c_force_rewind, c_autosave_tape_device,
                  tpd_is_open, tpd_fno);
            IF  tpd_mirror_index > 0
            THEN
                k38closeasyn (trans, glob, NOT c_auto_load,
                      c_force_rewind, tpd_mirror_index,
                      sta_tape^ [tpd_mirror_index].tpd_is_open,
                      sta_tape^ [tpd_mirror_index].tpd_fno);
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    trans.trError_gg00 := importantError;
    END;
&ifdef TRACE
(*ENDIF*) 
t01basis_error (kb_save, 'w_autosave  ', trans.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb38write_eof_block_to_open_tapes (
            VAR t               : tgg00_TransContext;
            glob                : tkb3_save_static_ptr;
            VAR errtext_tape_no : tsp00_Int2);
 
VAR
      i        : integer;
      open_cnt : integer;
 
BEGIN
IF  kb03Check.chkRegion_kb00 (* PTS 1103957 JA 1999-10-11 *)
THEN
    g08excl_check (t.trTaskId_gg00, g08save0 + glob^.sta_region);
(*ENDIF*) 
t.trError_gg00 := e_ok;
WITH glob^ DO
    BEGIN
    open_cnt := 0;
    FOR i := 1 TO sta_num_tapes DO
        IF  sta_tape^[i].tpd_is_open
        THEN
            open_cnt := open_cnt + 1;
        (*ENDIF*) 
    (*ENDFOR*) 
    sta_pages_transferred :=
          sta_pages_transferred + open_cnt * sta_blocksize;
    IF  open_cnt = 0
    THEN
        t.trError_gg00 := e_new_hostfile_required;
    (*ENDIF*) 
    i := 1;
    WHILE (t.trError_gg00 = e_ok) AND (i <= sta_num_tapes) DO
        BEGIN
        IF  sta_tape^[i].tpd_is_open
        THEN
            k39write_extra_block (t, glob, i,
                  pt2EndSaveInfo_egg00, sta_info);
        (*ENDIF*) 
        IF  t.trError_gg00 <> e_ok
        THEN
            errtext_tape_no := i;
        (*ENDIF*) 
        i := i + 1
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
