Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public interface VirtualNetworkApplianceService {
* the command specifying router's id
* @return router if successful
*/
VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork, boolean forced) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;

VirtualRouter upgradeRouter(UpgradeRouterCmd cmd);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public class RebootRouterCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
private Long id;

@Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force reboot the router (Router is force Stopped and then Started)", since = "4.16.0")
private Boolean forced;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -96,10 +99,14 @@ public Long getInstanceId() {
return getId();
}

public boolean isForced() {
return (forced != null) ? forced : false;
}

@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class,getId()));
VirtualRouter result = _routerService.rebootRouter(getId(), true);
VirtualRouter result = _routerService.rebootRouter(getId(), true, isForced());
if (result != null) {
DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
response.setResponseName("router");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public class RebootSystemVmCmd extends BaseAsyncCmd {
description = "The ID of the system virtual machine")
private Long id;

@Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force reboot the system VM (System VM is Stopped and then Started)", since = "4.16.0")
private Boolean forced;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -104,6 +107,10 @@ public Long getInstanceId() {
return getId();
}

public boolean isForced() {
return (forced != null) ? forced : false;
}

@Override
public void execute() {
CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public class RebootVMCmd extends BaseAsyncCmd implements UserCmd {
required=true, description="The ID of the virtual machine")
private Long id;

@Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force reboot the VM (VM is Stopped and then Started)", since = "4.16.0")
private Boolean forced;

@Parameter(name = ApiConstants.BOOT_INTO_SETUP, type = CommandType.BOOLEAN, required = false, description = "Boot into hardware setup menu or not", since = "4.15.0.0")
private Boolean bootIntoSetup;

Expand All @@ -64,6 +67,10 @@ public Long getId() {
return id;
}

public boolean isForced() {
return (forced != null) ? forced : false;
}

public Boolean getBootIntoSetup() {
return bootIntoSetup;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3430,7 +3430,6 @@ private void orchestrateReboot(final String vmUuid, final Map<VirtualMachineProf
final DeployDestination dest = new DeployDestination(dc, pod, cluster, host);

try {

final Commands cmds = new Commands(Command.OnError.Stop);
RebootCommand rebootCmd = new RebootCommand(vm.getInstanceName(), getExecuteInSequence(vm.getHypervisorType()));
VirtualMachineTO vmTo = getVmTO(vm.getId());
Expand All @@ -3448,7 +3447,10 @@ private void orchestrateReboot(final String vmUuid, final Map<VirtualMachineProf
}
return;
}
s_logger.info("Unable to reboot VM " + vm + " on " + dest.getHost() + " due to " + (rebootAnswer == null ? " no reboot answer" : rebootAnswer.getDetails()));

String errorMsg = "Unable to reboot VM " + vm + " on " + dest.getHost() + " due to " + (rebootAnswer == null ? "no reboot response" : rebootAnswer.getDetails());
s_logger.info(errorMsg);
throw new CloudRuntimeException(errorMsg);
} catch (final OperationTimedoutException e) {
s_logger.warn("Unable to send the reboot command to host " + dest.getHost() + " for the vm " + vm + " due to operation timeout", e);
throw new CloudRuntimeException("Failed to reboot the vm on host " + dest.getHost());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.GuestNetType;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
Expand Down Expand Up @@ -3177,35 +3176,15 @@ public String rebootVM(final Connect conn, final String vmName) throws LibvirtEx
String msg = null;
try {
dm = conn.domainLookupByName(vmName);
// Get XML Dump including the secure information such as VNC password
// By passing 1, or VIR_DOMAIN_XML_SECURE flag
// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainXMLFlags
String vmDef = dm.getXMLDesc(1);
final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
parser.parseDomainXML(vmDef);
for (final InterfaceDef nic : parser.getInterfaces()) {
if (nic.getNetType() == GuestNetType.BRIDGE && nic.getBrName().startsWith("cloudVirBr")) {
try {
final int vnetId = Integer.parseInt(nic.getBrName().replaceFirst("cloudVirBr", ""));
final String pifName = getPif(_guestBridgeName);
final String newBrName = "br" + pifName + "-" + vnetId;
vmDef = vmDef.replace("'" + nic.getBrName() + "'", "'" + newBrName + "'");
s_logger.debug("VM bridge name is changed from " + nic.getBrName() + " to " + newBrName);
} catch (final NumberFormatException e) {
continue;
}
}
}
s_logger.debug(vmDef);
msg = stopVM(conn, vmName, false);
msg = startVM(conn, vmName, vmDef);
// Perform ACPI based reboot
// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainReboot
// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainRebootFlagValues
// Send ACPI event to Reboot
dm.reboot(0x1);
return null;
} catch (final LibvirtException e) {
s_logger.warn("Failed to create vm", e);
msg = e.getMessage();
} catch (final InternalErrorException e) {
s_logger.warn("Failed to create vm", e);
msg = e.getMessage();
} finally {
try {
if (dm != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {

@Override
@ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true)
public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException,
public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork, final boolean forced) throws ConcurrentOperationException, ResourceUnavailableException,
InsufficientCapacityException {
final Account caller = CallContext.current().getCallingAccount();

Expand All @@ -529,7 +529,7 @@ public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNe
final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
s_logger.debug("Stopping and starting router " + router + " as a part of router reboot");

if (stop(router, false, user, caller) != null) {
if (stop(router, forced, user, caller) != null) {
return startRouter(routerId, reprogramNetwork);
} else {
throw new CloudRuntimeException("Failed to reboot router " + router);
Expand Down Expand Up @@ -1046,7 +1046,7 @@ protected void recoverRedundantNetwork(final DomainRouterVO masterRouter, final
}
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, backupRouter.getDataCenterId(), backupRouter.getPodIdToDeployIn(), title, title);
try {
rebootRouter(backupRouter.getId(), true);
rebootRouter(backupRouter.getId(), true, false);
} catch (final ConcurrentOperationException e) {
s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
} catch (final ResourceUnavailableException e) {
Expand Down
35 changes: 28 additions & 7 deletions server/src/main/java/com/cloud/server/ManagementServerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2439,7 +2439,6 @@ private ConsoleProxyVO startConsoleProxy(final long instanceId) {
}

private ConsoleProxyVO stopConsoleProxy(final VMInstanceVO systemVm, final boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {

_itMgr.advanceStop(systemVm.getUuid(), isForced);
return _consoleProxyDao.findById(systemVm.getId());
}
Expand All @@ -2449,6 +2448,11 @@ private ConsoleProxyVO rebootConsoleProxy(final long instanceId) {
return _consoleProxyDao.findById(instanceId);
}

private ConsoleProxyVO forceRebootConsoleProxy(final VMInstanceVO systemVm) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
_itMgr.advanceStop(systemVm.getUuid(), false);
return _consoleProxyMgr.startProxy(systemVm.getId(), true);
}

protected ConsoleProxyVO destroyConsoleProxy(final long instanceId) {
final ConsoleProxyVO proxy = _consoleProxyDao.findById(instanceId);

Expand Down Expand Up @@ -3338,6 +3342,11 @@ public SecondaryStorageVmVO rebootSecondaryStorageVm(final long instanceId) {
return _secStorageVmDao.findById(instanceId);
}

private SecondaryStorageVmVO forceRebootSecondaryStorageVm(final VMInstanceVO systemVm) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
_itMgr.advanceStop(systemVm.getUuid(), false);
return _secStorageVmMgr.startSecStorageVm(systemVm.getId());
}

protected SecondaryStorageVmVO destroySecondaryStorageVm(final long instanceId) {
final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(instanceId);
cleanupDownloadUrlsInZone(secStorageVm.getDataCenterId());
Expand Down Expand Up @@ -3507,12 +3516,24 @@ public VMInstanceVO rebootSystemVM(final RebootSystemVmCmd cmd) {
throw ex;
}

if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy Vm");
return rebootConsoleProxy(cmd.getId());
} else {
ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_REBOOT, "rebooting secondary storage Vm");
return rebootSecondaryStorageVm(cmd.getId());
try {
if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy Vm");
if (cmd.isForced()) {
return forceRebootConsoleProxy(systemVm);
}
return rebootConsoleProxy(cmd.getId());
} else {
ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_REBOOT, "rebooting secondary storage Vm");
if (cmd.isForced()) {
return forceRebootSecondaryStorageVm(systemVm);
}
return rebootSecondaryStorageVm(cmd.getId());
}
} catch (final ResourceUnavailableException e) {
throw new CloudRuntimeException("Unable to reboot " + systemVm, e);
} catch (final OperationTimedoutException e) {
throw new CloudRuntimeException("Operation timed out - Unable to reboot " + systemVm, e);
}
}

Expand Down
40 changes: 34 additions & 6 deletions server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ private boolean resetVMPasswordInternal(Long vmId, String password) throws Resou
return true;
}

if (rebootVirtualMachine(userId, vmId, false) == null) {
if (rebootVirtualMachine(userId, vmId, false, false) == null) {
s_logger.warn("Failed to reboot the vm " + vmInstance);
return false;
} else {
Expand Down Expand Up @@ -911,7 +911,7 @@ private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String pas
s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of SSH Key reset");
return true;
}
if (rebootVirtualMachine(userId, vmId, false) == null) {
if (rebootVirtualMachine(userId, vmId, false, false) == null) {
s_logger.warn("Failed to reboot the vm " + vmInstance);
return false;
} else {
Expand Down Expand Up @@ -948,7 +948,7 @@ public boolean stopVirtualMachine(long userId, long vmId) {
return status;
}

private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup) throws InsufficientCapacityException, ResourceUnavailableException {
private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup, boolean forced) throws InsufficientCapacityException, ResourceUnavailableException {
UserVmVO vm = _vmDao.findById(vmId);

if (s_logger.isTraceEnabled()) {
Expand All @@ -963,6 +963,15 @@ private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup)
if (vm.getState() == State.Running && vm.getHostId() != null) {
collectVmDiskStatistics(vm);
collectVmNetworkStatistics(vm);

if (forced) {
Host vmOnHost = _hostDao.findById(vm.getHostId());
if (vmOnHost == null || vmOnHost.getResourceState() != ResourceState.Enabled || vmOnHost.getStatus() != Status.Up ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sureshanaparti is this a new behaviour, did it use to throw exception/fail when host is not enabled or up without forced=true?

Copy link
Copy Markdown
Contributor Author

@sureshanaparti sureshanaparti Feb 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhtyd Start VM can fail (or) either pick another host when the VM's host is not Enabled / not Up. As the force reboot stops and starts the VM, there are chances that start VM would fail in that case, and so it's safe to not allow when force reboot when host is not Enabled / not Up.

throw new CloudRuntimeException("Unable to force reboot the VM as the host: " + vm.getHostId() + " is not in the right state");
}
return forceRebootVirtualMachine(vmId, vm.getHostId(), enterSetup);
}

DataCenterVO dc = _dcDao.findById(vm.getDataCenterId());
try {
if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) {
Expand All @@ -986,7 +995,7 @@ private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup)
throw new CloudRuntimeException("Concurrent operations on starting router. " + e);
} catch (Exception ex){
throw new CloudRuntimeException("Router start failed due to" + ex);
}finally {
} finally {
if (s_logger.isInfoEnabled()) {
s_logger.info(String.format("Rebooting vm %s%s.", vm.getInstanceName(), enterSetup? " entering hardware setup menu" : " as is"));
}
Expand All @@ -1007,6 +1016,24 @@ private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup)
}
}

private UserVm forceRebootVirtualMachine(long vmId, long hostId, boolean enterSetup) {
try {
if (stopVirtualMachine(vmId, false) != null) {
Map<VirtualMachineProfile.Param,Object> params = null;
if (enterSetup) {
params = new HashMap();
params.put(VirtualMachineProfile.Param.BootIntoSetup, Boolean.TRUE);
}
return startVirtualMachine(vmId, null, null, hostId, params, null).first();
}
} catch (ResourceUnavailableException e) {
throw new CloudRuntimeException("Unable to reboot the VM: " + vmId, e);
} catch (CloudException e) {
throw new CloudRuntimeException("Unable to reboot the VM: " + vmId, e);
}
return null;
}

@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "upgrading Vm")
/*
Expand Down Expand Up @@ -2887,7 +2914,7 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE
// Verify input parameters
UserVmVO vmInstance = _vmDao.findById(vmId);
if (vmInstance == null) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
}

_accountMgr.checkAccess(caller, null, true, vmInstance);
Expand All @@ -2909,7 +2936,8 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE
if (enterSetup != null && enterSetup && !HypervisorType.VMware.equals(vmInstance.getHypervisorType())) {
throw new InvalidParameterValueException("Booting into a hardware setup menu is not implemented on " + vmInstance.getHypervisorType());
}
UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId, enterSetup == null ? false : cmd.getBootIntoSetup());

UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId, enterSetup == null ? false : cmd.getBootIntoSetup(), cmd.isForced());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sureshanaparti does forced parameter cause it to perform a stop/start at orchestration level?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes @rhtyd

if (userVm != null ) {
// update the vmIdCountMap if the vm is in advanced shared network with out services
final List<NicVO> nics = _nicDao.listByVmId(vmId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public VirtualRouter startRouter(final long routerId, final boolean reprogramNet
* @see com.cloud.network.VirtualNetworkApplianceService#rebootRouter(long, boolean)
*/
@Override
public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException {
public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork, final boolean forced) throws ConcurrentOperationException, ResourceUnavailableException {
// TODO Auto-generated method stub
return null;
}
Expand Down
Loading