O pipeline inteiro trava ao liberar a unidade flash USB

3

Estou executando o seguinte pipeline: tar -c directory | pv -T -c -B 2G | gzip -c9 | pv -T -c -B 2G | split -b 1G - /mnt/usbStick/f.tar.gz_

A idéia é gzipar um diretório > 4GB para um pendrive grande e formatado em FAT32 (suporta apenas arquivos < 2GB). split apenas corta um .gz em pedaços de 1 GB.

pv é usado como buffer de cachimbo (2GB cada), principalmente para evitar gzip de afogamento quando tropeça em dados mal compactados e gera dados compactados mais rapidamente do que o USB stick pode gravá-los.

O problema:

Quando outra parte de 1 GB for concluída, split limpará e fechará o arquivo. Ele não começa a escrever a próxima parte até que o flush esteja completo, então ele para de aceitar a entrada.

Espero que o segundo buffer de 2 GB comece a ser preenchido neste ponto, mas em vez disso tudo pára . O sistema está longe de estar totalmente esgotado, mas gzip pára de usar a CPU e até pv pára de atualizar sua saída. Da última parte concluo que todo IO está parado, até mesmo canos. (Prove-me errado se eu sou.)

(Eu estava errado, apenas esse pipeline específico estagnou.)

Então a questão é: por que funciona dessa maneira e como consertar isso?

Editar
Foi realmente pv , buffer funciona bem. A compilação incluída no Ubuntu 16.04 pode usar somente até 2048 blocos de até 512 KB cada ( buffer -m 1024m -s 512k ), mas eles podem ser encadeados para formar um buffer maior.

    
por EvgEnZh 06.10.2016 / 11:18

1 resposta

3

Como pv é apenas uma ferramenta de monitoramento, acho que é um programa de thread único que usa IO síncrono. Se a entrada e a saída estiverem sendo executadas em taxas diferentes, ela preencherá e esvaziará seu buffer para evitar a aceleração, mas se um dos canais estiver completamente paralisado (no seu caso, split não aceitará entrada), a segunda instância pv irá parar na chamada write também. Então, gzip tentará produzir mais dados, estourar o buffer de tubulação e também parar, e assim por diante até que todo o pipeline pare.

Tente usar buffer em vez de pv e veja se isso ajuda. buffer gera dois processos (um para entrada e outro para saída) e deve manter o pipeline funcionando mesmo se a saída estiver completamente paralisada.

    
por 06.10.2016 / 11:39

Tags