Překrytí systémového disku - overlay filesystem

Z DCEwiki
Skočit na navigaci Skočit na vyhledávání

Překrytí systémového disku, nasdíleného přes NFS, transparentní vrstvou která ukládá změny do ramdisku v lokální paměti, využíváme u bezdiskového linuxu od r. 2006.

Zpočátku jsme využívali UnionFS. Vývoj UnionFS započatý r. 2004 ale začal s přechodem na jádro 2.6 zaostávat a proto jsme dali přednost progresivnějšímu aufs, které podporuje jádra řady 3.x a zdrojový kód udržuje (stejně jako zdrojáky kernelu) v gitu.

Přesto že je modul aufs součástí distribučního jádra v Debianu, nejde o standardní součást vanilla jádra. Vývojářům kernelu se totiž nelíbila ani jedna ze zmíněných implementací. Především z toho důvodu, že slučování provádějí mimo rámec VFS.

Dlouho žádná jiná použitelná alternativa neexistovala, ale jak se zdá od jádra řady 3.10 se konečně stane součástí hlavní vývojové větve jádra [overlayfs], který umožňuje realizovat sloučení obsahu dvou adresářů do jednoho na úrovni VFS.

Podrobnější informace o problematice sjednocujících souborových systémů nabízí minisérie přeložených článků na http://www.abclinuxu.cz

Kompilace jádra s podporou aufs

Poznámka
root@nfsserver :~/git# git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git
root@nfsserver :~/git# cd aufs3-standalone.git
root@nfsserver :~/git# git checkout origin/aufs3.0

Zdrojáky z http://www.kernel.org

Poznámka
root@nfsserver :~/git# cd /usr/src
root@nfsserver :/usr/src# wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.8.1.tar.bz2
...
root@nfsserver :/usr/src# tar -xjf linux-3.8.1.tar.bz2


Poznámka
root@nfsserver :/usr/src/linux-3.8.1# cd /root/git/aufs3-standalone/
root@nfsserver :~/git/aufs3-standalone# cp -rvn ./{Documentation,fs,include} /usr/src/linux-3.8.1
	...
root@nfsserver :~/git/aufs3-standalone# cd /usr/src/linux-3.8.1
root@nfsserver :/usr/src/linux-3.8.1#
aufs3-kbuild.patch
aufs3-base.patch
aufs3-proc_map.patch
aufs3-standalone.patch
Poznámka
root@nfsserver :/usr/src/linux-3.8.1# patch -p1 < /root/git/aufs3-standalone/aufs3-kbuild.patch
...
root@nfsserver :/usr/src/linux-3.8.1# patch -p1 < /root/git/aufs3-standalone/aufs3-base.patch
...
root@nfsserver :/usr/src/linux-3.8.1# patch -p1 < /root/git/aufs3-standalone/aufs3-proc_map.patch
...
root@nfsserver :/usr/src/linux-3.8.1# patch -p1 < /root/git/aufs3-standalone/aufs3-standalone.patch
...
root@nfsserver :/usr/src/linux-3.8.1# cd ..
root@nfsserver :/usr/src# tar -cjf linux-3.8.1-aufs.tar.bz2 linux-3.8.1
...
Hunk #2 succeeded at 1432 (offset 7 lines).
...
Poznámka
root@diskless :/usr/src# ln -s linux-3.8.1 linux
root@diskless :/usr/src# cd linux
root@diskless :/usr/src/linux# gunzip -c /proc/config.gz > .config
root@diskless :/usr/src/linux# make oldconfig
...
Poznámka
root@diskless :/usr/src/linux# make menuconfig
Poznámka
root@diskless :/usr/src/linux# make
...
root@diskless :/usr/src/linux# make deb-pkg
...

Lokální swap

Pokud je systémový adresář připojený přes NFS překrytý tak, aby ukládal data na virtuální disk v paměti, pak by měla mít klientská pracovní stanice (nebo virtuál) k dispozici swapovací diskový oddíl, který jí umožní - v případě že dojde místo v paměti - odsypat data z docházející fyzické paměti na fyzický disk.

