Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Please see my question at the bottom.

This is the command I would like to have executed in a Perl script using system()

zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023

but I get this error

mbuffer: warning: error connecting to 10.10.47.47:8023: Connection refused
mbuffer: error: unable to connect to 10.10.47.47:8023
mbuffer: fatal: no output left - nothing to do

which is misleading, as I can execute the command in a terminal, and it works fine.

So now I have become creative to find a way to work around this limitation. Putting the command in a file and do

system("ssh localhost /tmp/test");

works, but having to SSH to localhost and make temp files are not good. The ssh localhost is needed otherwise I get the same error.

To avoid the temp file creation I tried to make a "parser file"

#!/usr/bin/bash
$1 | $2

which is call pipe.sh and then in Perl do

my $a = 'zfs send tank/Test0@snap';
my $b = "mbuffer -4 -O 10.10.47.47:8023";
system("pipe.sh $a $b");

but the pipe.sh executes zfs | send.

My next idea was

my $c = "zfs send tank/Test0\@snap \| mbuffer -4 -O 10.10.47.47:8023";
system("pipe.sh $c");

with pipe.sh become

#!/usr/bin/bash
$@

but this treats each as a separate command. I.e. zfs, then send and so on.

Question

I have run out of ideas how to execute that command without making a temp file, which is bad, as tank/Test0 is actually a variable inside a for-loop, so it would result in many writes.

Instead of calling a bash script I am open for executing a Ruby or Python script, if they can handle this better than Bash.

Update

If I from the terminal do

perl -e'system "bash", "-c", q{zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023}'

then it works, but doing the same from within the script

system("bash", "-c", q{zfs send tank/Test0@snap | mbuffer -4 -O 10.10.47.47:8023});

gives me (with mbuffer verbose 5 enabled)

mbuffer: Verbose = 5
mbuffer: total # of phys pages: 1132576 (pagesize 4096)
mbuffer: default buffer set to 22651 blocks of 4096 bytes
mbuffer: getting address info for 10.10.47.47:8023
mbuffer: warning: error connecting to 10.10.47.47:8023: Connection refused
mbuffer: error: unable to connect to 10.10.47.47:8023
mbuffer: allocating memory for 22651 blocks with 4096 byte (90604 kB total)...
mbuffer: creating semaphores...
mbuffer: opening input...
mbuffer: direct I/O hinting failed for input: Invalid argument
mbuffer: fatal: no output left - nothing to do

Update 2

This actually works!

system("ssh", "localhost", q{zfs send tank/Test0@snap | mbuffer -4 -v 5 -O 10.10.47.47:8023});

I get the following error with the most verbose enabled, but works for some reason.

mbuffer: Verbose = 5
mbuffer: total # of phys pages: 1130435 (pagesize 4096)
mbuffer: default buffer set to 22608 blocks of 4096 bytes
mbuffer: getting address info for 10.10.47.47:8023
mbuffer: successfully connected to 10.10.47.47:8023
mbuffer: set TCP send buffer size to 1048576
mbuffer: allocating memory for 22608 blocks with 4096 byte (90432 kB total)...
mbuffer: creating semaphores...
mbuffer: opening input...
mbuffer: direct I/O hinting failed for input: Invalid argument
mbuffer: direct I/O hinting failed for output to 10.10.47.47:8023: Invalid argument
mbuffer: checking if we have a controlling terminal...
mbuffer: registering signals...
mbuffer: starting threads...
mbuffer: checking output device...
mbuffer: no device on output stream
mbuffer: checking input device...
mbuffer: no device on input stream
mbuffer: outputThread: starting output on 10.10.47.47:8023...
mbuffer: inputThread: starting with threadid 3...
mbuffer: inputThread: last block has 2640 bytes
mbuffer: inputThread: exiting...
mbuffer: outputThread: last block has 2640 bytes
mbuffer: outputThread: syncing 10.10.47.47:8023...
mbuffer: syncing unsupported on 10.10.47.47:8023: omitted.
mbuffer: outputThread: finished - exiting...
mbuffer: waiting for senders...
mbuffer: joining sender for 10.10.47.47:8023

summary: 46.0 KiByte in  0.0 sec - average of 22.9 MiB/s
share|improve this question
    
Comments are not for extended discussion; this conversation has been moved to chat. –  George Stocker Nov 25 '14 at 18:15

1 Answer 1

up vote 0 down vote accepted

The mbuffer developer has this to say about the error

Concerning the warning related to I/O hinting - these warning can safely be ignored. mbuffer is just telling you that no I/O hinting is possible. I/O hinting just gives tips to the operating system what kind of I/O sequence is coming, so that the OS is able to tune its operation for that specific scenario. I/O hinting is implemented differently for most OSs...

As for the actual problem, then Mojo::IOLoop::ForkCall is the solution as seen in this module, which does exactly what I am trying to do.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.