/dev/random

Debian su Eee900 (parte 3)

Il sistema è installato e funziona. Iniziamo a personalizzarlo.

Dopo aver configurato tutto l'harwdare nella puntata precedente, in questa puntata vediamo come attivare e soprattutto personalizzare la sospensione e l'ibernazione.

In realtà, avendo installato il pacchetto eeepc-acpi-scripts e uswsusp, ed avendo una partizione di swap già attiva, la sospensione dovrebbe già funzionare, ma a me il comportamento di default non piace molto, quindi mi sono messo a studiare cosa succede effettivamente durante queste fasi. Purtroppo alcune parti mi sono ancora oscure, e non sono riuscito ad ottimizzarle, ma qualcosa di nuovo l'ho imparato.

Mi devo scusare per il ritardo di questo articolo, ma mentre stavo per pubblicarlo sono stati aggiornati il kernel, gli script eeepc-acpi-scripts e anche gnome. Sono stato costretto a rivedere tutta la configurazione. Il lato buono è che ora è un po' più preciso e dettagliato.

Configurazione di base

Innanzitutto avremo bisogno di una partizione di swap, visto che l'ibernazione (non la sospensione) ne ha bisogno.

Se ne avete creata una durante l'installazione, potete usare quella, altrimenti uswsusp supporta anche gli swapfile, quindi possiamo crearne uno con due semplici comandi (attenti a non sbagliare a scrivere qualcosa, qui si inizia a rischiare ;) ). Date, da root:

dd if=/dev/zero of=/home/.swapfile bs=1M count=512
mkswap /home/.swapfile

In questo modo abbiamo creato un file nascosto (notate il punto davanti a swapfile) di 512 MB, posizionato nella partizione con le home, e l'abbiamo trasformato in un file di swap.

Ora la scelta sta a voi. La strada più facile è di utilizzare sempre questo file come swap, con il vantaggio che avrete 512 MB di memoria (virtuale) disponibile in più, ma con due svantaggi:

  1. State usando una flash memory per la swap, che non è molto bello, perché aumenta notevolmente il numero di scritture
  2. Se andate ad occupare la swap perché finite la RAM, l'ibernazione non funzionerà più, perché non ha spazio dove salvare l'immagine della RAM.

Usare sempre la swap

Se volete comunque procedere, almeno limitate al minimo l'uso della swap, editando il file /etc/sysctl.conf (sempre da root, come tutto quello che faremo oggi tranne la config di gnome) e scrivendoci una riga come questa:

vm.swappiness = 0

In questo modo il sistema userà la swap solo se veramente necessario. Infine aggiungete la swap in /etc/fstab per attivarla automaticamente ad ogni riavvio:

/home/.swapfile       none            swap    sw              0       0

Naturalmente questa riga va inserita DOPO la riga che monta la partizione /home (se avete scelto di partizionare come vi ho detto nelle puntate precedenti).

Usare la swap solo per l'ibernazione

Io ho preferito attivare la swap solo quando iberno il notebook, e disattivarla quando lo risveglio, in modo da evitare il più possibile gli svantaggi che ho elencato sopra.

Il pacchetto eeepc-acpi-scripts dipende già da pm-utils, che raccomanda uswsusp. Installateli entrambi, mal che vada vi dirà che sono già aggiornati:

aptitude install pm-utils uswsusp

Ora avrete una nuova directory di configurazione, /etc/pm, che contiene varie sottodirectory. Quella che interessa a noi è sleep.d. Creiamo qui dentro il file 00swap:

/etc/pm/sleep.d/00swap
#!/bin/sh
case $1 in
        suspend|hibernate)
                mkswap /dev/sdb2
                swapon /dev/sdb2
        ;;

        resume|thaw)
                swapoff /dev/sdb2
        ;;
esac

Io ho usato una partizione, ma se avete creato lo swapfile come ho detto sopra, sostituite /dev/sdb2 con /home/.swapfile in entrambe le righe dopo hibernate e in quella dopo thaw.

La riga mkswap serve a ripulire la swap da eventuali immagini salvate in precedenza, in modo da evitare errori durante l'ibernazione.

