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

feature #1112: Save_as functionality

This commit is contained in:
Ruben S. Montero 2012-03-05 23:49:18 +01:00
parent 950ef37b69
commit 92dd8d4c5e
12 changed files with 430 additions and 343 deletions

View File

@ -39,6 +39,22 @@ public:
DATABLOCK = 2 /** < User persistent data device */
};
/**
* Return the string representation of an ImageType
* @param ob the type
* @return the string
*/
static string type_to_str(ImageType ob)
{
switch (ob)
{
case OS: return "OS" ; break;
case CDROM: return "CDROM" ; break;
case DATABLOCK: return "DATABLOCK" ; break;
default: return "";
}
};
/**
* Image State
*/
@ -199,6 +215,17 @@ public:
return (group_u == 1 || other_u == 1);
}
/**
* Check if the image is used for saving_as a current one
* @return true if the image will be used to save an existing image.
*/
bool isSaving()
{
ImageTemplate * it = static_cast<ImageTemplate *>(obj_template);
return it->is_saving();
}
/**
* Set permissions for the Image. Extends the PoolSQLObject method
* by checking the persistent state of the image.
@ -291,7 +318,7 @@ public:
/**
* Factory method for image templates
*/
Template * get_new_template()
Template * get_new_template() const
{
return new ImageTemplate;
}
@ -299,11 +326,19 @@ public:
/**
* Returns the Datastore ID
*/
int get_ds_id()
int get_ds_id() const
{
return ds_id;
};
/**
* Returns the Datastore ID
*/
const string& get_ds_name() const
{
return ds_name;
};
private:
// -------------------------------------------------------------------------

View File

@ -99,14 +99,8 @@ public:
/**
* Releases an image and triggers any needed operations in the repo
* @param iid image id of the image to be released
* @param disk_path base path for disk location
* @param disk number for this image in the VM
* @param saveid id of image to save the current image
*/
void release_image(const string& iid,
const string& disk_path,
int disk_num,
const string& saveid)
void release_image(const string& iid)
{
int image_id;
istringstream iss;
@ -114,30 +108,14 @@ public:
iss.str(iid);
iss >> image_id;
release_image(image_id, disk_path, disk_num, saveid);
release_image(image_id);
};
/**
* Releases an image and triggers any needed operations in the repo
* @param iid image id of the image to be released
* @param disk_path base path for disk location
* @param disk number for this image in the VM
* @param saveid id of image to save the current image
*/
void release_image(int iid,
const string& disk_path,
int disk_num,
const string& saveid);
/**
* Moves a VM disk to the Image Repository
* @param disk_path base path for disk location
* @param disk number for this image in the VM
* @param saveid id of image to save the current image
*/
void disk_to_image(const string& disk_path,
int disk_num,
const string& save_id);
void release_image(int iid);
/**
* Enables the image
@ -205,9 +183,7 @@ private:
* @param action the name of the action
* @param arg arguments for the action function
*/
void do_action(
const string & action,
void * arg);
void do_action(const string& action, void * arg);
/**
* Acquires an image updating its state.
@ -230,9 +206,7 @@ private:
* @param ds_data Datastore XML representation
* @return the XML message
*/
string * format_message(
const string& img_data,
const string& ds_data);
string * format_message(const string& img_data, const string& ds_data);
};
#endif /*IMAGE_MANAGER_H*/

View File