Není-li swapovací oddíl k dispozici, tak se systém sice nezhroutí, ale začne se chovat jako když dojde místo na disku - podivně.

Překrytí systémového disku

Překrytí systémového disku zajišťují dva skripty, umístěné v ramdisku.

Vyžadují instalaci nástrojů v initramfs-tools

root_overlay
Překryje systémový disk připojený přes NFS pomocí aufs
nfsrootsetup
Vygeneruje nový obsah souboru /etc/hosts, ve kterém použije doménové jméno nfsroot pro aktuální NFS server

root_overlay

Poznámka
#!/bin/sh
# Remounting root as overlay filesystem

PREREQ=""
prereqs()
{
     echo "$PREREQ"
}

case $1 in
prereqs)
     prereqs
     exit 0
     ;;
esac

Kód, který provede detekci a případně zavedení modulu, který umožní provést překrytí systémového adresáře...

Poznámka
insmodule()
{
    if ! grep -q $1 /proc/filesystems ; then
        modprobe $1 >/dev/null 2>/dev/null
        if ! grep -q $1 /proc/filesystems ; then
            if [[ ! "$(insmod ${rootmnt}/lib/modules/$(uname -r)/extra/$i/$i.ko)" ]] ; then
                echo $1
            fi
        else
            echo $1
        fi
    else
        echo $1
    fi
}

for i in overlayfs aufs unionfs
do
    OVERLAY=$(insmodule $i)
    [ "$OVERLAY" != "no" ] && break
done

Kód, který připraví přípojný bod a namountuje virtuální disk, kterým se překryje namountovaný systémový disk...

Poznámka
mkdir /tmp/unirw
mount -n -t tmpfs none /tmp/unirw

case "$OVERLAY" in
    overlayfs) echo "Remounting root as overlayfs ..."
        mount -n -t overlayfs -o upperdir=/tmp/unirw,lowerdir=${rootmnt} overlayfs ${rootmnt}
        ;;
    aufs) echo "Remounting root as aufs ..."
        mount -n -t aufs -o dirs=/tmp/unirw=rw:${rootmnt}=nfsro unionfs ${rootmnt}
        ;;
    unionfs) echo "Remounting root as unionfs ..."
        mount -n -t unionfs -o dirs=/tmp/unirw=rw:${rootmnt}=ro unionfs ${rootmnt}
        ;;
    *) panic "Actual initrd.img has not a module for overlay filesystem"
        ;;
esac

Mají-li být data co se ukládají na virtuální disk, kterým je systémový disk překrytý, dostupná, pak je třeba provést přesun namountovaného virtuálního disku do adresářové struktury sjednoceného souborového systému.

V opačném případě lze tento kód vynechat.

Poznámka
mkdir -p ${rootmnt}/overlay/unirw
mount -n -o move /tmp/unirw ${rootmnt}/overlay/unirw
chmod 755 ${rootmnt} # Disable rw access for non-root users

A vytvoření adresářů, nezbytných pro běh systému.

Poznámka
mkdir -p ${rootmnt}/dev
mkdir -p ${rootmnt}/proc
mkdir -p ${rootmnt}/sys
mkdir -p ${rootmnt}/tmp
mkdir -p ${rootmnt}/run
mkdir -p ${rootmnt}/var/lock

nfsrootsetup

Upozornění Obsah následujícího skriptu je specifický pro potřeby sítě naší katedry. Pokud jej hodláte využít, musíte upravit část ve které se nastavuje obsah proměnné HOSTNAME na základě IPv4 adresy, kterou přiřazuje DHCP server.
Poznámka
#!/bin/sh
# Setup hostnames according to IP address and create /etc/hosts

PREREQ="root_overlay"
prereqs()
{
     echo "$PREREQ"
}

case $1 in
prereqs)
     prereqs
     exit 0
     ;;
esac

echo "Setting hostname..."
# Bring in the main config
. /conf/initramfs.conf
# source relevant ipconfig output
. /tmp/net-*.conf

