Um arquivo virtual que contém a concatenação de outros arquivos

13

Existe uma maneira de criar um objeto de sistema de arquivos semelhante a este:

mknod files p
cat file1 file2 ... fileN > files

mas de modo que possa ser procurado, como se fosse um arquivo regular?

Witiko
fonte

Respostas:

18

Nos sistemas operacionais baseados em Linux, isso pode ser feito com dispositivos de bloco de rede ou dispositivos mapeadores de dispositivos. O arquivo que você obtém é um dispositivo de bloco.

Com nbd:

ln -s /path/to/first-file file.0
...
ln -s /path/to/last-file file.19
nbd-server -C /dev/null -m 127.0.0.1:12345 file

sudo nbd-client localhost 12345 /dev/nbd0

(a concatenação é /dev/nbd0).

Com o mapeador de dispositivos (os tamanhos dos arquivos precisam ser múltiplos de 512):

sudo losetup /dev/loop0 file1
sudo losetup /dev/loop1 file2
s0=$(sudo blockdev --getsize /dev/loop0)
s1=$(sudo blockdev --getsize /dev/loop1)
printf '%s\n' "0 $s0 linear /dev/loop0 0" "$s0 $s1 linear /dev/loop1 0" |
  sudo dmsetup create mybundle

(a concatenação é /dev/mapper/mybundle).

Stéphane Chazelas
fonte
8

escreveu um driver de fusível hoje, se alguém estiver interessado na solução de fusíveis (o mapeador de dispositivos e a solução nbd acima criarão dispositivos de bloco, não arquivos regulares - o que será interrompido se você quiser usar a saída resultante diretamente com a edição de vídeo software ou outras ferramentas que não estão preparadas para ler diretamente de um dispositivo de bloco)

https://github.com/schlaile/concatfs

Pedro
fonte
Muito educativo e simples de usar código fonte! Obrigado por fazer e compartilhar!
Grzegorz Wierzowiecki
3

Você basicamente respondeu na primeira frase da pergunta: sim, isso pode ser feito. No entanto, você teria que escrever um driver de sistema de arquivos personalizado. Se é para ser um objeto do sistema de arquivos, ele deve ser tratado pelo kernel em algum nível (que inclui o FUSE ). O driver teria que fornecer back-end para a API syscalls do sistema de arquivos padrão ( stat(), open()etc., incluindo a busca). Você não pode fazê-lo inteiramente no espaço do usuário (pelo menos não com um kernel monolítico - mas mesmo com um microkernel você ainda precisará fornecer um driver de sistema de arquivos, embora seja executado como um processo regular do espaço do usuário).

peterph
fonte
É bastante óbvio que isso pode ser feito. O que eu estou curioso é se existe alguma maneira de hack rápido para conseguir isso usando os pacotes un * x padrão - preferencialmente via bash sem a necessidade de escrever um driver de espaço no kernel dedicado.
Witiko
1
veja a resposta de Stephane - esqueci completamente o mapeador de dispositivos.
Peterph