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');