Security-X

Forum Security-X => Système d'Exploitation => Linux => Discussion démarrée par: Tawal le février 15, 2016, 19:43:10

Titre: [Résolu][cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le février 15, 2016, 19:43:10
Bonsoir,


Tout d'abord, un peu de documentation au sujet de cron et anacron :


Mon problème est simple :
   Empêcher l'arrêt du système (ou retarder) pendant l'exécution des scripts de cron.daily, cron.weekly et cron.monthly.
   Ou reprendre l'exécution des scripts à partir de celui qui n'a pas été terminé ou exécuté (à cause de l'arrêt du système).

Pourquoi j'ai ce problème :
   Car j'ai remarqué que le temps d'exécution des scripts du dossier cron.daily est de plus de 1/2 heure.
   Durant ce laps de temps, il peut arriver que j'éteigne le PC avant la fin de l'exécution de TOUS les scripts.

La "presque solution" de supprimer le script /etc/cron.daily/0anacron ne me convient guère.
En effet, cela permet de relancer les scripts jusqu'à ce que ceux-là soient tous exécutés et finis; mais les 1ers scripts exécutés avant l'arrêt sont re-exécutés au redémarrage.

Merci de vos réponses :AAN
Titre: Re : [cron][anacron]Cron.daily vs Arrêt du système
Posté par: igor51 le février 15, 2016, 21:51:19
J'ai une solution bien moche mais que je vais soumettre (juste par principe de me faire insulter)

- Je vais admettre que tu as plusieurs scripts (mais ça marche avec un seul)

- Lorsque ton premier script se lance, il va aller s'inscrire dans /etc/rc.local
  - S'il finit, il se supprimer du fichier /etc/rc.local
  - S'il ne finit pas, il sera exécuté au démarrage, dans ce cas, suffit de bien le coder pour reprendre où il en était (ou recommencer à 0 si ça ne dérange pas). Une fois qu'il a fini, il se supprime de /etc/rc.local

Et on recommence pour les scripts suivants. Ainsi, plus de problème de reboot :)
Titre: Re : [cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le février 15, 2016, 23:38:54
Holà, loin de moi de t'insulter car coté mocheté je te bats à plate couture.
Mais bon, je pense que tu ne pensais pas à moi  ::)  ;D



Merci déjà de m'orienter vers le script /etc/rc.local.
L'idée de le rendre dynamique pourquoi pas.

Pour dégrossir, on va faire 2 hypothèses :
   - plusieurs scripts à exécuter les uns après les autres
   - aucune importance qu'un script non-fini soit re-exécuté (même si je me pose la question pour le logrotate )

Je pense qu'il faut un script dans le dossier /etc/cron.daily (et les autres) qui inscrive la liste des scripts de ce dossier (sauf lui même et 0anacron) et placé juste après le script 0anacron.
Je m'explique par l'exemple :
   Partons d'un 1er démarrage du jour (donc avec un rc.local "vierge"). Anacron lance les scripts du dossier /etc/cron.daily.
   Si un arrêt survient avant la fin de l'exécution de tous les scripts, il faut que les derniers scripts (restant à exécuter) soient déjà inscrits dans rc.local
   D'où l'inscription de tous les scripts dès le départ.
   Ensuite, ton idée que chaque script (une fois fini) se désinscrive du rc.local est "bonne" (les guillemets pour ceux qui te jugent  :hi:).

Mais je me pose une question, cette manipulation survit-elle aux mises à jour ? (car il faut éditer chaque script même ceux installés automatiquement)

Voici la liste des scripts présents dans mon /etc/cron.daily :$ ls -1 /etc/cron.daily
0anacron
apache2
apt
aptitude
bsdmainutils
dpkg
exim4-base
l0SargCron
logrotate
man-db
mlocate
passwd
rkhunter

C'est faisable mais à approfondir, je pense.

Merci :AAN
Titre: Re : [cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le février 22, 2016, 18:58:45
Plop,

Je reviens exposer la solution que j'ai appliqué.
Et non ! Ce n'est pas celle que proposait igor51  :EEE

Commençons par la documentation (qui donnera une idée de ma solution) :


Comme l'indique la doc, je me suis dirigé vers un script de démarrage/arrêt du système (/etc/init.d) pour gérer le problème.

En effet, plutôt que faire ce qui n'a pas été fait; autant le terminer !  :NNN

Le script intervient en tout premier lieu à l'arrêt du système.
Et il teste l'exécution d'anacron, cron.daily, cron.weekly etc ...
Une fois l'exécution finie, il laisse la main et permet ainsi la poursuite de l'arrêt.

Voilà le script en question :
Code: (run-parts-wait) [Sélectionner]
#!/bin/bash

### BEGIN INIT INFO
# Provides:          run-parts-wait
# Required-Start:    $null
# Required-Stop:     $all
# Default-Start:     2
# Default-Stop:      0 6
# X-Interactive:     true
# Short-Description: Contrôle l'exécution d'anacron et de run-parts.
# Description:       Attend la fin de l'exécution de :
#                               anacron
#                               run-parts --report /etc/cron.hourly
#                               run-parts --report /etc/cron.daily
#                               run-parts --report /etc/cron.weekly
#                               run-parts --report /etc/cron.monthly
### END INIT INFO

. /lib/lsb/init-functions

case "$1" in
start)
log_begin_msg "Run-Parts-Wait activé"
log_end_msg $? ;;
stop)
log_begin_msg "Attente de fin d'Anacron"
a="1";b="1";c="1";d="1";e="1"
while [ ! -z "$a" ] || [ ! -z "$b" ] || [ ! -z "$c" ] || [ ! -z "$d" ] || [ ! -z "$e" ]; do
a=`ps ax | grep anacron | grep -v grep`
b=`ps ax | grep "run-parts --report /etc/cron.hourly" | grep -v grep`
c=`ps ax | grep "run-parts --report /etc/cron.daily" | grep -v grep`
d=`ps ax | grep "run-parts --report /etc/cron.weekly" | grep -v grep`
e=`ps ax | grep "run-parts --report /etc/cron.monthly" | grep -v grep`
sleep 1
done
log_end_msg $? ;;
esac

exit 0
et la commande (en root) pour "l'insérer" dans les phases de démarrage/arrêt :# update-rc.d run-parts-wait start 99 2 . stop 00 0 6 .


Voilà, ça marche.
Je teste et anacron et les run-parts car les scripts des dossiers /etc/cron.daily, /etc/cron.weekly ... sont appelés soit par anacron (cas de l'arrêt/démarrage de la machine) soit par cron (cas d'une machine non-éteinte sur plusieurs jours/semaines/mois).

L'effet du script :
   Si anacron (ou run-parts) tourne et que je demande l'arrêt/redémarrage de la machine, je me retrouve sur l'écran de login de gdm3.
   Normal étant donné que le script est le premier a se lancer, gdm3 et TOUS les autres services sont en cours d'exécution.
   Ça ne me dérange pas et me laisse une certaine liberté d'action.
   Je pense qu'en enlevant la ligne "# X-Interactive:     true" du script, on ne devrait plus avoir accès au gdm. Je n'ai pas testé.

Merci en tous cas igor51, tu m'as bien fait gratter en me proposant "ta mocheté".
(mocheté qui embellissait la mienne car je pensais faire un marqueur d'exécution finie pour chaque script pour ensuite exécuter les scripts n'ayant pas de marqueur :AAG mince j'ai avoué :oups:)

'fin, j'ai pas dit que c'était plus beau ce que j'avais fait. Mais ça résiste aux mises à jour  ;)
Et je suis tout ouïe pour les critiques (et même les insultes :NNN)

Merci encore de l'aide :AAN
   
