diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 9e2b62bff23..56232606035 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -3769,7 +3769,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements NodeInfo node = conn.nodeInfo(); utilization = utilization / node.cpus; - stats.setCPUUtilization(utilization * 100); + if(utilization > 0){ + stats.setCPUUtilization(utilization * 100); + } } /* get network stats */ diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/FindLogicalSwitchPortAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/FindLogicalSwitchPortAnswer.java new file mode 100644 index 00000000000..f54bd85882d --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/FindLogicalSwitchPortAnswer.java @@ -0,0 +1,36 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class FindLogicalSwitchPortAnswer extends Answer { + private String _logicalSwitchPortUuid; + + public FindLogicalSwitchPortAnswer(Command command, boolean success, + String details, String localSwitchPortUuid) { + super(command, success, details); + this._logicalSwitchPortUuid = localSwitchPortUuid; + } + + public String getLogicalSwitchPortUuid() { + return _logicalSwitchPortUuid; + } + + public FindLogicalSwitchPortAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/FindLogicalSwitchPortCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/FindLogicalSwitchPortCommand.java new file mode 100644 index 00000000000..cccce67182b --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/FindLogicalSwitchPortCommand.java @@ -0,0 +1,44 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class FindLogicalSwitchPortCommand extends Command { + private String _logicalSwitchUuid; + private String _logicalSwitchPortUuid; + + public FindLogicalSwitchPortCommand(String logicalSwitchUuid, String logicalSwitchPortUuid) { + this._logicalSwitchUuid = logicalSwitchUuid; + this._logicalSwitchPortUuid = logicalSwitchPortUuid; + } + + + public String getLogicalSwitchUuid() { + return _logicalSwitchUuid; + } + + + public String getLogicalSwitchPortUuid() { + return _logicalSwitchPortUuid; + } + + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/UpdateLogicalSwitchPortAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/UpdateLogicalSwitchPortAnswer.java new file mode 100644 index 00000000000..3b7fbf7f2ae --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/UpdateLogicalSwitchPortAnswer.java @@ -0,0 +1,36 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class UpdateLogicalSwitchPortAnswer extends Answer { + private String _logicalSwitchPortUuid; + + public UpdateLogicalSwitchPortAnswer(Command command, boolean success, + String details, String localSwitchPortUuid) { + super(command, success, details); + this._logicalSwitchPortUuid = localSwitchPortUuid; + } + + public String getLogicalSwitchPortUuid() { + return _logicalSwitchPortUuid; + } + + public UpdateLogicalSwitchPortAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/UpdateLogicalSwitchPortCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/UpdateLogicalSwitchPortCommand.java new file mode 100644 index 00000000000..83ae23146b5 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/UpdateLogicalSwitchPortCommand.java @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class UpdateLogicalSwitchPortCommand extends Command { + private String _logicalSwitchUuid; + private String _logicalSwitchPortUuid; + private String _attachmentUuid; + private String _ownerName; + private String _nicName; + + public UpdateLogicalSwitchPortCommand(String logicalSwitchPortUuid, String logicalSwitchUuid, String attachmentUuid, String ownerName, String nicName) { + this._logicalSwitchUuid = logicalSwitchUuid; + this._logicalSwitchPortUuid = logicalSwitchPortUuid; + this._attachmentUuid = attachmentUuid; + this._ownerName = ownerName; + this._nicName = nicName; + } + + + public String getLogicalSwitchUuid() { + return _logicalSwitchUuid; + } + + + public String getLogicalSwitchPortUuid() { + return _logicalSwitchPortUuid; + } + + + public String getAttachmentUuid() { + return _attachmentUuid; + } + + + public String getOwnerName() { + return _ownerName; + } + + + public String getNicName() { + return _nicName; + } + + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java index bff69aa235b..1fcccdb1ee3 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java @@ -51,8 +51,12 @@ import com.cloud.agent.api.CreateLogicalSwitchPortAnswer; import com.cloud.agent.api.CreateLogicalSwitchPortCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; import com.cloud.agent.api.DeleteLogicalSwitchPortCommand; +import com.cloud.agent.api.FindLogicalSwitchPortAnswer; +import com.cloud.agent.api.FindLogicalSwitchPortCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; +import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; +import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; import com.cloud.api.commands.AddNiciraNvpDeviceCmd; import com.cloud.api.commands.DeleteNiciraNvpDeviceCmd; import com.cloud.api.commands.ListNiciraNvpDeviceNetworksCmd; @@ -198,6 +202,26 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide } NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpNicMappingVO existingNicMap = _niciraNvpNicMappingDao.findByNicUuid(nicVO.getUuid()); + if (existingNicMap != null) { + FindLogicalSwitchPortCommand findCmd = new FindLogicalSwitchPortCommand(existingNicMap.getLogicalSwitchUuid(), + existingNicMap.getLogicalSwitchPortUuid()); + FindLogicalSwitchPortAnswer answer = (FindLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), findCmd); + + if (answer.getResult()) { + s_logger.warn("Existing Logical Switchport found for nic " + nic.getName() + " with uuid " + existingNicMap.getLogicalSwitchPortUuid()); + UpdateLogicalSwitchPortCommand cmd = new UpdateLogicalSwitchPortCommand(existingNicMap.getLogicalSwitchPortUuid(), + network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(), + context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName()); + _agentMgr.easySend(niciraNvpHost.getId(), cmd); + return true; + } + else { + s_logger.error("Stale entry found for nic " + nic.getName() + " with logical switchport uuid " + existingNicMap.getLogicalSwitchPortUuid()); + _niciraNvpNicMappingDao.remove(existingNicMap.getId()); + } + } CreateLogicalSwitchPortCommand cmd = new CreateLogicalSwitchPortCommand(network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(), context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName()); @@ -244,7 +268,7 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide s_logger.error("No mapping for nic " + nic.getName()); return false; } - + DeleteLogicalSwitchPortCommand cmd = new DeleteLogicalSwitchPortCommand(nicMap.getLogicalSwitchUuid(), nicMap.getLogicalSwitchPortUuid()); DeleteLogicalSwitchPortAnswer answer = (DeleteLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index 264b24a9e0e..2c002abdbff 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -195,6 +195,22 @@ public class NiciraNvpApi { return ccs; } + public NiciraNvpList findLogicalSwitchPortsByUuid(String logicalSwitchUuid, String logicalSwitchPortUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lswitch/" + logicalSwitchUuid + "/lport"; + Map params = new HashMap(); + params.put("uuid", logicalSwitchPortUuid); + params.put("fields", "uuid"); + + NiciraNvpList lspl = executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + + if (lspl == null ) { + throw new NiciraNvpApiException("Unexpected response from API"); + } + + return lspl; + } + + private void executeUpdateObject(T newObject, String uri, Map parameters) throws NiciraNvpApiException { String url; try { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java index f0f1a0c4786..31cac6f000c 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java @@ -35,6 +35,8 @@ import com.cloud.agent.api.DeleteLogicalSwitchAnswer; import com.cloud.agent.api.DeleteLogicalSwitchCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; import com.cloud.agent.api.DeleteLogicalSwitchPortCommand; +import com.cloud.agent.api.FindLogicalSwitchPortAnswer; +import com.cloud.agent.api.FindLogicalSwitchPortCommand; import com.cloud.agent.api.MaintainAnswer; import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.PingCommand; @@ -42,6 +44,8 @@ import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; +import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; +import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.network.nicira.ControlClusterStatus; @@ -49,6 +53,7 @@ import com.cloud.network.nicira.LogicalSwitch; import com.cloud.network.nicira.LogicalSwitchPort; import com.cloud.network.nicira.NiciraNvpApi; import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.nicira.NiciraNvpList; import com.cloud.network.nicira.NiciraNvpTag; import com.cloud.network.nicira.TransportZoneBinding; import com.cloud.network.nicira.VifAttachment; @@ -186,6 +191,12 @@ public class NiciraNvpResource implements ServerResource { else if (cmd instanceof DeleteLogicalSwitchPortCommand) { return executeRequest((DeleteLogicalSwitchPortCommand) cmd, numRetries); } + else if (cmd instanceof UpdateLogicalSwitchPortCommand) { + return executeRequest((UpdateLogicalSwitchPortCommand) cmd, numRetries); + } + else if (cmd instanceof FindLogicalSwitchPortCommand) { + return executeRequest((FindLogicalSwitchPortCommand) cmd, numRetries); + } s_logger.debug("Received unsupported command " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); } @@ -284,6 +295,51 @@ public class NiciraNvpResource implements ServerResource { } } + private Answer executeRequest(UpdateLogicalSwitchPortCommand cmd, int numRetries) { + String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); + String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid(); + String attachmentUuid = cmd.getAttachmentUuid(); + + try { + // Tags set to scope cs_account and account name + List tags = new ArrayList(); + tags.add(new NiciraNvpTag("cs_account",cmd.getOwnerName())); + + _niciraNvpApi.modifyLogicalSwitchPortAttachment(logicalSwitchUuid, logicalSwitchPortUuid, new VifAttachment(attachmentUuid)); + return new UpdateLogicalSwitchPortAnswer(cmd, true, "Attachment for " + logicalSwitchPortUuid + " updated", logicalSwitchPortUuid); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new UpdateLogicalSwitchPortAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(FindLogicalSwitchPortCommand cmd, int numRetries) { + String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); + String logicalSwitchPortUuid = cmd.getLogicalSwitchPortUuid(); + + try { + NiciraNvpList ports = _niciraNvpApi.findLogicalSwitchPortsByUuid(logicalSwitchUuid, logicalSwitchPortUuid); + if (ports.getResult_count() == 0) { + return new FindLogicalSwitchPortAnswer(cmd, false, "Logical switchport " + logicalSwitchPortUuid + " not found", null); + } + else { + return new FindLogicalSwitchPortAnswer(cmd, true, "Logical switchport " + logicalSwitchPortUuid + " found", logicalSwitchPortUuid); + } + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new FindLogicalSwitchPortAnswer(cmd, e); + } + } + } + private Answer executeRequest(ReadyCommand cmd) { return new ReadyAnswer(cmd); }