Файловая система ( / rootfs) полностью в RAM...

Автор: B.X - 25.10/2020, вс - 21:04

Давно наблюдаю за Puppyrus Linux очень мне нравится идея работать полностью в оперативной памяти. И быстро и диски не вырабатывают свой ресурс. И надёжно, так как чтобы ни случилось, после перезагрузки, у тебя новая система. Но, почему-то никто не хочет видеть очевидное и все основные дистрибутивы (и не основные тоже) ничего не делают, чтобы дать возможность работать всем в оперативной памяти. Хотя, технология довольно проста, правда не для всех дистрибутивов. На эту тему я нашёл всего две статьи, 2011 и 2015 годов. Одна на английском, вторая на русском.

Почему я вообще затронул эту тему и решил провести такой эксперимент, всё очень просто, у меня полетел SSD-диск, а на HDD, на который я переустановил систему, всё работает очень уж неторопливо. И мне это не нравится. Покупать новый диск? Так он тоже может полететь, причём весьма неожиданно. Если HDD-диски становятся нежизнеспособными не в один момент (хотя, не всегда), то SSD у меня умер сразу, буквально за пару минут. Очень неприятное чувство, хорошо, что у меня были бэкапы и системных настроек и тем, которые мне нравятся.

Итак, приступим. Начнём с того, что эти HOWTO были написаны только для Debian-совместимых дистрибутивов, поэтому мне пришлось, установить на соседний раздел, MXLinux и сделать всё с его помощью. В будущем, я попытаюсь использовать модифицированный initrd и для Calculate Linux. Конечно, некоторые настройки изменились и в файлах всё не так, как четыре и девять лет назад, но слава всевышним силам, до initramfs шаловливые руки Поттеринга и иже с ним, ещё не добрались и код рабочий. Сначала приведу две статьи источника, вот эту (сразу скажу, что код там с ошибками и надо будет кое-что поправить) и вот эту, здесь предлагается использовать дополнительно файл, в который надо было бы загрузить всю систему, которая находится на диске, так как это лишняя сущность, то этот код я использовал больше для справки.

Первый способ:
1. В файле /usr/share/initramfs-tools/scripts/local ищем на строках 179-185 (предварительно сделав бэкап файла):

  1.         checkfs "${ROOT}" root "${FSTYPE}"
  2.  
  3.         # Mount root
  4.         # shellcheck disable=SC2086
  5.         if ! mount ${roflag} ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" "${rootmnt?}"; then
  6.                 panic "Failed to mount ${ROOT} as root file system."
  7.         fi

