試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Portageツリーのディレクトリ(PORTDIR)をSquashfsに圧縮(準備とツリー更新方法)

Portageツリーのディレクトリ(PORTDIR)をSquashfsに圧縮(概要と下準備)」の続き。

  1. /tmp/以下をtmpfsにする設定(tmpfs上にSquashfsをコピーする場合)
  2. rsync、DISTDIR、PKGDIRの設定(/etc/make.conf)
  3. rsync時の除外ディレクトリ定義ファイル
  4. Squashfs作成時の除外ディレクトリ定義ファイル
  5. Squashfsを起動時に自動でtmpfs上にコピー/マウントする設定
  6. Squashfsをtmpfsでない場所に配置する場合の設定
  7. Squashfsを更新する一連の流れを半自動化

/tmp/以下をtmpfsにする設定(tmpfs上にSquashfsをコピーする場合)

/tmp/以下をtmpfsとして使用し、Squashfsを配置する場合には以下を記述。ここで設定せずに/dev/shm/以下に配置するのでもよいし、そもそもtmpfs上に置かない方法もある(好みの問題)。
ファイル名: /etc/fstab

[任意の名前]     /tmp        tmpfs       mode=1777,size=[最大サイズ]M 0 0

rsync、DISTDIR、PKGDIRの設定(/etc/make.conf)

DISTDIR*1とPKGDIR*2が書き込み可能な場所になるようにする。また、未圧縮Portageツリー以下にこれらを置く場合、Squashfs作成時にこれらのディレクトリを除外する必要がある(Squashfs内にソースファイルやパッケージファイルが含まれるのを防ぐため・設定は後述)。
必要に応じて、rsync時に更新の対象から除外するディレクトリも指定する。ここではそのリストファイル*3の指定を行う。
ファイル名: /etc/make.conf

# rsync実行時、除外ファイルを記述したファイルを指定するための設定
PORTAGE_RSYNC_EXTRA_OPTS="--exclude-from=/etc/portage/rsync_excludes"
#PORTAGE_RSYNC_EXTRA_OPTS="--exclude-from=/etc/portage/rsync_excludes --delete-excluded"
# パッケージダウンロードディレクトリは書き込める場所に指定する
DISTDIR=/usr/portage-uncompressed/distfiles
# ビルドしたパッケージをtbz2化したものの配置場所も同様
PKGDIR=/usr/portage-uncompressed/packages

PORTAGE_RSYNC_EXTRA_OPTSは、rsyncコマンドに対して渡す追加のオプション。

rsync時の除外ディレクトリ定義ファイル

このファイルで記述するのは、「確実に、自分の用途では使用しないとはっきりしている」ものだけに限定する。少しでも使用する可能性があると思ったものは含めないほうがよい。
「sci-libs/fftw」や「dev-scheme/guile」など、分野としては外せそうでも、他のパッケージが依存している場合があるため、除外してしまうと不具合が出ることがある。

下は除外ディレクトリの定義例だが、用途や好みによっては不要なディレクトリが異なるため、書き方の参考程度に。rsyncで除外せずにmksquashfs側で除外してもよい。なお、ここに記述したディレクトリは、上の/etc/make.conf内のPORTAGE_RSYNC_EXTRA_OPTSの中に--delete-excludedを追加することで、次回同期時に削除されるが、DISTDIRとPKGDIRをこのツリー内に置く場合、これらも消されてしまうので、このオプションを付ける場合には注意。
[任意]ファイル名: /etc/portage/rsync_excludes

app-mobilephone/
app-pda/
app-xemacs/
gnustep-*/
net-dialup/
sys-freebsd/

上の内容でも、不具合が出ないとは保証できない。

Squashfs作成時の除外ディレクトリ定義ファイル

mksquashfsで除外しなくてはならないのはDISTDIR(distfiles)とPKGDIR(packages)だが、未圧縮Portageツリー以下にDISTDIRとPKGDIRを置く使い方をしなければ下の設定は必要ない。
rsyncの除外ファイルリストと違い、パターン指定はできない?
[任意]ファイル名: /etc/portage/mksquashfs.excludes

distfiles
packages

これ以外にも、rsync時には除外したくない(未圧縮なツリーには配置する)がSquashfsの中には含めたくない、というものがあれば記述する。