@ -41,11 +41,36 @@ public:
return Template::check(rs_attr, restricted_attributes);
};
bool is_saving()
{
string saving;
get(saving_attribute, saving);
return (saving.empty() == false);
}
void set_saving()
{
SingleAttribute * attr= new SingleAttribute(saving_attribute, "YES");
erase(saving_attribute);
set(attr);
}
void unset_saving()
{
erase(saving_attribute);
}
private:
friend class ImagePool;
static vector<string> restricted_attributes;
static string saving_attribute;
/**
* Stores the attributes as restricted, these attributes will be used in
* ImageTemplate::check

View File

@ -48,8 +48,11 @@ protected:
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att) = 0;
bool vm_authorization(int id, ImageTemplate *tmpl,
RequestAttributes& att, PoolObjectAuth* host_perms);
bool vm_authorization(int id,
ImageTemplate * tmpl,
RequestAttributes& att,
PoolObjectAuth * host_perms,
PoolObjectAuth * ds_perm);
int get_host_information(int hid, string& name, string& vmm, string& vnm,
RequestAttributes& att, PoolObjectAuth& host_perms);

View File

@ -653,15 +653,27 @@ public:
int generate_context(string &files);
// ------------------------------------------------------------------------
// Image repository related functions
// Datastore related functions
// ------------------------------------------------------------------------
/**
* Set the SAVE_AS attribute for the "disk_id"th disk.
* @param disk_id Index of the disk to save
* @param img_id ID of the image this disk will be saved to.
* @param source to save the disk (SAVE_AS_SOURCE)
* @param img_id ID of the image this disk will be saved to (SAVE_AS).
* @return 0 if success
*/
int save_disk(int disk_id, int img_id, string& error_str);
int save_disk(const string& disk_id,
const string& source,
int img_id);
/**
* Get the original image id of the disk. It also checks that the disk can
* be saved_as.
* @param disk_id Index of the disk to save
* @param error_str describes the error
* @return -1 if failure
*/
int get_image_from_disk(int disk_id, string& error_str);
// ------------------------------------------------------------------------
// Authorization related functions

View File

@ -96,6 +96,7 @@ int Image::insert(SqlDB *db, string& error_str)
string dev_prefix;
string source_attr;
string aname;
string saved_id;
ostringstream oss;
@ -159,34 +160,36 @@ int Image::insert(SqlDB *db, string& error_str)
erase_template_attribute("PATH", path);
erase_template_attribute("SOURCE", source);
// The template should contain PATH or SOURCE
if ( source.empty() && path.empty() )
if (!isSaving()) //Not a saving image
{
string size_attr;
istringstream iss;
erase_template_attribute("SIZE", size_attr);
erase_template_attribute("FSTYPE", fs_type);
// DATABLOCK image needs SIZE and FSTYPE
if (type != DATABLOCK || size_attr.empty() || fs_type.empty())
if ( source.empty() && path.empty() )
{
goto error_no_path;
string size_attr;
istringstream iss;
erase_template_attribute("SIZE", size_attr);
erase_template_attribute("FSTYPE", fs_type);
// DATABLOCK image needs SIZE and FSTYPE
if (type != DATABLOCK || size_attr.empty() || fs_type.empty())
{
goto error_no_path;
}
iss.str(size_attr);
iss >> size_mb;
if (iss.fail() == true)
{
goto error_size_format;
}
}
iss.str(size_attr);
iss >> size_mb;
if (iss.fail() == true)
else if ( !source.empty() && !path.empty() )
{
goto error_size_format;
goto error_path_and_source;
}
}
else if ( !source.empty() && !path.empty() )
{
goto error_path_and_source;
}
state = LOCKED; //LOCKED till the ImageManager copies it to the Repository

View File