if [ -z "${HOSTNAME}" ]; then # No hostname sent by DHCP
	case "${IPV4ADDR}" in
		147.32.86.*)	HOSTNAME="dcezam-${IPV4ADDR##*.}";;
		147.32.87.*)	HOSTNAME="dcestud-${IPV4ADDR##*.}";;
		192.168.136.*)	HOSTNAME="k09-${IPV4ADDR##*.}";;
		192.168.202.*)	HOSTNAME="k2-${IPV4ADDR##*.}";;
		*)		HOSTNAME="dcelinux-${IPV4ADDR}";;
	esac
fi

[ -z "${DNSDOMAIN}" ] && DNSDOMAIN=local

rm -f ${rootmnt}/etc/hostname
echo ${HOSTNAME} > ${rootmnt}/etc/hostname

# Create /etc/hosts with correct IP for the server
rm -f ${rootmnt}/etc/hosts
cat <<EOF > ${rootmnt}/etc/hosts
127.0.0.1	localhost
${IPV4ADDR}	${HOSTNAME}.${DNSDOMAIN} ${HOSTNAME}
${nfsroot%%:*}	nfsroot
EOF

exit 0


Doplňkové operace...

k335linux
Skript, který symlinkuje adresář /opt
findswap
Skript, který se snaží najít a aktivovat lokální swap

k335linux

Poznámka
#! /bin/sh
### BEGIN INIT INFO
# Provides:          k335linux
# Required-Start:    $remote_fs
# Required-Stop: 
# Should-Start:
# Should-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Creates symlink in /opt
# Description:
### END INIT INFO

#
# k335linux	K335 diskless linux setup helpers.
#
#		Base on skeleton by Miquel van Smoorenburg <miquels@cistron.nl>.
#		Modified for Debian 
#		by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
# Version:	@(#)k335linux 1.0  12-Jan-2011  pisa@cmp.felk.cvut.cz
#

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=k335linux
DESC="station configuration"

# Include k335linux defaults if available
if [ -f /etc/default/k335linux ] ; then
	. /etc/default/k335linux
fi

set -e

case "$1" in
  start)
	echo -n "Starting $DESC: "
        #echo -n "xconf"
        #/usr/local/bin/xconf > /dev/null
	echo "."
	;;
  stop)
# 	echo -n "Stopping $DESC: "
# 	echo "."
	;;
  force-reload)
	$0 restart \
	|| exit 0
	;;
  restart)
    echo -n "Restarting $DESC: "
	start-stop-daemon --stop --quiet --pidfile \
		/var/run/$NAME.pid --exec $DAEMON
	sleep 1
	start-stop-daemon --start --quiet --pidfile \
		/var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
	;;
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start|stop|restart|force-reload}" >&2
	exit 1
	;;
esac

exit 0

Připojení swapu - findswap

Poznámka
#!/bin/sh
### BEGIN INIT INFO
# Provides:          findswap
# Required-Start:    mountall
# Required-Stop: 
# Should-Start:
# Should-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Find all unused swap partitions to enable swapping on them
# Description:
### END INIT INFO

do_start() {
  SWAPCANDIDATES="$(cat /proc/partitions | sed -n -e 's/^.* \([hs]d[a-z][0-9]\)$/\1/p' -e 's/^.* \(xvd[a-z][0-9]\)$/\1/p')"
  for i in $SWAPCANDIDATES ; do
    if [ "$( blkid -s TYPE /dev/$i -o value )" = "swap" ] ; then
      grep -q "/dev/$i" /proc/swaps
      if [ $? -ne 0 ] ; then
        echo "Adding swap device /dev/$i."
        swapon "/dev/$i"
      fi
    fi
  done
}

case "$1" in
  start|"")
	do_start
	;;
  restart|reload|force-reload)
	echo "Error: argument '$1' not supported" >&2
	exit 3
	;;
  stop)
	# No-op
	;;
  *)
	echo "Usage: $0 [start|stop]" >&2
	exit 3
	;;
esac

Mount uživatelských adresářů

Využívá souboru /etc/hosts, který vygeneroval skript v ramdisku

Využití překrytí při přípravě binárních distribučních balíků