Przeniesienie overlay na dysk zewnętrzny
Ostatnia zmiana: 2019-07-06 10:25
Routery wyposażone są w niewielką ilość pamięci flash, zwykle 4 lub 8MB. Wystarcza to do większości zastosowań, jednakże możemy spotkać się z sytuacją kiedy potrzebujemy więcej miejsca na instalację pakietów czy przechowywanie danych. Jeżeli router ma zrobiony tzw. SDMOD lub ma złącze USB można pokusić się o rozszerzenie pamięci flash o pojemność zewnętrznego nośnika.
Można zastosować dysk USB, pendrive a nawet czytnik kart np. SD czy kartę z modemu USB (pod pewnymi warunkami). Extroot wymaga linuksowego systemu plików, więc w przypadku formatowania dane na nim mogą zostać utracone! Oczywiście potrzebna jest tylko jedna partycja, więc można z istniejącego dysku wyodrębnić niewielką przestrzeń na extroota przy pomocy narzędzi dostępnych na Windows czy Linuksa.
Teoria
Podział pamięci flash w routerze w dużym uproszczeniu wygląda następująco:
- bootloader
- system operacyjny routera
- obszar systemowy z danymi konfiguracyjnymi, ustawieniami oryginalnego systemu itp.
Sam obszar w którym oryginalnie instalowany jest system routera, zastępowany jest obrazem z OpenWrt (zwykle jest to wysoko skompresowany system plików
squashfs - tylko do odczytu). Ponieważ firmware zwykle nie zajmuje całej pamięci flash, pozostała część jest przy pierwszym uruchomieniu routera formatowana przez OpenWrt systemem plików
jffs i montowana w katalogu /overlay. Następnie wykorzystując jeszcze jeden system plików o nazwie
mini_fo (w Backfire) lub
overlayfs (wydanie Attitude Adjustment i późniejsze), część z
jffs jest "nakładana" (overlay) na
squashfs, dzięki czemu użytkownik widzi oba jako jeden i ma wrażenie zapisywalnego systemu plików. A tak naprawdę wszystkie zmiany są zapisywane w przestrzeni
jffs, bo
squashfs jest tylko do odczytu.
Nic nie stoi na przeszkodzie, aby obszar z
jffs zastąpić zewnętrznym nośnikiem - kartą SD czy pendrive. W ten sposób powstaje wspomniany extroot.
Jeżeli używasz Gargoyle to extroota robi się w gui (Zakładka "Nośniki", odmontuj wszystkie nośniki).
Cały poradnik zakłada że extroot będzie wykonywany na pierwszej partycji nośnika (która przedstawia się zwykle jako
sda1). Jeżeli używamy innych nośników, innych partycji itd to należy odpowiednio dostosować przedstawione poniżej polecenia.
LEDE, OpenWrt 18.06 i późniejsze wydania
Podobnie jak dla wydania BB i CC możliwe jest wykonanie extroota z wykorzystaniem systemu plików ext4. Jednakże wydanie LEDE i późniejsze wspierają także inny system plików -
f2fs który jest dedykowany do nośników z pamięciami NAND (karty SD, nośniki USB czy dyski SSD), jest mniejszy niż ext4 i tym samym umożliwia bezproblemowe zmieszczenie obsługi tego systemu plików wraz z odpowiednimi narzędziami w 4MB pamięci flash.
Formatowanie dysku systemem f2fs
# opkg update
# opkg install mkf2fs # jeżeli nie ma go jeszcze w obrazie
# mkfs.f2fs /dev/sda1
F2FS-tools: mkfs.f2fs Ver: 1.7.0 (2016-07-28)
Info: Debug level = 0
Info: Label =
Info: Trim is enabled
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 8025745 (3918 MB)
Info: zone aligned segment0 blkaddr: 256
Info: format version with
"Linux version 4.4.50 (cezary@eko.one.pl) (gcc version 5.4.0 (LEDE GCC 5.4.0 r3103-1b51a49) ) #0 Thu Feb 23 16:34:14 2017"
Info: Discarding device
Info: This device doesn't support BLKSECDISCARD
Info: This device doesn't support BLKDISCARD
Info: Overprovision ratio = 3.220%
Info: Overprovision segments = 130 (GC reserved = 70)
Info: format successful
Szybka instalacja
# opkg update
# opkg install block-mount kmod-fs-f2fs f2fsck # jeżeli nie ma ich jeszcze w obrazie
# block detect > /etc/config/fstab
# uci set fstab.@mount[0].target='/overlay'
# uci set fstab.@mount[0].enabled='1'
# uci set fstab.@global[0].check_fs='1'
# uci commit fstab
W tym przykładzie zrobi to extroota na pierwszej partycji zdefiniowanej w konfigu. Jeżeli extroot ma być na innej - trzeba dostosować polecenia.
Skopiowanie bieżącej konfiguracji
Opcjonalnie - przed wykonaniem reboot i aktywacją extroota można przenieść bieżącą konfigurację systemu wraz z zainstalowanymi programami czy wykonanymi modyfikacjami na nośnik który będzie extrootem, dzięki czemu nie będzie potrzeby ponownej konfiguracji systemu
# mkdir -p /tmp/dysk
# mount /dev/sda1 /tmp/dysk
# tar -C /overlay -cvf - . | tar -C /tmp/dysk -xf -
# umount /tmp/dysk
Wymagany jest restart systemu
Dostęp do starej zawartości flash
Dotyczy tylko systemów typu
squashfs
# uci add fstab mount
# uci set fstab.@mount[-1].target='/tmp/flash'
# uci set fstab.@mount[-1].device='/dev/mtdblock3'
# uci set fstab.@mount[-1].fstype='jffs2'
# uci set fstab.@mount[-1].options='rw,sync'
# uci set fstab.@mount[-1].enabled='1'
# uci set fstab.@mount[-1].enabled_fsck='0'
# uci commit
Gdzie /dev/mtdblock
3 to numer partycji we flash o nazwie
rootfs_data. Można ją znaleźć poleceniem:
# grep rootfs_data /proc/mtd | sed 's/mtd\(.*\):.*/\1/g'
Po restarcie w katalogu
/tmp/flash będzie oryginalna zawartość katalogu
/overlay z pamięci flash.
Barrier Breaker, Chaos Calmer
Należy podłączyć nośnik i wygenerować
konfigurację. Utworzenie extroota sprowadza się tylko do zmiany opcji
target na
/overlay. Poniżej przedstawiono to w skrócie.
Formatowanie dysku systemem ext4
Jeżeli nie ma na nośniku jeszcze systemu plików ext4 to należy go zrobić (UWAGA: usunie to wszystkie dane z dysku). Dysk oczywiście musi być
odmontowany (można to sprawdzić poleceniem
mount | grep "dev/sd").
# opkg update
# opkg install e2fsprogs # jeżeli nie ma go jeszcze w obrazie
# mkfs.ext4 -m 0 /dev/sda1
mke2fs 1.42.4 (12-June-2012)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
30600 inodes, 122112 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
15 block groups
8192 blocks per group, 8192 fragments per group
2040 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
Szybka instalacja
# opkg update
# opkg install block-mount kmod-fs-ext4 # jeżeli nie ma ich jeszcze w obrazie
# block detect > /etc/config/fstab
# uci set fstab.@mount[0].target='/overlay'
# uci set fstab.@mount[0].enabled='1'
# uci set fstab.@global[0].check_fs='1'
# uci commit fstab
# reboot
W tym przykładzie zrobi to extroota na pierwszej partycji zdefiniowanej w konfigu. Jeżeli extroot ma być na innej - trzeba dostosować polecenia.
W przypadku potrzeby ponownej aktywacji istniejącego extroota należy usunąć plik
/etc/.extroot-uuid (nie etc/extroot.md5sum jak to było dla wydania Attitude Adjustment)
Attitude Adjustment
Poniższe konfiguracje są prawidłowe tylko dla wydania OpenWrt Attitude Adjustment. Dla innych wydań:
patrz powyżejZakładam, że mamy nośnik z systemem plików ext4. Podłączamy go do usb jako jedyny (inne należy odłączyć). Włączenie extroota sprowadza się do wydania poleceń:
# opkg update
# opkg install block-mount kmod-fs-ext4 # jeżeli używamy systemu pliku ext4, ext3 lub ext2.
# uci set fstab.@mount[0].target=/overlay
# uci set fstab.@mount[0].device=/dev/sda1
# uci set fstab.@mount[0].fstype=ext4
# uci set fstab.@mount[0].options=rw,noatime
# uci set fstab.@mount[0].enabled=1
# uci commit fstab
# /etc/init.d/fstab enable
# reboot
(sda1 to pierwsza partycja tego dysku). Aby przekonać się czy extroot działa, po restarcie należy wydać polecenie
mount i odnaleźć linię podobną do tej:
root@OpenWrt:/# mount
...
/dev/sda1 on /overlay type ext4 (rw,noatime,errors=continue)
Uwagi
- po włączeniu extroota system jest jak świeżo po flashowaniu: nie ma żadnej konfiguracji, nie ma ustawionego hasła, nie ma ustawionego wifi. Trzeba podłączyć się przez telnet i skonfigurować wszystko łączenie z instalacją pakietów. Lub skopiować z obszaru jffs pamięci routera.
- trzeba podać dokładnie takie system plików jaki jest na nośniku. Jeżeli mamy tam ext2 to należy podać ext2, nie ext3 czy ext4.
- zakładamy, że w systemie jest już zainstalowana obsługa magistrali usb, nośników usb-storage i odpowiedniego systemu plików (ext4 w przedstawionym przykładzie).
Firmware
Należy posłużyć się firmware (lub skompilować samodzielnie) który będzie zawierał następujące pakiety (mogą także zostać po prostu doinstalowane):
- obsługę usb-storage, kart SD/SDHC lub dysków IDE/SATA
- obsługę systemu plików - ext2, ext3 lub ext4.
Systemu plików FAT czy NTFS nie nadaje się do tego celu!- pakiet block-mount
oraz opcjonalnie
- e2fsprogs
- fdisk
Taki firmware należy zainstalować normalnie na routerze wykorzystując jedną z dostępnych metod.
Przygotowanie dysku
Dysk powinien być sformatowany systemem plików ext2, ext3 lub ext4. Jeżeli na routerze zainstalowane są pakiety e2fsprogs oraz fdisk (nie muszą być wkompilowane na stałe, można doinstalować), proces tworzenia partycji można wykonać właśnie z poziomu routera. Jeżeli dysk już ma taki system plików, poniższe czynności można pominąć.
Tworzenie partycji
Generalnie - dysk zapewne już ma jakąś partycję, więc nie ma zbytnio potrzeby ich robić ponownie. Nie ma także potrzeby zmieniać specjalnie typu partycji z Windows na Linux. Jeżeli jednak ktoś koniecznie chce to uczynić - informacje zawarte są poniżej.
Podłączamy dysk pod USB. Jeżeli został on zamontowany, należy go odmontować (po wykonaniu polecenia
mount nie powinno być tam żadnych wpisów związanych z tym dyskiem). Zakładając że został on wykryty jako /dev/sda (można się o tym przekonać wydając polecenie
logread i szukając odpowiedniego wpisu dotyczącego dysku), należy uruchomić program
fdisk. W tym przykładzie usuwane były wszystkie partycje i zakładana jedna na całym dysku. Pogrubioną czcionką zaznaczono dane prowadzane przez użytkownika.
root@OpenWrt:# fdisk /dev/sda
The number of cylinders for this disk is set to 7301.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): d
Selected partition 1
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-7301, default 1): <enter>
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-7301, default 7301): <enter>
Using default value 7301
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 83
Changed system type of partition 1 to 83 (Linux)
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
root@OpenWrt:#
Została usunięta stara partycja, a następnie założona jedna podstawowa, od pierwszego do ostatniego cylindra (cały obszar dysku) typu Linux.
Formatowanie dysku
Należy teraz utworzyć system plików na dysku. W tym przykładzie był to ext4. Do formatowania niezbędne jest zainstalowanie pakietu
e2fsprogs.
Uwagi:
- formatuje się partycję (/dev/sda1), nie dysk (/dev/sda)!
- tworzenie systemu plików wymaga sporo pamięci ram. Routery z 32MB pamięci nie są w stanie sformatować dysku o pojemności 1TB. Należy wcześniej utworzyć i aktywować swap, podzielić dysk na mniejsze partycje lub sformatować go na normalnym komputerze.
- nie należy tego robić na komputerze z Ubuntu. O ile operacja się uda, o tyle jest później problem z dnsami na tak zrobionym extroocie.
root@OpenWrt:# mkfs.ext4 -m 0 /dev/sda1
mke2fs 1.40.11 (17-June-2008)
Warning: 256-byte inodes not usable on older systems
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
3670016 inodes, 14661312 blocks
733065 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
448 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
Konfiguracja routera
Mając tak przygotowany dysk zostaje jeszcze tylko wskazać routerowi że ma go wykorzystać. Robi się to odpowiednio konfigurując plik
/etc/fstab. Dysk można wskazać na trzy sposoby:
- przez UUID (unikalny identyfikator dysku, do odczytania programem
blkid). Metoda konieczna jak mamy kilka dysków!
- przez etykietę (LABEL - którą można nadać uruchamiając program
tune2fs z przełącznikiem
-L)
- przez urządzenie (czyli /dev/sdaX wskazywany przez system)
W tym przykładzie wykorzystano nazwę urządzenia.
# uci set fstab.@mount[0].target=/overlay
# uci set fstab.@mount[0].device=/dev/sda1
# uci set fstab.@mount[0].enabled=1
# uci set fstab.@mount[0].fstype=ext4
# uci commit fstab
(jeżeli po pierwszym poleceniu pojawi się błąd uci, należy zrobić nową sekcję: uci add fstab mount)
Jeżeli chcemy wykorzystać UUID należy najpierw odczytać identyfikator partycji
# blkid /dev/sda1
/dev/sda1: UUID="f11dbc98-b4f9-4ac9-9908-03d53a8d979f"
a następnie ustawić opcję
uuid w konfiguracji
# uci set fstab.@mount[0].uuid=f11dbc98-b4f9-4ac9-9908-03d53a8d979f
# uci commit fstab
Cały plik
/etc/config/fstab może więc wyglądać następująco:
config 'global' 'automount'
option 'from_fstab' '1'
option 'anon_mount' '1'
config 'global' 'autoswap'
option 'from_fstab' '1'
option 'anon_swap' '0'
config 'mount'
option 'target' '/overlay'
option 'fstype' 'ext4'
option 'options' 'rw,noatime'
option 'enabled_fsck' '0'
option 'device' '/dev/sda1'
option 'enabled' '1'
Jeżeli zostanie ustawiona opcja
enabled_fsck i został wkompilowany lub zainstalowany pakiet
e2fsprogs to przy starcie routera zostanie wykonane także sprawdzenie systemu plików.
Dysk można więc podłączyć identyfikując go na trzy sposoby:
- przez UUID (
option uuid): unikalny identyfikator, więc tylko ten dysk i ta partycja będzie wykorzystana do tego celu
- przez etykietę (
option label): można posiadać wiele nośników z różnymi konfiguracjami, jeżeli tylko będzie miał odpowiednią etykietę to będzie wykorzystany
- przez nazwę urządzenia (
option device): każdy podłączony nośnik, o ile oczywiście ma odpowiedni system plików, będzie wykorzystany
Testowanie
Wystarczy teraz wykonać restart routera z podłączonym dyskiem. Czas inicjacji i wykrycia dysku jest ustawiony domyślnie na 20s. Dysk powinien się zamontować i być widoczny w systemie. Oto wynik po zastosowaniu w/w przepisu:
root@OpenWrt:/# mount
rootfs on / type rootfs (rw)
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,relatime,size=31040k)
tmpfs on /dev type tmpfs (rw,relatime,size=512k)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
/dev/sda1 on /overlay type ext4 (rw,sync,relatime,errors=continue,data=writeback)
overlayfs:/overlay on / type mini_fo (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
none on /proc/bus/usb type usbfs (rw,relatime)
root@OpenWrt:/# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 1.9M 1.9M 0 100% /rom
tmpfs 30.3M 44.0K 30.3M 0% /tmp
tmpfs 512.0K 0 512.0K 0% /dev
/dev/sda1 55.0G 180.0M 52.1G 0% /overlay
overlayfs:/overlay 1.9M 1.9M 0 100% /
Swap
Często ilość pamięci ram jest niewystarczająca i można się poratować tworzą tzw. swap. Jeżeli dzielimy dysk na partycje należy wydzielić mały obszar (np. 64MB) i utworzyć partycję typu Linux-swap:
root@OpenWrt:# fdisk /dev/sda
The number of cylinders for this disk is set to 7301.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): d
Selected partition 1
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-7301, default 1): <enter>
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-7301, default 7301): +64M
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 82
Changed system type of partition 1 to 82 (Linux swap / Solaris)
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (132-7301, default 132): <enter>
Using default value 132
Last cylinder or +size or +sizeM or +sizeK (1-7301, default 7301): <enter>
Using default value 7301
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
root@OpenWrt:#
W tym przykładzie została utworzona pierwsza partycja typu Linux-swap o wielkości 64MB oraz następna typu Linux na pozostałej przestrzeni. Należy teraz ten swap utworzyć poleceniem:
Na drugiej partycji moża utworzyć system plików:
# mkfs.ext4 -m 0 /dev/sda2
Plik konfiguracyjny dla tego przypadku wygląda następująco:
config 'global' 'automount'
option 'from_fstab' '1'
option 'anon_mount' '1'
config 'global' 'autoswap'
option 'from_fstab' '1'
option 'anon_swap' '0'
...
config 'swap'
option 'device' '/dev/sda1'
option 'enabled' '1'
Aktualizacja
Ostatnie wersje OpenWrt wprowadzają jeszcze jeden element do całości - sumę kontrolną. Jeżeli pierwszy raz robimy extroota, system na nośniku umieszcza plik extroot.md5sum który jest sumą kontrolną systemu. Podczas uruchamiania extroota jest ona porównywana - jeżeli się zgadza, system kontynuuje działanie uruchamiając extroota. Jeżeli nie - np. z powodu upgrade systemu - system odmawia aktywacji, bo może to oznaczać że na nośniku mogą być pliki z poprzedniej wersji systemu, niekompatybilne z bieżącą. Więc po upgrade systemu, jeżeli mamy pewność że wszystko się zgadza należy po prostu usunąć z nośnika plik kontrolny o wspomnianej nazwie i system normalnie wystartuje z nim.
Po aktualizacji systemu (mtd/sysupgrade itd) dane na nośniku zostają takie jak były - aktualizacja ani nie usunie danych z nośnika ani nie zaktualizuje pakietów które są tam zainstalowane. Co więcej - extroot zostanie zdeaktywowany! Więc po upgrade systemu należy
ręcznie aktualizować pakiety i pliki konfiguracyjne na nośniku, potem zostaje tylko zmiana w
fstab i usunąć z nośnika plik
etc/extroot.md5sum, lub wydać polecenia
# /etc/init.d/fstab overlay_enable
# reboot
Zakończenie
Po uruchomieniu extroot'a znika cała pierwotna konfiguracja - więc o ile router był już wcześniej skonfigurowany (np. ustawione wifi czy zainstalowane pakiety) - po tej operacji należy jeszcze raz to zrobić. Stara konfiguracja jest "przykrywana" przez extroot, więc albo trzeba jeszcze raz wszystko skonfigurować albo przenieść pliki z pamięci flash na dysk.
Mała sztuczka (
http://eko.one.pl/forum/viewtopic.php?id=1062): aby wiadomo było jak system startuje należy PRZED zrobieniem extroota zrobić:
# echo "Booted from internal flash" >> /etc/banner
A po zrobieniu:
# echo "Booted from EXTERNAL ROOT" >> /etc/banner
Po zalogowaniu przez telnet/ssh wyświetli się informacja jak został uruchomiony router.
Backfire
Wersja z Backfire wymagała innej konfiguracji:
- należało zainstalować kmod-fs-ext2, kmod-fs-ext3 lub kmod-fs-ext4 w zależności od używanego systemu plików
- block-extroot, który był oddzielnym pakietem
- w konfiguracji fstab w sekcji mount dodatkowo podać opcję
option is_rootfs 1Czyli:
# opkg update
# opkg install block-mount block-extroot kmod-fs-ext4 #jeżeli używamy systemu pliku ext4, ext3 lub ext2.
# uci set fstab.@mount[0].target=''
# uci set fstab.@mount[0].device=/dev/sda1
# uci set fstab.@mount[0].fstype=ext4
# uci set fstab.@mount[0].options=rw,noatime
# uci set fstab.@mount[0].enabled=1
# uci set fstab.@mount[0].is_rootfs=1
# uci commit fstab
# /etc/init.d/fstab enable
# reboot