Ho dovuto impostare la swap sia per hibernate che per suspend, perché pm-utils, quando si usa lo script pm-suspend-hybrid (che sospende e iberna, come vedremo dopo) richiama le opzioni per suspend/resume, e non quelle per hibernate/thaw. Non dovrebbero esserci controindicazioni, a parte un leggero rallentamento (qualche decimo di secondo) durante il suspend “puro”, e il fatto che si perde l'immagine dell'ultimo hibernate quando si va in suspend puro, ma non dovrebbe mai servirvi, a meno che non stiate facendo cose molto brutte.

I nomi vengono passati automaticamente dalle pm-utils quando parte l'azione corrispondente, quindi manteneteli così (suspend, hibernate, resume, thaw).

Basta solo questo file, in quanto gli script qui dentro vengono richiamati in ordine alfabetico durante la sospensione, e in ordine inverso durante il risveglio. Usando 00 all'inizio del nome del file, siamo sicuri che venga eseguito per primo al suspend e per ultimo al resume.

Uswsusp funziona in modo un po' particolare. Appena parte l'ibernazione cerca di mettere in swap tutto il possibile, poi comprime la RAM e la salva sul resto della swap. Questo provoca uno strano effetto al resume: dopoche riappare la vostra schermata, la SSD “frulla” per un po', a causa dello swapoff che riporta tutto il contenuto della swap in RAM per poi disattivare la swap. Il sistema rimane comunque usabile, e l'operazione non dura più di qualche secondo.

Ora editate il file /etc/pm/config.d/default. Il mio è così:

SLEEP_MODE="uswsusp"
SUSPEND_MODULES="snd_hda_intel,snd_pcm,snd,snd_page_alloc,ath_rate_sample,ath_pci,wlan,ath_hal"

Questo dice a pm-utils di usare uswsusp come metodo di sospensione, e di provare a rimuovere dal kernel i moduli elencati prima di sospendere o ibernare.

I moduli elencati qui davano problemi con linux-image-2.6.25-1-686, ma almeno il modulo audio sembra non abbia più bisogno di essere rimosso con la nuova linux-image-2.6.25-2-686 (versione 2.6.25-6. Ogni tanto Debian mi perplime...). Sto pensando di mettere qui anche il modulo per la ethernet (atl2), perché, anche se solo una volta, mi ha piantato l'Eee dopo il resume con il cavo ethernet collegato. Dovrò fare altri esperimenti.

Ricordatevi anche di rigenerare la configurazione di uswsusp e l'initrd:

swapon /dev/sdb2
dpkg-reconfigure uswsusp
swapoff /dev/sdb2

Bisogna attivare la swap prima di configurarlo, in modo che la trovi da solo, senza doverla specificare a mano. Naturalmente se avete scelto di mantenere la swap sempre attiva, i due passi non servono, e basta il dpkg-reconfigure.

E rispondete alle varie domande che vi fa. Selezionate la compressione della RAM, altrimenti il thaw sarà lentissimo. Non ho notato differenze sostanzial, invece, tra l'avere scritture preventive o non averle. Alle altre domande normalmente basta premere Invio.

Al termine della configurazione viene rigenerato l'initrd, quindi dovete riavviare per renderlo attivo.

ATTENZIONE!

Questa operazione (dpkg-reconfigure) va fatta solo la prima volta, o se cambiate la partizione o il file di swap. NON va fatta se cambiate semplici configurazioni negli script di suspend/resume o in quelli di ACPI. Quindi praticamente la farete una volta sola, a meno che non usiate un file di swap e vogliate cancellarlo e ricrearlo periodicamente per evitare danni alla SSD, ma a meno che non mandiate in ibernazione il vostro Eee ogni 5 secondi, non dovreste averne bisogno. Con 3 ibernazioni al giorno la SSD dovrebbe durarvi qualche centinaio di anni.

Provare la configurazione

Se avete appena riconfigurato uswsusp con dpkg-reconfigure, ricordate di riavviare, poi potete provare le varie procedure di sospensione e ibernazione coi i comandi:

pm-suspend
pm-hibernate
pm-suspend-hybrid

