1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-30 22:50:10 +03:00

feature #3782: Re-design of revert operation. New action for drivers, and new state.

This commit is contained in:
Ruben S. Montero 2015-05-26 11:24:34 +02:00
parent 9bb5770f86
commit a5c04b47e6
16 changed files with 246 additions and 46 deletions

View File

@ -80,8 +80,10 @@ public:
/**
* Removes the snapshot from the list
* @param id of the snapshot
* @param error if any
* @return 0 on success -1 otherwise
*/
int delete_snapshot(unsigned int id);
int delete_snapshot(unsigned int id, string& error);
/**
* Set the given snapshot as active. Updates the values of the current

View File

@ -61,6 +61,7 @@ public:
DRIVER_CANCEL,
SAVEAS_HOT,
SNAPSHOT_CREATE,
SNAPSHOT_REVERT,
SNAPSHOT_DELETE,
FINALIZE
};
@ -328,11 +329,21 @@ private:
*/
void saveas_hot_action(int vid);
/**
* This function performs a generic snapshot action
*/
void do_snapshot_action(int vid, const char * action);
/**
* This function takes an snapshot of a disk
*/
void snapshot_create_action(int vid);
/**
* This function takes an snapshot of a disk
*/
void snapshot_revert_action(int vid);
/**
* This function deletes an snapshot of a disk
*/

View File

@ -156,7 +156,8 @@ public:
BOOT_STOPPED_FAILURE = 48,
PROLOG_RESUME_FAILURE = 49,
PROLOG_UNDEPLOY_FAILURE = 50,
DISK_SNAPSHOT_POWEROFF = 51
DISK_SNAPSHOT_POWEROFF = 51,
DISK_SNAPSHOT_REVERT_POWEROFF = 52
};
static int lcm_state_from_str(string& st, LcmState& state)
@ -213,6 +214,7 @@ public:
else if ( st == "PROLOG_RESUME_FAILURE") { state = PROLOG_RESUME_FAILURE; }
else if ( st == "PROLOG_UNDEPLOY_FAILURE") { state = PROLOG_UNDEPLOY_FAILURE; }
else if ( st == "DISK_SNAPSHOT_POWEROFF") { state = DISK_SNAPSHOT_POWEROFF; }
else if ( st == "DISK_SNAPSHOT_REVERT_POWEROFF") { state = DISK_SNAPSHOT_REVERT_POWEROFF; }
else {return -1;}
return 0;
@ -272,6 +274,7 @@ public:
case PROLOG_RESUME_FAILURE: st = "PROLOG_RESUME_FAILURE"; break;
case PROLOG_UNDEPLOY_FAILURE: st = "PROLOG_UNDEPLOY_FAILURE"; break;
case DISK_SNAPSHOT_POWEROFF: st = "DISK_SNAPSHOT_POWEROFF"; break;
case DISK_SNAPSHOT_REVERT_POWEROFF: st = "DISK_SNAPSHOT_REVERT_POWEROFF"; break;
}
return st;
@ -1522,21 +1525,37 @@ public:
*/
int revert_disk_snapshot(int disk_id, int snap_id, string& error);
/**
* Deletes the snap_id, the snapshot cannot be the current (active) one
* @param disk_id of the disk
* @param snap_id of the snapshot. It can be 0 to revert to the original
* disk
* @param error if any
* @return -1 if error
*/
int delete_disk_snapshot(int disk_id, int snap_id, string& error);
/**
* Get information about the disk to take the snapshot from
* @param ds_id id of the datastore
* @param tm_mad used by the datastore
* @param disk_id of the disk
* @param parent_id to take the snapshot from
* @param snap_id of the snapshot
*/
int get_snapshot_disk(string& ds_id, string& tm_mad,
string& disk_id, string& parent_id, string& snap_id);
int get_snapshot_disk(string& ds_id, string& tm_mad, string& disk_id,
string& snap_id);
/**
* Unset the current disk being snapshotted (reverted...)
*/
void clear_snapshot_disk();
/**
* Unset the current disk being snapshotted
* Set the disk as being snapshotted (reverted...)
* @param disk_id of the disk
* @param snap_id of the target snap_id
*/
void clear_snapshot_disk();
int set_snapshot_disk(int disk_id, int snap_id);
// ------------------------------------------------------------------------
// Snapshot related functions
// ------------------------------------------------------------------------

View File

@ -164,7 +164,8 @@
BOOT_STOPPED_FAILURE = 48,
PROLOG_RESUME_FAILURE = 49,
PROLOG_UNDEPLOY_FAILURE = 50,
DISK_SNAPSHOT_POWEROFF = 51
DISK_SNAPSHOT_POWEROFF = 51,
DISK_SNAPSHOT_REVERT_POWEROFF = 52
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="PREV_STATE" type="xs:integer"/>

