Снизу мы положим SquashFS, а сверху tmpfs. При изменении файла из первого слоя он автоматически перейдет на второй, т.е. мы получим SquashFS доступную на запись. Думаю, результат стоит того, чтобы связаться с таким неблагодарным делом, как наложение патчей на ядро. Нам потребуются рутовые права. Сайт проекта AUFS
http://aufs.sourceforge.net
На сайте приведена инструкция по получению, установке и использованию AUFS.
Для получения исходников последовательно вводим три команды:
# git clone http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-standalone.git aufs2-standalone.git
# cd aufs2-standalone.git
# git checkout origin/aufs2.1-31
# cd aufs2-standalone.git
# git checkout origin/aufs2.1-31
В последней команде вместо суффикса 31 необходимо поставить версию ядра на которую Вы хотите получить патчи. Тогда не будет ошибок приведенных ниже. Т.о. чтобы получить патчи AUFS-2.1 для ядра 2.6.38 нужно выполнить команды:
$ git clone http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-standalone.git aufs2-standalone.git
$ cd aufs2-standalone.git
$ git checkout origin/aufs2.1-38
(прим. от 29.05.11)$ cd aufs2-standalone.git
$ git checkout origin/aufs2.1-38
После чего выполняем ls -l и смотрим чего получили:
bash-4.1# ls -l
итого 272
-rw-r--r-- 1 root root 17990 2010-12-01 13:09 COPYING
-rw-r--r-- 1 root root 210297 2010-12-01 13:10 ChangeLog
drwxr-xr-x 3 root root 72 2010-12-01 13:10 Documentation
-rw-r--r-- 1 root root 1181 2010-12-01 13:09 Makefile
-rw-r--r-- 1 root root 14067 2010-12-01 13:10 README
-rw-r--r-- 1 root root 3090 2010-12-01 13:10 aufs2-base.patch
-rw-r--r-- 1 root root 980 2010-12-01 13:10 aufs2-kbuild.patch
-rw-r--r-- 1 root root 9495 2010-12-01 13:10 aufs2-standalone.patch
-rw-r--r-- 1 root root 3033 2010-12-01 13:10 config.mk
drwxr-xr-x 2 root root 368 2010-12-01 13:10 design
drwxr-xr-x 3 root root 72 2010-12-01 13:10 fs
drwxr-xr-x 3 root root 72 2010-12-01 13:09 include
итого 272
-rw-r--r-- 1 root root 17990 2010-12-01 13:09 COPYING
-rw-r--r-- 1 root root 210297 2010-12-01 13:10 ChangeLog
drwxr-xr-x 3 root root 72 2010-12-01 13:10 Documentation
-rw-r--r-- 1 root root 1181 2010-12-01 13:09 Makefile
-rw-r--r-- 1 root root 14067 2010-12-01 13:10 README
-rw-r--r-- 1 root root 3090 2010-12-01 13:10 aufs2-base.patch
-rw-r--r-- 1 root root 980 2010-12-01 13:10 aufs2-kbuild.patch
-rw-r--r-- 1 root root 9495 2010-12-01 13:10 aufs2-standalone.patch
-rw-r--r-- 1 root root 3033 2010-12-01 13:10 config.mk
drwxr-xr-x 2 root root 368 2010-12-01 13:10 design
drwxr-xr-x 3 root root 72 2010-12-01 13:10 fs
drwxr-xr-x 3 root root 72 2010-12-01 13:09 include
Итак, мы имеем три патча и директории: fs, include, Documentation.
Делаем копию исходников ядра:
# cp -a /usr/src/linux-2.6.33.4 /usr/src/linux-2.6.33.4.my
Копируем исходники aufs в исходники ядра:
# cp -v *patch /usr/src/linux-2.6.33.4.my
# cp -a ./Documentation /usr/src/linux-2.6.33.4.my
# cp -a ./fs /usr/src/linux-2.6.33.4.my
# cp -a ./include/linux/aufs_type.h /usr/src/linux-2.6.33.4.my/include/linux/
# echo "unifdef-y += aufs_type.h" >> /usr/src/linux-2.6.33.4.my/include/linux/Kbuild
# cp -a ./Documentation /usr/src/linux-2.6.33.4.my
# cp -a ./fs /usr/src/linux-2.6.33.4.my
# cp -a ./include/linux/aufs_type.h /usr/src/linux-2.6.33.4.my/include/linux/
# echo "unifdef-y += aufs_type.h" >> /usr/src/linux-2.6.33.4.my/include/linux/Kbuild
Дело за малым. Переходим в каталог исходников ядра:
# cd /usr/src/linux-2.6.33.4.my
Правим ревизию ядра:
# sed -i 's/^EXTRAVERSION = .4/EXTRAVERSION = .4_my/' ./Makefile
Очищаем от результатов предыдущей компиляции:
# make mrproper
Ставим конфиг:
cp -v /boot/config-generic-2.6.33.4 ./.config
Накладываем патчи aufs:
# patch -p1 -i aufs2-kbuild.patch
patching file fs/Kconfig
Hunk #1 succeeded at 44 with fuzz 2 (offset -143 lines).
patching file fs/Makefile
patching file include/linux/Kbuild
# patch -p1 -i aufs2-base.patch
patching file fs/namei.c
Hunk #1 succeeded at 1207 (offset -12 lines).
patching file fs/splice.c
Hunk #1 succeeded at 1053 (offset -4 lines).
Hunk #2 succeeded at 1085 (offset 1 line).
patching file include/linux/namei.h
Hunk #1 succeeded at 73 with fuzz 2 (offset -2 lines).
patching file include/linux/splice.h
# patch -p1 -i aufs2-standalone.patch
patching file fs/file_table.c
Hunk #1 succeeded at 34 (offset 2 lines).
Hunk #2 succeeded at 346 (offset -29 lines).
patching file fs/inode.c
Hunk #1 succeeded at 85 with fuzz 1.
patching file fs/namei.c
Hunk #1 succeeded at 349 (offset 12 lines).
Hunk #2 succeeded at 1205 (offset -24 lines).
Hunk #3 succeeded at 1264 (offset 12 lines).
patching file fs/namespace.c
patching file fs/notify/group.c
patching file fs/notify/inode_mark.c
patching file fs/open.c
Hunk #1 succeeded at 226 with fuzz 2 (offset 5 lines).
patching file fs/splice.c
Hunk #1 succeeded at 1077 (offset -3 lines).
Hunk #2 succeeded at 1107 (offset 1 line).
patching file security/commoncap.c
Hunk #1 succeeded at 946 (offset -68 lines).
patching file security/device_cgroup.c
Hunk #1 succeeded at 514 (offset 1 line).
patching file security/integrity/ima/ima_main.c
Hunk #1 succeeded at 273 (offset -51 lines).
patching file security/security.c
Hunk #1 succeeded at 404 (offset 18 lines).
Hunk #3 succeeded at 420 (offset 18 lines).
Hunk #5 succeeded at 438 (offset 18 lines).
Hunk #7 succeeded at 478 with fuzz 2 (offset 38 lines).
Hunk #9 succeeded at 565 (offset 38 lines).
misordered hunks! output would be garbled
Hunk #11 FAILED at 657.
1 out of 11 hunks FAILED -- saving rejects to file security/security.c.rej
patching file fs/Kconfig
Hunk #1 succeeded at 44 with fuzz 2 (offset -143 lines).
patching file fs/Makefile
patching file include/linux/Kbuild
# patch -p1 -i aufs2-base.patch
patching file fs/namei.c
Hunk #1 succeeded at 1207 (offset -12 lines).
patching file fs/splice.c
Hunk #1 succeeded at 1053 (offset -4 lines).
Hunk #2 succeeded at 1085 (offset 1 line).
patching file include/linux/namei.h
Hunk #1 succeeded at 73 with fuzz 2 (offset -2 lines).
patching file include/linux/splice.h
# patch -p1 -i aufs2-standalone.patch
patching file fs/file_table.c
Hunk #1 succeeded at 34 (offset 2 lines).
Hunk #2 succeeded at 346 (offset -29 lines).
patching file fs/inode.c
Hunk #1 succeeded at 85 with fuzz 1.
patching file fs/namei.c
Hunk #1 succeeded at 349 (offset 12 lines).
Hunk #2 succeeded at 1205 (offset -24 lines).
Hunk #3 succeeded at 1264 (offset 12 lines).
patching file fs/namespace.c
patching file fs/notify/group.c
patching file fs/notify/inode_mark.c
patching file fs/open.c
Hunk #1 succeeded at 226 with fuzz 2 (offset 5 lines).
patching file fs/splice.c
Hunk #1 succeeded at 1077 (offset -3 lines).
Hunk #2 succeeded at 1107 (offset 1 line).
patching file security/commoncap.c
Hunk #1 succeeded at 946 (offset -68 lines).
patching file security/device_cgroup.c
Hunk #1 succeeded at 514 (offset 1 line).
patching file security/integrity/ima/ima_main.c
Hunk #1 succeeded at 273 (offset -51 lines).
patching file security/security.c
Hunk #1 succeeded at 404 (offset 18 lines).
Hunk #3 succeeded at 420 (offset 18 lines).
Hunk #5 succeeded at 438 (offset 18 lines).
Hunk #7 succeeded at 478 with fuzz 2 (offset 38 lines).
Hunk #9 succeeded at 565 (offset 38 lines).
misordered hunks! output would be garbled
Hunk #11 FAILED at 657.
1 out of 11 hunks FAILED -- saving rejects to file security/security.c.rej
Упс... В последний раз что-то пошло не так. Но тем не менее ядро собирается, значит, продолжаем.
Корректируем конфиг:
# make oldconfig
Осталось поправить конфигурацию сборки ядра:
# make menuconfig
Файловую систему SquashFS нужно будет собрать монолитно, AUFS можно модулем, но есть смысл собрать ее также монолитно.
После сборки ядра и модулей, используя слакбилды, получаем два пакета. В моем случае это были:
kernel-generic-2.6.33.4_32.2-i486-1.txz
kernel-modules-2.6.33.4_32.2-i486-1.txz
Осталось все это заставить заработать на реальной системе. Качаем recovery-версию:
# cd /tmp
# wget http://sourceforge.net/projects/slavanka/files/SlavankaOS/slavanka-recovery-1.iso
# wget http://sourceforge.net/projects/slavanka/files/SlavankaOS/slavanka-recovery-1.iso
Монтируем и копируем содержимое:
# mount slavanka-recovery-1.iso /mnt/cdrom -o loop
# rm -r /tmp/livecd
# cp -a /mnt/cdrom /tmp/livecd
# umount /mnt/cdrom
# rm -r /tmp/livecd
# cp -a /mnt/cdrom /tmp/livecd
# umount /mnt/cdrom
Переходим в целевой каталог и распаковываем образ initrd
cd /tmp/livecd
sh ./op
sh ./op
удаляем 32-битное ядро и модули
# rm ./linux32
# rm -r ./1/lib/modules
# rm -r ./1/lib/modules
Ставим наше ядрышко:
# installpkg -root ./1 /tmp/kernel-generic-2.6.33.4_32.2-i486-1.txz
# installpkg -root ./1 /tmp/kernel-modules-2.6.33.4_32.2-i486-1.txz
# installpkg -root ./1 /tmp/kernel-modules-2.6.33.4_32.2-i486-1.txz
Теперь самое главное: как наш перпетум мобиле завести. У меня не получилось установить aufs сразу на корень системного раздела, не используя промежуточное монтирование из busybox. Зато не вызвало проблем установить aufs на корневые каталоги /etc, /var, /root и т.д. Делаем так:
# mkdir -p ./1/opt/{etc,var,tmp,root}
Далее открываем нашим любимым текстовым радактором nano первый инициализационный скрипт rc.S
# nano -w ./1/etc/rc.d/rc.S
...и видим там такие строки:
#!/bin/sh
#
# /etc/rc.d/rc.S: System initialization script.
#
# Mostly written by: Patrick J. Volkerding,
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin
# Try to mount /proc:
/sbin/mount -v proc /proc -n -t proc 2> /dev/null
# Mount sysfs next, if the kernel supports it:
if [ -d /sys ]; then
if grep -wq sysfs /proc/filesystems ; then
if ! grep -wq sysfs /proc/mounts ; then
/sbin/mount -v sysfs /sys -n -t sysfs
fi
fi
fi
#
# /etc/rc.d/rc.S: System initialization script.
#
# Mostly written by: Patrick J. Volkerding,
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin
# Try to mount /proc:
/sbin/mount -v proc /proc -n -t proc 2> /dev/null
# Mount sysfs next, if the kernel supports it:
if [ -d /sys ]; then
if grep -wq sysfs /proc/filesystems ; then
if ! grep -wq sysfs /proc/mounts ; then
/sbin/mount -v sysfs /sys -n -t sysfs
fi
fi
fi
Эти команды - первое, что делает операционная система после инициализации ядра и запуска первого процесса init. Видно, что перво-наперво система монтирует виртуальные файловые системы proc и sysfs. Полагаю, это тот самый момент, когда наши RO каталоги следует сделать доступными на запись. Вписываем следующие строки:
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/etc
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/var
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/tmp
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/root
/sbin/mount -t aufs -o dirs=/opt/etc:/etc=ro none /etc
/sbin/mount -t aufs -o dirs=/opt/var:/var=ro none /var
/sbin/mount -t aufs -o dirs=/opt/tmp:/tmp=ro none /tmp
/sbin/mount -t aufs -o dirs=/opt/root:/root=ro none /root
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/var
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/tmp
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/root
/sbin/mount -t aufs -o dirs=/opt/etc:/etc=ro none /etc
/sbin/mount -t aufs -o dirs=/opt/var:/var=ro none /var
/sbin/mount -t aufs -o dirs=/opt/tmp:/tmp=ro none /tmp
/sbin/mount -t aufs -o dirs=/opt/root:/root=ro none /root
Дело сделано. Сохраняем файл и выходим из редактора. Остальное - дело техники. Удаляем лишние модули ядра:
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/; rm -rv `ls -1 ./ |grep -vE "fs|drivers|net"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/fs/; rm -rv `ls -1 ./ |grep -vE "mbcache|nls|jbd|jbd2|fuse|ext2|ext3|ext4|isofs|reiserfs|fat"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/fs/nls/; rm -rv `ls -1 ./ |grep -vE "utf8|koi8|cp866"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/drivers/; rm -rv `ls -1 ./ |grep -vE "acpi|dma|i2c|rtc|usb|net|hwmon|thermal|watchdog"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/drivers/net; rm -rv `ls -1 ./ |grep -vE "ko|e1000"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/net/; rm -rv `ls -1 ./ |grep -vE "ipv4|netfilter"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/fs/; rm -rv `ls -1 ./ |grep -vE "mbcache|nls|jbd|jbd2|fuse|ext2|ext3|ext4|isofs|reiserfs|fat"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/fs/nls/; rm -rv `ls -1 ./ |grep -vE "utf8|koi8|cp866"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/drivers/; rm -rv `ls -1 ./ |grep -vE "acpi|dma|i2c|rtc|usb|net|hwmon|thermal|watchdog"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/drivers/net; rm -rv `ls -1 ./ |grep -vE "ko|e1000"`;cd -
# cd ./1/lib/modules/2.6.33.4_32.2/kernel/net/; rm -rv `ls -1 ./ |grep -vE "ipv4|netfilter"`;cd -
Копируем новое ядро в директорию загрузчика и удаляем /boot каталог:
# cp -v ./1/boot/vmlinuz-generic-2.6.33.4_32.2 ./linux32
# rm -r ./1/boot
# rm -r ./1/boot
Удаляем теперь уже не нужную опцию монтирования /usr директории в fstab:
# sed -i "1d" ./1/etc/fstab
Сжимаем системный раздел:
# cd ./1
# mksquashfs . ../image
# cd ..
# rm -r ./1
# mksquashfs . ../image
# cd ..
# rm -r ./1
Для полноты картины поправим 64-битный образ:
# sh ./op
# rm -r ./1/lib/modules/2.6.33.4_32
# sh ./cl
# rm -r ./1/lib/modules/2.6.33.4_32
# sh ./cl
Последний шаг. Правим в isolinux.cfg строку в секции linux32:
APPEND vga=normal initrd=rootfs.cgz root=/dev/ram0 rw vt.default_utf8=1 acpi_enforce_resources=lax
на
APPEND vga=normal initrd=image root=/dev/ram0 ro looptype=squashfs ramdisk_size=54000 vt.default_utf8=1 acpi_enforce_resources=lax
Дело в шляпе. Запускаем:
# sh ./mk
...и получаем образ /tmp/mycd.iso на выходе.
В итоге таких нехитрых действий мы уменьшили потребеление оперативки LiveCD в два раза с 256Мб до 128Мб, не теряя на функционале, не жертвуя содержимым, лишь используя более грамотную организацию корневого раздела LiveCD.
-------------- Д О П О Л Н Е Н И Е от 9 марта 2012 -----------------------------
Сейчас, спустя более года может показаться странным, к чему такие сложности, если у Junjiro Okajima лежит готовое ядро с наложенными патчами. Бери и собирай. Дело в том, что тогда в ядре еще не было поддержки сверхсильного сжатия XZ, LZMA для SquashFS и на ядро приходилось последовательно накладывать патчи LZMA for SqushFS, а затем AUFS. На тот момент самым простым для меня оказалось взять готовое ядро с LZMA SquashFS и затем наложить патчти AUFS. Сейчас с появлением сжатия XZ для SquashFS в ядре нет никакой необходимости для таких сложностей. Время самураев ушло :)
С выходом ядра третьей версии Junjiro Okajima выпустил AUFS также третьей версии и перевел git репозиторий третьей версии на sourceforge.net
читаем инструкцию Junjiro:
$ git clone --reference /your/linux/git/tree \и соответственно выполняем
git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-linux.git \
aufs3-linux.git
- if you don't have linux GIT tree, then remove "--reference ..."
$ cd aufs3-linux.git
$ git checkout origin/aufs3.0
$ cd /tmp
$ git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-linux.git linux-3.2.9.aufs64
$ cd linux-3.2.9.aufs64
$ git checkout origin/aufs3.2
Обратите внимание на последнюю цифру. В инструкции написано 3.0, а нам нужно набрать 3.2 потому что к у нас ядро 3.2 а не 3.0. В итоге у нас оказываются готовые исходники ядра 3.2.0 и дело за малым осталось наложить минорный патч. На сегодня это 3.2.9$ git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-linux.git linux-3.2.9.aufs64
$ cd linux-3.2.9.aufs64
$ git checkout origin/aufs3.2
$ wget http://www.kernel.org/pub/linux/kernel/v3.0/patch-3.2.9.bz2
$ bzcat patch-3.2.9.bz2 | patch -p1
$ bzcat patch-3.2.9.bz2 | patch -p1
вот и все сложности, дальше собираем обычным способом.
добавил небольшое дополнение в свете нынешних реальностей
ОтветитьУдалитьСтатья информативная и нужная. Спасибо автору за работу.
ОтветитьУдалитьПосле добавления патча AUFS в конфигурации ядра появляются параметры
ОтветитьУдалитьMaximum number of branches
Detect direct branch access (bypassing aufs)
NFS-exportable aufs
Readdir in userspace
support for /proc/maps and lsof(1)
Respect the attributes (mtime/ctime mainly) of special files
Show whiteouts
Ramfs (initramfs/rootfs) as an aufs branch
Fuse fs as an aufs branch
Hfsplus as an aufs branch
Debug aufs
По умолчанию почти все параметры отключены. Нужно ли установить их в yes или лучше всё оставить как есть?
>По умолчанию почти все параметры отключены. Нужно ли установить их в yes или лучше всё оставить как есть?
Удалитьзависит от ваших задач)
скрин с моими опциями:
http://3.bp.blogspot.com/-YOxFn93MM48/UU0L6Ku7GZI/AAAAAAAAAHc/g76N0qB0Wck/s1600/kernel.png
Присоединяюсь к вопросу. Что будет, если включить все параметры (кроме Debug, с ним ясно)? Если среди них нет таких, могущих повлиять на стабильность системы или сильно замедлить скорость работы, хочу попробовать включить всё, кроме debug.
УдалитьЯдро с поддержкой aufs мне нужно для своей сборки, на основе Linux Mint 17.3 Mate.
Нигде нет внятного объяснения по этим опциям aufs.
ничего страшного не будет. Но мне они, по большей части, кажутся бесполезными. Для чего например мне fuse файловые системы монтировать в качестве слоя aufs? FUSE ФС - это всякие превдо ФС типа ntfs-3g, webdav, sshfs ftpfp и пр. Это же очень тормозные штуки. Зачем? c hfsplus полагаю тоже все не просто. "show whiteouts" - это такие файлики, которые aufs создает каогда удаляется какой-либо файл из RO слоя/branch ФС в этом служебном файле, помечает удаленный файл как несуществующий. Вам обязательно натыкаться на эти файлики? Ну и т.д
Удалить