diff --git a/perl-xCAT-2.0/xCAT/Schema.pm b/perl-xCAT-2.0/xCAT/Schema.pm index 262c3898b..b7e69141f 100644 --- a/perl-xCAT-2.0/xCAT/Schema.pm +++ b/perl-xCAT-2.0/xCAT/Schema.pm @@ -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 => { diff --git a/xCAT-nbroot/overlay/bin/dodestiny b/xCAT-nbroot/overlay/bin/dodestiny index 2604ef920..afc4557d0 100755 --- a/xCAT-nbroot/overlay/bin/dodestiny +++ b/xCAT-nbroot/overlay/bin/dodestiny @@ -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 "$DRIVER|$i" + ADDRESS=`ip address show dev $IFACE|grep 'inet '|awk '{print $2}'` + echo "$DRIVER|$i|$ADDRESS" done modprobe ipmi_devintf if modprobe ipmi_si; then diff --git a/xCAT-server-2.0/lib/xcat/plugins/dhcp.pm b/xCAT-server-2.0/lib/xcat/plugins/dhcp.pm index 6eaa05daf..1391cca34 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/dhcp.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/dhcp.pm @@ -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; diff --git a/xCAT-server-2.0/lib/xcat/plugins/networks.pm b/xCAT-server-2.0/lib/xcat/plugins/networks.pm index d5d36064d..a5d4c4622 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/networks.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/networks.pm @@ -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; diff --git a/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm b/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm index ca89877b5..3fcc824b9 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm @@ -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');