From f1685293c7f8d7ce36daa35b26415a4a60a75033 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Tue, 6 Oct 2009 16:13:58 +0000 Subject: [PATCH] -Change MAC autogen code to remove the race condition in the unlikely event that we had parallel mkvm processes pick the same mac randomly. git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4310 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/VMCommon.pm | 53 +++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/perl-xCAT/xCAT/VMCommon.pm b/perl-xCAT/xCAT/VMCommon.pm index afc4367a5..80bf1d24a 100644 --- a/perl-xCAT/xCAT/VMCommon.pm +++ b/perl-xCAT/xCAT/VMCommon.pm @@ -31,11 +31,48 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes $macs=$cfghash->{mac}->{$_}->[0]->{mac}; foreach $mac (split /\|/,$macs) { $mac =~ s/\!.*//; - $cfghash->{usedmacs}->{lc($mac)}=1; + if ($cfghash->{usedmacs}->{lc($mac)}) { + $cfghash->{usedmacs}->{lc($mac)} += 1; + } else { + $cfghash->{usedmacs}->{lc($mac)}=1; + } } } } +sub macsAreUnique { #internal function, do not call, argument format may change without warning + #Take a list of macs, ensure that in the table view, they are unique. + #this should be performed after the macs have been committed to + #db + my $cfghash = shift; + my @macs = @_; + my $mactab = xCAT::Table->new("mac",-create=>0); + unless ($mactab) { + return 1; + } + $cfghash->{mac} = $mactab->getAllNodeAttribs(['mac'],1); + $cfghash->{usedmacs} = {}; + my $macs; + my $mac; + foreach (keys %{$cfghash->{mac}}) { + $macs=$cfghash->{mac}->{$_}->[0]->{mac}; + foreach $mac (split /\|/,$macs) { + $mac =~ s/\!.*//; + if ($cfghash->{usedmacs}->{lc($mac)}) { + $cfghash->{usedmacs}->{lc($mac)} += 1; + } else { + $cfghash->{usedmacs}->{lc($mac)}=1; + } + } + } + foreach $mac (@macs) { + if ($cfghash->{usedmacs}->{lc($mac)} > 1) { + return 0; + } + } + return 1; +} + sub getMacAddresses { my $tablecfg = shift; my $node = shift; @@ -56,6 +93,7 @@ sub getMacAddresses { } srand(); #Re-seed the rng. This will make the mac address generation less deterministic + while ($count > 0) { while ($count > 0) { #still need more, autogen $macaddr = ""; while (not $macaddr) { @@ -78,6 +116,19 @@ sub getMacAddresses { $mactab->setNodeAttribs($node,{mac=>$macdata}); $tablecfg->{dhcpneeded}->{$node}=1; #at our leisure, this dhcp binding should be updated } + #TODO: LOCK if a distributed lock management structure goes in place, that may be a faster solution than this + #this code should be safe though as it is, if a tiny bit slower + #can also be sped up by doing it for a noderange in a sweep instead of once per node + #but the current architecture has this called at a place that is unaware of the larger context + #TODO2.4 would be either the lock management or changing this to make large scale mkvm faster + unless (macsAreUnique($tablecfg,@macs)) { #Throw away ALL macs and try again + #this currently includes manually specified ones + $count += scalar(@macs); + @macs = (); + $macdata=""; + } + } + return @macs; # $cfghash->{usedmacs}-{lc{$mac}};