И меняем этот код на такой:

  1.         #checkfs "${ROOT}" root "${FSTYPE}"
  2.  
  3.         # Mount root
  4.         # shellcheck disable=SC2086
  5.         mkdir /ramboottmp
  6.         mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /ramboottmp
  7.         mount -t tmpfs -o size=100% none ${rootmnt}
  8.         cd ${rootmnt}
  9.         cp -rfa /ramboottmp/* ${rootmnt}
  10.         umount /ramboottmp

2. Сохраняем файл. И вводим команду в терминале от рута:

  1. mkinitramfs -o /boot/initrd.img-ramboot

3. Проверяем, что файл создан в папке /boot и возращаем старый local в папке /usr/share/initramfs-tools/scripts/local на место (или удаляем все наши изменения, которые мы сделали в шаге 1).
4. Идём в папку /etc и находим файл fstab, сохраняем его копию и редактируем его, ищем в первых строках что-то вроде этого:

  1. UUID=35378150-4a4b-4405-b856-c5f533a971e2 / ext4 defaults 1 1

и меняем на:

  1. none / tmpfs defaults 0 0

5. Сохраняем и идём в папку /boot/grub, находим grub.cfg и изменяем (предварительно сохранив копию) эти строки 106-121:

  1. menuentry 'MX 19.2 patito feo, with Linux 4.19.0-12-amd64' --class mx --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.19.0-12-amd64-advanced-35378250-4a4b-4405-b956-c5f546a970e2' {
  2.         load_video
  3.         insmod gzio
  4.         if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
  5.         insmod part_msdos
  6.         insmod ext2
  7.         set root='hd2,msdos3'
  8.         if [ x$feature_platform_search_hint = xy ]; then
  9.           search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos3 --hint-efi=hd2,msdos3 --hint-baremetal=ahci2,msdos3  35378250-4a4b-4405-b956-c5f546a970e2
  10.         else
  11.           search --no-floppy --fs-uuid --set=root 35378250-4a4b-4405-b956-c5f546a970e2
  12.         fi
  13.         echo    'Loading Linux 4.19.0-12-amd64 ...'
  14.         linux   /boot/vmlinuz-4.19.0-12-amd64 root=UUID=35378250-4a4b-4405-b956-c5f546a970e2 ro  quiet hush
  15.         echo    'Loading initial ramdisk ...'
  16.         initrd  /boot/initrd.img-4.19.0-12-amd64
  17. }

на тот код, что находится ниже, то есть, просто добавляем ещё одно меню, немного видоизменённое в названии и на строчке initrd (для других систем, этот код меню, естественно, будет другой, но те изменения, которые сделали мы, будут те же самые):

  1. menuentry 'RAMBOOT' --class mx --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.19.0-12-amd64-advanced-35378250-4a4b-4405-b956-c5f546a970e2' {
  2.         load_video
  3.         insmod gzio
  4.         if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
  5.         insmod part_msdos
  6.         insmod ext2
  7.         set root='hd2,msdos3'
  8.         if [ x$feature_platform_search_hint = xy ]; then
  9.           search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos3 --hint-efi=hd2,msdos3 --hint-baremetal=ahci2,msdos3  35378250-4a4b-4405-b956-c5f546a970e2
  10.         else
  11.           search --no-floppy --fs-uuid --set=root 35378250-4a4b-4405-b956-c5f546a970e2
  12.         fi
  13.         echo    'Loading Linux 4.19.0-12-amd64 ...'
  14.         linux   /boot/vmlinuz-4.19.0-12-amd64 root=UUID=35378250-4a4b-4405-b956-c5f546a970e2 ro  quiet hush
  15.         echo    'Loading initial ramdisk ...'
  16.         initrd  /boot/initrd.img-ramboot
  17. }
  18. menuentry 'MX 19.2 patito feo, with Linux 4.19.0-12-amd64' --class mx --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.19.0-12-amd64-advanced-35378250-4a4b-4405-b956-c5f546a970e2' {
  19.         load_video
  20.         insmod gzio
  21.         if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
  22.         insmod part_msdos
  23.         insmod ext2
  24.         set root='hd2,msdos3'
  25.         if [ x$feature_platform_search_hint = xy ]; then
  26.           search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos3 --hint-efi=hd2,msdos3 --hint-baremetal=ahci2,msdos3  35378250-4a4b-4405-b956-c5f546a970e2
  27.         else
  28.           search --no-floppy --fs-uuid --set=root 35378250-4a4b-4405-b956-c5f546a970e2
  29.         fi
  30.         echo    'Loading Linux 4.19.0-12-amd64 ...'
  31.         linux   /boot/vmlinuz-4.19.0-12-amd64 root=UUID=35378250-4a4b-4405-b956-c5f546a970e2 ro  quiet hush
  32.         echo    'Loading initial ramdisk ...'
  33.         initrd  /boot/initrd.img-4.19.0-12-amd64
  34. }

Теперь у нас два варианта меню. Если надо зайти в быструю систему и комфортно работать, то мы идём в RAMBOOT, а если надо обновиться или что-то сделать с системой, то идём во второе меню, которое никак не изменилось. Конечно, нельзя не сказать о недостатках, а именно о долгой загрузке такой системы, то есть, чем больше у вас на диске занимает файловая система ( / rootfs), тем дольше будет загружаться компьютер. Но на самом деле это не так страшно. Дело привычки, да и систему можно постараться уменьшить в размере. Наверняка возможны какие-то варианты со сжатыми файловыми системами только для чтения и тд. Лучше всего, конечно, всё это реализовано в Puppyrus Linux, но там другая проблема, нет стабильного репозитария и собирают пакеты все, кто может и часто нет того, что нужно.

Добавлено(1) - через несколько часов: После нескольких часов работы, могу сказать, что ощущения от работы в оперативной памяти просто несравнимы. Ни с SSD, ни с HDD. Особенно это заметно при просмотре сайтов в интернете. Всё просто летает, открывается мгновенно, браузер не тормозит, ни при возвращении на предыдущую страницу, ни при открытии новых (которые теперь зависят действительно только от интернета). И это Vivaldi (основанный на Хроме), что уж говорить о других, более легковесных браузерах, там вообще даже минимальных задержек нет. Интересное ощущение, удивительное...

Добавлено(2) - 26.10.2020: Для изменения последующей загрузки, чтобы не работать в вечно неизменной системе, я изменяю состояние раздела, с которого загрузился. Например, добавил ссылку в закладки браузера или наоборот, удалил что-нибудь ненужное, монтирую (разделы наверняка будет примонтированы автоматически при загрузке, тогда их сначала отмонтируем и перемонтируем в ручном режиме) тот раздел, который у меня теперь в RAM и меняю там файлы, которые нужно. У браузера просто копирую папку настроек, которые находятся в домашнем разделе (/home//"user"), у других программ - аналогично. Таким образом, все изменения в системе находятся под моим контролем и если мне что-то не нужно, то этого у меня не будет. Также, могу тестировать какие-нибудь программы, не опасаясь за целостность ОС (код для примера, на других компьютерах нужно указать другие значения диска):

  1. sudo mkdir /mnt/root
  2. sudo mount /dev/sdc3 -v /mnt/root

Добавлено(3) - 28.10.2020: Использую в течение нескольких дней такую систему. Очень всё быстро работает, постепенно начинаю привыкать к такой скорости, но всё равно, всё радует. Например, фильмы онлайн если смотреть, на youtube всё стало отзывчивей. Единственный недостаток, это долгая загрузка ОС. С моими почти 10GB, загружается 7 минут 10 секунд (специально секундомером мерил). Также приобретаю привычку, при нужных изменениях (закладки, изменения в настройках), записывать сразу изменения на диск, чтобы не забыть. Зато выключение компьютера почти мгновенное. На самом деле, со скоростью загрузки можно, наверное, что-то сделать... почистить логи, кеши, а может быть вообще всё поотключать, но это сделаю позднее. Кстати, с SSD-диска скорость загрузки должна быть выше. Не знаю, насколько, но должно быть существенно, так что имеет смысл подумать об этом...

Второй способ:
Нашёл его в обсуждении на ЛОРе. Оригинал кода здесь. Это уже изменённый мной скрипт. По умолчанию, он создавал rootfs в памяти только 10GB, чего естественно мне не хватало. Я поправил код и теперь root раздел в RAM занимает 80% от существующей памяти. Можно и меньше сделать, я думаю... Чтобы всё работало, перед выполнением этого кода, создайте в папке /mnt папку mnt - или измените пути в скрипте.

  1. # Script to copy / to tmpfs and continue boot from there
  2. # Do not run this from a child shell. Use ". ramify" or exec.
  3. # The shell running this script must be the only process on the system.
  4.  
  5. # Ensure this runs in /
  6. cd /
  7.  
  8. # Create and mount tmpfs file system for /
  9. mount -t tmpfs -o size=80% tmpfs mnt/mnt
  10.  
  11. # Copy everything from / filesystem to tmpfs
  12. # Tar will restore proper owners and permissions when run as root
  13. # FIXME: This is very slow because it reads / in many small pieces
  14. # TODO: Add --exclude to prevent copying unneeded stuff
  15. tar --one-file-system -c . | tar -C /mnt/mnt -x
  16.  
  17. # Move other mounts
  18. mount --move dev mnt/mnt/dev
  19. mount --move proc mnt/mnt/proc
  20. mount --move run mnt/mnt/run
  21. mount --move sys mnt/mnt/sys
  22.  
  23. # Create fstab with just new root file system
  24. sed -i '/^[^#]/d;' mnt/mnt/etc/fstab
  25. echo 'tmpfs / tmpfs defaults 0 0' >> mnt/mnt/etc/fstab
  26.  
  27. # Pivot root using instructions from pivot_root(8) man page
  28. cd mnt/mnt
  29. mkdir old_root
  30. pivot_root . old_root
  31.  
  32. # Old root can only be unmounted once sh running from old root
  33. # finishes. Continue startup normally using init.
  34. exec chroot . bin/sh -c "umount old_root ; exec sbin/init"

Третий способ:
Разработано специально для ArchLinux. Так что, скорее всего, не работает в других дистрибутивах (не протестирован) ramroot.

Ну и несколько скриншотов напоследок, по работающей системе, в conky видно, что десять с лишним гигабайт заполнены (раньше было меньше 1GB) в оперативной памяти и ещё десять свободны, используемые гигабайты - это именно наша rootfs: