Como / proc / * funciona?

62

Há muitos arquivos /proc, como /proc/cpuinfo, /proc/meminfo, /proc/devicese assim por diante, que, quando aberto, informações do sistema de retorno.

Esses arquivos parecem não existir na realidade, pois a execução fileneles apenas indica que eles estão vazios.

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

Como esses arquivos funcionam exatamente?

user2064000
fonte

Respostas:

72

Na verdade, é bem simples, pelo menos se você não precisar dos detalhes da implementação.

Primeiro, no Linux todos os sistemas de arquivos (ext2, ext3, btrfs, reiserfs, tmpfs, zfs, ...) são implementados no kernel. Alguns podem descarregar o trabalho para o código da terra do usuário através do FUSE, e outros vêm apenas na forma de um módulo do kernel (o ZFS nativo é um exemplo notável deste último devido a restrições de licença), mas de qualquer forma permanece um componente do kernel. Este é um importante básico.

Quando um programa quer ler a partir de um arquivo, ele irá emitir várias chamadas de bibliotecas do sistema que finalmente acabam no kernel na forma de um open(), read(), close()seqüência (possivelmente com seek()jogado em boa medida). O kernel usa o caminho e o nome do arquivo fornecidos e, através do sistema de arquivos e da camada de E / S do dispositivo, os converte em solicitações de leitura física (e em muitos casos também solicitações de gravação - pense, por exemplo, atualizações atime) em algum armazenamento subjacente.

No entanto, ele não precisa converter essas solicitações especificamente para armazenamento físico persistente . O contrato do kernel é que a emissão desse conjunto específico de chamadas do sistema fornecerá o conteúdo do arquivo em questão . Onde exatamente em nosso domínio físico o "arquivo" existe é secundário a isso.

Em /procgeralmente é montado o que é conhecido como procfs. Esse é um tipo especial de sistema de arquivos, mas como é um sistema de arquivos, na verdade não é diferente de, por exemplo, um ext3sistema de arquivos montado em algum lugar. Portanto, a solicitação é passada para o código do driver do sistema de arquivos procfs, que conhece todos esses arquivos e diretórios e retorna informações específicas das estruturas de dados do kernel .

A "camada de armazenamento", neste caso, são as estruturas de dados do kernel e procfsfornece uma interface limpa e conveniente para acessá-las. Lembre-se de que montar procfs no /procé simplesmente uma convenção; você poderia facilmente montá-lo em outro lugar. De fato, isso às vezes é feito, por exemplo, nas cadeias chroot quando o processo em execução lá precisa acessar / proc por algum motivo.

Funciona da mesma maneira se você escrever um valor em algum arquivo; no nível do kernel, que se traduz em uma série de open(), seek(), write(), close()chamadas que novamente são passadas para o driver de sistema de arquivos; novamente, nesse caso em particular, o código procfs.

A razão específica pela qual você vê o fileretorno emptyé que muitos dos arquivos expostos pelo procfs são expostos com um tamanho de 0 bytes. O tamanho de 0 byte é provavelmente uma otimização no lado do kernel (muitos dos arquivos em / proc são dinâmicos e podem variar facilmente em comprimento, possivelmente até de uma leitura para a próxima, e calcular o tamanho de cada arquivo em cada diretório lido potencialmente muito caro). Indo pelos comentários a esta resposta, que você pode verificar em seu próprio sistema, executando o strace ou uma ferramenta semelhante, fileemite uma stat()chamada para detectar arquivos especiais e, em seguida, aproveita a oportunidade para, se o tamanho do arquivo for 0 , anule e relate o arquivo como vazio.

Esse comportamento é realmente documentado e pode ser substituído, especificando -sou --special-filesna fileinvocação, embora conforme declarado na página de manual que possa ter efeitos colaterais. A citação abaixo é da página do manual do arquivo BSD 5.11, de 17 de outubro de 2011.

Normalmente, o arquivo tenta apenas ler e determinar o tipo de arquivos de argumento que os relatórios stat (2) são arquivos comuns. Isso evita problemas, porque a leitura de arquivos especiais pode ter consequências peculiares. A especificação da -sopção faz com que o arquivo também leia arquivos de argumento que são arquivos especiais de bloco ou caractere. Isso é útil para determinar os tipos de sistema de arquivos dos dados nas partições de disco bruto, que são arquivos especiais de bloco. Essa opção também faz com que o arquivo desconsidere o tamanho do arquivo, conforme relatado pelo stat (2), pois em alguns sistemas ele relata um tamanho zero para partições de disco bruto.

