Unicode

Já há algum tempo que queria começar a usar o Unicode em consola no Slackware.

Há uns meses atrás, tentei, mas a informação disponível dizia que era difícil, que havia dificuldade com línguas diferentes do inglês/americano.

Afinal, e segundo um documento recente que encontrei aqui é relativamente fácil.

Basicamente, é apenas necessário editar os ficheiros /etc/profile.d/lang.sh e /etc/profile.d/lang.csh e atualizar a linha seguinte:

export LANG=pt_PT.UTF-8

Depois, editar o ficheiro /etc/lilo.conf e adicionar/modificar a linha seguinte:

append="vt.default_utf8=1"

No fim, correr o comando lilo e reiniciar a máquina.

Gerir as máquinas virtuais

Eis os comandos necessários para compilar o VirtualBox:

cd /root
bat/vboxes stop
cd /usr/local/
VBoxManage extpack uninstall "Oracle VM VirtualBox Extension Pack"
reboot
exit
cd /usr/local/
chmod +x ./VirtualBox-X.X.XX-XXXXX-Linux_amd64.run
./VirtualBox-X.X.XX-XXXXX-Linux_amd64.run
VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-X.X.XX-XXXXX.vbox-extpack
cd -
bat/vboxes start

Nota : o ficheiro bat/vboxes é um ficheiro de comandos que criei para gerir as máquinas virtuais do VirtualBox. Já agora, este script serve para lançar as máquinas virtuais em modo headless e tem o conteúdo seguinte:

#!/bin/sh
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/usr/sbin:/usr/bin:/sbin:/bin
SCRIPTNAME=/root/bat/vboxes
MANAGE_CMD=/root/bat/vboxcase "$1" in
start|stop|shutdown|restart|force-reload)
echo "-- $1 virtual boxes --"
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|shutdown|restart|force-reload}" >&2
exit 3
;;
esac

for i in `VBoxManage list vms | grep "^\"" | sed -e "s/{.*}//g" | sed -e "s/\"//g"`;
do
echo "$MANAGE_CMD $i $1"
$MANAGE_CMD $i $1
done

No script anterior faço referência a um outro script bat/vbox cujo conteúdo se segue e serve para gerir uma máquina virtual de cada vez (ver código original aqui)):

#!/bin/sh
### BEGIN INIT INFO
# Provides: vbox
# Required-Start:$local_fs $remote_fs vboxdrv vboxnet
# Required-Stop: $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: MAQUINA virtual machine
# Description: MAQUINA virtual machine hosted by VirtualBox
### END INIT INFO# Author: Brendan Kidwell <brendan@glump.net>#
# Based on /etc/init.d/skeleton from Ubuntu 8.04. Updated for Ubuntu 9.10.
# If you are using Ubuntu <9.10, you might need to change "Default-Stop" # above to "S 0 1 6". # Do NOT "set -e" # O nome da máquina tem que vir como 1º parâmetro # O nome do comando tem que vir como 2º parâmetro MAQUINA="$1" COMANDO="$2" # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/usr/sbin:/usr/bin:/sbin:/bin DESC="$MAQUINA virtual machine" NAME=vbox SCRIPTNAME=/root/bat/$NAME MANAGE_CMD=VBoxManage VM_OWNER=root VM_NAME="$MAQUINA" #This has to be the name exactly as it appears in your VirtualBox GUI control panel. # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables [ -f /etc/default/rcS ] && . /etc/default/rcS # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
#. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started

sudo -H -u $VM_OWNER $MANAGE_CMD showvminfo "$VM_NAME"|grep "^State:\s*running" >/dev/null && {
echo "$VM_NAME" is already running.
return 1
}

sudo -H -u $VM_OWNER $MANAGE_CMD startvm "$VM_NAME" -type headless >/dev/null || {
echo Failed to start "$VM_NAME".
return 2
}

echo "$VM_NAME" started or resumed.
return 0
}

#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred

sudo -H -u $VM_OWNER $MANAGE_CMD showvminfo "$VM_NAME"|grep "^State:\s*running" >/dev/null || {
echo "$VM_NAME" is already stopped.
return 1
}

sudo -H -u $VM_OWNER $MANAGE_CMD controlvm "$VM_NAME" savestate || {
echo Failed to stop "$VM_NAME".
return 2
}

echo "$VM_NAME" suspended.
return 0
}

#
#
# Function that powers off the daemon/service
#
do_shutdown()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred

