O processo abriu o inode que não está em nenhum sistema de arquivos?

2

Estou tentando descobrir se o stderr de um processo foi redirecionado para algo incomum (é um processo java e eu quero um dump de thread, mas ele é lançado através de um ninho de scripts de inicialização).

Eu localizo meu processo com pgrep e uso pfiles para ver o que há:

4366:   /foo/bar/platform/solaris2/jre_1.5.0/bin/java -Xmx2048m -Xms10
Current rlimit: 65536 file descriptors
 0: S_IFCHR mode:0666 dev:302,0 ino:6815752 uid:0 gid:3 rdev:13,2
    O_RDONLY|O_LARGEFILE
    /devices/pseudo/mm@0:null
 1: S_IFREG mode:0640 dev:85,56 ino:26471 uid:0 gid:0 size:10485812
    O_WRONLY|O_LARGEFILE
 2: S_IFREG mode:0640 dev:85,56 ino:26471 uid:0 gid:0 size:10485812
    O_WRONLY|O_LARGEFILE
 3: S_IFCHR mode:0666 dev:302,0 ino:6815772 uid:0 gid:3 rdev:13,12

Portanto, posso ver que stdout e stderr (descritores de arquivo 1 e 2) estão apontando para o mesmo local; Acho que eles são redirecionados para o mesmo arquivo nos scripts de inicialização.

Mas quando procuro um arquivo com o número de inode 26471, vejo isso:

# find / -inum 26471
/usr/share/man/man3mlib/mlib_MatrixScale_S16_U8_Sat.3mlib
/proc/4366/fd/1
/proc/4366/fd/2
/proc/4366/fd/83

O primeiro hit é (estou certo) um arquivo em um sistema de arquivos diferente. As três entradas em /proc são fds que meu processo abriu.

Olhando em /proc/4366 , não consigo ver mais informações do que as que recebo de pfiles .

# ls -li 0 1 2 3
   6815752 c---------   1 root     sys       13,  2 Jan 20 14:10 0
     26471 --w-------   0 root     root     10485812 Jan 20 13:42 1
     26471 --w-------   0 root     root     10485812 Jan 20 13:42 2
   6815772 c---------   1 root     sys       13, 12 Jun  7  2009 3
# file 0 1 2 3
0:              character special (13/2)
1:              ascii text
2:              ascii text
3:              character special (13/12)

(Eu posso seguir um desses fds e descobrir qual é o arquivo dele. Estou perguntando porque eu claramente não entendo a relação entre os fds e os inodes com profundidade suficiente).

Então, meu processo está escrevendo para algo (em algum dispositivo, com inode 26471) e os dados estão, então, entrando em um arquivo com um número de inode diferente. Alguém pode me dar uma idéia do que essa coisa pode ser (ou até mesmo me avisar se meu raciocínio está totalmente quebrado)?

    
por Tom Dunham 20.01.2010 / 14:32

1 resposta

6

AFAIK, find pesquisa os diretórios do sistema de arquivos. Se esse arquivo foi excluído, mas ainda existe porque está aberto (um truque comum no unix), ele não será encontrado por find .

Eu não tentei no Solaris, mas aqui é uma observação sobre o uso lsof para identificar os arquivos "excluídos, mas abertos" e se recuperando por meio de um cat /proc/<procid>/fd/<fdid> > /tmp/xxxx

Editar :

parece que você já identificou este é o caso, mas ainda se perguntando como é possível. aqui está uma breve explicação:

no sistema de arquivos POSIX, os arquivos são manipulados pelo seu inode , e os diretórios são pouco mais que um mapeamento "path = > inode". Você pode ter mais de um caminho 'apontando' para o mesmo inode (ele é chamado de hardlink), e o inode mantém uma contagem de quantos links ele possui. O comando rm simplesmente chama unlink() nesse caminho, o que reduz a contagem de links e 'possivelmente' exclui o próprio arquivo.

Mas um caminho na árvore de diretórios não é a única referência possível a um inode, um fd aberto em um processo em execução também conta e um arquivo 'excluído' não será realmente removido até que ele seja 0 .

Como mencionei acima, é um truque comum: se você tem um arquivo temporário que não quer manter depois que o processo termina de ser executado, basta abri-lo e excluí-lo imediatamente. O identificador aberto funcionará de forma confiável e, quando o processo for concluído (normalmente, morto ou travado), o sistema removerá o identificador e excluirá o arquivo temporário.

Um arquivo de log não é um candidato provável para esse arquivo 'autodeleting oculto'; mas não é difícil fazer isso acidentalmente.

Como seu arquivo de log apagado ainda está ativo e coletando dados, parece que simplesmente copiar o conteúdo não ajudaria muito. então tente criar um novo hardlink para o / proc // fd / file, algo como ln /proc/4366/fd/1 /tmp/xxxx . Note que não há -s flag, então ln deve criar um novo hardlink com o mesmo inode do original, não um link simbólico (que é pouco mais que um ponteiro para um caminho existente, e não o que você quer). / p>

Editar :

O comando ln /proc/... /tmp/... não pode funcionar porque / proc e / tmp estão em sistemas de arquivos diferentes. Infelizmente, não sei como criar um nome de caminho para um inode existente. Alguém poderia querer que o link() syscall levasse um número de inode e um caminho, mas ele toma caminhos de origem e de destino.

    
por 20.01.2010 / 15:29