<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style>
</head>
<body class='hmmessage'><div dir='ltr'>
<br>Hi All,<br><br>The attached patch enables dnsmasq(8) to return the ip addresses<br>of multiple tftp servers (for pxe boot) having a single alias<br>name (thru the /etc/hosts) in round robin fashion.<br><br>We have a virtual environment where there are some managed hosts<br>running kvm hypervisor and some > 150 virtual machines<br>carved out of these hosts. All these virtual machines are thin<br>clients which boot of the net using pxe. The arrangement is such<br>that all of these machines boot at the same time and in order to<br>balance the load on the tftp server, we planned to have multiple<br>tftp servers (on these managed hosts themselves) running.<br><br>dnsmasq currently returns only one address for tftp server<br>which it finds in the dhcp-boot option in the dnsmasq.conf<br>file. Although there is a provision for specifying the<br>tftp server name there but it is not used. We made<br>use of this name as an alias for multiple tftp servers<br>(using /etc/hosts) and then return the resolved addresses<br>one by one in cycle.<br><br>The function cache_find_by_name() already takes care<br>of all this and all we had to do was to just call<br>it in dhcp_reply() to get one address and return<br>that as tftp address.<br><br>If the tftp server address is specified in the dhcp-boot<br>option then that address is returned always. If address<br>is not specified and name is specified then this cyclic<br>stuff is done. This solution is working for us and hope it<br>will be useful to others.<br><br><br>Following is the patch (also attached) based on<br>dnsmasq-2.57:<br><br>................................................................<br><br>--- dnsmasq-2.57.origg/src/rfc2131.c 2011-02-17 21:00:15.000000000 +0530<br>+++ dnsmasq-2.57/src/rfc2131.c 2011-06-18 17:48:59.000000000 +0530<br>@@ -829,8 +829,23 @@<br> and set discovery_control = 8 */<br> if (boot)<br> {<br>- if (boot->next_server.s_addr)<br>+ if (boot->next_server.s_addr) {<br> mess->siaddr = boot->next_server;<br>+ } else if (boot->sname) {<br>+<br>+ /*<br>+ * If the pxe server name is given in the conf then<br>+ * cycle thru its addresses.<br>+ */<br>+<br>+ struct crec *crecp;<br>+ time_t now = dnsmasq_time();<br>+ crecp = cache_find_by_name(NULL, boot->sname, now,<br>+ F_DHCP | F_HOSTS);<br>+ if (crecp) {<br>+ mess->siaddr = *(struct in_addr*)&crecp->addr;<br>+ }<br>+ }<br> <br> if (boot->file)<br> strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);<br>@@ -2222,8 +2237,23 @@<br> strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);<br> }<br> <br>- if (boot->next_server.s_addr)<br>+ if (boot->next_server.s_addr) {<br> mess->siaddr = boot->next_server;<br>+ } else if (boot->sname) {<br>+<br>+ /*<br>+ * If the pxe server name is given in the conf then<br>+ * cycle thru its addresses.<br>+ */<br>+<br>+ struct crec *crecp;<br>+ time_t now = dnsmasq_time();<br>+ crecp = cache_find_by_name(NULL, boot->sname, now,<br>+ F_DHCP | F_HOSTS);<br>+ if (crecp) {<br>+ mess->siaddr = *(struct in_addr*)&crecp->addr;<br>+ }<br>+ }<br> }<br> else<br> /* Use the values of the relevant options if no dhcp-boot given and<br>................................................................<br><br>Sushil.<br><br><br>                                            </div></body>
</html>