From 676bfcc1dbdfd007bc766e6bbfe75c71a08d2e72 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 14 May 2015 19:43:31 +0200 Subject: [PATCH] feature #3782: Initial class for Snapshot list --- include/Snapshot.h | 85 +++++++++++++++++++ src/vm/SConstruct | 3 +- src/vm/Snapshots.cc | 195 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 include/Snapshot.h create mode 100644 src/vm/Snapshots.cc diff --git a/include/Snapshot.h b/include/Snapshot.h new file mode 100644 index 0000000000..2817b28b22 --- /dev/null +++ b/include/Snapshot.h @@ -0,0 +1,85 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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 SNAPSHOT_POOL_H_ +#define SNAPSHOT_POOL_H_ + +#include +#include +#include + +#include + +#include "Template.h" + +using namespace std; + +class VectorAttribute; + +/** + * This class represents the List of Snapshots associated to an image or Virtual + * Machine Disk + */ +class Snapshots +{ +public: + Snapshots(int _disk_id); + + virtual ~Snapshots(); + + // ************************************************************************* + // Inititalization functions + // ************************************************************************* + + /** + * Builds the snapshot list from its XML representation. This function + * is used when importing it from the DB. + * @param node xmlNode for the template + * @return 0 on success + */ + int from_xml_node(const xmlNodePtr node); + + int create_snapshot(unsigned int p_id, const string& tag, string& error); + + int delete_snapshot(unsigned int id); + + /** + * Set the given snapshot as active. Updates the values of the current + * snapshot + */ + int active_snapshot(unsigned int id); + +private: + + /** + * Get a snapshot from the pool + * @param id of the snapshot + * @return pointer to the snapshot (VectorAttribute) or null + */ + VectorAttribute * get_snapshot(unsigned int id); + + Template snapshot_template; + + unsigned int next_snapshot; + + unsigned int disk_id; + + map snapshot_pool; + + unsigned int active; +}; + +#endif /*SNAPSHOT_H_*/ diff --git a/src/vm/SConstruct b/src/vm/SConstruct index 957aaa163a..1c29aa6180 100644 --- a/src/vm/SConstruct +++ b/src/vm/SConstruct @@ -47,7 +47,8 @@ source_files=[ 'vm_file_var_syntax.cc', 'VirtualMachinePool.cc', 'VirtualMachineHook.cc', - 'VirtualMachineTemplate.cc' + 'VirtualMachineTemplate.cc', + 'Snapshots.cc' ] # Build library diff --git a/src/vm/Snapshots.cc b/src/vm/Snapshots.cc new file mode 100644 index 0000000000..803da7c6e7 --- /dev/null +++ b/src/vm/Snapshots.cc @@ -0,0 +1,195 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#include "Snapshot.h" + +Snapshots::Snapshots(int _disk_id): + snapshot_template(false,'=',"SNAPSHOTS"), + next_snapshot(0), + disk_id(_disk_id), + active(-1) +{ + snapshot_template.add("DISK_ID",_disk_id); +}; + +Snapshots::~Snapshots(){}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Snapshots::from_xml_node(const xmlNodePtr node) +{ + int rc = snapshot_template.from_xml_node(node); + + if (rc != 0) + { + return -1; + } + + vector vsnap; + + unsigned int id; + bool current; + + int num_snap = snapshot_template.get("SNAPSHOT", vsnap); + + for (int i=0; i < num_snap; i++) + { + VectorAttribute * snap = static_cast(vsnap[i]); + + snap->vector_value("ID", id); + + snap->vector_value("ACTIVE", current); + + if (current) + { + active = id; + } + + if (id >= next_snapshot) + { + next_snapshot = id + 1; + } + + snapshot_pool.insert(pair(id, snap)); + } + + int did; + + if (snapshot_template.get("DISK_ID", did)) + { + disk_id = id; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Snapshots::create_snapshot(unsigned int p_id, const string& tag, + string& error) +{ + VectorAttribute * parent = get_snapshot(p_id); + + if (parent == 0) + { + error = "Parent snapshot not found."; + return -1; + } + + string psource = parent->vector_value("SOURCE"); + + if (psource.empty()) + { + error = "Parent snapshot has no source."; + return -1; + } + + VectorAttribute * snapshot = new VectorAttribute("SNAPSHOT"); + + if (!tag.empty()) + { + snapshot->replace("TAG",tag); + } + + snapshot->replace("ID", next_snapshot++); + + snapshot->replace("DATE", static_cast(time(0))); + + snapshot->replace("PARENT", psource); + + snapshot_template.set(snapshot); + + snapshot_pool.insert(pair(next_snapshot, snapshot)); + + return next_snapshot; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Snapshots::delete_snapshot(unsigned int id) +{ + VectorAttribute * snapshot = get_snapshot(id); + + if (snapshot == 0) + { + return -1; + } + + bool current; + + snapshot->vector_value("ACTIVE", current); + + if (current) + { + return -1; + } + + snapshot_template.remove(snapshot); + + delete snapshot; + + snapshot_pool.erase(id); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Snapshots::active_snapshot(unsigned int id) +{ + VectorAttribute * snapshot = get_snapshot(id); + + if (snapshot == 0) + { + return -1; + } + + snapshot->replace("ACTIVE", true); + + snapshot = get_snapshot(active); + + if (snapshot != 0) + { + snapshot->remove("ACTIVE"); + } + + active = id; + + return 0; +} + + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +VectorAttribute * Snapshots::get_snapshot(unsigned int id) +{ + map::iterator it; + + it = snapshot_pool.find(id); + + if (it == snapshot_pool.end()) + { + return 0; + } + + return it->second; +}; +