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

Aumentar o RAID

Tive que aumentar um RAID 1, de 2TB para 3TB, em Linux.

O RAID 1 era constituído pelos dispositivos /dev/sdc1 e /dev/sdd1, cada um com 1.922.599.672 bytes.
Constituiam o dispositivo /dev/md1.

Desliguei a máquina, retirei um dos discos – o /dev/sdc – e adicionei um disco de 3TB.

No arranque, o RAID não arrancou corretamente. Ao invés, arrancou como /dev/md127, como é usual sempre que há problemas. Tive que o parar com o comando

mdadm --stop /dev/md127

Entrei no fdisk, para criar uma partição no disco, e ele queixou-se de que não podia criar uma partição maior do que 2TB.


Device does not contain a recognized partition table.
The size of this disk is 2.7 TiB (3000592982016 bytes). DOS partition table format cannot be used on drives for volumes larger than 2199023255040 bytes for 512-byte sectors. Use GUID partition table format (GPT).

Estranhei aquela coisa da partição DOS, mas como já tinha tido um problema semelhante há 4 anos atrás, decidi usar o gdisk.

Com o gdisk criei uma partição de 3TB e defini-a como Linux RAID, com o código FD00, ao invés do FD do fdisk.

Depois de ter parado o RAID incompleto (mdadm --stop /dev/md127), tentei iniciar o novo RAID:

mdadm --assemble /dev/md1 /dev/sdc1 /dev/sdd1

mas a máquina queixou-se:

mdadm: /dev/sdc1 has no superblock - assembly aborted

Tive então que aplicar os comandos seguintes:

mdadm --zero-superblock /dev/sdc
mdadm --zero-superblock /dev/sdc1
mdadm --assemble --run /dev/md1 /dev/sdd1
mdadm --add /dev/md1 /dev/sdc1

Depois, para verificar que tudo estava OK, corri o comando seguinte, que me mostrou o RAID a ser construído:

cat /proc/mdstat

Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath]
md1 : active raid1 sdc1[2] sdd1[1]
1953382336 blocks super 1.2 [2/1] [_U]
[>....................] recovery = 0.0% (707264/1953382336) finish=184.0min speed=176816K/sec

———————

Quando o mdstat chegou a 100%, parei a máquina e fiz o mesmo para o /dev/sdd.
Após terminar, montei o RAID no sistema de ficheiros, usandp a informação do /etc/fstab:

mount -a

———————

Por fim, para estender o /dev/md1 para 3TB, executei os seguintes comandos

e2fsck -f /dev/md1
mdadm --grow /dev/md1 --size=2881959520
resize2fs /dev/md1

Note-se que o parâmetro size vem em kilobytes.

Falha no disco

Durante um upgrade de uma máquina virtual, o disco principal da máquina falhou. Como as máquinas – a correr em Oracle Virtual Machine – arrancam em modo headless, só percebo a falha porque a máquina não regista, os novos serviços instalados, no meu servidor de logs.

Entrei no VirtualBox, abri uma janela dessa máquina e vi a mensagem – que me aparece de tempos a tempos – a pedir CTRL-D para reboot, ou passwrod de root para manutenção. Introduzi a password e segui os passos indicados neste site para reparar o disco e recuperar a máquina. São os seguintes:

  • Entrar em modo monoutilizador: init 1
  • Desmontar o disco: umount /dev/sda2
  • Verificar o disco: fsck /dev/sda2

Depois, e uma vez que a máquina ainda nem arrancou, fazer reboot.

Slackware 15

Enquanto aguardamos a saída do Slackware 15, o Patrick publicou a seguinte mensagem no Changelog da versão current, enquanto decorria o maior eclipse lunar do século:

Fri Jul 27 21:01:22 UTC 2018
Hey folks, my first order of business here needs to be a huge thank you to
everyone who has donated at https://paypal.me/volkerdi to help keep this
project going. As most of you are already aware by now, the financal situation
here at Slackware HQ has not been great for many years, including not getting
any pay for the last two years and forcing me (and my family) to live very
frugally while I continued to work on the project hoping I’d figure out a way
to actually monitize it by the time that Slackware 15.0 is ready for release.
(…)

Kernel 4.14.47 – II

O ficheiro /etc/rc.d/rc.inet1 está diferente e está a dar problemas. Ainda não identifiquei o problema, por isso tive que reverter a atualização nas 3 máquinas em que isto causou falhas de comunicação.

Além disso, aparentemente, esqueci-me de correr o lilo num dos hosts das máquinas virtuais. Tive que 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

Kernel 4.14.47

Nas atualizações a partir da versão current, 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.

Esqueci-me de fazê-lo em quatro das minhas máquinas virtuais e duas delas não arrancaram. A solução para voltar a arrancar com elas foi semelhante a outra já explicada anteriormente.

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

Perl – IO::Socket::INET segmentation fault

Já há uns meses que tinha este problema pendurado e consegui resolvê-lo hoje.
Tenho 18 máquinas com o Linux Slackware instalado e todas elas têm um script, que corre no arranque e no crontab, e atualiza uma base de dados com as versões dos vários pacotes de software que estão instalados, incluindo a versão do kernel. Assim, consigo saber se me escapou alguma máquina durante as sessões de atualização de software.

Em duas máquinas a atualização da BD não era feita porque o script produzia um segmentation fault ao usar o pacote IO::Socket::INET.

Hoje andei pela net@ a ver como fazer debug de um programa em Perl e descobri que tinha uma diretoria com ficheiros antigos de Perl, nessas duas máquinas, que estavam a causar o problema.

