Refactoring createSnapshot to new API framework.

This commit is contained in:
Kris McQueen 2010-09-09 17:13:29 -07:00
parent 39038721a8
commit 037f1ff327
7 changed files with 140 additions and 245 deletions

View File

@ -18,26 +18,18 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseAsyncCreateCmd;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseCmd.Manager;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.async.AsyncJobResult;
import com.cloud.async.AsyncJobVO;
import com.cloud.async.executor.CreateSnapshotResultObject;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.api.response.SnapshotResponse;
import com.cloud.serializer.SerializerHelper;
import com.cloud.server.ManagementServer;
import com.cloud.storage.Snapshot.SnapshotType;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.VolumeVO;
import com.cloud.utils.Pair;
import com.cloud.user.Account;
@Implementation(createMethod="createSnapshotDB", method="createSnapshot", manager=Manager.SnapshotManager)
public class CreateSnapshotCmd extends BaseAsyncCreateCmd {
@ -88,128 +80,27 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd {
@Override
public String getResponse() {
}
SnapshotVO snapshot = (SnapshotVO)getResponseObject();
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
// Long volumeId = (Long) params.get(BaseCmd.Properties.VOLUME_ID.getName());
// Long userId = (Long) params.get(BaseCmd.Properties.USER_ID.getName());
SnapshotResponse response = new SnapshotResponse();
response.setId(snapshot.getId());
ManagementServer managementServer = getManagementServer();
// Verify that a volume exists with a specified volume ID
VolumeVO volume = managementServer.findVolumeById(volumeId);
if (volume == null) {
throw new ServerApiException (BaseCmd.PARAM_ERROR, "Unable to find a volume with id " + volumeId);
Account account = getAsyncJobMgr().getExecutorContext().getAccountDao().findById(snapshot.getAccountId());
if (account != null) {
response.setAccountName(account.getAccountName());
response.setDomainId(account.getDomainId());
response.setDomainName(getAsyncJobMgr().getExecutorContext().getManagementServer().findDomainIdById(account.getDomainId()).getName());
}
// If an account was passed in, make sure that it matches the account of the volume
// FIXME: permission checks go in business logic
checkAccountPermissions(params, volume.getAccountId(), volume.getDomainId(), "volume", volumeId);
VolumeVO volume = managementServer.findVolumeById(snapshot.getVolumeId());
String snapshotTypeStr = SnapshotType.values()[snapshot.getSnapshotType()].name();
response.setSnapshotType(snapshotTypeStr);
response.setVolumeId(snapshot.getVolumeId());
response.setVolumeName(volume.getName());
response.setVolumeType(volume.getVolumeType().toString());
response.setCreated(snapshot.getCreated());
response.setName(snapshot.getName());
// If command is executed via 8096 port, set userId to the id of System account (1)
if (userId == null) {
userId = Long.valueOf(1);
}
try {
long jobId = managementServer.createSnapshotAsync(userId, volumeId.longValue());
if (jobId == 0) {
s_logger.warn("Unable to schedule async-job for CreateSnapshot comamnd");
} else {
if (s_logger.isDebugEnabled())
s_logger.debug("CreateSnapshot command has been accepted, job id: " + jobId);
}
long snapshotId = waitInstanceCreation(jobId);
List<Pair<String, Object>> returnValues = new ArrayList<Pair<String, Object>>();
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.SNAPSHOT_ID.getName(), Long.valueOf(snapshotId)));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId)));
return returnValues;
} catch (ResourceAllocationException rae) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to create a snapshot for volume with id " + volumeId + ": " + rae.getMessage());
} catch (ServerApiException apiEx) {
throw apiEx;
} catch (Exception ex) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to create a snapshot for volume with id " + volumeId + " because of: " + ex.getMessage());
}
}
protected long waitInstanceCreation(long jobId) {
ManagementServer mgr = getManagementServer();
long snapshotId = 0;
AsyncJobVO job = null;
boolean interruped = false;
// as job may be executed in other management server, we need to do a database polling here
try {
boolean quit = false;
while(!quit) {
job = mgr.findAsyncJobById(jobId);
if(job == null) {
s_logger.error("CreateSnapshotAsync.waitInstanceCreation error: job-" + jobId + " no longer exists");
break;
}
switch(job.getStatus()) {
case AsyncJobResult.STATUS_IN_PROGRESS :
if(job.getProcessStatus() == BaseCmd.PROGRESS_INSTANCE_CREATED) {
Long id = (Long)SerializerHelper.fromSerializedString(job.getResult());
if(id != null) {
snapshotId = id.longValue();
if(s_logger.isDebugEnabled())
s_logger.debug("CreateSnapshotAsync succeeded in taking snapshot on primary, snapshotId: " + snapshotId);
} else {
s_logger.warn("CreateSnapshotAsync succeeded in taking snapshot on primary, but value as null?");
}
quit = true;
}
break;
case AsyncJobResult.STATUS_SUCCEEDED :
{
CreateSnapshotResultObject resultObject = (CreateSnapshotResultObject)SerializerHelper.fromSerializedString(job.getResult());
if(resultObject != null) {
snapshotId = resultObject.getId();
if(s_logger.isDebugEnabled())
s_logger.debug("CreateSnapshotAsync succeeded in backing up snapshot to secondary, snapshotId: " + snapshotId);
} else {
s_logger.warn("CreateSnapshotAsync successfully completed, but result object is null?");
}
}
quit = true;
break;
case AsyncJobResult.STATUS_FAILED :
s_logger.error("CreateSnapshotAsync job-" + jobId + " failed, result: " + job.getResult());
quit = true;
break;
}
if(quit)
break;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
interruped = true;
}
}
} finally {
if(interruped)
Thread.currentThread().interrupt();
}
return snapshotId;
}
protected long getInstanceIdFromJobSuccessResult(String result) {
CreateSnapshotResultObject resultObject = (CreateSnapshotResultObject)SerializerHelper.fromSerializedString(result);
if(resultObject != null) {
return resultObject.getId();
}
return 0;
return SerializerHelper.toSerializedString(response);
}
}

