Affichage des articles dont le libellé est Cobol. Afficher tous les articles
Affichage des articles dont le libellé est Cobol. Afficher tous les articles

28 juillet 2025

Personnaliser le Makefile pour conserver les sources des programmes Cobol

Lors des générations, HR Access rédige puis compile les programmes exécutables. Puis les sources sont détruits. Il peut être intéressant de conserver ces sources pour :

  • Relecture de code
  • Recompilation après adaptations manuelles
  • Recompilation après migration technique

Pour cela, on pourra par exemple :

  • Créer un répertoire $SIGACS/prod/cbl
  • Adapter le fichier $SIGACS/adm/cfg/Makefile pour y ajouter une copie et compression du source


Par exemple sur ce chapitre (à reproduire sur les autre en adaptant les suffixes) :

#-----------------------------------------------------------------
#       Build the dynamically loadable module from a .pco
#       Pro*Cobol program.
#

.pco.gnt: $(*).pco
        @echo "--- "
        @echo "---    $(*).pco  -->  $(*).gnt "
        @echo "--- "
        @echo "$(PROCOB) $(PROFLAGS) iname=$(*).pco oname=$(*).cbl"

        @cp $(*).pco ${SIGACS}/prod/cbl; gzip -f $(*).pco

        @cd `dirname $(*)`; $(PROCOB) $(PROFLAGS) iname=$(*).pco oname=$(*).cbl
        @$(COB_VAR) cd `dirname $(*)` ; $(COB) -vP -u $(COBFLAGS) $(*).cbl
        @chmod 775 $(*).gnt

