CS-15407 [2.2.14 to 3.0.4 upgrade] After upgrade VLAN allocation doesn't happen properly for multiple physical networks

Reviewed-by: Alena

Changes:
- If a 2.2.14 setup uses guest vnet and has multiple network tags, we cannot upgrade this to 3.0.x since on upgrade we dont know how to assign the vnets to physical networks
- So we error out and provide instructions
- If an already upgraded 3.0.3 setup has this some guest networks using vnet but the assignment of vnet to physical network is wrong, upgrade to 3.04 will detect it and error out with further steps
This commit is contained in:
prachi 2012-07-06 00:02:42 -07:00
parent 86b7d7cd41
commit 63491fb893
3 changed files with 110 additions and 4 deletions

View File

@ -162,13 +162,64 @@ public class Upgrade2214to30 extends Upgrade30xBase implements DbUpgrade {
//check if there are multiple guest networks configured using network_tags
PreparedStatement pstmt2 = conn.prepareStatement("SELECT distinct tag FROM `cloud`.`network_tags` t JOIN `cloud`.`networks` n where t.network_id = n.id and n.data_center_id = ? and n.removed IS NULL");
PreparedStatement pstmt2 = conn.prepareStatement("SELECT distinct tag FROM `cloud`.`network_tags` t JOIN `cloud`.`networks` n ON t.network_id = n.id WHERE n.data_center_id = ? and n.removed IS NULL");
pstmt2.setLong(1, zoneId);
ResultSet rsTags = pstmt2.executeQuery();
if(rsTags.next()){
s_logger.debug("Network tags are not empty, might have to create more than one physical network...");
//make sure setup does not use guest vnets
if(vnet != null){
//check if any vnet is allocated and guest networks are using vnets.
PreparedStatement pstmt4 = conn.prepareStatement("SELECT v.* FROM `cloud`.`op_dc_vnet_alloc` v JOIN `cloud`.`networks` n ON CONCAT('vlan://' , v.vnet) = n.broadcast_uri WHERE v.taken IS NOT NULL AND v.data_center_id = ? AND n.removed IS NULL");
pstmt4.setLong(1, zoneId);
ResultSet rsVNet = pstmt4.executeQuery();
if(rsVNet.next()){
String message = "Cannot upgrade. Your setup will translate to multiple Physical Networks and is using guest Vnet. To upgrade, first do the following: \n" +
"1. Please rollback to your 2.2.x setup \n" +
"2. Please stop all VMs through CloudStack and wait for all networks to shutdown. [Networks shutdown will be determined by network.gc.interval and network.gc.wait seconds] \n" +
"3. Please ensure all networks are shutdown and all guest Vnet's are free." +
"4. Run upgrade. This will allocate all your guest vnet range to first physical network. \n" +
"5. Reconfigure the vnet ranges for each physical network as desired by using updatePhysicalNetwork API \n" +
"6. Start all your VMs";
s_logger.error(message);
throw new CloudRuntimeException("Cannot upgrade this setup since it uses guest vnet and will have multiple physical networks. Please check the logs for details on how to proceed");
}
rsVNet.close();
pstmt4.close();
//Clean up any vnets that have no live networks/nics
pstmt4 = conn.prepareStatement("SELECT v.id, v.vnet, v.reservation_id FROM `cloud`.`op_dc_vnet_alloc` v LEFT JOIN networks n ON CONCAT('vlan://' , v.vnet) = n.broadcast_uri WHERE v.taken IS NOT NULL AND v.data_center_id = ? AND n.broadcast_uri IS NULL AND n.removed IS NULL");
rsVNet = pstmt4.executeQuery();
while(rsVNet.next()){
Long vnet_id = rsVNet.getLong(1);
String vnetValue = rsVNet.getString(2);
String reservationId = rsVNet.getString(3);
//does this vnet have any nic associated?
PreparedStatement pstmt5 = conn.prepareStatement("SELECT id, instance_id FROM `cloud`.`nics` where broadcast_uri = ? and removed IS NULL");
String uri = "vlan://"+vnetValue;
pstmt5.setString(1, uri);
ResultSet rsNic = pstmt5.executeQuery();
Long nic_id = rsNic.getLong(1);
Long instance_id = rsNic.getLong(2);
if(rsNic.next()){
throw new CloudRuntimeException("Cannot upgrade. Please cleanup the guest vnet: "+ vnetValue +" , it is being used by nic_id: "+ nic_id +" , instance_id: " + instance_id );
}
//free this vnet
String freeVnet = "UPDATE `cloud`.`op_dc_vnet_alloc` SET account_id = NULL, taken = NULL, reservation_id = NULL WHERE id = ?";
pstmtUpdate = conn.prepareStatement(freeVnet);
pstmtUpdate.setLong(1, vnet_id);
pstmtUpdate.executeUpdate();
pstmtUpdate.close();
}
}
boolean isFirstPhysicalNtwk = true;
do{
s_logger.debug("Network tags are not empty, might have to create more than one physical network...");
//create one physical network per tag
String guestNetworkTag = rsTags.getString(1);
long physicalNetworkId = addPhysicalNetworkToZone(conn, zoneId, zoneName, networkType, (isFirstPhysicalNtwk) ? vnet : null, domainId);

View File

@ -148,7 +148,62 @@ public class Upgrade303to304 extends Upgrade30xBase implements DbUpgrade {
pstmt.close();
if(multiplePhysicalNetworks){
//check if guest vnet is wrongly configured by earlier upgrade. If yes error out
//check if any vnet is allocated and guest networks are using vnet But the physical network id does not match on the vnet and guest network.
PreparedStatement pstmt4 = conn.prepareStatement("SELECT v.id, v.vnet, v.reservation_id, v.physical_network_id as vpid, n.id, n.physical_network_id as npid FROM `cloud`.`op_dc_vnet_alloc` v JOIN `cloud`.`networks` n ON CONCAT('vlan://' , v.vnet) = n.broadcast_uri WHERE v.taken IS NOT NULL AND v.data_center_id = ? AND n.removed IS NULL AND v.physical_network_id != n.physical_network_id");
pstmt4.setLong(1, zoneId);
ResultSet rsVNet = pstmt4.executeQuery();
if(rsVNet.next()){
String vnet = rsVNet.getString(2);
String networkId = rsVNet.getString(5);
String vpid = rsVNet.getString(4);
String npid = rsVNet.getString(6);
s_logger.error("Guest Vnet assignment is set wrongly . Cannot upgrade until that is corrected. Example- Vnet: "+ vnet +" has physical network id: " + vpid +" ,but the guest network: " +networkId+" that uses it has physical network id: " +npid );
String message = "Cannot upgrade. Your setup has multiple Physical Networks and is using guest Vnet that is assigned wrongly. To upgrade, first correct the setup by doing the following: \n" +
"1. Please rollback \n" +
"2. Please stop all VMs through CloudStack and wait for all networks to shutdown. [Networks shutdown will be determined by network.gc.interval and network.gc.wait seconds] \n" +
"3. Please ensure all networks are shutdown and all guest Vnet's are free." +
"4. Run upgrade. This will allocate all your guest vnet range to first physical network. \n" +
"5. Reconfigure the vnet ranges for each physical network as desired by using updatePhysicalNetwork API \n" +
"6. Start all your VMs";
s_logger.error(message);
throw new CloudRuntimeException("Cannot upgrade this setup since Guest Vnet assignment to the multiple physical networks is incorrect. Please check the logs for details on how to proceed");
}
rsVNet.close();
pstmt4.close();
//Clean up any vnets that have no live networks/nics
pstmt4 = conn.prepareStatement("SELECT v.id, v.vnet, v.reservation_id FROM `cloud`.`op_dc_vnet_alloc` v LEFT JOIN networks n ON CONCAT('vlan://' , v.vnet) = n.broadcast_uri WHERE v.taken IS NOT NULL AND v.data_center_id = ? AND n.broadcast_uri IS NULL AND n.removed IS NULL");
rsVNet = pstmt4.executeQuery();
while(rsVNet.next()){
Long vnet_id = rsVNet.getLong(1);
String vnetValue = rsVNet.getString(2);
String reservationId = rsVNet.getString(3);
//does this vnet have any nic associated?
PreparedStatement pstmt5 = conn.prepareStatement("SELECT id, instance_id FROM `cloud`.`nics` where broadcast_uri = ? and removed IS NULL");
String uri = "vlan://"+vnetValue;
pstmt5.setString(1, uri);
ResultSet rsNic = pstmt5.executeQuery();
Long nic_id = rsNic.getLong(1);
Long instance_id = rsNic.getLong(2);
if(rsNic.next()){
throw new CloudRuntimeException("Cannot upgrade. Please cleanup the guest vnet: "+ vnetValue +" , it is being used by nic_id: "+ nic_id +" , instance_id: " + instance_id );
}
//free this vnet
String freeVnet = "UPDATE `cloud`.`op_dc_vnet_alloc` SET account_id = NULL, taken = NULL, reservation_id = NULL WHERE id = ?";
pstmtUpdate = conn.prepareStatement(freeVnet);
pstmtUpdate.setLong(1, vnet_id);
pstmtUpdate.executeUpdate();
pstmtUpdate.close();
}
rsVNet.close();
pstmt4.close();
//add tags to the physical networks if not present and clone offerings
pstmt = conn.prepareStatement("SELECT pn.id as pid , ptag.tag as tag FROM `cloud`.`physical_network` pn LEFT JOIN `cloud`.`physical_network_tags` ptag ON pn.id = ptag.physical_network_id where pn.data_center_id = ?");

View File

@ -91,7 +91,7 @@ public abstract class Upgrade30xBase implements DbUpgrade{
pstmtUpdate.setString(4, vnet);
pstmtUpdate.setString(5, broadcastDomainRange);
pstmtUpdate.setString(6, "Enabled");
zoneName = zoneName + "-pNtwk";
zoneName = zoneName + "-pNtwk" +physicalNetworkId;
pstmtUpdate.setString(7, zoneName);
s_logger.warn("Statement is " + pstmtUpdate.toString());
pstmtUpdate.executeUpdate();