You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ya...@apache.org on 2013/07/24 23:15:09 UTC

git commit: updated refs/heads/master to e14f5d0

Updated Branches:
  refs/heads/master a47faa9d2 -> e14f5d0ae


Cloudstack-3694 Dnsmasq rewrite in bash

(Sheng: Fix typo, fix log and error message, remove 'set -x' in script)

Signed-off-by: Sheng Yang <sh...@citrix.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e14f5d0a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e14f5d0a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e14f5d0a

Branch: refs/heads/master
Commit: e14f5d0aeb85fdd0eb2aff0b7d7130154e903c96
Parents: a47faa9
Author: Bharat Kumar <bh...@citrix.com>
Authored: Wed Jul 24 14:06:31 2013 +0530
Committer: Sheng Yang <sh...@citrix.com>
Committed: Wed Jul 24 14:00:31 2013 -0700

----------------------------------------------------------------------
 .../agent/api/routing/DnsMasqConfigCommand.java |  60 +-------
 .../virtualnetwork/VirtualRoutingResource.java  |  28 ++--
 .../com/cloud/network/DnsMasqConfigurator.java  | 140 -------------------
 .../debian/config/etc/init.d/cloud-early-config |   2 +
 patches/systemvm/debian/config/root/dnsmasq.sh  | 105 ++++++++++++--
 .../vmware/resource/VmwareResource.java         |  54 +++----
 .../xen/resource/CitrixResourceBase.java        |  19 +--
 scripts/vm/hypervisor/xenserver/vmops           |   4 +-
 .../VirtualNetworkApplianceManagerImpl.java     |   6 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java |   5 +
 10 files changed, 139 insertions(+), 284 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java b/core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
