, , Comment repérer les requêtes SQL consommatrices sur votre IBMi

Comment voir à un instant donné , le requêtes les plus consommatrices de votre système ?

Vous êtes sans doute demandé comment connaitre les requêtes SQL qui consomment sur votre système voici une solution.

Nous allons utiliser un dump du plan cache , vous pouvez aussi y accéder par ACS en quelques clics

Voici une méthode qui va vous permettre d’automatiser et de trouver plus rapidement un problème.

Commencer par supprimer le fichier qui va servir à extraire le dump

Drop table gdata.dump_cache ;

Extrayez le cache dump dans votre fichier de travail

CALL QSYS2.DUMP_PLAN_CACHE (fileschema => ‘GDATA’ ,
Filename => ‘DUMP_CACHE’) ;

Exécuter une requête sur ce fichier

Dans notre exemple, on sélectionne les jobs actifs sur le système
on sélectionne les requêtes SELECT
et on trie par consommation descendante !

With job_act (JOB_NAME_SHORT, JOB_USER, JOB_NUMBER, JOB_USER_IDENTITY)
as (SELECT JOB_NAME_SHORT, JOB_USER, JOB_NUMBER,JOB_USER_IDENTITY
FROM TABLE (QSYS2.ACTIVE_JOB_INFO(DETAILED_INFO => ‘ALL’)) X
where substr(job_user_identity, 1, 1) <> ‘Q’
)
Select qqjob, qquser, qvc102, qqjnum, qq1000, qqi6 as temps_execution
from gdata.dump_cache a join job_act b on
QQJOB = JOB_NAME_SHORT and QQUSER = JOB_USER and QQJNUM = JOB_NUMBER
where substr(QQ1000 , 1, 6) = ‘SELECT’
order by qqi6 desc

Vous pouvez changer vos critères de tri et de sélection, ici on est en mode pompier ?
Vous pouvez plannifier cette requête et la faire retourner plusieurs fois par jour sur votre système en gardant le résultat ou les dump cache

Nous avons packagé ce scripte pour faire une commande WRKSQLJOB que vous pouvez trouver ici !

https://github.com/Plberthoin/PLB/tree/master/GTOOLS


Vous retrouvez également une version un peu plus évoluée dans notre produit GODBC
https://www.gaia.fr/produits/

Les sites à connaitre, si vous voulez aller plus loin

https://www.ibm.com/docs/en/i/7.4?topic=services-dump-plan-cache-procedure
https://www.ibm.com/docs/en/i/7.4?topic=cache-creating-snapshots
https://www.ibm.com/docs/api/v1/content/ssw_ibm_i_74/pdf/rzajqpdf.pdf

, , , Renommer votre serveur LDAP Pour EIM

Vous utilisez la solution de single signon sur IBMi à base de kerberos et EIM

Votre serveur LDAP change de nom

Voici la liste des opérations à effectuer

Sur le serveur LDAP, vous n’avez rien à faire

Sur le serveur Kerberos

Vous avez 2 modifications à faire

Changer le nom du KDC sur l’onglet principal

Changer le nom du serveur de mot de passe sur l’onglet Serveur de mot de passe

Sur le serveur EIM

Sur le domaine changer le registre kerberos

Créer un nouveau registre utilisateurs de type source kerberos

et vous devrez ensuite sur chaque inscription remplacer votre source par le nouveau serveur

Ca peut être long si vous n’avez pas d’outils pour le faire

Chez nous notre produit GEIM peut vous aider dans cette tache

Une des nouveautés de TR4 c’est Query Supervisor

L’idée est de limiter les requêtes selon certain critéres (de temps d’éxécution , d’espace temporaire occupé etc… )
Jusqu’à présent c’était pas toujours simple et un peu binaire

Ajout d’un seuil à contrôler

Ce fait par la procédure QSYS2.ADD_QUERY_THRESHOLD

Exemple

CALL QSYS2.ADD_QUERY_THRESHOLD(THRESHOLD_NAME => ‘Seuil’,
THRESHOLD_TYPE => ‘CPU TIME’,
THRESHOLD_VALUE => 1,
INCLUDE_USERS => ‘PLB’,
DETECTION_FREQUENCY => 60)

