1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

feature #3782: Generate snapshot files for TransferManager

This commit is contained in:
Ruben S. Montero 2015-05-20 17:48:27 +02:00
parent 986cf14c6b
commit 20fac744a7
7 changed files with 233 additions and 7 deletions

View File

@ -98,6 +98,15 @@ public:
return disk_id;
}
/**
* Get Attribute from the given snapshot
* @param id of the snapshot
* @param name of the attribute
*
* @return value or empty if not found
*/
string get_snapshot_attribute(unsigned int id, const char* name);
private:
/**

View File

@ -60,6 +60,8 @@ public:
CHECKPOINT,
DRIVER_CANCEL,
SAVEAS_HOT,
SNAPSHOT_CREATE,
SNAPSHOT_DELETE,
FINALIZE
};
@ -325,6 +327,16 @@ private:
* This function starts the saveas of the given disk
*/
void saveas_hot_action(int vid);
/**
* This function takes an snapshot of a disk
*/
void snapshot_create_action(int vid);
/**
* This function deletes an snapshot of a disk
*/
void snapshot_delete_action(int vid);
};
#endif /*TRANSFER_MANAGER_H*/

View File

@ -1522,6 +1522,16 @@ public:
*/
int revert_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 parent to take the snapshot from
* @param snap_id of the snapshot
*/
int get_snapshot_disk(string& ds_id, string& tm_mad, string& parent,
string& snap_id);
// ------------------------------------------------------------------------
// Snapshot related functions
// ------------------------------------------------------------------------

View File

@ -1643,8 +1643,8 @@ int DispatchManager::disk_snapshot_create(
return -1;
}
//TODO set state (reuse HOTPLUG_SNAPSHOT?)
//vm->set_state(VirtualMachine::HOTPLUG_SNAPSHOT);
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_POWEROFF);
snap_id = vm->new_disk_snapshot(did, tag, error_str);
@ -1658,8 +1658,7 @@ int DispatchManager::disk_snapshot_create(
vmpool->update(vm);
//TODO Trigger snapshot action on the TM
//vmm->trigger(VirtualMachineManager::SNAPSHOT_CREATE,vid);
tm->trigger(TransferManager::SNAPSHOT_CREATE,vid);
return 0;
}
@ -1702,8 +1701,8 @@ int DispatchManager::disk_snapshot_revert(
return -1;
}
//TODO set state (reuse HOTPLUG_SNAPSHOT?)
//vm->set_state(VirtualMachine::HOTPLUG_SNAPSHOT);
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_POWEROFF);
if (vm->revert_disk_snapshot(did, snap_id, error_str) == -1)
{

View File

@ -139,6 +139,14 @@ void TransferManager::trigger(Actions action, int _vid)
aname = "DRIVER_CANCEL";
break;
case SNAPSHOT_CREATE:
aname = "SNAPSHOT_CREATE";
break;
case SNAPSHOT_DELETE:
aname = "SNAPSHOT_DELETE";
break;
case FINALIZE:
aname = ACTION_FINALIZE;
break;
@ -378,6 +386,14 @@ void TransferManager::do_action(const string &action, void * arg)
{
driver_cancel_action(vid);
}
else if (action == "SNAPSHOT_CREATE")
{
snapshot_create_action(vid);
}
else if (action == "SNAPSHOT_DELETE")
{
snapshot_delete_action(vid);
}
else
{
ostringstream oss;
@ -2082,7 +2098,7 @@ void TransferManager::saveas_hot_action(int vid)
if (vm->get_saveas_disk_hot(disk_id, save_source, image_id) == -1)
{
vm->log("TM", Log::ERROR, "Could not get disk information to saveas it");
vm->log("TM", Log::ERROR,"Could not get disk information to saveas it");
goto error_common;
}
@ -2190,6 +2206,105 @@ void TransferManager::migrate_transfer_command(
<< endl;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::snapshot_create_action(int vid)
{
string tm_mad;
string ds_id;
string parent;
string snap_id;
ostringstream os;
ofstream xfr;
string xfr_name;
VirtualMachine * vm;
const TransferManagerDriver * tm_md;
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
vm = vmpool->get(vid,true);
if (vm == 0)
{
vm->log("TM", Log::ERROR, "Could not obtain the VM");
goto error_common;
}
if (!vm->hasHistory())
{
vm->log("TM", Log::ERROR, "The VM has no history");
goto error_common;
}
if (vm->get_snapshot_disk(ds_id, tm_mad, parent, snap_id) == -1)
{
vm->log("TM", Log::ERROR, "Could not get disk information to"
"take snapshot");
goto error_common;
}
tm_md = get();
if (tm_md == 0)
{
goto error_driver;
}
xfr_name = vm->get_transfer_file() + ".disk_snapshot";
xfr.open(xfr_name.c_str(),ios::out | ios::trunc);
if (xfr.fail() == true)
{
goto error_file;
}
//SNAP_CREATE tm_mad hostname:parent_path vmid dsid
xfr << "SNAP_CREATE "
<< tm_mad << " "
<< vm->get_hostname() << ":"
<< parent << " "
<< snap_id << " "
<< vm->get_oid() << " "
<< ds_id
<< endl;
xfr.close();
tm_md->transfer(vid, xfr_name);
vm->unlock();
return;
error_driver:
os << "saveas_hot_transfer, error getting TM driver.";
goto error_common;
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);
vm->unlock();
return;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::snapshot_delete_action(int vid){};
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

View File

@ -202,3 +202,21 @@ VectorAttribute * Snapshots::get_snapshot(unsigned int id)
return it->second;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Snapshots::get_snapshot_attribute(unsigned int id, const char * name)
{
VectorAttribute * snapshot = get_snapshot(id);
if (snapshot == 0)
{
return "";
}
return snapshot->vector_value(name);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -4161,6 +4161,66 @@ int VirtualMachine::get_public_cloud_hypervisors(
return public_cloud_hypervisors.size();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
//TODO SNAPSHOT clear_snapshot_disk (deletes)
int VirtualMachine::get_snapshot_disk(string& ds_id, string& tm_mad,
string& parent, string& snap_id)
{
vector<Attribute *> disks;
VectorAttribute * disk;
int num_disks;
num_disks = obj_template->get("DISK", disks);
for(int i=0; i<num_disks; i++)
{
disk = dynamic_cast<VectorAttribute * >(disks[i]);
if ( disk == 0 )
{
continue;
}
if ( disk->vector_value("DISK_SNAPSHOT_ACTIVE") == "YES" )
{
map<int, Snapshots *>::iterator it;
int did;
if (disk->vector_value("DISK_ID", did) == -1)
{
return -1;
}
it = snapshots.find(did);
if (it == snapshots.end())
{
return -1;
}
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
snap_id = disk->vector_value("DISK_SNAPSHOT_ID");
int isnap_id = strtol(snap_id.c_str(),NULL,0);
parent = it->second->get_snapshot_attribute(isnap_id, "PARENT");
if (parent.empty() || snap_id.empty() || tm_mad.empty()
|| ds_id.empty())
{
return -1;
}
return 0;
}
}
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -4197,6 +4257,9 @@ int VirtualMachine::new_disk_snapshot(int did, const string& tag, string& error)
snap_id = it->second->create_snapshot(source, tag);
}
disk->replace("DISK_SNAPSHOT_ACTIVE", "YES");
disk->replace("DISK_SNAPSHOT_ID", snap_id);
return snap_id;
}