sexta-feira, outubro 16, 2009

Interface Gráfica em 8 segundos no Arch Linux

Não você não leu errado o titulo do post, é EXATAMENTE isso que você leu. Carregar a interface gráfica em 8 SEGUNDOS desde a tela do GRUB até a tela do Gnome.
Há um tempo eu procurei muito como acelerar o boot do Arch Linux, comecei como a grande maioria começa, desabilitando serviços. Editando o /etc/rc.conf, mudando ordem de prioridade, colocando serviço pra começar em paralelo, mas tudo isso não mudava muito coisa, mesmo com com o boot em 20 segundos eu ainda achava lento. Foi então que eu encontrei, em forum italiano ou espanhol, o tal do finit-arc, um programa que substitui o INIT tradicional do Arch. Escrito em C e que carrega os serviços de forma assincrona. Mas o que me deixou mais entusiasmado era a promessa de uma interface gráfica em 5 segundos.
Confesso que nunca atingi os 5 segundos, mesmo porque nao me aprofundei tanto, pois o Arch foi deixado de ser usado no meu trabalho para dar lugar ao Debia, mas isso é outra história um dia eu a contarei, mas cheguei a conseguir 7 segundos usando um processador ATOM.
Que conclusão chegamos com isso? Não precisamos de um SUPER COMPUTADOR e nem MILHARES de GB-RAM para que o sistema inicie rápido, só precisamos de um bom inicializados.
Mas vamos deixar de papo e vamos por a mão na massa.
Passo 1: Instalar o finit-arc no Arch Linux.
#yaourt -Sy finit-arc

Passo 2: Ajustar o sistema para o funcionamento do finit-arc
Faça o backup dos rc.sysinit, menu.lst, /etc/fstab
#cp /etc/rc.sysinit /etc/rc.sysinit.bkp
#cp /etc/fstab /etc/fstab.bkp
#cp /boot/grub/menu.lst /boot/grub/menu.lst.bkp