vous devez indiquer
un nom ici Seuil
le seuil à controler
une valeur pour ce seuil
un filtre d’inclusion ou d’exclusion ici inclusion du profil PLB
Un délai de raffraichissemnt en seconde

Vous avez une vue qui permet de voir les seuils définis sur votre partition

c’est la vue QUERY_SUPERVISOR

exemple

voir tous les seuils définis pour Query supervisor

SELECT *
FROM QSYS2.QUERY_SUPERVISOR ORDER BY THRESHOLD_TYPE, THRESHOLD_VALUE DESC;

;

Vous pouvez indiquer un programme d’exit QIBM_QQQ_QRY_SUPER

ci joint un exemple basic pour expliquer ce qui ce passe

pgm parm(&qrysupdta &returncod)
/* Paramètres */
dcl &qrysupdta *char 1024
dcl &returncod char 8

/* Variables de Travail */

DCL VAR(&SIZ_HEADER) TYPE(CHAR) LEN(4) +
STG(DEFINED) DEFVAR(&qrysupdta 1)

DCL VAR(&FMT_NAME) TYPE(CHAR) LEN(8) +
STG(DEFINED) DEFVAR(&qrysupdta 5)

DCL VAR(&JOB_NAME) TYPE(CHAR) LEN(10) +
STG(DEFINED) DEFVAR(&qrysupdta 13)

DCL VAR(&JOB_USER) TYPE(CHAR) LEN(10) +
STG(DEFINED) DEFVAR(&qrysupdta 23)

DCL VAR(&JOB_NUMBER) TYPE(CHAR) LEN(6) +
STG(DEFINED) DEFVAR(&qrysupdta 33)

DCL VAR(&SUBSYSTEM) TYPE(CHAR) LEN(10) +
STG(DEFINED) DEFVAR(&qrysupdta 39)

DCL VAR(&Usr_name) TYPE(CHAR) LEN(49) +
STG(DEFINED) DEFVAR(&qrysupdta 23)

DCL VAR(&QRYPLANID) TYPE(CHAR) LEN(08) +
STG(DEFINED) DEFVAR(&qrysupdta 67)

DCL VAR(&THR_NAME) TYPE(CHAR) LEN(60) +
STG(*DEFINED) DEFVAR(&qrysupdta 75)
dcl &msg *char 2056
chgvar &msg (&JOB_NAME *cat ‘/’ *cat &JOB_USER *tcat ‘/’ *tcat +
&JOB_NUMBER *bcat ‘Arreté pour dépassement, ‘ *bcat &THR_NAME)
SNDUSRMSG MSG(&MSG)
/* on force l’arret de la requete */
CHGVAR VAR(%BIN(&returncod 1 4)) VALUE(1)
ENDPGM
Pour en savoir plus le lien ici

https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/xqrysuper.htm

Le message ne cas de débordement

Le message remonté depuis notre programme d’exit

Vous pouvez enlever vos seuils

c’est la procédure REMOVE_QUERY_THRESHOLD

CALL QSYS2.REMOVE_QUERY_THRESHOLD(THRESHOLD_NAME => ‘Seuil’);

vous indiquer le nom que vous avez donné à votre seuil

Conclusion

C’est bonne nouveauté pour les administrateurs DB2

On peut regretter l’absence du procédure de change qui permettrait de revenir sur les paramètres de définition

, , Passage SQLSTATE en SQL

Depuis la TR4 de la V7R4, vous pouvez passer votre propre SQLSTATE ce qui est très intéressants sur les triggers avants par exemple.
Vous pouvez avoir la vrai raison du refus
C’est un petit pas pour SQL, mais un grand pas pour le développeur SQL

Exemple

Création de la table

CREATE OR REPLACE TABLE ARTICLE (
NOMART CHAR(30) CCSID 297 NOT NULL DEFAULT  » ,
NUMART DECIMAL(6) ,
DESIGN CHAR(25) CCSID 297 NOT NULL DEFAULT  » ,
PRXUNI DECIMAL(6)
)
Insertion d’un article (Je sais, je surfe sur l’actualité du moment)
INSERT INTO ARTICLE VALUES(‘Maillot Benzema’, 19,
‘Maillot Benzema EDF’, 166)

tentative de mise à jour

UPDATE ARTICLE SET PRXUNI = 167 WHERE NUMART = 19

