e2fsck em uma máquina com pouca memória: posso obter mais de scratch_files ou swap?

1

Estou executando o CentOS 6 em uma máquina de 32 bits com 1 GB de RAM.

Eu tenho um disco rígido externo de 1 TB que estou tentando executar o e2fsck. Ele é executado por cerca de uma hora e meia e, em seguida, falha com Error storing directory block information (inode=45206324, block=0, num=39291127): Memory allocation failed . Depois de encontrar esta questão , criei /etc/e2fsck.conf com o conteúdo indicado e com base nas respostas a pergunta , criei um arquivo de swap de 20GB (eu só tenho um disco, então dividir swap em vários discos não é possível). Já havia 2GB de espaço de troca.

No momento da falha, ele usava cerca de 325MB em seu diretório scratch_files e o uso de swap era de 550MB. O novo swapfile de 20GB não foi tocado. Ele permaneceu por mais 45 minutos com cerca de 2% de uso da CPU antes do programa morrer com e2fsck: aborted e a troca voltou para cerca de 65 MB.

Usando iostat -dx , descobri que a utilização do disco principal era de 4.3% e a unidade externa de 7.2% enquanto o e2fsck ainda estava em execução (mas falhava), mas não tive isso enquanto a CPU estava a 100% então eu não sei como isso era. Depois que o programa foi finalmente abortado, esses números de utilização de disco não mudaram.

Então, minha pergunta é: por que o e2fsck falhou sem usar espaço de swap ou preencher o disco com arquivos scratch? Há mais alguma coisa que eu possa tentar consertar este disco usando esta máquina? São 3000 milhas de distância ...

Editar: Aqui estão as linhas relacionadas à memória de top antes da falha de memória:

Mem:   1029080k total,  1010780k used,    18300k free,   309780k buffers
Swap: 23019504k total,    71796k used, 22947708k free,   433072k cached

E depois, enquanto ainda está em execução:

Mem:  1004.961M total,  991.344M used,   13.617M free, 1728.000k buffers
Swap:   21.953G total,  541.621M used,   21.424G free,   27.949M cached

Editar 2

Eu corri e2fsck novamente usando strace . Curiosamente, foi capaz de executar por muito mais tempo, usando cerca de 220 minutos de tempo de CPU, enquanto em cerca de 70% de uso ( strace e tail ocuparam os outros 30%). O programa alcançou 1832 MB de memória virtual, 811 MB de memória residente e 105 MB de memória compartilhada. Aqui estão as linhas strace da alocação de memória com falha:

