socat pipe para pipe para várias operações open-write-close e open-read-close

2

Estou tentando usar socat em dois sistemas para enviar um tar de vários volumes de um sistema para outro. O multivolume é um requisito absoluto, pois estou tentando mudar potencialmente petabytes de dados para um arquivo de fita montado.

Por fim, quero fazer algo assim:

#  on system1:
socat PIPE:/tmp/pipe1 SYSTEM:"ssh system2 socat - PIPE\:/tmp/pipe2" &
tar -M -L 10G -F /tmp/chvol -cvf /tmp/pipe1 <source-path> &

#  on system2:
cat /tmp/pipe2 > file001.tar
cat /tmp/pipe2 > file002.tar
...

(O script chvol apenas ecoa o caminho / tmp / pipe1.)

Como ainda não consegui fazer isso funcionar, estou executando o seguinte teste muito simplificado em um único sistema:

socat PIPE:/tmp/pipe1 PIPE:/tmp/pipe2 &
sh -c 'while sleep 1; do echo "sending date ..."; date > /tmp/pipe1; done' &
sh -c 'while sleep 1; do echo "slurping ..."; cat < /tmp/pipe2; done' &

que serve para simular um processo de gravação repetidamente abrindo, escrevendo, fechando e um processo de leitura abrindo repetidamente, lendo até EOF, fechando.

Mas isso não se comporta como eu esperava: o escritor é aparentemente feliz, mas o leitor lê todo o texto acumulado de uma só vez e depois disso fica bloqueado em uma chamada cat < ... .

Alguém pode explicar (1) o que realmente está acontecendo no teste muito simplificado e (2) o que eu deveria estar fazendo em vez disso?

Eu tentei várias opções de shut-* em ambos os canais (na suposição de que o problema está na propagação do EOF) e fiz um monte de googling.

    
por Alexis Huxley 20.04.2017 / 13:24

1 resposta

2

Seu problema é que você não especificou que deseja pipes unidirecionais. A página de manual explica como, neste caso, PIPE: é como um eco.

O que provavelmente aconteceu foi que quando você escreveu a data no fifo 1, seu socat leu, escreveu para o fifo 2, então percebeu que havia entrada no fifo 2, então leia e escreva para o fifo 1, e assim por diante ocupado loop até que o primeiro cat no fifo 2 conseguiu esvaziá-lo antes de socat lê-lo. Depois disso, este primeiro cat continuará lendo o fifo, nunca vendo um fim de arquivo, e você pode continuar escrevendo a data no fifo.

Você pode ver isso se adicionar a opção -v para socat mostrar o i / o.

Adicionar -u para a E / S unidirecional torna o que você provavelmente queria, mas agora o socat sairá depois que a data for gravada e lida, então você precisará de um loop para ele:

while socat -v -u PIPE:/tmp/pipe1 PIPE:/tmp/pipe2; do echo new; done &

Com a sua versão tar você pode colocar o comando socat dentro do script /tmp/chvol .

Se você tiver uma unidade de fita real, também poderá procurar uma solução usando nbd-server para exportar um dispositivo de bloco a rede.

    
por 20.04.2017 / 18:50