Archivos de November, 2007

Trabajando con Catálogos

Este artículo pretende arrojar algo más de luz al universo críptico de MVS (o OS/390, z/OS, lo mismo da). Trataré de explicar como funciona la estructura de los catálogos del sistema y cómo interactuar con ellos.

Introducción a los catálogos

Un catálogo es un tipo de fichero VSAM que almacena punteros a datasets o librerías. Si una librería no estuviera catalogada, seria necesario para poder referenciarla especificar, además del nombre de la librería, el volumen donde reside, y en instalaciones con gran número de librerías, llevar un recuento de esto seria demencial.

Generalmente, cuando una librería se crea con un JCL, por lo general, con el parámetro DISP se puede controlar si se cataloga o no. Por ejemplo, con un DISP=(NEW,CATLG,DELETE) le estás diciendo que la librería es nueva, si se crea bien que la catalogue y que si hay algún error al finalizar ese paso del JCL, que la borre.

Por tanto, cuando dicha librería se cataloga, se guardan dos cosas: Por un lado, el nombre de dicha librería y por otro, el volumen de disco donde reside. Ahora bien, ¿Dónde se está catalogando dicha librería? ¿Y cómo se cataloga?.

Estructura de catálogos de z/OS

Para responder a esas dos preguntas, antes hay que conocer la estructura de catálogos en la que puede estar formada nuestra instalación. Por una parte, tenemos el catálogo MAESTRO (MASTER CATALOG) que viene a ser el catálogo por omisión que reside en la raíz. De hecho, el Master Catalog es el primero al que se hace referencia cuando se hace IPL al sistema, en el miembro LOADxx de la SYS1.IPLPARM o en su defecto, en la PARMLIB.

Por otro lado, existen los catálogos de Usuario o USER CATALOGS, que son todos aquellos catálogos que no son el Master Catalog y que podemos crear o borrar a placer.

Dichos catálogos de usuario están conectados al catálogo maestro, de tal forma que existe un puntero desde el Master Catalog a los catálogos de usuario que hayamos definido, y es posible también que un catálogo de usuario dependa de otro catalogo de Usuario del nivel superior, de tal forma que creamos una estructura de índices en arbol tan simple o compleja como nos dé la gana.

Funcionamiento de los catálogos

Una librería es catalogada en un catalogo por su nombre, concretamente, por el nombre de su HLQ o High Level Qualifier.

Si cuando creo una librería, la llamo de cualquier manera, se cataloga por defecto en el Master Catalog. Pero si tenemos miles de librerías, realizar una búsqueda por el Master Catalog le resta rendimiento porque debe buscar las entradas una por una, y si dicho catálogo se hace muy grande, la búsqueda se puede llegar a prolongar mucho innecesariamente.

Además, por lo general, el Master Catalog se debe utilizar para almacenar las entradas de las librerías del sistema, y las librerías o datos de usuario se deberían catalogar aparte para no tener problemas ni mezclar churras con merinas.

Por tanto, cuando creemos una librería nueva, tenemos que tener muy en cuenta la nomenclatura que va a tener, y liberar al Master Catalog de entradas innecesarias. Claro, pero ¿Cómo le digo yo donde catalogar las librerías que yo quiera y asÍ­ luego poder referenciarlas?.

ALIASes

Para eso se crearon los ALIAS. Un ALIAS es una forma de decirle al sistema donde buscar la librería sin tener que recorrerse todos los catálogos. El ALIAS es una entrada más en el Master Catalog, pero tiene tres datos fundamentales: El HLQ de la librería, el catálogo de usuario donde dicho ALIAS está relacionado y el volumen donde dicho catalogo de usuario reside.

Por ejemplo, si quiero que todas las librerías que empiecen por URD se cataloguen en un catálogo de usuario llamado USERCAT.URD, basta con definir un alias y a partir de ese momento, toda librería nueva que empiece por URD, se catalogará siempre en ese catálogo de usuario, y no tocará nada del Master Catalog. Y para buscar es muy sencillo, como todas las búsquedas empiezan en el Master Catalog, al buscar por URD en seguida encontrará la entrada del alias, que redirigirá al catálogo de usuario relacionado y buscará allí dentro, de una manera rápida y eficaz.

Librerías SYS1

