Multi-interface discovery support

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@261 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
jbjohnso 2008-01-14 19:13:43 +00:00
parent 7717527a3b
commit 45fe630583
5 changed files with 131 additions and 38 deletions

View File

@ -67,7 +67,7 @@ package xCAT::Schema;
keys => [qw(node)],
},
networks => {
cols => [qw(netname net mask gateway dhcpserver tftpserver nameservers dynamicrange comments disable)],
cols => [qw(netname net mask mgtifname gateway dhcpserver tftpserver nameservers dynamicrange nodehostname comments disable)],
keys => [qw(net mask)]
},
osimage => {

View File

@ -55,7 +55,8 @@ while :; do
for i in `ifconfig -a|grep HWaddr|grep -v sit|awk '{print $1 "|" $5}'`; do
IFACE=`echo $i|awk -F'|' '{print $1}'`
DRIVER=`ethtool -i $IFACE|grep ^driver|awk '{print $2}'`
echo "<mac>$DRIVER|$i</mac>"
ADDRESS=`ip address show dev $IFACE|grep 'inet '|awk '{print $2}'`
echo "<mac>$DRIVER|$i|$ADDRESS</mac>"
done
modprobe ipmi_devintf
if modprobe ipmi_si; then

View File

@ -57,45 +57,54 @@ sub addnode {
my $ent;
my $mactab = xCAT::Table->new('mac');
unless ($mactab) { return; } #TODO: report error sanely
$ent = $mactab->getNodeAttribs($node,[qw(mac interface)]);
$ent = $mactab->getNodeAttribs($node,[qw(mac)]);
unless ($ent and $ent->{mac}) {
return; #TODO: sane error
}
my $inetn = inet_aton($node);
unless ($inetn) {
syslog("local1|err","xCAT DHCP plugin unable to resolve IP for $node");
return;
}
my $ip = inet_ntoa(inet_aton($node));;
print "Setting $node ($ip) to ".$ent->{mac}."\n";
print $omshell "new host\n";
print $omshell "set name = \"$node\"\n"; #Find and destroy conflict name
print $omshell "open\n";
print $omshell "remove\n";
print $omshell "close\n";
print $omshell "new host\n";
print $omshell "set ip-address = $ip\n"; #find and destroy ip conflict
print $omshell "open\n";
print $omshell "remove\n";
print $omshell "close\n";
print $omshell "new host\n";
print $omshell "set hardware-address = ".$ent->{mac}."\n"; #find and destroy mac conflict
print $omshell "open\n";
print $omshell "remove\n";
print $omshell "close\n";
print $omshell "new host\n";
print $omshell "set name = \"$node\"\n";
print $omshell "set hardware-address = ".$ent->{mac}."\n";
print $omshell "set hardware-type = 1\n";
print $omshell "set ip-address = $ip\n";
if ($statements) {
print $omshell "set statements = \"$statements\"\n";
my @macs = split(/\|/,$ent->{mac});
my $mace;
foreach $mace (@macs) {
my $mac;
my $hname;
($mac,$hname) = split (/!/,$mace);
unless ($hname) { $hname = $node; } #Default to hostname equal to nodename
unless ($mac) { next; } #Skip corrupt format
my $inetn = inet_aton($hname);
unless ($inetn) {
syslog("local1|err","xCAT DHCP plugin unable to resolve IP for $hname (for $node)");
return;
}
my $ip = inet_ntoa(inet_aton($hname));;
print "Setting $node ($hname|$ip) to ".$ent->{mac}."\n";
print $omshell "new host\n";
print $omshell "set name = \"$hname\"\n"; #Find and destroy conflict name
print $omshell "open\n";
print $omshell "remove\n";
print $omshell "close\n";
print $omshell "new host\n";
print $omshell "set ip-address = $ip\n"; #find and destroy ip conflict
print $omshell "open\n";
print $omshell "remove\n";
print $omshell "close\n";
print $omshell "new host\n";
print $omshell "set hardware-address = ".$mac."\n"; #find and destroy mac conflict
print $omshell "open\n";
print $omshell "remove\n";
print $omshell "close\n";
print $omshell "new host\n";
print $omshell "set name = \"$hname\"\n";
print $omshell "set hardware-address = ".$mac."\n";
print $omshell "set hardware-type = 1\n";
print $omshell "set ip-address = $ip\n";
if ($statements) {
print $omshell "set statements = \"$statements\"\n";
}
print $omshell "create\n";
unless (grep /#definition for host $node aka host $hname/,@dhcpconf) {
push @dhcpconf,"#definition for host $node aka host $hname can be found in the dhcpd.leases file\n";
}
}
print $omshell "create\n";
unless (grep /#definition for host $node/,@dhcpconf) {
push @dhcpconf,"#definition for host $node can be found in the dhcpd.leases file\n";
}
}
}
sub process_request {
my $req = shift;
$callback = shift;

View File

@ -35,12 +35,14 @@ sub process_request {
foreach (@rtable) { #should be the lines to think about, do something with U, and something else with UG
my $net;
my $mask;
my $mgtifname;
my $gw;
my @ent = split /\s+/,$_;
if ($ent[3] eq 'U') {
$net = $ent[0];
$mask = $ent[2];
$nettab->setAttribs({'net'=>$net},{'mask'=>$mask});
$mgtifname = $ent[7];
$nettab->setAttribs({'net'=>$net},{'mask'=>$mask,'mgtifname'=>$mgtifname});
my $tent = $nettab->getAttribs({'net'=>$net},nameservers);
unless ($tent and $tent->{nameservers}) {
my $text = join ',',@nameservers;

View File

@ -16,6 +16,66 @@ use IO::Handle;
use Sys::Syslog;
sub gethosttag {
#This function tries to return a good hostname for a node based on the
#network to which it is connected (by $netn or maybe $ifname)
#heuristic:
#if the client had a valid IP address from a dhcp server, that is used as key
#once the matching network is found, and an explicit mapping defined, try that
#next, try to see if the ip for the case where hostname==nodename is on this net, if so, return that
#next, try to do nodename-ifname, return that if successful
#next, repeat process for all networks that have the common mgtifname field
#return undef for now if none of the above worked
my $node = shift;
my $netn = shift;
my $ifname = shift;
my $mgtifname = "";
my $secondpass = 0;
my $name = "";
my $defhost = inet_aton($node);
my $nettab = xCAT::Table->new('networks');
my $defn="";
my @netents = @{$nettab->getAllEntries()};
my $pass;
foreach $pass (1,2) { #two passes to allow for mgtifname matching
foreach (@netents) {
if ($_->{net} eq $netn or ($mgtifname and $mgtifname eq $_->{mgtifname})) {
$mgtifname = $_->{mgtifname}; #This flags the managementethernet for a second pass
if ($_->{nodehostname}) {
my $left;
my $right;
($left,$right) = split(/\//,$_->{nodehostname},2);
$name = $node;
$name =~ s/$left/$right/;
if ($name and inet_aton($name)) {
if ($netn eq $_->{net}) { return $name; }
#At this point, it could still be valid if block was entered due to mgtifname
my $nnetn = inet_ntoa(pack("N",unpack("N",inet_aton($name)) & unpack("N",inet_aton($_->{mask}))));
if ($nnetn eq $_->{net}) { return $name; }
}
$name=""; #Still here, this branch failed
}
$defn = inet_ntoa(pack("N",unpack("N",$defhost) & unpack("N",inet_aton($_->{mask}))));
if ($defn eq $_->{net}) { #the default nodename is on this network
return $node;
}
my $tentativehost = $node . "-".$ifname;
my $tnh = inet_aton($tentativehost);
if ($tnh) {
my $nnetn = inet_ntoa(pack("N",unpack("N",$tnh) & unpack("N",inet_aton($_->{mask}))));
if ($nnetn eq $_->{net}) {
return $tentativehost;
}
}
}
}
}
}
sub handled_commands {
return {
discovered => 'chain:ondiscover',
@ -41,6 +101,27 @@ sub process_request {
my $typetab=xCAT::Table->new("nodetype",-create=>1);
$typetab->setNodeAttribs($node,{arch=>$request->{arch}->[0]});
}
if (defined($request->{mac})) {
my $mactab = xCAT::Table->new("mac",-create=>1);
my @ifinfo;
my $macstring = "";
foreach (@{$request->{mac}}) {
@ifinfo = split /\|/;
if ($ifinfo[3]) {
(my $ip,my $netbits) = split /\//,$ifinfo[3];
if ($ip =~ /\d+\.\d+\.\d+\.\d+/) {
my $ipn = unpack("N",inet_aton($ip));
my $mask = 2**$netbits-1<<(32-$netbits);
my $netn = inet_ntoa(pack("N",$ipn & $mask));
my $hosttag = gethosttag($node,$netn,@ifinfo[1]);
if ($hosttag) {
$macstring .= $ifinfo[2]."!".$hosttag."|";
}
}
}
}
$mactab->setNodeAttribs($node,{mac=>$macstring});
}
#TODO: mac table? on the one hand, 'the' definitive interface was determined earlier...
#Delete the state it was in to make it traverse destiny once agoin
my $chaintab = xCAT::Table->new('chain');