Raspberry Pi root filesystem in read only
Raspberry Pi è un piccolo e simpatico dispositivo, un PC completo, con SO Linux dal costo di poche decine di euro. Ideale per imparare Linux e applicazioni varie, anche di una certa importanza, ma con le dovute premesse.
Raspberry ha come dispositivo di boot una scheda SD nella quale, normalmente, si trova anche il file system (FS) root. La scheda SD non è molto affidabile specie per il file system. Numerose operazioni di scrittura ed interruzioni di alimentazione possono portare a corruzione del FS e conseguenti problemi.
Una soluzione è usare la scheda SD solo per il boot e installare il FS su un dispositivo più affidabile come una memoria USB o un disco esterno. In alternativa si può montare il FS di root dalla scheda SD, ma solo in lettura.Qui viene descritta quest'ultima soluzione.
E' utile anche disabilitare tutti i processi che non sono utili alla applicazione implementata e che scrivono sul FS. Fra questi anche lo swap dopo aver verificato che la memoria RAM è sufficiente per i nostri scopo.
Premesso che con Raspberry non è gestito lo switch su SD per la protezione da scrittura, rimane la soluzione di montare il FS di root in sola lettura.
Per il corretto funzionamento del dispositivo occorre garantire la possibilità di scrivere su alcune directory che normalmente fanno parte del FS root, ad esempio /var/log, /tmp /home. Si può ovviare facendo montando un FS o in ram o su una partizione diversa da root. Nella configurazione illustrata in parte si farà uso di un FS in ram, in parte di una partizione sulla stessa SD, confidando nel fatto che la corruzione di una partizione che non contiene root è meno critica e si può, con maggiore semplicità, gestire backup e ripristini.
Nell'esempio si è utilizzato una scheda SD da 32 GB, classe 10, che è stata inizializzata con Raspbian.
Al primo avvio viene eseguita la procedura di configurazione raspi-config.
Non espandere il FS , e configurare le varie opzioni come la password, la selezione della lingua, il nome del dispositivo e l'abilitazione di ssh.
La scheda SD da 32G la partizione di boot è di 56 MB, mentre la root è di 3GB e restano disponibili circa 26 - 27 GB. In relazione alle applicazioni che si installeranno, potrebbe essere necessario ampliare la partizione di root.
Si creano le partizioni su SD per gli usi che necessitano, in particolare per la cartella /home e /tmp. Per la prima partizione riservo 20 GB per la seconda 1 GB.
Per visualizzare le partizioni presenti: fdisk -l
root@weewx-pi:~# fdisk -l
Disk /dev/mmcblk0: 32.1 GB, 32090619904 bytes
4 heads, 16 sectors/track, 979328 cylinders, total 62676992 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0009bf4f
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 6399999 3138560 83 Linux
Il device SD ha nome mmcblk0, mmcblkop1 e mmcblk0p2 sono le partizioni di boot e di root. Per cereare le nuove partizioni fdisk /dev/mmcblk0
fdisk /dev/mmcblk0
Command (m for help): p
Disk /dev/mmcblk0: 32.1 GB, 32090619904 bytes
4 heads, 16 sectors/track, 979328 cylinders, total 62676992 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0009bf4f
Device Boot Start End Blocks Id System
dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 6399999 3138560 83 Linux
Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): p
Partition number (1-4, default 3):
Using default value 3
First sector (2048-62676991, default 2048): 6400000
Last sector, +sectors or +size{K,M,G} (6400000-62676991, default 62676991): +20G
Command (m for help):
La partizione da 20 GB è la terza partizione primaria, la successiva deve essere un partizione estesa entro la quale troveranno posto le successive partizioni. Questo è il risultato finale:
Command (m for help): p
Disk /dev/mmcblk0: 32.1 GB, 32090619904 bytes
4 heads, 16 sectors/track, 979328 cylinders, total 62676992 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0009bf4f
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 6399999 3138560 83 Linux
/dev/mmcblk0p3 6400000 48343039 20971520 83 Linux
/dev/mmcblk0p4 48343040 62676991 7166976 5 Extended
/dev/mmcblk0p5 48345088 50442239 1048576 83 Linux
La tabella delle partizioni viene letta al boot o forzata con il comando partprobe
Creiamo i FS con il comando mke2fs.
root@weewx-pi:~# mke2fs -t ext4 -L homeFS /dev/mmcblk0p3
mke2fs 1.42.5 (29-Jul-2012)
Discarding device blocks: fatto
Etichetta del filesystem=homeFS
OS type: Linux
Dimensione blocco=4096 (log=2)
Dimensione frammento=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
1310720 inodes, 5242880 blocks
262144 blocks (5.00%) reserved for the super user
Primo blocco dati=0
Maximum filesystem blocks=0
160 gruppi di blocchi
32768 blocchi per gruppo, 32768 frammenti per gruppo
8192 inode per gruppo
Backup del superblocco salvati nei blocchi:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000
Allocating group tables: fatto
Scrittura delle tavole degli inode: fatto
Creating journal (32768 blocks): fatto
Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto
root@weewx-pi:~# mke2fs -t ext4 -L tmpFS /dev/mmcblk0p5
mke2fs 1.42.5 (29-Jul-2012)
Discarding device blocks: fatto
Etichetta del filesystem=tmpFS
OS type: Linux
Dimensione blocco=4096 (log=2)
Dimensione frammento=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
Primo blocco dati=0
Maximum filesystem blocks=268435456
8 gruppi di blocchi
32768 blocchi per gruppo, 32768 frammenti per gruppo
8192 inode per gruppo
Backup del superblocco salvati nei blocchi:
32768, 98304, 163840, 229376
Allocating group tables: fatto
Scrittura delle tavole degli inode: fatto
Creating journal (8192 blocks): fatto
Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto
root@weewx-pi:~#
La partizione home è montata provvisoriamente su /mnt per copiare il contenuto di /home
root@weewx-pi:~# mount /dev/mmcblk0p3 /mnt
root@weewx-pi:~# cd /mnt
root@weewx-pi:/mnt# cp -r /home/* .
root@weewx-pi:/mnt# ls
lost+found pi
root@weewx-pi:/mnt#
In /home è presente solo /home/pi. Ora è possibile modificare il file /etc/fstab per il mount definitivo delle due partizioni.
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
/dev/mmcblk0p3 /home ext4 defaults,noatime 0 1
/dev/mmcblk0p5 /tmp ext4 defaults,noatime 0 1
A questo punto si può fare un reboot per vedere l'effetto che fa.
root@weewx-pi:~# reboot
Broadcast message from root@weewx-pi (pts/0) (Tue May 12 11:59:39 2015):
The system is going down for reboot NOW!
root@weewx-pi:~#
Dopo il reboot il comando mount mostra il risultato e le partizioni.
root@weewx-pi:/tmp# mount
/dev/root on / type ext4 (rw,noatime,data=ordered)
devtmpfs on /dev type devtmpfs (rw,relatime,size=218604k,nr_inodes=54651,mode=755)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=44576k,mode=755)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=89140k)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
/dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
/dev/mmcblk0p3 on /home type ext4 (rw,noatime,data=ordered)
/dev/mmcblk0p5 on /tmp type ext4 (rw,noatime,data=ordered)
root@weewx-pi:/tmp#
Da notare che /run /run/lock e /run/shm sono filesystem in ram (tmpfs). La gestione di questi FS è delagata al dile di configurazione /etc/default/tmpfs
Normalmente lascio la cartella lost+found, anche se praticamente inutile, giusto per evidenziare il nuovo filesystem
root@weewx-pi:/tmp# ls -al /home
totale 28
drwxr-xr-x 4 root root 4096 mag 12 11:43 .
drwxr-xr-x 22 root root 4096 feb 15 12:27 ..
drwx------ 2 root root 16384 mag 12 11:38 lost+found
drwxr-xr-x 3 root root 4096 mag 12 11:43 pi
root@weewx-pi:/tmp#
A questo punto è conveniente aggiornare il software e il firmware.
sudo apt-get update
sudo apt-get upgrade
apt-get clean
Per disabiltare lo swap:
swapoff --all
Lo swap in Raspberry è gestiti non con una propria partizione, ma attraverso il processo dphys-swapfile che crea l'aera di swap in /var/swap. Occorre anche evitare che la gestion dello swap parta al boot disabilitando la il relativo servizio o disinstallando pdhys-svapfile.
update-rc.d dphys-swapfile disable
Resta da spostare la cartella /var/log un filesystem in ram modificando il file /etc/fstab. Al riavvio di verranno persi i file di log, ma in diversi casi è cosa accettabile.
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
/dev/mmcblk0p3 /home ext4 defaults,noatime 0 1
/dev/mmcblk0p5 /tmp ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, so no using swapon|off from here on, use dphys-swapfile swap[on|off] for that
none /var/log tmpfs size=2M,noatime
L'ultima riga crea un filesystem in ram di 2 MB.
per montare il nuovo FS:
mount -a
Altri file da spostare in una area scrivibile sono quelli relativi alla gestione di dhcp, oppure occorre definire un indirizzi IP statico. Sposto questi file in /tmp con un link simbolico.
root@weewx-pi:~# rm -rf /var/lib/dhcp/
root@weewx-pi:~# ln -s /tmp /var/lib/dhcp
root@weewx-pi:~#
root@weewx-pi:~# cp /etc/resolv.conf /tmp/resolv.conf
root@weewx-pi:~# rm /etc/resolv.conf
root@weewx-pi:~# ln -s /tmp/resolv.conf /etc/resolv.conf
root@weewx-pi:~#
Non resta che abilitare read only (ro) per il FS di root in /etc/fstab
/dev/mmcblk0p2 / ext4 ro,defaults,noatime 0 1
e fare il reboot
Nel riavvio porre attenzione al log per eventuali errori.
A questo punto non è più possibile modificare file nella partizione di root. All'occorrenza bisogna riabilitare la scrittura, modificare eventuali configurazioni e riabilitare la sola lettura.
Per ripristinare la scrittura:
mount -o remount rw /
Commenti
lorenzo_s (non verificato)
Mer, 16/03/2016 - 18:37
Collegamento permanente
Ringrazio per l'ottima guida
Ringrazio per l'ottima guida per mettere in read-only la SD; prima di metterla in pratica chiedo solo un parere tecnico: ho visto che altri risolvono il problema utilizzando tmpfs per scrivere temporaneamente su RAM; quali sono i pro e i contro?
webmaster
Mer, 16/03/2016 - 20:12
Collegamento permanente
Un filesystem temporaneo va
Un filesystem temporaneo va bene per memorizzare dati che possono andare persi, ad esempio /tmp o /run in quanto viene distrutto quando la macchina si spegne.
Per risolvere problemi di corruzione della scheda SD, ritengo più conveniete trasferire i file system su una chiavetta USB. Meglio ancora un disco, magari allo ststo solido. Troppo lusso.
ANDREA (non verificato)
Lun, 16/03/2020 - 18:52
Collegamento permanente
Taglio corto...
Ciao, scusa se cerco il pelo nell'uovo ma è giusto per capire: se ho già due partizioni e abilito solo il flag ro nel fstab, posso continuare a lavorare utilizzando la seconda partizione come deposito dati variabili?
webmaster
Lun, 16/03/2020 - 19:40
Collegamento permanente
Non vedo perchè no. Se la
Non vedo perchè no. Se la seconda partizione è rw ci puoi scrivere.
ANDREA (non verificato)
Mer, 18/03/2020 - 18:14
Collegamento permanente
Taglio corto...
Ok, però tu hai scritto che per il corretto funzionamento ci sono due cartelle che vanno escluse dal file system
webmaster
Mer, 18/03/2020 - 19:16
Collegamento permanente
Ho riletto velocemente quanto
Ho riletto velocemente quanto ho scritto nel 2015.
Si parla di directory che non possono essere solo in lettura, quindi occorre un FS rw da montare per le directory che non possono essere di sola lettura.