> Tech > IBMi, Extraire facilement les références de programmes

IBMi, Extraire facilement les références de programmes

Tech - Par System iNews - Publié le 21 mars 2013
email

Toutes les réponses aux questions des administrateurs d'environnements IBM i.

IBMi, Extraire facilement les références de programmes

Au sommaire de cette édition :

– Extraire facilement les références de programmes
– Trouver toutes les instances d’un nom de colonne
– Charger des volumes de bandes virtuels dans un catalogue d’images
– Améliorer la performance du serveur HTTP
– Bonne syntaxe ‘Not Equal’
– Commande QSH pour copier des enregistrements dans le fichier Testout
– Scruter un grand nombre d’espaces utilisateur

Retrouvez toutes les Boîtes à Outils System iNews.

Extraire facilement les références de programmes

Q. Existe-t-il autre chose que Display File Description (DSPFD) pour extraire des références de programmes ? Actuellement, j’extrais la liste des membres d’une bibliothèque particulière en utilisant *MBRLST, puis en appliquant DSPPGMREF à chaque membre, mais c’est une opération très longue. Y a-t-il un autre moyen d’obtenir les références afin de pouvoir filtrer les données et les utiliser ?

R. La commande Display Program References —DSPPGMREF PGM(*ALL)— est bien plus rapide et facile que d’appeler DSPPGMREF pour chaque membre individuel.  Nous soumettons un DSPPGMREF PGM(*ALL/*ALL) OUTPUT(*OUTFILE) en batch chaque week-end, quand le système est peu sollicité. Ensuite, pour savoir ce qui a été utilisé par chaque programme, nous appliquons simplement une requête SQL au fichier de sortie.

—Scott Klemen

Trouver toutes les instances d’un nom de colonne

Q. À partir d’un nom de colonne, est-il possible sur un IBM i 5.4 de trouver le nom du ou des fichiers où ce nom de colonne est présent ? Dans MySQL, vous pouvez juste interroger (query) INFORMATION_SCHEMA.COLUMNS. Cela ne semble pas marcher en DB2.

R. QSYS2.COLUMNS est une vue de compatibilité ANSI/ISO, ou fichier logique, que vous pouvez interroger pour trouver toutes les instances d’un nom de colonne.

—J. Taylor

Charger des volumes de bandes virtuels dans un catalogue d’images

J’ai créé un fichier de bandes virtuel que j’utilise pour sauvegarder mes bibliothèques de données. Mon idée était la suivante : envoyer par FTP les volumes de bandes virtuels à une unité NAS (network attached storage) Ethernet, puis supprimer le volume virtuel pour libérer de l’espace disque sur mon IBM i. Mais je ne vois pas comment extraire les volumes de bandes virtuels et les recharger dans le catalogue d’images virtuelles. Y a-t-il un secret pour cela ?

R. Avant de restaurer votre image de bande du NAS sur l’IBM i, vous devez d’abord créer une entrée catalogue d’images, en indiquant un nom de volume désiré, par exemple :
ADDIMGCLGE IMGCLG(VIRTTAPE)
FROMFILE(*new)
TOFILE(2009MAR)
IMGSIZ(20000)
VOLNAM(MAR09)
Ensuite vous pouvez envoyer par FTP votre fichier binaire sauvegardé dans le catalogue d’images. Pour utiliser l’image, employez la commande Work With Image Catalogs (WRKIMGCLG). Prenez Action 12 pour travailler avec les entrées, puis Action 11 sur le volume qui vous intéresse. Ce dernier est alors monté et vous pouvez vérifier que la bande virtuelle est bien celle que vous voulez

—Bryan641

Améliorer la performance du serveur HTTP

Q. Nous devons démarrer le serveur HTTP sur l’AS/400 pour un système tiers que nous voulons utiliser. Mais cette opération ralentit l’IFS à un point tel que les utilisateurs ne peuvent pas ouvrir, sauvegarder, etc. des documents. Nos buffers send/receive IP sont réglés sur 65535. Pouvons-nous vérifier d’autres valeurs de configuration ? Nous sommes au niveau 5.4.

R. Par défaut, les jobs système IBM i qui servent les fonctions HTTP et Netserver s’exécutent dans le pool *BASE, pool numéro deux dans l’affichage Work with System Status (WRKSYSSTS). Votre problème de performances est peut-être dû au fait que les jobs HTTP s’exécutent dans des threads multiples et ont besoin d’un « niveau d’activité » supérieur dans le pool *BASE. Si le niveau d’activité est insuffisant, certains jobs ne pourront peut-être pas s’exécuter.

Exécutez  WRKSYSSTS puis augmentez de 100 le paramètre MAX ACTIVE du pool *BASE pour voir si la performance s’améliore. Si l’amélioration est faible, augmentez  MAX ACTIVE de 50 de plus.
Quand vous appuyez sur F11 pour regarder l’écran Job Transition State et que vous appuyez sur F10 toutes les 10 à 15 secondes environ pour rafraîchir l’écran, (n’utilisez pas F5), la colonne « Wait –> Inel » et « Active –> Inel » devrait montrer une valeur très basse ou zéro. Si ce n’est pas le cas, vous devez augmenter MAX ACTIVE afin que davantage de threads soient actifs dans le pool, pour un meilleur temps de réponse.

—Satid Singkorapoom

Bonne syntaxe ‘Not Equal’

Q. Quelle est la bonne syntaxe pour sélectionner « not equal to %VALUES() » dans le paramètre OPNQRYF QRYSLT() ? J’essaye d’utiliser l’opérateur *NE pour “not equal,” mais j’obtiens le message d’erreur : « CPD3129—Missing operand on expression in QRYSLT parameter. An operand was missing for the operator or built-in function <, specified at position 171 in the expression.” (Opérande manquant sur l’expression dans le paramètre QRYSLT. Il manquait un opérande qpour l’opérateur ou la fonction <, spécifié à la position 171 dans l’expression). Et la position 171 est exactement l’endroit où le « *NE » se trouve dans l’expression :
(DPAHACLDAC = %VALUES(« TERMP » « TERM »))
& (DPAHRE1 = %RANGE(« T00 » « T99 »))
& (DPAHEFFCTD = %RANGE(« 2009-01-01 » « 2009-12-31 »))
& (DPAHCMPNY = %VALUES(1000 2000))
& (DPAHRE1 *NE %VALUES(« T51 » « T63 »))

R. Utilisez *NOT au lieu de *NE, par exemple :
QRYSLT( ‘ *NOT (MyField *EQ %VALUES(« A » « B « C »)) ‘ )

—J. Suzuki

Commande QSH pour copier des enregistrements dans le fichier Testout

Q. Je veux copier un fichier .CSV présent dans l’IFS, dans un fichier base de données afin de lire ce dernier avec SQL. Voici ce que je fais :
CRTPF FILE(JADE/TESTOUT) RCDLEN(2000)
STRQSH
CMD(‘tail /TMP/ALI7IC_304463.CSV > /qsys.lib/jade.lib /testout.file/testout.mbr’)
J’ai essayé les deux commandes QSH “Tail” et “Head”. Tail copiera les derniers enregistrements, et Head copiera les premiers. Quelle commande QSH dois-je utiliser pour copier tous les enregistrements dans mon fichier testout ?

R. Utilisez la commande “Cat” au lieu de “Head” ou “Tail”. Cat vient de “caténer,” un synonyme de “concaténer”. Ce faisant, vous concaténez le fichier source à la fin du fichier de sortie vide. Si le fichier existe déjà, vous pouvez concaténer la sortie à la fin de ce fichier en utilisant le symbole  >>, qui signifie “append” (ajouter).

—Dan Devoe et Mel Beckman

Scruter un grand nombre d’espaces utilisateur

Q. Nous avons environ 1200 espaces utilisateur qui contiennent des requêtes créées par un outil de requête tiers. Certaines de ces requêtes utilisent des chemins QDLS, et on m’a demandé de les identifier et de les changer pour utiliser plutôt un répertoire IFS. Comment puis-je rechercher la chaîne « QDLS » dans ces espaces utilisateur ? J’ai essayé l’outil grep dans QShell, mais il ne cherche que 2048 caractères par ligne, et donc il ne trouve pas les chaînes dans ces espaces utilisateur. Pouvez-vous m’aider ?

R. Je vais fournir le code d’un utilitaire QShell (écrit en RPG) qui peut rechercher une chaîne dans un espace utilisateur ou dans un fichier stream IFS. Je vous montrerai aussi comment QShell peut l’appeler et fournir les noms des espaces utilisateur à explorer.

Ma solution rudimentaire consiste à écrire mon propre utilitaire Qshell, lequel pourra trouver les noms de fichiers à ma place. S’il ne s’agissait pas d’un programme ponctuel, je choisirais probablement quelque chose de plus performant.

En substance, vous pouvez appeler n’importe quel objet *PGM à partir de QShell (à condition qu’il n’utilise pas un fichier d’affichage). Pour mon exemple, j’écris un programme nommé FINDQDLS. Donc, pourvu qu’il se trouve dans la bibliothèque MYLIB, je peux l’appeler à partir de QShell comme ceci :

  > /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM

Cela exécute mon programme FINDQDLS, sans passer de paramètres, à partir de QShell.
Supposons maintenant que je veuille l’exécuter plusieurs fois, une fois pour chaque fichier qui obéit au modèle *.txt dans un répertoire IFS donné. Je pourrais faire ceci à partir de Qshell :

> for f in *.txt; do /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM « $f »; done

Ici, j’ai dit à QShell que, pour chaque fichier conforme au modèle « *.txt, » je veux qu’il exécute MYLIB/FINDQDLS et qu’il passe le nom de fichier comme paramètre. S’il y a 200 fichiers dans mon répertoire IFS qui se terminent par *.txt, il appellera mon programme FINDQDLS 200 fois, en passant chaque fois un nom de fichier différent comme paramètre.

Dans l’IFS, un objet *USRSPC peut être utilisé exactement de la même manière qu’un fichier stream. Donc, si je veux appeler mon programme mais aussi que QShell passe le nom du chemin IFS à tous les espaces utilisateur dans la bibliothèque USRSPCLIB, je peux faire ceci :

> for f in /QSYS.LIB/USRSPCLIB.LIB/*.USRSPC; do /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM « $f »; done

Remarque : en utilisant les noms de chemin /QSYS.LIB pour accéder au système name library/object file, j’obtiens d’étranges résultats dans QShell si je ne tape pas les noms entièrement en majuscules. Par conséquent, avec des objets natifs, il faut taper les noms de chemins en majuscules.

L’exemple précédent appelle MYLIB/FINDQDLS une fois pour chaque espace utilisateur dans la bibliothèque USRSPCLIB, en passant chaque fois le nom du chemin IFS à l’espace utilisateur.

Le programme FINDQDLS est celui que j’ai écrit pour rechercher la chaîne « QDLS » dans un  fichier stream ou un objet espace utilisateur. À la fin de cet article, un lien vous indiquera où télécharger le code source. Pour vous aider à comprendre le programme, voici un pseudo-code décrivant son déroulement :

•    Obtenir un nom de chemin à partir du premier paramètre.
•    Ouvrir le le nom du chemin avec l’API IFS open(). Si nécessaire, traduire le texte en  EBCDIC.
•    Utiliser l’API fstat() pour obtenir la taille du fichier que je viens d’ouvrir .
•    Allouer un buffer avec assez de mémoire pour stocker toutes les données du fichier.
•    Lire tout le fichier dans le buffer. 
•    Fermer le fichier IFS maintenant que nous avons une copie des données.
•    Convertir le buffer en majuscules  (pour que la recherche ignore la casse).
•    Explorer le buffer en appelant la procédure ScanMem(). (J’avais déjà cette procédure — elle utilise les API C pour rechercher une certaine chaîne dans un grand segment de mémoire.)
•    Si le fichier est trouvé, imprimer son nom.
•    Libérer la mémoire qui a été allouée. 
•    Terminer le programme.

On l’a vu, il ne traitera que des fichiers d’environ 16Mo ou moins (c’est d’ailleurs la taille maximale d’un espace utilisateur). Mais, avec quelques changements, il pourrait travailler dans un téra-espace pour de plus grands fichiers. Par conséquent, si vous l’exécutez sur un répertoire IFS dans lequel quelques objets STMF dépassent 16Mo, vous risquez d’obtenir des erreurs « Not enough memory for this object » (pas assez de mémoire pour cet objet).

Dès lors que ce programme est dans MYLIB, vous pouvez l’exécuter comme indiqué ci-dessus, et il imprimera la liste des objets contenant la chaîne « QDLS ».

> for f in /QSYS.LIB/USRSPCLIB.LIB/*.USRSPC; do /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM « $f »; done
   /QSYS.LIB/USRSPCLIB.LIB/TESTUSRSPC.USRSPC
   /QSYS.LIB/USRSPCLIB.LIB/ANOTHER.USRSPC
   $

Vous pouvez télécharger le source du programme FINDQDLS à systeminetwork.com/article/scanning-slew-spaces. Défiler simplement jusqu’au bas de la page.

—Scott Klement

Téléchargez cette ressource

Sécuriser votre système d’impression

Sécuriser votre système d’impression

Longtemps sous-estimée, la sécurisation d’un système d’impression d’entreprise doit être pleinement prise en compte afin de limiter le risque de fuite d’informations sensibles. Voici les 3 principales précautions à prendre.

Tech - Par System iNews - Publié le 21 mars 2013