XFS corrompido e nenhuma maneira de xfs_repair

2

Um dos meus servidores hospedados tem alguns problemas de XFS. após a última falha, algumas das minhas pastas do RRD foram corrompidas.

exemplo (desculpe, é em francês):

# rm *
rm: impossible de supprimer « create_rrd.sh »: La structure a besoin d'un nettoyage
rm: impossible de supprimer « old »: est un dossier
rm: impossible de supprimer « tcgraph.log »: La structure a besoin d'un nettoyage
rm: impossible de supprimer « tcgraph.rrd »: La structure a besoin d'un nettoyage

A mudança normal seria reiniciar o sistema em um único usuário, ou usar um live cd, e rodar um xfs_repair em / dev / sda. Infelizmente (seria muito fácil), a empresa de hospedagem oferece uma opção para reiniciar em um CD ao vivo, o que não funciona. E visitar o datacenter não é uma opção.

Parece que não consigo tocar nos inodes, recebo toda a mensagem "a estrutura precisa de uma limpeza".

Então, a pergunta é: alguém sabe uma maneira de reparar / consertar o sistema de arquivos XFS manualmente? Qualquer ferramenta de manipulação de XFS de baixo nível que possa ajudar?

    
por Julien Vehent 28.01.2011 / 00:56

1 resposta

4

A resposta curta é não.

A resposta mais longa é que seria muito fascinante tentar copiar tudo em um ramdisk tmpfs, trocando / passando por isso, então desmontando o sistema de arquivos do disco rígido e rodando inteiramente do RAM enquanto você repara o sistema de arquivos do drive.

Eu não sou o primeiro a pensar nisso, encontrei esta discussão mas nenhuma informação sobre se o esquema realmente funcionou. Como o objetivo era limpar o disco, eles não se incomodaram em desmontá-lo.

Para fazer isso, crie um diretório e mount -t tmpfs none /some/directory e, em seguida, comece a preenchê-lo com uma cópia dos bits importantes do sistema (sshd, mount, umount, ferramentas xfs, um shell e todas as bibliotecas necessárias para executá-lo , provavelmente todos os / etc para ter certeza, e finalmente init ... scripts de criação de jail chroot ajudaria aqui, assim como ter cerca de 4GB de RAM. Monte uma cópia de proc nele e se você estiver usando devfs, monte uma cópia Usando o copy de / etc / ssh / sshd_config, configure o sshd para iniciar em uma porta diferente, chroot no seu ramdisk e certifique-se de que tudo funciona e não há nenhuma biblioteca perdida, então execute o sshd no ramdisk ( na porta alternativa) para que seja chroot lá.Certifique-se de que você pode ssh para ele (isso pode exigir a cópia de seu diretório / home para lá também) (e abrir a porta em qualquer firewall que você possa ter).

Agora, a mágica começa: em vez de chrooting para esse tmpfs, você precisa encontrar um utilitário chamado pivot_root . Seu único objetivo na vida é chamar pivot_root () . Está no util-linux no Debian. O objetivo do pivot_root () é essencialmente para chroot todos os processos de uma só vez . Originalmente usado para mover / a partir de uma imagem ramdisk initrd para a unidade real, se isso funcionar, você estará se movendo / da unidade real para uma imagem ramdisk. Então, digamos que você fez mkdir /mnt/tmpfs; mount -t tmpfs none /mnt/tmpfs Depois de copiar tudo que você precisa lá, o próximo passo é mkdir /mnt/tmpfs/oldroot; pivot_root /mnt/tmpfs /oldroot (Se você ficou sem copiar espaço, desmonte / mnt / tmpfs e monte de novo, desta vez com -o size=... desde que o padrão é permitir somente metade de sua memória.)

O último passo é obter / oldroot desmontado. Você precisará desmontar / oldroot / sysfs / oldroot / proc e assim por diante (check / proc / mounts). Se você ainda tiver "sistema de arquivos está ocupado", pode tentar forçá-lo, ou pelo menos rastrear tudo o que tinha arquivos abertos, observando ls -l /proc/*/cwd /proc/*/fd/ | grep /oldroot/ e matando tudo ainda relacionado a ele (isso provavelmente inclui o servidor ssh que não foi chrooted) Certifique-se de estar logado no sshd alternativo antes de começar a matar coisas. Obviamente, não mate o processo 1 (init). Se você não pode forçar umount com o init em execução, você precisará usar chroot /oldroot /sbin/telinit u2 ( 2 = runlevel em que você está atualmente ou o init provavelmente matará tudo e então você reinicializará e iniciar novamente ) obtenha o init para "atualizar" executando o "novo" init que você tem no ramdisk. Você precisará fazer o chroot para / oldroot para que ele use / oldroot / dev / initctl (o ramdisk / dev / initctl não é o mesmo) (note que o telinit usará [/ oldroot] / dev / initctl para conversar com o processo init existente que foi pivot_rooted para o ramdisk, então o init que ele inicia será no ramdisk, não / oldroot).

Não estou prestes a tentar isso em um servidor de produção aqui. Talvez eu tente em casa neste fim de semana.

    
por 28.01.2011 / 02:07