View File

@ -27,6 +27,7 @@ import com.cloud.api.commands.AssignPortForwardingServiceCmd;
import com.cloud.api.commands.CreateDomainCmd;
import com.cloud.api.commands.CreatePortForwardingServiceCmd;
import com.cloud.api.commands.CreatePortForwardingServiceRuleCmd;
import com.cloud.api.commands.CreateSnapshotCmd;
import com.cloud.api.commands.CreateUserCmd;
import com.cloud.api.commands.DeletePortForwardingServiceCmd;
import com.cloud.api.commands.DeleteUserCmd;
@ -1114,18 +1115,6 @@ public interface ManagementServer {
public long getMemoryUsagebyHost(Long hostId);
/**
* Create a snapshot of a volume
* @param userId the user for whom this snapshot is being created
* @param volumeId the id of the volume
* @return the Snapshot that was created
* @throws InternalErrorException
*/
long createSnapshotAsync(long userId, long volumeId)
throws InvalidParameterValueException,
ResourceAllocationException,
InternalErrorException;
/**
* @param userId The Id of the user who invoked this operation.
* @param volumeId The volume for which this snapshot is being taken

View File

@ -58,6 +58,7 @@ import com.cloud.api.commands.AssignPortForwardingServiceCmd;
import com.cloud.api.commands.CreateDomainCmd;
import com.cloud.api.commands.CreatePortForwardingServiceCmd;
import com.cloud.api.commands.CreatePortForwardingServiceRuleCmd;
import com.cloud.api.commands.CreateSnapshotCmd;
import com.cloud.api.commands.CreateUserCmd;
import com.cloud.api.commands.CreateVolumeCmd;
import com.cloud.api.commands.DeletePortForwardingServiceCmd;
@ -207,6 +208,7 @@ import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.Snapshot;
import com.cloud.storage.Snapshot.SnapshotType;
import com.cloud.storage.SnapshotPolicyVO;
import com.cloud.storage.SnapshotScheduleVO;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.ImageFormat;
@ -5270,42 +5272,6 @@ public class ManagementServerImpl implements ManagementServer {
return mem;
}
@Override
public long createSnapshotAsync(long userId, long volumeId)
throws InvalidParameterValueException,
ResourceAllocationException,
InternalErrorException
{
VolumeVO volume = findVolumeById(volumeId); // not null, precondition.
if (volume.getStatus() != AsyncInstanceCreateStatus.Created) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in Created state but " + volume.getStatus() + ". Cannot take snapshot.");
}
StoragePoolVO storagePoolVO = findPoolById(volume.getPoolId());
if (storagePoolVO == null) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " does not have a valid storage pool. Is it destroyed?");
}
if (storagePoolVO.isLocal()) {
throw new InvalidParameterValueException("Cannot create a snapshot from a volume residing on a local storage pool, poolId: " + volume.getPoolId());
}
Long instanceId = volume.getInstanceId();
if (instanceId != null) {
// It is not detached, but attached to a VM
if (findUserVMInstanceById(instanceId) == null) {
// It is not a UserVM but a SystemVM or DomR
throw new InvalidParameterValueException("Snapshots of volumes attached to System or router VM are not allowed");
}
}
Long jobId = _snapshotScheduler.scheduleManualSnapshot(userId, volumeId);
if (jobId == null) {
throw new InternalErrorException("Snapshot could not be scheduled because there is another snapshot underway for the same volume. " +
"Please wait for some time.");
}
return jobId;
}
@Override
public SnapshotVO createTemplateSnapshot(Long userId, long volumeId) {
return _vmMgr.createTemplateSnapshot(userId, volumeId);

View File

@ -19,6 +19,7 @@ package com.cloud.storage.snapshot;
import java.util.List;
import com.cloud.api.commands.CreateSnapshotCmd;
import com.cloud.api.commands.CreateSnapshotPolicyCmd;
import com.cloud.api.commands.DeleteSnapshotCmd;
import com.cloud.api.commands.DeleteSnapshotPoliciesCmd;
@ -46,51 +47,38 @@ public interface SnapshotManager extends Manager {
public static final int WEEKLYMAX = 8;
public static final int MONTHLYMAX = 8;
/**
* This is the synchronous version of the below command.
* @throws ResourceAllocationException
* @throws InvalidParameterValueException
/**
* Create a snapshot of a volume
* @param cmd the API command wrapping the parameters for creating the snapshot (mainly volumeId)
* @return the Snapshot that was created
* @throws InternalErrorException
*/
SnapshotVO createSnapshot(long userId, long volumeId, List<Long> policies) throws InvalidParameterValueException, ResourceAllocationException;
SnapshotVO createSnapshotDB(CreateSnapshotCmd cmd) throws InvalidParameterValueException, ResourceAllocationException, InternalErrorException;
/**
* Creates a snapshot for the given volume
* Create a snapshot of a volume
* @param cmd the API command wrapping the parameters for creating the snapshot (mainly volumeId)
* @return the Snapshot that was created
* @throws InternalErrorException
*/
long createSnapshotAsync(long userId, long volumeId, List<Long> policies);
SnapshotVO createSnapshot(CreateSnapshotCmd cmd) throws InvalidParameterValueException, ResourceAllocationException, InternalErrorException;
/**
* After successfully creating a snapshot of a volume, copy the snapshot to the secondary storage for
* 1) reliability
* 2) So that storage space on Primary is conserved.
* @param userId The user who invoked this command.
* @param snapshot Info about the created snapshot on primary storage.
* @return True if the snapshot was successfully backed up.
* Create a snapshot of a volume
* @param cmd the API command wrapping the parameters for creating the snapshot (mainly volumeId)
* @return the Snapshot that was created
* @throws InternalErrorException
*/
public boolean backupSnapshotToSecondaryStorage(long userId, SnapshotVO snapshot);
/**
* Once a snapshot has completed,
* 1) If success, update the database entries
* 2) If success and there are excess snapshots for any of the policies given, delete the oldest one.
* 3) Schedule the next recurring snapshot.
* @param userId The user who executed this command
* @param volumeId The volume for which the snapshot is being taken
* @param snapshotId The snapshot which has just completed
* @param policyIds The list of policyIds to which this snapshot belongs to
* @param backedUp If true, the snapshot has been successfully created.
*/
void postCreateSnapshot(long userId, long volumeId, long snapshotId, List<Long> policyIds, boolean backedUp);
SnapshotVO createSnapshotImpl(long volumeId, List<Long> policyIds) throws InvalidParameterValueException, ResourceAllocationException, InternalErrorException;
/**
* Creates a volume from the specified snapshot. A new volume is returned which is not attached to any VM Instance
*/
//VolumeVO createVolumeFromSnapshot(long userId, long accountId, long snapshotId, String volumeName);
long createVolumeFromSnapshotAsync(long userId, long accountId, long snapshotId, String volumeName) throws InternalErrorException;
/**
* Destroys the specified snapshot from secondary storage
*/
// long destroySnapshotAsync(long userId, long volumeId, long snapshotId, long policyId);
boolean destroySnapshot(long userId, long snapshotId, long policyId);
/**

View File

@ -48,6 +48,7 @@ import com.cloud.api.commands.DeleteSnapshotCmd;
import com.cloud.api.commands.DeleteSnapshotPoliciesCmd;
import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
import com.cloud.api.commands.ListSnapshotPoliciesCmd;
import com.cloud.async.AsyncInstanceCreateStatus;
import com.cloud.async.AsyncJobExecutor;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
@ -150,22 +151,6 @@ public class SnapshotManagerImpl implements SnapshotManager {
private final boolean _shouldBeSnapshotCapable = true; // all methods here should be snapshot capable.
@Override @DB
public long createSnapshotAsync(long userId, long volumeId, List<Long> policies) {
VolumeVO volume = _volsDao.findById(volumeId);
SnapshotOperationParam param = new SnapshotOperationParam(userId, volume.getAccountId(), volumeId, policies);
Gson gson = GsonHelper.getBuilder().create();
AsyncJobVO job = new AsyncJobVO();
job.setUserId(userId);
job.setAccountId(volume.getAccountId());
job.setCmd("CreateSnapshot");
job.setCmdInfo(gson.toJson(param));
job.setCmdOriginator(CreateSnapshotCmd.getResultObjectName());
return _asyncMgr.submitAsyncJob(job, true);
}
private boolean isVolumeDirty(long volumeId, List<Long> policies) {
VolumeVO volume = _volsDao.findById(volumeId);
boolean runSnap = true;
@ -276,8 +261,47 @@ public class SnapshotManagerImpl implements SnapshotManager {
return runSnap;
}
@Override
public SnapshotVO createSnapshotDB(CreateSnapshotCmd cmd) throws InvalidParameterValueException, ResourceAllocationException, InternalErrorException {
// FIXME: When a valid snapshot is returned, the snapshot must have been created on the storage server side so that the caller
// knows it is safe to once again resume normal operations on the volume in question.
Long volumeId = cmd.getVolumeId();
VolumeVO volume = _volsDao.findById(volumeId); // not null, precondition.
if (volume.getStatus() != AsyncInstanceCreateStatus.Created) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in Created state but " + volume.getStatus() + ". Cannot take snapshot.");
}
StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
if (storagePoolVO == null) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " does not have a valid storage pool. Is it destroyed?");
}
if (storagePoolVO.isLocal()) {
throw new InvalidParameterValueException("Cannot create a snapshot from a volume residing on a local storage pool, poolId: " + volume.getPoolId());
}
Long instanceId = volume.getInstanceId();
if (instanceId != null) {
// It is not detached, but attached to a VM
if (_vmDao.findById(instanceId) == null) {
// It is not a UserVM but a SystemVM or DomR
throw new InvalidParameterValueException("Snapshots of volumes attached to System or router VM are not allowed");
}
}
SnapshotScheduleVO schedule = _snapSchedMgr.scheduleManualSnapshot(volumeId);
if (schedule == null) {
throw new InternalErrorException("Snapshot could not be scheduled because there is another snapshot underway for the same volume. " +
"Please wait for some time.");
}
List<Long> policyIds = new ArrayList<Long>();
policyIds.add(Snapshot.MANUAL_POLICY_ID);
return createSnapshotImpl(volumeId, policyIds);
}
@Override @DB
public SnapshotVO createSnapshot(long userId, long volumeId, List<Long> policyIds) throws InvalidParameterValueException, ResourceAllocationException {
public SnapshotVO createSnapshotImpl(long volumeId, List<Long> policyIds) throws InvalidParameterValueException, ResourceAllocationException {
Long userId = UserContext.current().getUserId();
// Get the async job id from the context.
Long jobId = null;
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor();
@ -316,7 +340,7 @@ public class SnapshotManagerImpl implements SnapshotManager {
if (prevSnapshot.getRemoved() != null && snapshotStatus != Status.BackedUp) {
// The snapshot was deleted and it was deleted not manually but because backing up failed.
// Try to back it up again.
boolean backedUp = backupSnapshotToSecondaryStorage(userId, prevSnapshot);
boolean backedUp = backupSnapshotToSecondaryStorage(prevSnapshot);
if (!backedUp) {
// If we can't backup this snapshot, there's not much chance that we can't take another one and back it up again.
return null;
@ -398,6 +422,30 @@ public class SnapshotManagerImpl implements SnapshotManager {
return createdSnapshot;
}
@Override
public SnapshotVO createSnapshot(CreateSnapshotCmd cmd) throws InvalidParameterValueException, ResourceAllocationException, InternalErrorException {
SnapshotVO snapshot = _snapshotDao.findById(cmd.getId());
Long snapshotId = null;
boolean backedUp = false;
if (snapshot != null && snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) {
snapshotId = snapshot.getId();
backedUp = backupSnapshotToSecondaryStorage(snapshot);
if (!backedUp) {
throw new InternalErrorException("Created snapshot: " + snapshotId + " on primary but failed to backup on secondary");
}
}
// FIXME: this is for create snapshot through the API, which is a manual snapshot, is there a better way to keep track of policy ids? Like
// add them to the command?
List<Long> policyIds = new ArrayList<Long>();
policyIds.add(Snapshot.MANUAL_POLICY_ID);
// Cleanup jobs to do after the snapshot has been created.
postCreateSnapshot(cmd.getVolumeId(), snapshotId, policyIds, backedUp);
return snapshot;
}
private SnapshotVO updateDBOnCreate(Long id, String snapshotPath) {
SnapshotVO createdSnapshot = _snapshotDao.findById(id);
Long volumeId = createdSnapshot.getVolumeId();
@ -473,16 +521,16 @@ public class SnapshotManagerImpl implements SnapshotManager {
// It has entered backupSnapshotToSecondaryStorage.
// But we have no idea whether it was backed up or not.
// So call backupSnapshotToSecondaryStorage again.
backupSnapshotToSecondaryStorage(userId, snapshot);
backupSnapshotToSecondaryStorage(snapshot);
break;
case BackedUp:
// No need to do anything as snapshot has already been backed up.
}
}
@Override
@DB
public boolean backupSnapshotToSecondaryStorage(long userId, SnapshotVO snapshot) {
private boolean backupSnapshotToSecondaryStorage(SnapshotVO snapshot) {
Long userId = UserContext.current().getUserId();
long id = snapshot.getId();
snapshot.setStatus(Snapshot.Status.BackingUp);
@ -674,9 +722,9 @@ public class SnapshotManagerImpl implements SnapshotManager {
return backedUp;
}
@Override
@DB
public void postCreateSnapshot(long userId, long volumeId, long snapshotId, List<Long> policyIds, boolean backedUp) {
private void postCreateSnapshot(long volumeId, long snapshotId, List<Long> policyIds, boolean backedUp) {
Long userId = UserContext.current().getUserId();
// Update the snapshot_policy_ref table with the created snapshot
// Get the list of policies for this snapshot
Transaction txn = Transaction.currentTxn();

View File

@ -20,6 +20,7 @@ package com.cloud.storage.snapshot;
import java.util.Date;
import com.cloud.storage.SnapshotPolicyVO;
import com.cloud.storage.SnapshotScheduleVO;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.Scheduler;
@ -45,6 +46,5 @@ public interface SnapshotScheduler extends Manager, Scheduler {
*/
boolean removeSchedule(Long volumeId, Long policyId);
Long scheduleManualSnapshot(Long userId, Long volumeId);
SnapshotScheduleVO scheduleManualSnapshot(Long volumeId);
}

