diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 080075190ed..d99c9efa49e 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -3147,7 +3147,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra //1) allocate nic (if needed) Always allocate if it is a user vm if (nic == null || (vmProfile.getType() == VirtualMachine.Type.User)) { - int deviceId = _nicDao.countNics(vm.getId()); + int deviceId = _nicDao.getFreeDeviceId(vm.getId()); nic = allocateNic(requested, network, false, deviceId, vmProfile).first(); diff --git a/engine/schema/src/com/cloud/vm/dao/NicDao.java b/engine/schema/src/com/cloud/vm/dao/NicDao.java index a7ad01692cf..2c7895a5a55 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicDao.java +++ b/engine/schema/src/com/cloud/vm/dao/NicDao.java @@ -55,7 +55,7 @@ public interface NicDao extends GenericDao { String getIpAddress(long networkId, long instanceId); - int countNics(long instanceId); + int getFreeDeviceId(long instanceId); NicVO findByNetworkIdInstanceIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri); diff --git a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java index 027670b1164..f27088a4457 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java @@ -24,6 +24,7 @@ import javax.inject.Inject; import org.springframework.stereotype.Component; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; @@ -42,7 +43,7 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { private SearchBuilder AllFieldsSearch; private GenericSearchBuilder IpSearch; private SearchBuilder NonReleasedSearch; - private GenericSearchBuilder CountBy; + private GenericSearchBuilder deviceIdSearch; private GenericSearchBuilder CountByForStartingVms; @Inject @@ -79,11 +80,10 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { NonReleasedSearch.and("state", NonReleasedSearch.entity().getState(), Op.NOTIN); NonReleasedSearch.done(); - CountBy = createSearchBuilder(Integer.class); - CountBy.select(null, Func.COUNT, CountBy.entity().getId()); - CountBy.and("vmId", CountBy.entity().getInstanceId(), Op.EQ); - CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL); - CountBy.done(); + deviceIdSearch = createSearchBuilder(Integer.class); + deviceIdSearch.select(null, Func.DISTINCT, deviceIdSearch.entity().getDeviceId()); + deviceIdSearch.and("instance", deviceIdSearch.entity().getInstanceId(), Op.EQ); + deviceIdSearch.done(); CountByForStartingVms = createSearchBuilder(Integer.class); CountByForStartingVms.select(null, Func.COUNT, CountByForStartingVms.entity().getId()); @@ -220,11 +220,20 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { } @Override - public int countNics(long instanceId) { - SearchCriteria sc = CountBy.create(); - sc.setParameters("vmId", instanceId); - List results = customSearch(sc, null); - return results.get(0); + public int getFreeDeviceId(long instanceId) { + Filter searchFilter = new Filter(NicVO.class, "deviceId", true, null, null); + SearchCriteria sc = deviceIdSearch.create(); + sc.setParameters("instance", instanceId); + List deviceIds = customSearch(sc, searchFilter); + + int freeDeviceId = 0; + for (int deviceId : deviceIds) { + if (deviceId > freeDeviceId) + break; + freeDeviceId ++; + } + + return freeDeviceId; } @Override