google web font

пятница, 2 октября 2009 г.

Покормил питомца: сделал squashfs под portage :-)

Как я уже выяснил раньше, мой Gentoo у меня существует как домашний питомец, которого нужно кормить и с которым нужно играть. Сегодня я то ли покормил его, то ли поиграл с ним, не понятно, однако теперь у меня /usr/portage лежит в образе squashfs, aufs2 отвечает за то, чтобы можно было делать emerge --sync, а найденный в интернетах init-script сохраняет результаты синьки и монтирует всю эту радость при загрузке.

Надо отметить, что рецепт, найденный в интернетах, предлагал использовать некоторым образом морально устаревшую unionfs. Из-за такого совета пришлось размаскировать лишний пакет, который вскоре был замаскирован обратно. Итак, план действий.


Разумеется, нужно в первую очередь:
 # USE="kernel-patch" emerge -p sys-fs/squashfs-tools sys-fs/aufs2
и только потом нужно задуматься, для чего это, собственно, надо. После всех этих действий скорость выполнения emerge -pDNu world (при ещё незакешированных файлах) выросла в 3-4 раза. И это не предел, конечно. Можно увеличить эту скорость другими средствами, но я за это не брался и не собираюсь в ближайшем будущем, мне хватило результата. После установки пакетов нужно перекомпилять ядро и перезагрузиться.

На самом деле, сначала я хотел городить натурально велосипед, да ещё с квадратными колёсами: я начал экспериментировать с tmpfs, задумался о том, как при загрузке вгонять на неё образ и прочей ерунде. Через некоторое время мне начало казаться, что на tmpfs образ загонять сложновато (я додумался только до tar) и в голову пришёл ramdisk. В общем, жуть. К счастью, у меня хватило фантазии задать вопрос на форуме, где мне дали ссылку на вариант со squashfs. Ознакомившись с предлагаемыми материалами я понял, что хороший сисадмин должен знать много файловых систем, что он бы даже не подумал про tmpfs и что хорошо, что я не сисадмин. В общем, нужно сделать squashfs-образ директории /usr/portage, примонтировать его в /usr/portage, создать директорию для записи изменений при emerge --sync и смонтировать эту директорию туда же, используя unionfs/aufs. Сохраняются изменения путём создания нового образа. Итак, по пунктам.

Создаём образ

 # mksquashfs /usr/portage/ /var/tmp/portage.sqfs -no-duplicates
При большом желании, можно его пробно примонтировать и посмотреть на ускорение. В листинге присутствует сброс дискового кеша:
 # mount -rt squashfs -o loop,nodev,noexec /var/tmp/portage.sqfs /usr/portage
 # sync && echo 3 > /proc/sys/vm/drop_caches
 # time emerge -pDNu world
Как я понимаю, всё прошло гладко, иначе я не помощник. Дальше создаём директорию для записи. Если есть ненужная оперативная память, можно сделать директорию в /dev/shm/ (туда примонтирована tmpfs, если gentoo устанавливался по рекомендациям из хендбука) либо сделать где-нибудь в /tmp и примонтировать туда tmpfs (mount -t tmpfs some_label /tmp/portage-rw). Если лишней оперативы нет, то директорию надо делать где-нибудь в /tmp и монтировать в неё ничего не нужно. Хотя init-скрипт умеет эту директорию сам создавать, я предлагаю сделать это для теста
 # mount -t aufs -o nodev,noexec,dirs=/tmp/portage-rw=rw:/usr/portage/=ro portaufs /usr/portage/
Если и тут всё хорошо, то можно браться за

init-скрипт

Собственно, предлагаю такой:
 $ cat /etc/init.d/squashfs_portage
#!/sbin/runscript
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

source /etc/make.conf
SQFS_CUR="$SQFS_DIRNAME/portage.sqfs"
SQFS_NEW="$SQFS_DIRNAME/portage-current.sqfs"
SQFS_OLD="$SQFS_DIRNAME/portage-old.sqfs"
[ ! $PORTDIR ] && PORTDIR="/usr/portage/"
DEF_RW="/dev/shm/.portage-rw"

depend() {
        need localmount
}

start() {
        ebegin "Mounting read-only Portage squashfs image"
        [ -f $SQFS_CUR ] || {
                eend 1
                eerror "No squashfs image in $SQFS_CUR. Create image first!"
                einfo "You may use 'mksquashfs $PORTDIR $SQFS_CUR -no-duplicates' for it"
                return 1
        }
        mount -rt squashfs -o loop,nodev,noexec $SQFS_CUR $PORTDIR
        retval=$?
        eend $retval
        [ $retval -ne 0 ] && return $retval

        ebegin "Mounting read-write Portage image with unionfs (aufs2)"
        if [ ! $PORTAGE_RW ]
        then
                einfo "  mounted in tmpfs (actually RAM)"
                PORTAGE_RW="${DEF_RW}"
        fi
        [ -d $PORTAGE_RW ] || mkdir -p $PORTAGE_RW
        chmod 0750 $PORTAGE_RW
        chown portage:portage $PORTAGE_RW
        mount -t aufs -o nodev,noexec,dirs=$PORTAGE_RW=rw:$PORTDIR=ro portAufs $PORTDIR
        eend $?
}

stop() {
        ebegin "Updating portage image"
        [ ! $PORTAGE_RW ] && PORTAGE_RW="${DEF_RW}"
        if [ ! -z `ls -A $PORTAGE_RW | grep -v '.wh..wh.' | head -n1` ]
        then
                einfo "  Syncing the tree"
                mv -f $SQFS_NEW $SQFS_OLD
                mksquashfs $PORTDIR $SQFS_NEW -no-duplicates 2>/dev/null
                retval=$?
                ln -sf $SQFS_NEW $SQFS_CUR
        else
                einfo "  Nothing to do"
                retval=0
        fi
        eend $retval

        ebegin "Unmounting Portage"
        umount -t aufs  $PORTDIR
        umount -t squashfs $PORTDIR
        rm -rf $PORTAGE_RW
        eend 0
}
Напоминаю про важную возможность системы инициализации Gentoo: у каждого init-скрипта есть соответствующий файл настройки. Вот такой нужен нам
 # cat /etc/conf.d/squashfs_portage
# /etc/conf.d/squash_portage

# SQFS_DIRNAME points to the directory that will contain the sqfs
# images, recommended value is /var/tmp
SQFS_DIRNAME=/var/tmp

# Leave PORTAGE_RW empty for use with tmpfs, a ram-based filesystem,
# This is recommended unless you are short of RAM
PORTAGE_RW=""

После этого нужно всё отмонтировать и проверить, как скрипт работает. Это легко.
 # umount /usr/portage
 # umount /usr/portage
 # chmod +x /etc/init.d/squashfs_portage
 # /etc/init.d/squashfs_portage start
 # /etc/init.d/squashfs_portage stop
 # /etc/init.d/squashfs_portage start
 # rc-update add squashfs_portage default
Будет немного интересно, но не сильно. При остановке скрипт создаст новый образ - так будет потом каждый раз, если дерево обновится. Поскольку заканчивается всё вот так неожиданно банально, я добавил такую строчку в /etc/fstab
var_tmp_portage    /var/tmp/portage    tmpfs    defaults    0 0
это чтобы компилялось чуть быстрее. Памяти у меня навалом, всё равно простаивает.

Комментариев нет:

Отправить комментарий