Como determinar qual host gerou um arquivo principal?

2

Eu tenho uma configuração onde várias máquinas compartilham o mesmo sistema de arquivos via NFS. Através de um sistema de filas, as tarefas de processamento podem ser submetidas a várias máquinas de computação (com diferentes propriedades).

Às vezes, um trabalho irá travar e deixar para trás um arquivo principal (com um nome como core.1234 ).

Existe uma maneira de descobrir qual host gerou esse arquivo principal? Qual foi o nome do seu host?

(Isto é no Linux 64 bits, se isso faz diferença).

    
por luispedro 26.11.2013 / 11:21

2 respostas

5

Em um sistema ELF , um arquivo principal é quase certamente um arquivo ELF válido.

 $ readelf -a core
 ELF Header:
 Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
 Class:                             ELF32
 Data:                              2's complement, little endian
 Version:                           1 (current)
 OS/ABI:                            UNIX - System V
 ABI Version:                       0
 Type:                              CORE (Core file)
 Machine:                           Intel 80386
 [...]

Um número específico de "notas" da plataforma é adicionado a um segmento NOTES para que um depurador possa ser encontrado, por exemplo, para Solaris, veja o núcleo (4) , e você notará o NT_UTSNAME estrutura que contém a estrutura de dados do uname(2) syscall. elfdump -n é a maneira de ler isso, mas até onde sei, o Solaris é o único SO que faz isso (e eu suspeito que apenas o Solaris 11 elfdump funcione como esperado).

Uma maneira simples, embora um pouco complicada e não garantida, é tentar pescar as variáveis HOST ou HOSTNAME (definidas por alguns scripts e shells de inicialização, bash pelo menos define HOSTNAME ) fora do ambiente de despejo de núcleo. Você pode fazer isso com gdb , embora precise do binário original:

$ gdb /usr/bin/sleep core
[... snip ...]
(gdb) print (char ***) &environ
$1 = (char ***) 0x600bf8
(gdb) print $1[0][0]@10
$2 = {0x7fffffffd9c9 "HOST=myhostname", 0x7fffffffd9d9 "TERM=screen", 
0x7fffffffd9e5 "SHELL=/bin/csh", 
[...]

Este imprime um trecho de strings do environ símbolo . Embora seja um hack horrível, o strings | grep HOSTNAME= também pode funcionar.

Portanto, a resposta curta para " Existe uma maneira de descobrir qual host gerou o arquivo principal " é: não é fácil, e não confiavelmente no Linux.

FWIW, o código relevante do coredump no Linux está em fs/binfmt_elf.c , e existe um gancho para permitir "anotações" extras por meio de ARCH_HAVE_EXTRA_ELF_NOTES , atualmente usado apenas no PowerPC.

Um plano melhor é usar o sysctl para definir o nome do arquivo principal em cada cliente , como sugerido por @jlliagre:

sysctl kernel.core_pattern="%h-%t-%e.core"

( sysctl e pesquisa em /proc são equivalentes aqui, eu prefiro sysctl , pois as alterações podem ser mantidas documentadas em /etc/sysctl.conf e também são usadas em sistemas * BSD.)

    
por 26.11.2013 / 18:54
5

Você pode executar strings core.1234 e descobrir se o nome do host aparece em algum lugar. Alguns sistemas operacionais como o Solaris colocam o nome do host no cabeçalho principal, mas, até onde eu sei, o Linux não o faz, portanto, o método strings não seria confiável.

Uma abordagem melhor seria configurar os clientes NFS para colocar seus nomes de host nos nomes dos arquivos principais definindo o arquivo /proc/sys/kernel/core_pattern ou alguma configuração específica de distribuição se core_pattern referir-se a um executável.

    
por 26.11.2013 / 11:44

Tags