Revision 36b66e6e lib/config.py
b/lib/config.py | ||
---|---|---|
137 | 137 |
self._cfg_file = cfg_file |
138 | 138 |
self._temporary_ids = TemporaryReservationManager() |
139 | 139 |
self._temporary_drbds = {} |
140 |
self._temporary_macs = set()
|
|
140 |
self._temporary_macs = TemporaryReservationManager()
|
|
141 | 141 |
# Note: in order to prevent errors when resolving our name in |
142 | 142 |
# _DistributeConfig, we compute it here once and reuse it; it's |
143 | 143 |
# better to raise an error before starting to modify the config |
... | ... | |
154 | 154 |
""" |
155 | 155 |
return os.path.exists(constants.CLUSTER_CONF_FILE) |
156 | 156 |
|
157 |
def _GenerateOneMAC(self): |
|
158 |
"""Generate one mac address |
|
159 |
|
|
160 |
""" |
|
161 |
prefix = self._config_data.cluster.mac_prefix |
|
162 |
byte1 = random.randrange(0, 256) |
|
163 |
byte2 = random.randrange(0, 256) |
|
164 |
byte3 = random.randrange(0, 256) |
|
165 |
mac = "%s:%02x:%02x:%02x" % (prefix, byte1, byte2, byte3) |
|
166 |
return mac |
|
167 |
|
|
157 | 168 |
@locking.ssynchronized(_config_lock, shared=1) |
158 |
def GenerateMAC(self): |
|
169 |
def GenerateMAC(self, ec_id):
|
|
159 | 170 |
"""Generate a MAC for an instance. |
160 | 171 |
|
161 | 172 |
This should check the current instances for duplicates. |
162 | 173 |
|
163 | 174 |
""" |
164 |
prefix = self._config_data.cluster.mac_prefix |
|
165 |
all_macs = self._AllMACs() |
|
166 |
retries = 64 |
|
167 |
while retries > 0: |
|
168 |
byte1 = random.randrange(0, 256) |
|
169 |
byte2 = random.randrange(0, 256) |
|
170 |
byte3 = random.randrange(0, 256) |
|
171 |
mac = "%s:%02x:%02x:%02x" % (prefix, byte1, byte2, byte3) |
|
172 |
if mac not in all_macs and mac not in self._temporary_macs: |
|
173 |
break |
|
174 |
retries -= 1 |
|
175 |
else: |
|
176 |
raise errors.ConfigurationError("Can't generate unique MAC") |
|
177 |
self._temporary_macs.add(mac) |
|
178 |
return mac |
|
175 |
existing = self._AllMACs() |
|
176 |
return self._temporary_ids.Generate(existing, self._GenerateOneMAC, ec_id) |
|
179 | 177 |
|
180 | 178 |
@locking.ssynchronized(_config_lock, shared=1) |
181 |
def IsMacInUse(self, mac):
|
|
182 |
"""Predicate: check if the specified MAC is in use in the Ganeti cluster.
|
|
179 |
def ReserveMAC(self, mac, ec_id):
|
|
180 |
"""Reserve a MAC for an instance.
|
|
183 | 181 |
|
184 | 182 |
This only checks instances managed by this cluster, it does not |
185 | 183 |
check for potential collisions elsewhere. |
186 | 184 |
|
187 | 185 |
""" |
188 | 186 |
all_macs = self._AllMACs() |
189 |
return mac in all_macs or mac in self._temporary_macs |
|
187 |
if mac in all_macs: |
|
188 |
raise errors.ReservationError("mac already in use") |
|
189 |
else: |
|
190 |
self._temporary_macs.Reserve(mac, ec_id) |
|
190 | 191 |
|
191 | 192 |
@locking.ssynchronized(_config_lock, shared=1) |
192 | 193 |
def GenerateDRBDSecret(self): |
... | ... | |
799 | 800 |
self._config_data.instances[instance.name] = instance |
800 | 801 |
self._config_data.cluster.serial_no += 1 |
801 | 802 |
self._UnlockedReleaseDRBDMinors(instance.name) |
802 |
for nic in instance.nics: |
|
803 |
self._temporary_macs.discard(nic.mac) |
|
804 | 803 |
self._WriteConfig() |
805 | 804 |
|
806 | 805 |
def _EnsureUUID(self, item, ec_id): |
... | ... | |
1420 | 1419 |
|
1421 | 1420 |
if isinstance(target, objects.Instance): |
1422 | 1421 |
self._UnlockedReleaseDRBDMinors(target.name) |
1423 |
for nic in target.nics: |
|
1424 |
self._temporary_macs.discard(nic.mac) |
|
1425 | 1422 |
|
1426 | 1423 |
self._WriteConfig(feedback_fn=feedback_fn) |
1427 | 1424 |
|
... | ... | |
1431 | 1428 |
|
1432 | 1429 |
""" |
1433 | 1430 |
self._temporary_ids.DropECReservations(ec_id) |
1431 |
self._temporary_macs.DropECReservations(ec_id) |
|
1434 | 1432 |
|
Also available in: Unified diff