@ -128,84 +128,14 @@ int ImageManager::acquire_image(Image *img, string& error)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void ImageManager::move_image(Image *img, const string& source)
{
const ImageManagerDriver* imd = get();
ostringstream oss;
if ( imd == 0 )
{
NebulaLog::log("ImM",Log::ERROR,
"Could not get driver to update repository");
return;
}
oss << "Moving disk " << source << " to repository image "
<< img->get_oid();
imd->mv(img->get_oid(),source,img->get_source());
NebulaLog::log("ImM",Log::INFO,oss);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void ImageManager::disk_to_image(const string& disk_path,
int disk_num,
const string& save_id)
{
int sid;
istringstream iss;
Image * img;
ostringstream disk_file;
iss.str(save_id);
iss >> sid;
img = ipool->get(sid,true);
if ( img == 0 )
{
NebulaLog::log("ImM",Log::ERROR,"Could not get image to saveas disk.");
}
else
{
disk_file << disk_path << "/disk." << disk_num;
move_image(img,disk_file.str());
}
img->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void ImageManager::release_image(int iid,
const string& disk_path,
int disk_num,
const string& save_id)
void ImageManager::release_image(int iid)
{
int rvms;
int sid = -1;
istringstream iss;
Image * img;
Image * img;
ostringstream disk_file;
if ( save_id.empty() == false )
{
iss.str(save_id);
iss >> sid;
}
img = ipool->get(iid,true);
if ( img == 0 )
@ -218,48 +148,14 @@ void ImageManager::release_image(int iid,
case Image::USED:
rvms = img->dec_running();
if ( img->isPersistent() && !disk_path.empty() )
if ( img->isPersistent() || rvms == 0 )
{
disk_file << disk_path << "/disk." << disk_num;
img->set_state(Image::LOCKED);
move_image(img,disk_file.str());
img->set_state(Image::READY);
ipool->update(img);
img->unlock();
}
else
{
if ( rvms == 0)
{
img->set_state(Image::READY);
}
ipool->update(img);
img->unlock();
if ( sid != -1 )
{
img = ipool->get(sid,true);
if ( img == 0 )
{
NebulaLog::log("ImM",Log::ERROR,
"Could not get image to saveas disk.");
}
else
{
disk_file << disk_path << "/disk." << disk_num;
move_image(img,disk_file.str());
}
img->unlock();
}
}
break;
case Image::DISABLED:
@ -372,8 +268,7 @@ int ImageManager::delete_image(int iid, const string& ds_data)
}
drv_msg = format_message(img->to_xml(img_tmpl), ds_data);
source = img->get_source();
source = img->get_source();
if (source.empty())
{
@ -431,30 +326,25 @@ int ImageManager::register_image(int iid, const string& ds_data)
drv_msg = format_message(img->to_xml(img_tmpl), ds_data);
path = img->get_path();
if ( path.empty() == true ) //NO PATH -> USE SOURCE OR MKFS FOR DATABLOCK
if ( path.empty() == true ) //NO PATH
{
if ( img->get_type() == Image::DATABLOCK)
{
string fs = img->get_fstype();
int size = img->get_size();
string source = img->get_source();
if ( img->isSaving() || img->get_type() == Image::DATABLOCK )
{
imd->mkfs(img->get_oid(), *drv_msg);
oss << "Creating disk at " << img->get_source() << " of "
<< size << "Mb with format " << fs;
oss << "Creating disk at " << source
<< " of "<< img->get_size()
<< "Mb (type: " << img->get_fstype() << ")";
}
else
else if ( !source.empty() ) //Source in Template
{
string source = img->get_source();
img->set_state(Image::READY);
ipool->update(img);
if (source != "-") //SAVE_AS IMAGE DO NOT ENABLE THE IMAGE
{
img->set_state(Image::READY);
ipool->update(img);
oss << "Using source " << img->get_source()
<< " from template for image " << img->get_name();
}
oss << "Using source " << source
<< " from template for image " << img->get_name();
}
}
else //PATH -> COPY TO REPOSITORY AS SOURCE

View File

@ -179,40 +179,69 @@ void ImageManagerDriver::protocol(
goto error_cp;
}
}
else if ( action == "MV" )
{
if ( result == "SUCCESS" )
{
if (image->get_source() == "-")
{
image->set_source(source);
}
image->set_size(size_mb);
image->set_state(Image::READY);
ipool->update(image);
NebulaLog::log("ImM", Log::INFO, "Image saved and ready to use.");
}
else
{
goto error_mv;
}
}
else if ( action == "MKFS" )
{
if ( result == "SUCCESS" )
{
image->set_source(source);
image->set_size(size_mb);
bool is_saving = image->isSaving();
image->set_state(Image::READY);
string disk_id;
string vm_id;
int rc;
image->set_source(source);
if (is_saving)
{
image->get_template_attribute("SAVED_DISK_ID",disk_id);
image->get_template_attribute("SAVED_VM_ID", vm_id);
}
else
{
image->set_size(size_mb);
image->set_state(Image::READY);
NebulaLog::log("ImM", Log::INFO,
"Image created and ready to use");
}
ipool->update(image);
NebulaLog::log("ImM", Log::INFO, "Image created and ready to use");
image->unlock();
if (is_saving)
{
Nebula& nd = Nebula::instance();
VirtualMachinePool * vmpool = nd.get_vmpool();
VirtualMachine * vm;
istringstream iss(vm_id);
int vm_id_i;
iss >> vm_id_i;
vm = vmpool->get(vm_id_i, true);
if ( vm == 0 )
{
goto error_save_no_vm;
}
rc = vm->save_disk(disk_id, source, id);
if ( rc == -1 )
{
vm->unlock();
goto error_save_state_vm;
}
vm->unlock();
}
return;
}
else
{
@ -255,11 +284,6 @@ error_cp:
os << "Error copying image in the repository";
goto error_common;
error_mv:
os.str("");
os << "Error saving image to the repository";
goto error_common;
error_mkfs:
os.str("");
os << "Error creating datablock";
@ -280,9 +304,28 @@ error_rm:
}
NebulaLog::log("ImM", Log::ERROR, os);
return;
error_save_no_vm:
os.str("");
os << "Image created for SAVE_AS, but the associated VM does not exist.";
goto error_save_common;
error_save_state_vm:
os.str("");
os << "Image created for SAVE_AS, but VM is no longer running";
goto error_save_common;
error_save_common:
image = ipool->get(id, true);
if (image == 0 )
{
return;
}
error_common:
getline(is,info);

View File

@ -21,5 +21,7 @@
vector<string> ImageTemplate::restricted_attributes;
string ImageTemplate::saving_attribute = "SAVE_AS";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -24,7 +24,8 @@
bool RequestManagerVirtualMachine::vm_authorization(int oid,
ImageTemplate * tmpl,
RequestAttributes& att,
PoolObjectAuth * host_perm)
PoolObjectAuth * host_perm,
PoolObjectAuth * ds_perm)
{
PoolObjectSQL * object;
PoolObjectAuth vm_perms;
@ -57,13 +58,19 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid,
{
ar.add_auth(AuthRequest::MANAGE, *host_perm);
}
else if (tmpl != 0)
if (tmpl != 0)
{
string t_xml;
ar.add_create_auth(PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml));
}
if ( ds_perm != 0 )
{
ar.add_auth(AuthRequest::USE, *ds_perm);
}
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
@ -177,7 +184,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
if ( vm_authorization(id,0,att,0) == false )
if ( vm_authorization(id, 0, att, 0, 0) == false )
{
return;
}
@ -282,7 +289,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
auth = vm_authorization(id,0,att,&host_perms);
auth = vm_authorization(id, 0, att, &host_perms, 0);
if ( auth == false )
{
@ -344,7 +351,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
auth = vm_authorization(id,0,att,&host_perms);
auth = vm_authorization(id, 0, att, &host_perms, 0);
if ( auth == false )
{
@ -394,8 +401,10 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
ImagePool * ipool = nd.get_ipool();
Nebula& nd = Nebula::instance();
ImagePool * ipool = nd.get_ipool();
DatastorePool * dspool = nd.get_dspool();
int id = xmlrpc_c::value_int(paramList.getInt(1));
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
@ -403,24 +412,100 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
string img_type = xmlrpc_c::value_string(paramList.getString(4));
VirtualMachine * vm;
string vm_owner;
int iid;
ImageTemplate * itemplate;
int iid_orig;
Image * img;
Datastore * ds;
int rc;
ostringstream oss;
string error_str;
// ------------------ Template for the new image ------------------
// -------------------------------------------------------------------------
// Prepare and check the VM/DISK to be saved_as
// -------------------------------------------------------------------------
if ( (vm = get_vm(id, att)) == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::VM), id),
att);
return;
}
oss << "NAME= \"" << img_name << "\"" << endl;
oss << "PUBLIC = NO " << endl;
oss << "SOURCE = - " << endl;
oss << "SAVED_DISK_ID = " << disk_id << endl;
oss << "SAVED_VM_ID = " << id << endl;
iid_orig = vm->get_image_from_disk(disk_id, error_str);
if ( img_type != "" )
pool->update(vm);
vm->unlock();
if ( iid_orig == -1 )
{
failure_response(INTERNAL,
request_error("Can not used selected DISK", error_str),
att);
return;
}
// -------------------------------------------------------------------------
// Get the data of the Image to be saved
// -------------------------------------------------------------------------
if ( (img = ipool->get(iid_orig, true)) != 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::IMAGE), iid_orig),
att);
return;
}
int ds_id = img->get_ds_id();
string ds_name = img->get_ds_name();
int size = img->get_size();
Image::ImageType type = img->get_type();
img->unlock();
if ((ds = dspool->get(ds_id, true)) == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
att);
return;
}
// -------------------------------------------------------------------------
// Get the data of the DataStore for the new image
// -------------------------------------------------------------------------
string ds_data;
PoolObjectAuth ds_perms;
ds->get_permissions(ds_perms);
ds->to_xml(ds_data);
ds->unlock();
// -------------------------------------------------------------------------
// Create a template for the new Image
// -------------------------------------------------------------------------
ImageTemplate * itemplate;
ostringstream oss;
oss << "NAME = \"" << img_name << "\"" << endl;
oss << "PUBLIC = NO" << endl;
oss << "SIZE = " << size << endl;
oss << "FS_TYPE = save_as" << endl;
oss << "SAVED_IMAGE_ID = " << iid_orig << endl;
oss << "SAVED_DISK_ID = " << disk_id << endl;
oss << "SAVED_VM_ID = " << id << endl;
if ( img_type.empty() )
{
oss << "TYPE = " << Image::type_to_str(type) << endl;
}
else
{
oss << "TYPE = " << img_type << endl;
}
@ -429,24 +514,32 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
itemplate->parse_str_or_xml(oss.str(), error_str);
// ------------------ Authorize the operation ------------------
itemplate->set_saving();
if ( vm_authorization(id,itemplate,att,0) == false )
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, itemplate, att, 0, &ds_perms) == false )
{
delete itemplate;
return;
}
// ------------------ Create the image ------------------
// TODO: get values from source image DS
int ds_id = 0;
string ds_name = "";
string ds_data = "";
rc = ipool->allocate(att.uid, att.gid, att.uname, att.gname, itemplate,
ds_id, ds_name, ds_data, &iid, error_str);
// -------------------------------------------------------------------------
// Create the image
// -------------------------------------------------------------------------
rc = ipool->allocate(att.uid,
att.gid,
att.uname,
att.gname,
itemplate,
ds_id,
ds_name,
ds_data,
&iid,
error_str);
if (rc < 0)
{
failure_response(INTERNAL,
@ -454,50 +547,6 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
return;
}
// ------------------ Store image id to save the disk ------------------
if ( (vm = get_vm(id, att)) == 0 )
{
Image * img;
if ( (img = ipool->get(iid,true)) != 0 )
{
string tmp_error;
ipool->drop(img, tmp_error);
img->unlock();
}
return;
}
rc = vm->save_disk(disk_id, iid, error_str);
if ( rc == 0 )
{
pool->update(vm);
}
vm->unlock();
if ( rc == -1 )
{
Image * img;
if ( (img = ipool->get(iid,true)) != 0 )
{
string tmp_error;
ipool->drop(img, tmp_error);
img->unlock();
}
failure_response(INTERNAL,
request_error("Can not save_as disk",error_str),
att);
return;
}
// Return the new allocated Image ID
success_response(iid, att);
}

