defect 4229 add new rescanplugins support to xcatd

This commit is contained in:
mellor 2014-07-29 11:18:39 -04:00
parent 3ed8c3b884
commit e4839d2f81
2 changed files with 253 additions and 11 deletions

View File

@ -0,0 +1,194 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------
=head1
xCAT plugin package to tell xcatd daemon to rescan plugin directory
Supported command:
rescanplugins->rescanplugins
=cut
#-------------------------------------------------------
package xCAT_plugin::rescanplugins;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::Utils;
use xCAT::MsgUtils;
use Getopt::Long;
use strict;
1;
#-------------------------------------------------------
=head3 handled_commands
Return list of commands handled by this plugin
=cut
#-------------------------------------------------------
sub handled_commands
{
return {rescanplugins => "rescanplugins"};
}
#-------------------------------------------------------
=head3 preprocess_request
If hierarchy, send request to xcatd on service nodes
=cut
#-------------------------------------------------------
sub preprocess_request
{
my $req = shift;
my $callback = shift;
my $subreq = shift;
$::CALLBACK=$callback;
my $args = $req->{arg};
my $envs = $req->{env};
#if already preprocessed, go straight to request
if (($req->{_xcatpreprocessed}) and
($req->{_xcatpreprocessed}->[0] == 1) ) { return [$req]; }
# do your processing here
# return info
if ($args) {
@ARGV = @{$args}; # get arguments
}
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
my %options = ();
if (
!GetOptions(
'h|help' => \$options{'help'},
's|servicenodes' => \$options{'servicenodes'},
'v|version' => \$options{'version'},
'V|Verbose' => \$options{'verbose'}
)
)
{
&usage;
exit 1;
}
if ($options{'help'})
{
&usage;
exit 0;
}
if ($options{'version'})
{
my $version = xCAT::Utils->Version();
#$version .= "\n";
my $rsp={};
$rsp->{data}->[0] = $version;
xCAT::MsgUtils->message("I",$rsp,$callback, 0);
exit 0;
}
if ( @ARGV && $ARGV[0] ) {
my $rsp={};
$rsp->{data}->[0] = "Ignoring arguments ". join(',',@ARGV);
xCAT::MsgUtils->message("I",$rsp,$callback, 0);
}
if ( $req->{node} && $req->{node}->[0] ) {
my $rsp={};
$rsp->{data}->[0] = "Ignoring nodes ". join(',',@{$req->{node}});
xCAT::MsgUtils->message("I",$rsp,$callback, 0);
$req->{node}=[];
}
if ($options{'servicenodes'}) {
# Run rescanplugins on MN and all service nodes
# build an individual request for each service node
my @requests;
my $MNreq = {%$req};
$MNreq->{_xcatpreprocessed}->[0] = 1;
push @requests, $MNreq;
foreach my $sn (xCAT::ServiceNodeUtils->getAllSN())
{
my $SNreq = {%$req};
$SNreq->{'_xcatdest'} = $sn;
$SNreq->{_xcatpreprocessed}->[0] = 1;
push @requests, $SNreq;
}
return \@requests; # return requests for all Service nodes
}
return [$req];
}
#-------------------------------------------------------
=head3 process_request
Process the command
=cut
#-------------------------------------------------------
sub process_request
{
my $req = shift;
my $callback = shift;
my $subreq = shift;
# The xcatd daemon should intercept this command and process it directly
print "in rescanplugins->process_request -- xcatd should process this request directly. WE SHOULD NEVER GET HERE \n";
my $rsp={};
$rsp->{data}->[0] = "in rescanplugins->process_request: xcatd should process this request directly. WE SHOULD NEVER GET HERE";
xCAT::MsgUtils->message("I", $rsp, $callback, 0);
return;
}
#-------------------------------------------------------------------------------
=head3
usage
puts out usage message for help
Arguments:
None
Returns:
Globals:
Error:
None
=cut
#-------------------------------------------------------------------------------
sub usage
{
## usage message
my $usagemsg = " rescanplugins [-h|--help] \n rescanplugins [-v|--version] \n rescanplugins [-s|--servicenodes]\n";
### end usage mesage
my $rsp = {};
$rsp->{data}->[0] = $usagemsg;
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
return;
}

View File

