1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

F #6029: Prevent backup removal VM is in BACKUP

Some backup drivers may not allow delete (forget) operations while an
active backup is being performed. This commits fails the
one.image.delete API call in that case.

A new configuration attribute to describe the related driver behavior has been
added CONCURRENT_FORGET for DS_MAD_CONF.
This commit is contained in:
Ruben S. Montero 2023-02-09 19:00:07 +01:00
parent 81648c449f
commit 940c1d7d63
No known key found for this signature in database
GPG Key ID: A0CEA6FA880A1D87
3 changed files with 88 additions and 32 deletions

View File

@ -240,11 +240,16 @@ public:
};
/**
* Returns true if the DS_MAD_CONF has PERSISTENT_ONLY = "YES" flag
* @return true if persistent only
* @return true if the DS_MAD_CONF has PERSISTENT_ONLY = "YES" flag
*/
bool is_persistent_only() const;
/**
* (only relevant for backup datastores)
* @return true if the DS_MAD_CONF has CONCURRENT_FORGET = "YES" flag
*/
bool is_concurrent_forget() const;
/**
* Enable or disable the DS. Only for System DS.
* @param enable true to enable

View File

@ -1110,58 +1110,77 @@ bool Datastore::get_avail_mb(long long &avail) const
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
bool Datastore::is_persistent_only() const
template <typename T>
static T ds_conf_value(const string& mad, const string& name, const T& defval)
{
int rc;
bool persistent_only = false;
const VectorAttribute* vatt;
rc = Nebula::instance().get_ds_conf_attribute(ds_mad, vatt);
int rc = Nebula::instance().get_ds_conf_attribute(mad, vatt);
if ( rc != 0 )
{
// No DS_MAD_CONF is available for this DS_MAD.
// Assuming this DS is not PERSISTENT_ONLY
return false;
return defval;
}
vatt->vector_value("PERSISTENT_ONLY", persistent_only);
T value;
return persistent_only;
};
rc = vatt->vector_value(name, value);
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
if ( rc != 0 )
{
// Attribute missing in DS_MAD_CONF
return defval;
}
return value;
}
/* -------------------------------------------------------------------------- */
bool Datastore::is_persistent_only() const
{
return ds_conf_value(ds_mad, "PERSISTENT_ONLY", false);
}
bool Datastore::is_concurrent_forget() const
{
return ds_conf_value(ds_mad, "CONCURRENT_FORGET", false);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Datastore::get_tm_mad_targets(const string &tm_mad, string& ln_target,
string& clone_target, string& disk_type) const
{
if (!tm_mad.empty())
if (tm_mad.empty())
{
string tm_mad_t = one_util::trim(tm_mad);
one_util::toupper(tm_mad_t);
return 0;
}
get_template_attribute("CLONE_TARGET_" + tm_mad_t, clone_target);
string tm_mad_t = one_util::trim(tm_mad);
one_util::toupper(tm_mad_t);
if (clone_target.empty())
{
return -1;
}
get_template_attribute("CLONE_TARGET_" + tm_mad_t, clone_target);
get_template_attribute("LN_TARGET_" + tm_mad_t, ln_target);
if (clone_target.empty())
{
return -1;
}
if (ln_target.empty())
{
return -1;
}
get_template_attribute("LN_TARGET_" + tm_mad_t, ln_target);
get_template_attribute("DISK_TYPE_" + tm_mad_t, disk_type);
if (ln_target.empty())
{
return -1;
}
if (disk_type.empty())
{
return -1;
}
get_template_attribute("DISK_TYPE_" + tm_mad_t, disk_type);
if (disk_type.empty())
{
return -1;
}
return 0;

View File

@ -462,6 +462,8 @@ int ImageManager::delete_image(int iid, string& error_str)
int cloning_id = -1;
int vm_saving_id = -1;
bool cforget;
ostringstream oss;
if (auto img = ipool->get_ro(iid))
@ -479,6 +481,8 @@ int ImageManager::delete_image(int iid, string& error_str)
ds->decrypt();
ds->to_xml(ds_data);
cforget = ds->is_concurrent_forget();
}
else
{
@ -494,6 +498,34 @@ int ImageManager::delete_image(int iid, string& error_str)
return -1;
}
// Check associted VM state for backups. Note VM can no longer exist
// Fai if VM is in BACKUP and INCREMENT mode or FULL with no CONCURRENT_FORGET
if ( img->get_type() == Image::BACKUP )
{
auto ids = img->get_running_ids();
auto first = ids.cbegin();
if (first != ids.cend())
{
VirtualMachinePool* vmpool = Nebula::instance().get_vmpool();
if (auto vm = vmpool->get_ro(*first))
{
auto lstate = vm->get_lcm_state();
auto bmode = vm->backups().mode();
if ((lstate == VirtualMachine::BACKUP ||
lstate == VirtualMachine::BACKUP_POWEROFF) &&
(bmode == Backups::INCREMENT || !cforget))
{
error_str = "Active backup on the associated VM. Wait till "
"it finish to delete the backup Image";
return -1;
}
}
}
}
switch (img->get_state())
{
case Image::READY: