Essa é uma pergunta de baixo nível, e entendo que talvez não seja o melhor lugar para perguntar. Mas, parecia mais apropriado do que qualquer outro site SE, então aqui vai.
Eu sei que no sistema de arquivos Linux, existem alguns arquivos , por exemplo: /usr/bin/bash
é um que existe. No entanto, (tanto quanto eu entendo), alguns também não realmente existir como tal e são mais virtuais arquivos, por exemplo: /dev/sda
, /proc/cpuinfo
, etc. Minhas perguntas são (são dois, mas também intimamente relacionado para ser questões separadas):
- Como o kernel do Linux descobre se esses arquivos são reais (e, portanto, os lêem no disco) ou não, quando um comando de leitura (ou tal) é emitido?
- Se o arquivo não for real: como exemplo, uma leitura de
/dev/random
retornará dados aleatórios e uma leitura de/dev/null
retornaráEOF
. Como funciona os dados a serem lidos nesse arquivo virtual (e, portanto, o que fazer quando / se os dados também são gravados no arquivo virtual) - existe algum tipo de mapa com ponteiros para separar os comandos de leitura / gravação apropriados para cada arquivo, ou mesmo para o próprio diretório virtual? Portanto, uma entrada para/dev/null
poderia simplesmente retornar umEOF
.
linux
filesystems
devices
Joe
fonte
fonte
Respostas:
Portanto, existem basicamente dois tipos diferentes de coisas aqui:
/proc
e/sys
são exemplos aqui, assim como os sistemas de arquivos personalizados do FUSE, comosshfs
ouifuse
. Há muito mais diversidade nelas, porque na verdade elas se referem a um sistema de arquivos com semântica que, em certo sentido, é "personalizada". Portanto, quando você lê um arquivo em baixo/proc
, na verdade não está acessando uma parte específica de dados que foi armazenada por outra coisa que foi gravada anteriormente, como em um sistema de arquivos normal. Você está essencialmente fazendo uma chamada do kernel, solicitando algumas informações geradas on-the-fly. E esse código pode fazer o que quiser, pois é apenas uma função em algum lugar implementandoread
semântica. Assim, você tem o comportamento estranho dos arquivos/proc
, como, por exemplo, fingir ser links simbólicos quando eles não são 'A chave é que
/dev
, na verdade, geralmente é do primeiro tipo. É normal nas distribuições modernas ter/dev
algo como um tmpfs, mas em sistemas mais antigos era normal ter um diretório simples no disco, sem atributos especiais. A chave é que os arquivos abaixo/dev
são nós do dispositivo, um tipo de arquivo especial semelhante aos soquetes FIFOs ou Unix; um nó de dispositivo possui um número maior e menor, e a leitura ou gravação deles está fazendo uma chamada para um driver do kernel, assim como a leitura ou gravação de um FIFO está chamando o kernel para armazenar sua saída em buffer em um pipe. Este driver pode fazer o que quiser, mas geralmente toca no hardware de alguma forma, por exemplo, para acessar um disco rígido ou reproduzir som nos alto-falantes.Para responder às perguntas originais:
Há duas questões relevantes para saber se o 'arquivo existe' ou não; é se o arquivo do nó do dispositivo existe literalmente e se o código do kernel que o suporta é significativo. O primeiro é resolvido como qualquer coisa em um sistema de arquivos normal. Os sistemas modernos usam
udev
ou algo parecido para observar eventos de hardware e criar e destruir automaticamente os nós de dispositivos de/dev
acordo. Porém, sistemas mais antigos, ou construções leves e personalizadas, podem ter todos os nós de dispositivos literalmente no disco, criados com antecedência. Enquanto isso, quando você lê esses arquivos, está fazendo uma chamada para o código do kernel, que é determinado pelos números de dispositivos principais e secundários; se isso não for razoável (por exemplo, você estiver tentando ler um dispositivo de bloco que não existe), você receberá algum tipo de erro de E / S.A maneira como funciona o código do kernel para qual arquivo de dispositivo varia. Para sistemas de arquivos virtuais como
/proc
, eles implementam suas próprias funçõesread
ewrite
; o kernel apenas chama esse código, dependendo do ponto de montagem em que está, e a implementação do sistema de arquivos cuida do resto. Para arquivos de dispositivo, ele é enviado com base nos números de dispositivos principais e secundários.fonte
/dev
ainda estariam lá, mas acho que eles seriam limpos quando o sistema inicializar?tmpfs
criaria e excluiria dinamicamente conforme necessário, por exemplo: inicialização e desligamento?devtmpfs
, o/dev
sistema de arquivos no Linux moderno, é semelhante a umtmpfs
, mas tem algumas diferenças para oferecer suporteudev
. (O kernel faz a criação automática de nós por conta própria antes de entregá-udev
los, a fim de tornar a inicialização menos complicada.) Em todos esses casos, os nós dos dispositivos vivem apenas na RAM e são criados e destruídos dinamicamente conforme o hardware exige. Presumivelmente, você também pode usarudev
em um disco comum/dev
, mas nunca vi isso feito e não parece haver boas razões para isso.Aqui está uma lista de arquivos do
/dev/sda1
meu servidor Arch Linux quase atualizado:Assim, a entrada de diretório no
/dev/
parasda
tem um número de inode, 1294. É um arquivo real no disco.Veja onde o tamanho do arquivo geralmente aparece. "8, 1" aparece em seu lugar. Este é um número de dispositivo principal e secundário. Observe também o 'b' nas permissões de arquivo.
O arquivo
/usr/include/ext2fs/ext2_fs.h
contém essa estrutura C (fragmento):Essa estrutura nos mostra a estrutura em disco do inode de um arquivo. Muitas coisas interessantes estão nessa estrutura; dê uma olhada longa nisso.
O
i_mode
elementostruct ext2_inode
possui 16 bits e usa apenas 9 para o usuário / grupo / outro, permissões de leitura / gravação / execução e outros 3 para setuid, setgid e sticky. Possui 4 bits para diferenciar tipos como "arquivo simples", "link", "diretório", "pipe nomeado", "soquete da família Unix" e "dispositivo de bloco".O kernel do Linux pode seguir o algoritmo usual de pesquisa de diretório e tomar uma decisão com base nas permissões e sinalizadores no
i_mode
elemento. Para 'b', bloquear arquivos de dispositivos, ele pode encontrar os números de dispositivos principais e secundários e, tradicionalmente, usar o número do dispositivo principal para procurar um ponteiro para alguma função do kernel (um driver de dispositivo) que lida com discos. O número menor do dispositivo geralmente é usado como, por exemplo, o número do dispositivo do barramento SCSI ou o número do dispositivo EIDE ou algo parecido.Algumas outras decisões sobre como lidar com um arquivo como
/proc/cpuinfo
são tomadas com base no tipo de sistema de arquivos. Se você fizer um:você pode ver que
/proc
possui o tipo de sistema de arquivos "proc". A leitura de um arquivo no/proc
faz com que o kernel faça algo diferente com base no tipo do sistema de arquivos, assim como abrir um arquivo em um sistema de arquivos ReiserFS ou DOS faria com que o kernel usasse funções diferentes para localizar arquivos e localizar dados do arquivos.fonte
4026531975 -r--r--r-- 1 root root 0 Nov 14 18:41 /proc/mdstat
que claramente não é um "arquivo real".No final das contas, todos são arquivos para o Unix, essa é a beleza da abstração.
A maneira como os arquivos são manipulados pelo kernel, agora essa é uma história diferente.
/ proc e atualmente / dev e / run (também conhecido como / var / run) são sistemas de arquivos virtuais na RAM. / proc é uma interface / windows para variáveis e estruturas do kernel.
Eu recomendo a leitura do The Linux Kernel http://tldp.org/LDP/tlk/tlk.html e dos drivers de dispositivo Linux, terceira edição https://lwn.net/Kernel/LDD3/ .
Eu também gostei de Design e implementação do sistema operacional FreeBSD http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Dê uma olhada na página relevante que pertence à sua pergunta.
http://www.tldp.org/LDP/tlk/dd/drivers.html
fonte
Além das respostas de @ RuiFRibeiro e @ BruceEdiger, a distinção que você faz não é exatamente a distinção que o kernel faz. Na verdade, você tem vários tipos de arquivos: arquivos regulares, diretórios, links simbólicos, dispositivos, soquetes (e eu sempre esqueço alguns, para não tentar fazer uma lista completa). Você pode ter as informações sobre o tipo de arquivo
ls
: é o primeiro caractere na linha. Por exemplo:O 'b' no início indica que esse arquivo é um dispositivo de bloco. Um traço, significa um arquivo regular, 'l' um link simbólico e assim por diante. Essas informações são armazenadas nos metadados do arquivo e são acessíveis através da chamada do sistema,
stat
por exemplo, para que o kernel possa ler de maneira diferente um arquivo e um link simbólico, por exemplo.Em seguida, você faz outra distinção entre "arquivos reais"
/bin/bash
e "arquivos virtuais",/proc/cpuinfo
masls
informa ambos como arquivos regulares, portanto a diferença é de outro tipo:O que acontece é que eles pertencem a diferentes sistemas de arquivos.
/proc
é o ponto de montagem de um pseudo-sistema de arquivosprocfs
enquanto/bin/bash
em um sistema de arquivos em disco comum. Quando o Linux abre um arquivo (de maneira diferente dependendo do sistema de arquivos), ele preenche uma estrutura de dadosfile
que possui, entre outros atributos, uma estrutura de vários indicadores de função que descrevem como usar esse arquivo. Portanto, ele pode implementar comportamentos distintos para diferentes tipos de arquivos.Por exemplo, estas são as operações anunciadas por
/proc/meminfo
:Se você observar a definição de
meminfo_proc_open
, poderá ver que essa função preenche um buffer na memória com as informações retornadas pela funçãomeminfo_proc_show
, cuja tarefa é coletar dados sobre o uso da memória. Esta informação pode ser lida normalmente. Sempre que você abre o arquivo, a funçãomeminfo_proc_open
é chamada e as informações sobre a memória são atualizadas.fonte
Todos os arquivos em um sistema de arquivos são "reais" no sentido em que permitem E / S de arquivo. Quando você abre um arquivo, o kernel cria um descritor de arquivo, que é um objeto (no sentido de programação orientada a objetos) que age como um arquivo. Se você ler o arquivo, o descritor de arquivo executará seu método de leitura, que, por sua vez, solicitará ao sistema de arquivos (sysfs, ext4, nfs etc.) dados do arquivo. Os sistemas de arquivos apresentam uma interface uniforme para o espaço do usuário e sabem o que fazer para lidar com leituras e gravações. Os sistemas de arquivos, por sua vez, solicitam que outras camadas tratem de suas solicitações. Para um arquivo regular, por exemplo, um sistema de arquivos ext4, isso envolverá pesquisas nas estruturas de dados do sistema de arquivos (que podem envolver leituras de disco) e, eventualmente, uma leitura do disco (ou cache) para copiar dados no buffer de leitura. Para um arquivo em say sysfs, geralmente apenas sprintf () é algo para o buffer. Para um nó de desenvolvimento de bloco, ele solicitará ao driver de disco que leia alguns blocos e copie-os no buffer (os números principais e secundários informam ao sistema de arquivos para qual driver solicitar).
fonte