View File

@ -97,7 +97,8 @@
BOOT_STOPPED_FAILURE = 48,
PROLOG_RESUME_FAILURE = 49,
PROLOG_UNDEPLOY_FAILURE = 50,
DISK_SNAPSHOT_POWEROFF = 51
DISK_SNAPSHOT_POWEROFF = 51,
DISK_SNAPSHOT_REVERT_POWEROFF = 52
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="PREV_STATE" type="xs:integer"/>

View File

@ -1643,9 +1643,6 @@ int DispatchManager::disk_snapshot_create(
return -1;
}
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_POWEROFF);
snap_id = vm->new_disk_snapshot(did, tag, error_str);
if (snap_id == -1)
@ -1654,6 +1651,9 @@ int DispatchManager::disk_snapshot_create(
return -1;
}
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_POWEROFF);
vm->unlock();
vmpool->update(vm);
@ -1700,15 +1700,20 @@ int DispatchManager::disk_snapshot_revert(
return -1;
}
if (vm->revert_disk_snapshot(did, snap_id, error_str) == -1)
if (vm->set_snapshot_disk(did, snap_id) == -1)
{
vm->unlock();
return -1;
}
vm->unlock();
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF);
vmpool->update(vm);
vm->unlock();
tm->trigger(TransferManager::SNAPSHOT_REVERT, vid);
return 0;
}

View File

@ -167,6 +167,7 @@ void DispatchManager::poweroff_success_action(int vid)
vm->get_lcm_state() == VirtualMachine::HOTPLUG_EPILOG_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF_FAILURE))
{
vm->set_state(VirtualMachine::POWEROFF);

View File

@ -969,6 +969,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
vm->clear_snapshot_disk();
vmpool->update(vm);
@ -1243,6 +1244,7 @@ void LifeCycleManager::recover(VirtualMachine * vm, bool success)
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
lcm_action = LifeCycleManager::DISK_SNAPSHOT_FAILURE;
break;
}
@ -1446,6 +1448,7 @@ void LifeCycleManager::retry(VirtualMachine * vm)
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
case VirtualMachine::HOTPLUG_EPILOG_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
case VirtualMachine::RUNNING:
case VirtualMachine::UNKNOWN:
break;

View File

@ -1721,13 +1721,40 @@ void LifeCycleManager::disk_snapshot_success(int vid)
if ( vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_POWEROFF )
{
vm->log("LCM", Log::INFO, "VM Disk snapshot successfully taken.");
vm->log("LCM", Log::INFO, "VM disk snapshot successfully taken.");
vm->clear_snapshot_disk();
vmpool->update(vm);
dm->trigger(DispatchManager::POWEROFF_SUCCESS,vid);
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
}
else if (vm->get_lcm_state()==VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF)
{
string disk_id, tm_mad, ds_id, snap_id, err;
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, snap_id) == -1)
{
vm->log("LCM", Log::INFO, "Active disk snapshot not found.");
}
else
{
int isnap_id = strtol(snap_id.c_str(),NULL,0);
int idisk_id = strtol(disk_id.c_str(),NULL,0);
if (vm->revert_disk_snapshot(idisk_id, isnap_id, err)==-1)
{
vm->log("LCM", Log::INFO, "Error activating snapshot: " + err);
}
}
vm->log("LCM", Log::INFO, "VM disk snapshot successfully reverted.");
vm->clear_snapshot_disk();
vmpool->update(vm);
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
}
else
{
@ -1742,4 +1769,59 @@ void LifeCycleManager::disk_snapshot_success(int vid)
void LifeCycleManager::disk_snapshot_failure(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_POWEROFF )
{
string disk_id, tm_mad, ds_id, snap_id, err;
vm->log("LCM",Log::ERROR,"Error taking disk snapshot");
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, snap_id) == -1)
{
vm->log("LCM", Log::INFO, "Active disk snapshot not found."
" Remove failed snapshot manually.");
}
else
{
int isnap_id = strtol(snap_id.c_str(),NULL,0);
int idisk_id = strtol(disk_id.c_str(),NULL,0);
if (vm->delete_disk_snapshot(idisk_id, isnap_id, err) == -1)
{
vm->log("LCM", Log::INFO, "Error deleting snapshot: " + err
+ " Remove failed snapshot manually.");
}
}
vm->clear_snapshot_disk();
vmpool->update(vm);
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
}
else if (vm->get_lcm_state()==VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF)
{
vm->log("LCM",Log::ERROR,"Could not revert to disk snapshot.");
vm->clear_snapshot_disk();
vmpool->update(vm);
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
}
else
{
vm->log("LCM",Log::ERROR,"disk_snapshot_success, VM in a wrong state.");
}
vm->unlock();
};