Com o debug, encontrei a origem do erro:

# perl -d bat/kern2.pl

Loading DB routines from perl5db.pl version 1.51
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

Signal SEGV at /usr/local/lib64/perl5/Socket.pm line 858.
        require Socket.pm called at /usr/lib64/perl5/IO/Socket.pm line 13
        IO::Socket::BEGIN() called at /usr/local/lib64/perl5/Socket.pm line 0
        eval {...} called at /usr/local/lib64/perl5/Socket.pm line 0
        require IO/Socket.pm called at /usr/lib64/perl5/IO/Socket/INET.pm line 11
        IO::Socket::INET::BEGIN() called at /usr/local/lib64/perl5/Socket.pm line 0
        eval {...} called at /usr/local/lib64/perl5/Socket.pm line 0
        require IO/Socket/INET.pm called at bat/kern2.pl line 3
        main::BEGIN() called at /usr/local/lib64/perl5/Socket.pm line 0
        eval {...} called at /usr/local/lib64/perl5/Socket.pm line 0
Aborted

O erro estava na linha 858 do ficheiro /usr/local/lib64/perl5/Socket.pm.

Decidi ver se havia diferenças, entre máquinas, nas diretorias de INCLUDE e corri o comando seguinte:

# perl -E'say for @INC'
/usr/local/lib64/perl5
/usr/local/share/perl5
/usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl
/usr/lib64/perl5
/usr/share/perl5

Mas as diretorias eram as mesmas tanto nas máquinas que corriam o script, como nas que não corriam.

Então, fui ver se o ficheiro onde o erro ocorria – /usr/local/lib64/perl5/Socket.pm – era diferente entre máquinas, se, por exemplo, a linha 858 era igual entre ficheiros. E descobri que o ficheiro /usr/local/lib64/perl5/Socket.pm só existia nas máquinas que não corriam o script. Nas outras máquinas, a diretoria /usr/local/lib64/perl5/ estava vazia. Apaguei o conteúdo dessa diretoria nas máquinas-problema, e o problema desapareceu.

Há muitos anos atrás, tive que instalar o pacote IO::Socket::INET e outros, nessas máquinas, para poder comunicar pela rede, mas agora esses pacotes fazem parte do núcleo do Perl. Os pacotes antigos estavam a sobrepor-se aos do núcleo e estavam a gerar o erro.

Recuperar RAID 1

Tive problemas com o RAID de uma das máquinas. Por algum motivo, um dos discos saltou fora do RAID 1.
Fui à procura na net e encontrei dois sítios com informação importante:
Replacing A Failed Hard Drive In A Software RAID1 Array
How to check ‘mdadm’ RAIDs while running?

Ao emitir o comando cat /proc/mdstat o resultado foi o seguinte:

md2 : active raid1 sdf1[1] sde1[0]
      1953512400 blocks super 1.2 [2/2] [UU]

md3 : active raid1 sdd1[1]
      1953512400 blocks super 1.2 [2/1] [_U]

md0 : active raid1 sda3[0] sdb3[1]
      73939072 blocks [2/2] [UU]

No md3 faltava o sdc1. Se estivesse lá, mas com erro, teria que ser removido primeiro, com os comandos seguintes:

mdadm --manage /dev/md3 --fail /dev/sdc1
mdadm --manage /dev/md3 --remove /dev/sdc1

E depois, desligaria a máquina e, se o disco estivesse mesmo avariado, trocaria o disco.
É necessário criar uma partição igual à da partição sdd1. Para comparar as partições, emitir o comando fdisk -l, cujo resultado, para os discos em causa, é:

Disk /dev/sdc: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x98f9dba0

Device     Boot Start        End    Sectors  Size Id Type
/dev/sdc1        2048 3907029167 3907027120  1.8T fd Linux raid autodetect


Disk /dev/sdd: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0xbe1f7c22

Device     Boot Start        End    Sectors  Size Id Type
/dev/sdd1        2048 3907029167 3907027120  1.8T fd Linux raid autodetect

A partir daí, e para recolocar o disco novamente no RAID, o comando é o seguinte:

mdadm --manage /dev/md3 --add /dev/sdc1

A reconstrução do RAID é iniciada. Pode-se ir acompanhando o processo com o comando cat /proc/mdstat

md2 : active raid1 sdf1[1] sde1[0]
      1953512400 blocks super 1.2 [2/2] [UU]

md3 : active raid1 sdc1[2] sdd1[1]
      1953512400 blocks super 1.2 [2/1] [_U]
      [=============>.......]  recovery = 66.1% (1291278848/1953512400) finish=142.0min speed=77670K/sec

md0 : active raid1 sda3[0] sdb3[1]
      73939072 blocks [2/2] [UU]

ou então com o comando mdadm -D /dev/md3:

/dev/md3:
        Version : 1.2
  Creation Time : Sat Mar 10 21:20:35 2012
     Raid Level : raid1
     Array Size : 1953512400 (1863.01 GiB 2000.40 GB)
  Used Dev Size : 1953512400 (1863.01 GiB 2000.40 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Wed Apr 25 12:51:45 2018
          State : clean, degraded, recovering
 Active Devices : 1
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 1

 Rebuild Status : 65% complete

           Name : tao:3
           UUID : 90d1dc37:d4fd77a4:a4a1d0fe:98a3717d
         Events : 68048

    Number   Major   Minor   RaidDevice State
       2       8       33        0      spare rebuilding   /dev/sdc1
       1       8       49        1      active sync   /dev/sdd1