Файловая система (и ОС) полностью в RAM (решено)

Сделал систему загружаемую полностью в оперативную память. Плюсы:

  1. Неубиваемость, пока есть электричество.
  2. Всё очень быстро (быстрее чем SSD), ну это понятно, всё в оперативной памяти работает, к диску обращений нет (в том числе, просмотр онлайн-фильмов, youtube, да даже просто сайты открываются мгновенно).
  3. Неизменность системы, можно устанавливать что хочешь, пробовать какие угодно программы, а потом просто перезагрузиться (если ничего не нужно).
  4. Все изменения делаешь вручную, полностью контролируя систему.

Минусы:

  1. Нужные изменения приходится делать вручную (добавил закладку в браузере, копируешь изменённые файлы на диск), но так как полная копия системы находится на диске, это не сложно.
  2. Долгое время загрузки ОС. Для 8-9GB это 7 минут. Но привыкнуть можно, плюс можно предпринять необходимые шаги для уменьшения места занимаемого разделом (логи и тд.)…
  3. Нет решения для Calculate Linux.

Вот моё решение, основанное на заметках 2011 и 2015 годов, но для Debian-подобных дистрибутивов. Там для создания initrd используется mkinitrd, а в Calculate Linux для создания этого файла используется или dracut или genkernel. Куда вставлять и каким будет код, мне не ясно. Кто может помочь?

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

    checkfs "${ROOT}" root "${FSTYPE}"

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

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

    #checkfs "${ROOT}" root "${FSTYPE}"

	# Mount root
	# shellcheck disable=SC2086
	mkdir /ramboottmp
	mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /ramboottmp
	mount -t tmpfs -o size=100% none ${rootmnt}
	cd ${rootmnt}
	cp -rfa /ramboottmp/* ${rootmnt}
	umount /ramboottmp

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

mkinitramfs -o /boot/initrd.img-ramboot

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

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

и меняем на:

none / tmpfs defaults 0 0

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

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' {
	load_video
	insmod gzio
	if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos3'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos3 --hint-efi=hd2,msdos3 --hint-baremetal=ahci2,msdos3  35378250-4a4b-4405-b956-c5f546a970e2
	else
	  search --no-floppy --fs-uuid --set=root 35378250-4a4b-4405-b956-c5f546a970e2
	fi
	echo	'Loading Linux 4.19.0-12-amd64 ...'
	linux	/boot/vmlinuz-4.19.0-12-amd64 root=UUID=35378250-4a4b-4405-b956-c5f546a970e2 ro  quiet hush
	echo	'Loading initial ramdisk ...'
	initrd	/boot/initrd.img-4.19.0-12-amd64
}

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

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' {
	load_video
	insmod gzio
	if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos3'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos3 --hint-efi=hd2,msdos3 --hint-baremetal=ahci2,msdos3  35378250-4a4b-4405-b956-c5f546a970e2
	else
	  search --no-floppy --fs-uuid --set=root 35378250-4a4b-4405-b956-c5f546a970e2
	fi
	echo	'Loading Linux 4.19.0-12-amd64 ...'
	linux	/boot/vmlinuz-4.19.0-12-amd64 root=UUID=35378250-4a4b-4405-b956-c5f546a970e2 ro  quiet hush
	echo	'Loading initial ramdisk ...'
	initrd	/boot/initrd.img-ramboot
}
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' {
	load_video
	insmod gzio
	if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos3'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos3 --hint-efi=hd2,msdos3 --hint-baremetal=ahci2,msdos3  35378250-4a4b-4405-b956-c5f546a970e2
	else
	  search --no-floppy --fs-uuid --set=root 35378250-4a4b-4405-b956-c5f546a970e2
	fi
	echo	'Loading Linux 4.19.0-12-amd64 ...'
	linux	/boot/vmlinuz-4.19.0-12-amd64 root=UUID=35378250-4a4b-4405-b956-c5f546a970e2 ro  quiet hush
	echo	'Loading initial ramdisk ...'
	initrd	/boot/initrd.img-4.19.0-12-amd64
}

Также скажу, что решение меня полностью устраивает. Даже долгая загрузка не проблема. Главное, что всё быстро и всё под контролем. Только как это адаптировать под Calculate Linux?

1 Like

Я не как сейчас. А пару лет назад на на gentoo livecd достаточнo было передать ядру опцию docache https://wiki.gentoo.org/wiki/Handbook:AMD64/Blocks/Booting

Также можно посмотреть как сделано было на systemrescuecd которая еще была основана на gentoo версия 5.3.1 точно она https://cloud.mail.ru/public/7yNs/4DFtKiGAS (сохранял для себя)
С мылору не скачать перезалил на яндекс https://yadi.sk/d/5CSt7jsCIDNbyQ

Тут исходники https://sourceforge.net/p/systemrescuecd/code/ci/master/tree/ но наверно это уже версия которая на рач линакс основана

Удачи в ваших опытах

Забыл сказать у systemrescuecd загрузчик lilo

Спасибо, попробую посмотреть и что-то сделать. Скачал ваш изошник systemrescuecd, буду разбираться. Пока нашёл такой код:

# Script to copy / to tmpfs and continue boot from there
# Do not run this from a child shell. Use ". ramify" or exec.
# The shell running this script must be the only process on the system.

# Ensure this runs in /
cd /

# Create and mount tmpfs file system for /
mount -t tmpfs tmpfs mnt

# Copy everything from / filesystem to tmpfs
# Tar will restore proper owners and permissions when run as root
# FIXME: This is very slow because it reads / in many small pieces
# TODO: Add --exclude to prevent copying unneeded stuff
tar --one-file-system -c . | tar -C /mnt -x

# Move other mounts
mount --move dev mnt/dev
mount --move proc mnt/proc
mount --move run mnt/run
mount --move sys mnt/sys

# Create fstab with just new root file system
sed -i '/^[^#]/d;' mnt/etc/fstab
echo 'tmpfs / tmpfs defaults 0 0' >> mnt/etc/fstab

# Pivot root using instructions from pivot_root(8) man page
cd mnt
mkdir old_root
pivot_root . old_root

# Old root can only be unmounted once sh running from old root
# finishes. Continue startup normally using init.
exec chroot . bin/sh -c "umount old_root ; exec sbin/init"

Оригинал кода и обсуждение на ЛОРе по этой теме. Это скрипт уже в работающей системе копирует всё в RAM и переносит туда root.

Но, к сожалению, он почему-то ограничен 10-ю гигабайтами, а RAM у меня занимает больше и он заканчивает свою работу, а я в системе ничего не могу сделать, памяти не хватает. Хотя оперативная ещё есть, но примонтировано для RAM-диска только 10GB и где это изменить, я не вижу.

Добавлено:
Да, этот код рабочий на 100%. Просто нужны небольшие изменения. Спасибо за внимание и может быть кому-нибудь понадобится. Привожу рабочий код (дополнительно создайте в папке /mnt папку mnt или измените пути):

# Script to copy / to tmpfs and continue boot from there
# Do not run this from a child shell. Use ". ramify" or exec.
# The shell running this script must be the only process on the system.

# Ensure this runs in /
cd /

# Create and mount tmpfs file system for /
mount -t tmpfs -o size=80% tmpfs mnt/mnt

# Copy everything from / filesystem to tmpfs
# Tar will restore proper owners and permissions when run as root
# FIXME: This is very slow because it reads / in many small pieces
# TODO: Add --exclude to prevent copying unneeded stuff
tar --one-file-system -c . | tar -C /mnt/mnt -x

# Move other mounts
mount --move dev mnt/mnt/dev
mount --move proc mnt/mnt/proc
mount --move run mnt/mnt/run
mount --move sys mnt/mnt/sys

# Create fstab with just new root file system
sed -i '/^[^#]/d;' mnt/mnt/etc/fstab
echo 'tmpfs / tmpfs defaults 0 0' >> mnt/mnt/etc/fstab

# Pivot root using instructions from pivot_root(8) man page
cd mnt/mnt
mkdir old_root
pivot_root . old_root

# Old root can only be unmounted once sh running from old root
# finishes. Continue startup normally using init.
exec chroot . bin/sh -c "umount old_root ; exec sbin/init"

В кальке раньше можно было ставить систему в squashfs + aufs. Попробуйте: основная система в памяти в сквоше, а изменения в aufs. При выключении или руками можно объединять слои и в следующий раз все изменения будут в системе.

А по подробнее как это сделать ?

Да, это можно было бы сделать, но нет ни готовых примеров, ни рабочего кода. Надо искать… Ну чтож поищем. Ещё есть zram, так как Calculate перешёл на него, то у меня показывает 41.1 GB свопа (при оперативной памяти в 20GB), надо бы его как-то использовать…

На форуме были примеры, как с этим работать, но тогда этот функционал был в утилитах и было достаточно просто делать.

Протестировал скрипт на SSD-диске. Отличные результаты получились. Примерно 2.5 минуты на загрузку 6GB Calculate Linux в память. По сравнению с HDD выигрыш составил больше чем в два с половиной раза.

Так что, это интересный способ работы с системой. По сравнению с initrd, более простой и понятный:

  1. Не надо делать два пункта меню в загрузчике, вообще никак не надо вмешиваться в загрузку системы.
  2. Можно обновиться, изменить какие угодно данные заранее, а потом перейти на режим в памяти.
  3. Сохранение данных полностью прозрачное (не система пишет что-то в какой-то файл, а ты сам решаешь, что сохранять, а что - нет). Сохранение данных простое потому, что копия находится на диске и ты туда можешь скопировать все изменения, которые произвёл в системе, которая в оперативной памяти, более того, ты можешь выбрать, что сохранять, а что не нужно сохранять.
  4. Перед загрузкой решаются все проблемные моменты (например, решил проверить, как пройдёт установка программы, установил её, не понравилось, её даже не надо удалять, после перезагрузки её не будет).

Осталось немного доработать скрипт. Изначально он монтировал всё в папку /mnt, но у меня она занята, поэтому используется другая. Но если один раз создашь эту папку, потом надо удалять. Или убрать создание в начале скрипта или сделать её удаление в конце скрипта, когда она уже не нужна.

По идее можно было бы написать обратный скрипт, сохранёнку, которая бы все изменения сохраняла обратно на диск, но надо ли? Теряется идея контрольного сохранения только того, что нужно, хотя, иногда может быть нужно, если изменения масштабные и те, которые необходимы для последующей работы… Можно даже копировать обратно только /home директорию. Или сделать какой-то гибридный режим.

Добавлено:
Установил CLDX на SSD-диск, раздел которого отформатировал в сжатую файловую систему btrfs. В результате, у меня rootfs стала занимать около 6.5GB (при обычной установке CLDX занимает около 11-12GB). При использовании скрипта, она конечно распаковывается в память. Но происходит это меньше, чем за минуту. Очень быстро…

Сама работа со сжатого раздела (на SSD) вроде нормально всё, но бывает немного притормаживает при просмотре видео. А вот как способ уменьшить время распаковки в ОЗУ - этот способ просто идеален. Быстрее некуда.