mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-16 02:22:52 +01:00
more changes
This commit is contained in:
parent
49143dbe4a
commit
c443867f28
@ -137,7 +137,7 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateCommand;
|
|||||||
import com.cloud.agent.api.storage.DestroyCommand;
|
import com.cloud.agent.api.storage.DestroyCommand;
|
||||||
import com.cloud.agent.api.storage.DownloadAnswer;
|
import com.cloud.agent.api.storage.DownloadAnswer;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||||
import com.cloud.agent.api.to.StoragePoolTO;
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
import com.cloud.agent.api.to.VolumeTO;
|
import com.cloud.agent.api.to.VolumeTO;
|
||||||
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType;
|
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType;
|
||||||
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat;
|
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat;
|
||||||
@ -1173,7 +1173,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Answer execute(CreateCommand cmd) {
|
protected Answer execute(CreateCommand cmd) {
|
||||||
StoragePoolTO pool = cmd.getPool();
|
StorageFilerTO pool = cmd.getPool();
|
||||||
DiskProfile dskch = cmd.getDiskCharacteristics();
|
DiskProfile dskch = cmd.getDiskCharacteristics();
|
||||||
StorageVol tmplVol = null;
|
StorageVol tmplVol = null;
|
||||||
StoragePool primaryPool = null;
|
StoragePool primaryPool = null;
|
||||||
|
|||||||
@ -18,19 +18,16 @@
|
|||||||
package com.cloud.agent.api.storage;
|
package com.cloud.agent.api.storage;
|
||||||
|
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
import com.cloud.agent.api.to.StoragePoolTO;
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
import com.cloud.storage.StoragePoolVO;
|
import com.cloud.storage.StoragePool;
|
||||||
import com.cloud.storage.VolumeVO;
|
|
||||||
import com.cloud.vm.DiskProfile;
|
import com.cloud.vm.DiskProfile;
|
||||||
import com.cloud.vm.VMInstanceVO;
|
|
||||||
|
|
||||||
public class CreateCommand extends Command {
|
public class CreateCommand extends Command {
|
||||||
private long volId;
|
private long volId;
|
||||||
private StoragePoolTO pool;
|
private StorageFilerTO pool;
|
||||||
private DiskProfile diskCharacteristics;
|
private DiskProfile diskCharacteristics;
|
||||||
private String templateUrl;
|
private String templateUrl;
|
||||||
private long size;
|
private long size;
|
||||||
private String instanceName;
|
|
||||||
|
|
||||||
protected CreateCommand() {
|
protected CreateCommand() {
|
||||||
super();
|
super();
|
||||||
@ -45,8 +42,8 @@ public class CreateCommand extends Command {
|
|||||||
* @param templateUrl
|
* @param templateUrl
|
||||||
* @param pool
|
* @param pool
|
||||||
*/
|
*/
|
||||||
public CreateCommand(VolumeVO vol, VMInstanceVO vm, DiskProfile diskCharacteristics, String templateUrl, StoragePoolVO pool) {
|
public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool) {
|
||||||
this(vol, vm, diskCharacteristics, pool, 0);
|
this(diskCharacteristics, pool, 0);
|
||||||
this.templateUrl = templateUrl;
|
this.templateUrl = templateUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,13 +55,20 @@ public class CreateCommand extends Command {
|
|||||||
* @param diskCharacteristics
|
* @param diskCharacteristics
|
||||||
* @param pool
|
* @param pool
|
||||||
*/
|
*/
|
||||||
public CreateCommand(VolumeVO vol, VMInstanceVO vm, DiskProfile diskCharacteristics, StoragePoolVO pool, long size) {
|
public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool, long size) {
|
||||||
this.volId = vol.getId();
|
this.volId = diskCharacteristics.getVolumeId();
|
||||||
this.diskCharacteristics = diskCharacteristics;
|
this.diskCharacteristics = diskCharacteristics;
|
||||||
this.pool = new StoragePoolTO(pool);
|
this.pool = pool;
|
||||||
this.templateUrl = null;
|
this.templateUrl = null;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
//this.instanceName = vm.getInstanceName();
|
}
|
||||||
|
|
||||||
|
public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool) {
|
||||||
|
this(diskCharacteristics, templateUrl, new StorageFilerTO(pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool, long size) {
|
||||||
|
this(diskCharacteristics, new StorageFilerTO(pool), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,7 +80,7 @@ public class CreateCommand extends Command {
|
|||||||
return templateUrl;
|
return templateUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StoragePoolTO getPool() {
|
public StorageFilerTO getPool() {
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +96,8 @@ public class CreateCommand extends Command {
|
|||||||
return this.size;
|
return this.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public String getInstanceName() {
|
public String getInstanceName() {
|
||||||
return instanceName;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,11 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.cloud.agent.api.to;
|
package com.cloud.agent.api.to;
|
||||||
|
|
||||||
import com.cloud.storage.StoragePoolVO;
|
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
|
import com.cloud.storage.StoragePool;
|
||||||
|
|
||||||
|
public class StorageFilerTO {
|
||||||
public class StoragePoolTO {
|
|
||||||
long id;
|
long id;
|
||||||
String uuid;
|
String uuid;
|
||||||
String host;
|
String host;
|
||||||
@ -29,7 +28,7 @@ public class StoragePoolTO {
|
|||||||
int port;
|
int port;
|
||||||
StoragePoolType type;
|
StoragePoolType type;
|
||||||
|
|
||||||
public StoragePoolTO(StoragePoolVO pool) {
|
public StorageFilerTO(StoragePool pool) {
|
||||||
this.id = pool.getId();
|
this.id = pool.getId();
|
||||||
this.host = pool.getHostAddress();
|
this.host = pool.getHostAddress();
|
||||||
this.port = pool.getPort();
|
this.port = pool.getPort();
|
||||||
@ -62,7 +61,7 @@ public class StoragePoolTO {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StoragePoolTO() {
|
protected StorageFilerTO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -20,18 +20,39 @@ package com.cloud.exception;
|
|||||||
import com.cloud.utils.SerialVersionUID;
|
import com.cloud.utils.SerialVersionUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This exception is thrown when the storage device can not be reached.
|
* This exception is thrown when storage for a VM is unavailable.
|
||||||
|
* If the cause is due to storage pool unavailable, calling
|
||||||
|
* getOffendingObject() will return the object that we have
|
||||||
|
* problem with.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class StorageUnavailableException extends AgentUnavailableException {
|
public class StorageUnavailableException extends Exception {
|
||||||
|
Object _obj;
|
||||||
|
|
||||||
private static final long serialVersionUID = SerialVersionUID.StorageUnavailableException;
|
private static final long serialVersionUID = SerialVersionUID.StorageUnavailableException;
|
||||||
|
|
||||||
public StorageUnavailableException(long hostId) {
|
public StorageUnavailableException(String msg) {
|
||||||
super(hostId);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StorageUnavailableException(String msg) {
|
public StorageUnavailableException(String msg, Throwable cause) {
|
||||||
super(msg, -1);
|
super(msg, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageUnavailableException(String msg, Object cause) {
|
||||||
|
super(msg);
|
||||||
|
_obj = cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageUnavailableException(String msg, Object obj, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
_obj = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return object that caused this problem. It can either be a StoragePool or volume.
|
||||||
|
*/
|
||||||
|
public Object getOffendingObject() {
|
||||||
|
return _obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,10 +23,10 @@ public interface NetworkConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum State implements FiniteState<State, Event> {
|
enum State implements FiniteState<State, Event> {
|
||||||
Allocated, // Indicates the network configuration is in allocated but not setup.
|
Allocated("Indicates the network configuration is in allocated but not setup"),
|
||||||
Setup, // Indicates the network configuration is setup.
|
Setup("Indicates the network configuration is setup"),
|
||||||
Implemented, // Indicates the network configuration is in use.
|
Implemented("Indicates the network configuration is in use"),
|
||||||
Destroying;
|
Destroying("Indicates the network configuration is being destroyed");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StateMachine<State, Event> getStateMachine() {
|
public StateMachine<State, Event> getStateMachine() {
|
||||||
@ -48,7 +48,23 @@ public interface NetworkConfiguration {
|
|||||||
return s_fsm.getPossibleEvents(this);
|
return s_fsm.getPossibleEvents(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _description;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
|
||||||
|
private State(String description) {
|
||||||
|
_description = description;
|
||||||
|
}
|
||||||
|
|
||||||
private static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
|
private static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
|
||||||
|
static {
|
||||||
|
s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implemented);
|
||||||
|
s_fsm.addTransition(State.Implemented, Event.DestroyNetwork, State.Destroying);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -26,11 +26,13 @@ public interface Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum State implements FiniteState<State, Event> {
|
enum State implements FiniteState<State, Event> {
|
||||||
Allocated, // Resource is allocated
|
Allocated("Resource is allocated but not reserved"),
|
||||||
Reserving, // Resource is being reserved right now.
|
Reserving("Resource is being reserved right now"),
|
||||||
Reserved, // Resource is reserved
|
Reserved("Resource has been reserved."),
|
||||||
Releasing, // Resource is being released.
|
Releasing("Resource is being released"),
|
||||||
Ready; // Resource is ready which means it does not need to go through reservation.
|
Ready("Resource is ready which means it doesn't need to go through resservation");
|
||||||
|
|
||||||
|
String _description;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StateMachine<State, Event> getStateMachine() {
|
public StateMachine<State, Event> getStateMachine() {
|
||||||
@ -54,12 +56,24 @@ public interface Resource {
|
|||||||
return s_fsm.getPossibleEvents(this);
|
return s_fsm.getPossibleEvents(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private State(String description) {
|
||||||
|
_description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
|
||||||
final static private StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
|
final static private StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
|
||||||
static {
|
static {
|
||||||
s_fsm.addTransition(State.Allocated, Event.ReservationRequested, State.Reserving);
|
s_fsm.addTransition(State.Allocated, Event.ReservationRequested, State.Reserving);
|
||||||
s_fsm.addTransition(State.Reserving, Event.CancelRequested, State.Allocated);
|
s_fsm.addTransition(State.Reserving, Event.CancelRequested, State.Allocated);
|
||||||
s_fsm.addTransition(State.Reserving, Event.OperationCompleted, State.Reserved);
|
s_fsm.addTransition(State.Reserving, Event.OperationCompleted, State.Reserved);
|
||||||
s_fsm.addTransition(State.Reserving, Event.OperationFailed, State.Allocated);
|
s_fsm.addTransition(State.Reserving, Event.OperationFailed, State.Allocated);
|
||||||
|
s_fsm.addTransition(State.Reserved, Event.ReleaseRequested, State.Releasing);
|
||||||
|
s_fsm.addTransition(State.Releasing, Event.OperationCompleted, State.Allocated);
|
||||||
|
s_fsm.addTransition(State.Releasing, Event.OperationFailed, State.Reserved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
api/src/com/cloud/storage/StorageGuru.java
Normal file
30
api/src/com/cloud/storage/StorageGuru.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under the GNU General Public License v3 or later.
|
||||||
|
*
|
||||||
|
* It is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.cloud.storage;
|
||||||
|
|
||||||
|
import com.cloud.utils.component.Adapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StorageGuru understands about how to implement different
|
||||||
|
* types of storage pools.
|
||||||
|
*/
|
||||||
|
public interface StorageGuru extends Adapter {
|
||||||
|
void createVolume();
|
||||||
|
void prepareVolume();
|
||||||
|
void destroyVolume();
|
||||||
|
}
|
||||||
@ -101,4 +101,8 @@ public interface StoragePool {
|
|||||||
* @return the storage pool status
|
* @return the storage pool status
|
||||||
*/
|
*/
|
||||||
Status getStatus();
|
Status getStatus();
|
||||||
|
|
||||||
|
int getPort();
|
||||||
|
|
||||||
|
Long getPodId();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,10 +18,14 @@
|
|||||||
package com.cloud.storage;
|
package com.cloud.storage;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.cloud.domain.PartOf;
|
import com.cloud.domain.PartOf;
|
||||||
import com.cloud.template.BasedOn;
|
import com.cloud.template.BasedOn;
|
||||||
import com.cloud.user.OwnedBy;
|
import com.cloud.user.OwnedBy;
|
||||||
|
import com.cloud.utils.fsm.FiniteState;
|
||||||
|
import com.cloud.utils.fsm.StateMachine;
|
||||||
|
|
||||||
|
|
||||||
public interface Volume extends PartOf, OwnedBy, BasedOn {
|
public interface Volume extends PartOf, OwnedBy, BasedOn {
|
||||||
@ -29,14 +33,70 @@ public interface Volume extends PartOf, OwnedBy, BasedOn {
|
|||||||
|
|
||||||
enum MirrorState {NOT_MIRRORED, ACTIVE, DEFUNCT};
|
enum MirrorState {NOT_MIRRORED, ACTIVE, DEFUNCT};
|
||||||
|
|
||||||
enum State {
|
enum State implements FiniteState<State, Event> {
|
||||||
Allocated,
|
Allocated("The volume is allocated but has not been created yet."),
|
||||||
Creating,
|
Creating("The volume is being created. getPoolId() should reflect the pool where it is being created."),
|
||||||
Created,
|
Ready("The volume is ready to be used."),
|
||||||
Corrupted,
|
Destroy("The volume is set to be desctroyed but can be recovered."),
|
||||||
ToBeDestroyed,
|
Expunging("The volume is being destroyed. There's no way to recover."),
|
||||||
Expunging,
|
Destroyed("The volume is destroyed. Should be removed.");
|
||||||
Destroyed
|
|
||||||
|
String _description;
|
||||||
|
|
||||||
|
private State(String description) {
|
||||||
|
_description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StateMachine<State, Event> getStateMachine() {
|
||||||
|
return s_fsm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getNextState(Event event) {
|
||||||
|
return s_fsm.getNextState(this, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<State> getFromStates(Event event) {
|
||||||
|
return s_fsm.getFromStates(this, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Event> getPossibleEvents() {
|
||||||
|
return s_fsm.getPossibleEvents(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
|
||||||
|
static {
|
||||||
|
s_fsm.addTransition(Allocated, Event.Create, Creating);
|
||||||
|
s_fsm.addTransition(Allocated, Event.Destroy, Destroyed);
|
||||||
|
s_fsm.addTransition(Creating, Event.OperationRetry, Creating);
|
||||||
|
s_fsm.addTransition(Creating, Event.OperationFailed, Allocated);
|
||||||
|
s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready);
|
||||||
|
s_fsm.addTransition(Creating, Event.Destroy, Expunging);
|
||||||
|
s_fsm.addTransition(Ready, Event.Destroy, Destroy);
|
||||||
|
s_fsm.addTransition(Destroy, Event.Expunge, Expunging);
|
||||||
|
s_fsm.addTransition(Destroy, Event.Recover, Ready);
|
||||||
|
s_fsm.addTransition(Expunging, Event.OperationSucceeded, Destroyed);
|
||||||
|
s_fsm.addTransition(Expunging, Event.OperationFailed, Destroy);
|
||||||
|
s_fsm.addTransition(Allocated, Event.Destroy, Destroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Event {
|
||||||
|
Create,
|
||||||
|
OperationFailed,
|
||||||
|
OperationSucceeded,
|
||||||
|
OperationRetry,
|
||||||
|
Destroy,
|
||||||
|
Recover,
|
||||||
|
Expunge;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SourceType {
|
enum SourceType {
|
||||||
|
|||||||
@ -26,21 +26,28 @@ import com.cloud.utils.fsm.StateMachine;
|
|||||||
import com.cloud.vm.VirtualMachine.Event;
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
|
|
||||||
public enum State implements FiniteState<State, Event> {
|
public enum State implements FiniteState<State, Event> {
|
||||||
Creating(true),
|
Creating(true, "VM is being created"),
|
||||||
Starting(true),
|
Starting(true, "VM is being started. At this state, you should find host id filled which means it's being started on that host."),
|
||||||
Running(false),
|
Running(false, "VM is running. host id has the host that it is running on."),
|
||||||
Stopping(true),
|
Stopping(true, "VM is being stopped. host id has the host that it is being stopped on."),
|
||||||
Stopped(false),
|
Stopped(false, "VM is stopped. host id should be null."),
|
||||||
Destroyed(false),
|
Destroyed(false, "VM is marked for destroy."),
|
||||||
Expunging(true),
|
Expunging(true, "VM is being expunged."),
|
||||||
Migrating(true),
|
Migrating(true, "VM is being migrated. host id holds to from host"),
|
||||||
Error(false),
|
Error(false, "VM is in error"),
|
||||||
Unknown(false);
|
Unknown(false, "VM state is unknown.");
|
||||||
|
|
||||||
private final boolean _transitional;
|
private final boolean _transitional;
|
||||||
|
String _description;
|
||||||
|
|
||||||
private State(boolean transitional) {
|
private State(boolean transitional, String description) {
|
||||||
_transitional = transitional;
|
_transitional = transitional;
|
||||||
|
_description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return _description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransitional() {
|
public boolean isTransitional() {
|
||||||
@ -67,6 +74,7 @@ public enum State implements FiniteState<State, Event> {
|
|||||||
return s_fsm;
|
return s_fsm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected static final StateMachine<State, VirtualMachine.Event> s_fsm = new StateMachine<State, VirtualMachine.Event>();
|
protected static final StateMachine<State, VirtualMachine.Event> s_fsm = new StateMachine<State, VirtualMachine.Event>();
|
||||||
static {
|
static {
|
||||||
s_fsm.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating);
|
s_fsm.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating);
|
||||||
|
|||||||
@ -145,7 +145,7 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
|||||||
import com.cloud.agent.api.storage.ShareAnswer;
|
import com.cloud.agent.api.storage.ShareAnswer;
|
||||||
import com.cloud.agent.api.storage.ShareCommand;
|
import com.cloud.agent.api.storage.ShareCommand;
|
||||||
import com.cloud.agent.api.to.NicTO;
|
import com.cloud.agent.api.to.NicTO;
|
||||||
import com.cloud.agent.api.to.StoragePoolTO;
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||||
import com.cloud.agent.api.to.VolumeTO;
|
import com.cloud.agent.api.to.VolumeTO;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
@ -4449,7 +4449,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
|
|
||||||
protected Answer execute(ModifyStoragePoolCommand cmd) {
|
protected Answer execute(ModifyStoragePoolCommand cmd) {
|
||||||
StoragePoolVO pool = cmd.getPool();
|
StoragePoolVO pool = cmd.getPool();
|
||||||
StoragePoolTO poolTO = new StoragePoolTO(pool);
|
StorageFilerTO poolTO = new StorageFilerTO(pool);
|
||||||
try {
|
try {
|
||||||
Connection conn = getConnection();
|
Connection conn = getConnection();
|
||||||
|
|
||||||
@ -4478,7 +4478,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
|
|
||||||
protected Answer execute(DeleteStoragePoolCommand cmd) {
|
protected Answer execute(DeleteStoragePoolCommand cmd) {
|
||||||
StoragePoolVO pool = cmd.getPool();
|
StoragePoolVO pool = cmd.getPool();
|
||||||
StoragePoolTO poolTO = new StoragePoolTO(pool);
|
StorageFilerTO poolTO = new StorageFilerTO(pool);
|
||||||
try {
|
try {
|
||||||
Connection conn = getConnection();
|
Connection conn = getConnection();
|
||||||
SR sr = getStorageRepository(conn, poolTO);
|
SR sr = getStorageRepository(conn, poolTO);
|
||||||
@ -4719,7 +4719,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CreateAnswer execute(CreateCommand cmd) {
|
public CreateAnswer execute(CreateCommand cmd) {
|
||||||
StoragePoolTO pool = cmd.getPool();
|
StorageFilerTO pool = cmd.getPool();
|
||||||
DiskProfile dskch = cmd.getDiskCharacteristics();
|
DiskProfile dskch = cmd.getDiskCharacteristics();
|
||||||
|
|
||||||
VDI vdi = null;
|
VDI vdi = null;
|
||||||
@ -4893,7 +4893,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SR getIscsiSR(StoragePoolTO pool) {
|
protected SR getIscsiSR(StorageFilerTO pool) {
|
||||||
Connection conn = getConnection();
|
Connection conn = getConnection();
|
||||||
synchronized (pool.getUuid().intern()) {
|
synchronized (pool.getUuid().intern()) {
|
||||||
Map<String, String> deviceConfig = new HashMap<String, String>();
|
Map<String, String> deviceConfig = new HashMap<String, String>();
|
||||||
@ -5003,7 +5003,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SR getNfsSR(StoragePoolTO pool) {
|
protected SR getNfsSR(StorageFilerTO pool) {
|
||||||
Connection conn = getConnection();
|
Connection conn = getConnection();
|
||||||
|
|
||||||
Map<String, String> deviceConfig = new HashMap<String, String>();
|
Map<String, String> deviceConfig = new HashMap<String, String>();
|
||||||
@ -5124,7 +5124,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
public CopyVolumeAnswer execute(final CopyVolumeCommand cmd) {
|
public CopyVolumeAnswer execute(final CopyVolumeCommand cmd) {
|
||||||
String volumeUUID = cmd.getVolumePath();
|
String volumeUUID = cmd.getVolumePath();
|
||||||
StoragePoolVO pool = cmd.getPool();
|
StoragePoolVO pool = cmd.getPool();
|
||||||
StoragePoolTO poolTO = new StoragePoolTO(pool);
|
StorageFilerTO poolTO = new StorageFilerTO(pool);
|
||||||
String secondaryStorageURL = cmd.getSecondaryStorageURL();
|
String secondaryStorageURL = cmd.getSecondaryStorageURL();
|
||||||
|
|
||||||
URI uri = null;
|
URI uri = null;
|
||||||
@ -6041,7 +6041,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SR getStorageRepository(Connection conn, StoragePoolTO pool) {
|
protected SR getStorageRepository(Connection conn, StorageFilerTO pool) {
|
||||||
Set<SR> srs;
|
Set<SR> srs;
|
||||||
try {
|
try {
|
||||||
srs = SR.getByNameLabel(conn, pool.getUuid());
|
srs = SR.getByNameLabel(conn, pool.getUuid());
|
||||||
|
|||||||
@ -28,6 +28,8 @@ import com.cloud.agent.api.to.VolumeTO;
|
|||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.HostPodVO;
|
import com.cloud.dc.HostPodVO;
|
||||||
import com.cloud.deploy.DeployDestination;
|
import com.cloud.deploy.DeployDestination;
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
import com.cloud.exception.InsufficientStorageCapacityException;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.exception.ResourceInUseException;
|
import com.cloud.exception.ResourceInUseException;
|
||||||
@ -229,9 +231,9 @@ public interface StorageManager extends Manager {
|
|||||||
*/
|
*/
|
||||||
boolean volumeOnSharedStoragePool(VolumeVO volume);
|
boolean volumeOnSharedStoragePool(VolumeVO volume);
|
||||||
|
|
||||||
Answer[] sendToPool(StoragePoolVO pool, Command[] cmds, boolean stopOnError);
|
Answer[] sendToPool(StoragePool pool, Command[] cmds, boolean stopOnError);
|
||||||
|
|
||||||
Answer sendToPool(StoragePoolVO pool, Command cmd);
|
Answer sendToPool(StoragePool pool, Command cmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that one of the following is true:
|
* Checks that one of the following is true:
|
||||||
@ -314,9 +316,9 @@ public interface StorageManager extends Manager {
|
|||||||
<T extends VMInstanceVO> DiskProfile allocateTemplatedVolume(VolumeType type, String name, DiskOfferingVO offering, VMTemplateVO template, T vm, AccountVO owner);
|
<T extends VMInstanceVO> DiskProfile allocateTemplatedVolume(VolumeType type, String name, DiskOfferingVO offering, VMTemplateVO template, T vm, AccountVO owner);
|
||||||
|
|
||||||
<T extends VMInstanceVO> void create(T vm);
|
<T extends VMInstanceVO> void create(T vm);
|
||||||
Long findHostIdForStoragePool(StoragePoolVO pool);
|
Long findHostIdForStoragePool(StoragePool pool);
|
||||||
void createCapacityEntry(StoragePoolVO storagePool, long allocated);
|
void createCapacityEntry(StoragePoolVO storagePool, long allocated);
|
||||||
|
|
||||||
|
|
||||||
VolumeTO[] prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException;
|
VolumeTO[] prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,6 +82,7 @@ public class StoragePoolVO implements StoragePool {
|
|||||||
@Enumerated(value=EnumType.STRING)
|
@Enumerated(value=EnumType.STRING)
|
||||||
private Status status;
|
private Status status;
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -95,18 +96,22 @@ public class StoragePoolVO implements StoragePool {
|
|||||||
// TODO Auto-generated constructor stub
|
// TODO Auto-generated constructor stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StoragePoolType getPoolType() {
|
public StoragePoolType getPoolType() {
|
||||||
return poolType;
|
return poolType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Date getCreated() {
|
public Date getCreated() {
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
@ -115,18 +120,22 @@ public class StoragePoolVO implements StoragePool {
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Date getUpdateTime() {
|
public Date getUpdateTime() {
|
||||||
return updateTime;
|
return updateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getDataCenterId() {
|
public long getDataCenterId() {
|
||||||
return dataCenterId;
|
return dataCenterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getAvailableBytes() {
|
public long getAvailableBytes() {
|
||||||
return availableBytes;
|
return availableBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getCapacityBytes() {
|
public long getCapacityBytes() {
|
||||||
return capacityBytes;
|
return capacityBytes;
|
||||||
}
|
}
|
||||||
@ -160,10 +169,12 @@ public class StoragePoolVO implements StoragePool {
|
|||||||
this.clusterId = clusterId;
|
this.clusterId = clusterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getHostAddress() {
|
public String getHostAddress() {
|
||||||
return hostAddress;
|
return hostAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@ -217,10 +228,12 @@ public class StoragePoolVO implements StoragePool {
|
|||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isShared() {
|
public boolean isShared() {
|
||||||
return poolType.isShared();
|
return poolType.isShared();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isLocal() {
|
public boolean isLocal() {
|
||||||
return !poolType.isShared();
|
return !poolType.isShared();
|
||||||
}
|
}
|
||||||
@ -252,6 +265,10 @@ public class StoragePoolVO implements StoragePool {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInMaintenance() {
|
||||||
|
return status == Status.PrepareForMaintenance || status == Status.Maintenance || status == Status.ErrorInMaintenance || removed != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof StoragePoolVO) || obj == null) {
|
if (!(obj instanceof StoragePoolVO) || obj == null) {
|
||||||
|
|||||||
@ -237,6 +237,10 @@ public class VolumeVO implements Volume {
|
|||||||
this.recreatable = false;
|
this.recreatable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setState(State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRecreatable() {
|
public boolean isRecreatable() {
|
||||||
return recreatable;
|
return recreatable;
|
||||||
}
|
}
|
||||||
@ -245,6 +249,7 @@ public class VolumeVO implements Volume {
|
|||||||
return iscsiName;
|
return iscsiName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package com.cloud.storage.dao;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
@ -47,4 +48,13 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long> {
|
|||||||
List<VolumeVO> findCreatedByInstance(long id);
|
List<VolumeVO> findCreatedByInstance(long id);
|
||||||
List<VolumeVO> findByPoolId(long poolId);
|
List<VolumeVO> findByPoolId(long poolId);
|
||||||
List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
|
List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
|
||||||
|
List<VolumeVO> findUsableVolumesForInstance(long instanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the volume only if the state in memory matches the state in the database.
|
||||||
|
* @param vol Volume to be updated.
|
||||||
|
* @param event event that causes the database change.
|
||||||
|
* @return true if update happened, false if not.
|
||||||
|
*/
|
||||||
|
boolean update(VolumeVO vol, Volume.Event event) throws ConcurrentOperationException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,11 +29,13 @@ import javax.ejb.Local;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.async.AsyncInstanceCreateStatus;
|
import com.cloud.async.AsyncInstanceCreateStatus;
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.Volume.MirrorState;
|
import com.cloud.storage.Volume.MirrorState;
|
||||||
import com.cloud.storage.Volume.VolumeType;
|
import com.cloud.storage.Volume.VolumeType;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.utils.db.Attribute;
|
||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.GenericSearchBuilder;
|
import com.cloud.utils.db.GenericSearchBuilder;
|
||||||
@ -42,6 +44,7 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
import com.cloud.utils.db.SearchCriteria.Func;
|
import com.cloud.utils.db.SearchCriteria.Func;
|
||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
|
import com.cloud.utils.db.UpdateBuilder;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@Local(value=VolumeDao.class) @DB(txn=false)
|
@Local(value=VolumeDao.class) @DB(txn=false)
|
||||||
@ -62,6 +65,10 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||||||
protected final SearchBuilder<VolumeVO> RemovedButNotDestroyedSearch;
|
protected final SearchBuilder<VolumeVO> RemovedButNotDestroyedSearch;
|
||||||
protected final SearchBuilder<VolumeVO> PoolIdSearch;
|
protected final SearchBuilder<VolumeVO> PoolIdSearch;
|
||||||
protected final SearchBuilder<VolumeVO> InstanceAndDeviceIdSearch;
|
protected final SearchBuilder<VolumeVO> InstanceAndDeviceIdSearch;
|
||||||
|
protected final SearchBuilder<VolumeVO> InstanceStatesSearch;
|
||||||
|
protected final SearchBuilder<VolumeVO> IdStateSearch;
|
||||||
|
|
||||||
|
protected final Attribute _stateAttr;
|
||||||
|
|
||||||
protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?";
|
protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?";
|
||||||
protected static final String SELECT_VM_ID_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ?";
|
protected static final String SELECT_VM_ID_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ?";
|
||||||
@ -143,6 +150,15 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||||||
return listBy(sc);
|
return listBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<VolumeVO> findUsableVolumesForInstance(long instanceId) {
|
||||||
|
SearchCriteria<VolumeVO> sc = InstanceStatesSearch.create();
|
||||||
|
sc.setParameters("instance", instanceId);
|
||||||
|
sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated);
|
||||||
|
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VolumeVO> findByInstanceAndType(long id, VolumeType vType) {
|
public List<VolumeVO> findByInstanceAndType(long id, VolumeType vType) {
|
||||||
SearchCriteria<VolumeVO> sc = InstanceAndTypeSearch.create();
|
SearchCriteria<VolumeVO> sc = InstanceAndTypeSearch.create();
|
||||||
@ -271,6 +287,28 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||||||
update(volumeId, volume);
|
update(volumeId, volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(VolumeVO vol, Volume.Event event) throws ConcurrentOperationException {
|
||||||
|
Volume.State oldState = vol.getState();
|
||||||
|
Volume.State newState = oldState.getNextState(event);
|
||||||
|
|
||||||
|
assert newState != null : "Event "+ event + " cannot happen from " + oldState;
|
||||||
|
|
||||||
|
UpdateBuilder builder = getUpdateBuilder(vol);
|
||||||
|
builder.set(vol, _stateAttr, newState);
|
||||||
|
|
||||||
|
SearchCriteria<VolumeVO> sc = IdStateSearch.create();
|
||||||
|
sc.setParameters("id", vol.getId());
|
||||||
|
sc.setParameters("state", vol.getState());
|
||||||
|
|
||||||
|
int rows = update(builder, sc, null);
|
||||||
|
if (rows != 1) {
|
||||||
|
VolumeVO dbVol = findById(vol.getId());
|
||||||
|
throw new ConcurrentOperationException("Unable to update " + vol + ": Old State=" + oldState + "; New State = " + newState + "; DB State=" + dbVol.getState());
|
||||||
|
}
|
||||||
|
return rows == 1;
|
||||||
|
}
|
||||||
|
|
||||||
protected VolumeDaoImpl() {
|
protected VolumeDaoImpl() {
|
||||||
AccountIdSearch = createSearchBuilder();
|
AccountIdSearch = createSearchBuilder();
|
||||||
AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
@ -353,6 +391,19 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||||||
RemovedButNotDestroyedSearch.and("destroyed", RemovedButNotDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
RemovedButNotDestroyedSearch.and("destroyed", RemovedButNotDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||||
RemovedButNotDestroyedSearch.and("removed", RemovedButNotDestroyedSearch.entity().getRemoved(), SearchCriteria.Op.NNULL);
|
RemovedButNotDestroyedSearch.and("removed", RemovedButNotDestroyedSearch.entity().getRemoved(), SearchCriteria.Op.NNULL);
|
||||||
RemovedButNotDestroyedSearch.done();
|
RemovedButNotDestroyedSearch.done();
|
||||||
|
|
||||||
|
InstanceStatesSearch = createSearchBuilder();
|
||||||
|
InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
|
||||||
|
InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||||
|
InstanceStatesSearch.done();
|
||||||
|
|
||||||
|
IdStateSearch = createSearchBuilder();
|
||||||
|
IdStateSearch.and("id", IdStateSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||||
|
IdStateSearch.and("state", IdStateSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||||
|
IdStateSearch.done();
|
||||||
|
|
||||||
|
_stateAttr = _allAttributes.get("state");
|
||||||
|
assert _stateAttr != null : "Couldn't get the state attribute";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @DB(txn=false)
|
@Override @DB(txn=false)
|
||||||
|
|||||||
@ -516,7 +516,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
@Override
|
@Override
|
||||||
public ConsoleProxyVO startProxy(long proxyVmId, long startEventId) {
|
public ConsoleProxyVO startProxy(long proxyVmId, long startEventId) {
|
||||||
try {
|
try {
|
||||||
return start(proxyVmId, startEventId);
|
return start2(proxyVmId, startEventId);
|
||||||
} catch (StorageUnavailableException e) {
|
} catch (StorageUnavailableException e) {
|
||||||
s_logger.warn("Exception while trying to start console proxy", e);
|
s_logger.warn("Exception while trying to start console proxy", e);
|
||||||
return null;
|
return null;
|
||||||
@ -852,7 +852,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
if (s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
s_logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
|
s_logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
|
||||||
|
|
||||||
Map<String, Object> context = createProxyInstance(dataCenterId);
|
Map<String, Object> context = createProxyInstance2(dataCenterId);
|
||||||
|
|
||||||
long proxyVmId = (Long) context.get("proxyVmId");
|
long proxyVmId = (Long) context.get("proxyVmId");
|
||||||
if (proxyVmId == 0) {
|
if (proxyVmId == 0) {
|
||||||
@ -892,7 +892,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
if (s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
s_logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
|
s_logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
|
||||||
|
|
||||||
Map<String, Object> context = createProxyInstance(dataCenterId);
|
Map<String, Object> context = createProxyInstance2(dataCenterId);
|
||||||
|
|
||||||
long proxyVmId = (Long) context.get("proxyVmId");
|
long proxyVmId = (Long) context.get("proxyVmId");
|
||||||
if (proxyVmId == 0) {
|
if (proxyVmId == 0) {
|
||||||
@ -1417,7 +1417,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
try {
|
try {
|
||||||
if (proxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
|
if (proxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
|
||||||
try {
|
try {
|
||||||
readyProxy = start(readyProxy.getId(), 0);
|
readyProxy = start2(readyProxy.getId(), 0);
|
||||||
} finally {
|
} finally {
|
||||||
proxyLock.unlock();
|
proxyLock.unlock();
|
||||||
}
|
}
|
||||||
@ -2150,7 +2150,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
|
|
||||||
if (!_storageMgr.share(proxy, vols, routingHost, false)) {
|
if (!_storageMgr.share(proxy, vols, routingHost, false)) {
|
||||||
s_logger.warn("Can not share " + proxy.getName());
|
s_logger.warn("Can not share " + proxy.getName());
|
||||||
throw new StorageUnavailableException(vol.getPoolId());
|
throw new StorageUnavailableException("Can not share " + proxy.getName(), vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
|
Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
|
||||||
|
|||||||
@ -2139,7 +2139,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
|
|||||||
|
|
||||||
if( ! _storageMgr.share(router, vols, routingHost, false) ) {
|
if( ! _storageMgr.share(router, vols, routingHost, false) ) {
|
||||||
s_logger.warn("Can not share " + vol.getPath() + " to " + router.getName() );
|
s_logger.warn("Can not share " + vol.getPath() + " to " + router.getName() );
|
||||||
throw new StorageUnavailableException(vol.getPoolId());
|
throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + router.getName(), vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
|
final Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
|
||||||
|
|||||||
@ -26,7 +26,6 @@ import java.util.Enumeration;
|
|||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -56,6 +55,7 @@ import com.cloud.agent.api.storage.CreateAnswer;
|
|||||||
import com.cloud.agent.api.storage.CreateCommand;
|
import com.cloud.agent.api.storage.CreateCommand;
|
||||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||||
import com.cloud.agent.api.storage.DestroyCommand;
|
import com.cloud.agent.api.storage.DestroyCommand;
|
||||||
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
import com.cloud.agent.api.to.VolumeTO;
|
import com.cloud.agent.api.to.VolumeTO;
|
||||||
import com.cloud.alert.AlertManager;
|
import com.cloud.alert.AlertManager;
|
||||||
import com.cloud.api.BaseCmd;
|
import com.cloud.api.BaseCmd;
|
||||||
@ -84,6 +84,7 @@ import com.cloud.exception.AgentUnavailableException;
|
|||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.exception.DiscoveryException;
|
import com.cloud.exception.DiscoveryException;
|
||||||
import com.cloud.exception.InsufficientCapacityException;
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
|
import com.cloud.exception.InsufficientStorageCapacityException;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.OperationTimedoutException;
|
import com.cloud.exception.OperationTimedoutException;
|
||||||
@ -103,6 +104,7 @@ import com.cloud.service.ServiceOfferingVO;
|
|||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
|
import com.cloud.storage.Volume.Event;
|
||||||
import com.cloud.storage.Volume.MirrorState;
|
import com.cloud.storage.Volume.MirrorState;
|
||||||
import com.cloud.storage.Volume.SourceType;
|
import com.cloud.storage.Volume.SourceType;
|
||||||
import com.cloud.storage.Volume.VolumeType;
|
import com.cloud.storage.Volume.VolumeType;
|
||||||
@ -173,10 +175,6 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
@Inject protected ConsoleProxyDao _consoleProxyDao;
|
@Inject protected ConsoleProxyDao _consoleProxyDao;
|
||||||
@Inject protected DetailsDao _detailsDao;
|
@Inject protected DetailsDao _detailsDao;
|
||||||
@Inject protected SnapshotDao _snapshotDao;
|
@Inject protected SnapshotDao _snapshotDao;
|
||||||
@Inject(adapter=StoragePoolAllocator.class)
|
|
||||||
protected Adapters<StoragePoolAllocator> _storagePoolAllocators;
|
|
||||||
@Inject(adapter=StoragePoolDiscoverer.class)
|
|
||||||
protected Adapters<StoragePoolDiscoverer> _discoverers;
|
|
||||||
@Inject protected StoragePoolHostDao _storagePoolHostDao;
|
@Inject protected StoragePoolHostDao _storagePoolHostDao;
|
||||||
@Inject protected AlertManager _alertMgr;
|
@Inject protected AlertManager _alertMgr;
|
||||||
@Inject protected VMTemplateHostDao _vmTemplateHostDao = null;
|
@Inject protected VMTemplateHostDao _vmTemplateHostDao = null;
|
||||||
@ -197,6 +195,11 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
@Inject protected ServiceOfferingDao _offeringDao;
|
@Inject protected ServiceOfferingDao _offeringDao;
|
||||||
@Inject protected UserDao _userDao;
|
@Inject protected UserDao _userDao;
|
||||||
|
|
||||||
|
@Inject(adapter=StoragePoolAllocator.class)
|
||||||
|
protected Adapters<StoragePoolAllocator> _storagePoolAllocators;
|
||||||
|
@Inject(adapter=StoragePoolDiscoverer.class)
|
||||||
|
protected Adapters<StoragePoolDiscoverer> _discoverers;
|
||||||
|
|
||||||
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
|
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
|
||||||
protected SearchBuilder<StoragePoolVO> PoolsUsedByVmSearch;
|
protected SearchBuilder<StoragePoolVO> PoolsUsedByVmSearch;
|
||||||
|
|
||||||
@ -272,79 +275,6 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
return vols.get(0);
|
return vols.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public VolumeTO[] prepare(VirtualMachineProfile vm, DeployDestination dest) {
|
|
||||||
List<VolumeVO> vols = _volsDao.findCreatedByInstance(vm.getId());
|
|
||||||
List<VolumeVO> recreateVols = new ArrayList<VolumeVO>(vols.size());
|
|
||||||
Host host = dest.getHost();
|
|
||||||
|
|
||||||
VolumeTO[] disks = new VolumeTO[vols.size()];
|
|
||||||
int i = 0;
|
|
||||||
Iterator<VolumeVO> it = vols.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
VolumeVO vol = it.next();
|
|
||||||
if (vol.isRecreatable()) {
|
|
||||||
it.remove();
|
|
||||||
//if we have a system vm
|
|
||||||
//get the storage pool
|
|
||||||
//if pool is in maintenance
|
|
||||||
//add to recreate vols, and continue
|
|
||||||
if(vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.DomainRouter) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm))
|
|
||||||
{
|
|
||||||
StoragePoolVO sp = _storagePoolDao.findById(vol.getPoolId());
|
|
||||||
|
|
||||||
if(sp!=null && sp.getStatus().equals(Status.PrepareForMaintenance))
|
|
||||||
{
|
|
||||||
recreateVols.add(vol);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StoragePoolHostVO ph = _storagePoolHostDao.findByPoolHost(vol.getPoolId(), host.getId());
|
|
||||||
if (ph == null) {
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
|
||||||
s_logger.debug("Must recreate " + vol + " since " + vol.getPoolId() + " has is not hooked up with host " + host.getId());
|
|
||||||
}
|
|
||||||
recreateVols.add(vol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (VolumeVO vol : recreateVols) {
|
|
||||||
VolumeVO create = allocateDuplicateVolume(vol);
|
|
||||||
vols.add(vol);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
create.setDiskOfferingId(vol.getDiskOfferingId());
|
|
||||||
create.setDeviceId(vol.getDeviceId());
|
|
||||||
create = _volsDao.persist(create);
|
|
||||||
VMTemplateVO template = _templateDao.findById(create.getTemplateId());
|
|
||||||
DataCenterVO dc = _dcDao.findById(create.getDataCenterId());
|
|
||||||
HostPodVO pod = _podDao.findById(host.getPodId());
|
|
||||||
DiskOfferingVO diskOffering = null;
|
|
||||||
diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
|
|
||||||
ServiceOfferingVO offering;
|
|
||||||
if (vm instanceof UserVmVO) {
|
|
||||||
offering = _offeringDao.findById(((UserVmVO)vm).getServiceOfferingId());
|
|
||||||
} else {
|
|
||||||
offering = _offeringDao.findById(vol.getDiskOfferingId());
|
|
||||||
}
|
|
||||||
VolumeVO created = createVolume(create, vm, template, dc, pod, host.getClusterId(), offering, diskOffering, new ArrayList<StoragePoolVO>(),0);
|
|
||||||
if (created == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
createds.add(created);
|
|
||||||
|
|
||||||
for (VolumeVO vol : recreateVols) {
|
|
||||||
_volsDao.remove(vol.getId());
|
|
||||||
}
|
|
||||||
disks[i++] = null;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return disks;
|
|
||||||
}
|
|
||||||
|
|
||||||
VolumeVO allocateDuplicateVolume(VolumeVO oldVol) {
|
VolumeVO allocateDuplicateVolume(VolumeVO oldVol) {
|
||||||
VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(), oldVol.getSize());
|
VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(), oldVol.getSize());
|
||||||
newVol.setTemplateId(oldVol.getTemplateId());
|
newVol.setTemplateId(oldVol.getTemplateId());
|
||||||
@ -487,7 +417,7 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long findHostIdForStoragePool(StoragePoolVO pool) {
|
public Long findHostIdForStoragePool(StoragePool pool) {
|
||||||
List<StoragePoolHostVO> poolHosts = _poolHostDao.listByHostStatus(pool.getId(), Status.Up);
|
List<StoragePoolHostVO> poolHosts = _poolHostDao.listByHostStatus(pool.getId(), Status.Up);
|
||||||
|
|
||||||
if (poolHosts.size() == 0) {
|
if (poolHosts.size() == 0) {
|
||||||
@ -498,7 +428,7 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer[] sendToPool(StoragePoolVO pool, Command[] cmds, boolean stopOnError) {
|
public Answer[] sendToPool(StoragePool pool, Command[] cmds, boolean stopOnError) {
|
||||||
List<StoragePoolHostVO> poolHosts = _poolHostDao.listByHostStatus(pool.getId(), Status.Up);
|
List<StoragePoolHostVO> poolHosts = _poolHostDao.listByHostStatus(pool.getId(), Status.Up);
|
||||||
Collections.shuffle(poolHosts);
|
Collections.shuffle(poolHosts);
|
||||||
|
|
||||||
@ -520,7 +450,7 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer sendToPool(StoragePoolVO pool, Command cmd) {
|
public Answer sendToPool(StoragePool pool, Command cmd) {
|
||||||
Command[] cmds = new Command[]{cmd};
|
Command[] cmds = new Command[]{cmd};
|
||||||
Answer[] answers = sendToPool(pool, cmds, true);
|
Answer[] answers = sendToPool(pool, cmds, true);
|
||||||
if (answers == null) {
|
if (answers == null) {
|
||||||
@ -885,9 +815,9 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
if (tmpltStoredOn == null) {
|
if (tmpltStoredOn == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cmd = new CreateCommand(volume, vm, dskCh, tmpltStoredOn.getLocalDownloadPath(), pool);
|
cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
|
||||||
} else {
|
} else {
|
||||||
cmd = new CreateCommand(volume, vm, dskCh, pool, size);
|
cmd = new CreateCommand(dskCh, new StorageFilerTO(pool), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Answer answer = sendToPool(pool, cmd);
|
Answer answer = sendToPool(pool, cmd);
|
||||||
@ -2441,6 +2371,149 @@ public class StorageManagerImpl implements StorageManager {
|
|||||||
return createDiskCharacteristics(volume, offering);
|
return createDiskCharacteristics(volume, offering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected StoragePool findStorage(DiskProfile dskCh, DeployDestination dest, VirtualMachineProfile vm, List<? extends Volume> alreadyAllocated, Set<? extends StoragePool> avoid) {
|
||||||
|
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||||
|
StoragePool pool = allocator.allocateTo(dskCh, vm, dest, alreadyAllocated, avoid);
|
||||||
|
if (pool != null) {
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VolumeTO[] prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException {
|
||||||
|
List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Preparing " + vols.size() + " volumes for " + vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<VolumeVO> recreateVols = new ArrayList<VolumeVO>(vols.size());
|
||||||
|
VolumeTO[] disks = new VolumeTO[vols.size()];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (VolumeVO vol : vols) {
|
||||||
|
Volume.State state = vol.getState();
|
||||||
|
if (state == Volume.State.Ready) {
|
||||||
|
StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
|
||||||
|
if (pool.getRemoved() != null || pool.isInMaintenance()) {
|
||||||
|
if (vol.isRecreatable()) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Volume " + vol + " has to be recreated due to storage pool " + pool + " is unavailable");
|
||||||
|
}
|
||||||
|
recreateVols.add(vol);
|
||||||
|
} else {
|
||||||
|
throw new StorageUnavailableException("Volume " + vol + " is not available on the storage pool.", pool);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Volume " + vol + " is ready.");
|
||||||
|
}
|
||||||
|
disks[i++] = new VolumeTO(vol, pool);
|
||||||
|
}
|
||||||
|
} else if (state == Volume.State.Allocated) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Creating volume " + vol + " for the first time.");
|
||||||
|
}
|
||||||
|
recreateVols.add(vol);
|
||||||
|
} else {
|
||||||
|
throw new StorageUnavailableException("Volume " + vol + " can not be used", vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (VolumeVO vol : recreateVols) {
|
||||||
|
VolumeVO newVol;
|
||||||
|
if (vol.getState() == Volume.State.Allocated) {
|
||||||
|
newVol = vol;
|
||||||
|
} else {
|
||||||
|
newVol = switchVolume(vol);
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Created new volume " + newVol + " for old volume " + vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_volsDao.update(newVol, Volume.Event.Create);
|
||||||
|
} catch(ConcurrentOperationException e) {
|
||||||
|
throw new StorageUnavailableException("Unable to create " + newVol, newVol);
|
||||||
|
}
|
||||||
|
Pair<VolumeTO, StoragePool> created = createVolume(newVol, _diskOfferingDao.findById(newVol.getDiskOfferingId()), vm, vols, dest);
|
||||||
|
if (created == null) {
|
||||||
|
newVol.setPoolId(null);
|
||||||
|
try {
|
||||||
|
_volsDao.update(newVol, Event.OperationFailed);
|
||||||
|
} catch (ConcurrentOperationException e) {
|
||||||
|
throw new CloudRuntimeException("Unable to update the failure on a volume: " + newVol, e);
|
||||||
|
}
|
||||||
|
throw new StorageUnavailableException("Unable to create " + newVol, newVol);
|
||||||
|
}
|
||||||
|
newVol.setStatus(AsyncInstanceCreateStatus.Created);
|
||||||
|
newVol.setFolder(created.second().getPath());
|
||||||
|
newVol.setPath(created.first().getPath());
|
||||||
|
newVol.setSize(created.first().getSize());
|
||||||
|
newVol.setPoolType(created.second().getPoolType());
|
||||||
|
newVol.setPodId(created.second().getPodId());
|
||||||
|
try {
|
||||||
|
_volsDao.update(newVol, Event.OperationSucceeded);
|
||||||
|
} catch (ConcurrentOperationException e) {
|
||||||
|
throw new CloudRuntimeException("Unable to update an CREATE operation succeeded on volume " + newVol, e);
|
||||||
|
}
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Volume " + newVol + " is created on " + created.second());
|
||||||
|
}
|
||||||
|
disks[i++] = created.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
return disks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DB
|
||||||
|
protected VolumeVO switchVolume(VolumeVO existingVolume) throws StorageUnavailableException {
|
||||||
|
Transaction txn = Transaction.currentTxn();
|
||||||
|
try {
|
||||||
|
txn.start();
|
||||||
|
_volsDao.update(existingVolume, Event.Destroy);
|
||||||
|
VolumeVO newVolume = allocateDuplicateVolume(existingVolume);
|
||||||
|
txn.commit();
|
||||||
|
return newVolume;
|
||||||
|
} catch (ConcurrentOperationException e) {
|
||||||
|
throw new StorageUnavailableException("Unable to duplicate the volume " + existingVolume, existingVolume, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<VolumeTO, StoragePool> createVolume(VolumeVO toBeCreated, DiskOfferingVO offering, VirtualMachineProfile vm, List<? extends Volume> alreadyCreated, DeployDestination dest) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Creating volume: " + toBeCreated);
|
||||||
|
}
|
||||||
|
DiskProfile diskProfile = new DiskProfile(toBeCreated, offering);
|
||||||
|
|
||||||
|
Set<StoragePool> avoids = new HashSet<StoragePool>();
|
||||||
|
StoragePool pool = null;
|
||||||
|
while ((pool = findStorage(diskProfile, dest, vm, alreadyCreated, avoids)) != null) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Trying to create in " + pool);
|
||||||
|
}
|
||||||
|
avoids.add(pool);
|
||||||
|
toBeCreated.setPoolId(pool.getId());
|
||||||
|
try {
|
||||||
|
_volsDao.update(toBeCreated, Volume.Event.OperationRetry);
|
||||||
|
} catch (ConcurrentOperationException e) {
|
||||||
|
throw new CloudRuntimeException("Unable to retry a create operation on volume " + toBeCreated);
|
||||||
|
}
|
||||||
|
CreateCommand cmd = new CreateCommand(diskProfile, new StorageFilerTO(pool), diskProfile.getSize());
|
||||||
|
Answer answer = sendToPool(pool, cmd);
|
||||||
|
if (answer.getResult()) {
|
||||||
|
CreateAnswer createAnswer = (CreateAnswer)answer;
|
||||||
|
return new Pair<VolumeTO, StoragePool>(createAnswer.getVolume(), pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Unable to create volume " + toBeCreated);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends VMInstanceVO> void create(T vm) {
|
public <T extends VMInstanceVO> void create(T vm) {
|
||||||
List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
|
List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
|
||||||
|
|||||||
@ -28,6 +28,8 @@ import javax.naming.ConfigurationException;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.configuration.dao.ConfigurationDao;
|
import com.cloud.configuration.dao.ConfigurationDao;
|
||||||
|
import com.cloud.dc.DataCenterVO;
|
||||||
|
import com.cloud.dc.HostPodVO;
|
||||||
import com.cloud.deploy.DeployDestination;
|
import com.cloud.deploy.DeployDestination;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
@ -229,8 +231,11 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StoragePool allocateTo(DiskProfile dskCh, VirtualMachineProfile vm, DeployDestination dest, List<Volume> disks, Set<StoragePool> avoids) {
|
public StoragePool allocateTo(DiskProfile dskCh, VirtualMachineProfile vm, DeployDestination dest, List<? extends Volume> disks, Set<? extends StoragePool> avoids) {
|
||||||
|
|
||||||
return null;
|
VMInstanceVO instance = (VMInstanceVO)(vm.getVm());
|
||||||
|
|
||||||
|
VMTemplateVO template = vm.getTemplateId() != null ? _templateDao.findById(vm.getTemplateId()) : null;
|
||||||
|
return allocateToPool(dskCh, (DataCenterVO)dest.getDataCenter(), (HostPodVO)dest.getPod(), dest.getCluster().getId(), instance, template, avoids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,5 +43,5 @@ public interface StoragePoolAllocator extends Adapter {
|
|||||||
|
|
||||||
String chooseStorageIp(VirtualMachine vm, Host host, Host storage);
|
String chooseStorageIp(VirtualMachine vm, Host host, Host storage);
|
||||||
|
|
||||||
StoragePool allocateTo(DiskProfile dskCh, VirtualMachineProfile vm, DeployDestination dest, List<Volume> disks, Set<StoragePool> avoids);
|
StoragePool allocateTo(DiskProfile dskCh, VirtualMachineProfile vm, DeployDestination dest, List<? extends Volume> disks, Set<? extends StoragePool> avoids);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1822,7 +1822,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
|||||||
|
|
||||||
if( !_storageMgr.share(secStorageVm, vols, routingHost, false) ) {
|
if( !_storageMgr.share(secStorageVm, vols, routingHost, false) ) {
|
||||||
s_logger.warn("Can not share " + vol.getPath() + " to " + secStorageVm.getName());
|
s_logger.warn("Can not share " + vol.getPath() + " to " + secStorageVm.getName());
|
||||||
throw new StorageUnavailableException(vol.getPoolId());
|
throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + secStorageVm.getName(), vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
|
Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
|
||||||
|
|||||||
@ -36,7 +36,9 @@ import com.cloud.deploy.DeployDestination;
|
|||||||
import com.cloud.deploy.DeploymentPlan;
|
import com.cloud.deploy.DeploymentPlan;
|
||||||
import com.cloud.deploy.DeploymentPlanner;
|
import com.cloud.deploy.DeploymentPlanner;
|
||||||
import com.cloud.exception.AgentUnavailableException;
|
import com.cloud.exception.AgentUnavailableException;
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.exception.InsufficientCapacityException;
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
|
import com.cloud.exception.StorageUnavailableException;
|
||||||
import com.cloud.network.NetworkConfigurationVO;
|
import com.cloud.network.NetworkConfigurationVO;
|
||||||
import com.cloud.network.NetworkManager;
|
import com.cloud.network.NetworkManager;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
@ -233,7 +235,7 @@ public class MauriceMoss implements VmManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends VMInstanceVO> T start(T vm, DeploymentPlan plan) throws InsufficientCapacityException {
|
public <T extends VMInstanceVO> T start(T vm, DeploymentPlan plan) throws InsufficientCapacityException, ConcurrentOperationException {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Creating actual resources for VM " + vm);
|
s_logger.debug("Creating actual resources for VM " + vm);
|
||||||
}
|
}
|
||||||
@ -246,7 +248,7 @@ public class MauriceMoss implements VmManager {
|
|||||||
|
|
||||||
Set<DeployDestination> avoids = new HashSet<DeployDestination>();
|
Set<DeployDestination> avoids = new HashSet<DeployDestination>();
|
||||||
int retry = _retry;
|
int retry = _retry;
|
||||||
while (retry-- > 0) {
|
while (retry-- != 0) { // It's != so that it can match -1.
|
||||||
DeployDestination dest = null;
|
DeployDestination dest = null;
|
||||||
for (DeploymentPlanner dispatcher : _planners) {
|
for (DeploymentPlanner dispatcher : _planners) {
|
||||||
dest = dispatcher.plan(vmProfile, plan, avoids);
|
dest = dispatcher.plan(vmProfile, plan, avoids);
|
||||||
@ -266,8 +268,15 @@ public class MauriceMoss implements VmManager {
|
|||||||
_vmDao.updateIf(vm, Event.StartRequested, dest.getHost().getId());
|
_vmDao.updateIf(vm, Event.StartRequested, dest.getHost().getId());
|
||||||
|
|
||||||
VirtualMachineTO vmTO = new VirtualMachineTO();
|
VirtualMachineTO vmTO = new VirtualMachineTO();
|
||||||
|
try {
|
||||||
|
_storageMgr.prepare(vmProfile, dest);
|
||||||
|
} catch (ConcurrentOperationException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (StorageUnavailableException e) {
|
||||||
|
s_logger.warn("Unable to contact storage.", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
_networkMgr.prepare(vmProfile, dest);
|
_networkMgr.prepare(vmProfile, dest);
|
||||||
// _storageMgr.prepare(vm, dest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
|||||||
@ -179,9 +179,9 @@ import com.cloud.vm.DomainRouter.Role;
|
|||||||
import com.cloud.vm.VirtualMachine.Event;
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
import com.cloud.vm.VirtualMachine.Type;
|
import com.cloud.vm.VirtualMachine.Type;
|
||||||
import com.cloud.vm.dao.DomainRouterDao;
|
import com.cloud.vm.dao.DomainRouterDao;
|
||||||
|
import com.cloud.vm.dao.InstanceGroupDao;
|
||||||
import com.cloud.vm.dao.InstanceGroupVMMapDao;
|
import com.cloud.vm.dao.InstanceGroupVMMapDao;
|
||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
import com.cloud.vm.dao.InstanceGroupDao;
|
|
||||||
|
|
||||||
@Local(value={UserVmManager.class})
|
@Local(value={UserVmManager.class})
|
||||||
public class UserVmManagerImpl implements UserVmManager {
|
public class UserVmManagerImpl implements UserVmManager {
|
||||||
@ -1207,6 +1207,7 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public void releaseGuestIpAddress(UserVmVO userVm) {
|
public void releaseGuestIpAddress(UserVmVO userVm) {
|
||||||
ServiceOffering offering = _offeringDao.findById(userVm.getServiceOfferingId());
|
ServiceOffering offering = _offeringDao.findById(userVm.getServiceOfferingId());
|
||||||
|
|
||||||
@ -2117,7 +2118,7 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||||||
|
|
||||||
if( !_storageMgr.share(vm, vols, vmHost, false) ) {
|
if( !_storageMgr.share(vm, vols, vmHost, false) ) {
|
||||||
s_logger.warn("Can not share " + vm.toString() + " on host " + vmHost.getId());
|
s_logger.warn("Can not share " + vm.toString() + " on host " + vmHost.getId());
|
||||||
throw new StorageUnavailableException(vmHost.getId());
|
throw new StorageUnavailableException("Can not share " + vm.toString() + " on host " + vmHost.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
Answer answer = _agentMgr.easySend(vmHost.getId(), cmd);
|
Answer answer = _agentMgr.easySend(vmHost.getId(), cmd);
|
||||||
@ -2400,6 +2401,7 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public VMTemplateVO createPrivateTemplateRecord(Long userId, long volumeId, String name, String description, long guestOSId, Boolean requiresHvm, Integer bits, Boolean passwordEnabled, boolean isPublic, boolean featured)
|
public VMTemplateVO createPrivateTemplateRecord(Long userId, long volumeId, String name, String description, long guestOSId, Boolean requiresHvm, Integer bits, Boolean passwordEnabled, boolean isPublic, boolean featured)
|
||||||
throws InvalidParameterValueException {
|
throws InvalidParameterValueException {
|
||||||
|
|
||||||
@ -3014,6 +3016,7 @@ public class UserVmManagerImpl implements UserVmManager {
|
|||||||
_vmMgr = vmMgr;
|
_vmMgr = vmMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
|
GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -52,4 +52,6 @@ public interface FiniteState<S, E> {
|
|||||||
* @return array of events.
|
* @return array of events.
|
||||||
*/
|
*/
|
||||||
Set<E> getPossibleEvents();
|
Set<E> getPossibleEvents();
|
||||||
|
|
||||||
|
String getDescription();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user