sudo -H -u $VM_OWNER $MANAGE_CMD showvminfo "$VM_NAME"|grep "^State:\s*running" >/dev/null || {
echo "$VM_NAME" is already stopped.
return 1
}

sudo -H -u $VM_OWNER $MANAGE_CMD controlvm "$VM_NAME" acpipowerbutton || {
echo Failed to stop "$VM_NAME".
return 2
}

echo "$VM_NAME" powered off.
return 0
}

#
# Display "State" field from showinfo action
#
do_status()
{
sudo -H -u $VM_OWNER $MANAGE_CMD showvminfo "$VM_NAME"|grep "^State:\s*.*$"
}

case "$COMANDO" in
start)
[ "$VERBOSE" != no ] && logger "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && logger 0 ;;
2) [ "$VERBOSE" != no ] && logger 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && logger "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && logger 0 ;;
2) [ "$VERBOSE" != no ] && logger 1 ;;
esac
;;
shutdown)
[ "$VERBOSE" != no ] && logger "Powering off $DESC" "$NAME"
do_shutdown
case "$?" in
0|1) [ "$VERBOSE" != no ] && logger 0 ;;
2) [ "$VERBOSE" != no ] && logger 1 ;;
esac
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
logger "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) logger 0 ;;
1) logger 1 ;; # Old process is still running
*) logger 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
logger 1
;;
esac
;;
status)
do_status
;;
*)
#echo "Usage: $SCRIPTNAME nome-maquina {start|stop|shutdown|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME nome-maquina {start|stop|shutdown|restart|force-reload|status}" >&2
exit 3
;;
esac

Usei outro script logo no arranque da máquina (host) para criar placas de rede virtuais para serem usadas pelas máquinas virtuais. São criadas como uma ponte (bridge) para uma placa física no host que só serve para rencaminhar o tráfego das máquinas virtuais para a rede e vice-versa. O seu conteúdo é o seguinte:

#!/bin/sh
# set PATH for the case we are called via sudo or su root
# PATH=/sbin:/usr/bin:/bin:/usr/binUSER=root

NUMBER_OF_VM=9
# create the bridge
brctl addbr br0

# create the taps and insert them into the bridge

NB=1
while [ $NB -le $NUMBER_OF_VM ]
do
tunctl -t tap$NB -u $USER
ip link set up dev tap$NB
brctl addif br0 tap$NB
let NB=$NB+1
done

ip route add 192.168.40.0/24 dev eth1

# set the IP address and routing
ip link set up dev br0
ip addr add 192.168.40.1/24 dev br0
##ip route add 192.168.40.0/24 dev br0

brctl addif br0 eth1

Slackware current – atualizações

Já há uns anos que uso a versão current do Slackware. Com alguma frequência, atualizo as minhas máquinas todas para a última versão dos vários pacotes. Algumas são máquinas virtuais, outras são máquinas físicas, duas delas têm o VirtualBox.

Durante as atualizações, têm surgido vários problemas, e tenho escrito artigos soltos sobre as soluções encontradas para os resolver. Vou tentar copiar para esta crónica, toda a lista de problemas e soluções que estão espalhadas por este blog.

slackpkg

Eis a lista de comandos que utilizo no Slackware para fazer update das minhas máquinas, a partir de um mirror que tenho e que é atualizado diariamente.

slackpkg update
slackpkg update gpg
slackpkg install-new
slackpkg upgrade-all
slackpkg clean-system

De vez em quando, e ainda não percebi porquê, o slackpkg pendura. A máquina que estava a ser atualizada deixa de responder. Não sei se é por fazer muitas atualizações em simultâneo, todas a ler no mesmo mirror, se é demasiado peso na rede a carregar os pacotes para as atualizações… Duvido que a causa seja uma destas, mas ainda não consegui descobrir a origem dos problemas.

Algumas vezes tenho que mandar a máquina abaixo, embora nem sempre. Mas uma consequência chata destes penduranços é que os pacotes que estavam a ser atualizados são considerados instalados, apesar de não estarem. Ainda demorei algum tempo a encontrar solução para este problema, por isso fica aqui para consulta futura.

cd /var/lib/slackpkg/
rm ChangeLog.txt

E depois já posso recomeçar os updates.

LILO

Há cerca de um ano (em 2018), o Slackware passou a avisar que instalou um novo kernel, mas já não corre o lilo; pede antes que sejamos nós a fazê-lo.

Se me esquecer de correr o lilo numa máquina virtual, a solução para voltar a arrancar com ela é a seguinte:

