Conversation
On a redundant router dnsmasq listens on the gateway (VIP) and uses it as its DHCP server identifier. dhcp_release puts the first address of the interface in that option, which is the router's own address, so dnsmasq drops every DHCPRELEASE without logging anything. The lease of an expunged VM stays in dnsmasq's memory and the next VM given that address is refused it. The fallback added by apache#13194 cannot help: it replaces the leases file and reloads dnsmasq, but dnsmasq reads the file only when it starts, so the lease stays in memory, and from then on dnsmasq writes to the deleted file. Send the DHCPRELEASE with the address dnsmasq listens on in the VM's network as the server identifier. Give dnsmasq a moment to drop the lease before falling back, and make the fallback edit the file in place and restart a running dnsmasq.
calvix
force-pushed
the
fix/vr-redundant-dhcp-release
branch
from
September 30, 2026 06:10
8c5fea6 to
d0ca8c5
Compare
dnsmasq does not run on the backup of a redundant pair, and on routers with IPv6 on the guest NIC it keeps the leases file read-only (leasefile-ro). In both cases it never takes a released lease out of the file, so every expunge waited the full 2 s and then restarted dnsmasq; on a dual-stack router that restart also dropped every other lease dnsmasq held in memory. There the line is now taken out of the file right away, without a restart, and the backup no longer sends a release to the primary's VIP. Also read the leases file before going through it: dnsmasq and remove_lease rewrite it in place, and reading it while that happens skipped leases once the file outgrew one read buffer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
With redundant routers, the lease of an expunged VM never gets released from dnsmasq. If a new VM later gets the same IP, the primary router refuses to give it out and the VM comes up without an address.
On a redundant router the guest NIC has the router's own IP as primary and the gateway (VIP) as secondary, and dnsmasq only listens on the VIP (
listen-address=127.0.0.1,<VIP>), so the VIP is what it uses as its DHCP server identifier. On expungeCsDhcp.pycallsdhcp_release, which puts the first address of the interface into option 54 - the router IP, not the VIP. dnsmasq ignores a DHCPRELEASE that isn't addressed to its own server identifier, without logging anything, so the lease just stays in memory.The fallback from apache#13194 doesn't help either. It writes a new leases file over the old one and reloads dnsmasq, but dnsmasq only reads that file on startup, so the lease is still there, and from then on dnsmasq keeps writing to the deleted file.
Non-redundant routers aren't affected, there dnsmasq listens on the router IP, which is what
dhcp_releasesends.The fixed IP in the steps below is only there to make it reproducible. In normal use the IP is picked at random, and a freed IP is a normal candidate, so it happens whenever a new VM happens to land on the IP of an expunged one. Leases are infinite, so these stuck ones stay until dnsmasq is restarted.
How to reproduce
Create an isolated network offering with redundant routers and a network from it:
Deploy a VM with a fixed IP and expunge it:
Then deploy another one on the same IP:
One catch: dnsmasq looks leases up by client identifier first, so if the second VM sends the same client id as the first one, it just takes over the old lease and you won't see the problem. Clones of a template with a baked-in
/etc/machine-iddo exactly that. If your templates regenerate the machine-id the same template is fine, otherwise use a different one for the second VM.The second VM gets no IP, and
/var/log/dnsmasq.logon the primary router has:There's no DHCPRELEASE line for the first VM anywhere in the log.
ls -l /proc/$(pidof dnsmasq)/fdshows/var/lib/misc/dnsmasq.leases (deleted), and reading that fd still shows the old lease.You can also see the release being dropped directly on the primary router with
dhcp_release eth0 <ip> <mac>for any VM - the lease stays and nothing shows up in the log.What the fix does
listen-addressincloud.conf(the VIP on a redundant router, the router IP otherwise).CsHelper.send_dhcp_release()builds the same packet asdhcp_releaseand sends it the same way, just with the right server identifier. Guests still see the VIP as the DHCP server, so Windows passwords cannot be set or reset when the system is on an isolated network with dual routers apache/cloudstack#11877 / Password server on redundant VRs binds only the VRRP VIP, so guests never receive their password apache/cloudstack#13720 stay fixed.systemctl try-restart dnsmasqinstead of a reload. On the backup router dnsmasq isn't running, sotry-restartdoesn't do anything there.Types of changes
Feature/Enhancement Scale or Bug Severity
Bug Severity