View File

@ -790,26 +790,23 @@ void TransferManager::epilog_action(int vid)
tm_mad = disk->vector_value("TM_MAD");
if ( save == "YES" )
if ( save == "YES" ) //TODO SAVE_SOURCE
{
ostringstream tsource;
string source;
string save_source;
source = disk->vector_value("SOURCE");
source = disk->vector_value("SOURCE");
save_source = disk->vector_value("SAVE_AS_SOURCE");
if ( source.empty() )
if ( source.empty() && save_source.empty() )
{
vm->log("TM", Log::ERROR, "No SOURCE to save disk image");
continue;
}
if ( source.find(":") == string::npos ) //Regular file
if (!save_source.empty()) //Use the save as source instead
{
tsource << nd.get_nebula_hostname() << ":" << source << " ";
}
else //TM Plugin specific protocol
{
tsource << source << " ";
source = save_source;
}
//MVDS tm_mad hostname:remote_system_dir/disk.0 <fe:SOURCE|SOURCE>
@ -817,7 +814,7 @@ void TransferManager::epilog_action(int vid)
<< tm_mad << " "
<< vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << i << " "
<< tsource.str() << endl;
<< source << endl;
}
else if ( !tm_mad.empty() ) //No saving disk and no system_ds disk
{

View File

@ -824,9 +824,7 @@ error_common:
for ( it=acquired_images.begin() ; it < acquired_images.end(); it++ )
{
// Set disk_path and save_id to empty string, this way the image manager
// won't try to move any files
imagem->release_image(*it,"",-1,"");
imagem->release_image(*it);
}
return -1;
@ -849,14 +847,7 @@ void VirtualMachine::release_disk_images()
Nebula& nd = Nebula::instance();
imagem = nd.get_imagem();
num_disks = get_template_attribute("DISK",disks);
if (hasHistory() != 0)
{
/*
disk_base_path = get_local_dir();
*/
}
num_disks = get_template_attribute("DISK",disks);
for(int i=0; i<num_disks; i++)
{
@ -868,19 +859,11 @@ void VirtualMachine::release_disk_images()
continue;
}
iid = disk->vector_value("IMAGE_ID");
saveas = disk->vector_value("SAVE_AS");
iid = disk->vector_value("IMAGE_ID");
if ( iid.empty() )
if ( !iid.empty() )
{
if (!saveas.empty())
{
imagem->disk_to_image(disk_base_path,i,saveas);
}
}
else
{
imagem->release_image(iid,disk_base_path,i,saveas);
imagem->release_image(iid);
}
}
}
@ -1037,26 +1020,45 @@ int VirtualMachine::generate_context(string &files)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str)
static int id_from_attr (VectorAttribute * attr, const char *name)
{
int num_disks;
int id;
string id_str;
id_str = attr->vector_value(name);
if (id_str.empty())
{
return -1;
}
istringstream iss(id_str);
iss >> id;
return id;
}
/* -------------------------------------------------------------------------- */
int VirtualMachine::get_image_from_disk(int disk_id, string& error_str)
{
int num_disks;
int tid;
int iid = -1;
vector<Attribute * > disks;
VectorAttribute * disk;
string disk_id_str;
int tmp_disk_id;
ostringstream oss;
istringstream iss;
num_disks = obj_template->get("DISK",disks);
if ( state == DONE || state == FAILED )
{
goto error_state;
}
num_disks = obj_template->get("DISK",disks);
for(int i=0; i<num_disks; i++, iss.clear())
for(int i=0; i<num_disks; i++)
{
disk = dynamic_cast<VectorAttribute * >(disks[i]);
@ -1065,12 +1067,9 @@ int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str)
continue;
}
disk_id_str = disk->vector_value("DISK_ID");
tid = id_from_attr(disk,"DISK_ID");
iss.str(disk_id_str);
iss >> tmp_disk_id;
if ( tmp_disk_id == disk_id )
if ( disk_id == tid )
{
if(!((disk->vector_value("SAVE_AS")).empty()))
{
@ -1082,12 +1081,16 @@ int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str)
goto error_persistent;
}
iid = id_from_attr(disk, "IMAGE_ID");
if (iid == -1)
{
goto error_image_id;
}
disk->replace("SAVE", "YES");
oss << (img_id);
disk->replace("SAVE_AS", oss.str());
return 0;
return iid;
}
}
@ -1105,6 +1108,10 @@ error_saved:
oss << "The DISK " << disk_id << " is already going to be saved.";
goto error_common;
error_image_id:
oss << "The DISK " << disk_id << "does not have a valid IMAGE_ID.";
goto error_common;
error_not_found:
oss << "The DISK " << disk_id << " does not exist for VM " << oid << ".";
@ -1117,6 +1124,53 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::save_disk(const string& disk_id,
const string& source,
int img_id)
{
vector<Attribute * > disks;
VectorAttribute * disk;
int num_disks;
string tdisk_id;
ostringstream oss;
if ( state == DONE || state == FAILED )
{
return -1;
}
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;
}
tdisk_id = disk->vector_value("DISK_ID");
if ( tdisk_id == disk_id )
{
disk->replace("SAVE_AS_SOURCE", source);
oss << (img_id);
disk->replace("SAVE_AS", oss.str());
break;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::set_auth_request(int uid,
AuthRequest& ar,
VirtualMachineTemplate *tmpl)