Création d’un trigger de controle
ici on teste que l’utilisateur est bien ‘DBADMIN’ pour pouvoir modifier le tarif

CREATE OR REPLACE TRIGGER ARTICLETRG
BEFORE UPDATE OF PRXUNI ON ARTICLE
FOR EACH ROW
BEGIN ATOMIC
IF CURRENT USER <> ‘DBADMIN’ THEN
SIGNAL SQLSTATE ‘DB999’
SET MESSAGE_TEXT = ‘UTILISATEUR NON AUTORISÉ’;
END IF;
END;

Par SQL

Maintenant dans un programme RPGLE

On va utiliser get diagnostics pour récupérer le SQLTATES et le Message associé

**free
dcl-s MessageText char(45) ;
dcl-s ReturnedSQLState char(5);
exec sql SET OPTION COMMIT = *NONE ;
// test mise à jour trigger
exec sql
UPDATE ARTICLE SET PRXUNI = 167 WHERE NUMART = 19 ;
exec sql
get diagnostics condition 2
:ReturnedSQLState = RETURNED_SQLSTATE ,
:MessageText = MESSAGE_TEXT;
dsply (ReturnedSQLState + ‘ ‘ + MessageText) ;
*inlr = *on ;

Vous lancer le programme

Conclusion :

c’est une nouveauté qui devrait simplifier le contrôle des triggers est donc leur usage.

, Utiliser SNMP pour superviser votre IBM i.

Sur votre partition SNMP agent est disponible et sa mise en œuvre est très simple
(tout du moins en version snmp1) , Si vous décidez de continuer avec cette solution il est recommandé de passer en SNMP3

SNMP (Simple Network Management Protocol) RFC 1157

C’est un protocole simple qui permet de superviser vos éléments réseaux

https://www.commentcamarche.net/contents/537-le-protocole-snmp

Il y a trois éléments à connaitre (oui je sais 4, je ne parlerai pas ici de la communauté)
L’agent c’est celui qui va collecter les informations à mettre à dispo
La MIB (Management Information Base) c’est la description des informations extraites
Un manager de type console de supervision par exemple CENTREON, ou un logiciel de supervision réseau type ,PRTG (Paessler Router Traffic Grapher), c’est celui qui va interpréter les informations reçues et les consolider

Pour faire la mise en oeuvre

Vous devez démarrer snmp sur votre partition , par navigator for i , ou par STRTCPSVR *SNMP

Dans navigator for i

en 5250

Vous devez avoir ensuite un manager , si vous n’en avez pas déjà un disponible (Centreon par exemple)

par exemple check_mk disponible ici https://checkmk.com , l’installation se fait en NEXT, NEXT

Vous devez ensuite paramétrer votre IBM i

Et voila le résultat, vous avez les principales informations comme la taille disque occupée par exemple

Quelques liens

https://www.ibm.com/support/pages/ibm-i-snmp-overview

https://www.ibm.com/support/pages/configuring-snmpv3-ibm-i

, 5 contrôles rapides par SQL

SQL service vous simplifie l’administration au quotidien, voici quelques contrôles que vous pouvez automatiser pour être proactif

1) Les logiciels en erreurs

SELECT PRODUCT_ID , PRODUCT_OPTION, TEXT_DESCRIPTION, LOAD_ERROR, SYMBOLIC_LOAD_STATE, COMPATIBLE, SUPPORTED
FROM QSYS2.SOFTWARE_PRODUCT_INFO
WHERE LOAD_ERROR = ‘YES’
or SYMBOLIC_LOAD_STATE = ‘DAMAGED’
or (COMPATIBLE = ‘NO’ and SUPPORTED = ‘NO’)

Compatible et supported ne sont pas forcément bloquants

2) Les logiciels qui expirent dans un mois

SELECT ‘Expire dans un mois’ AS STAtUS, PRODUCT_ID , PRODUCT_TEXT FROM QSYS2.LICENSE_INFO
WHERE LICENSE_EXPIRATION between (CURRENT DATE + 1 month) and current date
union
SELECT ‘Expiré’ AS STAtUS, PRODUCT_ID , PRODUCT_TEXT FROM QSYS2.LICENSE_INFO
WHERE LICENSE_EXPIRATION < CURRENT DATE ;

3) Les PTFs en erreur

