diff --git a/clusterd b/clusterd index 5ec48f5..9b01eb3 100755 --- a/clusterd +++ b/clusterd @@ -1274,6 +1274,22 @@ sub expand_netgroup_hosts { return @out; } +sub exec_at { + my ($host,@cmd)=@_; + sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n"; + my $s=new IO::Socket::INET(PeerAddr=>$host,PeerPort=>$CLP_PORT); + unless (defined $s) { + die "$host: $!\n"; + } + clp_send_message($s,'CMD',@cmd); + my $pbuffer=''; + my $olbuffer=''; + my $elbuffer=''; + Donald::Select::reader($s,\&cmd_rx,$host,$s,\$pbuffer,\$olbuffer,\$elbuffer); + $slave=1; + Donald::Select::run() if $slave;; +} + sub lsof { my ($pattern)=@_; sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n"; @@ -1367,13 +1383,13 @@ sub cmd_msg { } elsif ($channel eq 'O') { my $msg=$$olbufref.substr($data,1); for ($msg=~/([^\n]*\n)/gs) { - print "$host $_"; + print "$host: $_"; } ($$olbufref)=$msg=~/([^\n]*)\z/; } elsif ($channel eq 'E') { my $msg=$$elbufref.substr($data,1); for ($msg=~/([^\n]*\n)/gs) { - print STDERR "$host $_"; + print STDERR "$host: $_"; } ($$elbufref)=$msg=~/([^\n]*)\z/; } @@ -1389,6 +1405,7 @@ usage: $0 [options] --push-amd-tar # broadcast /etc/amd --send-restart # broadcast a restart request to all nodes --exec mkmotd # execute /usr/sbin/mkmotd.pl on all nodes + --exec @node cmd [args...] # execute cmd on node --flush-gidcache # flush rpc auth.unix.gid cache on all nodes --lsof=pattern @@ -1423,9 +1440,15 @@ if (defined $options{'push'}) { $donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n"; push_file($donald_s,$options{'push'}); } elsif (defined $options{'exec'}) { - sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n"; - $donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n"; - send_exec($donald_s,$options{'exec'}); + if (substr($options{'exec'},0,1) eq '@') { + length(length($options{'exec'})>1) or die USAGE; + @ARGV>=1 or die USAGE; + exec_at(substr($options{'exec'},1),@ARGV); + } else { + sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n"; + $donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n"; + send_exec($donald_s,$options{'exec'}); + } } elsif (defined $options{'push_amd_tar'}) { sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n"; $donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n";