- A investigação começou ao notar uma lentidão enorme ao descompactar um
tar.gz de 518GiB
- Explica o formato Tar e apresenta a implementação de um código de extração de tar rápido
Formato original de arquivo Tar
- O Tar é muito incomum como formato de arquivo compactado
→ Não tem cabeçalho de arquivo, não tem índice de arquivos para busca, não tem magic bytes para identificar que é um tar, não tem rodapé e não tem metadados
→ Dentro do tar existe apenas um tipo de objeto: arquivo
- Tipos de arquivo: 0 (arquivo comum), 1 (link físico), 2 (link simbólico)
- Explicação da estrutura do cabeçalho de objeto de arquivo de 512 bytes
→ A maior limitação é que o caminho do arquivo só pode ter 100 caracteres. Além disso, o tamanho máximo do arquivo é 8GiB
Arquivo com extensão UStar
- O comprimento máximo do caminho do arquivo passa a ser 256, e novos tipos de arquivo são adicionados
- O cabeçalho é expandido com adição de magic bytes e do campo
prefix
- Tipos de arquivo adicionados: 3 (dispositivo de caractere), 4 (dispositivo de bloco), 5 (diretório), 6 (arquivo FIFO), 7 (arquivo contíguo)
- Mas o limite de 8GiB continua existindo
Formato de arquivo Pax
- O padrão POSIX.1-2001 estende o formato tar por meio da CLI
pax
- É igual ao UStar, mas adiciona os formatos de arquivo
x e g
→ Como registros de cabeçalho estendido, x se aplica apenas ao arquivo seguinte, enquanto g se aplica a todos os arquivos posteriores
Formato de arquivo GNU Tar
- Seu formato próprio é
gnu, diferente do pax
- Assim como o pax, é baseado em UStar, mas usa outra forma de codificar caminhos e arquivos grandes
→ Tipo L: o payload do próximo objeto de arquivo representa file_path
→ Tipo K: o payload do próximo objeto de arquivo representa link_path
→ É possível aplicar os dois em sequência
→ Se o arquivo for maior que 8GiB, o bit mais alto do primeiro caractere de file_size é ativado. Então o restante da string é interpretado em base 256 (inteiro de 95 bits)
Por que o GNU tar é lento para descompactar?
- Se o cabeçalho de um arquivo contiver um valor como
file_path="../hello.txt", isso gera um problema de segurança. Mas bloquear isso não é simples
- O GNU tar, ao encontrar
".." em link_path, cria um placeholder e adia o processamento
- Porém, no caso de links físicos sem
"..", ele gostaria de criá-los diretamente, mas isso não é possível porque o placeholder já existe
- Ou seja, para criar um link físico, primeiro é preciso verificar completamente se ele é um link adiado; se for, o novo link também precisa ser adiado
→ Para todos os links físicos, é necessário procurar links adiados. Não se sabe o motivo, mas na prática essa busca é feita duas vezes
- No arquivo Tar do autor, havia mais de 800 mil links contendo
".." e mais de 5,4 milhões de links físicos, o que tornou a descompactação lenta
- Para evitar isso, adicione ao tar a opção
--absolute-paths ou -P
→ É a opção que salva caminhos absolutos e rejeita ".."
→ Ou seja, ao usar a opção -P, o mecanismo de links adiados é desativado
1 comentários
Textos sobre tar sempre parecem interessantes..
hop - um formato de arquivo 10 vezes mais rápido que o tar
Por que um arquivo tar.xz criado em Python é menor do que um criado com o tar padrão?