SELECT PTF_PRODUCT_ID, PTF_IDENTIFIER
FROM QSYS2.PTF_INFO A
WHERE PTF_LOADED_STATUS = ‘DAMAGED’

4) Les certificats qui expirent dans 1 mois

Vous devez connaitre le mot de passe de votre magasin
ensuite il vous faudra le passer à votre requete

le choix ici est d’utiliser une variable globale (attention à sécuriser)

CREATE VARIABLE VOTRBIB/PASSWORD_CERTIF VARCHAR(32);
SET VOTRBIB/PASSWORD_CERTIF = ‘votre mot de passe’;

SELECT ‘Expire avant un mois’ as status, CERTIFICATE_LABEL, VALIDITY_END FROM TABLE(QSYS2/CERTIFICATE_INFO(CERTIFICATE_STORE_PASSWORD=> VOTRBIB/PASSWORD_CERTIF))
WHERE VALIDITY_END between (CURRENT DATE + 1 MONTH) and current date
union
SELECT ‘Expiré’ as status, CERTIFICATE_LABEL, VALIDITY_END FROM TABLE(QSYS2/CERTIFICATE_INFO(CERTIFICATE_STORE_PASSWORD=> VOTRBIB/PASSWORD_CERTIF))
WHERE VALIDITY_END < CURRENT DATE ;

5) Les Problèmes en cours


C’est la liste des incidents ouverts par le système sur vos partitions, il n’y a pas encore de vue SQL , vous devez générer la table

cl: DSPPRB OUTPUT(*OUTFILE) OUTFILE(QTEMP/LSTPRB) ;
SELECT PBID, PBSEV, PBSTAT, PBDESC, PBDATO, PBTIMO FROM lstprb

Il existe bien d’autres contrôles que vous pouvez automatiser et que vous pourrez automatiser, les TR apportant de nouvelles informations à chaque fois !

, Téléchargement d’un fichier en HTTP

Vous voulez télécharger sur votre IBMi un fichier à partir du web.

Le premier reflexe est de passer par les HTTPAPI de Scott Klement, (on ne dira jamais assez ce que Scott a apporté à la plateforme) .

Mais aujourd’hui il y a plus simple grâce à l’open source, vous avez des produits qui permettent de faire ca simplement.

par exemple wget permet de faire cette opération :

Une documentation pour avoir les principales options de cet outil

https://doc.ubuntu-fr.org/wget

Vous avez l’adresse de votre page

vous lancer QP2TERM

wget
Si votre site est en HTTPS sauf si vous avez le certificat sur votre machine vous devrez utiliser l’option –no-check-certificate

exemple :

wget https://www.ibm.com/support/pages/node/1116645/ –no-check-certificate

Remarques

Idéal pour récupérer les produits sous licence, par exemple.

Ca ne marche pas avec QSH
Vous devez avoir accès au site avec le port http ou https ouvert, possibilité de mettre un PROXY

Ci joint
un exemple dans un programme CLLE, une commande RCVHTTPFIL pour vous simplifier la vie.

https://github.com/Plberthoin/PLB/tree/master/GTOOLS/CMD

Une vidéo pour télécharger un produit sur notre chaine youtube


https://www.youtube.com/watch?v=kFZ5_eQVZ5s

et puis un lien pour vous aider dans la mise au point d’un shell

https://www.ibm.com/support/pages/how-trace-qshell

, Tracer les connexions REXEC sur votre IBMi

Le REXEC est un protocole qui a été déclassifié pour des questions de sécurité depuis plusieurs années et qui ne devrait plus être utilisés mais il est possible qu’ils soient encore ouvert chez c’est le port 512
Voici une solution pour connaitre qui se connecte en REXEC sur votre prtition IBM

1) Création d’une table pour la log des tentatives de REXEC

CREATE TABLE GTOOLS/CTLREXEC (REXIP CHAR ( 15) NOT NULL WITH
DEFAULT, REXUSR CHAR ( 10) NOT NULL WITH DEFAULT, REXDAT DATE NOT
NULL WITH DEFAULT, REXTIM TIME NOT NULL WITH DEFAULT)

2) Création d’un Programme CLP

//
/* / / Exemple REXEC Server Logon exit program. / / PGM CTLREXEC / / / /*/