Passo 3: Modificar /etc/rc.sysinit
Para que se consiga bootar mais rápido com o finit-arc é necessário substituir o conteudo do /etc/rc.sysinit pelo código abaixo
#!/bin/bash
#
# /etc/rc.sysinit
#
. /etc/rc.conf
. /etc/rc.d/functions
echo " "
printhl "Arch Linux - Speedup boot"
printsep
#**************************** WARNING ******************************
# If you're using initramfs for your kernel, uncomment steps 5 and 17
# To improve boot speed it's recommendend to make a static kernel
# without modules and without initramfs.
#
# MAKE STEP 2
# Type in a term from root: ls -l /dev | grep sda
# you'll receive the list of /dev/sda devices
# make your /dev/sda devices in step 2 like the example
#*******************************************************************
#
# STEP 1 - mount /proc, /sys and our RAM /dev
/bin/mount -n -t ramfs none /dev
/bin/mount -n -t proc none /proc
/bin/mount -n -t sysfs none /sys
#
# STEP 2 - make static sda nodes for start udevadm --settle in background
/bin/mknod /dev/sda b 8 0
/bin/mknod /dev/sda1 b 8 1
/bin/mknod /dev/sda2 b 8 2
/bin/mknod /dev/sda3 b 8 3
/bin/mknod /dev/sda4 b 8 4
#...5...6..etc..(from your fdisk -l)
#
# STEP 3 - copy static device nodes to /dev
/bin/cp -a /lib/udev/devices/* /dev/
#
# STEP 4 - enable rtc access
/sbin/modprobe rtc-cmos >/dev/null 2>&1
if [ -n "$RTC_MAJOR" ]; then
/bin/mkdir /dev/misc/
/bin/mknod /dev/misc/rtc0 c $RTC_MAJOR 0
/bin/ln -s /dev/misc/rtc0 /dev/rtc
fi
#
# STEP 5 - Load modules from the MODULES array defined in rc.conf
#if ! [ "$load_modules" = "off" ]; then
# if [ -f /proc/modules ]; then
# stat_busy "Loading Modules"
# for mod in "${MODULES[@]}"; do
# if [ "$mod" = "${mod#!}" ]; then
# /sbin/modprobe $mod
# fi
# done
# stat_done
# fi
# if [ -d /proc/acpi ]; then
# stat_busy "Loading standard ACPI modules"
# ACPI_MODULES="ac battery button fan processor thermal"
# k="$(echo $BLACKLIST ${MOD_BLACKLIST[@]} | /bin/sed 's|-|_|g')"
# j="$(echo ${MODULES[@]} | /bin/sed 's|-|_|g')"
# #add disabled MODULES (!) to blacklist - much requested feature
# for m in ${j}; do
# [ "$m" != "${m#!}" ] && k="${k} ${m#!}"
# done
# # add disablemodules= from commandline to blacklist
# k="${k} $(echo ${disablemodules} | /bin/sed 's|-|_|g' | /bin/sed 's|,| |g')"
# for n in ${ACPI_MODULES}; do
# if ! echo ${k} | /bin/grep "\" 2>&1 >/dev/null; then
# /sbin/modprobe $n > /dev/null 2>&1
# fi
# done
# stat_done
# fi
#fi
#
# STEP 6 - set hardware clock for fs check
{
HWCLOCK_PARAMS="--hctosys"
if [ "$HARDWARECLOCK" = "UTC" ]; then
HWCLOCK_PARAMS="$HWCLOCK_PARAMS --utc"
else
HWCLOCK_PARAMS="$HWCLOCK_PARAMS --localtime"
fi
if [ "$USEDIRECTISA" = "yes" -o "$USEDIRECTISA" = "YES" ]; then
HWCLOCK_PARAMS="$HWCLOCK_PARAMS --directisa"
fi
if [ -f /etc/localtime ]; then
/sbin/hwclock $HWCLOCK_PARAMS --noadjfile
fi
} &
#
echo > /proc/sys/kernel/hotplug
#
# STEP 7 - start udevadm trigger and udevd in background
{
if [ -x /sbin/udevadm -a -d /sys/block ]; then
stat_busy "Starting UDev Daemon"
/sbin/udevd --daemon &
/sbin/udevadm trigger &
stat_done
else
status "Using static /dev filesystem" true
fi
} &
#
# STEP 8 - start udevadm settle in background
/sbin/udevadm settle &
#
# STEP 9 - make lo interface
{
if [ -d /sys/class/net/lo ]; then
stat_busy "Bringing up loopback interface"
/sbin/ifconfig lo 127.0.0.1 up
if [ $? -ne 0 ]; then
stat_fail
else
stat_done
fi
fi
} &
#
# STEP 10 - mounting root read-only
status "Mounting Root Read-only" /bin/mount -n -o remount,ro / &
#
# STEP 11 - filesystem check
FORCEFSCK=
[ -f /forcefsck ] && FORCEFSCK="-- -f"
NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk"
fsck_reboot() {
echo "Automatic reboot in progress..."
/bin/umount -a
/bin/mount -n -o remount,ro /
/sbin/reboot -f
exit 0
}
if [ -x /sbin/fsck ]; then
stat_busy "Checking Filesystems"
FSCK_OUT=/dev/stdout
FSCK_ERR=/dev/null
/sbin/fsck -A -T -C -a -t $NETFS $FORCEFSCK >$FSCK_OUT 2>$FSCK_ERR
fsckret=$?
if [ ${fsckret} -gt 1 ]; then
stat_fail
fi
if [ $((${fsckret}&2)) -eq 2 ]; then
echo
echo "********************** REBOOT REQUIRED *********************"
echo "* *"
echo "* The system will be rebooted automatically in 15 seconds. *"
echo "* *"
echo "************************************************************"
echo
/bin/sleep 15
fsck_reboot
fi
if [ ${fsckret} -gt 1 -a ${fsckret} -ne 32 ]; then
echo
echo "***************** FILESYSTEM CHECK FAILED ****************"
echo "* *"
echo "* Please repair manually and reboot. Note that the root *"
echo "* file system is currently mounted read-only. To remount *"
echo "* it read-write type: mount -n -o remount,rw / *"
echo "* When you exit the maintenance shell the system will *"
echo "* reboot automatically. *"
echo "* *"
echo "************************************************************"
echo
/sbin/sulogin -p
fsck_reboot
fi
stat_done
fi
#
# STEP 12 - remount root and mount local file system
stat_busy "Mounting Local Filesystems"
/bin/mount -n -o remount,rw /
/bin/rm -f /etc/mtab*
/bin/mount -o remount,rw /
if [ -e /proc/mounts ]; then
/bin/grep -e "/proc " -e "/sys " -e "/dev " /proc/mounts >> /etc/mtab
fi
/bin/mount -a -t $NETFS
stat_done
#
# STEP 13 - activating swap partition
status "Activating Swap" /sbin/swapon -a &
#
# STEP 14 - set urandom
{
RANDOM_SEED=/var/lib/misc/random-seed
if [ -f $RANDOM_SEED ]; then
stat_busy "Initializing Random Seed"
/bin/cat $RANDOM_SEED > /dev/urandom
stat_done
fi
} &
#
# STEP 15 - removing temp files
stat_busy "Removing Leftover Files"
/bin/rm -f /etc/nologin &>/dev/null
/bin/rm -f /etc/shutdownpid &>/dev/null
/bin/rm -f /var/lock/* &>/dev/null
/bin/rm -rf /tmp/* /tmp/.* &>/dev/null
/bin/rm -f /forcefsck &>/dev/null
(cd /var/run && /usr/bin/find . ! -type d -exec /bin/rm -f -- {} \; )
: > /var/run/utmp
/bin/chmod 0664 /var/run/utmp
/bin/mkdir /tmp/.ICE-unix && /bin/chmod 1777 /tmp/.ICE-unix
/bin/mkdir /tmp/.X11-unix && /bin/chmod 1777 /tmp/.X11-unix
stat_done
#
# STEP 16 - set rc.conf hostname
if [ "$HOSTNAME" != "" ]; then
status "Setting Hostname: $HOSTNAME" /bin/hostname $HOSTNAME &
fi
#
# STEP 17 - load modules depends
#status "Updating Module Dependencies" /sbin/depmod -A &
#
# STEP 18 - set lang
{
: >/etc/profile.d/locale.sh
/bin/chmod 755 /etc/profile.d/locale.sh
[ -z "$LOCALE" ] && LOCALE="it_IT@euro"
stat_busy "Setting Locale: $LOCALE"
echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh
stat_done
} &
#
# STEP 19 - Save our dmesg output from this boot
if [ -f /var/log/dmesg.log ]; then
/bin/rm /var/log/dmesg.log &
fi
/bin/dmesg > /var/log/dmesg.log &


Passo 4: Configurar /boot/grub/menu.lst
OBS. o Finit-arc não suporta aqueles UUID para as partições. VOCÊ deve usar o nome padrão usado no linux como /dev/sda1. Também altere o arquivo /etc/fstab
vim /etc/menu.lst
#(0) Arch Linux
title Arch Linux SpeedBoot
kernel /boot/vmlinuz26 root=/dev/sda2 ro vga=791 splash resume=/dev/sda1 init=/sbin/finit-arc
initrd /boot/kernel26.img


Passo 5: Alteração do /etc/fstab
O original deve estar mais ou menos assim:
UUID=24f28fc6-717e-4bcd-a5f7-32b959024e26 / ext4 defaults,noatime 0 1
UUID=03ec5dd3-45c0-4f95-a363-61ff321a09ff /home ext4 defaults,noatime 0 2
UUID=4209c845-f495-4c43-8a03-5363dd433153 swap swap defaults 0 0


Para algo parecido com o que segue abaixo(Claro que isso vai depender da sua configuração de partições):
#vi /etc/fstab

/dev/sda1 / ext4 defaults,noatime 0 1
/dev/sda2 /home ext4 defaults,noatime 0 2
/dev/sda3 swap swap defaults 0 0



Apartir daqui você terá o configurador do seu novo sistema de inicialização finit-arc em substituição ao antigo init

Passo 6: Edite/crie o arquivo /etc/finit.conf
O conteudo do finit.conf deve ser mais ou menos esse.
##Set user on "login_manager" if you want access
##in a console login manager or GDM,KDM
#user login_manager
#
##mountdevices before udev (DONT REMOVE IT!)
mountdev
#
##modules that you want load
#module intel_agp
#module agpgart
#
##filesystem device that you want check
check /dev/sda2
check /dev/sda3
#
##hostname
host arch_msdark
#
##startx command
startx /bin/bash --login -c /usr/bin/startx


Depois você pode verificar cada opção desse arquivo de como configura-lo

Passo 7: Crie/Edite o arquivo /usr/sbin/services.sh
#!/bin/sh
#
#Starts udev events
/sbin/udevd --daemon &>/dev/null &
/sbin/udevadm trigger &>/dev/null &
/sbin/udevadm settle &>/dev/null &
#
#Make swap (not for ssd)
/sbin/swapon -a &
#
#Starting background daemons
/etc/rc.d/syslog-ng start &>/dev/null &
/etc/rc.d/hal start &>/dev/null &
/etc/rc.d/laptop-mode start &>/dev/null &
/etc/rc.d/alsa start &>/dev/null &
/etc/rc.d/wicd start &>/dev/null &
/etc/rc.d/fam start &>/dev/null &
/etc/rc.d/klogd start &>/dev/null &
/etc/rc.d/crond start &>/dev/null &


Pronto. Agora reset seu PC e veja o ganho de velocidade.
Mais tarde faço um post sobre como configurar o bootchart para você verificar o ganho de velocidade
referência no forum em portugues e no forum original chileno