bug 11585: using pre-allocated NIC approach to support additional public interfaces for VMware

This commit is contained in:
Kelven Yang 2011-10-11 15:13:30 -07:00
parent c6c5e8f557
commit dce4e74b58
8 changed files with 306 additions and 28 deletions

View File

@ -47,6 +47,7 @@ public interface VmwareManager {
Pair<Integer, Integer> getAddiionalVncPortRange(); Pair<Integer, Integer> getAddiionalVncPortRange();
int getMaxHostsPerCluster(); int getMaxHostsPerCluster();
int getRouterExtraPublicNics();
boolean beginExclusiveOperation(int timeOutSeconds); boolean beginExclusiveOperation(int timeOutSeconds);
void endExclusiveOperation(); void endExclusiveOperation();

View File

@ -213,6 +213,7 @@ import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualDeviceConfigSpecOperation; import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
import com.vmware.vim25.VirtualDisk; import com.vmware.vim25.VirtualDisk;
import com.vmware.vim25.VirtualEthernetCard; import com.vmware.vim25.VirtualEthernetCard;
import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo;
import com.vmware.vim25.VirtualLsiLogicController; import com.vmware.vim25.VirtualLsiLogicController;
import com.vmware.vim25.VirtualMachineConfigSpec; import com.vmware.vim25.VirtualMachineConfigSpec;
import com.vmware.vim25.VirtualMachineFileInfo; import com.vmware.vim25.VirtualMachineFileInfo;
@ -452,7 +453,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
s_logger.info("Executing resource SetPortForwardingRulesCommand: " + _gson.toJson(cmd)); s_logger.info("Executing resource SetPortForwardingRulesCommand: " + _gson.toJson(cmd));
} }
// String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = getRouterSshControlIp(cmd); String controlIp = getRouterSshControlIp(cmd);
String args = ""; String args = "";
String[] results = new String[cmd.getRules().length]; String[] results = new String[cmd.getRules().length];
@ -547,7 +547,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
s_logger.info("Executing resource SetFirewallRuleCommand: " + _gson.toJson(cmd)); s_logger.info("Executing resource SetFirewallRuleCommand: " + _gson.toJson(cmd));
} }
// String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String args = null; String args = null;
String[] results = new String[cmd.getRules().length]; String[] results = new String[cmd.getRules().length];
int i = 0; int i = 0;
@ -759,7 +758,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
} }
if (removeVif) { if (removeVif) {
vmMo.tearDownDevice(publicNicInfo.second());
String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
int nicMasks = Integer.parseInt(nicMasksStr);
nicMasks &= ~(1 << publicNicInfo.first().intValue());
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
// vmMo.tearDownDevice(publicNicInfo.second());
HostMO hostMo = vmMo.getRunningHost(); HostMO hostMo = vmMo.getRunningHost();
List<NetworkDetails> networks = vmMo.getNetworksWithDetails(); List<NetworkDetails> networks = vmMo.getNetworksWithDetails();
@ -782,12 +787,64 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
Pair<ManagedObjectReference, String> networkInfo = HypervisorHostHelper.preparePublicNetwork(this._publicNetworkVSwitchName, Pair<ManagedObjectReference, String> networkInfo = HypervisorHostHelper.preparePublicNetwork(this._publicNetworkVSwitchName,
vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true); vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true);
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); int nicIndex = allocPublicNicIndex(vmMo);
try {
VirtualDevice[] nicDevices = vmMo.getNicDevices();
VirtualEthernetCard device = (VirtualEthernetCard)nicDevices[nicIndex];
VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
nicBacking.setDeviceName(networkInfo.second());
nicBacking.setNetwork(networkInfo.first());
device.setBacking(nicBacking);
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec();
deviceConfigSpecArray[0].setDevice(device);
deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.edit);
vmConfigSpec.setDeviceChange(deviceConfigSpecArray);
if(!vmMo.configureVm(vmConfigSpec)) {
throw new Exception("Failed to configure devices when plugPublicNic");
}
} catch(Exception e) {
// restore allocation mask in case of exceptions
String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
int nicMasks = Integer.parseInt(nicMasksStr);
nicMasks &= ~(1 << nicIndex);
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
throw e;
}
/*
// Note: public NIC is plugged inside system VM // Note: public NIC is plugged inside system VM
VirtualDevice nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), VirtualEthernetCardType.Vmxnet3, VirtualDevice nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), VirtualEthernetCardType.Vmxnet3,
networkInfo.second(), vifMacAddress, -1, 1, true, true); networkInfo.second(), vifMacAddress, -1, 1, true, true);
vmMo.plugDevice(nic); vmMo.plugDevice(nic);
*/
}
private int allocPublicNicIndex(VirtualMachineMO vmMo) throws Exception {
String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
if(nicMasksStr == null || nicMasksStr.isEmpty()) {
throw new Exception("Could not find NIC allocation info");
}
int nicMasks = Integer.parseInt(nicMasksStr);
VirtualDevice[] nicDevices = vmMo.getNicDevices();
for(int i = 3; i < nicDevices.length; i++) {
if((nicMasks & (1 << i)) == 0) {
nicMasks |= (1 << i);
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
return i;
}
}
throw new Exception("Could not allocate a free public NIC");
} }
protected Answer execute(IpAssocCommand cmd) { protected Answer execute(IpAssocCommand cmd) {
@ -804,7 +861,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
IpAddressTO[] ips = cmd.getIpAddresses(); IpAddressTO[] ips = cmd.getIpAddresses();
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
// String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = VmwareResource.getRouterSshControlIp(cmd); String controlIp = VmwareResource.getRouterSshControlIp(cmd);
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName); VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName);
@ -1352,6 +1408,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
} }
VirtualDevice nic; VirtualDevice nic;
int nicMask = 0;
int nicCount = 0;
for (NicTO nicTo : sortNicsByDeviceId(nics)) { for (NicTO nicTo : sortNicsByDeviceId(nics)) {
s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo)); s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
@ -1365,7 +1423,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if(s_logger.isDebugEnabled()) if(s_logger.isDebugEnabled())
s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i])); s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i]));
// this is really a hacking for DomR, upon DomR startup, we will reset all the NIC allocation after eth3
if(nicCount < 3)
nicMask |= (1 << nicCount);
i++; i++;
nicCount++;
} }
vmConfigSpec.setDeviceChange(deviceConfigSpecArray); vmConfigSpec.setDeviceChange(deviceConfigSpecArray);
@ -1389,6 +1452,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
throw new Exception("Failed to configure VM before start. vmName: " + vmName); throw new Exception("Failed to configure VM before start. vmName: " + vmName);
} }
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMask));
if (!vmMo.powerOn()) { if (!vmMo.powerOn()) {
throw new Exception("Failed to start VM. vmName: " + vmName); throw new Exception("Failed to start VM. vmName: " + vmName);
} }
@ -1510,7 +1575,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
} }
protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) { protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) {
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = getRouterSshControlIp(cmd); String controlIp = getRouterSshControlIp(cmd);
StringBuffer argsBuf = new StringBuffer(); StringBuffer argsBuf = new StringBuffer();
if (cmd.isCreate()) { if (cmd.isCreate()) {
@ -1557,7 +1621,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
protected synchronized Answer execute(final VpnUsersCfgCommand cmd) { protected synchronized Answer execute(final VpnUsersCfgCommand cmd) {
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = getRouterSshControlIp(cmd); String controlIp = getRouterSshControlIp(cmd);
for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) {
StringBuffer argsBuf = new StringBuffer(); StringBuffer argsBuf = new StringBuffer();
@ -1776,6 +1839,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
} }
try { try {
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, "0");
if (getVmState(vmMo) != State.Stopped) { if (getVmState(vmMo) != State.Stopped) {
Long bytesSent = 0L; Long bytesSent = 0L;
Long bytesRcvd = 0L; Long bytesRcvd = 0L;
@ -3781,6 +3846,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID); cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC); cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC);
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID); cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
VmwareHypervisorHost hostMo = this.getHyperHost(context); VmwareHypervisorHost hostMo = this.getHyperHost(context);
_hostName = hostMo.getHyperHostName(); _hostName = hostMo.getHyperHostName();

View File

@ -24,13 +24,44 @@ log_it() {
log_action_begin_msg "$@" log_action_begin_msg "$@"
} }
init_interfaces_orderby_macs() {
macs=( $(echo $1 | sed "s/|/ /g") )
total_nics=${#macs[@]}
interface_file=${2:-"/etc/network/interfaces"}
rule_file=${3:-"/etc/udev/rules.d/70-persistent-net.rules"}
echo -n "auto lo" > $interface_file
for((i=0; i<total_nics; i++))
do
if [[ $i < 3 ]]
then
echo -n " eth$i" >> $interface_file
fi
done
cat >> $interface_file << EOF
iface lo inet loopback
EOF
echo "" > $rule_file
for((i=0; i < ${#macs[@]}; i++))
do
echo "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"${macs[$i]}\", NAME=\"eth$i\"" >> $rule_file
done
}
init_interfaces() { init_interfaces() {
cat > /etc/network/interfaces << EOF if [ "$NIC_MACS" == "" ]
then
cat > /etc/network/interfaces << EOF
auto lo $1 $2 $3 auto lo $1 $2 $3
iface lo inet loopback iface lo inet loopback
EOF EOF
else
init_interfaces_orderby_macs "$NIC_MACS"
fi
} }
hypervisor() { hypervisor() {
@ -120,6 +151,7 @@ patch() {
hyperVisor=$(hypervisor) hyperVisor=$(hypervisor)
/opt/cloud/bin/patchsystemvm.sh $PATCH_MOUNT $hyperVisor /opt/cloud/bin/patchsystemvm.sh $PATCH_MOUNT $hyperVisor
umount $PATCH_MOUNT umount $PATCH_MOUNT
if [ "$shouldpatch" == "true" ] if [ "$shouldpatch" == "true" ]
then then
log_it "Rebooting system since we patched init scripts" log_it "Rebooting system since we patched init scripts"
@ -139,6 +171,7 @@ setup_interface() {
local ip=$2 local ip=$2
local mask=$3 local mask=$3
local gw=$4 local gw=$4
local force=$5
local intf=eth${intfnum} local intf=eth${intfnum}
local bootproto="static" local bootproto="static"
@ -151,7 +184,7 @@ setup_interface() {
fi fi
fi fi
if [ "$ip" != "0.0.0.0" -a "$ip" != "" ] if [ "$ip" != "0.0.0.0" -a "$ip" != "" -o "$force" == "force" ]
then then
echo "iface $intf inet $bootproto" >> /etc/network/interfaces echo "iface $intf inet $bootproto" >> /etc/network/interfaces
if [ "$bootproto" == "static" ] if [ "$bootproto" == "static" ]
@ -161,11 +194,16 @@ setup_interface() {
fi fi
fi fi
ifdown $intf if [ "$force" == "force" ]
ifup $intf
if [ "$RROUTER" == "1" -a "$1" == "2" ]
then then
ifdown $intf ifdown $intf
else
ifdown $intf
ifup $intf
if [ "$RROUTER" == "1" -a "$1" == "2" ]
then
ifdown $intf
fi
fi fi
} }
@ -391,17 +429,56 @@ setup_redundant_router() {
setup_router() { setup_router() {
log_it "Setting up virtual router system vm" log_it "Setting up virtual router system vm"
oldmd5=
[ -f "/etc/udev/rules.d/70-persistent-net.rules" ] && oldmd5=$(md5sum "/etc/udev/rules.d/70-persistent-net.rules" | awk '{print $1}')
if [ -n "$ETH2_IP" ] if [ -n "$ETH2_IP" ]
then then
setup_common eth0 eth1 eth2 setup_common eth0 eth1 eth2
if [ "$RROUTER" == "1" ]
if [ -n "$EXTRA_PUBNICS" ]
then then
setup_redundant_router for((i = 3; i < 3 + $EXTRA_PUBNICS; i++))
do
setup_interface "$i" "0.0.0.0" "255.255.255.255" $GW "force"
done
fi fi
else else
setup_common eth0 eth1 setup_common eth0 eth1
if [ -n "$EXTRA_PUBNICS" ]
then
for((i = 2; i < 2 + $EXTRA_PUBNICS; i++))
do
setup_interface "$i" "0.0.0.0" "255.255.255.255" $GW "force"
done
fi
fi fi
if [ -n "$ETH2_IP" -a "$RROUTER" == "1" ]
then
setup_redundant_router
fi
log_it "Checking udev NIC assignment order changes"
if [ "$NIC_MACS" != "" ]
then
init_interfaces_orderby_macs "$NIC_MACS" "/tmp/interfaces" "/tmp/udev-rules"
newmd5=$(md5sum "/tmp/udev-rules" | awk '{print $1}')
rm /tmp/interfaces
rm /tmp/udev-rules
if [ "$oldmd5" != "$newmd5" ]
then
log_it "udev NIC assignment requires reboot to take effect"
sync
sleep 2
reboot
fi
fi
setup_dnsmasq setup_dnsmasq
NS=$NS1 NS=$NS1
@ -706,6 +783,12 @@ for i in $CMDLINE
router_pr) router_pr)
ROUTER_PR=$VALUE ROUTER_PR=$VALUE
;; ;;
extra_pubnics)
EXTRA_PUBNICS=$VALUE
;;
nic_macs)
NIC_MACS=$VALUE
;;
esac esac
done done
} }

View File

@ -151,6 +151,7 @@ public enum Config {
RestartRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "restart.retry.interval", "600", "Time (in seconds) between retries to restart a vm", null), RestartRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "restart.retry.interval", "600", "Time (in seconds) between retries to restart a vm", null),
RouterStatsInterval("Advanced", NetworkManager.class, Integer.class, "router.stats.interval", "300", "Interval (in seconds) to report router statistics.", null), RouterStatsInterval("Advanced", NetworkManager.class, Integer.class, "router.stats.interval", "300", "Interval (in seconds) to report router statistics.", null),
RouterTemplateId("Advanced", NetworkManager.class, Long.class, "router.template.id", "1", "Default ID for template.", null), RouterTemplateId("Advanced", NetworkManager.class, Long.class, "router.template.id", "1", "Default ID for template.", null),
RouterExtraPublicNics("Advanced", NetworkManager.class, Integer.class, "router.extra.public.nics", "2", "specify extra public nics used for virtual router(up to 5)", "0-5"),
StartRetry("Advanced", AgentManager.class, Integer.class, "start.retry", "10", "Number of times to retry create and start commands", null), StartRetry("Advanced", AgentManager.class, Integer.class, "start.retry", "10", "Number of times to retry create and start commands", null),
StopRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "stop.retry.interval", "600", "Time in seconds between retries to stop or destroy a vm" , null), StopRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "stop.retry.interval", "600", "Time in seconds between retries to stop or destroy a vm" , null),
StorageCleanupInterval("Advanced", StorageManager.class, Integer.class, "storage.cleanup.interval", "86400", "The interval (in seconds) to wait before running the storage cleanup thread.", null), StorageCleanupInterval("Advanced", StorageManager.class, Integer.class, "storage.cleanup.interval", "86400", "The interval (in seconds) to wait before running the storage cleanup thread.", null),

View File

@ -3,7 +3,11 @@
*/ */
package com.cloud.hypervisor.guru; package com.cloud.hypervisor.guru;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.ejb.Local; import javax.ejb.Local;
@ -19,9 +23,11 @@ import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.cluster.CheckPointManager; import com.cloud.cluster.CheckPointManager;
import com.cloud.cluster.ClusterManager; import com.cloud.cluster.ClusterManager;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDetailsDao;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
@ -31,6 +37,10 @@ import com.cloud.hypervisor.HypervisorGuruBase;
import com.cloud.hypervisor.vmware.VmwareCleanupMaid; import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
import com.cloud.hypervisor.vmware.manager.VmwareManager; import com.cloud.hypervisor.vmware.manager.VmwareManager;
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkVO;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.secstorage.CommandExecLogDao; import com.cloud.secstorage.CommandExecLogDao;
import com.cloud.secstorage.CommandExecLogVO; import com.cloud.secstorage.CommandExecLogVO;
import com.cloud.storage.GuestOSVO; import com.cloud.storage.GuestOSVO;
@ -40,9 +50,11 @@ import com.cloud.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
import com.cloud.utils.component.Inject; import com.cloud.utils.component.Inject;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.NetUtils;
import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouterVO; import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
@ -52,6 +64,7 @@ import com.cloud.vm.VmDetailConstants;
public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru { public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
private static final Logger s_logger = Logger.getLogger(VMwareGuru.class); private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
@Inject NetworkDao _networkDao;
@Inject GuestOSDao _guestOsDao; @Inject GuestOSDao _guestOsDao;
@Inject HostDao _hostDao; @Inject HostDao _hostDao;
@Inject HostDetailsDao _hostDetailsDao; @Inject HostDetailsDao _hostDetailsDao;
@ -60,6 +73,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject VmwareManager _vmwareMgr; @Inject VmwareManager _vmwareMgr;
@Inject SecondaryStorageVmManager _secStorageMgr; @Inject SecondaryStorageVmManager _secStorageMgr;
@Inject CheckPointManager _checkPointMgr; @Inject CheckPointManager _checkPointMgr;
@Inject NetworkManager _networkMgr;
protected VMwareGuru() { protected VMwareGuru() {
super(); super();
@ -109,12 +123,107 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
} }
to.setDetails(details); to.setDetails(details);
if(vm.getVirtualMachine() instanceof DomainRouterVO) {
List<NicProfile> nicProfiles = vm.getNics();
NicProfile publicNicProfile = null;
for(NicProfile nicProfile : nicProfiles) {
if(nicProfile.getTrafficType() == TrafficType.Public) {
publicNicProfile = nicProfile;
break;
}
}
if(publicNicProfile != null) {
NicTO[] nics = to.getNics();
// reserve extra NICs
NicTO[] expandedNics = new NicTO[nics.length + _vmwareMgr.getRouterExtraPublicNics()];
int i = 0;
int deviceId = -1;
for(i = 0; i < nics.length; i++) {
expandedNics[i] = nics[i];
if(nics[i].getDeviceId() > deviceId)
deviceId = nics[i].getDeviceId();
}
deviceId++;
long networkId = publicNicProfile.getNetworkId();
NetworkVO network = _networkDao.findById(networkId);
for(; i < nics.length + _vmwareMgr.getRouterExtraPublicNics(); i++) {
NicTO nicTo = new NicTO();
nicTo.setDeviceId(deviceId++);
nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
nicTo.setType(publicNicProfile.getTrafficType());
nicTo.setIp("0.0.0.0");
nicTo.setNetmask("255.255.255.255");
try {
String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId);
nicTo.setMac(mac);
} catch (InsufficientAddressCapacityException e) {
throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
}
nicTo.setDns1(publicNicProfile.getDns1());
nicTo.setDns2(publicNicProfile.getDns2());
if (publicNicProfile.getGateway() != null) {
nicTo.setGateway(publicNicProfile.getGateway());
} else {
nicTo.setGateway(network.getGateway());
}
nicTo.setDefaultNic(false);
nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null);
nicTo.setNetworkRateMbps(networkRate);
expandedNics[i] = nicTo;
}
to.setNics(expandedNics);
}
StringBuffer sbMacSequence = new StringBuffer();
for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
sbMacSequence.append(nicTo.getMac()).append("|");
}
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
String bootArgs = to.getBootArgs();
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
}
// Determine the VM's OS description // Determine the VM's OS description
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
to.setOs(guestOS.getDisplayName()); to.setOs(guestOS.getDisplayName());
return to; return to;
} }
private NicTO[] sortNicsByDeviceId(NicTO[] nics) {
List<NicTO> listForSort = new ArrayList<NicTO>();
for (NicTO nic : nics) {
listForSort.add(nic);
}
Collections.sort(listForSort, new Comparator<NicTO>() {
@Override
public int compare(NicTO arg0, NicTO arg1) {
if (arg0.getDeviceId() < arg1.getDeviceId()) {
return -1;
} else if (arg0.getDeviceId() == arg1.getDeviceId()) {
return 0;
}
return 1;
}
});
return listForSort.toArray(new NicTO[0]);
}
@Override @DB @Override @DB
public long getCommandHostDelegation(long hostId, Command cmd) { public long getCommandHostDelegation(long hostId, Command cmd) {
boolean needDelegation = false; boolean needDelegation = false;

View File

@ -113,6 +113,7 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
int _additionalPortRangeStart; int _additionalPortRangeStart;
int _additionalPortRangeSize; int _additionalPortRangeSize;
int _maxHostsPerCluster; int _maxHostsPerCluster;
int _routerExtraPublicNics = 2;
String _cpuOverprovisioningFactor = "1"; String _cpuOverprovisioningFactor = "1";
String _reserveCpu = "false"; String _reserveCpu = "false";
@ -213,7 +214,6 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
_managemetPortGroupName = "Management Network"; _managemetPortGroupName = "Management Network";
} }
configDao.getValue(Config.VmwareServiceConsole.key());
_additionalPortRangeStart = NumbersUtil.parseInt(configDao.getValue(Config.VmwareAdditionalVncPortRangeStart.key()), 59000); _additionalPortRangeStart = NumbersUtil.parseInt(configDao.getValue(Config.VmwareAdditionalVncPortRangeStart.key()), 59000);
if(_additionalPortRangeStart > 65535) { if(_additionalPortRangeStart > 65535) {
s_logger.warn("Invalid port range start port (" + _additionalPortRangeStart + ") for additional VNC port allocation, reset it to default start port 59000"); s_logger.warn("Invalid port range start port (" + _additionalPortRangeStart + ") for additional VNC port allocation, reset it to default start port 59000");
@ -226,6 +226,8 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
_additionalPortRangeSize = Math.min(1000, 65535 - _additionalPortRangeStart); _additionalPortRangeSize = Math.min(1000, 65535 - _additionalPortRangeStart);
} }
_routerExtraPublicNics = NumbersUtil.parseInt(configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
_maxHostsPerCluster = NumbersUtil.parseInt(configDao.getValue(Config.VmwarePerClusterHostMax.key()), VmwareManager.MAX_HOSTS_PER_CLUSTER); _maxHostsPerCluster = NumbersUtil.parseInt(configDao.getValue(Config.VmwarePerClusterHostMax.key()), VmwareManager.MAX_HOSTS_PER_CLUSTER);
_cpuOverprovisioningFactor = configDao.getValue(Config.CPUOverprovisioningFactor.key()); _cpuOverprovisioningFactor = configDao.getValue(Config.CPUOverprovisioningFactor.key());
if(_cpuOverprovisioningFactor == null || _cpuOverprovisioningFactor.isEmpty()) if(_cpuOverprovisioningFactor == null || _cpuOverprovisioningFactor.isEmpty())
@ -242,6 +244,8 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
if(_reserveMem == null || _reserveMem.isEmpty()) if(_reserveMem == null || _reserveMem.isEmpty())
_reserveMem = "false"; _reserveMem = "false";
s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize)); s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize));
value = configDao.getValue("vmware.host.scan.interval"); value = configDao.getValue("vmware.host.scan.interval");
@ -829,4 +833,9 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
public int getMaxHostsPerCluster() { public int getMaxHostsPerCluster() {
return this._maxHostsPerCluster; return this._maxHostsPerCluster;
} }
@Override
public int getRouterExtraPublicNics() {
return this._routerExtraPublicNics;
}
} }

