O que acontece quando executo o comando cat / proc / cpuinfo?

Respostas:

72

Sempre que você lê um arquivo /proc, isso invoca algum código no kernel que calcula o texto a ser lido como o conteúdo do arquivo. O fato de o conteúdo ser gerado dinamicamente explica por que quase todos os arquivos têm seu tempo relatado como agora e seu tamanho relatado como 0 - aqui você deve ler 0 como "não sei". Diferentemente dos sistemas de arquivos comuns, o sistema de arquivos montado /proc, chamado procfs , não carrega dados de um disco ou outra mídia de armazenamento (como FAT, ext2, zfs,…) ou através da rede (como NFS, Samba, ...) e não chama o código do usuário (ao contrário do FUSE ).

O Procfs está presente na maioria das unidades não-BSD. Ele começou sua vida no Bell Labs da AT&T na 8ª edição do UNIX como uma maneira de relatar informações sobre processos (e psmuitas vezes é uma bonita impressora de informações lidas /proc). A maioria das implementações do procfs tem um arquivo ou diretório chamado /proc/123para relatar informações sobre o processo com o PID 123. O Linux estende o sistema de arquivos proc com muito mais entradas que relatam o estado do sistema, incluindo o seu exemplo /proc/cpuinfo.

No passado, o Linux /procadquiria vários arquivos que forneciam informações sobre drivers, mas esse uso agora é preterido em favor /syse /procagora evolui lentamente. As entradas gostam /proc/buse /proc/fs/ext4permanecem onde estão para compatibilidade com versões anteriores, mas são criadas interfaces semelhantes mais recentes /sys. Nesta resposta, vou me concentrar no Linux.

Seu primeiro e segundo pontos de entrada para a documentação sobre /procLinux são:

  1. a proc(5)página do manual ;
  2. O /procsistema de arquivos na documentação do kernel .

Seu terceiro ponto de entrada, quando a documentação não cobre, está lendo a fonte . Você pode fazer o download da fonte em sua máquina, mas este é um programa enorme e o LXR , a referência cruzada do Linux, é uma grande ajuda. (Existem muitas variantes do LXR; a que está sendo executada lxr.linux.noé de longe a mais agradável, mas infelizmente o site geralmente está inativo.) É necessário um pouco de conhecimento de C, mas você não precisa ser um programador para rastrear um valor misterioso .

A manipulação principal de /procentradas está no fs/procdiretório Qualquer driver pode registrar entradas /proc(embora, como indicado acima, agora seja preterido em favor de /sys), portanto, se você não encontrar o que está procurando fs/proc, procure em qualquer outro lugar. Drivers chamam funções declaradas em include/linux/proc_fs.h. As versões do kernel até 3.9 fornecem as funções create_proc_entrye alguns wrappers (especialmente create_proc_read_entry), e as versões do kernel 3.10 e superior fornecem apenas proc_createe proc_create_data(e mais algumas).

Tomando /proc/cpuinfocomo exemplo, uma pesquisa por "cpuinfo"leva-lo para a chamada para proc_create("cpuinfo, …")nos fs/proc/cpuinfo.c. Você pode ver que o código é basicamente um código padrão: como a maioria dos arquivos /procdespeja apenas alguns dados de texto, há funções auxiliares para fazer isso. Existe apenas uma seq_operationsestrutura, e a carne real está na cpuinfo_opestrutura de dados, que depende da arquitetura, geralmente definida em arch/<architecture>/kernel/setup.c(ou às vezes em um arquivo diferente). Tomando o x86 como exemplo, somos levados a arch/x86/kernel/cpu/proc.c. Lá a função principal éshow_cpuinfo, que imprime o conteúdo do arquivo desejado; o restante da infraestrutura existe para alimentar os dados com o processo de leitura na velocidade solicitada. Você pode ver os dados sendo reunidos em tempo real a partir de dados em várias variáveis ​​no kernel, incluindo alguns números computados em tempo real, como a frequência da CPU .

Uma grande parte /procé das informações por processo no /proc/<PID>. Estas entradas são registradas em fs/proc/base.c, no tgid_base_stuffconjunto ; algumas funções registradas aqui são definidas em outros arquivos. Vejamos alguns exemplos de como essas entradas são geradas:

