[ KOI8 | CP1251(MS-Windows) | CP866(DOS) | ISO8859-5 | Mac ]
Внезапные выключения PC-роутера (как и любой Linux-машины) могут привести к нарушениям корректности файловой системы. Повреждения возникают из-за того, что операции с файловой системой не являются неделимыми; например, модификация файла включает в себя изменение как блоков файла, так и описателя файла (i-node), списка свободных блоков и т.д., которые записываются на диск несколькими раздельными операциями записи. После выполнения первой из операций и вплоть до завершения последней файловая система на диске находится в промежуточном, переходном состоянии; если в этот момент произойдет выключение, файловая система так и останется в некорректном состоянии и будет требовать починки (fsck).
Во многих случаях повреждения оказываются несерьезными, так что при загрузке системы возможна автоматическая починка без потери файлов (fsck -a). Тем не менее, существует вероятность серьезного повреждения, которое потребует починки в ручном режиме и, возможно, восстановления потерянных файлов. Поэтому допускать повреждения файловой системы нельзя, ибо это противоречит принципу необслуживаемости (см. раздел 2.2) изделия.
Поскольку повреждения возникают исключительно как результат незавершенных операций записи на диск, мы можем избежать повреждений, работая с диском в режиме "только на чтение" (read-only, r/o). Однако просто смонтировать весь диск read-only нельзя, поскольку для полноценной работы системы требуется, чтобы некоторые каталоги (/tmp, /var/run, /var/log, ...) работали в режиме "чтение и запись" (read/write, r/w). При этом записываемая в эти каталоги информация носит преходящий характер (временные файлы, .pid файлы, файлы с отладочными протоколами и т.д.). Поэтому полноценное решение выглядит так:
r/w раздел монтируется на /var/lib/roroot/volatile, и при старте системы (/etc/init.d/boot) инициализируется из /var/lib/roroot/volatile.ini. Каталоги на r/o разделе, для которых необходимо обеспечить возможность записи, заменяются на символические ссылки на соответствующие им каталоги на r/w разделе:
ln -s /var/lib/roroot/volatile/X/Y/Z /X/Y/Z
Несколько моментов требуют особого обхождения при переходе к работе с корневым разделом в режиме r/o.
/etc/mtab модифицируется командой mount при монтировании и отмонтировании устройств. "mount -n" опускает модификацию mtab, но тогда некоторые команды, которые берут из mtab информацию о смонтированных файловых системах (например, df и собственно mount) будут работать неидеально.
К счастью, существует файл /proc/mounts, совпадающий по формату с /etc/mtab, и содержащий постоянно верную информацию о смонтированных файловых системах.
Поэтому решение проблемы с /etc/mtab следущее: /etc/mtab заменяем символической ссылкой на /proc/mounts, и всегда используем "mount -n".
Таблица зависимостей модулей существенна для работы modprobe и, следственно, kerneld, короче, для автоматической загрузки модулей ядра. /etc/init.d/modutils строит этот файл заново, если он не существует. Поскольку /lib/modules/`uname -r`/modules.dep находится на r/o разделе, это не будет работать просто так. Мы модифицируем /etc/init.d/modutils, чтобы на время построения modules.dep изменить режим монтирования корневой файловой системы на r/w.
Это не идеальное решение, поскольку машина оказывается на какое-то время уязвима для пропадания питания. Однако это время весьма мало (несколько секунд), и небольшой риск вполне окупается гарантией существования актуального modules.dep.
В процессе входа пользователя в систему, login пытается выполнить смену владельца и режимов доступа (chown, chmod) для /dev/ttyXXX, на котором происходит вход. Поскольку каталог /dev находится на r/o разделе, эти операции заканчиваются неудачей.
Смена владельца и режмов доступа терминала не критична (не создает возможности несанкционированного, либо невозможности санкционированного доступа) для роутеров, где обычно единственным пользователем системы является root. Однако login проверяет код завершения операций chown и chmod, и в случае неудачи обрывает процедуру входа--это означает невозможность входа в систему, если каталог /dev находится на r/o разделе. Разместить же /dev на r/w разделе нельзя, поскольку его присутствие необходимо на этапе раскрутки системы--в частности, для монтирования r/w раздела.
Поэтому для роутеров используется модифицированнaя версия /bin/login, которая спокойно воспринимает завершение chown/chmod с ошибкой EROFS.
На роутерах иногда все-таки возникает потребность записывать файлы так, чтобы они переживали выключение питания. Например, некоторые файлы статистики, или, скажем, база мигрирующих IP-адресов (pppmlogin.db) на роутере, выполняющем функции терминального сервера. Если первую проблему еще можно пытаться решать при помощи "syslog to remote host", то вторая в рамках описанного деления на r/o - r/w разделы не решается.
Решение дает использование удаленного сервера для хранения файлов. Аналогично монтированию r/w раздела на /var/lib/roroot/volatile, мы монтируем (mount -t nfs) удаленный диск на /var/lib/roroot/remote. Также аналогично, каталоги на r/o разделе, для которых необходимо обеспечить режим "r/w с постоянным хранением", заменяются на символические ссылки на соответствующие им подкаталоги на удаленном диске:
ln -s /var/lib/roroot/remote/X/Y/Z /X/Y/Z
Я надеюсь в обозримом будущем изготовить автоматически инсталлируемый пакет (roroot-NNN.deb), который при инсталляции (dpkg -i) будет создавать все необходимые каталоги, линки и т.д. А пока придется вручную; можно использовать файловое дерево dish-routerа в качестве прототипа.
dish-router:~# fdisk Using /dev/hda as default device! Command (m for help): p Disk /dev/hda: 10 heads, 34 sectors, 984 cylinders Units = cylinders of 340 * 512 bytes Device Boot Begin Start End Blocks Id System /dev/hda1 1 1 20 3383 1 DOS 12-bit FAT /dev/hda2 * 21 21 562 92140 83 Linux native /dev/hda3 563 563 755 32810 82 Linux swap /dev/hda4 756 756 984 38930 83 Linux native Command (m for help):
dish-router:~# ls -l `find / -lname '*roroot*'` lrwxrwxrwx 1 root root 28 Sep 29 22:41 /tmp -> /var/lib/roroot/volatile/tmp lrwxrwxrwx 1 root root 36 Sep 30 17:47 /var/backups -> /var/lib/roroot/volatile/var/backups lrwxrwxrwx 1 root root 35 Sep 29 22:41 /var/catman -> /var/lib/roroot/volatile/var/catman lrwxrwxrwx 1 root root 33 Sep 29 22:41 /var/lock -> /var/lib/roroot/volatile/var/lock lrwxrwxrwx 1 root root 32 Sep 29 22:41 /var/log -> /var/lib/roroot/volatile/var/log lrwxrwxrwx 1 root root 32 Sep 29 22:41 /var/run -> /var/lib/roroot/volatile/var/run lrwxrwxrwx 1 root root 38 Sep 29 22:41 /var/spool/lpd -> /var/lib/roroot/volatile/var/spool/lpd lrwxrwxrwx 1 root root 40 Sep 29 22:41 /var/spool/smail -> /var/lib/roroot/volatile/var/spool/smail lrwxrwxrwx 1 root root 32 Sep 29 22:41 /var/tmp -> /var/lib/roroot/volatile/var/tmpsizif@botik.ru
Last modified: Sun Oct 5 00:15:27 MSD 1997