Il primo sospende in RAM, il secondo iberna su disco, il terzo fa entrambe le cose. Per risvegliare l'Eee basta premere il pulsante di accensione. Non tenetelo premuto per troppo tempo (4 secondi), altrimenti l'effetto sarà quello di spegnerlo in modo brusco, che comporta anche l'invalidazione del BootBooster (non preoccupatevi, si riattiva da solo al successivo reboot) e, naturalmente, un tempo di boot più lungo, in quanto viene eseguito anche il controllo sui dischi.

Personalizzare tutto

Come ho detto, non mi piacevano i default scelti dal team Debian per l'ibernazione. Ho quindi configurato tutto in modo che:

  • chiudendo il coperchio si attiva il suspend2ram premendo il tasto di accensione/spegnimento si
  • attiva il suspend2disk premendo Fn-F1 si attivano entrambi: lo stato viene salvato su disco ma
  • il sistema entra in suspend2ram. In questo modo il resume è immediato, e se si scarica la
  • batteria comunque si riprende a lavorare senza perdere dati, caricando l'immagine da disco

Vediamo come fare. Il tutto viene controllato dagli script in /etc/acpi. Alcuni li ho dovuti creare io, altri li ho solo modificati. Eccoli qui:

/etc/acpi/events/lid
event=button/lid LID
action=/etc/acpi/actions/mysuspend.sh
/etc/acpi/events/powerbtn
# /etc/acpi/events/powerbtn
# This is called when the user presses the power button and calls
# /etc/acpi/powerbtn.sh for further processing.

# Optionally you can specify the placeholder %e. It will pass
# through the whole kernel event message to the program you've
# specified.

# We need to react on "button power.*" and "button/power.*" because
# of kernel changes.

event=button[ /]power
action=/etc/acpi/actions/myhibernate.sh
/etc/acpi/events/sleep
event=button/sleep SLPB
action=/etc/acpi/actions/myhibernatesuspend.sh

Questi sono i file di configurazione che determinano quale script viene eseguito quando un certo evento ACPI viene attivato. Ho usato nomi diversi da quelli di eeepc-acpi-scripts per le azioni, in modo che non vengano sovrascritti dopo un aggiornamento. Naturalmente verrebbe chiesta conferma, ma è più comodo verificare i cambiamenti e modificare i propri script.

Di seguito gli script veri e propri che vengono richiamati, presenti in /etc/acpi/actions:

/etc/acpi/actions/mysuspend.sh
#!/bin/sh

# do nothing if package is removed
[ -d /usr/share/doc/eeepc-acpi-scripts ] || exit 0

if (runlevel | grep -q [06]) || (pidof '/sbin/shutdown' > /dev/null); then
    exit 0
fi

brn_control=/sys/class/backlight/eeepc/brightness
[ -e $brn_control ] || brn_control=/proc/acpi/asus/brn # pre-2.6.26

brightness=$(cat $brn_control)
pm-suspend --quirk-s3-bios
echo $brightness > $brn_control

Viene verificato che non sia in corso un halt o un reboot (controllando il runlevel o se sta venendo eseguito il comando shutdown), quindi inizia la sospensione tramite “pm-suspend”. Prima del suspend viene salvata la luminosità dello schermo, e ripristinata dopo il resume.

/etc/acpi/actions/myhibernate.sh
#!/bin/sh
# do nothing if package is removed
[ -d /usr/share/doc/eeepc-acpi-scripts ] || exit 0

if (runlevel | grep -q [06]) || (pidof '/sbin/shutdown' > /dev/null); then
    exit 0
fi

brn_control=/proc/acpi/asus/brn

brightness=$(cat $brn_control)
/etc/acpi/actions/wireless.sh off
pm-hibernate
echo $brightness > $brn_control

Lo script è molto simile al precedente, ma ho aggiunto l'opzione per disattivare il wireless, senza riattivarlo al risveglio, contando sul fatto che se sto ibernando il PC, difficilmente quando lo risveglio mi troverò nello stesso posto ed anzi, potrei essere in aereo...

In ogni caso basterà premere Fn-F2 per riattivare il wireless dopo il risveglio.

Vediamo ora come sospendere e ibernare contemporaneamente:

/etc/acpi/actions/myhibernatesuspend.sh
#!/bin/sh

# do nothing if package is removed
[ -d /usr/share/doc/eeepc-acpi-scripts ] || exit 0

if (runlevel | grep -q [06]) || (pidof '/sbin/shutdown' > /dev/null); then
    exit 0