Nos settings da máquina, no VirtualBox, pedir para arrancar com o ISO da versão mais recente do Slackware. Depois de entrar, correr os seguintes comandos:

mount /dev/sda2 /mnt
chroot /mnt
lilo
reboot

Se me esquecer de correr o lilo num host das máquinas virtuais (que têm o disco de boot em RAID 1), a solução é arrancar de DVD e correr os seguintes comandos:

mdadm --assemble --run /dev/md0 /dev/sda2 /dev/sdb2 
mount /dev/md0 /mnt
chroot /mnt
lilo
exit
reboot

Pacotes duplicados

Depois de recuperar a máquina que pendurou nas atualizações, retomei o processo de atualização e recebi uma mensagem à qual nunca soube responder:

Checking local integrity... DONE
You have a broken /var/log/packages - with two versions of the same package.
The list of packages duplicated in your machine are shown below, but don't worry about this list - when you select your action, slackpkg will show a better list:

llvm-3.8.0-x86_64-1
llvm-3.8.0-x86_64-2

You can (B)lacklist, (R)emove, or (I)gnore these packages.
Select your action (B/R/I):

Premi ENTER, sem escolher opção nenhuma e fui à net@ ver o que deveria fazer. Descobri que devia remover o pacote llvm-3.8.0-x86_64-1 que não tinha sido removido na instalação anterior, que pendurou. Removi-o com o comando:

removepkg llvm-3.8.0-x86_64-1

e depois continuei a atualização com:

slackpkg upgrade-all

VirtualBox

Para atualizar a versão do VirtualBox nos hosts das máquinas virtuais, uso os comandos seguintes:

cd /root
bat/vboxes stop
cd /usr/local/
VBoxManage extpack uninstall "Oracle VM VirtualBox Extension Pack"
reboot
exit
cd /usr/local/
chmod +x ./VirtualBox-X.X.X-XXXXXX-Linux_amd64.run
./VirtualBox-X.X.X-XXXXXX-Linux_amd64.run
VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-X.X.X-XXXXXX.vbox-extpack
cd /root
bat/vboxes start

O ficheiro bat/vboxes é um ficheiro de comandos que criei para gerir as máquinas virtuais do VirtualBox. [ver aqui]

Entretanto, se alguma das máquinas falhar, posso recuperá-la da forma seguinte (para casos em que há problemas com o kernel):

Reiniciar a máquina virtual, ligando ao leitor de CD um ISO com a última versão do sistema operativo. Depois de arrancar e escolher o layout do teclado, executar os comandos seguintes.

mount /dev/sda2 /mnt
mount -t proc proc /mnt/proc (this was the magic step)
chroot /mnt
cd /boot
mkinitrd -c -k 4.14.2 -m ext3
# No ficheiro /etc/lilo.conf colocar a linha
initrd = /boot/initrd.gz
# no fim do ficheiro, logo após a linha
root = /dev/sda2
# depois, executar os comandos:
lilo
reboot

SSHD

A nova configuração do SSHD, no Slackware, não permite o acesso de clientes à conta “root”. Para permitir, é necessário, antes do último reboot, colocar a linha seguinte no ficheiro /etc/ssh/sshd_config: PermitRootLogin yes
Ou então apagar o ficheiro /etc/ssh/sshd_config.new antes de fazer o upgrade.
Ou, sempre que o SSHD é atualizado, não fazer o overwrite desse ficheiro.

input/output error

Durante a atualização das máquinas, uma das máquinas virtuais deu um erro de input/output, enquanto estava a remover um pacote. E a atualização ficou por ali.

Tive que reiniciar a máquina, mas só o consegui fazer dentro do VirtualBox, e não em modo headless através de um ficheiro batch que uso para lançar as máquinas. Qualquer acesso ao sistema de ficheiros dava um erro de input/output (o df, o mount). Tentei retomar a atualização, mas a diretoria remota – onde estão os pacotes do Slackware – não estava montada. Descobri, então, que não tinha rede e o sistema não permitia fazer o modprobe da placa de rede: dizia que o dispositivo não existia na diretoria /lib/modules/4.4.13.

Fui à pasta /lib/modules/4.4.13 ver que dispositivos de rede estavam disponíveis, mas a pasta /lib/modules/4.4.13 não existia. No entanto, havia uma mais recente: /lib/modules/4.4.14.

