source: trunk/debathena/third/schroot/sbuild/sbuild-chroot-lvm-snapshot.cc @ 24314

Revision 24314, 7.0 KB checked in by geofft, 14 years ago (diff)
In schroot: * Merge with Debian unstable; remaining changes: - Backport to Karmic, and adjust build-deps.
Line 
1/* Copyright © 2005-2009  Roger Leigh <rleigh@debian.org>
2 *
3 * schroot is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * schroot is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see
15 * <http://www.gnu.org/licenses/>.
16 *
17 *********************************************************************/
18
19#include <config.h>
20
21#include "sbuild-chroot-lvm-snapshot.h"
22#include "sbuild-chroot-block-device.h"
23#include "sbuild-chroot-facet-session-clonable.h"
24#include "sbuild-chroot-facet-source-clonable.h"
25#include "sbuild-chroot-facet-mountable.h"
26#include "sbuild-format-detail.h"
27#include "sbuild-lock.h"
28
29#include <cassert>
30#include <cerrno>
31
32#include <boost/format.hpp>
33
34using std::endl;
35using boost::format;
36using namespace sbuild;
37
38chroot_lvm_snapshot::chroot_lvm_snapshot ():
39  chroot_block_device_base(),
40  snapshot_device(),
41  snapshot_options()
42{
43  add_facet(sbuild::chroot_facet_source_clonable::create());
44}
45
46chroot_lvm_snapshot::chroot_lvm_snapshot (const chroot_lvm_snapshot& rhs):
47  chroot_block_device_base(rhs),
48  snapshot_device(rhs.snapshot_device),
49  snapshot_options(rhs.snapshot_options)
50{
51}
52
53chroot_lvm_snapshot::~chroot_lvm_snapshot ()
54{
55}
56
57sbuild::chroot::ptr
58chroot_lvm_snapshot::clone () const
59{
60  return ptr(new chroot_lvm_snapshot(*this));
61}
62
63sbuild::chroot::ptr
64chroot_lvm_snapshot::clone_session (std::string const& session_id,
65                                    std::string const& user,
66                                    bool               root) const
67{
68  chroot_facet_session_clonable::const_ptr psess
69    (get_facet<chroot_facet_session_clonable>());
70  assert(psess);
71
72  ptr session(new chroot_lvm_snapshot(*this));
73  psess->clone_session_setup(session, session_id, user, root);
74
75  return session;
76}
77
78sbuild::chroot::ptr
79chroot_lvm_snapshot::clone_source () const
80{
81  ptr clone(new chroot_block_device(*this));
82
83  chroot_facet_source_clonable::const_ptr psrc
84    (get_facet<chroot_facet_source_clonable>());
85  assert(psrc);
86
87  psrc->clone_source_setup(clone);
88
89  return clone;
90}
91
92std::string const&
93chroot_lvm_snapshot::get_snapshot_device () const
94{
95  return this->snapshot_device;
96}
97
98void
99chroot_lvm_snapshot::set_snapshot_device (std::string const& snapshot_device)
100{
101  if (!is_absname(snapshot_device))
102    throw error(snapshot_device, DEVICE_ABS);
103
104  this->snapshot_device = snapshot_device;
105
106  chroot_facet_mountable::ptr pmnt
107    (get_facet<chroot_facet_mountable>());
108  pmnt->set_mount_device(this->snapshot_device);
109}
110
111std::string const&
112chroot_lvm_snapshot::get_snapshot_options () const
113{
114  return this->snapshot_options;
115}
116
117void
118chroot_lvm_snapshot::set_snapshot_options (std::string const& snapshot_options)
119{
120  this->snapshot_options = snapshot_options;
121}
122
123std::string const&
124chroot_lvm_snapshot::get_chroot_type () const
125{
126  static const std::string type("lvm-snapshot");
127
128  return type;
129}
130
131void
132chroot_lvm_snapshot::setup_env (chroot const& chroot,
133                                environment&  env) const
134{
135  chroot_block_device_base::setup_env(chroot, env);
136
137  env.add("CHROOT_LVM_SNAPSHOT_NAME", sbuild::basename(get_snapshot_device()));
138  env.add("CHROOT_LVM_SNAPSHOT_DEVICE", get_snapshot_device());
139  env.add("CHROOT_LVM_SNAPSHOT_OPTIONS", get_snapshot_options());
140}
141
142void
143chroot_lvm_snapshot::setup_lock (chroot::setup_type type,
144                                 bool               lock,
145                                 int                status)
146{
147  std::string device;
148
149  /* Lock is removed by setup script on setup stop.  Unlocking here
150     would fail: the LVM snapshot device no longer exists. */
151  if (!(type == SETUP_STOP && lock == false))
152    {
153      if (type == SETUP_START)
154        device = get_device();
155      else
156        device = get_snapshot_device();
157
158      if (device.empty())
159        throw error(CHROOT_DEVICE);
160
161      try
162        {
163          stat file_status(device);
164          if (!file_status.is_block())
165            {
166              throw error(get_device(), DEVICE_NOTBLOCK);
167            }
168          else
169            {
170              sbuild::device_lock dlock(device);
171              if (lock)
172                {
173                  try
174                    {
175                      dlock.set_lock(lock::LOCK_EXCLUSIVE, 15);
176                    }
177                  catch (sbuild::lock::error const& e)
178                    {
179                      throw error(get_device(), DEVICE_LOCK, e);
180                    }
181                }
182              else
183                {
184                  try
185                    {
186                      dlock.unset_lock();
187                    }
188                  catch (sbuild::lock::error const& e)
189                    {
190                      throw error(get_device(), DEVICE_UNLOCK, e);
191                    }
192                }
193            }
194        }
195      catch (sbuild::stat::error const& e) // Failed to stat
196        {
197          // Don't throw if stopping a session and the device stat
198          // failed.  This is because the setup scripts shouldn't fail
199          // to be run if the LVM snapshot no longer exists, which
200          // would prevent the session from being ended.
201          if (type != SETUP_STOP)
202            throw;
203        }
204    }
205
206  /* Create or unlink session information. */
207  if ((type == SETUP_START && lock == true) ||
208      (type == SETUP_STOP && lock == false && status == 0))
209    {
210      bool start = (type == SETUP_START);
211      setup_session_info(start);
212    }
213}
214
215sbuild::chroot::session_flags
216chroot_lvm_snapshot::get_session_flags (chroot const& chroot) const
217{
218  session_flags flags = SESSION_NOFLAGS;
219
220  if (get_active())
221    flags = flags | SESSION_PURGE;
222
223  return flags;
224}
225
226void
227chroot_lvm_snapshot::get_details (chroot const& chroot,
228                                  format_detail& detail) const
229{
230  chroot_block_device_base::get_details(chroot, detail);
231
232  if (!this->snapshot_device.empty())
233    detail.add(_("LVM Snapshot Device"), get_snapshot_device());
234  if (!this->snapshot_options.empty())
235    detail.add(_("LVM Snapshot Options"), get_snapshot_options());
236}
237
238void
239chroot_lvm_snapshot::get_keyfile (chroot const& chroot,
240                                  keyfile& keyfile) const
241{
242  chroot_block_device_base::get_keyfile(chroot, keyfile);
243
244  if (get_active())
245    keyfile::set_object_value(*this,
246                              &chroot_lvm_snapshot::get_snapshot_device,
247                              keyfile, get_keyfile_name(),
248                              "lvm-snapshot-device");
249
250  if (!get_active())
251    keyfile::set_object_value(*this,
252                              &chroot_lvm_snapshot::get_snapshot_options,
253                              keyfile, get_keyfile_name(),
254                              "lvm-snapshot-options");
255}
256
257void
258chroot_lvm_snapshot::set_keyfile (chroot&        chroot,
259                                  keyfile const& keyfile,
260                                  string_list&   used_keys)
261{
262  chroot_block_device_base::set_keyfile(chroot, keyfile, used_keys);
263
264  keyfile::get_object_value(*this, &chroot_lvm_snapshot::set_snapshot_device,
265                            keyfile, get_keyfile_name(), "lvm-snapshot-device",
266                            get_active() ?
267                            keyfile::PRIORITY_REQUIRED :
268                            keyfile::PRIORITY_DISALLOWED);
269  used_keys.push_back("lvm-snapshot-device");
270
271  keyfile::get_object_value(*this, &chroot_lvm_snapshot::set_snapshot_options,
272                            keyfile, get_keyfile_name(), "lvm-snapshot-options",
273                            get_active() ?
274                            keyfile::PRIORITY_DEPRECATED :
275                            keyfile::PRIORITY_REQUIRED); // Only needed for creating snapshot, not using snapshot
276  used_keys.push_back("lvm-snapshot-options");
277}
Note: See TracBrowser for help on using the repository browser.