22648 mremap(0x32ebc000, 1675546624, 2513317888, MREMAP_MAYMOVE) = -1 ENOMEM (Cannot allocate memory)
22648 mmap2(NULL, 2513317888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
22648 mmap2(NULL, 2513453056, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
22648 mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb2ca5000
22648 munmap(0xb2ca5000, 372736)        = 0
22648 munmap(0xb2e00000, 675840)        = 0
22648 mprotect(0xb2d00000, 135168, PROT_READ|PROT_WRITE) = 0
22648 mmap2(NULL, 2513317888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

Parece que não houve nada de estranho com leituras e gravações:

22648 _llseek(3, 755934822400, [755934822400], SEEK_SET) = 0
22648 write(3, "/6
Mem:   1029080k total,  1010780k used,    18300k free,   309780k buffers
Swap: 23019504k total,    71796k used, 22947708k free,   433072k cached
Mem:  1004.961M total,  991.344M used,   13.617M free, 1728.000k buffers
Swap:   21.953G total,  541.621M used,   21.424G free,   27.949M cached
|}xA6
22648 mremap(0x32ebc000, 1675546624, 2513317888, MREMAP_MAYMOVE) = -1 ENOMEM (Cannot allocate memory)
22648 mmap2(NULL, 2513317888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
22648 mmap2(NULL, 2513453056, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
22648 mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb2ca5000
22648 munmap(0xb2ca5000, 372736)        = 0
22648 munmap(0xb2e00000, 675840)        = 0
22648 mprotect(0xb2d00000, 135168, PROT_READ|PROT_WRITE) = 0
22648 mmap2(NULL, 2513317888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
d/3
22648 _llseek(3, 755934822400, [755934822400], SEEK_SET) = 0
22648 write(3, "/6%pre%%pre%|}xA6%pre%d/3%pre%%pre%A6%pre%\%pre%%pre%%pre%%pre%733x80%pre%"..., 4096) = 4096
22648 lseek(3, 260845568, SEEK_SET)     = 260845568
22648 read(3, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 4096) = 4096
22648 _llseek(3, 755934793728, [755934793728], SEEK_SET) = 0
22648 write(3, "6527%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%5%pre%%pre%%pre%%pre%"..., 4096) = 4096
22648 write(1, "I", 1)                  = 1
22648 write(1, "node", 4)               = 4
22648 write(1, " ", 1)                  = 1
22648 write(1, "46217250", 8)           = 8
22648 write(1, " is too big.  ", 14)    = 14
22648 write(1, "Truncate? yes\n\n", 15) = 15
%pre%A6%pre%\%pre%%pre%%pre%%pre%733x80%pre%"..., 4096) = 4096 22648 lseek(3, 260845568, SEEK_SET) = 260845568 22648 read(3, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%"..., 4096) = 4096 22648 _llseek(3, 755934793728, [755934793728], SEEK_SET) = 0 22648 write(3, "6527%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%5%pre%%pre%%pre%%pre%"..., 4096) = 4096 22648 write(1, "I", 1) = 1 22648 write(1, "node", 4) = 4 22648 write(1, " ", 1) = 1 22648 write(1, "46217250", 8) = 8 22648 write(1, " is too big. ", 14) = 14 22648 write(1, "Truncate? yes\n\n", 15) = 15
    
por WinnieNicklaus 26.02.2013 / 18:35

1 resposta

1

Eu não sou especialista em e2fsck. Eu assumo que o e2fsck se importa se a memória que vê é RAM real ou swap. As páginas podem ser bloqueadas na memória. Eu assumo que a informação de quanta memória está bloqueada está disponível via / proc ou ps, top, ... Você pode monitorar este valor.

Obviamente, a única boa solução seria conectar o disco a um melhor hardware. Difícil para você. Mas pode até ajudar a não fazer essa conexão fisicamente, mas via rede. Se houver outro sistema Linux com uma conexão LAN adequada à sua e com mais RAM, você poderá exportar o dispositivo para ser verificado como um dispositivo de bloco de rede. Provavelmente ainda mais rápido que a minha próxima ideia.

Se o problema é que o e2fsck requer uma RAM "real", você pode criar uma máquina virtual com uma pequena instalação Linux (nada mais necessário que o e2fsck ...). Esta VM pode ser configurada com 2, 4, 16 GiB de "RAM". O dispositivo a ser verificado pode ser exportado como um dispositivo de bloco (aparecendo como um disco na VM). Provavelmente faz sentido usar o recurso scratch_files de qualquer maneira. Isso obviamente seria um pesadelo de performance, mas eu acho que você já aceitou qualquer solução possível nesta categoria.

Editar 1

Você pode ver a quantidade de memória virtual que um processo bloqueou na RAM:

grep VmLck /proc/$PID/status

Editar 2

Veja tudo de dmesg relacionado ao dispositivo sdb . Os erros de EXT4-fs são o motivo pelo qual eu estava executando e2fsck .

sd 0:0:0:0: [sdb] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
sd 0:0:0:0: [sdb] Write Protect is off
sd 0:0:0:0: [sdb] Mode Sense: 28 00 00 00
sd 0:0:0:0: [sdb] Assuming drive cache: write through
sd 0:0:0:0: [sdb] Assuming drive cache: write through
 sdb: sdb1
sd 0:0:0:0: [sdb] Assuming drive cache: write through
sd 0:0:0:0: [sdb] Attached SCSI disk
EXT4-fs (sdb1): barriers disabled
EXT4-fs (sdb1): warning: mounting fs with errors, running e2fsck is recommended
EXT4-fs (sdb1): recovery complete
EXT4-fs (sdb1): mounted filesystem with ordered data mode. Opts: 
SELinux: initialized (dev sdb1, type ext4), uses xattr
EXT4-fs error (device sdb1): ext4_lookup: deleted inode referenced: 46006273
EXT4-fs (sdb1): ext4_check_descriptors: Checksum for group 0 failed (2332!=0)
EXT4-fs (sdb1): group descriptors corrupted!
EXT4-fs (sdb1): ext4_check_descriptors: Checksum for group 0 failed (34754!=0)
EXT4-fs (sdb1): group descriptors corrupted!
EXT4-fs (sdb1): ext4_check_descriptors: Checksum for group 0 failed (34754!=0)
EXT4-fs (sdb1): group descriptors corrupted!
    
por 26.02.2013 / 21:12