diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index c8e65468b..475bd97c8 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -538,6 +538,7 @@ site => { " domain:\tThe DNS domain name used for the cluster.\n\n". " forwarders:\tThe DNS servers at your site that can provide names outside of the cluster. The DNS on the management node will forward requests it does not know to these servers.\n\n". " fsptimeout:\tThe timeout, in milliseconds, to use when communicating with FSPs.\n\n". + " genmacprefix:\tWhen generating mac addresses automatically, use this manufacturing prefix (i.e. 00:11:aa)\n\n". " genpasswords:\tAutomatically generate random passwords for BMCs when configuring them.\n\n". " installdir:\tThe local directory name used to hold the node deployment packages.\n\n". " installloc:\tThe location that service nodes should mount the install directory from in format hostname:/path. If hostname is omitted, it defaults to the management node.\n\n". diff --git a/perl-xCAT/xCAT/VMCommon.pm b/perl-xCAT/xCAT/VMCommon.pm index 14907f2d7..b935e4e1d 100644 --- a/perl-xCAT/xCAT/VMCommon.pm +++ b/perl-xCAT/xCAT/VMCommon.pm @@ -1,4 +1,5 @@ package xCAT::VMCommon; +use Socket; use strict; #Functions common to virtualization management (KVM, Xen, VMware) sub grab_table_data{ #grab table data relevent to VM guest nodes @@ -8,6 +9,8 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes my $vmtab = xCAT::Table->new("vm"); my $hmtab = xCAT::Table->new("nodehm"); my $nttab = xCAT::Table->new("nodetype"); + my $sitetab = xCAT::Table->new("site"); + $cfghash->{site}->{genmacprefix} = xCAT::Utils->get_site_attribute('genmacprefix'); if ($hmtab) { $cfghash->{nodehm} = $hmtab->getNodesAttribs($noderange,['serialspeed']); } @@ -33,4 +36,79 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes } } +sub getMacAddresses { + my $tablecfg = shift; + my $node = shift; + my $count = shift; + my $mactab = xCAT::Table->new("mac",-create=>1); + my $macdata = $tablecfg->{mac}->{$node}->[0]->{mac}; + unless ($macdata) { $macdata ="" } + my @macs; + my $macaddr; + foreach $macaddr (split /\|/,$macdata) { + $macaddr =~ s/\!.*//; + push @macs,lc($macaddr); + } + $count-=scalar(@macs); + my $updatesneeded=0; + if ($count > 0) { + $updatesneeded = 1; + } + + while ($count > 0) { #still need more, autogen + $macaddr = ""; + while (not $macaddr) { + $macaddr = lc(genMac($node,$tablecfg->{site}->{genmacprefix})); + if ($tablecfg->{usedmacs}->{$macaddr}) { + $macaddr = ""; + } + } + $count--; + $tablecfg->{usedmacs}->{$macaddr} = 1; + if (not $macdata) { + $macdata = $macaddr; + } else { + $macdata .= "|".$macaddr; + } + push @macs,$macaddr; + } + if ($updatesneeded) { + my $mactab = xCAT::Table->new('mac',-create=>1); + $mactab->setNodeAttribs($node,{mac=>$macdata}); + $tablecfg->{dhcpneeded}->{$node}=1; #at our leisure, this dhcp binding should be updated + } + return @macs; +# $cfghash->{usedmacs}-{lc{$mac}}; + +} + +sub genMac { #Generates a mac address for a node, does NOT assure uniqueness, calling code needs to do that + my $node=shift; + my $prefix = shift; + if ($prefix) { #Specific prefix requested, honor it + my $tail = int(rand(0xffffff)); #With only 24 bits of space, use random bits; + $tail = sprintf("%06x",$tail); + $tail =~ s/(..)(..)(..)/:$1:$2:$3/; + return $prefix.$tail; + } + my $allbutmult = 0xfeff; # to & with a number to ensure multicast bit is *not* set + my $locallyadministered = 0x200; # to | with the 16 MSBs to indicate a local mac + my $leading = int(rand(0xffff)); + $leading = $leading & $allbutmult; + $leading = $leading | $locallyadministered; + #If this nodename is a resolvable name, we'll use that for the other 32 bits + my $low32; + my $n; + if ($n = inet_aton($node)) { + $low32= unpack("N",$n); + } + unless ($low32) { #If that failed, just do 32 psuedo-random bits + $low32 = int(rand(0xffffffff)); + } + my $mac; + $mac = sprintf("%04x%08x",$leading,$low32); + $mac =~s/(..)(..)(..)(..)(..)(..)/$1:$2:$3:$4:$5:$6/; + return $mac; + +} 1; diff --git a/xCAT-server/lib/xcat/plugins/esx.pm b/xCAT-server/lib/xcat/plugins/esx.pm index 94156654d..305e1f648 100644 --- a/xCAT-server/lib/xcat/plugins/esx.pm +++ b/xCAT-server/lib/xcat/plugins/esx.pm @@ -64,73 +64,6 @@ sub handled_commands{ }; } -#CANDIDATE FOR COMMON CODE -sub getMacAddresses { - my $node = shift; - my $count = shift; - my $macdata = $tablecfg{mac}->{$node}->[0]->{mac}; - unless ($macdata) { $macdata ="" } - my @macs; - my $macaddr; - foreach $macaddr (split /\|/,$macdata) { - $macaddr =~ s/\!.*//; - push @macs,lc($macaddr); - } - $count-=scalar(@macs); - my $updatesneeded=0; - if ($count > 0) { - $updatesneeded = 1; - } - - while ($count > 0) { #still need more, autogen - $macaddr = ""; - while (not $macaddr) { - $macaddr = lc(genMac($node)); - if ($tablecfg{usedmacs}->{$macaddr}) { - $macaddr = ""; - } - } - $count--; - $tablecfg{usedmacs}->{$macaddr} = 1; - if (not $macdata) { - $macdata = $macaddr; - } else { - $macdata .= "|".$macaddr; - } - push @macs,$macaddr; - } - if ($updatesneeded) { - my $mactab = xCAT::Table->new('mac',-create=>1); - $mactab->setNodeAttribs($node,{mac=>$macdata}); - $tablecfg{dhcpneeded}->{$node}=1; #at our leisure, this dhcp binding should be updated - } - return @macs; -# $cfghash->{usedmacs}-{lc{$mac}}; - -} - -sub genMac { #Generates a mac address for a node - my $node=shift; - my $allbutmult = 0xfeff; # to & with a number to ensure multicast bit is *not* set - my $locallyadministered = 0x200; # to | with the 16 MSBs to indicate a local mac - my $leading = int(rand(0xffff)); - $leading = $leading & $allbutmult; - $leading = $leading | $locallyadministered; - #If this nodename is a resolvable name, we'll use that for the other 32 bits - my $low32; - my $n; - if ($n = inet_aton($node)) { - $low32= unpack("N",$n); - } - unless ($low32) { #If that failed, just do 32 psuedo-random bits - $low32 = int(rand(0xffffffff)); - } - my $mac; - $mac = sprintf("%04x%08x",$leading,$low32); - $mac =~s/(..)(..)(..)(..)(..)(..)/$1:$2:$3:$4:$5:$6/; - return $mac; - -} @@ -1224,7 +1157,7 @@ sub create_nic_devs { my @networks = split /,/,$tablecfg{vm}->{$node}->[0]->{nics}; my @devs; my $idx = 0; - my @macs = getMacAddresses($node,scalar @networks); + my @macs = xCAT::VMCommon::getMacAddresses(\%tablecfg,$node,scalar @networks); my $connprefs=VirtualDeviceConnectInfo->new( allowGuestControl=>1, connected=>0,