2.11 - É bom saber

A seguir estão listadas o uso de operacoes e comandos em procedures e jobsd em geral que não foram citadas ou explicadas até esse momento, e como, esse é o capitulo sobre JCL lá vai:

No "cabeçalho" de seu JCL, isto é, no cartão "JOB" existem mais alguns parametros que não discutimos, vamos lista-los aqui.

ADDRSPC=Memoria -- Solicita ao sistema operacional que o JOB seja executado com ou sem paginação de memoria.

Sendo a memoria: VIRT - O sistema podera utilizar paginação de memoria na execucao desse job. É o padrão caso o parametro ADDRSPC não seja informado. REAL - Evitar o uso o sistema operacional nao paginará a memoria sendo que seu job sera executado por completo na memoria central. TIME=tempo -- Permite fixar o tempo máximo e efectivo de CPU para o STEP ou para o JOB como um todo

Sendo o tempo em minutos ou (minutos,segundos): 1440 ou NOLIMIT - o step pode ficar rodando por 24 horas MAXIMUM - 357912 minutos (248 dias) (15,45) - 15 minutos e 45 segundos

USER e PASSWORD ="usuário" que submetera o job e sua senha. Nao precisa utilizar, o RACF cuida disso pra você - a não ser que você não queira !

Aqui um adendo sobre o seguinte trecho do JOB00001

//-------------------------------------------------------------------- 
//DESTINO OUTPUT DEFAULT=YES,DEST=LOCAL,FORMS=BUGAFORM,         1 
// CHARS=(AOA,AOB),COPIES=1                                     2 
//-------------------------------------------------------------------- 
//PROCS JCLLIB ORDER=(USER.BUGA.PROCS,USER.BUGA.TESTES) 
//-------------------------------------------------------------------- 
//JOBLIB DD DSN=USER.BUGA.CARGAS,DISP=SHR 
// DD DSN=USER.BUGA.TESTES,DISP=SHR 
/JOBPARM SYSAFF=IMAA ... 
//SYSOUT DD SYSOUT=,OUTLIM=999999,FREE=CLOSE                     3 
//FORM1 OUTPUT CLASS=R,DEFAULT=NO,DEST=LOCAL                     4 
//--------------------------------------------------------------------

O parametro COPIES informa ao sistema quantas reimpressões você deseja (abolido desde a troca da "impressão em impressora" para "impressao em arquivos").

OUTLIM informa a quantidade maxima de linhas que será "impressa" algo entre 1 e 16.777.215 linhas.

FREE pode conter 2 parametros distintos um default que é o "END" e outro que é o "CLOSE", no END o arquivo especificado no cartao DD será desalocado no utlimo step do JOB, já no CLOSE esse processo ocorrerá quando o arquivo for fechado.

Existem alguns comandos/parametros que encontrar seu significado, é o caso do trecho 1-2 e 3-4 que perderam seu sentido original por completo quando do final da impressão em papel, mas que devido ao copy/cola ainda existem em algumas instalações.

Para saber o que ocorria quando da utilizacao desses comandos recomenda-se a leitura dos manuais.

As linhas 1, 2 e 4 não devem ser utilizadas e a linha 3 pode ser trocada por um simples //SYSOUT DD SYSOUT=*

O JCLLIB ORDER informa ao sistema qual "particionado" deve ser procurado - além dos default de sua instalação - quando da execucao desse job a fim de localizar procedures catalogadas para execucao a partir desse JOB00001.

JOBLIB por sua vez indica ao sistema onde os cargas se encontram e em qual ordem devem ser procurados - além dos default de sua instalação - que serão executados via comando EXEC ao longo de todo esse job.

Um comando/cartão similar é o STEPLIB que funciona apenas para o step em que for codificado e não para o job inteiro como o JOBLIB.

Existe também no trecho acima um comando de JES2 ,sic, comando não nos manuais eles são chamados de "Control Statements" que é o