Ah! Durante a atualização, o kernel 4.4.14 já tinha sido instalado, mas como não cheguei a correr o lilo, devido à interrupção da instalação, o sistema ainda estava a arrancar com o 4.4.13. Contudo, as bibliotecas do 4.4.13 já tinham sido removidas. Corri o lilo e reiniciei a máquina. Depois já pude mandar verificar o sistema de ficheiros, com um comando que desliga a máquina e força a verificação no próximo arranque:

shutdown -rF now

BIND e cache

Tenho tido problemas com o BIND. Penso que é um problema de erros na cache, ou algo parecido. Quando tento aceder a um sítio a partir do nome, na rede interna, o browser diz que não consegue aceder ao sítio. Mas se eu aceder a partir das máquinas periféricas – os gateways – acedo sem problemas.

Independentemente do problema, aqui fica uma solução para limpar a cache do BIND.

Para fazer dump da cache:

rndc dumpdb -cache

Para ver o conteúdo do dump:

vi /var/named/named_dump.db

Para apagar a cache:

rndc flush

Depois é necessário recarregar o BIND:

rndc reload

Ver mais em: How to view and clear Bind DNS server’s cache on Linux

Ficheiro de swap

Precisei de aumentar o espaço de swap numa máquina com o Ubuntu. No Slackware costumo criar partições de swap, mas esta máquina Ubuntu tinha um ficheiro de swap, ao invés de uma partição.

Segui as instruções do site Linuxize, e criei dois ficheiros de 2G cada.

sudo swapon --show
sudo fallocate -l 2G /swapfile2
sudo chmod 600 /swapfile2
sudo mkswap /swapfile2
sudo swapon /swapfile2
sudo vi /etc/fstab
sudo swapon --show

sudo swapon --show
sudo fallocate -l 2G /swapfile3
sudo chmod 600 /swapfile3
sudo mkswap /swapfile3
sudo swapon /swapfile3
sudo vi /etc/fstab
sudo swapon --show
sudo free -h

O ficheiro /etc/fstab ficou com 3 ficheiros de swap, como indicado abaixo:

/swapfile             none            swap    sw              0       0
/swapfile2            none            swap    sw              0       0
/swapfile3            none            swap    sw              0       0

O resultado dos comandos de consulta foi:

$ sudo swapon --show
NAME       TYPE SIZE   USED PRIO
/swapfile  file   2G 977,5M   -2
/swapfile2 file   2G     0B   -3
/swapfile3 file   2G     0B   -4

$ sudo free -h
          total        used        free      shared  buff/cache   available
Mem:       7,7G        1,7G        122M        195M        5,9G        5,5G
Swap:      6,0G        977M        5,0G

Extrair um ficheiro de um tar

Precisei de extrair um ficheiro de um tar. Já não é a primeira vez. Fica aqui a solução para consultas futuras.

Em dezembro passado, movi o conteúdo das pastas de email, do servidor, para a máquina Windows, para mais tarde os arquivar.

Na prática cada pasta de email é um ficheiro na diretoria home do utilizador.

Um dos ficheiros que movi perdeu-se no éter, e desapareceu mesmo. Fiquei sem emails daquela pasta, de um período de 4 anos. Felizmente tenho backups diários de todas as máquinas e guardo-os durante 1 ano.

Aqui vai o comando:

tar xzvf /store/baks/bak.2018-12-26.MAQUINA5.tar.gz -C . home/user/Pasta

O parâmetro -C . é para dizer que quero que faça o restore para a diretoria atual.

Ideia tirada do stackoverflow.

postgres

Criei um pacote de instalação do postgres, versão 10, para o Slackware, a partir dos ficheiros do slackbuilds.org.

Precisei de colocar a BD numa drive SSD e, por isso, a configuração foi um pouco diferente do normal. Seguem as instruções.

installpkg postgresql-10.2-x86_64-1_SBo.tgz

groupadd -g 209 postgres
useradd -u 209 -g 209 -d /disco4/pgsql postgres
mkdir /disco4/pgsql
chown -R postgres:postgres /disco4/pgsql
su postgres -c "initdb -D /disco4/pgsql/10.2/data --locale=en_US.UTF-8 -A md5 -W"

Depois tive que atualizar a diretoria das BDs no ficheiro /etc/rc.d/rc.postgresql. Onde estava:

DATADIR=/var/lib/pgsql/$PG_VERSION/data

alterei para

DATADIR=/disco4/pgsql/$PG_VERSION/data

Depois já se pode arrancar com o postgres:

/etc/rc.d/rc.postgresql start