View File

@ -35,6 +35,9 @@ import com.cloud.async.AsyncJobResult;
import com.cloud.async.AsyncJobVO;
import com.cloud.async.dao.AsyncJobDao;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.InternalErrorException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotPolicyVO;
import com.cloud.storage.SnapshotScheduleVO;
@ -45,8 +48,8 @@ import com.cloud.storage.dao.SnapshotPolicyRefDao;
import com.cloud.storage.dao.SnapshotScheduleDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.DateUtil.IntervalType;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.concurrency.TestClock;
@ -199,7 +202,7 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
*/
@Override
@DB
public Long scheduleManualSnapshot(Long userId, Long volumeId) {
public SnapshotScheduleVO scheduleManualSnapshot(Long volumeId) {
// Check if there is another manual snapshot scheduled which hasn't been executed yet.
SearchCriteria<SnapshotScheduleVO> sc = _snapshotScheduleDao.createSearchCriteria();
sc.addAnd("volumeId", SearchCriteria.Op.EQ, volumeId);
@ -219,10 +222,14 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
// There is a race condition here. Two threads enter here.
// Both find that there are no manual snapshots for the same volume scheduled.
// Both try to schedule. One fails, which is what we wanted anyway.
_snapshotScheduleDao.persist(snapshotSchedule);
return _snapshotScheduleDao.persist(snapshotSchedule);
// do this for async?
/*
List<Long> policyIds = new ArrayList<Long>();
policyIds.add(Snapshot.MANUAL_POLICY_ID);
return _snapshotManager.createSnapshotAsync(userId, volumeId, policyIds);
*/
}
@DB
@ -233,10 +240,6 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
List<SnapshotScheduleVO> snapshotsToBeExecuted = _snapshotScheduleDao.getSchedulesToExecute(_currentTimestamp);
s_logger.debug("Got " + snapshotsToBeExecuted.size() + " snapshots to be executed at " + displayTime);
// This is done for recurring snapshots, which are executed by the system automatically
// Hence set user id to that of system
long userId = 1;
// The volumes which are going to be snapshotted now.
// The value contains the list of policies associated with this new snapshot.
// There can be more than one policy for a list if different policies coincide for the same volume.
@ -297,12 +300,22 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
txn.commit();
s_logger.debug("Scheduling 1 snapshot for volume " + volumeId + " for schedule ids: " + coincidentSchedules + " at " + displayTime);
long jobId = _snapshotManager.createSnapshotAsync(userId, volumeId, coincidingPolicies);
try {
_snapshotManager.createSnapshotImpl(volumeId, coincidingPolicies);
} catch (InternalErrorException ex) {
s_logger.warn("Internal error creating a recurring snapshot for volume " + volumeId + "; message: " + ex.getMessage());
// TODO: update the schedule w/ an error? error event?
} catch (ResourceAllocationException ex) {
s_logger.warn("Too many snapshots have been created for volume " + volumeId + "; message: " + ex.getMessage());
// TODO: update the schedule w/ an error? error event?
} catch (InvalidParameterValueException ex) {
s_logger.warn("Invalid parameter creating a snapshot for volume " + volumeId + "; message: " + ex.getMessage());
// TODO: update the schedule w/ an error? error event?
}
// Add this snapshot to the listOfVolumesSnapshotted
// So that the coinciding schedules don't get scheduled again.
listOfVolumesSnapshotted.put(volumeId, coincidingPolicies);
}
}
}