Andreas Bombe <[EMAIL PROTECTED]> writes:
> On Wed, May 31, 2006 at 10:53:18AM +0100, Roger Leigh wrote:
>> Andreas Bombe <[EMAIL PROTECTED]> writes:
>>
>> > The session cleanup in 10mount ignores failures of umount invocations
>> > and cleanup continues. In the case of file chroots with a /home bind
>> > mount that failed to umount, the rm -rf in 05file blindly descends into
>> > the system /home with obvious unpretty results.
>> There are a few possibilities here.
>>
>> 1) 10mount should exit with an error if umount fails.
>>
>> Caveat: if the session is ended with the setup scripts having
>> failed, this would require manual cleanup by the system admin.
>> This needs additional work in session::setup_chroot() in
>> sbuild-session.cc, so that the session is not ended if the scripts
>> fail. This means not removing the session file from
>> /var/lib/schroot/session/ on failure.
>>
>> Currently, because of the above consideration, the "setup-stop"
>> phase of the session scripts can not fail.
>
> If a umount fails it will require manual admin intervention anyway so
> that wouldn't make much of a difference. Making the rm -rf safe is
> still required in any case, I'd say.
OK, I agree here. In the patch below, any umount failure will abort
the cleanup.
>> 2) 05file must check if any filesystems are mounted under the chroot
>> root before running rm -rf. Is there a portable and reliable way
>> of doing this? Would
>>
>> if mount | grep "$CHROOT_MOUNT_LOCATION"; then
>> :
>> else
>> rm -rf "$CHROOT_MOUNT_LOCATION" || true
>> fi
>>
>> be sufficient?
>
> I don't think that is safe. It depends on all mounts being recorded in
> /etc/mtab, which is not the case if something *inside* the chroot
> mounted something, for example.
> I thought about rm with a "do not cross filesystems" option, still that
> wouldn't help because binds may well be on the same filesystem. There
> are no usable criteria for using "find ... -exec rm ..." either.
To work around this, I wrote a program called schroot-listmounts,
which uses /proc/mounts to get a list:
./schroot/schroot-listmounts -m /srv/chroot/sid
/srv/chroot/sid/tmp
/srv/chroot/sid/home
/srv/chroot/sid/dev/shm
/srv/chroot/sid/dev/pts
/srv/chroot/sid
The shell script can read this list and unmount them in turn.
> The only way I know to be sure there are no submounts is to mount --bind
> the chroot to a temporary location and rm -rf there, then unmount the
> temporary bind and rmdir the chroot.
>
> The rmdir will fail safely if the chroot isn't empty then. Even before,
> the rm -rf of the temp bind will fail safely upon trying to remove an
> empty directory used as a mount point in the chroot.
I think I now have this solved. If the chroot directories are
unmounted, schroot-listmounts will list nothing:
./schroot/schroot-listmounts -m
/var/lib/schroot/mount/testsnap-c4e53f96-e507-40e8-8cf4-fcfd31c17c32
[no output]
so in this case we can be sure it's safe to "rm -rf". If there's any
output at all, we know it's not safe.
I've attached a patch for this. Note: it's not yet tested; this is
just to give you an idea of what I'm thinking of as a solution. If
the testing works out, and you are happy with it, I'll include this in
the next release.
ChangeLog | 43 ++++++++
NEWS | 10 +
debian/changelog | 3
schroot/Makefile.am | 10 +
schroot/sbuild-chroot-block-device.cc | 3
schroot/sbuild-chroot-block-device.h | 9 -
schroot/sbuild-chroot-file.cc | 5
schroot/sbuild-chroot-file.h | 9 -
schroot/sbuild-chroot-lvm-snapshot.cc | 5
schroot/sbuild-chroot-lvm-snapshot.h | 9 -
schroot/sbuild-chroot-plain.cc | 5
schroot/sbuild-chroot-plain.h | 9 -
schroot/sbuild-chroot.cc | 13 ++
schroot/sbuild-chroot.h | 42 +++++++
schroot/sbuild-session.cc | 6 -
schroot/sbuild-util.cc | 13 ++
schroot/sbuild-util.h | 12 ++
schroot/schroot-listmounts-options.cc | 83 +++++++++++++++
schroot/schroot-listmounts-options.h | 59 +++++++++++
schroot/schroot-listmounts.cc | 181 ++++++++++++++++++++++++++++++++++
schroot/setup/05file | 15 ++
schroot/setup/10mount | 31 +----
test/sbuild-chroot.cc | 3
23 files changed, 522 insertions(+), 56 deletions(-)
Regards,
Roger
--
Roger Leigh
Printing on GNU/Linux? http://gutenprint.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Index: test/sbuild-chroot.cc
===================================================================
--- test/sbuild-chroot.cc (revision 697)
+++ test/sbuild-chroot.cc (working copy)
@@ -53,7 +53,8 @@
virtual void
setup_lock (setup_type type,
- bool lock)
+ bool lock,
+ int status)
{}
virtual sbuild::chroot::session_flags
Property changes on: schroot
___________________________________________________________________
Name: svn:ignore
- .deps
.libs
Makefile
Makefile.in
*.la
*.lo
*.gch
stamp-h2
sbuild-config.h
dchroot
schroot
schroot-releaselock
dchroot.1
schroot.1
schroot-setup.5
schroot.conf.5
+ .deps
.libs
Makefile
Makefile.in
*.la
*.lo
*.gch
stamp-h2
sbuild-config.h
dchroot
schroot
schroot-listmounts
schroot-releaselock
dchroot.1
schroot.1
schroot-setup.5
schroot.conf.5
Index: schroot/sbuild-session.cc
===================================================================
--- schroot/sbuild-session.cc (revision 697)
+++ schroot/sbuild-session.cc (working copy)
@@ -472,7 +472,7 @@
try
{
- session_chroot->setup_lock(setup_type, true);
+ session_chroot->lock(setup_type);
}
catch (chroot::error const& e)
{
@@ -480,7 +480,7 @@
try
{
// Release lock, which also removes session metadata.
- session_chroot->setup_lock(setup_type, false);
+ session_chroot->unlock(setup_type, 0);
}
catch (chroot::error const& ignore)
{
@@ -602,7 +602,7 @@
try
{
- session_chroot->setup_lock(setup_type, false);
+ session_chroot->unlock(setup_type, exit_status);
}
catch (chroot::error const& e)
{
Index: schroot/sbuild-chroot-lvm-snapshot.cc
===================================================================
--- schroot/sbuild-chroot-lvm-snapshot.cc (revision 697)
+++ schroot/sbuild-chroot-lvm-snapshot.cc (working copy)
@@ -116,7 +116,8 @@
void
chroot_lvm_snapshot::setup_lock (setup_type type,
- bool lock)
+ bool lock,
+ int status)
{
std::string device;
struct stat statbuf;
@@ -187,7 +188,7 @@
/* Create or unlink session information. */
if ((type == SETUP_START && lock == true) ||
- (type == SETUP_STOP && lock == false))
+ (type == SETUP_STOP && lock == false && status == 0))
{
bool start = (type == SETUP_START);
setup_session_info(start);
Index: schroot/sbuild-chroot-lvm-snapshot.h
===================================================================
--- schroot/sbuild-chroot-lvm-snapshot.h (revision 697)
+++ schroot/sbuild-chroot-lvm-snapshot.h (working copy)
@@ -94,15 +94,16 @@
virtual void
setup_env (environment& env);
- virtual void
- setup_lock (setup_type type,
- bool lock);
-
virtual session_flags
get_session_flags () const;
protected:
virtual void
+ setup_lock (setup_type type,
+ bool lock,
+ int status);
+
+ virtual void
print_details (std::ostream& stream) const;
virtual void
Index: schroot/sbuild-util.h
===================================================================
--- schroot/sbuild-util.h (revision 697)
+++ schroot/sbuild-util.h (working copy)
@@ -52,6 +52,18 @@
char separator = '/');
/**
+ * Normalise a pathname. This strips all trailing separators, and
+ * duplicate separators within a path.
+ *
+ * @param name the path to normalise.
+ * @param separator the separation delimiting directories.
+ * @returns the normalised name.
+ */
+ std::string
+ normalname (std::string name,
+ char separator = '/');
+
+ /**
* Convert a string_list into a string. The strings are
* concatenated using separator as a delimiter.
*
Index: schroot/setup/10mount
===================================================================
--- schroot/setup/10mount (revision 697)
+++ schroot/setup/10mount (working copy)
@@ -23,24 +23,17 @@
mount $VERBOSE $1 "$2" "$3"
}
-# Unmount a filesystem
-# $1: mount location
-do_umount()
-{
- if [ "$AUTH_VERBOSITY" = "verbose" ]; then
- echo "Unmounting $1"
- fi
- if [ -d "$1" ]; then
- umount "$1" || true
- fi
-}
-
# Unmount all filesystem under specified location
# $1: mount base location
do_umount_all()
{
- for dir in $(mount | grep $1 | sed -e 's/.* on \(.*\) type.*/\1/' | sort -r); do
- do_umount "$dir"
+ "$LIBEXEC_DIR/schroot-listmounts" -m "$1" |
+ while read mountloc; do
+ if [ "$AUTH_VERBOSITY" = "verbose" ]; then
+ echo "Unmounting $mountloc"
+ fi
+ umount "$mountloc"
+ fi
done
}
@@ -91,17 +84,11 @@
elif [ $1 = "setup-stop" ]; then
- do_umount "${CHROOT_PATH}/tmp"
- do_umount "${CHROOT_PATH}/home"
- do_umount "${CHROOT_PATH}/dev/shm"
- do_umount "${CHROOT_PATH}/dev/pts"
- do_umount "${CHROOT_PATH}/proc"
+ do_umount_all "$CHROOT_MOUNT_LOCATION"
if [ "$CHROOT_TYPE" != "file" ]; then
- do_umount "$CHROOT_MOUNT_LOCATION"
-
if echo "$CHROOT_MOUNT_LOCATION" | grep -q "^$MOUNT_DIR/"; then
- rmdir "$CHROOT_MOUNT_LOCATION" || true
+ rmdir "$CHROOT_MOUNT_LOCATION"
fi
fi
Index: schroot/setup/05file
===================================================================
--- schroot/setup/05file (revision 697)
+++ schroot/setup/05file (working copy)
@@ -88,8 +88,21 @@
cd "$CHROOT_MOUNT_LOCATION" && repack_file
fi
- rm -rf "$CHROOT_MOUNT_LOCATION" || true
+ "$LIBEXEC_DIR/schroot-listmounts" -m "$CHROOT_MOUNT_LOCATION" |
+ if read mountloc; then
+ if [ "$AUTH_VERBOSITY" = "verbose" ]; then
+ echo "Not purging $CHROOT_MOUNT_LOCATION; filesystems are mounted:"
+ "$LIBEXEC_DIR/schroot-listmounts" -m "$CHROOT_MOUNT_LOCATION"
+ fi
+ exit 1
+ fi
+ if [ "$AUTH_VERBOSITY" = "verbose" ]; then
+ echo "Purging $CHROOT_MOUNT_LOCATION"
+ fi
+
+ rm -rf "$CHROOT_MOUNT_LOCATION"
+
fi
fi
Index: schroot/sbuild-chroot-plain.cc
===================================================================
--- schroot/sbuild-chroot-plain.cc (revision 697)
+++ schroot/sbuild-chroot-plain.cc (working copy)
@@ -85,14 +85,15 @@
void
chroot_plain::setup_lock (setup_type type,
- bool lock)
+ bool lock,
+ int status)
{
/* By default, plain chroots do no locking. */
/* Create or unlink session information. */
if (get_run_setup_scripts() == true)
{
if ((type == SETUP_START && lock == true) ||
- (type == SETUP_STOP && lock == false))
+ (type == SETUP_STOP && lock == false && status == 0))
{
bool start = (type == SETUP_START);
setup_session_info(start);
Index: schroot/sbuild-chroot-plain.h
===================================================================
--- schroot/sbuild-chroot-plain.h (revision 697)
+++ schroot/sbuild-chroot-plain.h (working copy)
@@ -68,15 +68,16 @@
virtual void
setup_env (environment& env);
- virtual void
- setup_lock (setup_type type,
- bool lock);
-
virtual session_flags
get_session_flags () const;
protected:
virtual void
+ setup_lock (setup_type type,
+ bool lock,
+ int status);
+
+ virtual void
print_details (std::ostream& stream) const;
virtual void
Index: schroot/schroot-listmounts-options.h
===================================================================
--- schroot/schroot-listmounts-options.h (revision 0)
+++ schroot/schroot-listmounts-options.h (revision 0)
@@ -0,0 +1,59 @@
+/* Copyright © 2005-2006 Roger Leigh <[EMAIL PROTECTED]>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *********************************************************************/
+
+#ifndef SCHROOT_LISTMOUNTS_OPTIONS_H
+#define SCHROOT_LISTMOUNTS_OPTIONS_H
+
+#include <string>
+
+namespace schroot_listmounts
+{
+
+ /**
+ * schroot-listmounts command-line options.
+ */
+ class options {
+ public:
+ /**
+ * The constructor.
+ *
+ * @param argc the number of arguments.
+ * @param argv the list of arguments.
+ */
+ options (int argc,
+ char *argv[]);
+
+ /// The destructor.
+ virtual ~options ();
+
+ /// The mountpoint to check..
+ std::string mountpoint;
+ /// Display version information.
+ bool version;
+ };
+
+}
+
+#endif /* SCHROOT_LISTMOUNTS_OPTIONS_H */
+
+/*
+ * Local Variables:
+ * mode:C++
+ * End:
+ */
Index: schroot/sbuild-chroot-block-device.cc
===================================================================
--- schroot/sbuild-chroot-block-device.cc (revision 697)
+++ schroot/sbuild-chroot-block-device.cc (working copy)
@@ -111,7 +111,8 @@
void
chroot_block_device::setup_lock (setup_type type,
- bool lock)
+ bool lock,
+ int status)
{
struct stat statbuf;
Index: schroot/sbuild-chroot-block-device.h
===================================================================
--- schroot/sbuild-chroot-block-device.h (revision 697)
+++ schroot/sbuild-chroot-block-device.h (working copy)
@@ -106,15 +106,16 @@
virtual void
setup_env (environment& env);
- virtual void
- setup_lock (setup_type type,
- bool lock);
-
virtual session_flags
get_session_flags () const;
protected:
virtual void
+ setup_lock (setup_type type,
+ bool lock,
+ int status);
+
+ virtual void
print_details (std::ostream& stream) const;
virtual void
Index: schroot/sbuild-chroot.cc
===================================================================
--- schroot/sbuild-chroot.cc (revision 697)
+++ schroot/sbuild-chroot.cc (working copy)
@@ -316,6 +316,19 @@
}
void
+sbuild::chroot::lock (setup_type type)
+{
+ setup_lock(type, true, 0);
+}
+
+void
+sbuild::chroot::unlock (setup_type type,
+ int status)
+{
+ setup_lock(type, false, status);
+}
+
+void
sbuild::chroot::print_details (std::ostream& stream) const
{
if (this->active == true)
Index: schroot/sbuild-chroot-file.cc
===================================================================
--- schroot/sbuild-chroot-file.cc (revision 697)
+++ schroot/sbuild-chroot-file.cc (working copy)
@@ -97,7 +97,8 @@
void
chroot_file::setup_lock (setup_type type,
- bool lock)
+ bool lock,
+ int status)
{
// Check ownership and permissions.
if (type == SETUP_START && lock == true)
@@ -122,7 +123,7 @@
/* By default, file chroots do no locking. */
/* Create or unlink session information. */
if ((type == SETUP_START && lock == true) ||
- (type == SETUP_STOP && lock == false))
+ (type == SETUP_STOP && lock == false && status == 0))
{
bool start = (type == SETUP_START);
Index: schroot/sbuild-chroot-file.h
===================================================================
--- schroot/sbuild-chroot-file.h (revision 697)
+++ schroot/sbuild-chroot-file.h (working copy)
@@ -76,15 +76,16 @@
virtual void
setup_env (environment& env);
- virtual void
- setup_lock (setup_type type,
- bool lock);
-
virtual session_flags
get_session_flags () const;
protected:
virtual void
+ setup_lock (setup_type type,
+ bool lock,
+ int status);
+
+ virtual void
print_details (std::ostream& stream) const;
virtual void
Index: schroot/sbuild-util.cc
===================================================================
--- schroot/sbuild-util.cc (revision 697)
+++ schroot/sbuild-util.cc (working copy)
@@ -109,6 +109,19 @@
}
std::string
+sbuild::normalname (std::string name,
+ char separator)
+{
+ // Remove trailing separators
+ std::string::size_type cur = name.length();
+ while (cur - 1 != 0 && name[cur - 1] == separator)
+ --cur;
+ name.resize(cur);
+
+ return remove_duplicates(name, separator);
+}
+
+std::string
sbuild::string_list_to_string (sbuild::string_list const& list,
std::string const& separator)
{
Index: schroot/schroot-listmounts.cc
===================================================================
--- schroot/schroot-listmounts.cc (revision 0)
+++ schroot/schroot-listmounts.cc (revision 0)
@@ -0,0 +1,181 @@
+/* Copyright © 2005-2006 Roger Leigh <[EMAIL PROTECTED]>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *********************************************************************/
+
+#include <config.h>
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#include <iostream>
+#include <locale>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <mntent.h>
+
+#include <boost/format.hpp>
+#include <boost/program_options.hpp>
+
+#include <lockdev.h>
+
+#include "sbuild.h"
+
+#include "schroot-listmounts-options.h"
+
+using std::endl;
+using boost::format;
+namespace opt = boost::program_options;
+
+using namespace schroot_listmounts;
+
+/**
+ * Print version information.
+ *
+ * @param stream the stream to output to.
+ */
+void
+print_version (std::ostream& stream)
+{
+ stream << format(_("schroot-listmounts (Debian sbuild) %1%\n")) % VERSION
+ << _("Written by Roger Leigh\n\n")
+ << _("Copyright (C) 2004-2006 Roger Leigh\n")
+ << _("This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n")
+ << std::flush;
+}
+
+/**
+ * List mounts.
+ *
+ * @param mountfile the file containing the database of mounted filesystems.
+ * @param mountpoint the mount point to check for.
+ */
+sbuild::string_list
+list_mounts (std::string const& mountfile,
+ std::string const& mountpoint)
+{
+ sbuild::string_list ret;
+
+ std::string to_find = sbuild::normalname(mountpoint);
+
+ std::FILE *mntdb = std::fopen(mountfile.c_str(), "r");
+ if (mntdb == 0)
+ {
+ format fmt(_("%1%: Failed to open: %2%"));
+ fmt % mountfile % std::strerror(errno);
+ throw sbuild::runtime_error(fmt.str());
+ }
+
+ mntent *mount;
+ while ((mount = getmntent(mntdb)) != 0)
+ {
+ std::string mount_dir(mount->mnt_dir);
+ if (to_find == "/" ||
+ (mount_dir.find(to_find) == 0 &&
+ (// Names are the same.
+ mount_dir.size() == to_find.size() ||
+ // Must have a following /, or not the same directory.
+ (mount_dir.size() > to_find.size() &&
+ mount_dir[to_find.size()] == '/'))))
+ ret.push_back(mount_dir);
+ }
+
+ std::cout << std::flush;
+
+ if (std::fclose(mntdb) == EOF)
+ {
+ format fmt(_("%1%: Failed to close: %2%"));
+ fmt % mountfile % std::strerror(errno);
+ throw sbuild::runtime_error(fmt.str());
+ }
+
+ return ret;
+}
+
+/**
+ * Main routine.
+ *
+ * @param argc the number of arguments
+ * @param argv argument vector
+ *
+ * @returns 0 on success, 1 on failure or the exit status of the
+ * chroot command.
+ */
+int
+main (int argc,
+ char *argv[])
+{
+ try
+ {
+ // Set up locale.
+ std::locale::global(std::locale(""));
+ std::cout.imbue(std::locale());
+ std::cerr.imbue(std::locale());
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ textdomain (GETTEXT_PACKAGE);
+
+#ifndef SBUILD_DEBUG
+ sbuild::debug_level = sbuild::DEBUG_CRITICAL;
+#else
+ sbuild::debug_level = sbuild::DEBUG_NONE;
+#endif
+
+ // Parse command-line options.
+ options opts(argc, argv);
+
+ if (opts.version)
+ {
+ print_version(std::cerr);
+ exit(EXIT_SUCCESS);
+ }
+
+ if (opts.mountpoint.empty())
+ {
+ sbuild::log_error() << _("No mountpoint specified") << endl;
+ exit (EXIT_FAILURE);
+ }
+
+ // Check mounts.
+ sbuild::string_list mounts =
+ list_mounts("/proc/mounts", opts.mountpoint);
+
+ for (sbuild::string_list::const_reverse_iterator pos = mounts.rbegin();
+ pos != mounts.rend();
+ ++pos)
+ std::cout << *pos << '\n';
+ std::cout << std::flush;
+
+ exit (EXIT_SUCCESS);
+ }
+ catch (std::exception const& e)
+ {
+ sbuild::log_error() << e.what() << endl;
+
+ exit(EXIT_FAILURE);
+ }
+}
+
+/*
+ * Local Variables:
+ * mode:C++
+ * End:
+ */
Index: schroot/sbuild-chroot.h
===================================================================
--- schroot/sbuild-chroot.h (revision 697)
+++ schroot/sbuild-chroot.h (working copy)
@@ -368,12 +368,27 @@
* An error will be thrown on failure.
*
* @param type the type of setup being performed
- * @param lock true to lock, false to unlock
*/
- virtual void
- setup_lock (setup_type type,
- bool lock) = 0;
+ void
+ lock (setup_type type);
+ /**
+ * Unlock a chroot during setup. The locking technique (if any) may
+ * vary depending upon the chroot type and setup stage. For
+ * example, during creation of an LVM snapshot a block device
+ * might require locking, but afterwards this will change to the
+ * new block device.
+ *
+ * An error will be thrown on failure.
+ *
+ * @param type the type of setup being performed
+ * @param status the exit status of the setup commands (0 for
+ * success, nonzero for failure).
+ */
+ void
+ unlock (setup_type type,
+ int status);
+
protected:
/**
* Set up persistent session information.
@@ -383,6 +398,25 @@
virtual void
setup_session_info (bool start);
+ /**
+ * Unlock a chroot during setup. The locking technique (if any) may
+ * vary depending upon the chroot type and setup stage. For
+ * example, during creation of an LVM snapshot a block device
+ * might require locking, but afterwards this will change to the
+ * new block device.
+ *
+ * An error will be thrown on failure.
+ *
+ * @param type the type of setup being performed
+ * @param lock true to lock, false to unlock
+ * @param status the exit status of the setup commands (0 for
+ * success, nonzero for failure).
+ */
+ virtual void
+ setup_lock(setup_type type,
+ bool lock,
+ int status) = 0;
+
public:
/**
* Get the session flags of the chroot. These determine how the
Index: schroot/Makefile.am
===================================================================
--- schroot/Makefile.am (revision 697)
+++ schroot/Makefile.am (working copy)
@@ -38,7 +38,7 @@
endif
bin_PROGRAMS = $(dchroot) schroot
-pkglibexec_PROGRAMS = schroot-releaselock
+pkglibexec_PROGRAMS = schroot-releaselock schroot-listmounts
#BUILT_SOURCES = sbuild.gch
#CLEANFILES = sbuild.gch
@@ -129,6 +129,14 @@
schroot_releaselock_CFLAGS = $(AM_CFLAGS) $(SCHROOT_CFLAGS)
schroot_releaselock_LDADD = libsbuild.la
+schroot_listmounts_SOURCES = \
+ schroot-listmounts-options.h \
+ schroot-listmounts-options.cc \
+ schroot-listmounts.cc
+schroot_listmounts_CFLAGS = $(AM_CFLAGS) $(SCHROOT_CFLAGS)
+schroot_listmounts_LDADD = libsbuild.la
+
+
pkgsysconfdir = $(PACKAGE_SYSCONF_DIR)
pkgsysconf_DATA = schroot.conf
Index: schroot/schroot-listmounts-options.cc
===================================================================
--- schroot/schroot-listmounts-options.cc (revision 0)
+++ schroot/schroot-listmounts-options.cc (revision 0)
@@ -0,0 +1,83 @@
+/* Copyright © 2005-2006 Roger Leigh <[EMAIL PROTECTED]>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *********************************************************************/
+
+#include <config.h>
+
+#include <iostream>
+
+#include <stdlib.h>
+
+#include <boost/format.hpp>
+#include <boost/program_options.hpp>
+
+#include "sbuild.h"
+
+#include "schroot-listmounts-options.h"
+
+using std::endl;
+using boost::format;
+namespace opt = boost::program_options;
+using namespace schroot_listmounts;
+
+options::options (int argc,
+ char *argv[]):
+ mountpoint(),
+ version(0)
+{
+ opt::options_description general(_("General options"));
+ general.add_options()
+ ("help,?", _("Show help options"))
+ ("version,V",
+ _("Print version information"));
+
+ opt::options_description lock(_("Lock options"));
+ lock.add_options()
+ ("mountpoint,m", opt::value<std::string>(&this->mountpoint),
+ _("Mountpoint to check (full path)"));
+
+
+ opt::options_description global;
+ global.add(general).add(lock);
+
+ opt::variables_map vm;
+ opt::store(opt::parse_command_line(argc, argv, global), vm);
+ opt::notify(vm);
+
+ if (vm.count("help"))
+ {
+ std::cout
+ << _("Usage:") << '\n'
+ << _(" schroot-listmounts [OPTION...] - list mounts") << '\n'
+ << global << std::flush;
+ exit(EXIT_SUCCESS);
+}
+
+ if (vm.count("version"))
+ this->version = true;
+}
+
+options::~options ()
+{
+}
+
+/*
+ * Local Variables:
+ * mode:C++
+ * End:
+ */
Index: debian/changelog
===================================================================
--- debian/changelog (revision 697)
+++ debian/changelog (working copy)
@@ -5,6 +5,9 @@
* schroot/schroot.1.in, schroot/schroot.conf.5.in: Correct ambiguity and
mistakes in the documentation (Closes: #369633). Thanks to Andreas
Bombe.
+ * 05file and 10mount take additional steps to ensure that filesystems
+ are umounted correctly, and that no chroot will be purged if there are
+ mounted filesystems inside it (Closes: #369626).
--
Index: ChangeLog
===================================================================
--- ChangeLog (revision 697)
+++ ChangeLog (working copy)
@@ -1,3 +1,46 @@
+2006-06-09 Roger Leigh <[EMAIL PROTECTED]>
+
+ * debian/changelog: Close #369626.
+
+ * NEWS: Document 05file and 10mount changes.
+
+ * schroot/setup/05file: Use schroot-listmounts to check if there
+ are any mounted filesystems before purging the chroot.
+
+ * schroot/setup/10mount: Use schroot-listmounts to unmount all
+ filesystems in a chroot. Exit with an error if unmounting fails.
+
+ * test/sbuild-chroot.cc: Implement the new form of
+ sbuild::chroot::setup_lock().
+
+ * schroot/schroot-listmounts-options.(cc|h): New files. These are
+ the command-line option parser for schroot-listmounts.
+
+ * schroot/schroot-listmounts.cc: New file. This is a program to
+ list all of the mounts under a given mountpoint.
+
+ * schroot/sbuild-session.cc (setup_chroot): Use the chroot lock
+ and unlock methods, in place of setup_lock.
+
+ * schroot/sbuild-chroot-plain.cc, schroot/sbuild-chroot-file.cc,
+ schroot/sbuild-chroot-block-device.cc,
+ schroot/sbuild-chroot-lvm-snapshot.cc: setup_lock only removes the
+ session (using setup_session_info) if the setup scripts succeeded.
+
+ * schroot/sbuild-chroot-plain.h, schroot/sbuild-chroot-file.h,
+ schroot/sbuild-chroot-block-device.h,
+ schroot/sbuild-chroot-lvm-snapshot.h: setup_lock is protected and
+ has an additional status argument.
+
+ * schroot/sbuild-chroot.cc
+ (lock): New function; calls setup_lock.
+ (unlock): New function; calls setup_lock.
+
+ * schroot/sbuild-chroot.h: Replace setup_lock with lock and unlock
+ methods. Unlock takes a status argument which indicates if the
+ setup scripts failed or not. setup_lock is now a protected
+ virtual method used by lock and unlock.
+
2006-06-08 Roger Leigh <[EMAIL PROTECTED]>
* debian/changelog: Close #369633.
Index: NEWS
===================================================================
--- NEWS (revision 697)
+++ NEWS (working copy)
@@ -9,8 +9,16 @@
* Major changes in 0.2.11:
- Bugfixes only.
+ 1) The 10mount script, used to unmount filesystem in a chroot, will
+ exit with an error if unmounting fails (for safety). It also
+ uses /proc/mounts (via a new program, schroot-listmounts) to
+ ensure all filesystems in the chroot are unmounted.
+ 2) The 05file script, used to unpack and repack chroot archives,
+ will use schroot-listmounts to check if any filesystems are
+ mounted before purging the chroot. This is in order to avoid
+ dataloss.
+
* Major changes in 0.2.10:
Bugfixes only.