mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-26 06:50:09 +03:00
feature #1613: Triiger monitor actions when an image operation is made. Check datastore size before registering or cloning an image. RESERVED_SIZE and MAX_USED_SIZE control datastore capacity
This commit is contained in:
parent
0e2a876525
commit
f689d1ea4a
@ -162,6 +162,27 @@ public:
|
||||
used_mb = used;
|
||||
}
|
||||
|
||||
unsigned int get_avail_mb()
|
||||
{
|
||||
float reserved_size;
|
||||
float max_used_size;
|
||||
unsigned int effective_free = free_mb;
|
||||
|
||||
if (get_template_attribute("MAX_USED_SIZE", max_used_size))
|
||||
{
|
||||
if (used_mb >= max_used_size)
|
||||
{
|
||||
effective_free = 0;
|
||||
}
|
||||
}
|
||||
else if (get_template_attribute("RESERVED_SIZE", reserved_size))
|
||||
{
|
||||
effective_free -= reserved_size;
|
||||
}
|
||||
|
||||
return effective_free;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -182,6 +182,12 @@ public:
|
||||
*/
|
||||
int stat_image(Template* img_tmpl, const string& ds_tmpl, string& res);
|
||||
|
||||
/**
|
||||
* Trigger a monitor action for the datastore.
|
||||
* @param ds_id id of the datastore to monitor
|
||||
*/
|
||||
void monitor_datastore(int ds_id);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Generic name for the Image driver
|
||||
@ -264,7 +270,7 @@ private:
|
||||
* @param ds_data Datastore XML representation
|
||||
* @return the XML message
|
||||
*/
|
||||
string * format_message(const string& img_data, const string& ds_data);
|
||||
static string * format_message(const string& img_data, const string& ds_data);
|
||||
|
||||
/**
|
||||
* This function is executed periodically to monitor Datastores.
|
||||
|
@ -221,6 +221,14 @@ int DatastorePool::allocate(
|
||||
|
||||
*oid = PoolSQL::allocate(ds, error_str);
|
||||
|
||||
if ( *oid != -1 )
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * im = nd.get_imagem();
|
||||
|
||||
im->monitor_datastore(*oid);
|
||||
}
|
||||
|
||||
return *oid;
|
||||
|
||||
error_duplicated:
|
||||
|
@ -67,3 +67,5 @@ EOF
|
||||
)
|
||||
|
||||
echo "$MONITOR_DATA"
|
||||
|
||||
#vgdisplay --units M -o vg_free -C vg --noheadings --nosuffix
|
||||
|
@ -165,8 +165,6 @@ void ImageManager::timer_action()
|
||||
Nebula& nd = Nebula::instance();
|
||||
DatastorePool * dspool = nd.get_dspool();
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
rc = dspool->list(datastores);
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -174,33 +172,46 @@ void ImageManager::timer_action()
|
||||
return;
|
||||
}
|
||||
|
||||
const ImageManagerDriver* imd = get();
|
||||
|
||||
for(it = datastores.begin() ; it != datastores.end(); it++)
|
||||
{
|
||||
string ds_data;
|
||||
string* drv_msg;
|
||||
|
||||
Datastore * ds = dspool->get(*it, true);
|
||||
|
||||
if ( ds == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
drv_msg = format_message("", ds->to_xml(ds_data));
|
||||
|
||||
oss.str("");
|
||||
oss << "Monitoring datastore " << ds->get_name() << " (" << *it << ")";
|
||||
|
||||
NebulaLog::log("InM", Log::INFO, oss);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
imd->monitor(*it, *drv_msg);
|
||||
|
||||
delete drv_msg;
|
||||
monitor_datastore(*it);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManager::monitor_datastore(int ds_id)
|
||||
{
|
||||
string ds_data;
|
||||
string* drv_msg;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
DatastorePool * dspool = nd.get_dspool();
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
const ImageManagerDriver* imd = get();
|
||||
|
||||
Datastore * ds = dspool->get(ds_id, true);
|
||||
|
||||
if ( ds == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drv_msg = ImageManager::format_message("", ds->to_xml(ds_data));
|
||||
|
||||
oss << "Monitoring datastore " << ds->get_name() << " (" << ds_id << ")";
|
||||
|
||||
NebulaLog::log("InM", Log::INFO, oss);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
imd->monitor(ds_id, *drv_msg);
|
||||
|
||||
delete drv_msg;
|
||||
}
|
||||
|
@ -132,13 +132,14 @@ static void stat_action(istringstream& is, int id, const string& result)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void cp_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
static int cp_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
{
|
||||
string source;
|
||||
string info;
|
||||
int ds_id = -1;
|
||||
|
||||
Image * image;
|
||||
|
||||
@ -166,9 +167,11 @@ static void cp_action(istringstream& is,
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
ds_id = image->get_ds_id();
|
||||
|
||||
if ( result == "FAILURE" )
|
||||
{
|
||||
goto error;
|
||||
@ -194,7 +197,7 @@ static void cp_action(istringstream& is,
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image copied and ready to use.");
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
|
||||
error:
|
||||
oss << "Error copying image in the datastore";
|
||||
@ -215,17 +218,18 @@ error:
|
||||
|
||||
image->unlock();
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void clone_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
static int clone_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
{
|
||||
int cloning_id;
|
||||
int ds_id = -1;
|
||||
string source;
|
||||
string info;
|
||||
|
||||
@ -258,9 +262,10 @@ static void clone_action(istringstream& is,
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
ds_id = image->get_ds_id();
|
||||
cloning_id = image->get_cloning_id();
|
||||
|
||||
if ( result == "FAILURE" )
|
||||
@ -292,7 +297,7 @@ static void clone_action(istringstream& is,
|
||||
|
||||
im->release_cloning_image(cloning_id, id);
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
|
||||
error:
|
||||
oss << "Error cloning from Image " << cloning_id;
|
||||
@ -317,15 +322,15 @@ error:
|
||||
|
||||
im->release_cloning_image(cloning_id, id);
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void mkfs_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
static int mkfs_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
{
|
||||
string source;
|
||||
Image * image;
|
||||
@ -336,6 +341,8 @@ static void mkfs_action(istringstream& is,
|
||||
int rc;
|
||||
|
||||
int vm_id = -1;
|
||||
int ds_id = -1;
|
||||
|
||||
int disk_id;
|
||||
|
||||
VirtualMachine * vm;
|
||||
@ -367,11 +374,12 @@ static void mkfs_action(istringstream& is,
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
is_saving = image->isSaving();
|
||||
is_hot = image->isHot();
|
||||
ds_id = image->get_ds_id();
|
||||
|
||||
if ( is_saving )
|
||||
{
|
||||
@ -408,7 +416,7 @@ static void mkfs_action(istringstream& is,
|
||||
|
||||
if ( !is_saving )
|
||||
{
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
vm = vmpool->get(vm_id, true);
|
||||
@ -445,7 +453,7 @@ static void mkfs_action(istringstream& is,
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
|
||||
error_img:
|
||||
oss << "Error creating datablock";
|
||||
@ -465,7 +473,7 @@ error_save:
|
||||
if ( image == 0 )
|
||||
{
|
||||
NebulaLog::log("ImM", Log::ERROR, oss);
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
error:
|
||||
@ -496,17 +504,19 @@ error:
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void rm_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
static int rm_action(istringstream& is,
|
||||
ImagePool* ipool,
|
||||
int id,
|
||||
const string& result)
|
||||
{
|
||||
int rc;
|
||||
int rc;
|
||||
int ds_id = -1;
|
||||
|
||||
string tmp_error;
|
||||
string source;
|
||||
string info;
|
||||
@ -518,9 +528,10 @@ static void rm_action(istringstream& is,
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
ds_id = image->get_ds_id();
|
||||
source = image->get_source();
|
||||
|
||||
rc = ipool->drop(image, tmp_error);
|
||||
@ -538,14 +549,14 @@ static void rm_action(istringstream& is,
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image successfully removed.");
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
|
||||
error_drop:
|
||||
oss << "Error removing image from DB: " << tmp_error
|
||||
<< ". Remove image source " << source << " to completely delete image.";
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss);
|
||||
return;
|
||||
return ds_id;
|
||||
|
||||
error:
|
||||
oss << "Error removing image from datastore. Manually remove image source "
|
||||
@ -560,7 +571,7 @@ error:
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss);
|
||||
|
||||
return;
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -648,7 +659,9 @@ void ImageManagerDriver::protocol(const string& message) const
|
||||
string result;
|
||||
string source;
|
||||
string info;
|
||||
int id;
|
||||
|
||||
int id;
|
||||
int ds_id = -1;
|
||||
|
||||
oss << "Message received: " << message;
|
||||
NebulaLog::log("ImG", Log::DDEBUG, oss);
|
||||
@ -691,19 +704,19 @@ void ImageManagerDriver::protocol(const string& message) const
|
||||
}
|
||||
else if ( action == "CP" )
|
||||
{
|
||||
cp_action(is, ipool, id, result);
|
||||
ds_id = cp_action(is, ipool, id, result);
|
||||
}
|
||||
else if ( action == "CLONE" )
|
||||
{
|
||||
clone_action(is, ipool, id, result);
|
||||
ds_id = clone_action(is, ipool, id, result);
|
||||
}
|
||||
else if ( action == "MKFS" )
|
||||
{
|
||||
mkfs_action(is, ipool, id, result);
|
||||
ds_id = mkfs_action(is, ipool, id, result);
|
||||
}
|
||||
else if ( action == "RM" )
|
||||
{
|
||||
rm_action(is, ipool, id, result);
|
||||
ds_id = rm_action(is, ipool, id, result);
|
||||
}
|
||||
else if ( action == "MONITOR" )
|
||||
{
|
||||
@ -715,6 +728,14 @@ void ImageManagerDriver::protocol(const string& message) const
|
||||
NebulaLog::log("ImM", log_type(result[0]), info.c_str());
|
||||
}
|
||||
|
||||
if (ds_id != -1)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * im = nd.get_imagem();
|
||||
|
||||
im->monitor_datastore(ds_id);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
|
||||
Datastore * ds;
|
||||
Image::DiskType ds_disk_type;
|
||||
|
||||
int umask;
|
||||
int umask, avail;
|
||||
|
||||
// ------------------------- Get user's umask ------------------------------
|
||||
|
||||
@ -407,6 +407,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
|
||||
|
||||
ds_name = ds->get_name();
|
||||
ds_disk_type = ds->get_disk_type();
|
||||
avail = ds->get_avail_mb();
|
||||
|
||||
ds->to_xml(ds_data);
|
||||
|
||||
@ -437,6 +438,14 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
|
||||
return;
|
||||
}
|
||||
|
||||
if ( size_mb > avail )
|
||||
{
|
||||
failure_response(ACTION, "Not enough space in datastore", att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
}
|
||||
|
||||
tmpl->erase("SIZE");
|
||||
tmpl->add("SIZE", size_str);
|
||||
|
||||
|
@ -229,7 +229,7 @@ void ImageClone::request_execute(
|
||||
int clone_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
string name = xmlrpc_c::value_string(paramList.getString(2));
|
||||
|
||||
int rc, new_id, ds_id, size, umask;
|
||||
int rc, new_id, ds_id, size, umask, avail;
|
||||
string error_str, ds_name, ds_data;
|
||||
|
||||
Image::DiskType disk_type;
|
||||
@ -336,6 +336,8 @@ void ImageClone::request_execute(
|
||||
|
||||
ds->to_xml(ds_data);
|
||||
|
||||
avail = ds->get_avail_mb();
|
||||
|
||||
ds->unlock();
|
||||
|
||||
// ------------- Set authorization request ---------------------------------
|
||||
@ -343,6 +345,14 @@ void ImageClone::request_execute(
|
||||
img_usage.add("DATASTORE", ds_id);
|
||||
img_usage.add("SIZE", size);
|
||||
|
||||
if ( size > avail )
|
||||
{
|
||||
failure_response(ACTION, "Not enough space in datastore", att);
|
||||
|
||||
delete tmpl;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( att.uid != 0 )
|
||||
{
|
||||
AuthRequest ar(att.uid, att.gid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user