TSTLOGCL: PGM PARM(&APPIDIN &USRIN &USRLENIN &AUTIN &AUTLENIN &IPADDRIN &IPLENIN +
&RETCDOUT &USRPRFOUT &PASSWDOUT &CURLIBOUT)

/* Declare input parameters */

DCL VAR(&APPIDIN) TYPE(CHAR) LEN(4)

/* Application identifier */ /* 1 FTP server program */ /* 2 REXEC server program */

DCL VAR(&USRIN) TYPE(CHAR) LEN(999)

/* User ID */

DCL VAR(&USRLENIN) TYPE(CHAR) LEN(4)

/* Length of user ID */

DCL VAR(&AUTIN) TYPE(CHAR) LEN(999)

/* Authentication string */

DCL VAR(&AUTLENIN) TYPE(CHAR) LEN(4)

/* Length of auth. string */

DCL VAR(&IPADDRIN) TYPE(CHAR) LEN(15)

/* Client IP address */

DCL VAR(&IPLENIN) TYPE(CHAR) LEN(4)

/* IP address length */

DCL VAR(&RETCDOUT) TYPE(CHAR) LEN(4)

/* return code (out) / / 1 OK / / 0 KO */

DCL VAR(&USRPRFOUT) TYPE(CHAR) LEN(10)

/* user profile (out) */

DCL VAR(&PASSWDOUT) TYPE(CHAR) LEN(10)

/* password (out) */

       DCL        VAR(&CURLIBOUT)  TYPE(*CHAR) LEN(10) /* current library (out)   */

/* Declare local copies of parameters (in format usable by CL) */

DCL VAR(&APPID) TYPE(DEC) LEN(1 0)
DCL VAR(&USRLEN) TYPE(DEC) LEN(5 0)

DCL VAR(&AUTLEN) TYPE(DEC) LEN(5 0)
DCL VAR(&IPLEN) TYPE(*DEC) LEN(5 0)
MONMSG CPF0000 exec(goto fin)
addlible gtools
monmsg CPF2103
CHGJOB LOG(4 0 *SECLVL) LOGCLPGM(YES)

/* Assign input parameters to local copies * /

CHGVAR VAR(&APPID) VALUE(%BINARY(&APPIDIN))

CHGVAR VAR(&USRLEN) VALUE(%BINARY(&USRLENIN))

CHGVAR VAR(&AUTLEN) VALUE(%BINARY(&AUTLENIN))

CHGVAR VAR(&IPLEN) VALUE(%BINARY(&IPLENIN))

/* Renvoyer OK */

CHGVAR VAR(%BINARY(&RETCDOUT)) VALUE(1)