@ -716,6 +716,8 @@ sleep 0.05;
sub scan_plugins {
my $serialdest = shift;
my $rescan = shift;
%cmd_handlers=();
my @plugins=glob($plugins_dir."/*.pm");
foreach (@plugins) {
/.*\/([^\/]*).pm$/;
@ -751,14 +753,16 @@ sub scan_plugins {
}
}
}
foreach (@plugins) {
no strict 'refs';
/.*\/([^\/]*).pm$/;
my $modname = $1;
unless (defined(${"xCAT_plugin::".$modname."::"}{init_plugin})) {
next;
if ( ! $rescan ) {
foreach (@plugins) {
no strict 'refs';
/.*\/([^\/]*).pm$/;
my $modname = $1;
unless (defined(${"xCAT_plugin::".$modname."::"}{init_plugin})) {
next;
}
${"xCAT_plugin::".$modname."::"}{init_plugin}->(\&do_request);
}
${"xCAT_plugin::".$modname."::"}{init_plugin}->(\&do_request);
}
if ($serialdest) { store_fd(\%cmd_handlers,$serialdest); }; #print $serialdest freeze(\%cmd_handlers); };
}
@ -928,6 +932,17 @@ xCAT::NotifHandler::setup($$, $dbmaster);
#start the monitoring process
xCAT_monitoring::monitorctrl::start($$);
# Set up communication pipe to have subcommand process be able to reload the
# cmd_handlers hash and pass it back to this parent when rescanplugins requested
my $chreadpipe;
my $chwritepipe;
if ( !(socketpair($chreadpipe, $chwritepipe,AF_UNIX,SOCK_STREAM,PF_UNSPEC)) ) {
xCAT::MsgUtils->message("S", "socketpair failed: $!");
}
my $chrselect = new IO::Select;
$chrselect->add($chreadpipe);
my $peername;
my $ssltimeout;
my $retry=1;
@ -1026,6 +1041,14 @@ until ($quit) {
$listenwatcher->can_read(0.1); #when next connection tries to come in or a tenth of a second, whichever comes first
next; #just keep pulling things off listen queue onto our own
}
# before we fork, check to see if rescanplugins was previously processed and
# we now have a new cmd_handlers hash to refresh
my @chdata;
if (@chdata = $chrselect->can_read(0)) {
foreach my $chd (@chdata) {
%cmd_handlers = %{fd_retrieve($chd)};
}
}
#we have a pending connection and we are under the threshold, grab one from the list and process it...
my $cnnection=shift @pendingconnections;
my $connection;
@ -1366,7 +1389,13 @@ sub plugin_command {
dispatch_request($req,$callback,$modname);
} else {
$SIG{CHLD}='DEFAULT';
${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
# Call the plugin to process the command request
# rescanplugins request gets handled directly here in xcatd
if ($req->{command}->[0] eq 'rescanplugins') {
scan_plugins($chwritepipe,'1');
} else {
${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
}
}
$$progname=$oldprogname;
}; #REMOVEEVALFORDEBUG
@ -1454,7 +1483,13 @@ sub plugin_command {
dispatch_request($req,$callback,$modname);
} else {
$SIG{CHLD}='DEFAULT';
${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
# Call the plugin to process the command request
# rescanplugins request gets handled directly here in xcatd
if ($req->{command}->[0] eq 'rescanplugins') {
scan_plugins($chwritepipe,'1');
} else {
${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
}
}
$$progname=$oldprogname;
$parent_fd = $org_parent_fd;
@ -1679,7 +1714,13 @@ sub dispatch_request {
if ($onlyone and not ($_->{'_xcatdest'} and xCAT::NetworkUtils->thishostisnot($_->{'_xcatdest'}))) {
$SIG{CHLD}='DEFAULT';
if ($_->{'_xcatdelay'} and not ref $_->{'_xcatdelay'}) { sleep $_->{'_xcatdelay'}; }
${"xCAT_plugin::".$modname."::"}{process_request}->($_,$dispatch_cb,\&do_request);
# Call the plugin to process the command request
# rescanplugins request gets handled directly here in xcatd
if ($_->{command}->[0] eq 'rescanplugins') {
scan_plugins($chwritepipe,'1');
} else {
${"xCAT_plugin::".$modname."::"}{process_request}->($_,$dispatch_cb,\&do_request);
}
return;
}
@ -1762,7 +1803,13 @@ sub dispatch_request {
} else {
$$progname.=": locally executing";
$SIG{CHLD}='DEFAULT';
${"xCAT_plugin::".$modname."::"}{process_request}->($_,\&dispatch_callback,\&do_request);
# Call the plugin to process the command request
# rescanplugins request gets handled directly here in xcatd
if ($_->{command}->[0] eq 'rescanplugins') {
scan_plugins($chwritepipe,'1');
} else {
${"xCAT_plugin::".$modname."::"}{process_request}->($_,\&dispatch_callback,\&do_request);
}
last;
}
}
@ -1796,6 +1843,7 @@ sub do_request {
}
}
#my $sock = shift; #If no sock, will return a response hash
if ($cmd_handlers{$req->{command}->[0]}) {
return plugin_command($req,$sock,$rsphandler);