Para criar um utilizador “alex” e dar-lhe permissões de administrador, executar os comandos seguintes, inserindo a password de superuser, de cada vez:

sudo -u postgres createuser alex
sudo -u postgres createdb alex
sudo -u postgres psql

Com este último comando, entramos no psql e deve emitir-se o comando seguinte para atribuir permissões de administrador ao novo utilizador:

alter user alex with encrypted password 'password';

Para sair: \q

O postgres – vá-se lá saber porquê – cria uma BD de nome alex para o utilizador alex e atribui-a ao utilizador. Se quisermos criar outra BD para esse utilizador, podemos emitir os comandos seguintes, ainda dentro do psql:

sudo -u postgres createdb nova_bd
sudo -u postgres psql
grant all privileges on database nova_bd to alex ;

Depois, para sair, escrever \q

O utilizador alex pode agora entrar com o seu login:

psql -U alex

e ligar-se à sua nova BD:

\c nova_bd

Para correr um script SQL externo – por exemplo, para criar uma nova BD – executar o comando:

\i script.sql


Par ausar o postgres a partir do Python3, deve instalar-se o pacote seguinte:

pip3 install -U psycopg2-binary

Stale file handle

As minhas máquinas Linux vão buscar os pacotes de atualização do Slackware a um repositório meu, que atualizo diariamente.

Por vezes, quando me tento ligar à máquina onde está esse repositório, a partir de outras máquinas, obtenho a mensagem: Stale file handle

Por exemplo: df: /mnt/slack: Stale file handle, ou então: mount.nfs: Stale file handle

A solução é reiniciar o nfsd na máquina repositório,

/etc/rc.d/rc.nfsd restart

e depois remontar as pastas remotas nas outrs máquinas.

mount -a

Pode ser necessário desmontar a pasta primeiro:

umount /mnt/slack

Instalar Linux num RAID de raiz

Para instalar o Slackware num sistema RAID logo de raiz, é necessário seguir os passos seguintes.

Na instalação, antes de fazer ‘setup’:

Criar as partições nos discos, de tamanho igual, como sendo do tipo RAID (tipo FD no fdisk, ou FD00 no gdisk).

Depois, criar o array de RAID. O exemplo seguinte é para um RAID 1.

mdadm –create /dev/md0 –level=1 –raid-devices=2 –metadata=0.90 /dev/sda2 /dev/sdb2

O parâmetro –metadata=0.90 é por causa do lilo, que precisa disto para discos RAID de arranque. Não aceita a versão metadata=1.2 (não sei se ainda tem esta limitação).

Depois, manda-se instalar o sistema em /dev/md0.


Caso surja algum erro e seja necessário parar o RAID, eis os comandos:

mdadm –stop /dev/md0


Outras operações que por vezes tenho que efetuar com os RAIDs:

Se for necessário renomear os RAIDs:
mdadm –stop /dev/md2
mdadm –assemble /dev/md0 /dev/sda3 /dev/sdc3

# Normalmente tenho que fazer o seguinte:

mdadm –stop /dev/md127
mdadm –assemble /dev/md3 /dev/sda1 /dev/sdb1

mdadm –stop /dev/md126
mdadm –assemble /dev/md2 /dev/sdg1 /dev/sdh1

# mas pode ser melhor dar um nome ao RAID passando um parâmetro –name=2 ou –name=3
# em princípio isto tem que ser feito logo na criação

# Depois de criar/modificar o RAID, deve-se reescrever o ficheiro /etc/mdadm.conf

cp /etc/mdadm.conf /etc/mdadm.conf.ori
echo ‘DEVICES /dev/sd[abcdefgh]1’ > /etc/mdadm.conf
mdadm –detail –scan >> /etc/mdadm.conf

Parar e reiniciar um RAID
mdadm –stop /dev/md3
mdadm –assemble /dev/md3 /dev/sdc1 /dev/sdd1

Substituir um disco RAID1 que falhou. Ver:
http://www.howtoforge.com/replacing_hard_disks_in_a_raid1_array

# Dizer que o disco falhou
mdadm –manage /dev/md3 –fail /dev/sdc1

# Remover o disco do RAID
mdadm –manage /dev/md3 –remove /dev/sdc1

# Adicionar disco ao RAID
mdadm –manage /dev/md3 –add /dev/sdc1

Converter o disco de sistema em RAID 1

Numa das máquinas, talvez a mais antiga, o disco de sistema (boot) não está em RAID. É a única onde isso acontece, e vou tentar convertê-lo hoje para RAID 1.