Squashfsを起動時に自動でtmpfs上にコピー/マウントする設定

以下は、起動時に自動的にtmpfsな/tmp/以下にSquashfsファイルをディスク上からコピーし、マウントを行うための設定。
ファイル名: /etc/conf.d/local.start

ebegin "[好きなメッセージ]"
cp {/var,}/tmp/portage.sqfs3 && mount -t squashfs -o ro,loop /tmp/portage.sqfs3 /usr/portage
eend $?

上の内容では、ディスク上では/var/tmp/portage.sqfs3という場所に保存して、起動時にこれを/tmp/(tmpfs上)にコピーした後でマウントするようになっている。

Squashfsをtmpfsでない場所に配置する場合の設定

もし、ファイルをtmpfs上にコピーせずに、ディスク上の/var/tmp/portage.sqfs3を直接マウントしたいのであれば、この代わりに/etc/fstabに記述するのが楽。
ファイル名: /etc/fstab

/var/tmp/portage.sqfs3	/usr/portage	squashfs	ro,loop	0	0

Squashfsを更新する一連の流れを半自動化

一連の更新作業をスクリプトにしたもの。管理者権限で実行。
下の内容のままではtmpfs上にSquashfsを配置しないが、配置する場合は「#SQFSFILE_TMPFS=/tmp/portage.sqfs3」の行のコメントを解除する。
eixがインストールされている前提につき注意。
[任意]ファイル名: sqfs3-eix-sync.sh

#! /bin/bash

if [ "${UID}" -ne 0 ]; then
  echo "This script must be run as root."
  exit 1
fi

. /etc/init.d/functions.sh

#SQFSFILE_TMPFS=/tmp/portage.sqfs3
SQFSFILE=/var/tmp/portage.sqfs3
MKSQFS_OPTS="-ef /etc/portage/mksquashfs.excludes"
PORTDIR_UNCOMPRESSED=/usr/portage-uncompressed
MKSQ_LOG=/var/log/squash-sync-mksquashfs.log

run_eix-sync()
{
  ebegin "Running eix-sync"
  eix-sync
  eend $?
}
update_sqfs()
{
  ebegin "Updating Squashfs (${SQFSFILE})"
  rm ${SQFSFILE} -f
  mksquashfs ${PORTDIR_UNCOMPRESSED}/ ${SQFSFILE} ${MKSQFS_OPTS} > ${MKSQ_LOG} 2>&1
  eend $?
}
copy_sqfs()
{
  if [ -n "${SQFSFILE_TMPFS:-}" ]; then
    ebegin "Copying Squashfs (${SQFSFILE} => ${SQFSFILE_TMPFS})"
    cp ${SQFSFILE} ${SQFSFILE_TMPFS}
    eend $?
  else
    return 0
  fi
}
mount_sqfs()
{
  local sqfs
  if [ -n "${SQFSFILE_TMPFS:-}" ]; then
    sqfs=${SQFSFILE_TMPFS}
  else
    sqfs=${SQFSFILE}
  fi
  ebegin "Mounting Squashfs (${sqfs})"
  mount -t squashfs -o ro,loop ${sqfs} ${PORTDIR:-/usr/portage}
  eend $?
}
umount_sqfs()
{
  ebegin "Unmounting Squashfs"
  umount ${PORTDIR:-/usr/portage} 2> /dev/null
  eend $?
}

# Remount(bind) temporarily
mount --bind ${PORTDIR_UNCOMPRESSED} ${PORTDIR:-/usr/portage}
# Sync
SYNC_SUCCESS=0; run_eix-sync && SYNC_SUCCESS=1
# Unmount uncompressed(bind mount)
umount ${PORTDIR:-/usr/portage}
# Abort if syncing fails
if [ ${SYNC_SUCCESS} -eq 0 ]; then exit 1; fi
# Update/Mount Squashfs
umount_sqfs; update_sqfs && copy_sqfs && mount_sqfs

続けてこれを実行してしまうとeixの(Portageツリー部分の)データベースが空になる?現象が起きることがあるが、その場合は未圧縮Portageツリーのmetadata/timestamp.chkを消すとよい。

*1:パッケージのソースなどを一時的にダウンロードして保存する場所

*2:tbz2のパッケージファイルを作成したときに保存する場所

*3:ファイルの場所と名前は任意