Titre: Re : [cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le février 28, 2016, 23:40:51
Plop,

Je reviens encore :NNN car j'ai opté pour une autre solution car la précédente pose problème.

Toujours la doc : RunLevel (https://wiki.debian.org/fr/RunLevel)



En effet, certaines commandes des scripts du dossier /etc/cron.daily nécessitent d'être en runlevel 2.
Or le script LSB se lance en runlevel 0 ou 6 et le logrotate me donne ce genre d'erreurs :
Citer
/etc/cron.daily/logrotate:
invoke-rc.d: -----------------------------------------------------
invoke-rc.d: WARNING: 'invoke-rc.d cups force-reload' called
invoke-rc.d: during shutdown sequence.
invoke-rc.d: enabling safe mode: initscript policy layer disabled
invoke-rc.d: -----------------------------------------------------
invoke-rc.d: -----------------------------------------------------
invoke-rc.d: WARNING: 'invoke-rc.d rsyslog rotate' called
invoke-rc.d: during shutdown sequence.
invoke-rc.d: enabling safe mode: initscript policy layer disabled
invoke-rc.d: -----------------------------------------------------



Ma solution est de lancer quasiment le même script, mais avant la fermeture de session.
Pour ce faire, j'ai placé mon script dans le fichier /etc/gdm3/PostSession/Default

Voici mon nouveau fichier /etc/gdm3/PostSession/Default : #!/bin/bash

a="1";b="1";c="1";d="1";e="1";z="";ok=""
while [ ! -z "$a" ] || [ ! -z "$b" ] || [ ! -z "$c" ] || [ ! -z "$d" ] || [ ! -z "$e" ]; do
[ -z "$a" ] || a=`ps ax | grep anacron | grep -v grep`
[ -z "$b" ] || b=`ps ax | grep "run-parts --report /etc/cron.hourly" | grep -v grep`
[ -z "$c" ] || c=`ps ax | grep "run-parts --report /etc/cron.daily" | grep -v grep`
[ -z "$d" ] || d=`ps ax | grep "run-parts --report /etc/cron.weekly" | grep -v grep`
[ -z "$e" ] || e=`ps ax | grep "run-parts --report /etc/cron.monthly" | grep -v grep`
[ -z "$z" ] && z=`pgrep zenity`
[ -z "$a" ] && [ -z "$b" ] && [ -z "$c" ] && [ -z "$d" ] && [ -z "$e" ] || [ ! -z "$z" ] || { zenity --info --width 380 --height 160 --title "" --text "<span font-family=\"webdings\"><span color=\"red\"><b><big><u> Run-Parts-Wait </u></big></b></span></span>             \n\n\n\t<span font-family=\"arial\"><span color=\"blue\"><b>En cours ...</b></span></span>" & ok="1"; }
sleep 1
done
z=`pgrep zenity`
[ -z "$z" ] || killall zenity
[ -z "$ok" ] || zenity --info --width 380 --height 160 --title "" --text "<span font-family=\"webdings\"><span color=\"red\"><b><big><u> Run-Parts-Wait </u></big></b></span></span>             \n\n\n\t<span font-family=\"arial\"><span color=\"blue\"><b>Fini.</b></span></span>" --timeout 3

exit 0

Ainsi, j'ai une fenêtre Zenity si Anacron est en cours de d'exécution.
Et surtout plus de soucis de runlevel.

Voilà, si ça peut aider ...
Titre: Re : [Résolu][cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le mars 02, 2016, 18:31:19
Encore plop :NNN

Désolé pour les multiples posts, mais je préfère le partage ...



Tiens ! pas de doc, cette fois  ;D

En fait, le script /etc/gdm3/PostSession/Default fonctionne très bien lors d'une demande de fermeture de session.
Mais lors d'une demande d'arrêt/redémarrage, le scripts se lance bien aussi mais ne résiste pas au signal de clôture et donc se fait "killer" avant d'être fini.

En attendant de trouver comment le faire résister à ce signal, je suis revenu à la solution précédente (script d'init). [ d'ailleurs si quelqu'un a un idée ... ]

J'ai recherché les commandes provoquant les erreurs. En voici une provenant du fichier /etc/logrotate.d/cups : invoke-rc.d --quiet cups force-reload > /dev/nullOn voit que la sortie standard de cette commande est redirigée vers /dev/null (ça la rend muette en quelque sorte).
Alors j'ai tout simplement redirigé les erreurs de cette commande vers /dev/null et la commande devient : invoke-rc.d --quiet cups force-reload 2>&1 /dev/nullL'erreur est toujours là mais plus signalée (absente des logs et plus de mail système).
L'erreur en soit n'est pas importante car cette commande (même cas pour le fichier rsyslog) sert à arrêter et redémarrer le service après la rotation des ses logs.
Et moi je veux éteindre ou redémarrer donc pas grave.



Merci de m'avoir lu.  :AAC
Titre: Re : [Résolu][cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le mars 04, 2016, 19:56:30
Encore moi !   :AAG

Une autre solution : #!/bin/bash

### BEGIN INIT INFO
# Provides:          run-parts-wait
# Required-Start:    $null
# Required-Stop:     $all
# Default-Start:     2
# Default-Stop:      0 6
# X-Interactive:     true
# Short-Description: Contrôle l'exécution d'anacron et de run-parts.
# Description:       Attend la fin de l'exécution de :
#                               anacron
#                               run-parts --report /etc/cron.hourly
#                               run-parts --report /etc/cron.daily
#                               run-parts --report /etc/cron.weekly
#                               run-parts --report /etc/cron.monthly
### END INIT INFO

. /lib/lsb/init-functions

h="h"
m="min"
case "$1" in
start)
[ -e /var/spool/run-parts-wait ] && rm  /var/spool/run-parts-wait
log_action_msg "run-parts-wait : Actif" ;;
stop)
[ ! -e /var/spool/run-parts-wait ] && {
export DISPLAY=:0
d=`date "+%k$h%M$m"`
log_action_msg "run-parts-wait : Début à $d"
rnlvl=$(runlevel|awk '{print $2}')
echo $$ > /var/spool/run-parts-wait
telinit 3
a="1";b="1";c="1";d="1";e="1";f="1"
while [ ! -z "$a" ] || [ ! -z "$b" ] || [ ! -z "$c" ] || [ ! -z "$d" ] || [ ! -z "$e" ]; do
[ -z "$a" ] || a=`ps ax | grep anacron | grep -v grep`
[ -z "$b" ] || b=`ps ax | grep "run-parts --report /etc/cron.hourly" | grep -v grep`
[ -z "$c" ] || c=`ps ax | grep "run-parts --report /etc/cron.daily" | grep -v grep`
[ -z "$d" ] || d=`ps ax | grep "run-parts --report /etc/cron.weekly" | grep -v grep`
[ -z "$e" ] || e=`ps ax | grep "run-parts --report /etc/cron.monthly" | grep -v grep`
sleep 1
z=$(pgrep zenity)
[ -z "$z" ] && [ -z "$f" ] && zenity --info --width 1200 --height 800 --title "" --text "<span font-family=\"webdings\"><span color=\"blue\"><big><b><u> Run Parts Wait </u></b></big></span></span>\t\t\t\t\t\t\t\t\t\t\t\n\n\n<span font-family=\"arial\"><span color=\"black\"><b><i>Attente de fin d'Anacron ...</i></b></span></span>" &
f=""
done
telinit $rnlvl
} || { d=`date "+%k$h%M$m"`; log_action_msg "run-parts-wait : Fin à $d"; } ;;
esac

exit 0
Toujours un script LSB.
L'astuce (ou la mocheté  ::)) :
      - Je récupère la demande de runlevel (0=arrêt 6=redémarrage) : rnlvl=$(runlevel|awk '{print $2}')
      - Je passe en runlevel 3 (avec un /etc/rc3.d vide) : telinit 3
      - La détection et l'attente de fin d'Anacron s'exécute
      - Et je repasse en runlevel demandé : telinit $rnlvl
      - Le script LSB se relance forcément mais est "skippé" via la création du fichier /var/spool/run-parts-wait et sa détection (il est supprimé au démarrage).

Et voilà, j'ai aussi rajouté une fenêtre Zenity pour différencier le gdm de démarrage et celui ou on attend anacron.



@igor51 : Alors qui gagne en mocheté ? :NNN
Titre: Re : [Résolu][cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le mars 05, 2016, 13:32:49
Ah oui moche et avec des erreurs !  :AAG

C'est mieux déjà là :
#!/bin/bash

### BEGIN INIT INFO
# Provides:          run-parts-wait
# Required-Start:    $null
# Required-Stop:     $all
# Default-Start:     2
# Default-Stop:      0 6
# X-Interactive:     true
# Short-Description: Contrôle l'exécution d'anacron et de run-parts.
# Description:       Attend la fin de l'exécution de :
#                               anacron
#                               run-parts --report /etc/cron.hourly
#                               run-parts --report /etc/cron.daily
#                               run-parts --report /etc/cron.weekly
#                               run-parts --report /etc/cron.monthly
### END INIT INFO

. /lib/lsb/init-functions

h="h"
m="min"
case "$1" in
start)
log_action_msg "run-parts-wait : Actif"
;;
stop)
a=`ps ax | grep anacron | grep -v grep`
b=`ps ax | grep "run-parts --report /etc/cron.hourly" | grep -v grep`
c=`ps ax | grep "run-parts --report /etc/cron.daily" | grep -v grep`
d=`ps ax | grep "run-parts --report /etc/cron.weekly" | grep -v grep`
e=`ps ax | grep "run-parts --report /etc/cron.monthly" | grep -v grep`
z=""
[ -z "$a" ] && [ -z "$b" ] && [ -z "$c" ] && [ -z "$d" ] && [ -z "$e" ] && { log_begin_msg "run-parts-wait : OK"; log_end_msg $?; } || {
heure=`date "+%k$h%M$m"`
log_action_msg "run-parts-wait : Début à $heure"
rnlvl=$(runlevel|awk '{print $2}')
telinit 3
export DISPLAY=:0
while [ ! -z "$a" ] || [ ! -z "$b" ] || [ ! -z "$c" ] || [ ! -z "$d" ] || [ ! -z "$e" ]; do
[ -z "$a" ] || a=`ps ax | grep anacron | grep -v grep`
[ -z "$b" ] || b=`ps ax | grep "run-parts --report /etc/cron.hourly" | grep -v grep`
[ -z "$c" ] || c=`ps ax | grep "run-parts --report /etc/cron.daily" | grep -v grep`
[ -z "$d" ] || d=`ps ax | grep "run-parts --report /etc/cron.weekly" | grep -v grep`
[ -z "$e" ] || e=`ps ax | grep "run-parts --report /etc/cron.monthly" | grep -v grep`
sleep 1
[ -z "$z" ] && zenity --info --width 1200 --height 800 --title "" --text "<span font-family=\"webdings\"><span color=\"blue\"><big><b><u> Run Parts Wait </u></b></big></span></span>\t\t\t\t\t\t\t\t\t\t\t\n\n\n<span font-family=\"arial\"><span color=\"black\"><b><i>Attente de fin d'Anacron ...</i></b></span></span>" & z=$?
done
telinit $rnlvl
heure=`date "+%k$h%M$m"`
log_action_msg "run-parts-wait : Fin à $heure"; }
;;
esac

exit 0
Le cas "start" est facultatif.
Plus de telinit 3 ... telinit $rnlvl inutile (si pas d'anacron ou autres).
Plus d'écriture disque.
Et plus d'erreurs, je crois :NNN
Titre: Re : [Résolu][cron][anacron]Cron.daily vs Arrêt du système
Posté par: igor51 le mars 05, 2016, 13:49:52
Salut,

il faut que je relise tout pour te faire une réponse sur la qualité ;)

Alors, je ne suis pas allé vérifier, donc p-e que cela ne s'applique pour toi. Mais dans la pratique, on ne vérifie pas qu'un service tourne en utilisant PS, c'est moche ;)

On va utiliser (suivant ton système)

service nom_service status
systemctl status nom_service
Titre: Re : [Résolu][cron][anacron]Cron.daily vs Arrêt du système
Posté par: Tawal le mars 05, 2016, 14:24:09
Hello,

Citer
donc p-e que cela ne s'applique pour toi.
En effet, anacron n'est pas un démon, il est appelé par cron (qui lui est un démon).
ancron est bien un service sauf que le cas "status" est :  status)
    exit 4
    ;;

:AAN

Edit : # service anacron status
# echo $?
4
#