use of com.xensource.xenapi.VLAN in project cloudstack by apache.
the class CitrixResourceBase method enableVlanNetwork.
/**
* enableVlanNetwork creates a Network object, Vlan object, and thereby a
* tagged PIF object in Xapi.
*
* In XenServer, VLAN is added by - Create a network, which is unique
* cluster wide. - Find the PIF that you want to create the VLAN on. -
* Create a VLAN using the network and the PIF. As a result of this
* operation, a tagged PIF object is also created.
*
* Here is a list of problems with clustered Xapi implementation that we are
* trying to circumvent. - There can be multiple Networks with the same
* name-label so searching using name-label is not unique. - There are no
* other ways to search for Networks other than listing all of them which is
* not efficient in our implementation because we can have over 4000 VLAN
* networks. - In a clustered situation, it's possible for both hosts to
* detect that the Network is missing and both creates it. This causes a lot
* of problems as one host may be using one Network and another may be using
* a different network for their VMs. This causes problems in migration
* because the VMs are logically attached to different networks in Xapi's
* database but in reality, they are attached to the same network.
*
* To work around these problems, we do the following.
*
* - When creating the VLAN network, we name it as VLAN-UUID of the Network
* it is created on-VLAN Tag. Because VLAN tags is unique with one
* particular network, this is a unique name-label to quickly retrieve the
* the VLAN network with when we need it again. - When we create the VLAN
* network, we add a timestamp and a random number as a tag into the
* network. Then instead of creating VLAN on that network, we actually
* retrieve the Network again and this time uses the VLAN network with
* lowest timestamp or lowest random number as the VLAN network. This allows
* VLAN creation to happen on multiple hosts concurrently but even if two
* VLAN networks were created with the same name, only one of them is used.
*
* One cavaet about this approach is that it relies on the timestamp to be
* relatively accurate among different hosts.
*
* @param conn
* Xapi Connection
* @param tag
* VLAN tag
* @param network
* network on this host to create the VLAN on.
* @return VLAN Network created.
* @throws XenAPIException
* @throws XmlRpcException
*/
protected Network enableVlanNetwork(final Connection conn, final long tag, final XsLocalNetwork network) throws XenAPIException, XmlRpcException {
Network vlanNetwork = null;
final String oldName = "VLAN" + Long.toString(tag);
final String newName = "VLAN-" + network.getNetworkRecord(conn).uuid + "-" + tag;
XsLocalNetwork vlanNic = getNetworkByName(conn, newName);
if (vlanNic == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Couldn't find vlan network with the new name so trying old name: " + oldName);
}
vlanNic = getNetworkByName(conn, oldName);
if (vlanNic != null) {
s_logger.info("Renaming VLAN with old name " + oldName + " to " + newName);
vlanNic.getNetwork().setNameLabel(conn, newName);
}
}
if (vlanNic == null) {
// Can't find it, then create it.
if (s_logger.isDebugEnabled()) {
s_logger.debug("Creating VLAN network for " + tag + " on host " + _host.getIp());
}
final Network.Record nwr = new Network.Record();
nwr.nameLabel = newName;
nwr.tags = new HashSet<String>();
nwr.tags.add(generateTimeStamp());
vlanNetwork = Network.create(conn, nwr);
vlanNic = getNetworkByName(conn, newName);
if (vlanNic == null) {
// capture happened.
throw new CloudRuntimeException("Could not find/create vlan network with name: " + newName);
}
}
final PIF nPif = network.getPif(conn);
final PIF.Record nPifr = network.getPifRecord(conn);
vlanNetwork = vlanNic.getNetwork();
if (vlanNic.getPif(conn) != null) {
return vlanNetwork;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Creating VLAN " + tag + " on host " + _host.getIp() + " on device " + nPifr.device);
}
final VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork);
if (vlan != null) {
final VLAN.Record vlanr = vlan.getRecord(conn);
if (vlanr != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("VLAN is created for " + tag + ". The uuid is " + vlanr.uuid);
}
}
}
return vlanNetwork;
}
use of com.xensource.xenapi.VLAN in project cloudstack by apache.
the class XenServer56Resource method disableVlanNetwork.
@Override
public void disableVlanNetwork(final Connection conn, final Network network) {
try {
final Network.Record networkr = network.getRecord(conn);
if (!networkr.nameLabel.startsWith("VLAN")) {
return;
}
final String bridge = networkr.bridge.trim();
for (final PIF pif : networkr.PIFs) {
final PIF.Record pifr = pif.getRecord(conn);
if (!pifr.host.getUuid(conn).equalsIgnoreCase(_host.getUuid())) {
continue;
}
final VLAN vlan = pifr.VLANMasterOf;
if (vlan != null) {
final String vlannum = pifr.VLAN.toString();
final String device = pifr.device.trim();
if (vlannum.equals("-1")) {
return;
}
try {
vlan.destroy(conn);
final Host host = Host.getByUuid(conn, _host.getUuid());
host.forgetDataSourceArchives(conn, "pif_" + bridge + "_tx");
host.forgetDataSourceArchives(conn, "pif_" + bridge + "_rx");
host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_tx");
host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_rx");
} catch (final XenAPIException e) {
s_logger.trace("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.getUuid() + " due to " + e.toString());
}
}
return;
}
} catch (final XenAPIException e) {
final String msg = "Unable to disable VLAN network due to " + e.toString();
s_logger.warn(msg, e);
} catch (final Exception e) {
final String msg = "Unable to disable VLAN network due to " + e.getMessage();
s_logger.warn(msg, e);
}
}
Aggregations