/*JOBPARM SYSAFF=IMAA 

esse comando informa ao sistema em qual imagem o seu job deve ser executado nesse caso na imagem chamada "IMAA".

O JES2 possibilita a utilizacao de diversos comandos mas não costumam ser utilizados, no JOB00001 utilizou-se /*PRIORITY 1 , sendo que a prioridade varia de 1 mais baixa até 15 a mais alta existindo também o parametro PRTY=numero em cartão JOB com a mesma função. Por sua vez o

/*MESSAGE PROGRAMA HELLO000 EXECUTADO... VERIFIQUE SYSOUT !

envia mensagem diretamente para a console diferente do /*NOTIFY utilizado em jobs anteriores que envia diretamente para o usuario.

Continuando com nossa analise do JOB temos o seguinte trecho

//-------------------------------------------------------------------- 
//SCRATCH EXEC PGM=IEFBR14 
//DELETA DD DSN=USER.BUGA.SEQUENCI.A0000001, 
// DISP=(MOD,DELETE,DELETE),SPACE=(TRK,(0,0)) 
//--------------------------------------------------------------------

Sendo SCRATCH o nome do step que executa um programa "utilitário da IBM" - o IEFBR14 - que tem como funcao “fazer nada e retornar 0 no return code” de sua execução.

Aqui cabe um adendo histórico, os mainframes costumam ter um padrão para tudo, a nomenclatura dos módulos/aplicativos/programas originais da IBM não poderia ser diferente. Ssegundo a historia o "IEF" (era a sigla inicial de todos os programas criados por um grupo de programadores da época do OS/360 o BR significa a instrução BRanch que desvia a execucao do programa para um determinado endereço e o 14 é o registrador mais usual para se encerrar a execucao de um programa.

O IEFBR14 consta nos manuais como: "is a two-line program that clears register 15, thus passing a return code of 0, and then branches to the address in register 14, which returns control to the system."

O que é basicamente o código abaixo

 SR    15,15    Zera o r15 (return code)
 BR    14       Volta pro chamador

Bom, mas o que esse programa faz, nada, isso mesmo nada, mas permite que seu cartão DD possa criar ou deletar um arquivo, no nosso caso estamos deletando o arquivo/dataset "USER.BUGA.SEQUENCI.A0000001" para que não tenhamos problemas quando da utilizacao desse arquivo por nosso programa, caso o arquivo exista quando da execucao do step EXECUTA ocorrerá o seguinte erro:

IEF253I JOB00001 EXECUTA SAIDA - DUPLICATE NAME ON DIRECT ACCESS VOLUME
IGD17001I DUPLICATE DATA SET NAME ON VOLUME VOL001
FOR DATA SET USER.BUGA.SEQUENCI.A0000001
IEF272I JOB00099 EXECUTA - STEP WAS NOT EXECUTED.

O "parametro" DISP ajuda a nao ter esse problema, veja no subtopico especifico mais sobre o DISP

O Parametro SPACE indica quanto de espaço em disco é necessário para esse arquivo, como estamos apagando o arquivo indicamos zero trilhas.

Um pouco mais abaixo em nosso JOB temos o seguinte cartão exec

//EXECUTA EXEC PGM=HELLO000, 
// PARM='123456789Z', 
// ACCT='USER.BUGA', 
// ADDRSPC=, 
// DPRTY=, 
// PERFORM=01, 
// RD=NC

O programa que será executado é o HELLO000 para esse programa serão enviados para sua execucao os dados constantes em PARM, isto é, '123456789Z'.

ACCT indica qual conta deverá ser "cobrada" pela execucao desse step, atualmente desconheço instalaçoes que utilizam desse recurso. ADDRSPC sem diferenciacao em relação ao inserido no cabeçalho, exceto que o job como um todo pode ter um tipo e um determinado step outro, o padrao é VIRT. DPRTY é tão antigo que nem se encontra mais descrito nos manuais de JCL, atualmente a prioridade de execucao de jobs/steps é default por fila geralmente gerenciada por algum software de controle como o control-m pro exemplo, de maneira analoga temos o parametro PERFORM que de tão antigo nem é mais explicado, mas servia para classificar a execucao de um job de acordo com parametros de sistema pre-estabelecidos (serviços, discos, processador etc)

O parametro RD (restart definition) também não costuma ser utilizado, ele indica condicao de restart "automatico", os valores validos são R - Restart com checkpoints, RNC - Restart sem checkpoint, NR - Sem restart mas pode ter checpoint e NC - Sem restart e sem checkpoint.

Enfim, se um cartão exec contiver mais que o nome do programa ou de outro JOB/Procedure e do parametro a ser passado esse cartao esta com dados demais ! Para passagem de parametros pode-se utilizar ao inves do parametro PARM o cartao DD SYSIN, atentando-se ao fato que o programa que será executado deve tratar as entradas de dados de maneira diferente quando enviado via parm e quando enviado via SYSIN.

Continuando o estudo de nosso job encontramos

//*ENTRADA DD DSN=USER.BUGA.SEQUENCI.A0000002,DISP=SHR 
//ENTRADA DD *,DLM='FF' 
123456 FF

o //* indica que essa linha será ignorada, ela virou um comentário. O arquivo de entrada contido no comentário foi substituido propositadamente pelo cartao DD do tipo in-stream (igual um sysin) no qual os dados encontram-se no proprio JOB, sendo os dados 123456 o conteudo do arquivo que será referenciado no programa como ENTRADA.

Esse procedimento pode ser util quando deseja-se apenas testar a execucao do jcl ou do programa do cartao exec anterior. O dado DLM='FF' indica onde termina o "arquivo"

Continuando a analise nos deparamos com um cartão DD com o nome de SAIDA, esse DD contem as informações minimas para a criação de um DATASET que conterá os dados de saida do programa executado no cartao EXEC.

//SAIDA DD DSN=USER.BUGA.SEQUENCI.A0000001, 
// DISP=(,CATLG),LRECL=255,DSORG=PS,RECFM=FB, 
// AVGREC=K,SPACE=(255,(5,1),RLSE)

Vamos aos componentes desse cartão DD :

DSN ou DSNAME é o nome do arquivo/data set que esta sendo referenciado nesse cartao DD. O componente/parametro DISP contendo (,CATLG) indica o seu parm1 como nada, nesses casos o sistema utiliza o default que é NEW, no parm2 pede-se que o arquivo seja catalogado em caso de sucesso e como não há o parm3, o default é utilizado, DELETE.

Dados como o formato do registro (RECFM), organizacao do dataset (DSORG), Tamanho logico do registro (LRECL), tamanho maximo do bloco (BLKSIZE) e mais uma infinidade de parametros/dados são utilizados para informar ao sistema operacional as informacoes que ele necessita para criar o arquivo.

Um arquivo é referenciado dentro de um programa atraves do DDNAME, no nosso caso SAIDA, e as informações constantes no programa sobre o arquivo devem ser refletidas no JCL.

Nos programas escritos em assembler na linha que contem a utilizacao da macro DCB você encontra o nome do DDNAME que deve ser referenciado no JCL, algo como DCB DDNAME=SAIDA, em C encontrariamos o comando fopen(SAIDA,mode); em COBOL a clausula SELECT arquivo ASSIGN TO SAIDA e em PL/1 DECLARE (SAIDA) FILE .

A utilizacao de AVGREC/SPACE facilita muito a alocacao de arquivos, pois nao é necessario possuir conhecimentos sobre os tipos de dispositivo que o arquivo será gravado, os erros que ocorrem com esse tipo de alocacao se resumem a super ou mini alocacao de tamanho a ser alocado para o arquivo for incompativel com o dispositivo ou com a quantidade de dados a ser armazenada.

AVGREC indica a quantidade de vezes que os dados de alocacao contidos em SPACE devem ser multiplicados, U - Unidade (1), K - Kilo (1024), M - Mega (1048576)

O parametro SPACE possui o seguinte formato SPACE=(a,(b,c)) e tem a funcao de requisitar ao sistema o espaço necessário para acomodar os dados que estarao contidos no arquivo, pode ser expresso

(a) em TRK - Trilhas, CYL - Cilindros, numericamente indicando o tamanho do bloco (se não estiver codificado o parametro AVGREC) ou o tamanho do registro (obrigatoriamente é utilizado o parametro AVGREC), no nosso caso ele contem (255) que é o tamanho de um registro pois estamos utilizando o valor de AVGREC.

(b) é a quantidade primaria de ocorrencias e

(c) a quantidade secundaria

A quantidade primaria é o estaço alocado no inicio da execucao do JOB, essa quantidade deve ser compativel com a quantidade de dados estimada que será gerada na execucao normal do programa. A quantidade secundario é opcional, mas geralmente é informada; esse parametro informa ao sistema que ele pode alocar (geralmente) até 15 vezes essa quantidade caso mais espaço seja necessário, isto é, o espaço primario (comumente chamado de primeiro extent) esgotou e os novos dados serão gravados em novos "extents".

Exemplificando:

SPACE=(TRK,(15,20)) significa que o sistema reserva 15 trilhas no inicio do job para esse arquivo e se ele "crescer" além dessa primeira previsao (15 trilhas) poderão ser alocadas mais 300 trilhas (20*15, sendo 15 a quantidade maxima de extents para a area secundaria).

O raciocinio pode ser extrapolado para cilindros.

No nosso exemplo não utilizamos o parametro BLKSIZE para que o sistema utilize o valor padrão, raramente utiliza-se esse parametro tanto no jcl como nos codigos fontes dos programas.

Ao utilizar Trilhas ou Cilindros você precisa saber qual o DEVICE (dispositivo) receberá os dados e todas as caracteristicas desse DEVICE, existe uma infinidade de tipos de dispositivos de armazenamento de dados em mainframe, para exemplificar encontra-se abaixo a mesma definicao do arquivo SAIDA utilizando-se trilhas ao inves do SPACE/AVGREC.

//SAIDA DD DSN=USER.BUGA.SEQUENCI.A0000001, 
// DISP=(NEW,CATLG),UNIT=SYSALLDA, 
// VOL=SER=(VOL001,VOL002), 
// SPACE=(TRK,(100,1),RLSE), 
// DCB=(RECFM=FB,LRECL=255,DSORG=PS, 
// BLKSIZE=0)

As informações extras nesse cartão sao UNIT indicando o tipo de dispositivo, mais especificamente, um dispositivo especifico, um tipo de dispositivo ou um grupo de dispositivos. Sendo os grupos mais conhecidos TAPE (fita de rolo), TAPEC (fita em cartucho), SYSDA (SYStem Direct Access) que é algo muito parecido com um HD (caso encontre a nomenclatura DASD (Direct Access Storage) ela é equivalente a SYSDA) atualmente utiliza-se SYSALLDA para todos os dispositivos de acesso direto, mas ainda utiliza-se DISK com o mesmo significado.

VOL=SER (serial number do dispositivo) indicando que utilizaremos 2 volumes o VOL001 e o VOL002 (é opcional em discos, mas esta aqui para ilustrar o conceito). Esses 2 parametros adicionais não são o complicador, mas sim o calculo do tamanho de seu arquivo que deve ser estimado com base na quantidade de registros e se esse tamanho de arquivo cabera em seu dispositivo.

Um disco padrão 3390 (DISPOSITIVO) possui 56.664 bytes por trilha, 15 trilhas por cylinder e 849.960 Bytes por Cilindro, tais discos possuem diversos modelos variando a quantidade de cilindros que existem na unidade desde 1113 cilindros gerando um disco com aproximadamente 950 mega até 65.520 cilindros contendo esse disco 55 gigas. Existem outros padrões de disco e ao alocar um arquivo utilizando-se dados de trilha ou cilindros, deve-se ter em mente que o tamanho do seu arquivo deve ser compativel com o espaço alocado e esse espaço deve "caber" no disco escolhido.

Por exemplo um disco padrão 3350 possui trilhas com 19069 bytes digamos que você deseja alocar um arquivo com registros de 255 bytes, em cada trilha serão alocados 74 registros (19069/255), nesse dispositivo existem 555 cilindros, 30 trilhas por cilindro contendo uma capacidade incrivel de 317 MegaBytes !

Isso nos diz quem nesse disco poderao constar no maximo 1.303.523 registros (317 MEGA -> 332.398.592/255 = 1.303.523) esse valor deve ser observado para alocar volume e definir quantas trilhas/cilindros serão utilizados no arquivo e nos atentar para as alocacoes de espaço primario e secundario.

Ainda existem fitas, isso mesmo, fita magnetica mas que devido a sua baixa utilizacao não serão abordados nesse texto, caso se depare com algum arquivo que resida em fita, consulte os procedimentos catalogados em sua instalação e procure maiores informações nos manuais, uma consulta a seus colegas de trabalho também é bem vinda.

Mais abaixo em nosso JOB encontramos os seguintes cartoes DD

//SYSABEND DD DSN=NULLFILE 
//SYSUDUMP DD DUMMY

Ambos estão ignorados (DUMMY ou NULL) isto é não será gerado dado de saida para esses 2 cartoes.

Existem, como o leitor já deve ter notado, alguns cartões DD com caracteristicas especiais, já citamos o SYSIN, JOBLIB e o STEPLIB, existem outros entre eles como os cartões DD relativos a DUMP:

SYSABEND - SYSUDUMP - Geram "dump" quando da ocorrencia de ABEND, são utilizados para "debugar"/investigar a causa do erro.

O SYSUDUMP contem a área do programa em execução, o conteudo dos registradores e fornece uma cadeia de subrotinas executadas, o SYSABEND é um pouco mais completo e contem informações sobre o nucleo do sistema no momento do abend, incluindo a LSQA (Local System Queue Area) e blocos de controle de I/O.

SYSMDUMP - Gera "dump" das areas de sistema e do address space do programa sem formatacao, deve ser processado pelo IPCS (Interactive problem control system) ou outro software para posterior leitura/interpretação, geralmente saida em arquivo/data set para uso futuro.

E há ainda cartões DD relativos a checagem de execucao do job SYSCHK e SYSCKEOV, dificilmente o leitor encontrará situações em que eles são utilizados, caso necessário vide o manual.

Para finalizar nossa analise do JOB00001 encontramos uma estrutura IF-ELSE-ENDIF

//-------------------------------------------------------------------- 
// IF (EXECUTA.RC = 0) THEN             1 
//FIM#OK EXEC PGM=IEFBR14               2 
// ELSE                                 3 
//FIM#NOK EXEC PGM=IEFBR14              4 
// ENDIF                                5 
//--------------------------------------------------------------------

1 - Inicio do IF - Se o step EXECUTA terminar com RC (return code) zero 2 - Execute o cartão DD FIM#OK 3 - Senao (step executa não teve return code zero) 4 - Execute o cartão DD FIM#NOK 5 - Fim do IF

A linha 2 apenas será executada se o RC do step EXECUTA for zero A linha 4 apenas será executada se o RC do step EXECUTA for diferente de zero

Esse tipo de estrutura geralmente executa um programa no IF e outro no ELSE, no nosso caso ao verificarmos a execucao do job verificaremos na listagem do JOB que o step FIM#OK rodou indicando que deu tudo certo ou verificamos que rodou o step FIM#NOK indicando que estamos com erro.

Last updated