Linux : résoudre le problème de double mise en veille

J’ai récemment mis à jour mon système Salix OS de la version 14.1 vers la version 14.2. Il s’agit de la troisième mise à jour que je fais et cela se passe toujours sans gros problème, si ce n’est que je dois, à chaque fois, renouveler la procédure d’installation du pilote pour le Wifi.

Cependant, il arrive de temps en temps des petites surprises, en particulier avec la gestion des boutons liés à l’énergie.

Il y d’abord la fermeture de l’écran de mon ordinateur portable pour laquelle je souhaite qu’une hibernation (appelée aussi « mise en veille prolongée » dans Microsoft Windows, ou suspend-to-disk) soit effectuée.

Et il y a ensuite la mise en veille (appelée aussi suspend-to-ram) que je souhaite déclencher lors de l’appui de la touche Lune de mon ordinateur (Fn + F1).

Pour faire tout cela, sous Slackware (pour rappel, Salix OS utilise Slackware comme base), cela se passe dans le fichier de script shell /etc/acpi/acpi_handler.sh :
#!/bin/sh
# Default acpi script that takes an entry for all actions

IFS=${IFS}/
set $@

case « $1″ in
  button)
    case « $2″ in
      power) /sbin/init 0
         ;;
      *) logger « ACPI action $2 is not defined »
         ;;
    esac
    ;;
  *)
    logger « ACPI group $1 / action $2 is not defined »
    ;;
esac

Pour déclencher l’hibernation, j’avais simplement ajouté la branche suivante dans le case :
     lid) pm-hibernate
         ;;

« lid » (qui veut dire en anglais « couvercle ») correspond au bouton (plutôt virtuel dans le cas mon ordinateur) lié à la manipulation de l’écran d’un ordinateur portable. Je l’ai donc associé à la commande pm-hibernate, qui s’occupe de mettre l’ordinateur dans l’état d’hibernation de manière correcte.

Et pour déclencher une mise en veille, j’avais simplement ajouté la branche suivante :
     sleep) pm-suspend
         ;;

« sleep » correspond à la touche Lune de mon ordinateur. Je l’ai donc associé à la commande pm-suspend, qui s’occupe de mettre l’ordinateur dans l’état de veille.

Tout cela fonctionnait plutôt bien jusqu’à une première mise à jour, suite à laquelle il est apparu que le retour d’hibernation déclenchait automatiquement une nouvelle hibernation.

L’astuce que j’avais trouvée à l’époque était d’appliquer un contrôle sur l’état effectif du bouton lid :
     lid) grep -q closed /proc/acpi/button/lid/*/state && pm-hibernate

Suite à ma récente mise à jour vers Salix OS 14.2, un problème similaire est apparu avec la mise en veille déclenchée par la touche Lune. Suite au retour de veille, une deuxième mise en veille était effectuée immédiatement.

Lors de ma recherche d’une solution sur le Web, j’ai découvert, via cet article, l’existence de l’outil acpi_listen. Cet outil permet de voir les événements ACPI exacts déclenchés. Il suffit de le lancer puis de déclencher les boutons/touches :
# acpi_listen
button/lid LID close
button/lid LID open
button/sleep SBTN 00000080 00000000
button/sleep PNP0C0E:00 00000080 00000008

Ici, le résultat montre que la fermeture et l’ouverture de l’écran déclenchent deux événements. Il montre aussi que l’appui de la touche Lune déclenche deux événements.

Il m’est donc apparu clairement qu’utiliser les deux premiers composants de l’événement ACPI ($1 et $2 dans le fichier acpi_handler.sh) n’était pas suffisant. J’ai donc adapté le script de la façon suivante :
      lid) test $4 = « close » && pm-hibernate
         ;;
      sleep) test $3 = « SBTN » && pm-suspend
         ;;

Cela a réglé le problème… jusqu’à la prochaine mise à jour en tout cas. Car les composants supplémentaires ($3 et $4 dans le script) sont-ils suffisamment stables pour être utilisés ? Qui me dit que leurs valeurs ne changera pas lors d’une prochaine mise à jour ? L’avenir nous le dira…

Ci-dessous, le script complet du fichier /etc/acpi/acpi_handler.sh, après modification :
#!/bin/sh
# Default acpi script that takes an entry for all actions

IFS=${IFS}/
set $@

case « $1″ in
  button)
    case « $2″ in
      power) /sbin/init 0
         ;;
      lid) test $4 = « close » && pm-hibernate
         ;;
      sleep) test $3 = « SBTN » && pm-suspend
         ;;
      *) logger « ACPI action $2 is not defined »
         ;;
    esac
    ;;
  *)
    logger « ACPI group $1 / action $2 is not defined »
    ;;
esac

Mots-clefs : , , , ,

2 Réponses à “Linux : résoudre le problème de double mise en veille”

  1. Lyes dit :

    Salut Julien,
    Je te remercie pour tes posts qui sont utiles.

    Je me permet de t’écrire pour te signaler une supposée incoherence dans ton fichier « acpi_handler.sh »

    Les événements capturés sont du groupe « button », donc passée en argument $1
    chaque bouton de ce groupe seront donc passée en argument $2 au lieu de $3 et $4

    Le plus cohérent, à mon avis, c’est:
    ===================================
    case « $1″ in
    button)
    case « $2″ in
    power) /sbin/init 0
    ;;
    lid) test $2 = « close » && pm-hibernate
    ;;
    sleep) test $2 = « SBTN » && pm-suspend
    ;;
    *) logger « ACPI action $2 is not defined »
    ;;
    esac
    ;;
    ==================================

    qu’en penses-tu ?

    Bien à toi

    Lyes

  2. julien1001 dit :

    Bonjour Lyes,

    Je n’utilise plus ce script, ayant passé à une autre distribution.

    Cependant, je ne crois pas que mon script soit incohérent. Chaque ligne retournée par acpi_listen est de la forme :
    /

    SBTN est donc accessible avec $3, et close est accessible avec $4.

    Je crois que ta proposition ne peut pas fonctionner. Ton script suppose que $2 aurait à la fois la valeur sleep et la valeur close, ou bien à la fois la valeur sleep et la valeur SBTN, ce qui est impossible.

    Cordialement,

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>