fi

brn_control=/proc/acpi/asus/brn

brightness=$(cat $brn_control)
pm-suspend-hybrid --quirk-s3-bios
echo $brightness > $brn_control

Lo script è praticamente identico a quello di sospensione, cambia solo il comando eseguito: pm-suspend-hybrid invece del semplice pm-suspend.

Quando avete fatto, riavviate acpid:

/etc/init.d/acpid restart

per ricaricare le impostazioni.

Quel ficcanaso di Gnome

Gnome ha la “brutta” abitudine di prendere il controllo di tutto il sistema di risparmio energetico appena attivate il demone gnome-power-manager. Il problema è che per avere l'indicazione dello stato della batteria sul panel, dovete per forza attivarlo. Non ho ancora capito quali script vada a richiamare per la sospensione, ma quel che è certo è che ignora quelli che abbiamo appena impostato, e gestisce da solo tutto.

Vediamo come disattivare questo comportamento.

Aprite l'editor di configurazione (menu Gnome->Strumenti di sistema->Editor della configurazione) e andate alla voce /apps/gnome-power-manager/actions. A destra avrete diversi flag di configurazione. Io li ho impostati così:

critical_battery           hibernate
critical_ups               shutdown
event_when_closed_battery  v (attivo)
low_ups                    nothing
sleep_type_ac              nothing
sleep_type_battery         nothing

Mentre a /apps/gnome-power-manager/buttons ho questi:

hibernate               nothing
lid_ac                  nothing
lid_battery             nothing
power                   nothing
suspend                 nothing

In questo modo disabilitiamo la gestione dei tasti per Gnome, abilitando la nostra, che funziona anche se usate altri Desktop o Window Manager.

Io ho impostato anche alcuni valori in /apps/gnome-power-manager/backlight:

battery_reduce             v (attivo)
brightness_ac              70
brightness_battery         20
dpms_method_ac             default
dpms_method_battery        default
enable                     v (attivo)
idle_brightness            0
idle_dim_ac                v (attivo)
idle_dim_battery           v (attivo)
idle_dim_time              30

Così la luminosità sarà del 70% con l'alimentazione attiva, e del 20 a batteria, ma potete comunque regolarla con i soliti Fn-F3 e Fn-F4. Quando non usate l'Eee per 30 secondi, se siete “a batteria” la luminosità scende a 0, per risparmiare energia.

Se volete potete sperimentare con gli altri parametri di gnome-power-manager, visto che la gran parte di quelli configurabili qui non sono disponibili dall'interfaccia di configurazione, che è eccessivamente semplificata, secondo me.

Prestazioni

Le prestazioni in fase di suspend, resume sono eccellenti. In pochi secondi (3 o 4) il sistema va in sospensione e si risveglia. In fase di thaw (il risveglio dopo l'hibernate) sono ottime. Dall'avvio del kernel da parte di GRUB al desktop pronto com'era prima passano circa 10-15 secondi.

Il problema, che non ho trovato come risolvere, riguarda l'ibernazione, che impiega circa 30 secondi. Il sistema sembra non fare nulla per quasi 20 secondi, mentre scrive “Snapshotting system”, e poi in meno di 5 secondi scrive l'immagine compressa della RAM su disco. Forse sta comprimendo la RAM. Devo scoprire se c'è modo di fargli usare un algoritmo più leggero.

Conclusioni

Mi pare di non aver scordato nulla, anche se le modifiche da fare sono abbastanza numerose.

Una cosa che non ho preso in considerazione, ma che sarà una bella rogna, è la gestione di periferiche rimovibili. Se mandate in sospensione l'Eee con una penna USB o una SD inserite, quindi le staccate e poi risvegliat, succedono cose molto brutte. Purtroppo non c'è un modo sicuro per sistemare tutto, perché un'applicazione potrebbe avere un file aperto sulla penna, e un umount prima della sospensione non andrebbe a buon fine. Ricordatevi quindi di smontare i device rimovibili prima di sospendere o di non toglierli dopo aver sospeso (o almeno di ricollegarli prima di risvegliarlo).

Nella prossima puntata parlerò delle mie personalizzazioni di Gnome: scorciatoie da tastiera, panel, applet, ecc.