Li vários artigos na net@ – principalmente este – para ver se havia uma forma expedita de fazer isto, mas parece que tem mesmo que ser feito “à unha”. A solução que vou descrever abaixo é muito próxima da que imaginei a priori.

Arranjar um disco de tamanho igual ao do disco de boot.
Criar partições iguais.

No meu caso, o disco de boot tinha as partições seguintes:

Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 4196351 4194304 2G 82 Linux swap
/dev/sda2 4196352 8390655 4194304 2G 82 Linux swap
/dev/sda3 8390656 488397167 480006512 228.9G 83 Linux

Com o fdisk, criei também duas partições de SWAP com 2GB cada e uma de Linux RAID, no disco novo:

Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 4196351 4194304 2G 82 Linux swap
/dev/sdb2 4196352 8390655 4194304 2G 82 Linux swap
/dev/sdb3 8390656 488397167 480006512 228.9G fd Linux raid autodetect

Adicionei as partições de SWAP ao fstab:

/dev/sdb1 swap swap defaults 0 0
/dev/sdb2 swap swap defaults 0 0

Para copiar a partição sda3 para a sdb3, desliguei a máquina, e arranquei com o DVD de instalação de uma versão recente do Slackware.

Depois, criei o array do RAID. De notar o atributo missing que indica que há um disco em falta, que irá ser adicionado mais tarde:

mdadm --create --metadata=0.90 /dev/md0 --level=1 --raid-devices=2 missing /dev/sdb3

O parâmetro --metadata=0.90 é necessário porque este volume vai ser um volume de arranque e o lilo precisa disso.

Para confirmar se o RAID foi bem criado, corri o comando cat /proc/mdstat

Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath]
md0 : active raid1 sdb3[1]
239871104 blocks super 1.2 [2/1] [_U]
bitmap: 0/2 pages [0KB], 65536KB chunk

Depois formatei o RAID:

mkfs.ext4 /dev/md0

E copiei os ficheiros

mount /dev/sda3 /mnt/d1
mount /dev/md0 /mnt/d2
cp -rp /mnt/d1/* /mnt/d2

Nota: experimentei várias outras formas de copiar os ficheiros, mas esta foi a única que funcionou. Tentei copiar a partição inteira (com dd), tentei também usar o rsync, mas não estava instalado no sistema base de instalação do Slackware.

Como a cópia pode demorar muito tempo, pode verificar-se o andamento da cópia, noutra janela de consola (CTRL+ALT+F2), onde é o process ID do comando cp:

cat /proc//io

No meu caso, para 176GB, demorou 1h26m.

Depois da cópia feita, é necessário preparar o RAID para o arranque.

cp /mnt/d2/etc/mdadm.conf /mnt/d2/etc/mdadm.conf.ori
echo 'DEVICES /dev/sd[abcdefgh]3' > /mnt/d2/etc/mdadm.conf
mdadm --detail --scan >> /mnt/d2/etc/mdadm.conf

No lilo.conf, tenho que colocar, no início:

boot = /dev/md0
raid-extra-boot="/dev/sda,/dev/sdb"

e, mais abaixo:

root = /dev/md0

Para isso:

vi /mnt/d2/etc/lilo.conf

Como o ficheiro /proc/partitions não existe no disco do RAID, porque só existe no disco do sistema ativo, mas como preciso dele para correr o lilo, faço o seguinte:

cp /proc/partitions /mnt/d2/proc

Depois, corri o lilo, com a opção -H, porque um dos discos do RAID não está ainda ativo.

chroot /mnt/d2
lilo -H
exit

No ficheiro /mnt/d2/etc/fstab corrigi o caminho para o boot:

/dev/md0 / ext4 defaults 1 1

Desliguei a máquina. Retirei o DVD. No arranque, pedi para arrancar com o disco novo, aquele onde está o RAID.

Confirmei que o sistema tinha arrancado com o disco novo, com o comando cat /proc/mdstat.

Com o comando fdisk /dev/sda transformei a partição /dev/sda3 em Linux RAID.
Depois, adicionei o disco /dev/sda3 ao RAID.

mdadm --manage /dev/md0 --add /dev/sda3

E depois executei o comnando cat /proc/mdstat para verificar o estado do RAID.

Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath]
md0 : active raid1 sda3[2] sdb3[1]
240003136 blocks [2/1] [_U]
[>....................] recovery = 0.3% (810240/240003136) finish=68.8min speed=57874K/sec