No Linux, existe uma camada/script do sistema que lida com a abertura de arquivos?

No Linux, existe uma camada/script do sistema que lida com a abertura de arquivos?

no Linux, existe uma camada/script que lida com solicitações de programas para abrir arquivos?

Como quando você abre um descritor de arquivo no bash: exec 3 <>/documents/foo.txtou seu editor de texto abre/documents/foo.txt

Não acredito que um editor possa "simplesmente abrir um arquivo" para acesso de leitura/gravação por conta própria.

Prefiro imaginar que isso seja um pedido a uma "camada" (script init.d?) que pode inicialmente abrir apenas uma certa quantidade de arquivos e que mantém o controle sobre os arquivos abertos com seus tipos de acesso, por quais processos eles são abertos, etc.

Responder1

Essa camada está dentro do kernel no Linux e em outros sistemas que não se afastam muito do design histórico do Unix (e também na maioria dos sistemas operacionais não-Unix).

Esta parte do kernel é chamada deCamada VFS (sistema de arquivos virtual). A função do VFS é gerenciar informações sobre arquivos abertos (a correspondência entredescritores de arquivo,abrir descrições de arquivose entradas de diretório), para analisar caminhos de arquivos (interpretando /, .e ..) e para despachar operações em entradas de diretório para o driver de sistema de arquivos correto.

A maioria dos drivers de sistema de arquivos também está no kernel, mas oFUSÍVELO driver do sistema de arquivos permite que essa funcionalidade seja delegada fora do kernel. As operações do sistema de arquivos também podem envolver código de usuário se um armazenamento de nível inferior o fizer, por exemplo, se um sistema de arquivos em disco estiver em umdispositivo de loop.

Responder2

A abertura de arquivos no Linux é feita diretamente pelo kernelmas há várias coisas que você pode fazer para influenciar e estudar o processo.


Diagrama de pilha de armazenamento Linux


Chamadas do sistema

Começando do topo, você pode ver que a interface que os aplicativos usam para interagir com os arquivos échamadas do sistema.

Abrir,lereescreverfaça o que você espera, enquantoEstadoretorna informações sobre um arquivo sem abri-lo.

Você pode estudar o uso de syscalls relacionados a arquivos por um programa usando strace:

$ strace -e trace=%file /bin/ls /etc
[...]
stat("/etc", {st_mode=S_IFDIR|0755,  ...}) = 0
openat(AT_FDCWD, "/etc", O_RDONLY...) = 3

Isso analisa as syscalls causadas por ls /etc, mostrando que state openatsão chamadas no /etcdiretório.

Você deve estar se perguntando por que estamos chamando operações de arquivo em um diretório. No UNIX, os diretórios também são arquivos. Na verdadetudo é um arquivo!


Descritores de arquivo

Você pode estar se perguntando sobre openat() = 3o resultado acima.

No UNIX, os arquivos abertos são representados por umdescritor de arquivo, que é uma representação exclusiva do arquivo aberto por um determinado processo. Os descritores de arquivo 0, 1 e 2 são geralmente reservados para ofluxos padrão(entrada/saída do usuário), então o primeiro arquivo aberto será 3.

Você pode obter uma lista de descritores de arquivos abertos para um determinado processo usandolsof(eueuétócanetafarquivos):

$ cat /dev/urandom > /dev/null &
[1] 3242
$ lsof -p 3242
COMMAND  PID      USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
...
cat     3242 user         0u   CHR  136,0      0t0      3 /dev/pts/0
cat     3242 user         1w   CHR    1,3      0t0   1028 /dev/null
cat     3242 user         2u   CHR  136,0      0t0      3 /dev/pts/0
cat     3242 user         3r   CHR    1,9      0t0   1033 /dev/urandom

A FDcoluna mostra o número do descritor do arquivo, junto com o acesso.

Você também pode usarfuserpara procurar processos que contenham arquivos específicos:

$ fuser /dev/urandom
/dev/urandom:         ...  3242  ...

Pseudo-sistema de arquivos de informações de processo - /proc

Agora você deve estar se perguntando:mas como lsofsaber quais arquivos estão abertos em primeiro lugar?

Bem, vamos dar uma olhada!