index 521ad70..4155013 100644
--- a/core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
+++ b/core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
@@ -21,23 +21,10 @@ import com.cloud.agent.api.to.DhcpTO;
 import java.util.List;
 
 public class DnsMasqConfigCommand extends NetworkElementCommand {
-    String domain;
-    String dns1;
-    String dns2;
-    String internal_dns1;
-    String internal_dns2;
     List<DhcpTO> dhcpTOs;
-    boolean useExternal_dns;
-    String domain_suffix;
-    boolean dns;
 
-    public DnsMasqConfigCommand(String domain, List<DhcpTO> dhcpTOs, String dns1, String dns2, String internal_dns1, String internal_dns2) {
-        this.domain = domain;
+    public DnsMasqConfigCommand(List<DhcpTO> dhcpTOs) {
         this.dhcpTOs = dhcpTOs;
-        this.dns1= dns1;
-        this.dns2= dns2;
-        this.internal_dns1 = internal_dns1;
-        this.internal_dns2 = internal_dns2;
 
     }
 
@@ -45,49 +32,4 @@ public class DnsMasqConfigCommand extends NetworkElementCommand {
         return dhcpTOs;
     }
 
-    public  String getDomain() {
-        return domain;
-    }
-
-    public String getDns1() {
-        return dns1;
-    }
-
-    public String getDns2() {
-        return dns2;
-    }
-
-    public String getInternal_dns1() {
-        return internal_dns1;
-    }
-
-    public String getInternal_dns2() {
-        return internal_dns2;
-    }
-
-    public void setUseExternalDns(boolean useExternal_dns) {
-        this.useExternal_dns = useExternal_dns;
-    }
-
-    public void setDomainSuffix(String domain_suffix) {
-        this.domain_suffix = domain_suffix;
-    }
-
-    public void setIfDnsProvided(boolean dns) {
-        this.dns =dns;
-    }
-
-    public String getDomainSuffix() {
-        return this.domain_suffix;
-    }
-
-    public boolean getUseExternalDns() {
-        return useExternal_dns;
-    }
-
-    public boolean isDnsProvided() {
-        return dns;
-    }
-
-
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index b1532a8..e5f922d 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -53,12 +53,12 @@ import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.to.DhcpTO;
 import com.cloud.agent.api.to.FirewallRuleTO;
 import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.PortForwardingRuleTO;
 import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.exception.InternalErrorException;
-import com.cloud.network.DnsMasqConfigurator;
 import com.cloud.network.HAProxyConfigurator;
 import com.cloud.network.LoadBalancerConfigurator;
 import com.cloud.network.rules.FirewallRule;
@@ -628,25 +628,15 @@ public class VirtualRoutingResource implements Manager {
     protected Answer execute(final DnsMasqConfigCommand cmd) {
         final Script command  = new Script(_callDnsMasqPath, _timeout, s_logger);
         String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        DnsMasqConfigurator configurator = new DnsMasqConfigurator();
-        String [] config = configurator.generateConfiguration(cmd);
-        String cfgFileName = routerIp.replace(".","-")+"dns.cgf";
-        String tmpCfgFileContents = "";
-        for (int i = 0; i < config.length; i++) {
-            tmpCfgFileContents += config[i];
-            tmpCfgFileContents += "\n";
-        }
-        File permKey = new File("/root/.ssh/id_rsa.cloud");
-        String cfgFilePath = "/tmp/"+cfgFileName;
-        try {
-            SshHelper.scpTo(routerIp, 3922, "root", permKey, null, "/tmp/", tmpCfgFileContents.getBytes(), cfgFileName, null);
-            command.add(routerIp);
-            command.add(cfgFilePath);
-            final String result = command.execute();
-            return new Answer(cmd, result == null, result);
-        } catch (Exception e) {
-            return new Answer(cmd, false, e.getMessage());
+        List<DhcpTO> dhcpTos = cmd.getIps();
+        String args ="";
+        for(DhcpTO dhcpTo : dhcpTos) {
+            args = args + dhcpTo.getRouterIp()+":"+dhcpTo.getGateway()+":"+dhcpTo.getNetmask()+":"+dhcpTo.getStartIpOfSubnet()+"-";
         }
+        command.add(routerIp);
+        command.add(args);
+        final String result = command.execute();
+        return new Answer(cmd, result == null, result);
     }
 
     public String getRouterStatus(String routerIP) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/core/src/com/cloud/network/DnsMasqConfigurator.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/network/DnsMasqConfigurator.java b/core/src/com/cloud/network/DnsMasqConfigurator.java
deleted file mode 100644
index 3fc61df..0000000
--- a/core/src/com/cloud/network/DnsMasqConfigurator.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.to.DhcpTO;
-import org.apache.log4j.Logger;
-
-import java.util.Arrays;
-import java.util.List;
-
-
-
- public class DnsMasqConfigurator  {
-
-         private static final Logger s_logger = Logger.getLogger(DnsMasqConfigurator.class);
-         private static String[] Dnsmasq_config = {"# Never forward plain names (without a dot or domain part) \ndomain-needed\n",
-                                           "# Never forward addresses in the non-routed address spaces. \nbogus-priv\n",
-                                           "# Uncomment this to filter useless windows-originated DNS requests # which can trigger dial-on-demand links needlessly. \n # Note that (amongst other things) this blocks all SRV requests, # so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk.# This option only affects forwarding, SRV records originating for # dnsmasq (via srv-host= lines) are not suppressed by it. \nfilterwin2k\n",
-                                           "# Change this line if you want dns to get its upstream servers from# somewhere other that /etc/resolv.conf \nresolv-file=/etc/dnsmasq-resolv.conf\n",
-                                           "# Add local-only domains here, queries in these domains are answered\n # from /etc/hosts or DHCP only.\n local=/cs1cloud.internal/",
-                                           "# If you want dnsmasq to listen for DHCP and DNS requests only on\n #specified interfaces (and the loopback) give the name of the\n# interface (eg eth0) here.\n# Repeat the line for more than one interface.\ninterface=eth0\n",
-                                           "# Or you can specify which interface _not_ to listen on\nexcept-interface=eth1\nexcept-interface=eth2\nexcept-interface=lo\n",
-                                           "# Or which to listen on by address (remember to include 127.0.0.1 if\n# you use this.)\n#listen-address=?\n",
-                                           "# If you want dnsmasq to provide only DNS service on an interface,\n# configure it as shown above, and then use the following line to\n#disable DHCP and TFTP on it.\nno-dhcp-interface=eth1\nno-dhcp-interface=eth2\n",
-                                           "# On systems which support it, dnsmasq binds the wildcard address,\n" +
-                                                   "# even when it is listening on only some interfaces. It then discards\n" +
-                                                   "# requests that it shouldn't reply to. This has the advantage of\n" +
-                                                   "# working even when interfaces come and go and change address. If you\n" +
-                                                   "# want dnsmasq to really bind only the interfaces it is listening on,\n" +
-                                                   "# uncomment this option. About the only time you may need this is when\n" +
-                                                   "# running another nameserver on the same machine.\n" +
-                                                   "bind-interfaces\n",
-                                           "# Set this (and domain: see below) if you want to have a domain\n" +
-                                                   "# automatically added to simple names in a hosts-file.\n" +
-                                                   "expand-hosts\n",
-                                           "# Set the domain for dnsmasq. this is optional, but if it is set, it\n" +
-                                                   "# does the following things.\n" +
-                                                   "# 1) Allows DHCP hosts to have fully qualified domain names, as long\n" +
-                                                   "#     as the domain part matches this setting.\n" +
-                                                   "# 2) Sets the \"domain\" DHCP option thereby potentially setting the\n" +
-                                                   "#    domain of all systems configured by DHCP\n" +
-                                                   "# 3) Provides the domain part for \"expand-hosts\"\n",
-                                                   "domain=cs1cloud.internal\n",
-                                           "# Set a different domain for a particular subnet\n",
-                                                   "domain=cs1cloud.internal\n",
-                                           "# Same idea, but range rather then subnet\n",
-                                                   "domain=cs1cloud.internal\n",
-                                           "# Uncomment this to enable the integrated DHCP server, you need\n" +
-                                                   "# to supply the range of addresses available for lease and optionally\n" +
-                                                   "# a lease time. If you have more than one network, you will need to\n" +
-                                                   "# repeat this for each network on which you want to supply DHCP\n" +
-                                                   "# service.\n",
-                                                   "dhcp-range=set:net1,ipaddress,static\n",
-                                           "dhcp-hostsfile=/etc/dhcphosts.txt\n",
-                                           "log-facility=/var/log/dnsmasq.log\n",
-                                           "conf-dir=/etc/dnsmasq.d\n",
-                                           "dhcp-option=tag:net1,3,ipaddress\n",
-                                           "dhcp-option=tag:net1,1,netmask\n",
-                                           "dhcp-option=6,router_ip,external_dns\n",
-                                           "dhcp-optsfile=/etc/dhcpopts.txt\n",
-
-         };
-
-     public String[] generateConfiguration(DnsMasqConfigCommand dnsMasqconfigcmd) {
-         List<DhcpTO> dhcpTOs = dnsMasqconfigcmd.getIps();
-         List <String> dnsMasqconf = Arrays.asList(Dnsmasq_config);
-         String range="";
-         String gateway="";
-         String netmask="";
-         String domain= dnsMasqconfigcmd.getDomain();
-         String dnsServers="";
-         String dns_external="";
-         if (dnsMasqconfigcmd.getDns1()!= null) {
-             dns_external = dnsMasqconfigcmd.getDns1()+",";
-         }
-         if (dnsMasqconfigcmd.getDns2() != null) {
-             dns_external = dns_external+dnsMasqconfigcmd.getDns2()+",";
-         }
-         dns_external = dns_external + "*";
-         dns_external = dns_external.replace(",*","");
-         int i=0;
-         for (; i< dhcpTOs.size(); i++) {
-              range=range + "dhcp-range=set:range"+i+","+ dhcpTOs.get(i).getStartIpOfSubnet()+",static\n";
-              gateway=gateway +"dhcp-option=tag:range"+i+",3,"+ dhcpTOs.get(i).getGateway()+"\n";
-              netmask=netmask +"dhcp-option=tag:range"+i+",1,"+ dhcpTOs.get(i).getNetmask()+"\n";
-              if (!dnsMasqconfigcmd.isDnsProvided()) {
-                  dnsServers = dnsServers+"dhcp-option=tag:range"+i+",6,"+dns_external+"\n";
-              }
-              else {
-                  dnsServers=dnsServers+"dhcp-option=tag:range"+i+",6,"+ dhcpTOs.get(i).getRouterIp()+","+dns_external+"\n";
-              }
-
-         }
-         String domain_suffix= dnsMasqconfigcmd.getDomainSuffix();
-
-         if (domain != null) {
-             if (domain_suffix != null) {
-
-                 dnsMasqconf.get(5).replace(" local=/cs1cloud.internal/"," local=/"+domain+"/");
-                 dnsMasqconf.set(12, "domain="+domain_suffix+domain+"\n");
-                 dnsMasqconf.set(14, "domain="+domain_suffix+domain+"\n");
-                 dnsMasqconf.set(16,"domain="+domain_suffix+domain+"\n");
-             } else {
-                 dnsMasqconf.get(5).replace(" local=/cs1cloud.internal/"," local=/"+domain+"/");
-                 dnsMasqconf.set(12, "domain="+domain+"\n");
-                 dnsMasqconf.set(14, "domain="+domain+"\n");
-                 dnsMasqconf.set(16,"domain="+domain+"\n");
-             }
-         }
-         ///if no domain is specified. this happens when dns service is not provided by the virtualrouter.
-         else {
-             dnsMasqconf.get(5).replace(" local=/cs1cloud.internal/"," local=/"+domain+"/");
-             dnsMasqconf.set(12, "domain="+"cloudnine.internal\n");
-             dnsMasqconf.set(14, "domain="+"cloudnine.internal\n");
-             dnsMasqconf.set(16,"domain="+"cloudnine.internal\n");
-         }
-
-         dnsMasqconf.set(18, range);
-         dnsMasqconf.set(22, gateway);
-         dnsMasqconf.set(23, netmask);
-         dnsMasqconf.set(24,dnsServers);
-         return dnsMasqconf.toArray( new  String[dnsMasqconf.size()]);
-     }
-
- }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/patches/systemvm/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config
index 168c012..02af602 100755
--- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config
+++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config
@@ -521,6 +521,8 @@ setup_dnsmasq() {
   [ -z $DHCP_RANGE ] && [ $ETH0_IP ] && DHCP_RANGE=$ETH0_IP
   [ $ETH0_IP6 ] && DHCP_RANGE_IP6=$ETH0_IP6
   [ -z $DOMAIN ] && DOMAIN="cloudnine.internal"
+  #removing the dnsmasq multiple ranges config file.
+  rm /etc/dnsmasq.d/multiple_ranges.conf
 
   #get the template
   cp /etc/dnsmasq.conf.tmpl /etc/dnsmasq.conf

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/patches/systemvm/debian/config/root/dnsmasq.sh
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/dnsmasq.sh b/patches/systemvm/debian/config/root/dnsmasq.sh
index b70e2d3..c6ab07a 100755
--- a/patches/systemvm/debian/config/root/dnsmasq.sh
+++ b/patches/systemvm/debian/config/root/dnsmasq.sh
@@ -10,14 +10,13 @@
 #   http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
 
 usage() {
-  printf "Usage: %s:  <path to new dnsmasq config file>\n" $(basename $0) >&2
+  printf "Usage: %s:  <routerAliasIp:gateway:netmask:start_ip_of_subnet:-routerAlisIp:gateway:....>\n" $(basename $0) >&2
 }
 
 source /root/func.sh
@@ -29,24 +28,104 @@ then
     exit 1
 fi
 
-set -x
+#set -x
 #backup the old config file
-cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak
+DHCP_CONFIG=/etc/dnsmasq.d/multiple_ranges.conf
+DHCP_CONFIG_BAK=/etc/dnsmasq.d/multiple_ranges.conf.bak
+DHCP_CONFIG_MAIN=/etc/dnsmasq.conf
+DHCP_CONFIG_MAIN_BAK=/etc/dnsmasq.conf.bak
+DHCP_FAILURE_CONFIG=/etc/multiple_ranges.conf.failure
+DHCP_FAILURE_CONFIG_MAIN=/etc/dnsmasq.conf.failure
+CMDLINE=$(cat /var/cache/cloud/cmdline | tr '\n' ' ')
+
+#take a backup copy of the dnsmasq file.
+cp "$DHCP_CONFIG_MAIN"  "$DHCP_CONFIG_MAIN_BAK"
+cp "$DHCP_CONFIG" "$DHCP_CONFIG_BAK"
+
+#empty the config file
+echo > $DHCP_CONFIG
+
+var="$1"
+dhcp_range=""
+dhcp_gateway=""
+dhcp_netmask=""
+dns_option=""
+dns_servers=""
+count=0
+
+
+# fetching the dns Ips from the command line.
+dns1=$(echo "$CMDLINE" | grep -o " dns1=.* " | sed -e 's/dns1=//' | awk '{print $1}')
+dns2=$(echo "$CMDLINE" | grep -o " dns2=.* "  | sed -e 's/dns2=//' | awk '{print $1}')
+
+dns_servers="${dns1}"
+if [ -n "$dns2" ]
+then
+dns_servers="${dns1},${dns2}"
+fi
+
+
+# check if useextdns is true
+use_ext_dns=$(echo "$CMDLINE" | grep -o "useextdns=true")
+while [ -n "$var" ]
+do
+ var1=$(echo $var | cut -f1 -d "-")
+ routerip=$( echo $var1 | cut -f1 -d ":" )
+ gateway=$(echo $var1 | cut -f2 -d ":")
+ netmask=$(echo $var1 | cut -f3 -d ":")
+ start_ip_of_subnet=$(echo $var1 | cut -f4 -d ":")
+ dhcp_range="${dhcp_range}"'dhcp-range=set:range'$count","$start_ip_of_subnet",static \n"
+ dhcp_gateway="${dhcp_gateway}"'dhcp-option=tag:range'$count",3,"$gateway" \n"
+ dhcp_netmask="${dhcp_netmask}"'dhcp-option=tag:range'$count",1,"$netmask" \n"
+ if [ -n "$use_ext_dns" ]
+ then
+ dns_option="${dns_option}"'dhcp-option=tag:range'$count",6,"$dns_servers" \n"
+ else
+ dns_option="${dns_option}"'dhcp-option=tag:range'$count",6,$routerip"","$dns_servers" \n"
+ fi
+ var=$( echo $var | sed "s/${var1}-//" )
+ count=$[$count+1]
+done
+
+#logging the configuration being removed.
+log=""
+log="${log}"`grep "^dhcp-option=6.*" "$DHCP_CONFIG_MAIN"`"\n"
+log="${log}"`grep "^dhcp-option=option:router.*" "$DHCP_CONFIG_MAIN"`"\n"
+log="${log}"`grep "^dhcp-range=.*" "$DHCP_CONFIG_MAIN"`"\n"
+echo -e "$log" > log.dnsmasq.txt
+
+if [ "$log" != '\n\n\n' ]
+then
+ #Cleaning the existing dhcp confgiuration
+ logger -t cloud "dnsmasq.sh: remvoing the primaryip confg from dnsmasq.conf and adding it to /etc/dnsmaq.d/multiple_ranges.conf"
+ logger -t cloud "dnsmasq.sh: config removed from dnsmasq.conf is $log"
+ sed -i -e '/dhcp-option=6.*/d'  "$DHCP_CONFIG_MAIN"
+ sed -i -e '/dhcp-option=option:router.*/d' "$DHCP_CONFIG_MAIN"
+ sed -i -e '/dhcp-range=.*/d' "$DHCP_CONFIG_MAIN"
+fi
+
+#wrting the new config into the config file.
+echo -e "$dhcp_range" >> "$DHCP_CONFIG"
+echo -e "$dhcp_gateway" >> "$DHCP_CONFIG"
+echo -e "$dhcp_netmask" >> "$DHCP_CONFIG"
+echo -e "$dns_option" >> "$DHCP_CONFIG"
 
-#apply the new confg
-echo $1
-cp $1 /etc/dnsmasq.conf
 
 #restart the dnsmasq
 service dnsmasq restart
 result=$?
 if [ "$result" -ne "0" ]
 then
-   echo "could not configure dnsmasq"
-   echo "reverting to the old config"
-   cp /etc/dnsmasq.config.bak /etc/dnsmasq.conf
+   logger -t cloud "dnsmasq.sh: could not configure dnsmasq"
+   logger -t cloud "dnsmasq.sh: reverting to the old config"
+   logger -t cloud "dnsmasq.sh: copying the failure config to `$DHCP_FAILURE_CONFIG` and `$DHCP_FAILURE_CONFIG_MAIN`"
+   cp "$DHCP_CONFIG" "$DHCP_FAILURE_CONFIG"
+   cp "$DHCP_CONFIG_MAIN" "$DHCP_FAILURE_CONFIG_MAIN"
+   cp "$DHCP_CONFIG_BAK" "$DHCP_CONFIG"
+   cp "$DHCP_CONFIG_MAIN_BAK" "$DHCP_CONFIG_MAIN"
    service dnsmasq restart
-   unlock_exit $? $lock $locked
+   unlock_exit $result $lock $locked
 fi
-rm $1
-unlock_exit $? $lock $locked
+rm "$DHCP_CONFIG_BAK"
+rm "$DHCP_CONFIG_MAIN_BAK"
+unlock_exit $result $lock $locked

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index c7f487e..ab8c520 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -44,6 +44,7 @@ import java.util.UUID;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.agent.api.to.DhcpTO;
 import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 
@@ -287,7 +288,6 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.hypervisor.vmware.util.VmwareGuestOsMapper;
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.network.DnsMasqConfigurator;
 import com.cloud.network.HAProxyConfigurator;
 import com.cloud.network.LoadBalancerConfigurator;
 import com.cloud.network.Networks;
@@ -2136,47 +2136,35 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
 
         assert(controlIp != null);
 
-        DnsMasqConfigurator configurator = new DnsMasqConfigurator();
-        String [] config = configurator.generateConfiguration(cmd);
-        String tmpConfigFilePath = "/tmp/"+ routerIp.replace(".","_")+".cfg";
-        String tmpConfigFileContents = "";
-        for (int i = 0; i < config.length; i++) {
-            tmpConfigFileContents += config[i];
-            tmpConfigFileContents += "\n";
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/dnsmasq.sh " +"config file at" + tmpConfigFilePath);
+        List<DhcpTO> dhcpTos = cmd.getIps();
+        String args ="";
+        for(DhcpTO dhcpTo : dhcpTos) {
+            args = args + dhcpTo.getRouterIp()+":"+dhcpTo.getGateway()+":"+dhcpTo.getNetmask()+":"+dhcpTo.getStartIpOfSubnet()+"-";
         }
         VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
         File keyFile = mgr.getSystemVMKeyFile();
 
         try {
-            SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", keyFile, null, "/tmp/", tmpConfigFileContents.getBytes(), routerIp.replace('.', '_') + ".cfg", null);
-
-            try {
-
-                Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/root/dnsmasq.sh " + tmpConfigFilePath);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Run command on domain router " + routerIp + ",  /root/dnsmasq.sh");
-                }
-
-                if (!result.first()) {
-                    s_logger.error("Unable to copy dnsmasq configuration file");
-                    return new Answer(cmd, false, "dnsmasq config failed due to uanble to copy dnsmasq configuration file");
-                }
+            Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/root/dnsmasq.sh " + args);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Run command on domain router " + routerIp + ",  /root/dnsmasq.sh");
+            }
 
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("dnsmasq config command on domain router " + routerIp + " completed");
-                }
-            } finally {
-                SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "rm " + tmpConfigFilePath);
+            if (!result.first()) {
+                s_logger.error("Unable update dnsmasq config file");
+                return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second());
             }
 
-            return new Answer(cmd);
-        } catch (Throwable e) {
-            s_logger.error("Unexpected exception: " + e.toString(), e);
-            return new Answer(cmd, false, " DnsmasqConfig command failed due to " + VmwareHelper.getExceptionMessage(e));
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed");
+            }
+        }catch (Throwable e) {
+            String msg = "Dnsmasqconfig command failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
         }