View File

@ -112,6 +112,7 @@ import com.cloud.host.HostVO;
import com.cloud.host.Status; import com.cloud.host.Status;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.vmware.manager.VmwareManager;
import com.cloud.network.IPAddressVO; import com.cloud.network.IPAddressVO;
import com.cloud.network.IpAddress; import com.cloud.network.IpAddress;
import com.cloud.network.LoadBalancerVO; import com.cloud.network.LoadBalancerVO;
@ -329,6 +330,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
private String _dnsBasicZoneUpdates = "all"; private String _dnsBasicZoneUpdates = "all";
private boolean _disable_rp_filter = false; private boolean _disable_rp_filter = false;
int _routerExtraPublicNics = 2;
private long mgmtSrvrId = MacAddress.getMacAddress().toLong(); private long mgmtSrvrId = MacAddress.getMacAddress().toLong();
ScheduledExecutorService _executor; ScheduledExecutorService _executor;
@ -592,6 +594,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
_mgmt_host = configs.get("host"); _mgmt_host = configs.get("host");
_routerRamSize = NumbersUtil.parseInt(configs.get("router.ram.size"), DEFAULT_ROUTER_VM_RAMSIZE); _routerRamSize = NumbersUtil.parseInt(configs.get("router.ram.size"), DEFAULT_ROUTER_VM_RAMSIZE);
_routerCpuMHz = NumbersUtil.parseInt(configs.get("router.cpu.mhz"), DEFAULT_ROUTER_CPU_MHZ); _routerCpuMHz = NumbersUtil.parseInt(configs.get("router.cpu.mhz"), DEFAULT_ROUTER_CPU_MHZ);
_routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
String value = configs.get("start.retry"); String value = configs.get("start.retry");
_retry = NumbersUtil.parseInt(value, 2); _retry = NumbersUtil.parseInt(value, 2);
@ -1354,7 +1359,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
} }
} }
String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key());
if (rpValue != null && rpValue.equalsIgnoreCase("true")) { if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
_disable_rp_filter = true; _disable_rp_filter = true;
@ -1484,6 +1488,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
buf.append(" useextdns=true"); buf.append(" useextdns=true");
} }
if(profile.getHypervisorType() == HypervisorType.VMware) {
buf.append(" extra_pubnics=" + _routerExtraPublicNics);
}
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
} }

View File

@ -7,4 +7,5 @@ package com.cloud.hypervisor.vmware.mo;
public interface CustomFieldConstants { public interface CustomFieldConstants {
public final static String CLOUD_UUID = "cloud.uuid"; public final static String CLOUD_UUID = "cloud.uuid";
public final static String CLOUD_GC = "cloud.gc"; public final static String CLOUD_GC = "cloud.gc";
public final static String CLOUD_NIC_MASK = "cloud.nic.mask";
} }