/* Loguer les informations */

         RUNSQL     SQL('INSERT INTO CTLREXEC VALUES(''' *TCAT +  
                    %SST(&IPADDRIN 1 &iplen) *TCAT ''', ''' +   
                    *TCAT %SST(&USRIN 1 &USRLEN) *TCAT ''', +   
                    current date, current time)') COMMIT(*NONE) 
         monmsg sql0000 exec(do)
         sndusrmsg  msg(&IPADDRIN *bcat %sst(&USRIN 1 10)) msgtype(*info)
         enddo
         goto       end

fin:
CHGVAR VAR(%BINARY(&RETCDOUT)) VALUE(1)
END: ENDPGM

3) Compiler le programme en adoption de droit par rapport à QSECOFR

4) Associer au programme d’exit QIBM_QTMX_SVR_LOGON

ENDTCPSVR *REXEC

ADDEXITPGM EXITPNT(QIBM_QTMX_SVR_LOGON) +
FORMAT(TCPL0100) PGMNBR(1) +
PGM(gtools/ctlrexec)

STRTCPSVR *REXEC

5) Pour le suivi

select * from gtools/ctlrexec

REXIP REXUSR REXDAT REXTIM
10.10.10.10 GAIA 2021-03-29 21:39:11
10.2.0.8 PLB 2021-03-29 22:06:36
10.2.0.8 PLB 2021-03-30 06:38:02
10.2.0.8 PLB 2021-03-30 06:40:47
10.2.0.8 QSECOFR 2021-03-30 06:42:40

, 5 actions pour remplacer efficacement SNA

Vous le savez SNA ne sera pas éternel , et il vous faudra trouver des solutions pour le remplacer, ces solutions sont en plus souvent plus performantes

Exemple : en remplaçant les fichiers de /qdls par des fichiers de l’ifs natif !

Il y a plusieurs solutions:

Vous pouvez par exemple analyser vos sources, cette méthode pose 2 problèmes.

  • Vous allez analyser de nombreux sources qui ne sont plus utilisés
  • A contrario , vous n’avez pas forcément tous les sources

Voici une méthode plus efficace et facile à mettre en œuvre, elle est basé sur la traçabilité des commandes !

1) Démarrer le contrôle d’audit

Vous devez démarrer l’audit de journal si ce n’est pas encore le cas
la valeur QAUDCTL doit avoir *OBJAUD

2) Démarrer l’analyse des commandes

Le but est de trouvé les traitements qui utilisent les commandes du monde SNA
et ensuite de mettre une solution de remplacement.

Pour avoir une idée précise, vous devez laisser tourner au moins 15 jours …

PGM
/* démarrer l’analyse sur les commandes SNA * /

CHGOBJAUD OBJ(SNDDST) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SAVRSTLIB) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SAVRSTOBJ) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SAVRST) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SAVRSTCHG) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SNDNETF) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SNDNETMSG) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(SNDNETSPLF) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(CPYTOPCD) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(CPYFRMPCD) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(STRPASTHR) OBJTYPE(*CMD) OBJAUD(*ALL)
CHGOBJAUD OBJ(ADDDIRE) OBJTYPE(*CMD) OBJAUD(*ALL)

CHGOBJAUD OBJ(QY2FTML) OBJTYPE(*PGM) OBJAUD(*ALL)


ENDPGM

3) Analyse des commandes

DSPJRN JRN(QAUDJRN) JRNCDE((T)) ENTTYP(CD)

Si voulez avoir un fichier mieux présenté pour les fichiers type CD

CRTDUPOBJ OBJ(QASYCDJ5)
FROMLIB(QSYS)
OBJTYPE(*FILE) TOLIB(GTOOLS) NEWOBJ(ANALYSE) CST(*NO)
TRG(*NO)

puis

DSPJRN JRN(QAUDJRN)
JRNCDE((T))
ENTTYP(CD)
OUTPUT(*OUTFILE) OUTFILFMT(TYPE5)
OUTFILE(GTOOLS/ANALYSE)
OUTMBR(*FIRST *ADD)

4) Arrêt de l’audit

PGM
/* arrêt de l’analyse sur les commandes SNA */

CHGOBJAUD OBJ(SNDDST) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SAVRSTLIB) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SAVRSTOBJ) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SAVRST) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SAVRSTCHG) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SNDNETF) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SNDNETMSG) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(SNDNETSPLF) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(CPYTOPCD) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(CPYFRMPCD) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(STRPASTHR) OBJTYPE(*CMD) OBJAUD(*NONE)
CHGOBJAUD OBJ(ADDDIRE) OBJTYPE(*CMD) OBJAUD(*NONE)

CHGOBJAUD OBJ(QY2FTML) OBJTYPE(*PGM) OBJAUD(*NONE)
ENDPGM

5) Supprimer les commandes incriminées

Les solutions de remplacement

SNDDST par SNDMSG ou SNDSMTPEMM
SAVRSTLIB en V7R4 par un passage en IP ou solution à base de FTP
SAVRSTOBJ  »
SAVRST  »
SAVRSTCHG  »
SNDNETF par SNDSMTPEMM ou solution à base de FTP
SNDNETMSG par SNDMSG ou SNDSMTPEMM
CPYTOPCD par CPYTOSTMSF ou CPYTOIMPF
CPYFRMPCD par CPYFRMSTMF ou CPYFRMIMPF
STRPASTHR par TELNET
ADDDIRE par ADDSMTPLE pour les envois de mail

CALL QY2FTML par FTP ou SAVRSTOBJ en IP

Et les cas particuliers

Vous n’avez pas les sources, par exemple sur un progiciel de production
Il faudra faire preuve de plus d’imagination
par exemple une commande avec le même nom et des paramètres identiques à la commande d’origine placées avant dans la liste de bibliothèque, et qui remplace l’action souhaitée par une action similaire à déterminer !

80 % des problèmes sont sur le SNDDST