Todos los datasets que empiezan por SYS1 son del sistema y por lo tanto, especiales. Estas librerías están catalogadas siempre en el Master Catalog y sacarlas de ese catálogo puede llevar a errores de arranque y problemas con el z/OS en general, por lo que todo lo que empiece por SYS1 es mejor dejarlo en catálogo Maestro. De hecho, si creas una librería SYS1 se catalogará por defecto en el Maestro sin tener en cuenta los ALIAS ni nada. Así que con éstas cuidadito.
Utilidades de manejo de catálogos

Hay una serie de utilidades que nos pueden servir para crear catálogos, administrarlos, diagnosticarlos, listar su contenido, y también para catalogar, y descatalogar librerías o datasets. La gran mayoría se pueden ejecutar desde la Opción 6 del ISPF (TSO Commands) o desde JCL, utilizando la utilidad/comodín IDCAMS.
Como crear un Catálogo de Usuario

Para crear un catálogo de usuario (por ejemplo, USERCAT.URD) basta con lanzar este JCL :

//DEFINCAT JOB CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID
//DFNEWCAT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
DEFINE USERCATALOG -
(NAME(USERCAT.URD) -
VOLUME(PRODS1) -
MEGABYTES(15 5) -
ICFCATALOG -
FREESPACE(20 20) -
STRNO(3) -
REPLICATE ) -
DATA( CONTROLINTERVALSIZE(4096) -
BUFND(4) ) -
INDEX( BUFNI(4) )
/*

Con este JCL definimos el catálogo USERCAT.URD dentro del volumen PRODS1 que automáticamente se conectará al Catálogo Maestro. De todas formas, si no definimos ningún ALIAS relacionado con ese catálogo, este catálogo no guardará absolutamente nada y todo se seguirá catalogando en el Catálogo Maestro, así que para darle uso y liberar al catálogo Maestro de entradas innecesarias, definiremos un ALIAS.
Cómo definir un ALIAS

Desde la opción 6 del ISPF se puede teclear un DEFINE ALIAS (NAME(URD) RELATE(USERCAT.URD) pero también se puede lanzar el JCL con el IDCAMS:

//DEFINCAT JOB CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID
//DFNEWCAT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
DEFINE ALIAS (NAME(URD) RELATE(USERCAT.URD)
/*

Por lo que a partir de ese momento, todo lo que empiece por el HLQ URD se catalogará en ese catálogo de usuario.

También se pueden definir más ALIAS relacionadas con ese catálogo de usuario, de forma que con un DEFINE ALIAS (NAME(BELDANDY) RELATE(USERCAT.URD) y DEFINE ALIAS (NAME(SKULD) RELATE(USERCAT.URD) también podemos hacer que los datasets cuyo HLQ sea SKULD o BELDANDY se cataloguen en el mismo catálogo, pero se corre el riesgo de poblar demasiado ese catálogo de usuario y volver a tener problemas de rendimiento, así que cada uno verá en su instalación como controlar eso.
Catalogando y descatalogando librerías

Desde la opción 3.4 del ISPF, podemos listar los datasets que queremos catalogar o descatalogar, poniendo una C para catalogarlos o una U para descatalogarlos por delante, pero si quisiéramos hacerlo por JCL, tenemos la utility IEHPROGM que nos puede ayudar a resolver el problema:

//DESCATLG JOB CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID
//PASO001 EXEC PGM=IEHPROGM,REGION=0M
//SYSPRINT DD SYSOUT=A
//DD1      DD UNIT=3390,VOL=SER=WORK01,DISP=OLD
//SYSIN    DD *
UNCATLG DSNAME=URD.GODDESS.LICNMBR
/*

Es decir, que este JCL descatalogará (que no borrará) el dataset URD.GODDESS.LICNMBR y solo podremos hacerle referencia catalogándolo de nuevo o yendo al volumen donde reside y explorar su VTOC (en nuestro caso el volumen se llama WORK01).

Si queremos volver a catalogarlo, basta con cambiar UNCATLG por CATLG y añadir el VOLSER donde reside:

//CATLGDSN JOB CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID
//PASO001 EXEC PGM=IEHPROGM,REGION=0M
//SYSPRINT DD SYSOUT=A
//DD1      DD UNIT=3390,VOL=SER=WORK01,DISP=OLD
//SYSIN    DD *
CATLG DSNAME=URD.GODDESS.LICNMBR,VOL=3390=WORK01
/*

NOTA: Estas utilidades sólo sirven para catalogar y descatalogar datasets particionados, secuenciales o HFS. Para los VSAM, el procedimiento es distinto.
Moviendo y juntando catálogos

Puede ocurrir que se prefiera migrar los catálogos o realizar con varios catálogos de usuario, un único catálogo mas grande porque se tienen muchos catálogos de usuario pequeños y esto también puede afectar al rendimiento. Así pues, para migrar los catálogos a uno más grande, utilizaremos el IDCAMS con el REPRO MERGECAT.

Pero antes de todo, definiremos el nuevo catálogo de usuario al que luego cargaremos toda la información, cosa que he explicado en el apartado anterior. Una vez definido, podemos estar en condiciones de migrar los viejos catálogos de usuario a este nuevo catálogo con este JCL:

//MERGECAT JOB CLASS=A,MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID
//STEP1    EXEC PGM=IDCAMS
//DD1      DD VOL=SER=WORK01,UNIT=SYSDA,DISP=OLD
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
REPRO -
INDATASET(USERCAT.BELDANDY) -
OUTDATASET(USERCAT.GODDESS) -
MERGECAT -
FILE(DD1)
/*

Esto hará que se migre toda la información del catálogo de Usuario USERCAT.BELDANDY a USERCAT.GODDESS, quedando USERCAT.BELDANDY vacío.

¿Que queremos migrar USERCAT.URD a USERCAT.GODDESS? Pues se cambia ese JCL y se sustituye USERCAT.BELDANDY por USERCAT.URD y se ejecuta igual.

Comentar la Ficha DD1, que pondremos tantas como VVDS tengamos. En nuestro caso concreto, y dado que solo tenemos una VVDS en ese volumen, pondremos solo una.

Con esto, no basta. Debemos alterar los ALIAS que hacen referencia a ese catálogo, ya que si cuando se crearon hacían referencia al USERCAT.BELLDANDY o USERCAT.URD, y ahora deberán hacerlo a USERCAT.GODDESS. Así que hacemos un DEFINE ALIAS (NAME(BELDANDY) RELATE(USERCAT.GODDESS) y lo mismo para URD, con un DEFINE ALIAS (NAME(URD) RELATE(USERCAT.GODDESS).

Si tuviéramos un error por “DUPLICATE DATA SET NAME” es porque está el ALIAS viejo dando por saco, apuntando a un catálogo que ya está vacío. Así que, borramos el ALIAS con un DELETE URD ALIAS CATALOG(CATALOG.URD) para borrar la entrada y luego lo definimos de nuevo con las sentencias DEFINE de más arriba.

Tirado, ¿no?

¿Y que ocurre con los catálogos antiguos? Que se pueden borrar tranquilamente con un DELETE USERCAT.URD PURGE USERCATALOG y con el de Beldandy lo mismo, DELETE USERCAT.BELDANDY PURGE USERCATALOG.

En un siguiente artículo explicaré algo del universo VSAM, sistemas completos de ficheros/bases de datos especiales del entorno mainframe.

Operaciones y Comandos rutinarios

Hasta ahora hemos explicado temas de programación con COBOL-CICS, planificadores y demás, pero no nos hemos metido dentro de la Master Console del sistema y dar comandos para ver como funciona nuestro sistema y que hacer si queremos lanzar procesos, pararlos y trabajar con los dispositivos conectados.

Como esto puede llegar a convertirse en un capítulo tedioso (el manual MVS System Commands que os recomiendo leer tiene casi 800 páginas), explicaré de manera resumida los comandos más utilizados (o más habituales) y dejo el manual para situaciones más específicas.

Comentar también que estos comandos pueden o no estar autorizados en esa consola, con la configuración del miembro CONSOLXX de la PARMLIB. Si la consola que estamos usando tiene una línea con AUTH=MASTER significa que esa consola tiene la autorización para emitir todos los comandos, algunos de los cuales pueden llegar a ser destructivos (como el VARY por ejemplo, que explicaré más adelante).

Ahora mismo el comando más tecleado es el D o DISPLAY. Con este comando, nos visualiza el estado de TODO el sistema, dependiendo que le digamos que visualizar. Por ejemplo, un D A,L nos muestra todos los procesos activos del mainframe:

RESPONSE=ASGARD
IEE114I 09.22.36 2007.291 ACTIVITY 459
JOBS     M/S    TS USERS    SYSAS    INITS   ACTIVE/MAX VTAM     OAS
00003    00025    00008      00031    00007    00006/00010       00015
LLA      LLA      LLA      NSW  S  VLF      VLF      VLF      NSW  S
DLF      DLF      DLF      NSW  S  RMF      RMF      IEFPROC  NSW  S
SDSF     SDSF     SDSF     NSW  S  RRS      RRS      RRS      NSW  S
RACF     RACF     RACF     NSW  S  EPWFFST  FFST     EPWFFST  NSW  S
JES2     JES2     IEFPROC  NSW  S  TSO      TSO      STEP1    OWT  S
DFRMW3   DFRMW3   IEFPROC  NSW  S  VTAM     VTAM     VTAM     NSW  S
SYSLOGD1 STEP1    STCLOGD  OWT  AO FTPD1    STEP1    STCTCP   OWT  AO
BELDANDY  OWT      URD    OWT      SKULD   OWT     PEORTH    OWT
CHRONO    OWT      HILD   OWT      MARLLER OWT     KUJAKU    IN

Se pueden ver perfectamente arriba los procesos activos y, debajo, los usuarios conectados al sistema.

Si en cambio hacemos un D U (DISPLAY UNIT) con los parámetros adecuados podemos ver el estado de toda unidad o dispositivo conectado al sistema. Así pues, hacer un D U,DASD,ONLINE nos muestra una lista de unidades de disco que están online y disponibles en el sistema. Si cambiamos DASD por TAPE, pasará lo mismo pero listará las unidades de cinta.

RESPONSE=ASGARD
IEE457I 10.34.38 UNIT STATUS 753
UNIT TYPE STATUS        VOLSER     VOLSTATE
6101 3390 A             OSRES1     PRIV/RSDNT
6102 3390 A             OSRES2     PRIV/RSDNT
6103 3390 A             OSRES3     PRIV/RSDNT
6104 3390 A             PRODS1     PRIV/RSDNT
6105 3390 O             PRODS2     PRIV/RSDNT
6106 3390 O             DSNYGG     PRIV/RSDNT
6107 3390 A             CICYGG     PRIV/RSDNT
6108 3390 A             AORYGG     PRIV/RSDNT
6109 3390 A             TMPYGG     STRG/RSDNT
610A 3390 O             SMS001     PRIV/RSDNT
610B 3390 A             SMS002     PRIV/RSDNT
610C 3390 A             SMS003     PRIV/RSDNT
610D 3390 O             SMS004     PRIV/RSDNT
610E 3390 O             SMS005     PRIV/RSDNT
610F 3390 O             HSM001     PRIV/RSDNT

En definitiva, el DISPLAY viene muy bien para tener conciencia de lo que está haciendo tu instalación.

Otro de los comandos que se utiliza mucho, sobre todo relacionado con los dispositivos es el V o VARY. Con el VARY, puedes controlar el estado de todos los dispositivos del sistema, pudiendo desconectarlos o conectarlos a placer, de ahí que pueda ser destructivo (imaginaos que desactivo un volumen que tiene tablas de un DB2, con eso jodes el DB2 y se aborta el sistema).

Por ejemplo, si queremos poner un disco offline porque lo vamos a cambiar o quitar, basta con emitir el comando V 610D,OFFLINE. Esto hará que el volumen SMS004 del ejemplo anterior se desactive y no se realizarán operaciones sobre él.

En cambio, si hemos puesto un disco más grande o ya hemos terminado de arreglarlo, con hacer un V 610D,ONLINE, el disco volverá a estar disponible. De hecho, ciertas operaciones especiales (como formatear el disco) requieren que el disco esté OFFLINE para el host. Todo lo que digo para discos, vale para cintas, impresoras, terminales, etcétera.

En cuanto a los procesos, se pueden arrancar con un S o START y para pararlos basta con hacer un P o STOP. Si por lo que sea, el proceso se ha trincado y no acepta la parada ordenada con el STOP, se puede emitir un C o CANCEL, pero este proceso si tiene datos en memoria hará que se pierdan definitivamente, así que cuidadito con éste comando.

Estos comandos de control de procesos solo afectan a aquellos procesos que residen en la PROCLIB, que es una librería del sistema donde residen todos los “ejecutables” de los procesos. Por ejemplo, si hacemos un S TCPIP, el sistema irá a lanzar el JOB llamado TCPIP que reside en la PROCLIB. De lo contrario, dará un error.

Otro comando interesante aplicado a procesos es el F o MODIFY. Si queremos que un proceso cambie su comportamiento, cambiar su configuración o su modo de trabajo, basta con utilizar este comando. Por ejemplo, con un F BPXOINIT,SHUTDOWN=FORKINIT le estamos diciendo que modifique el proceso BPXOINIT, enviándole el comando SHUTDOWN=FORKINIT, que lo que hace es parar el sistema Unix System Services del z/OS (el z/OS tiene un Unix dentro, que funciona como un proceso más, por cierto).

A partir de aquí, lo mejor es consultar el manual que he comentado antes, y probar nuevos comandos, ya que cada comando tiene muchos parámetros según lo que se quiera visualizar, y puede llegar a ser un engorro.

Control del SPOOL del JES2

Como expliqué en anteriores artículos, el JES2 (Job Entry Subsystem) es el subsistema de trabajos que utiliza el mainframe para sacar adelante jobs que se envían para que los procesen, y luego dejan una salida para su estudio o análisis. El JES2 entre otras cosas tiene unos datasets de SPOOL o HASPACES que se utilizan para guardar el proceso y el resultado de los trabajos en ejecución, en cola o procesados. Y, salvo que se le diga en el JCL donde lanzas el trabajo, que los “purgue” o borre, van quedando ahi llenando el SPOOL, poco a poco, pero sin remisión.

La alarma puede llegar si se lee lo siguiente en la consola del sistema:

*09.33.16          *$HASP050 JES2 RESOURCE SHORTAGE OF JQES - 99%
* UTILIZATION REACHED

*09.33.40          *$HASP050 JES2 RESOURCE SHORTAGE OF JOES - 99%
* UTILIZATION REACHED

Estos mensajes alertan que el SPOOL de Job Queue elements (JQE) y el Job Output Elements (JOE) están al 99%. Si llegaran al 100%, se produciría una situación de deadlock, no pudiendo lanzar nada para borrar nada porque no nos lo permitiría y congelando la producción teniendo que recurrir al botonazo y tentetieso, teniendo que realizar una IPL “cold start” con el parámetro de JES2 r xx,cold,noreq.

Esto formatearía los SPOOLs y todo lo que tuvieramos guardado de salidas de trabajos, se perdería sin remedio, pero por lo menos todo volvería a arrancar.

Llegar al 100% es el extremo de la dejadez supina del departamento de operación, de hecho los mensajes del 99% también lo son, ya que dichos mensajes empiezan a aparecer cuando se sobrepasa el 80% de utilización (aunque este parámetro es configurable en el JES2PARM que reside en la PARMLIB), y a menos que no se haga nada para remediarlo y dejar que se llene todo, se podrían tratar sin problemas para nunca llegar al 100%.

El artículo de hoy tratará sobre cómo llevar un control del SPOOL haciendo un mantenimiento de las colas de salida para que no se llenen los dataset de SPOOL.

Opción 1: Borrado manual. La persona que lanza el job es al fin y al cabo responsable de su salida, así que lo lógico es que una vez que termine de ver su proceso y salida, lo borre del spool, así no se va llenando.
Opción 2: Automatizar el borrado. Se podría decidir una política en la instalación que los jobs acabados con mas de 15 días de antigüedad, se borren de manera automática, simplemente ejecutando el siguiente comando de consola:

$OJOBQ,Q=A,CANCEL,A>15

Este comando borraría todos los jobs de clase A. Si quisieramos borrar los de otra clase, cambiaríamos la Q=A por Q=B, Q=X, etcétera. Y si editamos nuestro planificador (ver Planificación de trabajos con Mainframes) y añadimos la siguiente línea al miembro PLANIF:

/*$TA,T=10.00,’$VS,”$OJOBQ,Q=A,CANCEL,A>15”’

Haremos que todos los días a las 10 de la mañana, se ejecute el comando que haga que los trabajos con mas de 15 días de antigüedad en la cola de salida de clase A se borren.

Sencillo, ¿no?