mercoledì 19 dicembre 2007

Portage: velocizzare e snellire!

Riprendo la guida riportata qui su come creare un'immagine compressa del portage tree allo scopo di far scendere l'occupazione di spazio su disco da quasi 1GB a circa 50MB.
L'unica differenza rispetto alla guida citata è l'utilizzo di aufs al posto di unionfs.

  • Opzioni Kernel
Controlliamo che nel kernel siano attivate le opzioni seguenti:

Device Drivers --->
Block Devices --->
<M> Loopback device support
File systems --->
Miscellaneous Filesystems --->
<M> SquashFS

Possono essere compilate come moduli o staticamente nel kernel; se scegliete di compilarle come moduli, allora sarà necessario aggiungere

loop
squashfs

al file /etc/modules.autoload.d/kernel-2.6.

  • Pacchetti da installare
Per squashfs:
emerge -av sys-fs/squashfs-tools

Per quanto riguarda aufs, l'ebuild sys-fs/aufs si può trovare nel layer sunrise. Tuttavia la compilazione potrebbe fallire a seconda del kernel che viene usato; se avete tale tipo di problema potete provare a prelevare la versione più recente (ad esempio da http://dev.gentooexperimental.org/~tommy/) e compilarla a mano con i soliti comandi make e make install. Verrà così compilato e installato il modulo aufs.

  • Caricare i moduli
modprobe squashfs
modprobe aufs
modprobe loop

Ricordarsi di aggiungere anche aufs al file /etc/modules.autoload.d/kernel-2.6.

  • Modifica del file make.conf
Inseriamo nel file /etc/make.conf le variabili d'ambiente necessarie:

PORTDIR = "/usr/portage"
DISTDIR = "/var/distfiles"

La variabile PORTDIR in effetti punta alla posizione di default, che è la stessa posizione nella quale verrà montata l'immagine compressa. Ovviamente può essere sostituita con il path che si desidera, a patto di modificare anche i successivi script.
E' importante invece settare la variabile DISTDIR in quanto ci permette di spostare la directory dei pacchetti scaricati al di fuori dell'albero di portage, in modo da non includerla nell'immagine compressa. Anche qui possiamo farla puntare al path che più ci piace.

  • Creazione dell'immagine

mkdir /var/portage
mksquashfs /usr/portage /var/portage/portage-current.sqfs -check_data
ln -sf /var/portage/portage-current.sqfs /var/portage/portage.sqfs

Se tutto va per il verso giusto, possiamo rimuovere la directory di portage:
rm -rf /usr/portage/*
I meno avventurosi possono procedere ad una semplice rinominazione per il momento... :)

  • File di configurazione

Creiamo il file /etc/conf.d/squash_portage contenente il seguente codice:
# /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/portage"

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


  • Script di avvio/arresto
Ora creiamo gli script che serviranno per automatizzare il tutto. Quello riportato nella guida a cui faccio riferimento funziona perfettamente, ma ha un solo difetto: l'immagine di portage viene ricreata ad ogni arresto del sistema, anche se non è stato modificato alcun file. C'è da dire che lo script è stato poi notevolmente migliorato (vedi questa discussione), rendendolo decisamente più complesso e adatto alla gestione di altre directory, non solo di portage.
Io invece propongo una modifica più semplice: in fase di arresto, lo script non si preoccuperà di ricreare l'immagine compressa del portage tree. L'aggiornamento di questo verrà gestito tramite uno script da richiamare al posto di emerge --sync.

Questo è lo script /etc/init.d/squash_portage come da me modificato:

#!/sbin/runscript
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
#
# /etc/init.d/squash_portage allows efficient compression of
# Gentoo portage arborescence
#
# It requires support for the loop device and squashfs enabled in the kernel,
# module autoloading is also *highly* recommended.
# sys-fs/squashfs and sys-fs/unionfs are necessary for read-write support.
#
# Author: Mathias Laurin
# 2006-11-28, v.0.1.5(4)

source /etc/make.globals
SQFS_CUR="$SQFS_DIRNAME/portage.sqfs"
SQFS_NEW="$SQFS_DIRNAME/portage-current.sqfs"
SQFS_OLD="$SQFS_DIRNAME/portage-old.sqfs"
DEF_RW="/dev/shm/.portage-rw"

depend() {
need localmount
}

start() {
ebegin "Mounting read-only squashfs image"
mount -rt squashfs -o loop,nodev,noexec $SQFS_CUR $PORTDIR
retval=$?
eend $retval
[ $retval -ne 0 ] && return $retval

ebegin "Mounting read-write with unionfs"
if [ ! $PORTAGE_RW ]
then
einfo " mounted in tmpfs (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 aufs $PORTDIR
eend $?
}

stop() {
ebegin "Unmounting the tree"
umount -t aufs $PORTDIR
umount -t squashfs $PORTDIR
rm -rf $PORTAGE_RW
eend 0
}


Confrontandolo con lo script originale noterete che effettivamente ho tagliato tutta la parte relativa alla ricreazione dell'immagine compressa.
Segue ora lo script che utilizzeremo per aggiornare portage:


#!/bin/bash
source /etc/make.globals
SQFS_DIRNAME="/var/portage"

SQFS_CUR="$SQFS_DIRNAME/portage.sqfs"
SQFS_NEW="$SQFS_DIRNAME/portage-current.sqfs"
SQFS_OLD="$SQFS_DIRNAME/portage-old.sqfs"
DEF_RW="/dev/shm/.portage-rw"


echo "Updating portage tree"
[ ! $PORTAGE_RW ] && PORTAGE_RW="${DEF_RW}"
if [ ! -z `ls -A $PORTAGE_RW | head -n1` ]
then
echo " Syncing the tree"
emerge --sync
mv -f $SQFS_NEW $SQFS_OLD
mksquashfs $PORTDIR $SQFS_NEW -no-duplicates 2>/dev/null
ln -sf $SQFS_NEW $SQFS_CUR
else
echo " Nothing to do"
fi


Per finire aggiungiamo lo script di mounting all'avvio:
rc-update add squash_portage boot


Nessun commento: