#!/bin/bash #------------------- CHECKPOINT --------------------------- # # exemple de programme "trop long" qui utilise la fonctionnalité # "checkpoint" d'OAR, suivi de reprise(s) automatique(s) # (fonctionnalité idempotent) ... jusqu' à la fin du programme # commande: oarsub -S ./checkpoint-user1.oar # Cet exemple est arrêté 2 fois ( 3 jobs consécutifs pour finir) # # IMPORTANT: # Ce script OAR capte bien le signal de checkpoint envoyé par # OAR, envoit un signal (à adapter éventuellement) au programme de # de l'utilisateur, MAIS c'est LE PROGRAMME de l'utilisateur qui # doit capter et interpréter ce signal ... afin de sauver le # "contexte" de son execution de sorte qu'au remédérrage # automatique ( - t idempotent ), il ne reprenne pas du début # ( sinon il y a une boucle infinie !) # # Le programme associé à ce script est un simple compteur # ( 1 incrémentation / secondes ) en C. # - son excécution dur 10 mn # - ce script OAR, pour l'exemple, ne prévoit que 5mn (trop court!) # - le script OAR reçoit (d'OAR) le signal checkpoint 12. # Il renvoit le signal 2 (SIGINT) au programme timer # - À réception de ce dernier (interruption) le timer sauve # aussitôt son contexte (le n° d'itération) dans un fichier local. # - timer10mn est arrêté mais est relancé par OAR # #-------------- paramètres OAR--------------------------- #OAR -l cpu=1/core=1,walltime=00:5:00 #OAR -n start_and_restart # Les fichiers de sortie sans paramètres $OAR_JOBID # (=> les jobs successifs écrivent dans les mêmes fichiers) #OAR -O OAR-ckpt-user1.out #OAR -E OAR-ckpt-user1.err #OAR -q default #IMPORTANT: # - par NFS: a priori pas de problème # - sur SCRATCH : il faut reprendre sur la même machine # par exemple : #OAR -p network_address = 'orval08' ## besteffort est optionnel #OAR -t besteffort ## idempotent ne l'est pas #OAR -t idempotent # checkpoint 60 s avant le walltime: pour un exemple # réel ( plusieurs heures, gros contexte, 600 (10mn)) #OAR --checkpoint 60 # signal envoyé par OAR (SIGUSR2) #OAR --signal 12 #---------- la tâche à exécuter ------------------------ # compilation ( peut être commenté si déjà compilé) gcc compteur10mn.c -o timer10mn # Note (compteur10mn.c): gère son propre checkpoint (SIGINT) #----------- pré-traitement ----------------------------- # DWTFYW ! echo "Debut du job ${OAR_JOB_ID}" #----------- lancement de la tâche ---------------------- ./timer10mn & #--------------------------------------------------------- # gestion de signaux #--------------------------------------------------------- # Warning: c'est le script OAR qui reçoit le signal 12! # => il faut le capter et le transmettre au PROG #################################################### # pid du programme = pid de la dernière commande (: ./timer10mn) PID=$! # signal Unix attendu par OAR (defaut = SIGUSR1/10, forcé ici # à 12 par le paramètre --signal 12 (cf. param OAR au début) CHKPNT_SIGNAL=12 # valeur de sortie pour l'option "--idempotent" # (restart automatique) ) EXIT_UNFINISHED=99 # si le script OAR reçoit le SIGUSR2 (signal 12), checkpoint! # Rq tentative d'envoyer le même signal au prog: ne fonctione pas!? # SIGUSR2 = 12 kill rééllement le programme : # => pas de checkpoint # => boucle infinie! # Du coup: # SIGINT = 2 = "CRTL + C" fonctionne trap "echo commande trap (script OAR); kill -s 2 $PID ; exit $EXIT_UNFINISHED" $CHKPNT_SIGNAL # # obliger le script OAR à attendre l'exécution du PROG # (sinon il s'exécute jusqu'au bout et ne récupérera # jamais le signal checkpoint !) wait $PID #--------------------------------------------------------- # fin du programme: postraitement #--------------------------------------------------------- # DWTFYW! echo " ---post treatement---" echo " ...suppression du fichier temporaire context_compteur.txt" rm -f context_compteur.txt echo " c'est FINI ! " # => idempotent devrait entraîner un redémarrage auto. exit $?