View File

@ -128,7 +128,8 @@ public class VirtualMachine extends PoolElement{
"BOOT_STOPPED_FAILURE",
"PROLOG_RESUME_FAILURE",
"PROLOG_UNDEPLOY_FAILURE",
"DISK_SNAPSHOT_POWEROFF"
"DISK_SNAPSHOT_POWEROFF",
"DISK_SNAPSHOT_REVERT_POWEROFF"
};
private static final String[] SHORT_LCM_STATES =
@ -184,7 +185,8 @@ public class VirtualMachine extends PoolElement{
"fail", // BOOT_STOPPED_FAILURE
"fail", // PROLOG_RESUME_FAILURE
"fail", // PROLOG_UNDEPLOY_FAILURE
"snap" // DISK_SNAPSHOT_POWEROFF
"snap", // DISK_SNAPSHOT_POWEROFF
"snap" // DISK_SNAPSHOT_REVERT_POWEROFF
};
/**

View File

@ -105,6 +105,7 @@ module OpenNebula
PROLOG_RESUME_FAILURE
PROLOG_UNDEPLOY_FAILURE
DISK_SNAPSHOT_POWEROFF
DISK_SNAPSHOT_REVERT_POWEROFF
}
SHORT_VM_STATES={
@ -171,7 +172,8 @@ module OpenNebula
"BOOT_STOPPED_FAILURE" => "fail",
"PROLOG_RESUME_FAILURE" => "fail",
"PROLOG_UNDEPLOY_FAILURE" => "fail",
"DISK_SNAPSHOT_POWEROFF" => "snap"
"DISK_SNAPSHOT_POWEROFF" => "snap",
"DISK_SNAPSHOT_REVERT_POWEROFF" => "snap"
}
MIGRATE_REASON=%w{NONE ERROR USER}

View File

@ -84,6 +84,7 @@ VNC_STATES = [
#49, #PROLOG_RESUME_FAILURE
#50, #PROLOG_UNDEPLOY_FAILURE
#51, #DISK_SNAPSHOT_POWEROFF
#52, #DISK_SNAPSHOT_REVERT_POWEROFF
]
class OpenNebulaVNC

View File

@ -143,6 +143,10 @@ void TransferManager::trigger(Actions action, int _vid)
aname = "SNAPSHOT_CREATE";
break;
case SNAPSHOT_REVERT:
aname = "SNAPSHOT_REVERT";
break;
case SNAPSHOT_DELETE:
aname = "SNAPSHOT_DELETE";
break;
@ -390,6 +394,10 @@ void TransferManager::do_action(const string &action, void * arg)
{
snapshot_create_action(vid);
}
else if (action == "SNAPSHOT_REVERT")
{
snapshot_revert_action(vid);
}
else if (action == "SNAPSHOT_DELETE")
{
snapshot_delete_action(vid);
@ -2209,7 +2217,7 @@ void TransferManager::migrate_transfer_command(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::snapshot_create_action(int vid)
void TransferManager::do_snapshot_action(int vid, const char * snap_action)
{
string tm_mad;
string ds_id;
@ -2226,6 +2234,8 @@ void TransferManager::snapshot_create_action(int vid)
const TransferManagerDriver * tm_md;
Nebula& nd = Nebula::instance();
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
@ -2243,7 +2253,7 @@ void TransferManager::snapshot_create_action(int vid)
goto error_common;
}
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, parent_id, snap_id) == -1)
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, snap_id) == -1)
{
vm->log("TM", Log::ERROR, "Could not get disk information to"
"take snapshot");
@ -2265,12 +2275,11 @@ void TransferManager::snapshot_create_action(int vid)
goto error_file;
}
//SNAP_CREATE tm_mad host:remote_system_dir/disk.0 parentid snapid vmid dsid
xfr << "SNAP_CREATE "
//SNAP_CREATE tm_mad host:remote_system_dir/disk.0 snapid vmid dsid
xfr << snap_action << " "
<< tm_mad << " "
<< vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << disk_id << " "
<< parent_id << " "
<< snap_id << " "
<< vm->get_oid() << " "
<< ds_id
@ -2290,22 +2299,31 @@ error_driver:
error_file:
os << "disk_snapshot_create, could not open file: " << xfr_name;
os << ". You may need to manually clean hosts (previous & current)";
goto error_common;
error_common:
vm->log("TM", Log::ERROR, os);
//TODO (nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_HOT_FAILURE, vid);
(nd.get_lcm())->trigger(LifeCycleManager::DISK_SNAPSHOT_FAILURE, vid);
vm->unlock();
return;
}
void TransferManager::snapshot_create_action(int vid)
{
return do_snapshot_action(vid, "SNAP_CREATE");
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::snapshot_revert_action(int vid)
{
return do_snapshot_action(vid, "SNAP_REVERT");
};
void TransferManager::snapshot_delete_action(int vid){};
void TransferManager::snapshot_delete_action(int vid)
{
return do_snapshot_action(vid, "SNAP_DELETE");
};
/* ************************************************************************** */
/* MAD Loading */