Outra área importante de /procé /proc/sys, que é uma interface direta para sysctl. A leitura de uma entrada nesta hierarquia retorna o valor do valor sysctl correspondente e a gravação define o valor sysctl. Os pontos de entrada para sysctl estão em fs/proc/proc_sysctl.c. Os Sysctls têm seu próprio sistema de registro com register_sysctle amigos.

Gilles
fonte
59

Ao tentar obter informações sobre que tipo de mágica está acontecendo nos bastidores, é o seu melhor amigo strace. Aprender a operar esta ferramenta é uma das melhores coisas que você pode fazer para obter uma melhor apreciação do que mágica louca está acontecendo nos bastidores.

$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536)                      = 0
close(3)                                = 0
...

A partir da saída acima, você pode ver que /proc/cpuinfoé apenas um arquivo comum ou, pelo menos, parece ser um. Então, vamos nos aprofundar.

Mergulho mais profundo

# 1 - com sl ..

Olhando para o próprio arquivo, parece ser "apenas um arquivo".

$ ls -l /proc/cpuinfo 
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo

Mas dê uma olhada mais de perto. Temos nossa primeira dica de que é especial, observe que o tamanho do arquivo é 0 bytes.

# 2 - com estatísticas ..

Se observarmos agora o arquivo stat, podemos obter nossa próxima dica de que há algo de especial /proc/cpuinfo.

corrida # 1
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
 Birth: -
corrida # 2
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
 Birth: -

Observe os horários de acesso, modificação e alteração? Eles continuam mudando para cada acesso. É altamente incomum que todos os três mudem assim. A menos que os atributos de carimbo de data e hora de um arquivo sejam editados, normalmente permanecem os mesmos.

# 3 - com arquivo ..

Ainda outra pista de que esse arquivo é tudo menos um arquivo regular:

$ file /proc/cpuinfo 
/proc/cpuinfo: empty

Se houvesse alguma manifestação de um pipe nomeado, seria semelhante a um desses arquivos:

$ ls -l /dev/initctl /dev/zero 
prw-------. 1 root root    0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero

$ file /dev/initctl /dev/zero 
/dev/initctl: fifo (named pipe)
/dev/zero:    character special

Se tocarmos em um emptyfile, /proc/cpuinfoparece mais um arquivo que um cachimbo:

$ touch emptyfile
$ ls -l emptyfile 
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile 
emptyfile: empty
# 4 - com montagem ..

Portanto, neste momento, precisamos dar um passo atrás e diminuir um pouco o zoom. Estamos olhando para um arquivo em particular, mas talvez devêssemos olhar para o sistema de arquivos em que este arquivo reside. E para isso, podemos usar o mountcomando

$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

OK, então o tipo de sistema de arquivos é do tipo proc. Portanto, /procé um tipo de sistema de arquivos diferente. Essa é a nossa dica de que os arquivos abaixo /procsão especiais. Eles não são apenas seus arquivos comuns. Então, vamos descobrir mais algumas informações sobre o que torna o procsistema de arquivos especial.

Dando uma olhada na mountpágina de manual de:

O sistema de arquivos proc não está associado a um dispositivo especial e, ao montá-lo, uma palavra-chave arbitrária, como proc, pode ser usada em vez de uma especificação de dispositivo. (A escolha habitual none é menos afortunada: a mensagem de erro 'none busy' da umount pode ser confusa.)

E se dermos uma olhada na procpágina de manual de:

O sistema de arquivos proc é um sistema de pseudo-arquivos que é usado como uma interface para estruturas de dados do kernel. Geralmente é montado em / proc. A maioria é somente leitura, mas alguns arquivos permitem que variáveis ​​do kernel sejam alteradas.

Um pouco mais abaixo na mesma página de manual:

/ proc / cpuinfo

Esta é uma coleção de itens dependentes da CPU e da arquitetura do sistema, para cada arquitetura suportada uma lista diferente. Duas entradas comuns são o processador, que fornece o número da CPU e os bogomips; uma constante do sistema que é calculada durante a inicialização do kernel. Máquinas SMP têm informações para cada CPU. O comando lscpu (1) reúne suas informações deste arquivo.

Na parte inferior da página do manual, há uma referência a um documento do kernel que você pode encontrar aqui, intitulado: THE / proc FILESYSTEM . Citando esse documento:

O sistema de arquivos proc atua como uma interface para estruturas de dados internas no kernel. Ele pode ser usado para obter informações sobre o sistema e alterar determinados parâmetros do kernel em tempo de execução (sysctl).

Conclusões

