O que acontece quando eu escrevo cat /proc/cpuinfo
. É um pipe nomeado (ou algo mais) para o sistema operacional que lê as informações da CPU em tempo real e gera esse texto toda vez que eu o chamo?
O que acontece quando eu escrevo cat /proc/cpuinfo
. É um pipe nomeado (ou algo mais) para o sistema operacional que lê as informações da CPU em tempo real e gera esse texto toda vez que eu o chamo?
Respostas:
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 ps
muitas vezes é uma bonita impressora de informações lidas /proc
). A maioria das implementações do procfs tem um arquivo ou diretório chamado /proc/123
para 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 /proc
adquiria vários arquivos que forneciam informações sobre drivers, mas esse uso agora é preterido em favor /sys
e /proc
agora evolui lentamente. As entradas gostam /proc/bus
e /proc/fs/ext4
permanecem 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 /proc
Linux são:
proc(5)
página do manual ;/proc
sistema 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 /proc
entradas está no fs/proc
diretó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_entry
e alguns wrappers (especialmente create_proc_read_entry
), e as versões do kernel 3.10 e superior fornecem apenas proc_create
e proc_create_data
(e mais algumas).
Tomando /proc/cpuinfo
como 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 /proc
despeja apenas alguns dados de texto, há funções auxiliares para fazer isso. Existe apenas uma seq_operations
estrutura, e a carne real está na cpuinfo_op
estrutura 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_stuff
conjunto ; algumas funções registradas aqui são definidas em outros arquivos. Vejamos alguns exemplos de como essas entradas são geradas:
cmdline
é gerado por proc_pid_cmdline
no mesmo arquivo. Ele localiza os dados no processo e os imprime.clear_refs
, diferentemente das entradas que vimos até agora, é gravável, mas não legível. Portanto, as proc_clear_refs_operations
estruturas definem uma clear_refs_write
função, mas nenhuma função de leitura.cwd
é um link simbólico (um pouco mágico), declarado por proc_cwd_link
, que consulta o diretório atual do processo e o retorna como o conteúdo do link.fd
é um subdiretório. As operações no próprio diretório são definidas na proc_fd_operations
estrutura de dados (elas são padrão, exceto pela função que enumera as entradas proc_readfd
, que enumera os arquivos abertos do processo) enquanto as operações nas entradas estão em `proc_fd_inode_operations .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_sysctl
e amigos.
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.
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
.
$ 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/cpuinfo
parece 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 mount
comando
$ 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 /proc
são especiais. Eles não são apenas seus arquivos comuns. Então, vamos descobrir mais algumas informações sobre o que torna o proc
sistema de arquivos especial.
Dando uma olhada na mount
pá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 proc
pá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).
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 proc
de 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
strace -o catcpuproc.txt cat /proc/cpuinfo
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:
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.