4343import javax .inject .Inject ;
4444import javax .naming .ConfigurationException ;
4545
46- import com .cloud .agent .api .Answer ;
47- import com .cloud .agent .api .Command ;
48- import com .cloud .agent .api .PatchSystemVmAnswer ;
49- import com .cloud .agent .api .PatchSystemVmCommand ;
50- import com .cloud .agent .api .routing .NetworkElementCommand ;
51- import com .cloud .agent .manager .Commands ;
52- import com .cloud .dc .DomainVlanMapVO ;
53- import com .cloud .dc .dao .DomainVlanMapDao ;
54- import com .cloud .exception .AgentUnavailableException ;
55- import com .cloud .network .Networks ;
56- import com .cloud .utils .db .UUIDManager ;
57- import com .cloud .utils .fsm .StateMachine2 ;
58- import com .cloud .vm .DomainRouterVO ;
59- import com .cloud .vm .NicVO ;
60- import com .cloud .vm .dao .DomainRouterDao ;
61- import com .cloud .vm .dao .NicDao ;
6246import org .apache .cloudstack .acl .ControlledEntity ;
6347import org .apache .cloudstack .acl .SecurityChecker ;
6448import org .apache .cloudstack .affinity .AffinityGroupProcessor ;
611595import org .apache .log4j .Logger ;
612596
613597import com .cloud .agent .AgentManager ;
598+ import com .cloud .agent .api .Answer ;
599+ import com .cloud .agent .api .Command ;
614600import com .cloud .agent .api .GetVncPortAnswer ;
615601import com .cloud .agent .api .GetVncPortCommand ;
602+ import com .cloud .agent .api .PatchSystemVmAnswer ;
603+ import com .cloud .agent .api .PatchSystemVmCommand ;
604+ import com .cloud .agent .api .routing .NetworkElementCommand ;
605+ import com .cloud .agent .manager .Commands ;
616606import com .cloud .agent .manager .allocator .HostAllocator ;
617607import com .cloud .alert .Alert ;
618608import com .cloud .alert .AlertManager ;
633623import com .cloud .dc .AccountVlanMapVO ;
634624import com .cloud .dc .ClusterVO ;
635625import com .cloud .dc .DataCenterVO ;
626+ import com .cloud .dc .DomainVlanMapVO ;
636627import com .cloud .dc .HostPodVO ;
637628import com .cloud .dc .Pod ;
638629import com .cloud .dc .PodVlanMapVO ;
642633import com .cloud .dc .dao .AccountVlanMapDao ;
643634import com .cloud .dc .dao .ClusterDao ;
644635import com .cloud .dc .dao .DataCenterDao ;
636+ import com .cloud .dc .dao .DomainVlanMapDao ;
645637import com .cloud .dc .dao .HostPodDao ;
646638import com .cloud .dc .dao .PodVlanMapDao ;
647639import com .cloud .dc .dao .VlanDao ;
656648import com .cloud .event .EventTypes ;
657649import com .cloud .event .EventVO ;
658650import com .cloud .event .dao .EventDao ;
651+ import com .cloud .exception .AgentUnavailableException ;
659652import com .cloud .exception .ConcurrentOperationException ;
660653import com .cloud .exception .InsufficientAddressCapacityException ;
661654import com .cloud .exception .InvalidParameterValueException ;
686679import com .cloud .network .IpAddressManagerImpl ;
687680import com .cloud .network .Network ;
688681import com .cloud .network .NetworkModel ;
682+ import com .cloud .network .Networks ;
689683import com .cloud .network .dao .IPAddressDao ;
690684import com .cloud .network .dao .IPAddressVO ;
691685import com .cloud .network .dao .LoadBalancerDao ;
760754import com .cloud .utils .db .Transaction ;
761755import com .cloud .utils .db .TransactionCallbackNoReturn ;
762756import com .cloud .utils .db .TransactionStatus ;
757+ import com .cloud .utils .db .UUIDManager ;
763758import com .cloud .utils .exception .CloudRuntimeException ;
759+ import com .cloud .utils .fsm .StateMachine2 ;
764760import com .cloud .utils .net .MacAddress ;
765761import com .cloud .utils .net .NetUtils ;
766762import com .cloud .utils .ssh .SSHKeysHelper ;
767763import com .cloud .vm .ConsoleProxyVO ;
768764import com .cloud .vm .DiskProfile ;
765+ import com .cloud .vm .DomainRouterVO ;
769766import com .cloud .vm .InstanceGroupVO ;
767+ import com .cloud .vm .NicVO ;
770768import com .cloud .vm .SecondaryStorageVmVO ;
771769import com .cloud .vm .UserVmDetailVO ;
772770import com .cloud .vm .UserVmManager ;
778776import com .cloud .vm .VirtualMachineProfile ;
779777import com .cloud .vm .VirtualMachineProfileImpl ;
780778import com .cloud .vm .dao .ConsoleProxyDao ;
779+ import com .cloud .vm .dao .DomainRouterDao ;
781780import com .cloud .vm .dao .InstanceGroupDao ;
781+ import com .cloud .vm .dao .NicDao ;
782782import com .cloud .vm .dao .SecondaryStorageVmDao ;
783783import com .cloud .vm .dao .UserVmDao ;
784784import com .cloud .vm .dao .UserVmDetailsDao ;
@@ -794,6 +794,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
794794 public static final ConfigKey <String > customCsIdentifier = new ConfigKey <String >("Advanced" , String .class , "custom.cs.identifier" , UUID .randomUUID ().toString ().split ("-" )[0 ].substring (4 ), "Custom identifier for the cloudstack installation" , true , ConfigKey .Scope .Global );
795795 private static final VirtualMachine .Type []systemVmTypes = { VirtualMachine .Type .SecondaryStorageVm , VirtualMachine .Type .ConsoleProxy };
796796
797+ private static final List <HypervisorType > LIVE_MIGRATION_SUPPORTING_HYPERVISORS = List .of (HypervisorType .Hyperv , HypervisorType .KVM ,
798+ HypervisorType .LXC , HypervisorType .Ovm , HypervisorType .Ovm3 , HypervisorType .Simulator , HypervisorType .VMware , HypervisorType .XenServer );
799+
797800 @ Inject
798801 public AccountManager _accountMgr ;
799802 @ Inject
@@ -807,7 +810,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
807810 @ Inject
808811 private ClusterDao _clusterDao ;
809812 @ Inject
810- private UserVmDetailsDao _UserVmDetailsDao ;
813+ protected UserVmDetailsDao _UserVmDetailsDao ;
811814 @ Inject
812815 private SecondaryStorageVmDao _secStorageVmDao ;
813816 @ Inject
@@ -823,7 +826,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
823826 @ Inject
824827 private HostDao _hostDao ;
825828 @ Inject
826- private HostDetailsDao _detailsDao ;
829+ protected HostDetailsDao _detailsDao ;
827830 @ Inject
828831 private UserDao _userDao ;
829832 @ Inject
@@ -1277,6 +1280,26 @@ public Pair<List<? extends Host>, Integer> searchForServers(final ListHostsCmd c
12771280 return new Pair <List <? extends Host >, Integer >(result .first (), result .second ());
12781281 }
12791282
1283+ protected Pair <Boolean , List <HostVO >> filterUefiHostsForMigration (List <HostVO > allHosts , List <HostVO > filteredHosts , VMInstanceVO vm ) {
1284+ UserVmDetailVO userVmDetailVO = _UserVmDetailsDao .findDetail (vm .getId (), ApiConstants .BootType .UEFI .toString ());
1285+ if (userVmDetailVO != null &&
1286+ (ApiConstants .BootMode .LEGACY .toString ().equalsIgnoreCase (userVmDetailVO .getValue ()) ||
1287+ ApiConstants .BootMode .SECURE .toString ().equalsIgnoreCase (userVmDetailVO .getValue ()))) {
1288+ s_logger .info (" Live Migration of UEFI enabled VM : " + vm .getInstanceName () + " is not supported" );
1289+ if (CollectionUtils .isEmpty (filteredHosts )) {
1290+ filteredHosts = new ArrayList <>(allHosts );
1291+ }
1292+ List <DetailVO > details = _detailsDao .findByName (Host .HOST_UEFI_ENABLE );
1293+ List <Long > uefiEnabledHosts = details .stream ().filter (x -> Boolean .TRUE .toString ().equalsIgnoreCase (x .getValue ())).map (DetailVO ::getHostId ).collect (Collectors .toList ());
1294+ if (CollectionUtils .isEmpty (uefiEnabledHosts )) {
1295+ return new Pair <>(false , null );
1296+ }
1297+ filteredHosts .removeIf (host -> !uefiEnabledHosts .contains (host .getId ()));
1298+ return new Pair <>(!filteredHosts .isEmpty (), filteredHosts );
1299+ }
1300+ return new Pair <>(true , filteredHosts );
1301+ }
1302+
12801303 @ Override
12811304 public Ternary <Pair <List <? extends Host >, Integer >, List <? extends Host >, Map <Host , Boolean >> listHostsForMigrationOfVM (final Long vmId , final Long startIndex , final Long pageSize ,
12821305 final String keyword ) {
@@ -1303,33 +1326,21 @@ public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Ho
13031326 throw ex ;
13041327 }
13051328
1306- UserVmDetailVO userVmDetailVO = _UserVmDetailsDao .findDetail (vm .getId (), ApiConstants .BootType .UEFI .toString ());
1307- if (userVmDetailVO != null ) {
1308- s_logger .info (" Live Migration of UEFI enabled VM : " + vm .getInstanceName () + " is not supported" );
1309- if ("legacy" .equalsIgnoreCase (userVmDetailVO .getValue ()) || "secure" .equalsIgnoreCase (userVmDetailVO .getValue ())) {
1310- // Return empty list.
1311- return new Ternary <Pair <List <? extends Host >, Integer >, List <? extends Host >, Map <Host , Boolean >>(new Pair <List <? extends Host >,
1312- Integer >(new ArrayList <HostVO >(), new Integer (0 )), new ArrayList <Host >(), new HashMap <Host , Boolean >());
1313- }
1314- }
1315-
13161329 if (_serviceOfferingDetailsDao .findDetail (vm .getServiceOfferingId (), GPU .Keys .pciDevice .toString ()) != null ) {
13171330 s_logger .info (" Live Migration of GPU enabled VM : " + vm .getInstanceName () + " is not supported" );
13181331 // Return empty list.
1319- return new Ternary <Pair < List <? extends Host >, Integer >, List <? extends Host >, Map < Host , Boolean >> (new Pair <List <? extends Host >, Integer >(new ArrayList <HostVO >(), new Integer (0 )),
1320- new ArrayList <Host >(), new HashMap <Host , Boolean >());
1332+ return new Ternary <> (new Pair <>(new ArrayList <HostVO >(), new Integer (0 )),
1333+ new ArrayList <>(), new HashMap <>());
13211334 }
13221335
1323- if (!vm .getHypervisorType ().equals (HypervisorType .XenServer ) && !vm .getHypervisorType ().equals (HypervisorType .VMware ) && !vm .getHypervisorType ().equals (HypervisorType .KVM )
1324- && !vm .getHypervisorType ().equals (HypervisorType .Ovm ) && !vm .getHypervisorType ().equals (HypervisorType .Hyperv ) && !vm .getHypervisorType ().equals (HypervisorType .LXC )
1325- && !vm .getHypervisorType ().equals (HypervisorType .Simulator ) && !vm .getHypervisorType ().equals (HypervisorType .Ovm3 )) {
1336+ if (!LIVE_MIGRATION_SUPPORTING_HYPERVISORS .contains (vm .getHypervisorType ())) {
13261337 if (s_logger .isDebugEnabled ()) {
13271338 s_logger .debug (vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM." );
13281339 }
13291340 throw new InvalidParameterValueException ("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only" );
13301341 }
13311342
1332- if (vm . getType (). equals ( VirtualMachine .Type .User ) && vm . getHypervisorType () .equals (HypervisorType . LXC )) {
1343+ if (VirtualMachine .Type .User . equals ( vm . getType ()) && HypervisorType . LXC .equals (vm . getHypervisorType () )) {
13331344 throw new InvalidParameterValueException ("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only" );
13341345 }
13351346
@@ -1376,21 +1387,21 @@ public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Ho
13761387 final Type hostType = srcHost .getType ();
13771388 Pair <List <HostVO >, Integer > allHostsPair = null ;
13781389 List <HostVO > allHosts = null ;
1379- List <HostVO > hostsForMigrationWithStorage = null ;
1380- final Map <Host , Boolean > requiresStorageMotion = new HashMap <Host , Boolean >();
1390+ List <HostVO > filteredHosts = null ;
1391+ final Map <Host , Boolean > requiresStorageMotion = new HashMap <>();
13811392 DataCenterDeployment plan = null ;
13821393 if (canMigrateWithStorage ) {
13831394 Long podId = !VirtualMachine .Type .User .equals (vm .getType ()) ? srcHost .getPodId () : null ;
13841395 allHostsPair = searchForServers (startIndex , pageSize , null , hostType , null , srcHost .getDataCenterId (), podId , null , null , keyword ,
13851396 null , null , srcHost .getHypervisorType (), null , srcHost .getId ());
13861397 allHosts = allHostsPair .first ();
1387- hostsForMigrationWithStorage = new ArrayList <>(allHosts );
1398+ filteredHosts = new ArrayList <>(allHosts );
13881399
13891400 for (final VolumeVO volume : volumes ) {
13901401 StoragePool storagePool = _poolDao .findById (volume .getPoolId ());
13911402 Long volClusterId = storagePool .getClusterId ();
13921403
1393- for (Iterator <HostVO > iterator = hostsForMigrationWithStorage .iterator (); iterator .hasNext ();) {
1404+ for (Iterator <HostVO > iterator = filteredHosts .iterator (); iterator .hasNext ();) {
13941405 final Host host = iterator .next ();
13951406 String hostVersion = host .getHypervisorVersion ();
13961407 if (HypervisorType .KVM .equals (host .getHypervisorType ()) && hostVersion == null ) {
@@ -1434,6 +1445,9 @@ public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Ho
14341445 }
14351446 }
14361447
1448+ if (CollectionUtils .isEmpty (filteredHosts )) {
1449+ return new Ternary <>(new Pair <>(allHosts , allHostsPair .second ()), new ArrayList <>(), new HashMap <>());
1450+ }
14371451 plan = new DataCenterDeployment (srcHost .getDataCenterId (), podId , null , null , null , null );
14381452 } else {
14391453 final Long cluster = srcHost .getClusterId ();
@@ -1446,8 +1460,14 @@ public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Ho
14461460 plan = new DataCenterDeployment (srcHost .getDataCenterId (), srcHost .getPodId (), srcHost .getClusterId (), null , null , null );
14471461 }
14481462
1449- final Pair <List <? extends Host >, Integer > otherHosts = new Pair <List <? extends Host >, Integer >(allHosts , allHostsPair .second ());
1450- List <Host > suitableHosts = new ArrayList <Host >();
1463+ final Pair <List <? extends Host >, Integer > otherHosts = new Pair <>(allHosts , allHostsPair .second ());
1464+ Pair <Boolean , List <HostVO >> uefiFilteredResult = filterUefiHostsForMigration (allHosts , filteredHosts , vm );
1465+ if (!uefiFilteredResult .first ()) {
1466+ return new Ternary <>(otherHosts , new ArrayList <>(), new HashMap <>());
1467+ }
1468+ filteredHosts = uefiFilteredResult .second ();
1469+
1470+ List <Host > suitableHosts = new ArrayList <>();
14511471 final ExcludeList excludes = new ExcludeList ();
14521472 excludes .addHost (srcHostId );
14531473
@@ -1470,8 +1490,8 @@ public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Ho
14701490 }
14711491
14721492 for (final HostAllocator allocator : hostAllocators ) {
1473- if (canMigrateWithStorage ) {
1474- suitableHosts = allocator .allocateTo (vmProfile , plan , Host .Type .Routing , excludes , hostsForMigrationWithStorage , HostAllocator .RETURN_UPTO_ALL , false );
1493+ if (CollectionUtils . isNotEmpty ( filteredHosts ) ) {
1494+ suitableHosts = allocator .allocateTo (vmProfile , plan , Host .Type .Routing , excludes , filteredHosts , HostAllocator .RETURN_UPTO_ALL , false );
14751495 } else {
14761496 suitableHosts = allocator .allocateTo (vmProfile , plan , Host .Type .Routing , excludes , HostAllocator .RETURN_UPTO_ALL , false );
14771497 }
@@ -1489,7 +1509,7 @@ public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Ho
14891509 }
14901510 }
14911511
1492- return new Ternary <Pair < List <? extends Host >, Integer >, List <? extends Host >, Map < Host , Boolean > >(otherHosts , suitableHosts , requiresStorageMotion );
1512+ return new Ternary <>(otherHosts , suitableHosts , requiresStorageMotion );
14931513 }
14941514
14951515 /**
0 commit comments