mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Summary: Fix bridge parsing when bridge names are subsets of others
Detail: There are several places in the code that do a "brctl show | grep bridgeName" or similar, which causes all sorts of problems when you have for example a cloudVirBr50 and a cloudVirBr5000. This patch attempts to stop relying on the output of brctl, instead favoring sysfs and /sys/devices/virtual/net. It cuts a lot of bash out altogether by using java File. It was tested in my devcloud-kvm against current 4.0, as well as by the customer reporting initial bug. BUG-ID: CLOUDSTACK-938 Fix-For: 4.0.1 Signed-off-by: Marcus Sorensen <marcus@betterservers.com>
This commit is contained in:
parent
98a289020f
commit
a65b584d18
@ -33,6 +33,7 @@ import org.libvirt.LibvirtException;
|
|||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class BridgeVifDriver extends VifDriverBase {
|
public class BridgeVifDriver extends VifDriverBase {
|
||||||
|
|
||||||
@ -206,15 +207,11 @@ public class BridgeVifDriver extends VifDriverBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBridgeExists(String bridgeName) {
|
private boolean isBridgeExists(String bridgeName) {
|
||||||
Script command = new Script("/bin/sh", _timeout);
|
File f = new File("/sys/devices/virtual/net/" + bridgeName);
|
||||||
command.add("-c");
|
if (f.exists()) {
|
||||||
command.add("brctl show|grep " + bridgeName);
|
|
||||||
final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
|
|
||||||
String result = command.execute(parser);
|
|
||||||
if (result != null || parser.getLine() == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -788,10 +788,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void getPifs() {
|
private void getPifs() {
|
||||||
/* gather all available bridges and find their pifs, so that we can match them against traffic labels later */
|
File dir = new File("/sys/devices/virtual/net");
|
||||||
String cmdout = Script.runSimpleBashScript("brctl show | tail -n +2 | grep -v \"^\\s\"|awk '{print $1}'|sed '{:q;N;s/\\n/%/g;t q}'");
|
File[] netdevs = dir.listFiles();
|
||||||
s_logger.debug("cmdout was " + cmdout);
|
List<String> bridges = new ArrayList<String>();
|
||||||
List<String> bridges = Arrays.asList(cmdout.split("%"));
|
for (int i = 0; i < netdevs.length; i++) {
|
||||||
|
File isbridge = new File(netdevs[i].getAbsolutePath() + "/bridge");
|
||||||
|
String netdevName = netdevs[i].getName();
|
||||||
|
s_logger.debug("looking in file " + netdevs[i].getAbsolutePath() + "/bridge");
|
||||||
|
if (isbridge.exists()) {
|
||||||
|
s_logger.debug("Found bridge " + netdevName);
|
||||||
|
bridges.add(netdevName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (String bridge : bridges) {
|
for (String bridge : bridges) {
|
||||||
s_logger.debug("looking for pif for bridge " + bridge);
|
s_logger.debug("looking for pif for bridge " + bridge);
|
||||||
String pif = getPif(bridge);
|
String pif = getPif(bridge);
|
||||||
@ -807,24 +816,53 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getPif(String bridge) {
|
private String getPif(String bridge) {
|
||||||
String pif = Script.runSimpleBashScript("brctl show | grep " + bridge + " | awk '{print $4}'");
|
String pif = matchPifFileInDirectory(bridge);
|
||||||
String vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + pif);
|
File vlanfile = new File("/proc/net/vlan" + pif);
|
||||||
|
|
||||||
if (vlan != null && !vlan.isEmpty()) {
|
if (vlanfile.isFile()) {
|
||||||
pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}");
|
pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/"
|
||||||
|
+ pif + " | awk {'print $2'}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return pif;
|
return pif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String matchPifFileInDirectory(String bridgeName){
|
||||||
|
File f = new File("/sys/devices/virtual/net/" + bridgeName + "/brif");
|
||||||
|
|
||||||
|
if (! f.isDirectory()){
|
||||||
|
s_logger.debug("failing to get physical interface from bridge"
|
||||||
|
+ bridgeName + ", does " + f.getAbsolutePath()
|
||||||
|
+ "exist?");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] interfaces = f.listFiles();
|
||||||
|
|
||||||
|
for (int i = 0; i < interfaces.length; i++) {
|
||||||
|
String fname = interfaces[i].getName();
|
||||||
|
s_logger.debug("matchPifFileInDirectory: file name '"+fname+"'");
|
||||||
|
if (fname.startsWith("eth") || fname.startsWith("bond")
|
||||||
|
|| fname.startsWith("vlan")) {
|
||||||
|
return fname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_logger.debug("failing to get physical interface from bridge"
|
||||||
|
+ bridgeName + ", did not find an eth*, bond*, or vlan* in "
|
||||||
|
+ f.getAbsolutePath());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean checkNetwork(String networkName) {
|
private boolean checkNetwork(String networkName) {
|
||||||
if (networkName == null) {
|
if (networkName == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = Script.runSimpleBashScript("brctl show | grep "
|
String name = matchPifFileInDirectory(networkName);
|
||||||
+ networkName + " | awk '{print $4}'");
|
|
||||||
if (name == null) {
|
if (name == null || name.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
@ -1381,20 +1419,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getVlanIdFromBridge(String brName) {
|
private String getVlanIdFromBridge(String brName) {
|
||||||
OutputInterpreter.OneLineParser vlanIdParser = new OutputInterpreter.OneLineParser();
|
String pif= matchPifFileInDirectory(brName);
|
||||||
final Script cmd = new Script("/bin/bash", s_logger);
|
String[] pifparts = pif.split("\\.");
|
||||||
cmd.add("-c");
|
|
||||||
cmd.add("vlanid=$(brctl show |grep " + brName
|
if(pifparts.length == 2) {
|
||||||
+ " |awk '{print $4}' | cut -s -d. -f 2);echo $vlanid");
|
return pifparts[1];
|
||||||
String result = cmd.execute(vlanIdParser);
|
|
||||||
if (result != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String vlanId = vlanIdParser.getLine();
|
|
||||||
if (vlanId.equalsIgnoreCase("")) {
|
|
||||||
return null;
|
|
||||||
} else {
|
} else {
|
||||||
return vlanId;
|
s_logger.debug("failed to get vlan id from bridge " + brName
|
||||||
|
+ "attached to physical interface" + pif);
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1632,7 +1665,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (IpAddressTO ip : ips) {
|
for (IpAddressTO ip : ips) {
|
||||||
String ipVlan = ip.getVlanId();
|
|
||||||
String nicName = "eth" + vlanToNicNum.get(ip.getVlanId());
|
String nicName = "eth" + vlanToNicNum.get(ip.getVlanId());
|
||||||
String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask()));
|
String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask()));
|
||||||
String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask());
|
String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user