updated various bypass mode subroutines to be similar to xcatd again
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4652 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
af1cd4333f
commit
c6b79c7c15
@ -189,7 +189,7 @@ sub submit_request {
|
||||
# will load all plugin perl modules and build a list of supported
|
||||
# commands
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 5/21/08).
|
||||
# NOTE: This is copied from xcatd (last merge 11/23/09).
|
||||
# TODO: Will eventually move to using common source....
|
||||
###################################
|
||||
sub scan_plugins {
|
||||
@ -197,7 +197,10 @@ sub scan_plugins {
|
||||
foreach (@plugins) {
|
||||
/.*\/([^\/]*).pm$/;
|
||||
my $modname = $1;
|
||||
unless (eval { require "$_" }) { print "Error loading module $_ ...skipping\n"; next;}
|
||||
unless (eval { require "$_" }) {
|
||||
print "Error loading module $_ ...skipping\n";
|
||||
next;
|
||||
}
|
||||
no strict 'refs';
|
||||
my $cmd_adds=${"xCAT_plugin::".$modname."::"}{handled_commands}->();
|
||||
foreach (keys %$cmd_adds) {
|
||||
@ -222,6 +225,51 @@ sub scan_plugins {
|
||||
}
|
||||
}
|
||||
}
|
||||
sub scan_plugins {
|
||||
my @plugins=glob($plugins_dir."/*.pm");
|
||||
foreach (@plugins) {
|
||||
/.*\/([^\/]*).pm$/;
|
||||
my $modname = $1;
|
||||
unless ( eval { require "$_" }) {
|
||||
# xCAT::MsgUtils->message("S","Error loading module ".$_." ...skipping");
|
||||
print "Error loading module $_ ...skipping\n";
|
||||
next;
|
||||
}
|
||||
no strict 'refs';
|
||||
my $cmd_adds=${"xCAT_plugin::".$modname."::"}{handled_commands}->();
|
||||
foreach (keys %$cmd_adds) {
|
||||
my $value = $_;
|
||||
if (defined($cmd_handlers{$_})) {
|
||||
my $add=1;
|
||||
#This next bit of code iterates through the handlers.
|
||||
#If the value doesn't contain an equal, and has an equivalent entry added by
|
||||
# another plugin already, don't add (otherwise would hit the DB multiple times)
|
||||
#referring to having redundant nodehm:mgt handlers registered, for example
|
||||
# a better idea, restructure the cmd_handlers as a multi-level hash
|
||||
# prove out this idea real quick before doing that
|
||||
foreach (@{$cmd_handlers{$_}}) {
|
||||
if (($_->[1] eq $cmd_adds->{$value}) and (($cmd_adds->{$value} !~ /=/) or ($_->[0] eq $modname))) {
|
||||
$add = 0;
|
||||
}
|
||||
}
|
||||
if ($add) { push @{$cmd_handlers{$_}},[$modname,$cmd_adds->{$_}]; }
|
||||
#die "Conflicting handler information from $modname";
|
||||
} else {
|
||||
$cmd_handlers{$_} = [ [$modname,$cmd_adds->{$_}] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (@plugins) {
|
||||
no strict 'refs';
|
||||
/.*\/([^\/]*).pm$/;
|
||||
my $modname = $1;
|
||||
unless (defined(${"xCAT_plugin::".$modname."::"}{init_plugin})) {
|
||||
next;
|
||||
}
|
||||
${"xCAT_plugin::".$modname."::"}{init_plugin}->(\&do_request);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -229,7 +277,7 @@ sub scan_plugins {
|
||||
# plugin_command
|
||||
# will invoke the correct plugin
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 5/21/08).
|
||||
# NOTE: This is copied from xcatd (last merge 11/23/09).
|
||||
# TODO: Will eventually move to using common source....
|
||||
###################################
|
||||
sub plugin_command {
|
||||
@ -237,6 +285,7 @@ sub plugin_command {
|
||||
my $sock = shift;
|
||||
my $callback = shift;
|
||||
my %handler_hash;
|
||||
my $usesiteglobal = 0;
|
||||
|
||||
# We require these only in bypass mode to reduce start up time for the normal case
|
||||
#use lib "$::XCATROOT/lib/perl";
|
||||
@ -274,10 +323,29 @@ sub plugin_command {
|
||||
my $useunhandled=0;
|
||||
if (defined($cmd_handlers{$req->{command}->[0]})) {
|
||||
my $hdlspec;
|
||||
my @globalhandlers=();
|
||||
my $useglobals=1; #If it stays 1, then use globals normally, if 0, use only for 'unhandled_nodes, if -1, don't do at all
|
||||
foreach (@{$cmd_handlers{$req->{command}->[0]}}) {
|
||||
$hdlspec =$_->[1];
|
||||
my $ownmod = $_->[0];
|
||||
if ($hdlspec =~ /:/) { #Specificed a table lookup path for plugin name
|
||||
if ($hdlspec =~ /^site:/) { #A site entry specifies a plugin
|
||||
my $sitekey = $hdlspec;
|
||||
$sitekey =~ s/^site://;
|
||||
$sitetab = xCAT::Table->new('site');
|
||||
my $sent = $sitetab->getAttribs({key=>$sitekey},['value']);
|
||||
if ($sent and $sent->{value}) { #A site style plugin specification is just like
|
||||
#a static global, it grabs all nodes rather than some
|
||||
$useglobals = -1; #If they tried to specify anything, don't use the default global handlers at all
|
||||
unless (@nodes) {
|
||||
$handler_hash{$sent->{value}} = 1;
|
||||
$usesiteglobal = 1;
|
||||
}
|
||||
foreach (@nodes) { #Specified a specific plugin, not a table lookup
|
||||
$handler_hash{$sent->{value}}->{$_} = 1;
|
||||
}
|
||||
}
|
||||
} elsif ($hdlspec =~ /:/) { #Specificed a table lookup path for plugin name
|
||||
$useglobals = 0; #Only contemplate nodes that aren't caught through searching below in the global handler
|
||||
$useunhandled=1;
|
||||
my $table;
|
||||
my $cols;
|
||||
@ -301,12 +369,19 @@ sub plugin_command {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unless (@nodes) { #register the plugin in the event of usage
|
||||
$handler_hash{$ownmod} = 1;
|
||||
$useglobals = 1;
|
||||
}
|
||||
my $hdlrcache;
|
||||
if ($hdlrtable) {
|
||||
$hdlrcache = $hdlrtable->getNodesAttribs(\@nodes,\@columns);
|
||||
}
|
||||
foreach $node (@nodes) {
|
||||
my $attribs = $hdlrtable->getNodeAttribs($node,\@columns);
|
||||
unless (defined($attribs)) { next; } #TODO: This really ought to craft an unsupported response for this request
|
||||
unless ($hdlrcache) { next; }
|
||||
my $attribs = $hdlrcache->{$node}->[0]; #$hdlrtable->getNodeAttribs($node,\@columns);
|
||||
unless (defined($attribs)) { next; }
|
||||
foreach (@columns) {
|
||||
my $col=$_;
|
||||
if (defined($attribs->{$col})) {
|
||||
@ -326,16 +401,37 @@ sub plugin_command {
|
||||
}
|
||||
$hdlrtable->close;
|
||||
} else {
|
||||
unless (@nodes) {
|
||||
$handler_hash{$hdlspec} = 1;
|
||||
}
|
||||
foreach (@nodes) { #Specified a specific plugin, not a table lookup
|
||||
$handler_hash{$hdlspec}->{$_} = 1;
|
||||
}
|
||||
push @globalhandlers,$hdlspec;
|
||||
}
|
||||
}
|
||||
if ($useglobals == 1) { #Behavior when globals have not been overriden
|
||||
my $hdlspec;
|
||||
foreach $hdlspec (@globalhandlers) {
|
||||
unless (@nodes) {
|
||||
$handler_hash{$hdlspec} = 1;
|
||||
}
|
||||
foreach (@nodes) { #Specified a specific plugin, not a table lookup
|
||||
$handler_hash{$hdlspec}->{$_} = 1;
|
||||
}
|
||||
}
|
||||
} elsif ($useglobals == 0) {
|
||||
unless (@nodes or $usesiteglobal) { #if something like 'makedhcp -n',
|
||||
foreach (keys %handler_hash) {
|
||||
if ($handler_hash{$_} == 1) {
|
||||
delete ($handler_hash{$_})
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach $hdlspec (@globalhandlers) {
|
||||
unless (@nodes or $usesiteglobal) {
|
||||
$handler_hash{$hdlspec} = 1;
|
||||
}
|
||||
foreach (keys %unhandled_nodes) { #Specified a specific plugin, not a table lookup
|
||||
$handler_hash{$hdlspec}->{$_} = 1;
|
||||
}
|
||||
}
|
||||
} #Otherwise, global handler is implicitly disabled
|
||||
} else {
|
||||
print "$req->{command}->[0] xCAT command not found \n";
|
||||
return 1; #TODO: error back that request has no known plugin for it
|
||||
}
|
||||
if ($useunhandled) {
|
||||
@ -352,7 +448,9 @@ sub plugin_command {
|
||||
# if ($sock) {
|
||||
# print $sock XMLout({node=>[{name=>[$_],data=>["Unable to identify plugin for this command, check relevant tables: $queuelist"],errorcode=>[1]}]},NoAttr=>1,RootName=>'xcatresponse');
|
||||
# } else {
|
||||
$callback->({node=>[{name=>[$_],data=>['Unable to identify plugin for this command, check relevant tables'],errorcode=>[1]}]});
|
||||
my $tabdesc = $queuelist;
|
||||
$tabdesc =~ s/=.*$//;
|
||||
$callback->({node=>[{name=>[$_],error=>['Unable to identify plugin for this command, check relevant tables: '.$tabdesc],errorcode=>[1]}]});
|
||||
# }
|
||||
}
|
||||
}
|
||||
@ -367,6 +465,7 @@ sub plugin_command {
|
||||
# }
|
||||
foreach (keys %handler_hash) {
|
||||
my $modname = $_;
|
||||
# my $shouldbealivepid=$$;
|
||||
if (-r $plugins_dir."/".$modname.".pm") {
|
||||
require $plugins_dir."/".$modname.".pm";
|
||||
# $plugin_numchildren++;
|
||||
@ -384,7 +483,9 @@ sub plugin_command {
|
||||
# }
|
||||
# unless (defined $child) { die "Fork failed"; }
|
||||
# if ($child == 0) {
|
||||
# $parent_fd = $parfd;
|
||||
# if ($parfd) { #If xCAT is doing multiple requests in same communication PID, things would get unfortunate otherwise
|
||||
# $parent_fd = $parfd;
|
||||
# }
|
||||
my $oldprogname=$$progname;
|
||||
$$progname=$oldprogname.": $modname instance";
|
||||
# if ($sock) { close $pfd; }
|
||||
@ -393,10 +494,11 @@ sub plugin_command {
|
||||
$req->{node}=\@nodes;
|
||||
}
|
||||
no strict "refs";
|
||||
# eval { #REMOVEEVALFORDEBUG
|
||||
# if ($dispatch_requests) {
|
||||
dispatch_request($req,$callback,$modname);
|
||||
# } else {
|
||||
# undef $SIG{CHLD};
|
||||
# $SIG{CHLD}='DEFAULT';
|
||||
# ${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
|
||||
# }
|
||||
$$progname=$oldprogname;
|
||||
@ -404,6 +506,23 @@ sub plugin_command {
|
||||
# close($parent_fd);
|
||||
# xexit(0);
|
||||
# }
|
||||
# }; #REMOVEEVALFORDEBUG
|
||||
# if ($sock or $shouldbealivepid != $$) { #We shouldn't still be alive, try to send as much detail to parent as possible as to why
|
||||
# my $error= "$modname plugin bug, pid $$, process description: '$$progname'";
|
||||
# if ($@) {
|
||||
# $error .= " with error '$@'";
|
||||
# } else { #Sys::Virt and perhaps Net::SNMP sometimes crashes in a way $@ won't catch..
|
||||
# $error .= " with missing eval error, probably due to special manipulation of $@ or strange circumstances in an XS library, remove evals in xcatd marked 'REMOVEEVALFORDEBUG and run xcatd -f for more info";
|
||||
# }
|
||||
# if (scalar (@nodes)) { #Don't know which of the nodes, so one error message warning about the possibliity..
|
||||
# $error .= " while trying to fulfill request for the following nodes: ".join(",",@nodes);
|
||||
# }
|
||||
# xCAT::MsgUtils->message("S","xcatd: $error");
|
||||
# $callback->({error=>[$error],errorcode=>[1]});
|
||||
# xexit(0); #Die like we should have done
|
||||
# } elsif ($@) { #We are still alive, should be alive, but yet we have an error. This means we are in the case of 'do_request' or something similar. Forward up the death since our communication channel is intact..
|
||||
# die $@;
|
||||
# }
|
||||
# } else {
|
||||
# $plugin_children{$child}=1;
|
||||
# close $parfd;
|
||||
@ -430,7 +549,13 @@ sub plugin_command {
|
||||
# if ($req->{transid}) {
|
||||
# $done{transid}=$req->{transid}->[0];
|
||||
# }
|
||||
# if ($sock) { print $sock XMLout(\%done,RootName => 'xcatresponse',NoAttr=>1); }
|
||||
# if ($sock) {
|
||||
# my $clientpresence = new IO::Select; #The client may have gone away without confirmation, don't PIPE over this trivial thing
|
||||
# $clientpresence->add($sock);
|
||||
# if ($clientpresence->can_write(5)) {
|
||||
# print $sock XMLout(\%done,RootName => 'xcatresponse',NoAttr=>1);
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
|
||||
@ -440,7 +565,7 @@ sub plugin_command {
|
||||
# dispatch_request
|
||||
# dispatch the requested command
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 5/21/08).
|
||||
# NOTE: This is copied from xcatd (last merge 11/23/09).
|
||||
# All we really need from this subroutine is to call preprocess_request
|
||||
# and to only run the command for nodes handled by the local server
|
||||
# Will eventually move to using common source....
|
||||
@ -464,7 +589,7 @@ sub dispatch_request {
|
||||
#will for now be required for a command to be scaled through service nodes
|
||||
#If the plugin offers a preprocess method, use it to set the request array
|
||||
if (defined(${"xCAT_plugin::".$modname."::"}{preprocess_request})) {
|
||||
undef $SIG{CHLD};
|
||||
$SIG{CHLD}='DEFAULT';
|
||||
$reqs = ${"xCAT_plugin::".$modname."::"}{preprocess_request}->($req,$dispatch_cb,\&do_request);
|
||||
} else { #otherwise, pass it in without hierarchy support
|
||||
$reqs = [$req];
|
||||
@ -472,6 +597,11 @@ sub dispatch_request {
|
||||
|
||||
# $dispatch_children=0;
|
||||
# $SIG{CHLD} = \&dispatch_reaper; #sub {my $cpid; while (($cpid =waitpid(-1, WNOHANG)) > 0) { if ($dispatched_children{$cpid}) { delete $dispatched_children{$cpid}; $dispatch_children--; } } };
|
||||
my $onlyone=0;
|
||||
if (defined $reqs and (scalar(@{$reqs}) == 1)) {
|
||||
$onlyone=1;
|
||||
}
|
||||
|
||||
foreach (@{$reqs}) {
|
||||
# my $pfd;
|
||||
# my $parfd; #use a private variable so it won't trounce itself recursively
|
||||
@ -481,6 +611,17 @@ sub dispatch_request {
|
||||
if ($_->{node}) {
|
||||
$_->{noderange}->[0]=join(',',@{$_->{node}});
|
||||
}
|
||||
#----- end added to Client.pm -----#
|
||||
|
||||
if (ref $_->{'_xcatdest'} and (ref $_->{'_xcatdest'}) eq 'ARRAY') {
|
||||
_->{'_xcatdest'} = $_->{'_xcatdest'}->[0];
|
||||
}
|
||||
if ($onlyone and not ($_->{'_xcatdest'} and xCAT::Utils->thishostisnot($_->{'_xcatdest'}))) {
|
||||
$SIG{CHLD}='DEFAULT';
|
||||
${"xCAT_plugin::".$modname."::"}{process_request}->($_,$dispatch_cb,\&do_request);
|
||||
return;
|
||||
}
|
||||
|
||||
# socketpair($pfd, $parfd,AF_UNIX,SOCK_STREAM,PF_UNSPEC) or die "socketpair: $!";
|
||||
# $parfd->autoflush(1);
|
||||
# $pfd->autoflush(1);
|
||||
@ -496,25 +637,73 @@ sub dispatch_request {
|
||||
# }
|
||||
# undef $SIG{CHLD};
|
||||
# $dispatch_parentfd = $parfd;
|
||||
if ($_->{'_xcatdest'} and xCAT::Utils->thishostisnot($_->{'_xcatdest'})) {
|
||||
my @prexcatdests=();
|
||||
my @xcatdests=();
|
||||
if (ref($_->{'_xcatdest'}) eq 'ARRAY') { #If array, consider it an 'anycast' operation, broadcast done through dupe
|
||||
#requests, or an alternative join '&' maybe?
|
||||
@prexcatdests=@{$_->{'_xcatdest'}};
|
||||
} else {
|
||||
@prexcatdests=($_->{'_xcatdest'});
|
||||
}
|
||||
foreach (@prexcatdests) {
|
||||
if ($_ and /,/) {
|
||||
push @xcatdests,split /,/,$_;
|
||||
} else {
|
||||
push @xcatdests,$_;
|
||||
}
|
||||
}
|
||||
my $xcatdest;
|
||||
my $numdests=scalar(@xcatdests);
|
||||
my $request_satisfied=0;
|
||||
foreach $xcatdest (@xcatdests) {
|
||||
my $dlock;
|
||||
if ($xcatdest and xCAT::Utils->thishostisnot($xcatdest)) {
|
||||
#----- added to Client.pm -----#
|
||||
$dispatch_cb->({warning=>['XCATBYPASS is set, skipping hierarchy call to '.$_->{'_xcatdest'}.'']});
|
||||
#----- end added to Client.pm -----#
|
||||
|
||||
# $ENV{XCATHOST} = ( $_->{'_xcatdest'} =~ /:/ ? $_->{'_xcatdest'} : $_->{'_xcatdest'}.":3001" );
|
||||
# $$progname.=": connection to ".$ENV{XCATHOST};
|
||||
# eval {
|
||||
# undef $_->{'_xcatdest'};
|
||||
# xCAT::Client::submit_request($_,\&dispatch_callback,$xcatdir."/cert/server-cred.pem",$xcatdir."/cert/server-cred.pem",$xcatdir."/cert/ca.pem");
|
||||
# };
|
||||
# if ($@) {
|
||||
# dispatch_callback({error=>["Error dispatching command to ".$ENV{XCATHOST}.""],errorcode=>[1]});
|
||||
# syslog("local4|err","Error dispatching request: ".$@);
|
||||
# }
|
||||
} else {
|
||||
$$progname.=": locally executing";
|
||||
undef $SIG{CHLD};
|
||||
${"xCAT_plugin::".$modname."::"}{process_request}->($_,$dispatch_cb,\&do_request);
|
||||
# #mkpath("/var/lock/xcat/"); #For now, limit intra-xCAT requests to one at a time, to mitigate DB handle usage
|
||||
# #open($dlock,">","/var/lock/xcat/dispatchto_$xcatdest");
|
||||
# #flock($dlock,LOCK_EX);
|
||||
# $ENV{XCATHOST} = ($xcatdest =~ /:/ ? $xcatdest : $xcatdest.":3001" );
|
||||
# $$progname.=": connection to ".$ENV{XCATHOST};
|
||||
# my $errstr;
|
||||
# eval {
|
||||
# undef $_->{'_xcatdest'};
|
||||
# xCAT::Client::submit_request($_,\&dispatch_callback,$xcatdir."/cert/server-cred.pem",$xcatdir."/cert/server-cred.pem",$xcatdir."/cert/ca.pem");
|
||||
# };
|
||||
# if ($@) {
|
||||
# $errstr=$@;
|
||||
# }
|
||||
# #unlink("/var/lock/xcat/dispatchto_$xcatdest");
|
||||
# #flock($dlock,LOCK_UN);
|
||||
# if ($errstr) {
|
||||
# if ($numdests == 1) {
|
||||
# dispatch_callback({error=>["Unable to dispatch command to ".$ENV{XCATHOST}.", command will not make changes to that server ($errstr)"],errorcode=>[1]});
|
||||
# xCAT::MsgUtils->message("S","Error dispatching request to ".$ENV{XCATHOST}.": ".$errstr);
|
||||
# } else {
|
||||
# xCAT::MsgUtils->message("S","Error dispatching request to ".$ENV{XCATHOST}.", trying other service nodes: ".$errstr);
|
||||
# }
|
||||
# next;
|
||||
# } else {
|
||||
# $request_satisfied=1;
|
||||
# last;
|
||||
# }
|
||||
} else {
|
||||
$$progname.=": locally executing";
|
||||
$SIG{CHLD}='DEFAULT';
|
||||
# ${"xCAT_plugin::".$modname."::"}{process_request}->($_,\&dispatch_callback,\&do_request);
|
||||
#----- changed in Client.pm -----#
|
||||
${"xCAT_plugin::".$modname."::"}{process_request}->($_,\&dispatch_cb,\&do_request);
|
||||
#----- end changed in Client.pm -----#
|
||||
last;
|
||||
}
|
||||
}
|
||||
# if ($numdests > 1 and not $request_satisfied) {
|
||||
# xCAT::MsgUtils->message("S","Error dispatching a request to all possible service nodes for request");
|
||||
# dispatch_callback({error=>["Failed to dispatch command to any of the following service nodes: ".join(",",@xcatdests)],errorcode=>[1]});
|
||||
# }
|
||||
|
||||
# xexit;
|
||||
}
|
||||
#while (($dispatch_children > 0) and ($child_fdset->count > 0)) { relay_dispatch($child_fdset) }
|
||||
@ -522,11 +711,12 @@ sub dispatch_request {
|
||||
}
|
||||
|
||||
|
||||
|
||||
###################################
|
||||
# do_request
|
||||
# called from a plugin to execute another xCAT plugin command internally
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 5/21/08).
|
||||
# NOTE: This is copied from xcatd (last merge 11/23/09).
|
||||
# Will eventually move to using common source....
|
||||
###################################
|
||||
sub do_request {
|
||||
|
Loading…
x
Reference in New Issue
Block a user