A noter : dans le Makefile les commandes doivent être précédées de tabulations (et non d'espaces)

28 mars 2025

Execution error : error code: 162, Arithmetic overflow or underflow

A l'occasion d'une migration Linux, le projet a recompilé l'application avec une nouvelle version de Microfocus Cobol et de nouvelles options.

A l'occasion de tests batch, le programme de calcul de paie s'interrompt parfois avec l'erreur :

Execution error : file 'JFCALDBI'
error code: 162, pc=0, call=1, seg=0
162     Arithmetic overflow or underflow

Il se trouve qu'un traitement de paie effectue une division par zéro.

En effet les options utilisées avec le nouveau compilateur Visual Cobol sont moins permissives que celles de l'ancien Server Express. 

  • NOCHECK
    • (NO)CHECKDIV qui contrôle  les divisions par zéro
    • (NO)CHECKNUM qui contrôle la numéricité des rubriques
  • BOUND contrôle les débordements de tableau occursés.

L'option NOCHECK désactive les options CHECKNUM et CHECKDIV. 
Avec NOCHECKDIV une division par zéro provoque une erreur bloquante du programme.

Si cela se produit en développement ou recette, il est possible d'activer des traces, repérer le traitement fautif et lui ajouter un contrôle pour ne pas provoquer l'erreur. Problème : si l'arrêt brutal du programme se produit en production, il met en danger l'exploitation des traitements batch.  

Pour débloquer la situation et laisser passer les divisions par zéro et les débordements de tableaux, retirer -C NOCHECK et -C BOUND puis placer les options suivantes dans le fichier adm/cfg/config :

COBFLAGS=-C ASSIGN=EXTERNAL -C SEQUENTIAL=LINE -C NOANIM -C NOCSI -C CHECKDIV -C NOCHECKNUM -C NOSERIAL -C IBMCOMP -C SIGN=EBCDIC -C WRITELOCK -C NOTRUNC -C NOBOUND -C PERFORM-TYPE=MF -C COPYLIST -C NORESEQ -C TRACE -U

Recompiler les programmes.

On supprime NOCHECK que l'on décompose en CHECKDIV et NOCHECKNUM.
On remplace BOUND par NOBOUND.

Attention toutefois : si le programme semble se dérouler normalement, une division par zéro donne "an undefined result" ... Quand au débordement de tableau, il écrase les variables définies au delà.

22 juin 2022

Programmes Visual Cobol persistant en mémoire

A compter d'une "certaine version" de MicroFocus Cobol, la libération des processus chargés par les BHR ne se fait plus par défaut. Les processus peuvent alors devenir très consommateurs de mémoire.

Pour obtenir une libération mémoire effective lors du déchargement des processus
Créer un fichier de configuration, par exemple $SIGACS/adm/cfg/visualCobol.cfg contenant la ligne :

set default_cancel_mode=0

Positionnez la variable COBCONFIG dans le .profile :

COBCONFIG=$SIGACS/adm/cfg/visualCobol.cfg 

export COBCONFIG

2 novembre 2017

Executer une commande système dans un traitement Cobol

Le site MicroFocus donne un exemple de Cobol exécutant une commande système et récupérant le code retour :
https://community.microfocus.com/microfocus/cobol/net_express__server_express/w/knowledge_base/6537/invoke-a-unix-command-from-within-cobol-using-call-system-and-retrieve-the-return-code

Dans le principe, on utilise la commande Cobol
CALL "SYSTEM" USING null-terminated-command  RETURNING return-code-ws.

La commande est terminée par un caractère NULL :

000014 01 null-terminated-command.
000015     05 command      pic x(2048).
000016     05 filler          pic x value x"00".


Le code retour est placé dans un numérique :
000002 01 return-code-ws     pic s9(8) comp-5.
L'article explique que pour AIX, Solaris, HP/UX PARISC and HP/UX Itanium (big-endian) il faut la redéfinir ainsi :
000005     05 filler          pic x.
000006     05 high-order-byte pic s9 comp-5.
000007     05 filler          pic x.
000008     05 low-order-byte pic s9 comp-5.

Et pour Linux x86, HP/Tru64, SCO, UnixWare - et certainement Windows - (little-endian) ainsi :
000010     05 filler          pic xx.
000011     05 high-order-byte pic s9 comp-5.
000012     05 low-order-byte pic s9 comp-5.


Pour le contrôler :
000024      if low-order-byte = 0
000025          display "return code from shell is: ",
000026               high-order-byte
000027      end-if


J'ai testé l'exemple fourni sur un AIX (donc un "big-endian") avec succès :

cob -vx callsys.cbl -o callsys
 

callsys

Enter command to be executed by shell
 (enter 'done' to quit)
ls -l  /tmp/dummy
-rw-r--r--    1 hraref   hraref          0 Aug 28 11:58 /tmp/dummy
return code from shell is: +000

Enter command to be executed by shell
 (enter 'done' to quit)
rm /tmp/dummy
rm: /tmp/dummy not removed.
Not owner
return code from shell is: +002


Merci à l'auteur de l'article ...

10 mars 2017

Erreur ASLM: Semaphore failure. Rerun as root

Sur un serveur Linux hébergeant HR Access, un script de sécurité a modifié les droits d'accès au fichier /var/aslmfsem.

Conséquence : plus aucun programme Cobol ne pouvait s'exécuter sur la machine ... Car ce fichier (sémaphore) sert lors du contrôle des licences d'exécution. 

  • Le TP est bloqué.
  • OpenHR ne redémarre pas (redémarrage figé)
  • Lors de l'exécution d'un batch, on trouve le message :

ASLM: Semaphore failure. Rerun as rootASLM: Errno 1013

Si cette erreur survient, contrôlez que le fichier existe, qu'il est propriété de root, et qu'il dispose des droits rw_rw_rw_.

Si le blocage persiste, envisagez de :
  • Exécuter $COBDIR/aslmf/apptrack option "6-Reinitialize Licensing",
  • $COBDIR/aslmf/initaslm,
  • Si nécessaire rebooter le system pour reinitialiser la memoire partagée,

Plus d'information sur le site de MicroFocus : community.microfocus.com : aslm-1013-semaphore-failure

22 avril 2013

0509-150 Le module dépendant libcobrts.2.so n'a pas pu être chargé

La variable LIBPATH ou LD_LIBRARY_PATH sert à localiser les librairie de COBOL. Elle est positionnée par le .profile - et est "remise en place" par le script $ENV. Sans cela il arrive que les processus Unix fils perdent la valeur de cette variable.

Le symptôme classique de la perte de cette variable est le message suivant (en général lorsqu'une chaîne batch exécute un tri MFSort) :


message : exec() : 0509-036 Impossible de charger le programme /opt/cobol/bin/mfsort32 en raison des erreurs suivantes :
0509-150 Le module dépendant libcobrts.2.so n'a pas pu être chargé.
0509-022 Impossible de charger le module libcobrts.2.so.
0509-026 Erreur système : Un fichier ou un répertoire du chemin d'accès n'existe pas. 


En standard le script $ENV de HRAccess est nommé en standard $FILE/.kshrc. Le préfixe "." rend le fichier invisible (sauf à utiliser l'option "-a" de la commande "ls"). Il est donc peu connu - et soumis au risque d'être purgé ou oublié lors des duplications.

Je préfère le rendre visible et le déplacer sous le nom $SIGACS/adm/cfg/kshrc.cfg. Si vous faites de même n'oubliez pas de corriger l'alimentation de $ENV et de faire un arrêt - démarrage pour que les transactionnels prennent en compte votre mise à jour.

Addendum : modifier aussi les scripts $SBIN/OPER job strcalck3w et stpcalck3w qui appellent directement $FILE/.kshrc au lieu d'utiliser la variable $ENV ...

8 janvier 2013

Micro Focus LMF - 004: You have exceeded the license limit for this product

Sur une même machine Unix, le nombre de compilations Cobol simultanées est limité par le nombre de clefs de licence de "Developement" achetées. Si ce nombre est dépassé, la compilation sort en erreur avec le message suivant :

Micro Focus LMF - 004: You have exceeded the license limit for this product.
No more licenses for this product are available.
All of the 0001 license units in the license database are in use.
Execution of this product has been terminated.
Contact your license administrator or Micro Focus product supplier to obtain additional license units.

Dans l'exemple ci dessus, la machine ne dispose que d'une clef. Donc sur la machine une seule compilation peut être exécutée à la fois.

Il est possible de demander la "mise en attente" de la compilation - ce qui évite de voir le traitement de génération sortir immédiatement en erreur. Ceci en positionnant la variable LMFWAIT : celle ci permet d'indiquer un nombre maximum de tentatives et un delai entre chaque tentative.

LMFWAIT=6,10
export LMFWAIT

Dans cet exemple, si la clef de compilation est déjà prise, le traitement fera 6 tentatives toutes les 10 secondes avant de sortir en erreur. Un message d'alarme est alors affiché :

Micro Focus LMF - 016: You have exceeded the license limit for this product. 
No more licenses for this product are available.
All license units in the license database are in use.
** Waiting for license unit to become available **
Contact your license administrator  or Micro Focus product supplier to obtain additional license units.

14 septembre 2012

Analyser les temps de traitement des fonctions Cobol avec le "Profiler"

Cobol offre un analyseur de temps de traitement. Ci joint un lien vers un article de la Micro Focus Community.

Pour l'activer il faut compiler l'exécutable avec une option particulière, lancer le traitement puis extraire les résultats obtenus :
  • Modifier le .profile pour exporter, dans en fin de chapitre "VARIABLES D'ENVIRONNEMENT COBOL" la variable COBPRFDIR=$TMPDIR
  • Faites une RBZ du programme à analyser avec conservation des sources
Conservation des fichiers de compilation (0/1)  [0]: 1
  • Dans $TMP contrôlez la présence des fichiers *.idy et *.cbl
  • Retrouvez (dans le log de la RBZ) et adaptez la commande de compilation Cobol "cob"  pour y ajouter l'option -C PROFILE
  • Recompilez le programme (exemple avec FFCALDBI) avec l'option -C PROFILE
cob32 -C nolist -vz -C ASSIGN=EXTERNAL ... -C COPYLIST -C NORESEQ -C PROFILE -U /hradev/txt/tmp/FFCALDBI.cbl
  • Copiez le généré (suffixe ".so" en général - consulter ${SUFMOD}) dans $SIGACS/prod/gnt
  • Conservez le fichier *.idy dans $TMP
  • Si le programme concerné est un programme TP, faites un arrêt / démarrage de OpenHR,
  • Exécutez votre traitement,
Une fois l'exécution du programme terminée, un fichier *.ipf est créé dans $TMPDIR,
  • Pour en lire les données, utilisez la commande cobprof (ici avec une limitation a 25 lignes) :

cobprof FFCALDBI.ipf +LIST | head -25

Total time:    1517240 milliseconds.      Module called once.
% time      time   entries  ms/entry      paragraph
-------------------------------------------------------------------------------
 45.35    688110        26     26466      UTTDP424-XB0B0LEC-XY
 10.99    166750 308687680         0      UTTBPUUU-XB0BBL5J-NC
 10.87    164900 308678970         0      UTTBPUUU-XB0BBL5J-NE
 10.51    159450 308678970         0      UTTBPUUU-XB0BBL5J-NC-900
 10.32    156650 308678970         0      UTTBPUUU-XB0BBL5J-NE-FN
  5.90     89460       151       592      GIP-ECR-01
  0.95     14400  26188434         0      UTTBPUUU-XB0BBL5J-AF
  0.94     14280  26192800         0      UTTBPUUU-XB0BBL5J-AE
  0.93     14150  26188434         0      UTTBPUUU-XB0BBL5J-AE-900
  0.92     13930       340        41      GIPLEC-01
  0.78     11890  26188434         0      UTTBPUUU-XB0BBL5J-AF-FN
  0.13      1950     22757         0      F8LCD
  0.12      1770      5550         0      RECHJOUR-01
  0.09      1410       150         9      VALCOND-DS3
  0.07      1020   1587369         0      RECH-ZYX3-01
  0.06       920      8710         0      UTTBPUUU-XB0BBL5J-PA
  0.06       910       150         6      TRICOND
  0.05       820   1582719         0      RECH-ZYX3-02
  0.04       560       150         4      F5025-2
  0.04       550         1       550      F-SGR2-01-TDP401


NB : En cas de message "Open Fail on .idy for FFCALDBI.idy", c'est que le fichier *.idy a été perdu. Pour pouvoir utiliser cobprof il vous faut le recréer (commande cob).

Vous trouverez :
  • Total time : temps CPU total
  • paragraph : fonction cobol concernée,
  • %time : pourcentage du temps total d'exécution passé dans ladite fonction,
  • time : temps en ms
  • entries : nombre de passages dans la fonction
  • ms/entry : temps moyen par passage

Notez le "Module called once" : le programme a été exécuté une seule fois (les statistiques sont cumulées à chaque exécution - si vous ne souhaitez pas cela, vous devez supprimer/renommer le *.ipf avant chaque exécution).

Si une fonction appelle un sous programme, le temps de ce sous programme est comptabilisé dans la fonction - sauf si ce sous programme est lui même compilé avec l'option "PROFILE".

La validité des résultats fournis par cet utilitaire est toutefois sujette à caution ... En effet, dans mon exemple :
  • UTTDP424-XB0B0LEC-XY est une fonction "vide" qui ne fait qu'un "perform" vers UTTBPUUU-XB0BBL5J ... qu'elle prenne 688 secondes pour 26 appels n'est pas compréhensible,
  • et si le temps attribué à cette fonction cumule celui des fonctions performées, pourquoi voit-on alors plus bas des références à ces même fonctions UTTBPUUU-XB0BBL5J ?
  • Mode "Profiler" activé le traitement complet dure 28 minutes, mais une fois ce mode désactivé (recompilation sans l'option -C PROFILE) le temps de traitement passe à 3 minutes !
  • En fait le mode "Profiler" semble extrêmement sensible aux boucles (ici 300.000 passages dans chacune des fonctions UTTBPUUU-XB0BBL5J-NC/NE...) et ralentit significativement le traitement ...

En conclusion, si ce Cobprof vous donne la cause de vos problèmes de performance, tant mieux ... Mais regardez son analyse avec circonspection.

  • Limitez son usage a des cas de "simples" (ex : un seul dossier traité).
  • Contrôlez que les temps de traitement avec / sans le mode "Profiler" est inchangé.

PS : Pour supprimer ce mode "Profile", refaites une RBZ sur le module concerné.

15 mars 2012

Editeur de fichier MF Cobol : dfed

MicroFocus met a disposition un utilitaire permettant sous Unix d'éditer les fichiers Record Sequential : dfed.

Avant de le déclencher, positionnez la "taille de la fenêtre" :
export LINES=25
export COLUMNS=80

Puis ouvrez le fichier à éditer
dfed monfichier

NB : L'interface peut devoir demander le type du fichier et la longueur des enregistrements.
Pour les archives de paie YS, le type de fichier et "Sequential" (valider en tapant "espace") et la longueur des enregistrements est de 3000 (validez en tapant <CR>).



Ci dessous des correspondances de touches clavier utiles :
  • F1 ... F9 F10 F11 F12 accessibles par les touches /1 ... /9 /0 /- /=
  • menu Alt (open, save) = /a
  • menu Ctrl (search) = /c

Déplacer vous avec les flèches.

Faites Esc deux fois pour sortir sans enregistrer


Syntaxe :
  dfed \[filename] \[{-A|-E}] \[{-B|-b}]
  • -A : ASCII (par défaut) / -E : EBCDIC
  • -B : backup du fichier si édition (par défaut) / -b : pas de backup


A voir :
supportline.microfocus.com editeur
supportline.microfocus.com keys

9 mars 2012

Obtenir les sources Cobol incluant le code des Clause Copy (fichier .lst)

Sur Unix, lorsque l'on compile les processus, il n'y a plus nécessairement de création des fichiers .lst (les seuls dans lesquels on ait le contenu des clauses COPY).

Pour les avoir, il faut ajouter l'option -P à la commande de compilation
  • dans le fichier "config" de ${SIGACS}/adm/cfg
Ajouter -P en fin de la ligne COBFLAGS

# Directives for Cobol compiler
COBFLAGS=-C ASSIGN=EXTERNAL -C SEQUENTIAL=LINE ... -P

  • ou dans le fichier "Makefile" $SIGACS/adm/cfg (pour chacun des types d’exécutable à générer)

@$(COB_VAR) cd `dirname $(*)`; $(COB) -vzP $(COBFLAGS) $(*).cbl

Les chaines de génération placeront désormais les ".lst" dans $LIS.
Attention : ces fichiers sont volumineux. Pensez à les purger.

21 novembre 2011

ERREUR D'ACCES (TABLE RELATIONNELLE) : PP10/SELECT/9X/DF/000000000000805

Ce genre de message (erreur SQL 805) se produit sous DB2 quand le "Bind" de certains Cobols n'a pas été joué.
SQL0805N Package "<package-name>" was not found

  • Si l'environnement était propre jusqu'alors, on pourra se contenter de refaire le bind du programme concerné.
  • Si le contexte est défavorable (environnement instable), il vaut mieux rejouer la totalité des binds de la totalité des programmes. Cela rendra la situation plus claire.

Re-Exécution des Bind pour les programmes référencés en table PG15


db2 -x "select pkgname from syscat.packages, ${HRSCHEMA}.pg15 where pkgschema='${HRSCHEMA}' and pkgname=rtrim(rdprog)||cdprog" | while read BND
do
   [ ! -f $SIGACS/prod/bnd/${BND}.bnd ] && echo "<W> Fichier ${BND}.bnd inexistant" && continue
   if ! db2 "bind $SIGACS/prod/bnd/${BND}.bnd collection ${HRSCHEMA} datetime iso isolation UR qualifier ${HRSCHEMA}" ; then
      echo "<W> Bind Ko pour ${BND}.bnd"
   else
      echo "<I> Bind Ok pour ${BND}.bnd"
   fi
done > ${LOG}/ReBind.log 2>&1

Exécution du Bind pour les programmes présents dans $SIGACS/prod/bnd mais absents en base de données


ls $SIGACS/prod/bnd | grep '\.bnd$' | while read F
do
   BND=$(basename $F .bnd)
   EXIST=$(db2 -x "select count(*) from syscat.packages where pkgschema='${HRSCHEMA}' and pkgname='${BND}'")
   if [ ${EXIST} -eq 0 ]; then
     if ! db2 "bind $SIGACS/prod/bnd/${BND}.bnd collection ${HRSCHEMA} datetime iso isolation UR qualifier ${HRSCHEMA}" ; then
      echo "<W> Bind Ko pour ${BND}.bnd"
     else
      echo "<I> Bind Ok pour ${BND}.bnd"
     fi
   fi
done > ${LOG}/NewBind.log 2>&1

FYI : la liste des packages générés par DB2 lors d'un bind est accessible à travers la vue "syscat.packages".

7 novembre 2011

Message d'erreur SORT(EXTSM) failed - sort engine status = 9/065

Le problème

Sur un de mes environnements HRv5, certaines chaines parallélisées sortent en erreur lors de tris Cobol avec un statut 9/065.

Le status 9/065 signifie "File locked". Si des traitements batch ont lieu en parallèle; c'est probablement que deux opération de tri ont eu lieu en même temps sur l'environnement, avec des noms de fichiers de travail identiques.

Une solution

Pour sécuriser les MFSort, le support microfocus dit nécessaire de positionner une variable $TMPDIR sur un répertoire différent pour chaque tri... une gageure. Ma proposition est d'utiliser un répertoire $TMP/$$ créé à chaque appel de "mfsort" ($$=Pid Unix du shell en cours),

Pour ceci, l'option la plus simple et la moins impactante pour l'application est :
  •  de surcharger la commande MicroFocus "mfsort"
  •  par une "fonction exportée" spécifique nommée "mfsort"
  •  déclarée et exportée via le script $ENV de chaque environnement.

Extrait du script $ENV

# Fonction mfsort
# Description :
#       Créer un repertoire temporaires dedie avant chaque appel a mfsort.
# Syntaxe : mfsort take ...
function mfsort
{
echo "mfsort Spécifique 20110620 : redefinition TMPDIR=${TMP}/$$"
export TMPDIR=${TMP}/$$
mkdir -p ${TMPDIR}
trap 'rm -rf ${TMPDIR}' 0
# Adapter le chemin en fonction du site
/logi/cobol/bin/mfsort "$@"
}
typset -fx mfsort 

A noter

Avec HRv7 les chaînes HR intègrent en début de script :
TMPDIR=$TMP/T"$nupro"
export TMPDIR 

Brainstorming

A- Ma proposition est d'utiliser un répertoire $TMP/$$ créé à chaque appel de "mfsort" ($$=Pid Unix du shell en cours),

B- Surcharger la variable TMPDIR au moment de l'exécution du shell n'est pas suffisant car il faut gérer la création et la purge dudit répertoire $TMP/$$.

C- L'appel à la commande "msfort" est présent dans les chaines standard HR. Remplacer les "mfsort" par des appels à une commande d'un autre nom est contraignant : ceci implique de patcher la macro A39MT de PVBAMC00, de regénérer et relivrer toutes les chaînes HR.

D- Ceci implique de créer une fonction ou un script Unix "mfsort" spécifique de MEME NOM et qui soit PRIORITAIRE sur la commande "msfort" de /logi/cobol/bin. Pour ceci,

E1- Créer un shell "mfsort Spécifique" n'est pas suffisant. Pour être prioritaire l'ordre des répertoires du "PATH" Unix peut devoir être adapté. Si tel est le cas, ceci peut être source d'effets de bords. Un autre moyen est de créer et d'exporter un alias "mfsort" pointant sur ce script "mfsort Spécifique"

E2- Créer une fonction "mfsort Spécifique" et la référencer dans le "FPATH" n'aura pas d'effet car le FPATH est pris en compte APRES le PATH. le "mfsort" de MicroFocus serait donc trouvé AVANT la fonction "mfsort Spécifique". Un autre moyen est de créer et d'exporter cette fonction.

F- Déclarer l'alias ou la fonction dans le .profile est gênant car ces scripts sont spécifiques à chaque environnement et exclus de la livraison. De plus ces alias et fonctions - exportées ou non - sont "perdus" lors de l'ouverture d'un sous-shell !

G- Déclarer l'alias ou la fonction dans un script de "fonctions communes" fonctionnerait, à condition que ce dernier soit bien appelé par TOUS les scripts, ce qui est peu probable.

H- Déclarer l'alias ou la fonction dans le script $ENV de l'environnement permet d'en disposer dans chaque session. L'y exporter permet d'en disposer dans les sous shells.

...

Ouf !

7 octobre 2011

MF-LMF: License Key database unusable due to copying, restoration or tampering

Suite à installation d'un patch AIX, le gestionnaire Microfocus Cobol a perdu les clefs de licence (compilation et runtime). Ci dessous la procédure utilisée pour les rétablir ...

Configuration du site : HRv7 Unix Oracle avec Cobol Server Express 5.1 sur AIX 6.1

Début des opérations :
  • Arrêt complet des applicatifs (dont listener oracle)
  • Arrêt et mise à jour système AIX + reboot
  • Redémarrage du listener Oracle (cas où le listener n'est pas démarré au boot)
  • Ouverture des bases de chaque environnement

Pour la licence d'usage

Avec root, reinitialisation de la base de licence
(chemin à adapter en fonction du site - il s'agit du chemin vers MF Cobol)

export COBDIR=/opt/microfocus/cobol
cd $COBDIR/aslmf
./aslmdbrecover


Avec root, installation de la licence

cd $COBDIR/aslmf
./apptrack
You must set an access password, before proceeding. Enter 6 characters as the password (6 spaces removes password)
-> ******

Server License Administration System - AppTrack
-----------------------------------------------------------
1. License List
2. License Summary
3. License Install
4. License Uninstall
5. Change/Set Password
6. Reinitialize Licensing
7. Current Users
9. Quit
Enter the Menu Selection


=> choix 3 (License Install)

Serial=***********AI+
License=************************

License installed ok


=> choix 9 (Quit)

Avec un des comptes hra***, test d'un batch :
subbn 
select NUDOSS from ZE00

Contrôle du log.


Si tout est correct, avec chacun des comptes hra***, redémarrage des applications  (la base étant active, démarrer AP0 avec csadmin, OpenHR, puis HRQuery et HRaSpace)

Opération a prévoir pour la licence de compilation

Reinitialisation de la base de licence, installation de la licence
(chemin à adapter en fonction du site - il s'agit du chemin vers le gestionnaire de licences MF Cobol)

export COBDIR=/opt/microfocus/mflmf
cd $COBDIR

./lmfdbrecover

This script will remove the existing LMF license database
and prompt you to install your LMF licenses to a new database.

Do you wish to continue? (y/n)
y
Empty database created ok

License db recovery utility (lmfdbrecover) starting.

1. Text Mode license install
2. Screen Mode license install
3. Exit with no license install

=> choix 1

Micro Focus License Manager Command Line Interface
--------------------------------------------------
Select the function you require from the list:
License Install - Enter 'I'
License Uninstall - Enter 'U'

=> choix I

installer la licence de compilation
Serial=************AI+
License=************************

License added ok

Install another license? (y/n)
n


Avec root, redémarrage du démon

cd /etc
./mflmrcscript
Starting MFLM License Manager
MF-LMF:Wed Oct 12 23:15:30 2011: LMF Starting


Avec un des comptes hra***, test d'une compilation
subbz 
processus et radical : AS800
module : BOT

Contrôle du log

12 septembre 2011

Message d'erreur SORT020U: SORT(EXTSM) failed - sort engine status = 24

Cette erreur provient de l'utilitaire mfsort. Elle survient lors de la génération d'un fichier indexés de plus de 4 Go.

  SORT013U: I/O error on dataset '/hraccess/file/PAPFR/PVBDFAS0
  SORT014U: Status = 24
  SORT020U: SORT(EXTSM) failed - sort engine status = 24

Cause : Par défaut le format des fichiers indexés on un IDXFORMAT (format des fichiers indexés) à 1 pour les fichiers dont les enregistrements sont de longueur fixe, et IDXFORMAT 3 pour les longueurs variables. Ces formats de fichier sont limités à 4 Go (cf http://supportline.microfocus.com/documentation/books/sx20books/fhlimi.htm#s006)

Solution : Changer le format des fichiers indexés pour passer l'IDXFORMAT à 8, ce qui porte la limite de volume à 128 To ou 8MTo avec FILEPOINTERSIZE=8 (longueur en octets pour stockage des pointeurs)
  • Ajouter dans le fichier $EXTFH le paramètre IDXFORMAT=8
  [XFH-DEFAULT]
  FILEMAXSIZE=8
  IDXFORMAT=8
  • Convertir les fichiers avec la commande rebuild ... (à confirmer : je n'ai pas eu l'occasion de tester)
  rebuild in-file[,out-file] [ -option ...]
  -i[:command]        - rebuild and display information
  -v[:n]              - display running count every n records
  -e                  - continue after duplicate key error
  -q                  - quick rebuild
  -p                  - rebuild format 8 file in place (no backup)
  -n[:command]        - no output - just display file information
  -x:n                - key of reference [out-file only]
  -d                  - rebuild corrupt data file
  -y                  - force rebuild when file size discrepancy reported
  -z                  - specifies server for all files

Ci joint un lien Microfocus à consulter sur le sujet.

Attention : ces fichiers prennent la forme d'un fichier unique (par opposition aux habituels fichiers .idx associés aux fichiers de données). Ceci peut avoir un impact sur des chaines ou des scripts qui prennent en charge ces fichiers ".idx".

28 juin 2010

Message d'erreur "98 RS BNA 9N CG TD11 00000000000818"

Sous DB2 l'erreur SQL 818 signifie qu'il existe un déphasage entre l'exécutable et sa bibliothèque de définition des accès SQL stockée en base. Ce déphasage a plusieurs causes possibles :

Des exécutables ont été copiés à partir d'un autre environnement, mais le bind n'a pas été fait (ou inversement) :

Suite à une livraison imparfaite, exécutable et bind sont déphasés.
Vérifiez que l'horodatage des fichiers ".so" et ".bnd" sont en phase, et cohérents avec ceux de l'environnement source.
Il suffit alors de faire la mise à jour de la bibliothèque de définition des accès SQL ("bind") par prise en compte du fichier *.bnd :

bind RRRRRPPP.bnd collection $HRSCHEMA  datetime iso qualifier $HRSCHEMA

Avec RRRRRPPP radical et code du programme.

La dernière génération s'est terminée en fin anormale :

Il est possible de se trouver dans le cas de figure ou le "bind" a été fait mais la compilation est sortie en erreur. Ce déphasage se résout en corrigeant la source du problème de compilation et en relançant la génération de l'exécutable.

Les chaines de génération physique réalisent dans l'ordre :
  • L'écriture du source Cobol
  • La pré-compilation DB2 du source contenant du SQL (création du *.bnd)
  • Mise à jour de la bibliothèque de définition des accès SQL ("bind" par prise en compte du fichier *.bnd)
  • La compilation du Cobol (fichiers *.so)
  • Le stockage des générés dans $SIGACS/prod (gnt et bnd)
Lorsqu'une étape sort en erreur, le stockage des *.so et *.bnd correspondants n'est pas réalisé.

Observer la correspondance de l'horodatage des fichiers *.bnd et *.so n'est donc pas pertinent.
Mieux vaut comparer l'horodatage du bind (LAST_BIND_TIME de SYSCAT.PACKAGES) avec celui de l'exécutable (TICOMP de PG15).

Une version obsolète de l'exécutable est encore active :


Avec les versions Web de HR Access, les BHR montés en mémoire sont partagés entre les différents utilisateurs de l'application. Un BHR peut ainsi rester plusieurs heures en ligne si l'activité TP est incessante.

Si une génération a lieu entre temps, la nouvelle version des exécutables n'est alors pas prise en compte. Néanmoins, le bind de la nouvelle version des programmes ayant été fait, les BHR actifs utilisent des exécutables BNA, BNK ... déphasés.

Pour limiter cette rémanence des programmes, il convient :
  • De réduire le temps de latence des BHR au minimum (working time out dans dispatcher.ini ou dispatcher.properties),
  • On s'arrangera pour que les BHR soient spécialisés par processus HR (reuse_cobol_runtimes à false dans dispatcher.ini ou dispatcher.properties),
  • En dernier recours on éliminera les processus unix BHR obsolètes (kill).

Exemple : un processus BHR a démarré à 11h21 mais certains programmes ont été regénérés à 11h52.

hrppr@hra:/hraccess5/hrppr/txt/log> ps -ef | grep BHR
hrppr     6604 22369  1 11:21 ?        00:00:14 /hraccess5/hrppr/bin/RTSDGN TYBXBHR WZ005BNM0000000000000001 192.168.64.11 58282 logdir=/hraccess5/hrppr/openhr/logs,trace=true,debug=true,chrono=false,client=*
hrppr@hra:/hraccess5/hrppr/prod/gnt> ltt
-rwxrwxr-x  1 hrppr v5ppr  402219 jun 28 11:52 WZ005BNA.so
-rwxrwxr-x  1 hrppr v5ppr  402219 jun 28 11:53 WZ005BJA.so
-rwxrwxr-x  1 hrppr v5ppr  402219 jun 28 11:53 WZ005BNK.so
-rwxrwxr-x  1 hrppr v5ppr  402219 jun 28 11:54 WZ005BNL.so

21 avril 2010

Récupérer l'heure systeme dans un traitement Cobol

Pour récupérer et afficher l’horodatage système dans un Cobol (heures, minutes, secondes, centièmes), déclarez une variable de 8 caractères et utilisez la commande "ACCEPT ... FROM TIME" :

Working :

       01         DIGIX-TIME.                  
         05         DIGIX-TIMEH PIC 9(2).     
         05         DIGIX-TIMEM PIC 9(2).     
         05         DIGIX-TIMES PIC 9(2).      
         05         DIGIX-TIMEC PIC 9(2).

Procedure :

  ACCEPT DIGIX-TIME FROM TIME.
  DISPLAY DIGIX-TIME.

13 mai 2007

Passer par un tableau Cobol indexé permet de limiter les accès SQL.
Utilisez ensuite des SEARCH pour être plus performant.

Exemple :

01 CountryTable.
   02 Country OCCURS 243 TIMES INDEXED BY Cidx.
      03 CountryCode    PIC XX.
      03 CountryName    PIC X(26).
...
          SET Cidx TO 1
          SEARCH Country
             AT END MOVE "Code not found" TO CountryNameSF
             WHEN CountryCode(Cidx) = CountryCodeWF
                  MOVE CountryName(Cidx) TO CountryNameSF
          END-SEARCH
...

Exemple complet sur http://www.csis.ul.ie/

Remarques :
  • Initialisez le tableau ligne à ligne avec un COB INITIALYZE,
  • Le remplir d'occurrences triées.

22 mai 2002

ProCobol Oracle - Utilisation d'une séquence dans un traitement HR Access

Cet exemple de traitement HR Access utilise une séquence Oracle pour attribuer un NUDOSS unique.

Les séquences sont plus fiables que tout mécanisme applicatif pour ce qui est d'éviter les affectations de NUDOSS en double (saisie TP importante, Mises à jours batch de reprise en parallèle).

Exemple de séquence

Création sous SQL :
SQL> create sequence HR.MYSEQUENCE start with 1 increment by 1 maxvalue 9 minvalue 1 cache 2 cycle order;
SQL> select mysequence.nextval from dual;
         1


Explicitation des options :
  • cycle : pour revenir automatiquement à MINVALUE si MAXVALUE est atteint,
  • cache : nombre d'identifiants conservés en mémoire par Oracle (minimum 2),
  • order : obtenir que les identifiants soient fournis obligatoirement dans l'ordre,

Les pseudocolonnes CURRVAL et NEXTVAL pemettent d'obtenir l'identifiant en cours ou le suivant :

SQL> select mysequence.currval from dual;
         1
SQL> select mysequence.nextval from dual;
         2
...
SQL> select mysequence.nextval from dual;
         8
SQL> select mysequence.nextval from dual;
         9
SQL> select mysequence.nextval from dual;
         1


Destruction :
SQL> drop sequence HR.MYSEQUENCE;

Création de la séquence NUDOSS pour ZO

SQL> create sequence HR.NEW_NUDOSS_FOR_ZO start with 1 increment by 1 maxvalue 999999999 minvalue 1 cache 2 cycle order;

Création du traitement BNK contexte TBP051

Ce contexte de BNK est dédié à l'attribution de NUDOSS.

 Contexte de Variables TBW003 du traitement XY-ZONUDO

 ---------------------------------------- Variables AA --------------
010    *    HOST-VARIABLES
020    *    --------------
030    *    <DEBSEC>SO
040      01 H-MYNBDOSS             PICTURE 9(02).
050      01 H-MYNUDOSS             PICTURE 9(09).
060    *    <FINSEC>SO
070      01 U-MYNUDOSS-FOUND       PICTURE 9(01).


Contexte de Procédures TBP033 du traitement XY-ZONUDO

 ---------------------------------------------------- Fonction BB -------------
010    N   AFFECTATION NUDOSS ZO            10 BL
020    *
030    *   UTILISATION DE LA SEQUENCE
040    *   HR.NEW_NUDOSS_FOR_ZO
045    *   ET LECTURE DE ZO00
050    M   ZERO U-MYNUDOSS-FOUND
 ---------------------------------------------------- Fonction BF -------------
010    N   BOUCLE DE REHERCHE NUDOSS LIBRE  20 DW U-MYNUDOSS-FOUND = ZERO
020    *
030    *   SELECT NEXTVAL -----------------
040    *   <DEBSUB>RDTCOM
050    EXQ SELECT
060        %1.NEW_NUDOSS_FOR_ZO.NEXTVAL
070        INTO           :H-MYNUDOSS
080        FROM DUAL
090    *   <FINSUB>
092    COB DISPLAY "<DIGIX> Lecture Nextval "
094        "(" SQLCODE ") = " H-MYNUDOSS
100    ERR 0000015SQLCODE                   99 IT SQLCODE NOT= ZERO
110    GT  10
120    *   CTRL NUDOSS LIBRE -------------- 99 BL
130    *   <DEBSUB>RDTCOM
140    EXQ SELECT
150        COUNT(*) INTO  :H-MYNBDOSS
160        FROM %1.ZO00
170        WHERE NUDOSS = :H-MYNUDOSS
180    *   <FINSUB>
190    COB DISPLAY "<DIGIX> Lecture NbDoss "
200        "(" SQLCODE ") = " H-MYNBDOSS
210    *   ERREUR TECHNIQUE --------------- 99 IT SQLCODE NOT= ZERO
220    ERR 0000025SQLCODE                      AN SQLCODE NOT= W-WP00-NOTFND
230    GT  10
231    *   NUDOSS N'EST PAS LIBRE --------- 99 IT H-MYNBDOSS NOT= ZERO
232    COB DISPLAY "<DIGIX> Retour"
233    GB  20
243    *   NUDOSS LIBRE ------------------- 99 EL
253    COB DISPLAY "<DIGIX> Fin"
263    M   1              U-MYNUDOSS-FOUND
273    M   H-MYNUDOSS     UT-NUDOCR



Rattachement du traitement a FP800 et regénération.

Tests

Test de création de dossier.

traces STTS_FP800BNM :
<DIGIX> Lecture Nextval (+0000000000) = 000000001
<DIGIX> Lecture NbDoss (+0000000000) = 00
<DIGIX> Fin


Select en base :
SQL> select * from zotd11 where timjdo > '2002-05-22-00.00.00';

    NUDOSS T TIVERR              TIMJDO              VAC CDS
---------- - ------------------- ------------------- --- ---
         1 0 0001-01-01-00.00.00 2002-05-22-11.39.44 NJP DG3



Reinitialisation de la séquence (par DROP et CREATE) et nouveau test.

traces STTS_FP800BNM :
<DIGIX> Lecture Nextval (+0000000000) = 000000001
<DIGIX> Lecture NbDoss (+0000000000) = 01
<DIGIX> Retour
<DIGIX> Lecture Nextval (+0000000000) = 000000002
<DIGIX> Lecture NbDoss (+0000000000) = 00
<DIGIX> Fin


Select en base :
SQL> select * from zotd11 where timjdo > '2002-05-22-00.00.00';

    NUDOSS T TIVERR              TIMJDO              VAC CDS
---------- - ------------------- ------------------- --- ---
         1 0 0001-01-01-00.00.00 2002-05-22-11.39.44 NJP DG3
         2 0 0001-01-01-00.00.00 2002-05-22-11.48.13 NJP DG4


Le traitement a bien vu que le NUDOSS 1 était déjà attribué et a affecté 2 au nouveau dossier.

17 mai 2002

Executer un PL/SQL dans un traitement Cobol HR

Ci joint un test d'exécution d'un PL/SQL Oracle se connectant a une base distante dans un traitement HR Access (d'un point de vue architectural, un traitement de ce genre est à proscrire car on génère un "lien fort" entre les deux applications : si l'application distante est indisponible, le traitement local est bloqué).

Prérequis pour la connexion à la base distante : le listener Oracle doit être démarré et paramétré pour les bases source et cible.

Création d'un database link vers la base éloignée

Sur la base locale, la base éloignée ayant le code "DIST",

create database link BASE_DIST connect to  HR identified by ** using 'DIST';

Test de select sur la table PP10 éloignée à partir de la base locale :
select * from PP10@BASE_DIST where CDPCOM='1';


Création du package sur la base distante

Exemple : insertion de la date système dans une table spécifique

drop table MY_TABLE
/
create table MY_TABLE (MYDATE DATE)
/
drop package MY_PACKAGE
/
create package MY_PACKAGE as
procedure UPDT_DATE;
end MY_PACKAGE;
/
create package body MY_PACKAGE as
procedure UPDT_DATE is
BEGIN
      insert into MY_TABLE values (SYSDATE);
END UPDT_DATE;
end MY_PACKAGE;
/


Test d’exécution du package a partir de la base éloignée :

SQL> begin my_package.updt_date@BASE_DIST;
  2  end;
  3  /
PL/SQL procedure successfully completed.

SQL> select sysdate from dual;
2002-05-17-14.34.18
SQL> select * from my_table@BASE_DIST;
2002-05-17-14.34.04
 

Exemple de traitement HR Access

En cas de création de dossier, on exécute la procédure stockée UPDT_DATE sur la base distante et on récupère la plus grande date dans la table distante MY_TABLE.

Working :
 Contexte de Variables TBW002 du traitement TT-TPSORA
 ---------------------------------------- Variables BB --------------
010    *    HOST-VARIABLES
020    *    --------------
030    *    <DEBSEC>SO
040      01  H-MYDATE PIC X(19).
050    *    <FINSEC>SO


Procedure :
 Contexte de Procédures TBP012 du traitement TT-TPSORA
 ---------------------------------------------------- Fonction BB -------------
010    N   EXECUTION D'UNE PROCEDURE STOCKE 10 BL
020    *   SUR UNE BASE DE DONNEES DISTANTE
030    *
040    *   PREREQUIS :
050    *   - DATABASE LINK BASE_DIST
060    *   - PACKAGE   MY_PACKAGE SUR DIST
070    *   - PROCEDURE UPDT_DATE  SUR DIST
075    COB DISPLAY "<DIGIX> ENTER TTTPSORA"
080    EXQ EXECUTE
085        BEGIN
090        MY_PACKAGE.UPDT_DATE@BASE_DIST;
100        END;
110    ERR 0000015SQLCODE                   99 IT SQLCODE NOT = ZERO
115    COB DISPLAY "<DIGIX> SQLCDE1 " SQLCODE
120    GT  10
130    EXQ SELECT                           99 BL
140        MYDATE INTO :H-MYDATE
150        FROM   MY_TABLE@BASE_DIST
160    ERR 0000025SQLCODE                   99 IT SQLCODE NOT = ZERO
162    COB DISPLAY "<DIGIX> SQLCDE2 " SQLCODE
164    GT  10
170    COB DISPLAY "<DIGIX> " H-MYDATE      99 EL


Incident a la compilation :
Les options de précompilation doivent intégrer une spécificité PL/SQL

Error at line 15886, column 24 in file FP800BNA.pco
000010     EXEC SQL    EXECUTE                                          TBP012
.......................1
PCB-S-00008, Must use option SQLCHECK=SEMANTICS(FULL) when there is embedded PL/SQL


Si l'option sqlcheck=semantics est ajoutée (fichier config, item PROFLAGS), la compilation du source affiche des warning volumineux avec un code retour bloquant :

/oracle/8.1.5/bin/procob    select_error=yes MODE=ANSI sqlcheck=SEMANTICS iname=FP800BNA.pco oname=FP800BNA.cbl

Pro*COBOL: Release 8.1.5.0.0 - Production on Fri May 17 16:26:39 2002
(c) Copyright 1999 Oracle Corporation.  All rights reserved.

System default option values taken from: /oracle/8.1.5/precomp/admin/pcbcfg.cfg

Error at line 6766, column 13 in file FP800BNA.pco
000001      EXEC SQL DECLARE CZOTD12 CURSOR FOR                         MACSYS
............1
PCB-S-00576, PLS-201: identifier 'ZOTD12' must be declared
Error at line 6766, column 13 in file FP800BNA.pco
000001      EXEC SQL DECLARE CZOTD12 CURSOR FOR                         MACSYS
............1

etc...

Il faut ajouter une seconde option userid=HR/** (fichier config, item PROFLAGS) pour permettre au précompilateur de vérifier l'existence des objets dans le dictionnaire Oracle.

En conséquence, on placera dans le fichier $SIGACS/adm/cfg/config :
PROFLAGS=select_error=yes MODE=ANSI sqlcheck=SEMANTICS userid=HR/**

Ces modifications faites, la compilation cobol se termine bien.

---
---    FP800BNA.pco  -->  FP800BNA.so
---
/oracle/8.1.5/bin/procob                                                 select_error=yes MODE=ANSI sqlcheck=SEMANTICS userid=HR/HR iname=FP800BNA.pco oname=FP800BNA.cbl

Pro*COBOL: Release 8.1.5.0.0 - Production on Fri May 17 16:59:12 2002

(c) Copyright 1999 Oracle Corporation.  All rights reserved.

System default option values taken from: /oracle/8.1.5/precomp/admin/pcbcfg.cfg

cob -C nolist -vz -C ASSIGN=EXTERNAL -C SEQUENTIAL=LINE -C IBMCOMP -C SIGN=EBCDIC -C WRITELOCK -C NOTRUNC -C NOBOUND -C PERFORM-TYPE=MF -C COPYLIST -C NORESEQ -U FP800BNA.cbl
* Micro Focus Server Express         V1.1 revision 000 Compiler
* Copyright (C) 1984-2000 MERANT International URN HXCAI/AA0/00000G

...
* Accepted - NORESEQ
* Compiling FP800BNA.cbl
* Total Messages:     0
* Data:       81196     Code:      160818
* Server Express V1.1.0 Code generator
* Copyright (C) 1984-2000 MERANT International Ltd. All rights reserved.
* Accepted - verbose
* Generating FP800BNA
* Data:       81728     Code:      264232     Literals:       13512.


A noter :
  • L'ajout de l'option userid fait que le user/password de connexion Oracle et présent dans le fichier $SIGACS/adm/cfg/config, et dans tous les compte rendus de précompilation...
  • L'ajout de l'option spellcheck=semantics impose que les tables soient créées (par RBH, RBF) avant la génération physique des programmes (par RBG, RBA).

L'executable fonctionne.
On trouve dans les traces après exécution :

<DIGIX> ENTER TTTPSORA
<DIGIX> 2002-05-17-16.23.00

SQL> select * from MY_TABLE@BASE_DIST;  
2002-05-17-16.23.00

16 avril 2002

ProCobol Oracle - Programmes volumineux - make : the return code from the last command is 11

Christophe m'indique que chez son client, un problème bloquait la pré-compilation Cobol de Oracle d'un gros programme BLK : le procob sortait en erreur suite à une opération en mémoire, et générait un généreux fichier 'core' (version Oracle  8.1.6 patchée).

make : the signal code from the last command is 11

La hot-line Oracle lui a conseillée de passer l'option ltype=none (option PROFLAGS dans le fichier $SIGACS/adm/cfg/config).

Cette option évite l'étape de génération du fichier ".lis" intermédiaire entre le .pco et le .cbl, et effectivement, une fois cette option modifiée, le programme se compile entièrement.