$ strace -e trace=%file lsof -p 3242
...
stat("/proc/3242/", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
openat(AT_FDCWD, "/proc/3242/stat", O_RDONLY) = 4
...
openat(AT_FDCWD, "/proc/3242/fd", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
readlink("/proc/3242/fd/0", "/dev/pts/0", 4096) = 10
lstat("/proc/3242/fd/0", {st_mode=S_IFLNK|0700, st_size=64, ...}) = 0
stat("/proc/3242/fd/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
openat(AT_FDCWD, "/proc/3242/fdinfo/0", O_RDONLY) = 7
...

Então lsofsabe quais arquivos estão abertos... lendo mais arquivos! Especificamente, o diretório /proc/3242/fd. Tudo abaixo /procé um sistema de arquivos "falso" mantido pelo kernel. Você pode ls -lver sua estrutura.


Influenciando a abertura de arquivos

Existem vários métodos que você pode usar para influenciar a abertura de arquivos, embora não sejam tão fáceis quanto apenas substituir algum script.

Se você deseja alterar a forma como os arquivos são armazenados ou acessados, como fornecer criptografia, armazená-los em cache, distribuí-los por vários discos ou algo semelhante, há uma boa chance de que já exista ummapeador de dispositivosque atenda às suas necessidades.

Se você deseja um controle refinado sobre a abertura de arquivos em um diretório/montagem específico, você pode escrever um simplesFUSÍVELsistema de arquivos e monte-o.

No nível do programa/processo, você pode usarLD_PRELOADpara alterar as chamadas da biblioteca C e impedi-las de fazer syscalls normais.

A maneira mais difícil, porém mais flexível, seria escrever seu próprio driver de sistema de arquivos.

Responder3

Gerenciar o acesso aos arquivos é a primeira e mais importante função de um sistema operacional. DOS, que é um dos sistemas operacionais mais antigos em computadores pessoais, significa Sistema Operacional de Disco. Ele permitiu que os programas acessassem diretamente o hardware em sua maior parte, mas não para acessar arquivos. Os programas tinham que usar chamadas do DOS e o DOS gerenciaria a entrada e saída de dados dos arquivos do programa. Somente utilitários de disco acessariam o disco rígido e os arquivos diretamente no DOS.

Os sistemas operacionais modernos em modo protegido, como o Linux, lidam com o acesso a arquivos como o DOS, mas também exigem que todo acesso a qualquer coisa fora do próprio programa (ou qualquer outro programa com o qual tenha sido configurado para compartilhar memória) passe pelo kernel (o Linux é um núcleo).

Seu programa no Linux pode chamar uma função na biblioteca C para ler ou gravar dados em um arquivo. A biblioteca C então faz sua parte de organizar o acesso aos dados no arquivo enquanto ainda é executada no mesmo contexto do seu programa. Então a biblioteca C chamará o kernel (Linux) com a função correta para acessar um arquivo, que muda a CPU para o anel 0 ou modo privilegiado. A CPU agora está executando o driver do sistema de arquivos Linux e o software do driver do disco rígido em modo privilegiado que acessa diretamente o hardware para acessar o arquivo. Os dados são copiados para a área de memória onde a biblioteca C instruiu o Linux a colocar os dados, e a CPU volta ao modo de usuário com o contexto de segurança do seu programa e a biblioteca C retoma e faz qualquer processamento necessário. esses dados e depois retorna à execução do seu programa.

Responder4

Resumindo, é isso que acontece quando um programa grava em um arquivo

  1. O programa solicita ao kernel openum arquivo, fornecido por um caminho, para gravação.
  2. O kernel configura algumas estruturas internas e delega parte da tarefa de abrir o arquivo a um driver específico para o tipo de sistema de arquivos. O kernel então retorna um descritor de arquivo, que é apenas um número inteiro (por exemplo, 3), para o programa.
  3. O programa solicita ao kernel writeuma sequência de bytes (por exemplo, uma string) para o arquivo referenciado pelo descritor de arquivo.
  4. O kernel novamente delega trabalho ao driver.
  5. As etapas 3 e 4 provavelmente são repetidas várias vezes.
  6. O programa solicita ao kernel closeo arquivo referenciado pelo descritor de arquivo.
  7. O kernel delega novamente o trabalho ao driver e então destrói as estruturas internas.

Aqui está um programa assembly bastante minimalista que escreve "Hello World!" para o arquivo saudação.txt:

.text
.globl _start

_start:
    # Open and possible create file
    mov $2,             %rax        # syscall 'open'
    mov $path_start,    %rdi        # path
    mov $0101,          %rsi        # create + write
    mov $400,           %edx        # only user gets read permissions
    syscall

    mov %rax,           %r10        # file descriptor

    # Write string to file
    mov $1,             %rax        # syscall 'write'
    mov %r10,           %rdi        # file descriptor
    mov $msg_start,     %rsi        # start of data
    mov $msg_length,    %edx        # length of data
    syscall                         # perform syscall

    # Close file
    mov $3,             %rax        # syscall 'close'
    mov %r10,           %rdi        # file descriptor
    syscall

    # Exit program
    mov $60,            %rax        # syscall 'exit'
    syscall                         # perform syscall


.section .rodata

path_start:
    .string "greeting.txt\0"
path_end:
path_length = path_end - path_start


msg_start:
    .string "Hello World!\n"
msg_end:
msg_length = msg_end - msg_start

Salve o código em write.s e construa usando

as -o write.o write.s
ld -o write   write.o

e então corra com

./write

Espero que tudo funcione.

(Observação: não faço nenhum tratamento de erros. Este é apenas um código de brinquedo.)

informação relacionada