/* -------------------------------------------------------------------------- */ /* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); you may */ /* not use this file except in compliance with the License. You may obtain */ /* a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ /* See the License for the specific language governing permissions and */ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ #ifndef VIRTUAL_MACHINE_DISK_H_ #define VIRTUAL_MACHINE_DISK_H_ #include #include #include "VirtualMachineAttribute.h" #include "Snapshots.h" #include "NebulaUtil.h" class AuthRequest; /** * The VirtualMachine DISK attribute */ class VirtualMachineDisk : public VirtualMachineAttribute { public: VirtualMachineDisk(VectorAttribute *va, int id): VirtualMachineAttribute(va, id), snapshots(0){}; virtual ~VirtualMachineDisk() { delete snapshots; }; /* ---------------------------------------------------------------------- */ /* DISK get/set functions for boolean disk flags */ /* ATTACH */ /* RESIZE */ /* OPENNEBULA_MANAGED */ /* ALLOW_ORPHANS */ /* CLONING */ /* PERSISTENT */ /* DISK_SNAPSHOT_ACTIVE */ /* ---------------------------------------------------------------------- */ bool is_persistent() const { return is_flag("PERSISTENT"); } Snapshots::AllowOrphansMode allow_orphans() const { string orphans; if (vector_value("ALLOW_ORPHANS", orphans) == -1) { orphans = Snapshots::DENY; } return Snapshots::str_to_allow_orphans_mode(one_util::toupper(orphans)); } void set_attach() { set_flag("ATTACH"); }; void set_resize() { set_flag("RESIZE"); }; void clear_resize() { clear_flag("RESIZE"); }; void clear_cloning() { clear_flag("CLONING"); }; bool is_cloning() const { return is_flag("CLONING"); } void set_active_snapshot() { set_flag("DISK_SNAPSHOT_ACTIVE"); }; void clear_active_snapshot() { clear_flag("DISK_SNAPSHOT_ACTIVE"); }; bool is_active_snapshot() const { return is_flag("DISK_SNAPSHOT_ACTIVE"); } void set_saveas() { set_flag("HOTPLUG_SAVE_AS_ACTIVE"); }; void clear_saveas() { clear_flag("HOTPLUG_SAVE_AS_ACTIVE"); }; /* ---------------------------------------------------------------------- */ /* Disk attributes, not accesible through vector_value */ /* ---------------------------------------------------------------------- */ /** * Return the disk id ("DISK_ID") */ int get_disk_id() const { return get_id(); } /** * Return the "effective" target (LN_TARGET/CLONE_TARGET) */ string get_tm_target() const; /** * Check if the given disk is volatile */ bool is_volatile() const; /** * Get the effective uid to get an image. Used in VM parsers */ int get_uid(int _uid) const; /** * Gets the ID of the image associated to the disks * @param id the image id, if found * @param uid effective user id making the call * @return 0 if the disk uses an image, -1 otherwise */ int get_image_id(int &id, int uid) const; /** * Return the TM_MAD_SYSTEM attribute */ std::string get_tm_mad_system() const; /* ---------------------------------------------------------------------- */ /* Image Manager Interface */ /* ---------------------------------------------------------------------- */ /** * Fills the disk extended information attributes */ void extended_info(int uid); /** * Fills the authorization request for this disk based on its Image use * requirements * @param uid of user making the request * @param ar auth request * @param check_lock for check if the resource is lock or not */ void authorize(int uid, AuthRequest* ar, bool check_lock); /* ---------------------------------------------------------------------- */ /* Snapshots Interface */ /* ---------------------------------------------------------------------- */ /** * Set the snapshots for this disks */ void set_snapshots(Snapshots * _snapshots) { snapshots = _snapshots; }; /** * Return the snapshots of this disk */ const Snapshots * get_snapshots() const { return snapshots; } /** * Clear snapshots from the disk and free resources */ void clear_snapshots() { if ( snapshots == 0 ) { return; } snapshots->clear(); delete snapshots; snapshots = 0; } /** * @return total snapshot size (virtual) in mb */ long long get_total_snapshot_size() const { if ( snapshots == 0 ) { return 0; } return snapshots->get_total_size(); } /** * Get the size (virtual) in mb of the given snapshot * @param id of the snapshot * @return size or 0 if not found */ long long get_snapshot_size(int snap_id) const { if ( snapshots == 0 ) { return 0; } return snapshots->get_snapshot_size(snap_id); } /** * @return true if the disk has snapshots */ bool has_snapshots() const { return (snapshots != 0); } bool has_snapshot(int snap_id) const { if (!has_snapshots()) { return false; } return snapshots->exists(snap_id); } /** * Renames a snapshot * * @param id_snap of the snapshot * @param new_name of the snapshot * @return 0 on success */ int rename_snapshot(int snap_id, const string& new_name, string& str_error) { if (!snapshots) { str_error = "The VM does not have any snapshot"; return -1; } return snapshots->rename_snapshot(snap_id, new_name, str_error); } /** * Creates a new snapshot of the disk * @param name a description for this snapshot * @param error if any * @return the id of the new snapshot or -1 if error */ int create_snapshot(const string& name, string& error); /** * Sets the snap_id as active, the VM will boot from it next time * @param snap_id of the snapshot * @param revert true if the cause of changing the active snapshot * is because a revert * @return -1 if error */ int revert_snapshot(int snap_id, bool revert); /** * Deletes the snap_id from the list * @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, bool& io, bool& vo); /* ---------------------------------------------------------------------- */ /* Disk resize functions */ /* ---------------------------------------------------------------------- */ /** * Cleans the resize attribute from the disk * @param restore the previous size */ void clear_resize(bool restore); /** * Calculate the quotas for a resize operation on the disk * @param new_size of disk * @param dsdeltas increment in datastore usage * @param vmdelta increment in system datastore usage * @param do_img_owner quotas counter allocated for image uid/gid * @param do_vm_owner quotas counter allocated for vm uid/gid * */ void resize_quotas(long long new_size, Template& dsdelta, Template& vmdelta, bool& do_img_owner, bool& do_vm_owner); /* ---------------------------------------------------------------------- */ /* Disk space usage functions */ /* ---------------------------------------------------------------------- */ /** * @return the space required by this disk in the system datastore */ long long system_ds_size() const; /** * @return the space required by this disk in the image datastore */ long long image_ds_size() const; /** * Compute the storage needed by the disk in the system and/or image * datastore * @param ds_id of the datastore * @param img_sz size in image datastore needed * @param sys_sz size in system datastore needed */ void datastore_sizes(int& ds_id, long long& img_sz, long long& sys_sz) const; /** * Update the TYPE and DISK_TYPE attributes based on the system DS * name * @param ds_name of the system ds tm_mad */ void set_types(const string& ds_name); /** * Marshall disk attributes in XML format with just essential information * @param stream to write the disk XML description */ void to_xml_short(std::ostringstream& oss) const; private: Snapshots * snapshots; }; /** * Set of VirtualMachine DIKS */ class VirtualMachineDisks : public VirtualMachineAttributeSet { public: /* ---------------------------------------------------------------------- */ /* Constructor and Initialization functions */ /* ---------------------------------------------------------------------- */ /** * Creates the VirtualMachineDisk set from a Template with DISK=[...] * attributes, in this case the id's of each disk is auto assigned * @param tmpl template with DISK */ VirtualMachineDisks(Template * tmpl, bool has_id): VirtualMachineAttributeSet(false) { std::vector vas; tmpl->get(DISK_NAME, vas); init(vas, has_id); }; /** * Creates the VirtualMachineDisk set from a vector of DISK VectorAttribute * The DIKS need to have a DISK_ID assgined to create the disk set. * @param va vector of DISK Vector Attributes */ VirtualMachineDisks(vector& va, bool has_id, bool dispose): VirtualMachineAttributeSet(dispose) { init(va, has_id); }; /** * Creates an empty disk set */ VirtualMachineDisks(bool dispose): VirtualMachineAttributeSet(dispose){}; virtual ~VirtualMachineDisks(){}; /** * Function used to initialize the attribute map based on a vector of DISK */ void init(std::vector& vas, bool has_id) { if ( has_id ) { init_attribute_map(DISK_ID_NAME, vas); } else { init_attribute_map("", vas); } } /* ---------------------------------------------------------------------- */ /* Iterators */ /* ---------------------------------------------------------------------- */ /** * Generic iterator for the disk set. */ class DiskIterator : public AttributeIterator { public: DiskIterator():AttributeIterator(){}; DiskIterator(const AttributeIterator& dit):AttributeIterator(dit){}; virtual ~DiskIterator(){}; VirtualMachineDisk * operator*() const { return static_cast(map_it->second); } }; DiskIterator begin() { DiskIterator it(ExtendedAttributeSet::begin()); return it; } DiskIterator end() { DiskIterator it(ExtendedAttributeSet::end()); return it; } typedef class DiskIterator disk_iterator; /* ---------------------------------------------------------------------- */ /* DISK interface */ /* ---------------------------------------------------------------------- */ /** * Returns the DISK attribute for a disk * @param disk_id of the DISK * @return pointer to the attribute ir null if not found */ VirtualMachineDisk * get_disk(int disk_id) const { return static_cast(get_attribute(disk_id)); } /** * Computes the storage needed in the system datastore. The static version * uses the disk definitions in the template (first argument) * @return the total disk SIZE that the VM instance needs in the system DS */ long long system_ds_size(); static long long system_ds_size(Template * ds_tmpl); /** * Completes the information of the disks (IMAGE_ID, SIZE...) */ void extended_info(int uid); static void extended_info(int uid, Template * tmpl); /** * Computes the storage in the image DS needed for the disks in a VM * template * @param tmpl with DISK descriptions * @param ds_quotas templates for quota updates */ static void image_ds_quotas(Template * tmpl, vector