+
+        return new Answer(cmd);
     }
 
     protected CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 0fba0d9..7173f0b 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -53,6 +53,7 @@ import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 import javax.xml.parsers.DocumentBuilderFactory;
 
+import com.cloud.agent.api.to.DhcpTO;
 import org.apache.log4j.Logger;
 import org.apache.xmlrpc.XmlRpcException;
 import org.w3c.dom.Document;
@@ -254,7 +255,6 @@ import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.exception.InternalErrorException;
 import com.cloud.host.Host.Type;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.DnsMasqConfigurator;
 import com.cloud.network.HAProxyConfigurator;
 import com.cloud.network.LoadBalancerConfigurator;
 import com.cloud.network.Networks;
@@ -2058,20 +2058,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     protected Answer execute(final DnsMasqConfigCommand cmd) {
         Connection conn = getConnection();
         String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        DnsMasqConfigurator configurator = new DnsMasqConfigurator();
-        String [] config = configurator.generateConfiguration(cmd);
-        String tmpConfigFilePath = "/tmp/"+ routerIp.replace(".","-")+".cfg";
-        String tmpConfigFileContents = "";
-        for (int i = 0; i < config.length; i++) {
-            tmpConfigFileContents += config[i];
-            tmpConfigFileContents += "\n";
+        List<DhcpTO> dhcpTos = cmd.getIps();
+        String args ="";
+        for(DhcpTO dhcpTo : dhcpTos) {
+            args = args + dhcpTo.getRouterIp()+":"+dhcpTo.getGateway()+":"+dhcpTo.getNetmask()+":"+dhcpTo.getStartIpOfSubnet()+"-";
         }
 
-        String result = callHostPlugin(conn, "vmops", "createFileInDomr", "filepath", tmpConfigFilePath, "filecontents", tmpConfigFileContents, "domrip" ,routerIp);
-        if (result == null || result.isEmpty()) {
-            return new Answer(cmd, false, "DnsMasqConfigCommand failed to create DnsMasq cfg file.");
-        }
-        result = callHostPlugin(conn, "vmops", "configdnsmasq", "routerip", routerIp, "filepath", tmpConfigFilePath);
+        String result = callHostPlugin(conn, "vmops", "configdnsmasq", "routerip", routerIp, "args", args);
 
         if (result == null || result.isEmpty()) {
             return new Answer(cmd, false, "DnsMasqconfigCommand failed");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/scripts/vm/hypervisor/xenserver/vmops
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops
index f8c0253..9a0ef44 100755
--- a/scripts/vm/hypervisor/xenserver/vmops
+++ b/scripts/vm/hypervisor/xenserver/vmops
@@ -358,10 +358,10 @@ def setLoadBalancerRule(session, args):
 @echo
 def configdnsmasq(session, args):
     routerip = args['routerip']
-    filepath = args['filepath']
+    args = args['filepath']
     target   = "root@"+routerip
     try:
-       util.pread2(['ssh','-p','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',target,'/root/dnsmasq.sh',filepath])
+       util.pread2(['ssh','-p','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',target,'/root/dnsmasq.sh',args])
        txt='success'
     except:
        util.SMlog("failed to config dnsmasq server")

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 5ab5934..c2a9d72 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -3446,15 +3446,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
              ipAliasVO.setVmId(router.getId());
         }
         DataCenterVO dcvo = _dcDao.findById(router.getDataCenterId());
-        boolean dnsProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter);
-        String domain_suffix = dcvo.getDetail(ZoneConfig.DnsSearchOrder.getName());
-        DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(network.getNetworkDomain(),ipList, dcvo.getDns1(), dcvo.getDns2(), dcvo.getInternalDns1(), dcvo.getInternalDns2());
+        DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(ipList);
         dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
         dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
         dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId()));
         dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        dnsMasqConfigCmd.setDomainSuffix(domain_suffix);
-        dnsMasqConfigCmd.setIfDnsProvided(dnsProvided);
         cmds.addCommand("dnsMasqConfig" ,dnsMasqConfigCmd);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e14f5d0a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 33dadf0..50e6812 100755
--- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -2894,6 +2894,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                 _networkModel.isSecurityGroupSupportedInNetwork(network),
                 _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
 
+        // Adding this to the dhcpservice config if this is the last nic in subnet.
+        if (vm.getType() == VirtualMachine.Type.User) {
+            removeDhcpServiceInsubnet(vm);
+        }
+
         //1) Unplug the nic
         if (vm.getState() == State.Running) {
             NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());