Skip to content

Commit e967037

Browse files
Ensure VM IP is removed from VR DHCP records in dnsmasq.leases after expunge VM
This also reverts the PR #10183 changes (for #10182), in turn resulting in #11877.
1 parent a7c2a05 commit e967037

1 file changed

Lines changed: 70 additions & 1 deletion

File tree

systemvm/debian/opt/cloud/bin/cs/CsDhcp.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
from netaddr import *
2121
from random import randint
2222
import json
23+
import fcntl
24+
import shutil
25+
import tempfile
26+
import signal
2327
from .CsGuestNetwork import CsGuestNetwork
2428
from cs.CsDatabag import CsDataBag
2529
from cs.CsFile import CsFile
@@ -139,7 +143,8 @@ def configure_server(self):
139143
# Listen Address
140144
if self.cl.is_redundant():
141145
listen_address.append(gateway)
142-
listen_address.append(ip)
146+
else:
147+
listen_address.append(ip)
143148
# Add localized "data-server" records in /etc/hosts for VPC routers
144149
if self.config.is_vpc() or self.config.is_router():
145150
self.add_host(gateway, "%s data-server" % CsHelper.get_hostname())
@@ -165,15 +170,79 @@ def delete_leases(self):
165170
mac = lease[1]
166171
ip = lease[2]
167172
if mac not in macs_dhcphosts:
173+
logging.info("Releasing DHCP lease for IP: %s, mac: %s", ip, mac)
168174
cmd = "dhcp_release $(ip route get %s | grep eth | head -1 | awk '{print $3}') %s %s" % (ip, ip, mac)
169175
logging.info(cmd)
170176
CsHelper.execute(cmd)
177+
if self.ensure_lease_removed(ip):
178+
logging.info("Lease for %s still existed after dhcp_release; removed manually", ip)
171179
removed = removed + 1
172180
self.del_host(ip)
173181
logging.info("Deleted %s entries from dnsmasq.leases file" % str(removed))
174182
except Exception as e:
175183
logging.error("Caught error while trying to delete entries from dnsmasq.leases file: %s" % e)
176184

185+
def lease_exists(self, ip):
186+
if not os.path.exists(LEASES):
187+
return False
188+
189+
with open(LEASES, "r") as fp:
190+
for line in fp:
191+
fields = line.split()
192+
if len(fields) >= 3 and fields[2] == ip:
193+
return True
194+
195+
return False
196+
197+
def remove_lease(self, ip):
198+
if not os.path.exists(LEASES):
199+
return False
200+
201+
removed = False
202+
203+
with open(LEASES, "r+") as fp:
204+
fcntl.flock(fp.fileno(), fcntl.LOCK_EX)
205+
lines = fp.readlines()
206+
207+
fd, tmp_path = tempfile.mkstemp(
208+
prefix="dnsmasq.leases.",
209+
dir=os.path.dirname(LEASES)
210+
)
211+
212+
try:
213+
with os.fdopen(fd, "w") as tmp:
214+
for line in lines:
215+
fields = line.split()
216+
217+
if len(fields) >= 3 and fields[2] == ip:
218+
removed = True
219+
continue
220+
221+
tmp.write(line)
222+
223+
if removed:
224+
shutil.move(tmp_path, LEASES)
225+
226+
# reload dnsmasq
227+
try:
228+
with open("/var/run/dnsmasq.pid") as pidf:
229+
os.kill(int(pidf.read().strip()), signal.SIGHUP)
230+
except Exception:
231+
pass
232+
233+
os.system("ip neigh flush all")
234+
else:
235+
os.remove(tmp_path)
236+
finally:
237+
fcntl.flock(fp.fileno(), fcntl.LOCK_UN)
238+
239+
return removed
240+
241+
def ensure_lease_removed(self, ip):
242+
if self.lease_exists(ip):
243+
return self.remove_lease(ip)
244+
return False
245+
177246
def preseed(self):
178247
self.add_host("127.0.0.1", "localhost")
179248
self.add_host("127.0.1.1", "%s" % CsHelper.get_hostname())

0 commit comments

Comments
 (0)