um CVn
fonte
5
Quando você olha para ele com strace file /proc/versionou ltrace -S /proc/version, a otimização é bastante pequena. Ele faz uma stat()chamada primeiro e descobre que o tamanho é 0, pulando o open()- mas antes disso está carregando vários arquivos mágicos.
ott--
2
@ ott-- Essa é realmente uma sequência ímpar de eventos, mas pode estar relacionada ao fato de que você pode passar vários nomes de arquivos para file. Dessa forma, o arquivo pré-carrega os arquivos mágicos e processa o parâmetro da linha de comando por parâmetro; em vez de mover o carregamento do arquivo mágico para a parte "faça isso imediatamente antes de tentar determinar que tipo de arquivo esse particular" é "parte do código, o que aumentaria a complexidade. Chamar stat()e agir com base no seu valor de retorno é essencialmente inofensivo; adicionando complexidade para acompanhar riscos internos adicionais do estado, introduzindo bugs.
um CVn 15/07/2013
@ ott-- Na verdade, o motivo pelo qual os filerelatórios relatam “o arquivo está vazio” é porque ele chama statpara detectar arquivos especiais (chamados pipes, dispositivos,…) e aproveita a oportunidade para parar de processar arquivos vazios. file -s /proc/versionrelata "texto ASCII".
Gilles 'SO- stop be evil'
4
@Gilles Suporta -sdispositivos especiais de bloco / caractere. Finalmente, olhei para a filefonte e, no final de fsmagic.c, vi esta explicação por que ela retorna em ASCII textvez de empty:If stat() tells us the file has zero length, report here that the file is empty, so we can skip all the work of opening and reading the file. But if the -s option has been given, we skip this optimization, since on some systems, stat() reports zero size for raw disk partitions.
ott--
15

Nesse diretório, você pode controlar como o kernel exibe os dispositivos, ajustar as configurações do kernel, adicionar dispositivos ao kernel e removê-los novamente. Nesse diretório, você pode visualizar diretamente o uso da memória e as estatísticas de E / S.

Você pode ver quais discos estão montados e quais sistemas de arquivos são usados. Em resumo, todos os aspectos do seu sistema Linux podem ser examinados nesse diretório, se você souber o que procurar.

O /procdiretório não é um diretório normal. Se você fosse inicializar a partir de um CD de inicialização e olhar para esse diretório no disco rígido, verá que está vazio. Quando você o observa no seu sistema em execução normal, ele pode ser bastante grande. No entanto, ele não parece estar usando espaço em disco rígido. Isso ocorre porque é um sistema de arquivos virtual.

Como o /procsistema de arquivos é um sistema de arquivos virtual e reside na memória, um novo /procsistema de arquivos é criado toda vez que a máquina Linux é reinicializada.

Em outras palavras, é apenas um meio de espiar e cutucar facilmente as entranhas do sistema Linux através de uma interface de tipo de arquivo e diretório. Quando você olha para um arquivo no /procdiretório, está olhando diretamente para um intervalo de memória no kernel do Linux e vendo o que ele pode ver.

As camadas no sistema de arquivos

Digite a descrição da imagem aqui

Exemplos:

  • Dentro /proc, há um diretório para cada processo em execução, nomeado com seu ID do processo. Esses diretórios contêm arquivos que possuem informações úteis sobre os processos, como:
    • exe: que é um link simbólico para o arquivo no disco em que o processo foi iniciado.
    • cwd: que é um link simbólico para o diretório de trabalho do processo.
    • wchan: que, quando lido, retorna o canal de espera em que o processo está.
    • maps: que, quando lido, retorna os mapas de memória do processo.
  • /proc/uptime retorna o tempo de atividade como dois valores decimais em segundos, separados por um espaço:
    • a quantidade de tempo desde que o kernel foi iniciado.
    • a quantidade de tempo que o kernel ficou ocioso.
  • /proc/interrupts: Para informações relacionadas a interrupções.
  • /proc/modules: Para uma lista de módulos.

Para informações mais detalhadas, consulte man proc ou kernel.org .

stderr
fonte
"Se você fosse inicializar a partir de um CD de inicialização e olhar para esse diretório no seu disco rígido, verá que está vazio." Isso não é específico para / proc, é geral para qualquer ponto de montagem em que o sistema de arquivos subjacente não tenha sido montado. Se você inicializar com o mesmo CD de inicialização e fizer algo parecido mount -t procfs procfs /mnt/proc, verá o / proc do kernel atualmente em execução.
a CVn 15/07/2013
5

Você está correto, eles não são arquivos reais.

Em termos mais simples, é uma maneira de conversar com o kernel usando os métodos normais de leitura e gravação de arquivos, em vez de chamar o kernel diretamente. Está de acordo com a filosofia "tudo é um arquivo" do Unix.

Os arquivos /procnão existem fisicamente em lugar algum, mas o kernel reage aos arquivos que você lê e escreve nele e, em vez de gravar no armazenamento, relata informações ou faz alguma coisa.

Da mesma forma, os arquivos /devnão são realmente arquivos no sentido tradicional (embora em alguns sistemas os arquivos /devpossam realmente existir no disco, eles não terão muito mais do que o dispositivo a que se referem) - eles permitem que você fale para um dispositivo usando a API de E / S de arquivo Unix normal - ou qualquer coisa que o use, como shells

LawrenceC
fonte
11
É mais parecido com * nix que apenas um arquivo pode ser protegido. Como as listas de controle de acesso são mantidas no sistema de arquivos, é conveniente proteger recursos privilegiados usando o mecanismo comum já fornecido pelo driver do sistema de arquivos. Isso simplifica a implementação de ferramentas que acessam as estruturas do kernel e permite que elas sejam executadas sem permissões elevadas, lendo os arquivos virtuais do sistema de arquivos proc.
Pekka
3