View File

@ -148,6 +148,7 @@ void TransferManagerDriver::protocol(const string& message) const
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
lcm_action = LifeCycleManager::DISK_SNAPSHOT_SUCCESS;
break;
@ -207,6 +208,7 @@ void TransferManagerDriver::protocol(const string& message) const
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
lcm_action = LifeCycleManager::DISK_SNAPSHOT_FAILURE;
break;

View File

@ -18,8 +18,8 @@
Snapshots::Snapshots(int _disk_id):
snapshot_template(false,'=',"SNAPSHOTS"),
next_snapshot(1),
active(0),
next_snapshot(0),
active(-1),
disk_id(_disk_id)
{
snapshot_template.add("DISK_ID",_disk_id);
@ -104,12 +104,13 @@ int Snapshots::create_snapshot(const string& tag)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Snapshots::delete_snapshot(unsigned int id)
int Snapshots::delete_snapshot(unsigned int id, string& error)
{
VectorAttribute * snapshot = get_snapshot(id);
if (snapshot == 0)
{
error = "Snapshot does not exists";
return -1;
}
@ -119,6 +120,7 @@ int Snapshots::delete_snapshot(unsigned int id)
if (current)
{
error = "Cannot delete the active snapshot";
return -1;
}

View File

@ -4164,6 +4164,25 @@ int VirtualMachine::get_public_cloud_hypervisors(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_snapshot_disk(int did, int snap_id)
{
VectorAttribute * disk;
disk = get_disk(did);
if ( disk == 0 )
{
return -1;
}
disk->replace("DISK_SNAPSHOT_ACTIVE", "YES");
disk->replace("DISK_SNAPSHOT_ID", snap_id);
return 0;
}
/* -------------------------------------------------------------------------- */
void VirtualMachine::clear_snapshot_disk()
{
int num_disks;
@ -4193,7 +4212,7 @@ void VirtualMachine::clear_snapshot_disk()
/* -------------------------------------------------------------------------- */
int VirtualMachine::get_snapshot_disk(string& ds_id, string& tm_mad,
string& disk_id, string& parent_id, string& snap_id)
string& disk_id, string& snap_id)
{
vector<Attribute *> disks;
VectorAttribute * disk;
@ -4228,17 +4247,12 @@ int VirtualMachine::get_snapshot_disk(string& ds_id, string& tm_mad,
return -1;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk_id = disk->vector_value("DISK_ID");
snap_id = disk->vector_value("DISK_SNAPSHOT_ID");
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
disk_id = disk->vector_value("DISK_ID");
snap_id = disk->vector_value("DISK_SNAPSHOT_ID");
int isnap_id = strtol(snap_id.c_str(),NULL,0);
parent_id =it->second->get_snapshot_attribute(isnap_id,"PARENT_ID");
if (parent_id.empty() || snap_id.empty() || tm_mad.empty()
|| ds_id.empty() || disk_id.empty())
if (snap_id.empty()||tm_mad.empty()||ds_id.empty()||disk_id.empty())
{
return -1;
}
@ -4268,7 +4282,6 @@ int VirtualMachine::new_disk_snapshot(int did, const string& tag, string& error)
return -1;
}
it = snapshots.find(did);
if ( it == snapshots.end() )
@ -4311,15 +4324,50 @@ int VirtualMachine::revert_disk_snapshot(int did, int snap_id, string& error)
it = snapshots.find(did);
if ( it == snapshots.end() && snap_id != 0 )
if (it == snapshots.end())
{
error = "Snapshot does not exists";
return -1;
}
else if ( it != snapshots.end() )
else
{
rc = it->second->active_snapshot(snap_id, error);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::delete_disk_snapshot(int did, int snap_id, string& error)
{
map<int, Snapshots *>::iterator it;
int rc;
VectorAttribute * disk;
string source;
disk = get_disk(did);
if ( disk == 0 )
{
error = "DISK does not exists";
return -1;
}
it = snapshots.find(did);
if (it == snapshots.end())
{
error = "Snapshot does not exists";
return -1;
}
else
{
rc = it->second->delete_snapshot(snap_id, error);
}
return rc;
}