Então, o que aprendemos aqui? Bem, considerando que /procé referido como um pseudo sistema de arquivos e também uma "interface para estruturas internas de dados", provavelmente é seguro assumir que os itens contidos nele não são arquivos reais, mas apenas manifestações feitas para se parecer com arquivos, mas na verdade não são.

Termino com esta citação que, aparentemente, estava em uma versão anterior da man 5 procde 2004, mas por qualquer motivo não está mais incluída. NOTA: Não sei por que foi removido, pois descreve muito bem o que /procé:

O diretório / proc nos sistemas GNU / Linux fornece uma interface semelhante ao sistema de arquivos para o kernel. Isso permite que aplicativos e usuários obtenham informações e definam valores no kernel usando a operação normal de E / S do sistema de arquivos.

O sistema de arquivos proc às vezes é chamado de sistema de pseudo-arquivos de informações do processo. Ele não contém arquivos `` reais '', mas informações do sistema em tempo de execução (por exemplo, memória do sistema, dispositivos montados, configuração de hardware, etc.). Por esse motivo, pode ser considerado um centro de controle e informações para o kernel. De fato, muitos utilitários de sistema são simplesmente chamadas para arquivos nesse diretório. Por exemplo, o comando lsmod, que lista os módulos carregados pelo kernel, é basicamente o mesmo que 'cat / proc / modules', enquanto o lspci, que lista os dispositivos conectados ao barramento PCI do sistema, é o mesmo que 'cat / proc / pci '. Alterando os arquivos localizados neste diretório, você pode alterar os parâmetros do kernel enquanto o sistema está em execução.

Fonte: O pseudo sistema de arquivos proc

Referências

slm
fonte
1
Cool, :) esta é a primeira coisa que eu tentei que eu vi a pergunta:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
Boa resposta! No linux, se você quiser aprofundar, a fonte do sistema de arquivos proc está em fs / proc na fonte do kernel. Você verá que existe um arquivo fs / proc / cpuinfo.c, mas infelizmente está vazio, pois o trabalho pesado está espalhado por todo o arco / pois depende da arquitetura. Para um exemplo mais simples, consulte fs / proc / uptime.c. Ao olhar para o arquivo, podemos adivinhar que uptime_proc_show é o cavalo de batalha do que nos fornece os dados que queremos e poderíamos explorá-los mais, mergulhando nas funções que chama. Para entender a interface seq_file e como ele é usado em procfs ver:
Steven D
1
@ SLM: +1, ótima resposta. Mas para mim, a primeira dica de que é um arquivo especial é o tamanho ^ ^ 0 bytes, mas você pode extrair muitas coisas dele (um pouco como alguns arquivos de pipe).
Olivier Dulac 27/03
@OlivierDulac - bom ponto. Fiz edições adicionais com base nos seus comentários. LMK se eu puder fazer mais melhorias. Obrigado.
slm
14

A resposta dada pelo @slm é muito abrangente, mas acho que uma explicação mais simples pode vir de uma mudança de perspectiva.

No uso diário, podemos pensar em arquivos como coisas físicas, ie. pedaços de dados armazenados em algum dispositivo. Isso torna arquivos como / proc / cpuinfo muito misteriosos e confusos. No entanto, tudo faz todo sentido se pensarmos nos arquivos como uma interface ; uma maneira de enviar e receber dados de algum programa.

Os programas que enviam e recebem dados dessa maneira são sistemas de arquivos ou drivers (dependendo de como você define esses termos, pode ser uma definição muito ampla ou muito restrita). O ponto importante é que alguns desses programas usam um dispositivo de hardware para armazenar e recuperar os dados enviados por essa interface; mas nem todos.

Alguns exemplos de sistemas de arquivos que não usam um dispositivo de armazenamento (pelo menos diretamente) são:

  • Sistemas de arquivos usando dados consultados ou calculados. Proc é um exemplo, pois obtém dados de vários módulos do kernel. Um exemplo extremo é πfs (github.com/philipl/pifs)
  • Todos os sistemas de arquivos FUSE, que manipulam os dados com um programa regular do espaço do usuário
  • Sistemas de arquivos que transformam os dados de outro sistema de arquivos rapidamente, por exemplo, usando criptografia, compactação ou até mesmo transcodificação de áudio (khenriks.github.io/mp3fs/)

O sistema operacional Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) é um exemplo extremo do uso de arquivos como uma interface de programação geral.

Warbo
fonte