Dentro do /procdiretório, existem dois tipos de conteúdo, o primeiro diretório numerado e o segundo é o arquivo de informações do sistema.

/procé um sistema de arquivos virtual. Por exemplo, se você fizer isso ls -l /proc/stat, notará que ele tem um tamanho de 0 bytes, mas se você fizer "cat / proc / stat", verá algum conteúdo dentro do arquivo.

Faça um ls -l /proce verá muitos diretórios com apenas números. Esses números representam os IDs do processo (PIDs). Os arquivos dentro desse diretório numerado correspondem ao processo com esse PID específico.

Alguns arquivos disponíveis em /proccontém informações do sistema, como cpuinfo, meminfo e loadavg.

Alguns comandos do Linux leem as informações desses /procarquivos e as exibem. Por exemplo, o comando free , lê as informações de memória do /proc/meminfoarquivo, formata-as e exibe-as.

Para aprender mais sobre os /procarquivos individuais , faça “man 5 FILENAME”.

/proc/cmdline – Kernel command line
/proc/cpuinfo – Information about the processors.
/proc/devices – List of device drivers configured into the currently running kernel.
/proc/dma – Shows which DMA channels are being used at the moment.
/proc/fb – Frame Buffer devices.
/proc/filesystems – File systems supported by the kernel.
/proc/interrupts – Number of interrupts per IRQ on architecture.
/proc/iomem – This file shows the current map of the system’s memory for its various devices
/proc/ioports – provides a list of currently registered port regions used for input or output communication with a device
/proc/loadavg – Contains load average of the system
The first three columns measure CPU utilization of the last 1, 5, and 10 minute periods.
The fourth column shows the number of currently running processes and the total number of processes.
The last column displays the last process ID used.
/proc/locks – Displays the files currently locked by the kernel
Sample line:
1: POSIX ADVISORY WRITE 14375 08:03:114727 0 EOF
/proc/meminfo – Current utilization of primary memory on the system
/proc/misc – This file lists miscellaneous drivers registered on the miscellaneous major device, which is number 10
/proc/modules – Displays a list of all modules that have been loaded by the system
/proc/mounts – This file provides a quick list of all mounts in use by the system
/proc/partitions – Very detailed information on the various partitions currently available to the system
/proc/pci – Full listing of every PCI device on your system
/proc/stat – Keeps track of a variety of different statistics about the system since it was last restarted
/proc/swap – Measures swap space and its utilization
/proc/uptime – Contains information about uptime of the system
/proc/version – Version of the Linux kernel, gcc, name of the Linux flavor installed.
Shailesh
fonte
2
Isso me parece mais como "como usar o que está em / proc?" ao invés de "como / proc funciona?". Informações úteis, mas não necessariamente respondendo a essa pergunta em particular .
um CVn 15/07/2013
Cada arquivo em / proc é uma informação de tempo de execução, o que significa que, quando você cat / proc / meminfo, parte do kernel executa uma função que gera o conteúdo do arquivo.
Shailesh
3

Exemplo mínimo executável

A melhor maneira de entender essas coisas na minha opinião é realmente brincar com elas, então aqui está um módulo do kernel que cria uma entrada procfs:

myprocfs.c

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_open, single_release */
#include <uapi/linux/stat.h> /* S_IRUSR */

static const char *filename = "lkmc_procfs";

static int show(struct seq_file *m, void *v)
{
    seq_printf(m, "abcd\n");
    return 0;
}

static int open(struct inode *inode, struct  file *file)
{
    return single_open(file, show, NULL);
}

static const struct file_operations fops = {
    .llseek = seq_lseek,
    .open = open,
    .owner = THIS_MODULE,
    .read = seq_read,
    .release = single_release,
};

static int myinit(void)
{
    proc_create(filename, 0, NULL, &fops);
    return 0;
}

static void myexit(void)
{
    remove_proc_entry(filename, NULL);
}

module_init(myinit)
module_exit(myexit)
MODULE_LICENSE("GPL");

e então interagimos com ele como:

insmod procfs.ko
cat /proc/lkmc_procfs

e que produz a saída:

abcd

Neste exemplo, vemos claramente que os procarquivos nos permitem implementar "chamadas de sistema relacionadas a arquivos" arbitrárias, como open, reade llseek.

Essas chamadas do sistema podem ser usadas para comunicação arbitrária com o kernel.

Portanto, esses arquivos não precisam ter nada a ver com arquivos reais em sistemas de arquivos, e esse é o caso de quase todos eles.

Em nosso pequeno exemplo, por exemplo, simplesmente criamos um arquivo inútil para o qual readsempre retorna abcd\n.

Aqui está minha configuração totalmente automatizada do QEMU + Buildroot para criar e jogar com facilidade e segurança com este módulo do kernel:

Algumas outras interfaces semelhantes incluem:

Ciro Santilli adicionou uma nova foto
fonte