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

B #5032: Further fixes for SELF DS (e.g. Ceph) for disks with resizes

and snapshots. Also updates delete-recreate quota computation
This commit is contained in:
Ruben S. Montero 2017-03-31 20:09:27 +02:00
parent d90cd64cca
commit d1ad6a0cc6
10 changed files with 201 additions and 103 deletions

View File

@ -206,7 +206,7 @@ public:
* *ARE FREED* by this function
* @param ds_quotas a map with image_id and a tmpl with usage attributes
*/
static void ds_del(map<int, Template *>& ds_quotas);
static void ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas);
/**
* Delete usage from the given quota counters.

View File

@ -243,6 +243,18 @@ public:
set(new SingleAttribute(name, value));
}
void add(const string& name, bool value)
{
if ( value )
{
set(new SingleAttribute(name, "YES"));
}
else
{
set(new SingleAttribute(name, "NO"));
}
}
/**
* Removes an attribute from the template. The attributes are returned. The
* attributes MUST be freed by the calling funtion

View File

@ -1374,7 +1374,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_disk_resizes(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
disks.delete_non_persistent_resizes(vm_quotas, ds_quotas);
}
@ -1471,11 +1471,13 @@ public:
* @param snap_id of the snapshot
* @param ds_quotas template with snapshot usage for the DS quotas
* @param vm_quotas template with snapshot usage for the VM quotas
* @param io delete ds quotas from image owners
* @param vo delete ds quotas from vm owners
*/
void delete_disk_snapshot(int disk_id, int snap_id, Template **ds_quotas,
Template **vm_quotas)
Template **vm_quotas, bool& io, bool& vo)
{
disks.delete_snapshot(disk_id, snap_id, ds_quotas, vm_quotas);
disks.delete_snapshot(disk_id, snap_id, ds_quotas, vm_quotas, io, vo);
}
/**
@ -1485,7 +1487,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_disk_snapshots(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
disks.delete_non_persistent_snapshots(vm_quotas, ds_quotas);
}

View File

@ -244,8 +244,11 @@ public:
* @param snap_id of the snapshot
* @param ds_quotas template with snapshot usage for the DS quotas
* @param vm_quotas template with snapshot usage for the VM quotas
* @param io delete ds quotas from image owners
* @param vo delete ds quotas from vm owners
*/
void delete_snapshot(int snap_id, Template **ds_quota, Template **vm_quota);
void delete_snapshot(int snap_id, Template **ds_quota, Template **vm_quota,
bool& io, bool& vo);
/* ---------------------------------------------------------------------- */
/* Disk resize functions */
@ -683,9 +686,11 @@ public:
* @param snap_id of the snapshot
* @param ds_quotas template with snapshot usage for the DS quotas
* @param vm_quotas template with snapshot usage for the VM quotas
* @param io delete ds quotas from image owners
* @param vo delete ds quotas from vm owners
*/
void delete_snapshot(int disk_id, int snap_id, Template **ds_quota,
Template **vm_quota);
Template **vm_quota, bool& io, bool& vo);
/**
* Deletes all the disk snapshots for non-persistent disks and for persistent
@ -694,7 +699,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_snapshots(Template **vm_quotas,
map<int, Template *>& ds_quotas);
vector<Template *> &ds_quotas);
/**
* Restores the disk original size for non-persistent and for persistent
@ -703,7 +708,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_resizes(Template **vm_quotas,
map<int, Template *>& ds_quotas);
vector<Template *> &ds_quotas);
protected:

View File

@ -1052,8 +1052,8 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
Template * vm_quotas_snp = 0;
Template * vm_quotas_rsz = 0;
map<int, Template *> ds_quotas_snp;
map<int, Template *> ds_quotas_rsz;
vector<Template *> ds_quotas_snp;
vector<Template *> ds_quotas_rsz;
int vm_uid, vm_gid;
@ -1118,12 +1118,12 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
if ( !ds_quotas_snp.empty() )
{
Quotas::ds_del(ds_quotas_snp);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_snp);
}
if ( !ds_quotas_rsz.empty() )
{
Quotas::ds_del(ds_quotas_rsz);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_rsz);
}
if ( vm_quotas_snp != 0 )

View File

@ -820,8 +820,8 @@ void LifeCycleManager::delete_recreate_action(const LCMAction& la)
Template * vm_quotas_snp = 0;
Template * vm_quotas_rsz = 0;
map<int, Template *> ds_quotas_snp;
map<int, Template *> ds_quotas_rsz;
vector<Template *> ds_quotas_snp;
vector<Template *> ds_quotas_rsz;
int vm_uid, vm_gid;
@ -888,12 +888,12 @@ void LifeCycleManager::delete_recreate_action(const LCMAction& la)
if ( !ds_quotas_snp.empty() )
{
Quotas::ds_del(ds_quotas_snp);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_snp);
}
if ( !ds_quotas_rsz.empty() )
{
Quotas::ds_del(ds_quotas_rsz);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_rsz);
}
if ( vm_quotas_snp != 0 )

View File

@ -1865,6 +1865,8 @@ void LifeCycleManager::disk_snapshot_success(int vid)
Template *ds_quotas = 0;
Template *vm_quotas = 0;
bool img_owner, vm_owner;
const VirtualMachineDisk * disk;
Snapshots snaps(-1);
const Snapshots* tmp_snaps;
@ -1909,7 +1911,8 @@ void LifeCycleManager::disk_snapshot_success(int vid)
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED:
vm->log("LCM", Log::INFO, "VM disk snapshot deleted.");
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas);
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas,
img_owner, vm_owner);
break;
default:
@ -1941,16 +1944,24 @@ void LifeCycleManager::disk_snapshot_success(int vid)
if ( ds_quotas != 0 )
{
Image* img = ipool->get(img_id, true);
if(img != 0)
if ( img_owner )
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Image* img = ipool->get(img_id, true);
img->unlock();
if(img != 0)
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
img->unlock();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
}
}
if ( vm_owner )
{
Quotas::ds_del(vm_uid, vm_gid, ds_quotas);
}
delete ds_quotas;
@ -2008,6 +2019,8 @@ void LifeCycleManager::disk_snapshot_failure(int vid)
bool has_snaps = false;
string error_str;
bool img_owner, vm_owner;
VirtualMachine * vm = vmpool->get(vid,true);
if ( vm == 0 )
@ -2036,7 +2049,8 @@ void LifeCycleManager::disk_snapshot_failure(int vid)
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_SUSPENDED:
vm->log("LCM", Log::ERROR, "Could not take disk snapshot.");
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas);
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas,
img_owner, vm_owner);
break;
case VirtualMachine::DISK_SNAPSHOT_DELETE:
@ -2077,16 +2091,24 @@ void LifeCycleManager::disk_snapshot_failure(int vid)
if ( ds_quotas != 0 )
{
Image* img = ipool->get(img_id, true);
if(img != 0)
if ( img_owner )
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Image* img = ipool->get(img_id, true);
img->unlock();
if(img != 0)
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
img->unlock();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
}
}
if ( vm_owner)
{
Quotas::ds_del(vm_uid, vm_gid, ds_quotas);
}
delete ds_quotas;

View File

@ -2564,8 +2564,7 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
PoolObjectAuth vm_perms;
const VirtualMachineDisk * disk;
VectorAttribute * delta_disk = 0;
VirtualMachineDisk * disk;
Template ds_deltas;
Template vm_deltas;
@ -2597,11 +2596,19 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
return;
}
string disk_size = disk->vector_value("SIZE");
string ds_id = disk->vector_value("DATASTORE_ID");
/* ---------------------------------------------------------------------- */
/* Get disk information and quota usage deltas */
/* ---------------------------------------------------------------------- */
bool img_ds_quota, vm_ds_quota;
long long ssize;
disk->vector_value("SIZE", ssize);
ssize = 2 * ssize; //Sanpshot accounts as another disk of same size
disk->resize_quotas(ssize, ds_deltas, vm_deltas, img_ds_quota, vm_ds_quota);
bool is_volatile = disk->is_volatile();
bool is_system = disk->get_tm_target() == "SYSTEM";
bool do_ds_quota = disk->is_persistent() || !is_system;
int img_id = -1;
disk->vector_value("IMAGE_ID", img_id);
@ -2617,11 +2624,12 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
return;
}
RequestAttributes ds_att_quota;
/* ---------- Attributes for quota update requests ---------------------- */
RequestAttributes img_att_quota;
RequestAttributes vm_att_quota;
//--------------------------- Persistent Images ----------------------------
if (do_ds_quota)
if (img_ds_quota)
{
PoolObjectAuth img_perms;
@ -2645,40 +2653,51 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
return;
}
ds_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
ds_deltas.add("DATASTORE", ds_id);
ds_deltas.add("SIZE", disk_size);
ds_deltas.add("IMAGES", 0);
if (!quota_authorization(&ds_deltas, Quotas::DATASTORE, ds_att_quota))
{
return;
}
img_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
}
//--------------------- Account for System DS storage ----------------------
if (is_system)
if ( vm_ds_quota )
{
if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false )
{
return;
}
}
vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
delta_disk = new VectorAttribute("DISK");
delta_disk->replace("TYPE", "FS");
delta_disk->replace("SIZE", disk_size);
/* ---------------------------------------------------------------------- */
/* Check quotas for the new size in image/system datastoress */
/* ---------------------------------------------------------------------- */
if ( img_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
img_att_quota) )
{
return;
}
vm_deltas.add("VMS", 0);
vm_deltas.set(delta_disk);
if ( vm_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
vm_att_quota) )
{
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
return;
}
if ( !vm_deltas.empty() )
{
if (!quota_resize_authorization(id, &vm_deltas, vm_att_quota))
{
if (do_ds_quota)
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
return;
@ -2692,12 +2711,17 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
if ( rc != 0 )
{
if (do_ds_quota)
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if (is_system)
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
if ( !vm_deltas.empty() )
{
quota_rollback(&vm_deltas, Quotas::VM, vm_att_quota);
}
@ -2996,7 +3020,7 @@ void VirtualMachineDiskResize::request_execute(
/* ---------------------------------------------------------------------- */
/* Authorize the request for VM and IMAGE for persistent disks */
/* ---------------------------------------------------------------------- */
RequestAttributes img_ds_att_quota, vm_ds_att_quota;
RequestAttributes img_att_quota;
RequestAttributes vm_att_quota;
if ( img_ds_quota )
@ -3026,7 +3050,7 @@ void VirtualMachineDiskResize::request_execute(
return;
}
img_ds_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
img_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
}
if ( vm_ds_quota )
@ -3035,8 +3059,6 @@ void VirtualMachineDiskResize::request_execute(
{
return;
}
vm_ds_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
}
vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
@ -3046,14 +3068,19 @@ void VirtualMachineDiskResize::request_execute(
/* ---------------------------------------------------------------------- */
if ( img_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
img_ds_att_quota))
img_att_quota))
{
return;
}
if ( vm_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
vm_ds_att_quota))
vm_att_quota))
{
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
return;
}
@ -3063,12 +3090,12 @@ void VirtualMachineDiskResize::request_execute(
{
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
return;
@ -3084,12 +3111,12 @@ void VirtualMachineDiskResize::request_execute(
{
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
if ( !vm_deltas.empty() )

View File

@ -295,33 +295,42 @@ void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::ds_del(map<int, Template *>& ds_quotas)
void Quotas::ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas)
{
Nebula& nd = Nebula::instance();
ImagePool * ipool = nd.get_ipool();
map<int, Template *>::iterator it;
vector<Template *>::iterator it;
for (it = ds_quotas.begin(); it != ds_quotas.end(); it++)
{
int image_id = it->first;
Template * tmpl = it->second;
int image_id = -1;
Template * tmpl = *it;
if ( tmpl == 0 )
bool vm_owner, img_owner;
tmpl->get("IMAGE_ID", image_id);
tmpl->get("VM_QUOTA", vm_owner);
tmpl->get("IMG_QUOTA", img_owner);
if ( img_owner )
{
continue;
Image* img = ipool->get(image_id, true);
if(img != 0)
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
img->unlock();
quota_del(DATASTORE, img_uid, img_gid, tmpl);
}
}
Image* img = ipool->get(image_id, true);
if(img != 0)
if ( vm_owner )
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
img->unlock();
quota_del(DATASTORE, img_uid, img_gid, tmpl);
quota_del(DATASTORE, uid, gid, tmpl);
}
delete tmpl;

View File

@ -270,8 +270,11 @@ int VirtualMachineDisk::revert_snapshot(int snap_id)
/* -------------------------------------------------------------------------- */
void VirtualMachineDisk::delete_snapshot(int snap_id, Template **ds_quotas,
Template **vm_quotas)
Template **vm_quotas, bool& img_owner, bool& vm_owner)
{
vm_owner = false;
img_owner = false;
if ( snapshots == 0 )
{
return;
@ -294,7 +297,10 @@ void VirtualMachineDisk::delete_snapshot(int snap_id, Template **ds_quotas,
string tm_target = get_tm_target();
if (is_persistent() || tm_target != "SYSTEM")
vm_owner = tm_target == "SELF";
img_owner = is_persistent() || tm_target == "NONE";
if ( img_owner || vm_owner )
{
*ds_quotas = new Template();
@ -372,7 +378,6 @@ long long VirtualMachineDisk::image_ds_size()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// Owner to update ds usage quotas
//
@ -1272,7 +1277,7 @@ int VirtualMachineDisks::revert_snapshot(int id, int snap_id)
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_snapshot(int disk_id, int snap_id,
Template **ds_quota, Template **vm_quota)
Template **ds_quota, Template **vm_quota,bool& img_owner, bool& vm_owner)
{
VirtualMachineDisk * disk =
static_cast<VirtualMachineDisk *>(get_attribute(disk_id));
@ -1285,14 +1290,14 @@ void VirtualMachineDisks::delete_snapshot(int disk_id, int snap_id,
return;
}
disk->delete_snapshot(snap_id, ds_quota, vm_quota);
disk->delete_snapshot(snap_id, ds_quota, vm_quota, img_owner, vm_owner);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *> &ds_quotas)
{
long long system_disk = 0;
@ -1305,9 +1310,11 @@ void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
continue;
}
bool vm_owner = tm_target == "SELF";
bool img_owner = (*disk)->is_persistent();
// Decrement DS quota on disks that do not modify the original image
if ( tm_target == "SELF" || ( (*disk)->is_persistent() &&
tm_target == "SYSTEM" ) )
if ( vm_owner || img_owner )
{
int image_id;
@ -1321,8 +1328,11 @@ void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
d_ds->add("DATASTORE", (*disk)->vector_value("DATASTORE_ID"));
d_ds->add("SIZE", (*disk)->get_total_snapshot_size());
d_ds->add("IMAGES", 0);
d_ds->add("IMAGE_ID", image_id);
d_ds->add("VM_QUOTA", vm_owner);
d_ds->add("IMG_QUOTA", img_owner);
ds_quotas.insert(pair<int, Template *>(image_id, d_ds));
ds_quotas.push_back(d_ds);
}
if ( tm_target == "SYSTEM" )
@ -1467,7 +1477,7 @@ int VirtualMachineDisks::get_saveas_info(int& disk_id, string& source,
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_non_persistent_resizes(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
long long original_size, size, delta_size, system_disk = 0;
@ -1488,9 +1498,17 @@ void VirtualMachineDisks::delete_non_persistent_resizes(Template **vm_quotas,
delta_size = original_size - size;
//Quotas uses del operation to substract counters, delta needs to be > 0
if ( delta_size < 0 )
{
delta_size = - delta_size;
}
bool vm_owner = tm_target == "SELF";
bool img_owner = (*disk)->is_persistent();
// Decrement DS quota on disks that do not modify the original image
if ( tm_target == "SELF" || ( (*disk)->is_persistent() &&
tm_target == "SYSTEM" ) )
if ( vm_owner || img_owner )
{
int image_id;
@ -1504,8 +1522,11 @@ void VirtualMachineDisks::delete_non_persistent_resizes(Template **vm_quotas,
d_ds->add("DATASTORE", (*disk)->vector_value("DATASTORE_ID"));
d_ds->add("SIZE", delta_size);
d_ds->add("IMAGES", 0);
d_ds->add("IMAGE_ID", image_id);
d_ds->add("VM_QUOTA", vm_owner);
d_ds->add("IMG_QUOTA", img_owner);
ds_quotas.insert(pair<int, Template *>(image_id, d_ds));
ds_quotas.push_back(d_ds);
}
if ( tm_target == "SYSTEM" )