diff --git a/pmirror/pmirror b/pmirror/pmirror index b86b9fd..0efa5c2 100755 --- a/pmirror/pmirror +++ b/pmirror/pmirror @@ -172,7 +172,7 @@ our ($debug,$quiet,$fileop_noop,$fileop_debug,$delete); our ($slave_mode,$local_slave,$slave_unprivileged, $lockident,$safety,$identity_file,$mkdir_slave, $reduce,$force_status,$bandwidth,$allowremotefs, - $ssh_opt , $cksum , $nice ); + $ssh_opt , $cksum , $nice , $unix_socket, $unix_socket_name); # globals @@ -598,6 +598,7 @@ sub master $allowremotefs and push @remote_opts,'--allowremotefs'; $cksum and push @remote_opts,'--cksum'; $nice and push @remote_opts,'--nice'; + $unix_socket_name and push @remote_opts,'--socket-name',$unix_socket_name; ($slave_unprivileged or ($slave_user ne 'root')) and push @remote_opts,'--unprivileged'; @@ -609,6 +610,7 @@ sub master ,'-x', '-l',$slave_user, '-oFallBackToRsh=no','-oStrictHostKeyChecking=no', + $unix_socket_name ? ('-L',"$unix_socket_name:$unix_socket_name") : (), $ssh_opt ? $ssh_opt : (), $slave, '/usr/local/bin/pmirror','--slave',@remote_opts,$slave_path @@ -621,6 +623,7 @@ sub master } $debug and warn "executing @l\n"; + $unix_socket_name and -e $unix_socket_name and unlink($unix_socket_name); exec @l; die "ssh: exec failed: $!\n"; } @@ -634,12 +637,20 @@ sub master local($, , $\)=(' ',"\n"); if ($slave) { + my $s_data; $_=$in->getline; defined $_ or die "client disconnected\n"; - /^LISTEN (\d+)$/ or die "protokoll error; expected LISTEN got $_\n"; - my $port=$1; - $debug and warn "connecting data port $slave:$port\n"; - my $s_data=new IO::Socket::INET (PeerHost=>$slave,PeerPort=>$port,Proto=>'tcp') or die "connect to slave data port: $!\n"; + if ($unix_socket_name) { + /^LISTEN (\S+)$/ or die "protocol error; expected 'LISTEN path' got '$_'\n"; + $debug and warn "connecting to slave data port via $unix_socket_name\n"; + $s_data=new IO::Socket::UNIX (Peer=>$unix_socket_name) or die "connect to slave data port: $!\n"; + unlink($unix_socket_name); + } else { + /^LISTEN (\d+)$/ or die "protocol error; expected 'LISTEN port' got '$_'\n"; + my $port=$1; + $debug and warn "connecting to slave data port at $slave:$port\n"; + $s_data=new IO::Socket::INET (PeerHost=>$slave,PeerPort=>$port,Proto=>'tcp') or die "connect to slave data port: $!\n"; + } ($in,$out)=($s_data,$s_data); } @@ -793,13 +804,21 @@ sub slave chdir $slave_path or die "$slave_path: $!\n"; unless ($local_slave) { - my $s_listen=IO::Socket::INET->new(Listen=>1) or die "$0: $!\n"; - my $port=$s_listen->sockport; - - $out->print("LISTEN $port"); + my $s_listen; + if ($unix_socket_name) { + -e $unix_socket_name && unlink($unix_socket_name); + $s_listen=IO::Socket::UNIX->new(Listen=>1,Local=>$unix_socket_name) or die "$unix_socket_name: $!\n"; + $out->print("LISTEN $unix_socket_name"); + } else { + $s_listen=IO::Socket::INET->new(Listen=>1) or die "$0: $!\n"; + my $port=$s_listen->sockport; + $out->print("LISTEN $port"); + } my $s_data = $s_listen->accept; - defined $s_data or die "$!\n"; + my $err=$!; + $unix_socket_name and unlink($unix_socket_name); + defined $s_data or die "$err\n"; ($in,$out)=($s_data,$s_data); } @@ -1005,7 +1024,7 @@ INDEX_RECORD: use constant USAGE => <<"__EOF__"; usage: $0 [options] path [node:]path - $0 --slave [--local-slave] path [options] + $0 --slave [--local-slave] [--socket-name path] path [options] options: --noop dont change anything @@ -1026,6 +1045,8 @@ usage: $0 [options] path [node:]path --cksum compare existing files with CRC checksum --unprivileged do not attempt to set file ownership, even if root --nice EXPERIMENTAL nice + --unix-socket EXPERIMENTAL establish data channel over ssh via AF unix sockets + --socket-name PATH EXPERIMENTAL use PATH as name for AF unix sockets __EOF__ @@ -1052,6 +1073,8 @@ use constant OPTIONS => ( 'ssh-opt=s' => \$ssh_opt, 'cksum' => \$cksum, 'nice' => \$nice, + 'unix-socket' => \$unix_socket, + 'socket-name=s' => \$unix_socket_name, ); if ($ENV{SSH_ORIGINAL_COMMAND}) { @@ -1094,5 +1117,9 @@ if ($slave_mode) { $>==0 or $slave_user='whatever'; # if we are not root, the local slave will also no be root } + if ($unix_socket && !defined $unix_socket_name) { + $unix_socket_name=sprintf '%s/pmirror_setup_%s_%05d',($ENV{'TMPDIR'}||'/tmp'),$ENV{'USER'},int(rand(100000)); + } + master($master_path,$slave_user,$slave,$slave_path); }