diff options
author | Roger Leigh <rleigh@debian.org> | 2013-04-07 19:12:45 +0100 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2013-04-07 19:12:45 +0100 |
commit | 9a90d2d28ff6624636170a177548f32f1b85cf93 (patch) | |
tree | 3f9100c28d82a111b663aed9197e7766b88f69e3 /lib | |
parent | 672cece52e18c0f3b4ea1119b132688e6683b069 (diff) | |
download | schroot-9a90d2d28ff6624636170a177548f32f1b85cf93.tar.gz |
sbuild: Move chroot-block-device and chroot-lvm-snapshot to namespace chroot
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sbuild/Makefile.am | 16 | ||||
-rw-r--r-- | lib/sbuild/chroot-block-device-base.cc | 135 | ||||
-rw-r--r-- | lib/sbuild/chroot-block-device-base.h | 109 | ||||
-rw-r--r-- | lib/sbuild/chroot-block-device.cc | 201 | ||||
-rw-r--r-- | lib/sbuild/chroot-block-device.h | 114 | ||||
-rw-r--r-- | lib/sbuild/chroot-facet-session-clonable.cc | 8 | ||||
-rw-r--r-- | lib/sbuild/chroot-facet-session.cc | 6 | ||||
-rw-r--r-- | lib/sbuild/chroot-lvm-snapshot.cc | 263 | ||||
-rw-r--r-- | lib/sbuild/chroot-lvm-snapshot.h | 141 | ||||
-rw-r--r-- | lib/sbuild/chroot/block-device-base.cc | 143 | ||||
-rw-r--r-- | lib/sbuild/chroot/block-device-base.h | 112 | ||||
-rw-r--r-- | lib/sbuild/chroot/block-device.cc | 209 | ||||
-rw-r--r-- | lib/sbuild/chroot/block-device.h | 117 | ||||
-rw-r--r-- | lib/sbuild/chroot/chroot.cc | 8 | ||||
-rw-r--r-- | lib/sbuild/chroot/lvm-snapshot.cc | 271 | ||||
-rw-r--r-- | lib/sbuild/chroot/lvm-snapshot.h | 144 |
16 files changed, 1012 insertions, 985 deletions
diff --git a/lib/sbuild/Makefile.am b/lib/sbuild/Makefile.am index 126e69a6..9b509e69 100644 --- a/lib/sbuild/Makefile.am +++ b/lib/sbuild/Makefile.am @@ -71,16 +71,16 @@ endif if BUILD_BLOCKDEV lib_sbuild_public_blockdev_base_h_sources = \ - lib/sbuild/chroot-block-device-base.h + lib/sbuild/chroot/block-device-base.h lib_sbuild_public_blockdev_h_sources = \ - lib/sbuild/chroot-block-device.h + lib/sbuild/chroot/block-device.h endif if BUILD_LVMSNAP lib_sbuild_public_blockdev_base_h_sources = \ - lib/sbuild/chroot-block-device-base.h + lib/sbuild/chroot/block-device-base.h lib_sbuild_public_lvmsnap_h_sources = \ - lib/sbuild/chroot-lvm-snapshot.h + lib/sbuild/chroot/lvm-snapshot.h endif if BUILD_BTRFSSNAP @@ -148,16 +148,16 @@ endif if BUILD_BLOCKDEV lib_sbuild_public_blockdev_base_cc_sources = \ - lib/sbuild/chroot-block-device-base.cc + lib/sbuild/chroot/block-device-base.cc lib_sbuild_public_blockdev_cc_sources = \ - lib/sbuild/chroot-block-device.cc + lib/sbuild/chroot/block-device.cc endif if BUILD_LVMSNAP lib_sbuild_public_blockdev_base_cc_sources = \ - lib/sbuild/chroot-block-device-base.cc + lib/sbuild/chroot/block-device-base.cc lib_sbuild_public_lvmsnap_cc_sources = \ - lib/sbuild/chroot-lvm-snapshot.cc + lib/sbuild/chroot/lvm-snapshot.cc endif if BUILD_BTRFSSNAP diff --git a/lib/sbuild/chroot-block-device-base.cc b/lib/sbuild/chroot-block-device-base.cc deleted file mode 100644 index ce77fd42..00000000 --- a/lib/sbuild/chroot-block-device-base.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> - * - * schroot is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - *********************************************************************/ - -#include <config.h> - -#include "chroot-block-device.h" -#include "chroot-lvm-snapshot.h" -#include "chroot-facet-mountable.h" -#include "format-detail.h" -#include "lock.h" -#include "util.h" - -#include <cerrno> -#include <cstring> - -#include <boost/format.hpp> - -using boost::format; -using namespace sbuild; - -chroot_block_device_base::chroot_block_device_base (): - chroot(), - device() -{ - add_facet(chroot_facet_mountable::create()); -} - -chroot_block_device_base::chroot_block_device_base -(const chroot_block_device_base& rhs): - chroot(rhs), - device(rhs.device) -{ -} - -chroot_block_device_base::~chroot_block_device_base () -{ -} - -std::string const& -chroot_block_device_base::get_device () const -{ - return this->device; -} - -void -chroot_block_device_base::set_device (std::string const& device) -{ - if (!is_absname(device)) - throw error(device, DEVICE_ABS); - - this->device = device; -} - -std::string -chroot_block_device_base::get_path () const -{ - chroot_facet_mountable::const_ptr pmnt - (get_facet<chroot_facet_mountable>()); - - std::string path(get_mount_location()); - - if (pmnt) - path += pmnt->get_location(); - - return path; -} - -void -chroot_block_device_base::setup_env (chroot const& chroot, - environment& env) const -{ - chroot::setup_env(chroot, env); - - env.add("CHROOT_DEVICE", get_device()); -} - -chroot::chroot::session_flags -chroot_block_device_base::get_session_flags (chroot const& chroot) const -{ - return SESSION_NOFLAGS; -} - -void -chroot_block_device_base::get_details (chroot const& chroot, - format_detail& detail) const -{ - this->chroot::get_details(chroot, detail); - - if (!this->device.empty()) - detail.add(_("Device"), get_device()); -} - -void -chroot_block_device_base::get_used_keys (string_list& used_keys) const -{ - chroot::get_used_keys(used_keys); - - used_keys.push_back("device"); -} - -void -chroot_block_device_base::get_keyfile (chroot const& chroot, - keyfile& keyfile) const -{ - chroot::get_keyfile(chroot, keyfile); - - keyfile::set_object_value(*this, &chroot_block_device_base::get_device, - keyfile, get_name(), "device"); -} - -void -chroot_block_device_base::set_keyfile (chroot& chroot, - keyfile const& keyfile) -{ - chroot::set_keyfile(chroot, keyfile); - - keyfile::get_object_value(*this, &chroot_block_device_base::set_device, - keyfile, get_name(), "device", - keyfile::PRIORITY_REQUIRED); -} diff --git a/lib/sbuild/chroot-block-device-base.h b/lib/sbuild/chroot-block-device-base.h deleted file mode 100644 index a105b8fe..00000000 --- a/lib/sbuild/chroot-block-device-base.h +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> - * - * schroot is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_BLOCK_DEVICE_BASE_H -#define SBUILD_CHROOT_BLOCK_DEVICE_BASE_H - -#include <sbuild/chroot/chroot.h> - -namespace sbuild -{ - - /** - * A base class for block-device chroots. - * - * This class doesn't implement a chroot (get_chroot_type - * is not implemented). - * - * Originally lvm-snapshot inherited from the block-device chroot, - * but this was changed when union support was introduced. This - * design prevents lvm-snapshot offering union based sessions. - */ - class chroot_block_device_base : public chroot::chroot - { - protected: - /// The constructor. - chroot_block_device_base (); - - /// The copy constructor. - chroot_block_device_base (const chroot_block_device_base& rhs); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_block_device_base (); - - /** - * Get the block device of the chroot. - * - * @returns the device. - */ - std::string const& - get_device () const; - - /** - * Set the block device of the chroot. This is the "source" device. - * It may be the case that the real device is different (for - * example, an LVM snapshot PV), but by default will be the device - * to mount. - * - * @param device the device. - */ - void - set_device (std::string const& device); - - virtual std::string - get_path () const; - - virtual void - setup_env (chroot const& chroot, - environment& env) const; - - virtual session_flags - get_session_flags (chroot const& chroot) const; - - protected: - virtual void - get_details (chroot const& chroot, - format_detail& detail) const; - - virtual void - get_used_keys (string_list& used_keys) const; - - virtual void - get_keyfile (chroot const& chroot, - keyfile& keyfile) const; - - virtual void - set_keyfile (chroot& chroot, - keyfile const& keyfile); - - /// The block device to use. - std::string device; - }; - -} - -#endif /* SBUILD_CHROOT_BLOCK_DEVICE_BASE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/lib/sbuild/chroot-block-device.cc b/lib/sbuild/chroot-block-device.cc deleted file mode 100644 index 28ecb104..00000000 --- a/lib/sbuild/chroot-block-device.cc +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> - * - * schroot is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - *********************************************************************/ - -#include <config.h> - -#include "chroot-block-device.h" -#include "chroot-facet-session-clonable.h" -#include "chroot-facet-source-clonable.h" -#ifdef SBUILD_FEATURE_UNION -#include "chroot-facet-union.h" -#endif // SBUILD_FEATURE_UNION -#include "format-detail.h" -#include "util.h" - -#include <cassert> -#include <cerrno> -#include <cstring> - -#include <boost/format.hpp> - -using boost::format; -using namespace sbuild; - -chroot_block_device::chroot_block_device (): - chroot_block_device_base() -{ -#ifdef SBUILD_FEATURE_UNION - add_facet(chroot_facet_union::create()); -#endif // SBUILD_FEATURE_UNION -} - -chroot_block_device::~chroot_block_device () -{ -} - -chroot_block_device::chroot_block_device (const chroot_block_device& rhs): - chroot_block_device_base(rhs) -{ -} - -#ifdef SBUILD_FEATURE_LVMSNAP -chroot_block_device::chroot_block_device (const chroot_lvm_snapshot& rhs): - chroot_block_device_base(rhs) -{ -#ifdef SBUILD_FEATURE_UNION - if (!get_facet<chroot_facet_union>()) - add_facet(chroot_facet_union::create()); -#endif // SBUILD_FEATURE_UNION -} -#endif // SBUILD_FEATURE_LVMSNAP - -chroot::chroot::ptr -chroot_block_device::clone () const -{ - return ptr(new chroot_block_device(*this)); -} - -chroot::chroot::ptr -chroot_block_device::clone_session (std::string const& session_id, - std::string const& alias, - std::string const& user, - bool root) const -{ - chroot_facet_session_clonable::const_ptr psess - (get_facet<chroot_facet_session_clonable>()); - assert(psess); - - ptr session(new chroot_block_device(*this)); - psess->clone_session_setup(*this, session, session_id, alias, user, root); - - return session; -} - -chroot::chroot::ptr -chroot_block_device::clone_source () const -{ - ptr clone(new chroot_block_device(*this)); - - chroot_facet_source_clonable::const_ptr psrc - (get_facet<chroot_facet_source_clonable>()); - assert(psrc); - - psrc->clone_source_setup(*this, clone); - - return clone; -} - -void -chroot_block_device::setup_env (chroot const& chroot, - environment& env) const -{ - chroot_block_device_base::setup_env(chroot, env); -} - -void -chroot_block_device::setup_lock (chroot::setup_type type, - bool lock, - int status) -{ - /* Lock is preserved through the entire session. */ - if ((type == SETUP_START && lock == false) || - (type == SETUP_STOP && lock == true)) - return; - - try - { - if (!stat -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - (this->get_device()).is_character() -#else - (this->get_device()).is_block() -#endif - ) - { - throw error(get_device(), DEVICE_NOTBLOCK); - } - else - { -#ifdef SBUILD_FEATURE_UNION - /* We don't lock the device if union is configured. */ - const chroot *base = dynamic_cast<const chroot *>(this); - assert(base); - chroot_facet_union::const_ptr puni - (base->get_facet<chroot_facet_union>()); -#endif - } - } - catch (sbuild::stat::error const& e) // Failed to stat - { - // Don't throw if stopping a session and the device stat - // failed. This is because the setup scripts shouldn't fail - // to be run if the block device no longer exists, which - // would prevent the session from being ended. - if (type != SETUP_STOP) - throw; - } - - /* Create or unlink session information. */ - if ((type == SETUP_START && lock == true) || - (type == SETUP_STOP && lock == false && status == 0)) - { - bool start = (type == SETUP_START); - setup_session_info(start); - } -} - -std::string const& -chroot_block_device::get_chroot_type () const -{ - static const std::string type("block-device"); - - return type; -} - -chroot::chroot::session_flags -chroot_block_device::get_session_flags (chroot const& chroot) const -{ - return chroot_block_device_base::get_session_flags(chroot); -} - -void -chroot_block_device::get_details (chroot const& chroot, - format_detail& detail) const -{ - chroot_block_device_base::get_details(chroot, detail); -} - -void -chroot_block_device::get_used_keys (string_list& used_keys) const -{ - chroot_block_device_base::get_used_keys(used_keys); -} - -void -chroot_block_device::get_keyfile (chroot const& chroot, - keyfile& keyfile) const -{ - chroot_block_device_base::get_keyfile(chroot, keyfile); -} - -void -chroot_block_device::set_keyfile (chroot& chroot, - keyfile const& keyfile) -{ - chroot_block_device_base::set_keyfile(chroot, keyfile); -} diff --git a/lib/sbuild/chroot-block-device.h b/lib/sbuild/chroot-block-device.h deleted file mode 100644 index 7494eb28..00000000 --- a/lib/sbuild/chroot-block-device.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> - * - * schroot is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_BLOCK_DEVICE_H -#define SBUILD_CHROOT_BLOCK_DEVICE_H - -#include <sbuild/config.h> -#include <sbuild/chroot-block-device-base.h> -#include <sbuild/chroot-lvm-snapshot.h> - -namespace sbuild -{ - - /** - * A chroot stored on an unmounted block device. - * - * The device will be mounted on demand. - */ - class chroot_block_device : public chroot_block_device_base - { - public: - /// Exception type. - typedef chroot::error error; - - protected: - /// The constructor. - chroot_block_device (); - - /// The copy constructor. - chroot_block_device (const chroot_block_device& rhs); - -#ifdef SBUILD_FEATURE_LVMSNAP - /// The copy constructor. - chroot_block_device (const chroot_lvm_snapshot& rhs); -#endif - - friend class chroot; -#ifdef SBUILD_FEATURE_LVMSNAP - friend class chroot_lvm_snapshot; -#endif - - public: - /// The destructor. - virtual ~chroot_block_device (); - - virtual chroot::ptr - clone () const; - - virtual chroot::ptr - clone_session (std::string const& session_id, - std::string const& alias, - std::string const& user, - bool root) const; - - virtual chroot::ptr - clone_source () const; - - std::string const& - get_chroot_type () const; - - virtual void - setup_env (chroot const& chroot, - environment& env) const; - - virtual session_flags - get_session_flags (chroot const& chroot) const; - - protected: - virtual void - setup_lock (chroot::setup_type type, - bool lock, - int status); - - - virtual void - get_details (chroot const& chroot, - format_detail& detail) const; - - virtual void - get_used_keys (string_list& used_keys) const; - - virtual void - get_keyfile (chroot const& chroot, - keyfile& keyfile) const; - - virtual void - set_keyfile (chroot& chroot, - keyfile const& keyfile); - }; - -} - -#endif /* SBUILD_CHROOT_BLOCK_DEVICE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/lib/sbuild/chroot-facet-session-clonable.cc b/lib/sbuild/chroot-facet-session-clonable.cc index ac3e330f..3475d609 100644 --- a/lib/sbuild/chroot-facet-session-clonable.cc +++ b/lib/sbuild/chroot-facet-session-clonable.cc @@ -25,10 +25,10 @@ #include "chroot-facet-source-clonable.h" #include <sbuild/chroot/plain.h> #ifdef SBUILD_FEATURE_BLOCKDEV -#include "chroot-block-device-base.h" +#include <sbuild/chroot/block-device-base.h> #endif #ifdef SBUILD_FEATURE_LVMSNAP -#include "chroot-lvm-snapshot.h" +#include <sbuild/chroot/lvm-snapshot.h> #endif // SBUILD_FEATURE_LVMSNAP #ifdef SBUILD_FEATURE_LOOPBACK #include "chroot-loopback.h" @@ -150,7 +150,7 @@ chroot_facet_session_clonable::clone_session_setup (chroot::chroot const& parent /* Block devices need the mount device name specifying. */ /* Note that this will be overridden by LVM snapshot, below, so the order here is important. */ - std::shared_ptr<chroot_block_device_base> blockdevbase(std::dynamic_pointer_cast<chroot_block_device_base>(clone)); + std::shared_ptr<chroot::block_device_base> blockdevbase(std::dynamic_pointer_cast<chroot::block_device_base>(clone)); if (blockdevbase) { chroot_facet_mountable::ptr pmnt @@ -174,7 +174,7 @@ chroot_facet_session_clonable::clone_session_setup (chroot::chroot const& parent #ifdef SBUILD_FEATURE_LVMSNAP /* LVM devices need the snapshot device name specifying. */ - std::shared_ptr<chroot_lvm_snapshot> snapshot(std::dynamic_pointer_cast<chroot_lvm_snapshot>(clone)); + std::shared_ptr<chroot::lvm_snapshot> snapshot(std::dynamic_pointer_cast<chroot::lvm_snapshot>(clone)); if (snapshot && !snapshot->get_device().empty()) { std::string device(dirname(snapshot->get_device())); diff --git a/lib/sbuild/chroot-facet-session.cc b/lib/sbuild/chroot-facet-session.cc index c0012fa3..d72b7bfe 100644 --- a/lib/sbuild/chroot-facet-session.cc +++ b/lib/sbuild/chroot-facet-session.cc @@ -22,12 +22,6 @@ #include <sbuild/chroot/config.h> #include "chroot-facet-session.h" #include "chroot-facet-source-clonable.h" -#ifdef SBUILD_FEATURE_LVMSNAP -#include "chroot-lvm-snapshot.h" -#endif // SBUILD_FEATURE_LVMSNAP -#ifdef SBUILD_FEATURE_UNION -#include "chroot-facet-union.h" -#endif // SBUILD_FEATURE_UNION #include "format-detail.h" #include <cassert> diff --git a/lib/sbuild/chroot-lvm-snapshot.cc b/lib/sbuild/chroot-lvm-snapshot.cc deleted file mode 100644 index be8484e9..00000000 --- a/lib/sbuild/chroot-lvm-snapshot.cc +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> - * - * schroot is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - *********************************************************************/ - -#include <config.h> - -#include "chroot-lvm-snapshot.h" -#include "chroot-block-device.h" -#include "chroot-facet-session.h" -#include "chroot-facet-session-clonable.h" -#include "chroot-facet-source-clonable.h" -#include "chroot-facet-mountable.h" -#include "format-detail.h" - -#include <cassert> -#include <cerrno> - -#include <boost/format.hpp> - -using std::endl; -using boost::format; -using namespace sbuild; - -chroot_lvm_snapshot::chroot_lvm_snapshot (): - chroot_block_device_base(), - snapshot_device(), - snapshot_options() -{ - add_facet(chroot_facet_source_clonable::create()); -} - -chroot_lvm_snapshot::chroot_lvm_snapshot (const chroot_lvm_snapshot& rhs): - chroot_block_device_base(rhs), - snapshot_device(rhs.snapshot_device), - snapshot_options(rhs.snapshot_options) -{ -} - -chroot_lvm_snapshot::~chroot_lvm_snapshot () -{ -} - -chroot::chroot::ptr -chroot_lvm_snapshot::clone () const -{ - return ptr(new chroot_lvm_snapshot(*this)); -} - -chroot::chroot::ptr -chroot_lvm_snapshot::clone_session (std::string const& session_id, - std::string const& alias, - std::string const& user, - bool root) const -{ - chroot_facet_session_clonable::const_ptr psess - (get_facet<chroot_facet_session_clonable>()); - assert(psess); - - ptr session(new chroot_lvm_snapshot(*this)); - psess->clone_session_setup(*this, session, session_id, alias, user, root); - - return session; -} - -chroot::chroot::ptr -chroot_lvm_snapshot::clone_source () const -{ - ptr clone(new chroot_block_device(*this)); - - chroot_facet_source_clonable::const_ptr psrc - (get_facet<chroot_facet_source_clonable>()); - assert(psrc); - - psrc->clone_source_setup(*this, clone); - - return clone; -} - -std::string const& -chroot_lvm_snapshot::get_snapshot_device () const -{ - return this->snapshot_device; -} - -void -chroot_lvm_snapshot::set_snapshot_device (std::string const& snapshot_device) -{ - if (!is_absname(snapshot_device)) - throw error(snapshot_device, DEVICE_ABS); - - this->snapshot_device = snapshot_device; - - chroot_facet_mountable::ptr pmnt - (get_facet<chroot_facet_mountable>()); - if (pmnt) - pmnt->set_mount_device(this->snapshot_device); -} - -std::string const& -chroot_lvm_snapshot::get_snapshot_options () const -{ - return this->snapshot_options; -} - -void -chroot_lvm_snapshot::set_snapshot_options (std::string const& snapshot_options) -{ - this->snapshot_options = snapshot_options; -} - -std::string const& -chroot_lvm_snapshot::get_chroot_type () const -{ - static const std::string type("lvm-snapshot"); - - return type; -} - -void -chroot_lvm_snapshot::setup_env (chroot const& chroot, - environment& env) const -{ - chroot_block_device_base::setup_env(chroot, env); - - env.add("CHROOT_LVM_SNAPSHOT_NAME", sbuild::basename(get_snapshot_device())); - env.add("CHROOT_LVM_SNAPSHOT_DEVICE", get_snapshot_device()); - env.add("CHROOT_LVM_SNAPSHOT_OPTIONS", get_snapshot_options()); -} - -void -chroot_lvm_snapshot::setup_lock (chroot::setup_type type, - bool lock, - int status) -{ - std::string device; - - /* Lock is removed by setup script on setup stop. Unlocking here - would fail: the LVM snapshot device no longer exists. */ - if (!(type == SETUP_STOP && lock == false)) - { - if (type == SETUP_START) - device = get_device(); - else - device = get_snapshot_device(); - - if (device.empty()) - throw error(CHROOT_DEVICE); - - try - { - stat file_status(device); - if (!file_status.is_block()) - { - throw error(get_device(), DEVICE_NOTBLOCK); - } - } - catch (sbuild::stat::error const& e) // Failed to stat - { - // Don't throw if stopping a session and the device stat - // failed. This is because the setup scripts shouldn't fail - // to be run if the LVM snapshot no longer exists, which - // would prevent the session from being ended. - if (type != SETUP_STOP) - throw; - } - } - - /* Create or unlink session information. */ - if ((type == SETUP_START && lock == true) || - (type == SETUP_STOP && lock == false && status == 0)) - { - bool start = (type == SETUP_START); - setup_session_info(start); - } -} - -chroot::chroot::session_flags -chroot_lvm_snapshot::get_session_flags (chroot const& chroot) const -{ - session_flags flags = SESSION_NOFLAGS; - - if (get_facet<chroot_facet_session>()) - flags = flags | SESSION_PURGE; - - return flags; -} - -void -chroot_lvm_snapshot::get_details (chroot const& chroot, - format_detail& detail) const -{ - chroot_block_device_base::get_details(chroot, detail); - - if (!this->snapshot_device.empty()) - detail.add(_("LVM Snapshot Device"), get_snapshot_device()); - if (!this->snapshot_options.empty()) - detail.add(_("LVM Snapshot Options"), get_snapshot_options()); -} - -void -chroot_lvm_snapshot::get_used_keys (string_list& used_keys) const -{ - chroot_block_device_base::get_used_keys(used_keys); - - used_keys.push_back("lvm-snapshot-device"); - used_keys.push_back("lvm-snapshot-options"); -} - -void -chroot_lvm_snapshot::get_keyfile (chroot const& chroot, - keyfile& keyfile) const -{ - chroot_block_device_base::get_keyfile(chroot, keyfile); - - bool session = static_cast<bool>(get_facet<chroot_facet_session>()); - - if (session) - keyfile::set_object_value(*this, - &chroot_lvm_snapshot::get_snapshot_device, - keyfile, get_name(), - "lvm-snapshot-device"); - - if (!session) - keyfile::set_object_value(*this, - &chroot_lvm_snapshot::get_snapshot_options, - keyfile, get_name(), - "lvm-snapshot-options"); -} - -void -chroot_lvm_snapshot::set_keyfile (chroot& chroot, - keyfile const& keyfile) -{ - chroot_block_device_base::set_keyfile(chroot, keyfile); - - bool session = static_cast<bool>(get_facet<chroot_facet_session>()); - - keyfile::get_object_value(*this, &chroot_lvm_snapshot::set_snapshot_device, - keyfile, get_name(), "lvm-snapshot-device", - session ? - keyfile::PRIORITY_REQUIRED : - keyfile::PRIORITY_DISALLOWED); - - keyfile::get_object_value(*this, &chroot_lvm_snapshot::set_snapshot_options, - keyfile, get_name(), "lvm-snapshot-options", - session ? - keyfile::PRIORITY_DEPRECATED : - keyfile::PRIORITY_REQUIRED); // Only needed for creating snapshot, not using snapshot -} diff --git a/lib/sbuild/chroot-lvm-snapshot.h b/lib/sbuild/chroot-lvm-snapshot.h deleted file mode 100644 index fbd20158..00000000 --- a/lib/sbuild/chroot-lvm-snapshot.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> - * - * schroot is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_LVM_SNAPSHOT_H -#define SBUILD_CHROOT_LVM_SNAPSHOT_H - -#include <sbuild/chroot-block-device-base.h> - -namespace sbuild -{ - - /** - * A chroot stored on an LVM logical volume (LV). - * - * A snapshot LV will be created and mounted on demand. - */ - class chroot_lvm_snapshot : public chroot_block_device_base - { - protected: - /// The constructor. - chroot_lvm_snapshot (); - - /// The copy constructor. - chroot_lvm_snapshot (const chroot_lvm_snapshot& rhs); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_lvm_snapshot (); - - virtual chroot::ptr - clone () const; - - virtual chroot::ptr - clone_session (std::string const& session_id, - std::string const& alias, - std::string const& user, - bool root) const; - - virtual chroot::ptr - clone_source () const; - - /** - * Get the logical volume snapshot device name. This is used by - * lvcreate. - * - * @returns the device name. - */ - std::string const& - get_snapshot_device () const; - - /** - * Set the logical volume snapshot device name. This is used by - * lvcreate. - * - * @param snapshot_device the device name. - */ - void - set_snapshot_device (std::string const& snapshot_device); - - /** - * Get the logical volume snapshot options. These are used by - * lvcreate. - * - * @returns the options. - */ - std::string const& - get_snapshot_options () const; - - /** - * Set the logical volume snapshot options. These are used by - * lvcreate. - * - * @param snapshot_options the options. - */ - void - set_snapshot_options (std::string const& snapshot_options); - - virtual std::string const& - get_chroot_type () const; - - virtual void - setup_env (chroot const& chroot, - environment& env) const; - - virtual session_flags - get_session_flags (chroot const& chroot) const; - - protected: - virtual void - setup_lock (chroot::setup_type type, - bool lock, - int status); - - virtual void - get_details (chroot const& chroot, - format_detail& detail) const; - - virtual void - get_used_keys (string_list& used_keys) const; - - virtual void - get_keyfile (chroot const& chroot, - keyfile& keyfile) const; - - virtual void - set_keyfile (chroot& chroot, - keyfile const& keyfile); - - private: - /// LVM snapshot device name for lvcreate. - std::string snapshot_device; - /// LVM snapshot options for lvcreate. - std::string snapshot_options; - }; - -} - -#endif /* SBUILD_CHROOT_LVM_SNAPSHOT_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/lib/sbuild/chroot/block-device-base.cc b/lib/sbuild/chroot/block-device-base.cc new file mode 100644 index 00000000..4f8cbf9c --- /dev/null +++ b/lib/sbuild/chroot/block-device-base.cc @@ -0,0 +1,143 @@ +/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include <sbuild/chroot/block-device-base.h> +#include <sbuild/chroot/lvm-snapshot.h> +#include "chroot-facet-mountable.h" +#include "format-detail.h" +#include "lock.h" +#include "util.h" + +#include <cerrno> +#include <cstring> + +#include <boost/format.hpp> + +using boost::format; +using namespace sbuild; + +namespace sbuild +{ + namespace chroot + { + + block_device_base::block_device_base (): + chroot(), + device() + { + add_facet(chroot_facet_mountable::create()); + } + + block_device_base::block_device_base + (const block_device_base& rhs): + chroot(rhs), + device(rhs.device) + { + } + + block_device_base::~block_device_base () + { + } + + std::string const& + block_device_base::get_device () const + { + return this->device; + } + + void + block_device_base::set_device (std::string const& device) + { + if (!is_absname(device)) + throw error(device, DEVICE_ABS); + + this->device = device; + } + + std::string + block_device_base::get_path () const + { + chroot_facet_mountable::const_ptr pmnt + (get_facet<chroot_facet_mountable>()); + + std::string path(get_mount_location()); + + if (pmnt) + path += pmnt->get_location(); + + return path; + } + + void + block_device_base::setup_env (chroot const& chroot, + environment& env) const + { + chroot::setup_env(chroot, env); + + env.add("CHROOT_DEVICE", get_device()); + } + + chroot::chroot::session_flags + block_device_base::get_session_flags (chroot const& chroot) const + { + return SESSION_NOFLAGS; + } + + void + block_device_base::get_details (chroot const& chroot, + format_detail& detail) const + { + this->chroot::get_details(chroot, detail); + + if (!this->device.empty()) + detail.add(_("Device"), get_device()); + } + + void + block_device_base::get_used_keys (string_list& used_keys) const + { + chroot::get_used_keys(used_keys); + + used_keys.push_back("device"); + } + + void + block_device_base::get_keyfile (chroot const& chroot, + keyfile& keyfile) const + { + chroot::get_keyfile(chroot, keyfile); + + keyfile::set_object_value(*this, &block_device_base::get_device, + keyfile, get_name(), "device"); + } + + void + block_device_base::set_keyfile (chroot& chroot, + keyfile const& keyfile) + { + chroot::set_keyfile(chroot, keyfile); + + keyfile::get_object_value(*this, &block_device_base::set_device, + keyfile, get_name(), "device", + keyfile::PRIORITY_REQUIRED); + } + + } +} diff --git a/lib/sbuild/chroot/block-device-base.h b/lib/sbuild/chroot/block-device-base.h new file mode 100644 index 00000000..b907809c --- /dev/null +++ b/lib/sbuild/chroot/block-device-base.h @@ -0,0 +1,112 @@ +/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_BLOCK_DEVICE_BASE_H +#define SBUILD_CHROOT_BLOCK_DEVICE_BASE_H + +#include <sbuild/chroot/chroot.h> + +namespace sbuild +{ + namespace chroot + { + + /** + * A base class for block-device chroots. + * + * This class doesn't implement a chroot (get_chroot_type + * is not implemented). + * + * Originally lvm-snapshot inherited from the block-device chroot, + * but this was changed when union support was introduced. This + * design prevents lvm-snapshot offering union based sessions. + */ + class block_device_base : public chroot::chroot + { + protected: + /// The constructor. + block_device_base (); + + /// The copy constructor. + block_device_base (const block_device_base& rhs); + + friend class chroot; + + public: + /// The destructor. + virtual ~block_device_base (); + + /** + * Get the block device of the chroot. + * + * @returns the device. + */ + std::string const& + get_device () const; + + /** + * Set the block device of the chroot. This is the "source" device. + * It may be the case that the real device is different (for + * example, an LVM snapshot PV), but by default will be the device + * to mount. + * + * @param device the device. + */ + void + set_device (std::string const& device); + + virtual std::string + get_path () const; + + virtual void + setup_env (chroot const& chroot, + environment& env) const; + + virtual session_flags + get_session_flags (chroot const& chroot) const; + + protected: + virtual void + get_details (chroot const& chroot, + format_detail& detail) const; + + virtual void + get_used_keys (string_list& used_keys) const; + + virtual void + get_keyfile (chroot const& chroot, + keyfile& keyfile) const; + + virtual void + set_keyfile (chroot& chroot, + keyfile const& keyfile); + + /// The block device to use. + std::string device; + }; + + } +} + +#endif /* SBUILD_CHROOT_BLOCK_DEVICE_BASE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/lib/sbuild/chroot/block-device.cc b/lib/sbuild/chroot/block-device.cc new file mode 100644 index 00000000..27718971 --- /dev/null +++ b/lib/sbuild/chroot/block-device.cc @@ -0,0 +1,209 @@ +/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include <sbuild/chroot/block-device.h> +#include "chroot-facet-session-clonable.h" +#include "chroot-facet-source-clonable.h" +#ifdef SBUILD_FEATURE_UNION +#include "chroot-facet-union.h" +#endif // SBUILD_FEATURE_UNION +#include "format-detail.h" +#include "util.h" + +#include <cassert> +#include <cerrno> +#include <cstring> + +#include <boost/format.hpp> + +using boost::format; +using namespace sbuild; + +namespace sbuild +{ + namespace chroot + { + + block_device::block_device (): + block_device_base() + { +#ifdef SBUILD_FEATURE_UNION + add_facet(chroot_facet_union::create()); +#endif // SBUILD_FEATURE_UNION + } + + block_device::~block_device () + { + } + + block_device::block_device (const block_device& rhs): + block_device_base(rhs) + { + } + +#ifdef SBUILD_FEATURE_LVMSNAP + block_device::block_device (const lvm_snapshot& rhs): + block_device_base(rhs) + { +#ifdef SBUILD_FEATURE_UNION + if (!get_facet<chroot_facet_union>()) + add_facet(chroot_facet_union::create()); +#endif // SBUILD_FEATURE_UNION + } +#endif // SBUILD_FEATURE_LVMSNAP + + chroot::chroot::ptr + block_device::clone () const + { + return ptr(new block_device(*this)); + } + + chroot::chroot::ptr + block_device::clone_session (std::string const& session_id, + std::string const& alias, + std::string const& user, + bool root) const + { + chroot_facet_session_clonable::const_ptr psess + (get_facet<chroot_facet_session_clonable>()); + assert(psess); + + ptr session(new block_device(*this)); + psess->clone_session_setup(*this, session, session_id, alias, user, root); + + return session; + } + + chroot::chroot::ptr + block_device::clone_source () const + { + ptr clone(new block_device(*this)); + + chroot_facet_source_clonable::const_ptr psrc + (get_facet<chroot_facet_source_clonable>()); + assert(psrc); + + psrc->clone_source_setup(*this, clone); + + return clone; + } + + void + block_device::setup_env (chroot const& chroot, + environment& env) const + { + block_device_base::setup_env(chroot, env); + } + + void + block_device::setup_lock (chroot::setup_type type, + bool lock, + int status) + { + /* Lock is preserved through the entire session. */ + if ((type == SETUP_START && lock == false) || + (type == SETUP_STOP && lock == true)) + return; + + try + { + if (!stat +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + (this->get_device()).is_character() +#else + (this->get_device()).is_block() +#endif + ) + { + throw error(get_device(), DEVICE_NOTBLOCK); + } + else + { +#ifdef SBUILD_FEATURE_UNION + /* We don't lock the device if union is configured. */ + const chroot *base = dynamic_cast<const chroot *>(this); + assert(base); + chroot_facet_union::const_ptr puni + (base->get_facet<chroot_facet_union>()); +#endif + } + } + catch (sbuild::stat::error const& e) // Failed to stat + { + // Don't throw if stopping a session and the device stat + // failed. This is because the setup scripts shouldn't fail + // to be run if the block device no longer exists, which + // would prevent the session from being ended. + if (type != SETUP_STOP) + throw; + } + + /* Create or unlink session information. */ + if ((type == SETUP_START && lock == true) || + (type == SETUP_STOP && lock == false && status == 0)) + { + bool start = (type == SETUP_START); + setup_session_info(start); + } + } + + std::string const& + block_device::get_chroot_type () const + { + static const std::string type("block-device"); + + return type; + } + + chroot::chroot::session_flags + block_device::get_session_flags (chroot const& chroot) const + { + return block_device_base::get_session_flags(chroot); + } + + void + block_device::get_details (chroot const& chroot, + format_detail& detail) const + { + block_device_base::get_details(chroot, detail); + } + + void + block_device::get_used_keys (string_list& used_keys) const + { + block_device_base::get_used_keys(used_keys); + } + + void + block_device::get_keyfile (chroot const& chroot, + keyfile& keyfile) const + { + block_device_base::get_keyfile(chroot, keyfile); + } + + void + block_device::set_keyfile (chroot& chroot, + keyfile const& keyfile) + { + block_device_base::set_keyfile(chroot, keyfile); + } + + } +} diff --git a/lib/sbuild/chroot/block-device.h b/lib/sbuild/chroot/block-device.h new file mode 100644 index 00000000..7619e994 --- /dev/null +++ b/lib/sbuild/chroot/block-device.h @@ -0,0 +1,117 @@ +/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_BLOCK_DEVICE_H +#define SBUILD_CHROOT_BLOCK_DEVICE_H + +#include <sbuild/config.h> +#include <sbuild/chroot/block-device-base.h> +#include <sbuild/chroot/lvm-snapshot.h> + +namespace sbuild +{ + namespace chroot + { + + /** + * A chroot stored on an unmounted block device. + * + * The device will be mounted on demand. + */ + class block_device : public block_device_base + { + public: + /// Exception type. + typedef chroot::error error; + + protected: + /// The constructor. + block_device (); + + /// The copy constructor. + block_device (const block_device& rhs); + +#ifdef SBUILD_FEATURE_LVMSNAP + /// The copy constructor. + block_device (const lvm_snapshot& rhs); +#endif + + friend class chroot; +#ifdef SBUILD_FEATURE_LVMSNAP + friend class lvm_snapshot; +#endif + + public: + /// The destructor. + virtual ~block_device (); + + virtual chroot::ptr + clone () const; + + virtual chroot::ptr + clone_session (std::string const& session_id, + std::string const& alias, + std::string const& user, + bool root) const; + + virtual chroot::ptr + clone_source () const; + + std::string const& + get_chroot_type () const; + + virtual void + setup_env (chroot const& chroot, + environment& env) const; + + virtual session_flags + get_session_flags (chroot const& chroot) const; + + protected: + virtual void + setup_lock (chroot::setup_type type, + bool lock, + int status); + + + virtual void + get_details (chroot const& chroot, + format_detail& detail) const; + + virtual void + get_used_keys (string_list& used_keys) const; + + virtual void + get_keyfile (chroot const& chroot, + keyfile& keyfile) const; + + virtual void + set_keyfile (chroot& chroot, + keyfile const& keyfile); + }; + + } +} + +#endif /* SBUILD_CHROOT_BLOCK_DEVICE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/lib/sbuild/chroot/chroot.cc b/lib/sbuild/chroot/chroot.cc index 8f9bc780..ef7ee334 100644 --- a/lib/sbuild/chroot/chroot.cc +++ b/lib/sbuild/chroot/chroot.cc @@ -25,13 +25,13 @@ #include "chroot-custom.h" #include "chroot-file.h" #ifdef SBUILD_FEATURE_BLOCKDEV -#include "chroot-block-device.h" +#include <sbuild/chroot/block-device.h> #endif // SBUILD_FEATURE_BLOCKDEV #ifdef SBUILD_FEATURE_LOOPBACK #include "chroot-loopback.h" #endif // SBUILD_FEATURE_LOOPBACK #ifdef SBUILD_FEATURE_LVMSNAP -#include "chroot-lvm-snapshot.h" +#include <sbuild/chroot/lvm-snapshot.h> #endif // SBUILD_FEATURE_LVMSNAP #ifdef SBUILD_FEATURE_BTRFSSNAP #include "chroot-btrfs-snapshot.h" @@ -175,7 +175,7 @@ namespace sbuild new_chroot = new chroot_file(); #ifdef SBUILD_FEATURE_BLOCKDEV else if (type == "block-device") - new_chroot = new chroot_block_device(); + new_chroot = new block_device(); #endif // SBUILD_FEATURE_BLOCKDEV #ifdef SBUILD_FEATURE_LOOPBACK else if (type == "loopback") @@ -183,7 +183,7 @@ namespace sbuild #endif // SBUILD_FEATURE_LOOPBACK #ifdef SBUILD_FEATURE_LVMSNAP else if (type == "lvm-snapshot") - new_chroot = new chroot_lvm_snapshot(); + new_chroot = new lvm_snapshot(); #endif // SBUILD_FEATURE_LVMSNAP #ifdef SBUILD_FEATURE_BTRFSSNAP else if (type == "btrfs-snapshot") diff --git a/lib/sbuild/chroot/lvm-snapshot.cc b/lib/sbuild/chroot/lvm-snapshot.cc new file mode 100644 index 00000000..0b6c55eb --- /dev/null +++ b/lib/sbuild/chroot/lvm-snapshot.cc @@ -0,0 +1,271 @@ +/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include <sbuild/chroot/lvm-snapshot.h> +#include <chroot/block-device.h> +#include "chroot-facet-session.h" +#include "chroot-facet-session-clonable.h" +#include "chroot-facet-source-clonable.h" +#include "chroot-facet-mountable.h" +#include "format-detail.h" + +#include <cassert> +#include <cerrno> + +#include <boost/format.hpp> + +using std::endl; +using boost::format; +using namespace sbuild; + +namespace sbuild +{ + namespace chroot + { + + lvm_snapshot::lvm_snapshot (): + block_device_base(), + snapshot_device(), + snapshot_options() + { + add_facet(chroot_facet_source_clonable::create()); + } + + lvm_snapshot::lvm_snapshot (const lvm_snapshot& rhs): + block_device_base(rhs), + snapshot_device(rhs.snapshot_device), + snapshot_options(rhs.snapshot_options) + { + } + + lvm_snapshot::~lvm_snapshot () + { + } + + chroot::chroot::ptr + lvm_snapshot::clone () const + { + return ptr(new lvm_snapshot(*this)); + } + + chroot::chroot::ptr + lvm_snapshot::clone_session (std::string const& session_id, + std::string const& alias, + std::string const& user, + bool root) const + { + chroot_facet_session_clonable::const_ptr psess + (get_facet<chroot_facet_session_clonable>()); + assert(psess); + + ptr session(new lvm_snapshot(*this)); + psess->clone_session_setup(*this, session, session_id, alias, user, root); + + return session; + } + + chroot::chroot::ptr + lvm_snapshot::clone_source () const + { + ptr clone(new block_device(*this)); + + chroot_facet_source_clonable::const_ptr psrc + (get_facet<chroot_facet_source_clonable>()); + assert(psrc); + + psrc->clone_source_setup(*this, clone); + + return clone; + } + + std::string const& + lvm_snapshot::get_snapshot_device () const + { + return this->snapshot_device; + } + + void + lvm_snapshot::set_snapshot_device (std::string const& snapshot_device) + { + if (!is_absname(snapshot_device)) + throw error(snapshot_device, DEVICE_ABS); + + this->snapshot_device = snapshot_device; + + chroot_facet_mountable::ptr pmnt + (get_facet<chroot_facet_mountable>()); + if (pmnt) + pmnt->set_mount_device(this->snapshot_device); + } + + std::string const& + lvm_snapshot::get_snapshot_options () const + { + return this->snapshot_options; + } + + void + lvm_snapshot::set_snapshot_options (std::string const& snapshot_options) + { + this->snapshot_options = snapshot_options; + } + + std::string const& + lvm_snapshot::get_chroot_type () const + { + static const std::string type("lvm-snapshot"); + + return type; + } + + void + lvm_snapshot::setup_env (chroot const& chroot, + environment& env) const + { + block_device_base::setup_env(chroot, env); + + env.add("CHROOT_LVM_SNAPSHOT_NAME", sbuild::basename(get_snapshot_device())); + env.add("CHROOT_LVM_SNAPSHOT_DEVICE", get_snapshot_device()); + env.add("CHROOT_LVM_SNAPSHOT_OPTIONS", get_snapshot_options()); + } + + void + lvm_snapshot::setup_lock (chroot::setup_type type, + bool lock, + int status) + { + std::string device; + + /* Lock is removed by setup script on setup stop. Unlocking here + would fail: the LVM snapshot device no longer exists. */ + if (!(type == SETUP_STOP && lock == false)) + { + if (type == SETUP_START) + device = get_device(); + else + device = get_snapshot_device(); + + if (device.empty()) + throw error(CHROOT_DEVICE); + + try + { + stat file_status(device); + if (!file_status.is_block()) + { + throw error(get_device(), DEVICE_NOTBLOCK); + } + } + catch (sbuild::stat::error const& e) // Failed to stat + { + // Don't throw if stopping a session and the device stat + // failed. This is because the setup scripts shouldn't fail + // to be run if the LVM snapshot no longer exists, which + // would prevent the session from being ended. + if (type != SETUP_STOP) + throw; + } + } + + /* Create or unlink session information. */ + if ((type == SETUP_START && lock == true) || + (type == SETUP_STOP && lock == false && status == 0)) + { + bool start = (type == SETUP_START); + setup_session_info(start); + } + } + + chroot::chroot::session_flags + lvm_snapshot::get_session_flags (chroot const& chroot) const + { + session_flags flags = SESSION_NOFLAGS; + + if (get_facet<chroot_facet_session>()) + flags = flags | SESSION_PURGE; + + return flags; + } + + void + lvm_snapshot::get_details (chroot const& chroot, + format_detail& detail) const + { + block_device_base::get_details(chroot, detail); + + if (!this->snapshot_device.empty()) + detail.add(_("LVM Snapshot Device"), get_snapshot_device()); + if (!this->snapshot_options.empty()) + detail.add(_("LVM Snapshot Options"), get_snapshot_options()); + } + + void + lvm_snapshot::get_used_keys (string_list& used_keys) const + { + block_device_base::get_used_keys(used_keys); + + used_keys.push_back("lvm-snapshot-device"); + used_keys.push_back("lvm-snapshot-options"); + } + + void + lvm_snapshot::get_keyfile (chroot const& chroot, + keyfile& keyfile) const + { + block_device_base::get_keyfile(chroot, keyfile); + + bool session = static_cast<bool>(get_facet<chroot_facet_session>()); + + if (session) + keyfile::set_object_value(*this, + &lvm_snapshot::get_snapshot_device, + keyfile, get_name(), + "lvm-snapshot-device"); + + if (!session) + keyfile::set_object_value(*this, + &lvm_snapshot::get_snapshot_options, + keyfile, get_name(), + "lvm-snapshot-options"); + } + + void + lvm_snapshot::set_keyfile (chroot& chroot, + keyfile const& keyfile) + { + block_device_base::set_keyfile(chroot, keyfile); + + bool session = static_cast<bool>(get_facet<chroot_facet_session>()); + + keyfile::get_object_value(*this, &lvm_snapshot::set_snapshot_device, + keyfile, get_name(), "lvm-snapshot-device", + session ? + keyfile::PRIORITY_REQUIRED : + keyfile::PRIORITY_DISALLOWED); + + keyfile::get_object_value(*this, &lvm_snapshot::set_snapshot_options, + keyfile, get_name(), "lvm-snapshot-options", + session ? + keyfile::PRIORITY_DEPRECATED : + keyfile::PRIORITY_REQUIRED); // Only needed for creating snapshot, not using snapshot + } + + } +} diff --git a/lib/sbuild/chroot/lvm-snapshot.h b/lib/sbuild/chroot/lvm-snapshot.h new file mode 100644 index 00000000..db6a59c4 --- /dev/null +++ b/lib/sbuild/chroot/lvm-snapshot.h @@ -0,0 +1,144 @@ +/* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_LVM_SNAPSHOT_H +#define SBUILD_CHROOT_LVM_SNAPSHOT_H + +#include <sbuild/chroot/block-device-base.h> + +namespace sbuild +{ + namespace chroot + { + + /** + * A chroot stored on an LVM logical volume (LV). + * + * A snapshot LV will be created and mounted on demand. + */ + class lvm_snapshot : public block_device_base + { + protected: + /// The constructor. + lvm_snapshot (); + + /// The copy constructor. + lvm_snapshot (const lvm_snapshot& rhs); + + friend class chroot; + + public: + /// The destructor. + virtual ~lvm_snapshot (); + + virtual chroot::ptr + clone () const; + + virtual chroot::ptr + clone_session (std::string const& session_id, + std::string const& alias, + std::string const& user, + bool root) const; + + virtual chroot::ptr + clone_source () const; + + /** + * Get the logical volume snapshot device name. This is used by + * lvcreate. + * + * @returns the device name. + */ + std::string const& + get_snapshot_device () const; + + /** + * Set the logical volume snapshot device name. This is used by + * lvcreate. + * + * @param snapshot_device the device name. + */ + void + set_snapshot_device (std::string const& snapshot_device); + + /** + * Get the logical volume snapshot options. These are used by + * lvcreate. + * + * @returns the options. + */ + std::string const& + get_snapshot_options () const; + + /** + * Set the logical volume snapshot options. These are used by + * lvcreate. + * + * @param snapshot_options the options. + */ + void + set_snapshot_options (std::string const& snapshot_options); + + virtual std::string const& + get_chroot_type () const; + + virtual void + setup_env (chroot const& chroot, + environment& env) const; + + virtual session_flags + get_session_flags (chroot const& chroot) const; + + protected: + virtual void + setup_lock (chroot::setup_type type, + bool lock, + int status); + + virtual void + get_details (chroot const& chroot, + format_detail& detail) const; + + virtual void + get_used_keys (string_list& used_keys) const; + + virtual void + get_keyfile (chroot const& chroot, + keyfile& keyfile) const; + + virtual void + set_keyfile (chroot& chroot, + keyfile const& keyfile); + + private: + /// LVM snapshot device name for lvcreate. + std::string snapshot_device; + /// LVM snapshot options for lvcreate. + std::string snapshot_options; + }; + + } +} + +#endif /* SBUILD_CHROOT_LVM_SNAPSHOT_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ |