Hello community,

here is the log from the commit of package snapper for openSUSE:Factory
checked in at Sun Aug 7 19:04:23 CEST 2011.



--------
--- snapper/snapper.changes     2011-08-01 14:50:48.000000000 +0200
+++ /mounts/work_src_done/STABLE/snapper/snapper.changes        2011-08-05 
14:41:08.000000000 +0200
@@ -1,0 +2,5 @@
+Thu Aug 04 20:51:59 CEST 2011 - [email protected]
+
+- added experimental ext4 support
+
+-------------------------------------------------------------------

calling whatdependson for head-i586


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ snapper.spec ++++++
--- /var/tmp/diff_new_pack.4IOYUk/_old  2011-08-07 19:03:27.000000000 +0200
+++ /var/tmp/diff_new_pack.4IOYUk/_new  2011-08-07 19:03:27.000000000 +0200
@@ -20,7 +20,7 @@
 
 Name:           snapper
 Version:        0.0.7
-Release:        1
+Release:        3
 License:        GPL
 Group:          System/Packages
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -77,8 +77,9 @@
 
 Summary:        Library for filesystem snapshot management
 Group:          System/Libraries
-Requires:       btrfsprogs diffutils util-linux
+Requires:       diffutils util-linux
 PreReq:         %fillup_prereq
+Supplements:    btrfsprogs
 
 %description -n libsnapper1
 This package contains libsnapper, a library for filesystem snapshot management.

++++++ snapper-0.0.7.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/LIBVERSION new/snapper-0.0.7/LIBVERSION
--- old/snapper-0.0.7/LIBVERSION        2011-07-29 16:34:02.000000000 +0200
+++ new/snapper-0.0.7/LIBVERSION        2011-08-03 14:25:59.000000000 +0200
@@ -1 +1 @@
-1.1.0
+1.2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/doc/snapper.8 
new/snapper-0.0.7/doc/snapper.8
--- old/snapper-0.0.7/doc/snapper.8     2011-08-01 14:49:29.000000000 +0200
+++ new/snapper-0.0.7/doc/snapper.8     2011-08-05 14:40:21.000000000 +0200
@@ -1,7 +1,7 @@
 .TH "snapper" "8" 0.0.7 "snapper" "System Tools"
 .SH "NAME"
 .LP
-snapper - Command\-line program for btrfs snapshot management
+snapper - Command\-line program for filesystem snapshot management
 
 .SH "SYNTAX"
 .LP
@@ -12,16 +12,17 @@
 
 .SH "DESCRIPTION"
 .LP
-Snapper is a command\-line program for btrfs snapshot management. It can
-create, delete and compare snapshots and rollback changes between snapshots.
+Snapper is a command\-line program for filesystem snapshot management. It can
+create, delete and compare snapshots and rollback changes between
+snapshots. Supported filesystems are btrfs and ext4.
 
 .SH CONCEPTS
 
 .SS Configurations
 .LP
-For each btrfs subvolume that should be snapshotted by snapper a configuration
-file is required. The complete setup can be done with the create-config
-command.
+For each filesystem or subvolume that should be snapshotted by snapper a
+configuration file is required. The complete setup can be done with the
+create-config command.
 
 .SS Snapshots
 .LP
@@ -36,7 +37,7 @@
 \fBsingle\fR - These snapshots have no special relationship to other
 snapshots.
 .LP
-Note that btrfs\-wise all three types are the same.
+Note that filesystem\-wise all three types are the same.
 
 .SS Automatic Snapshot Creation
 Next to manual snapshot creation snapshots are also created automatically.
@@ -70,7 +71,7 @@
 Increase verbosity.
 .TP
 .I \-t, \-\-table\-style
-Specifies table style to use. Table style is identified by an integer number.
+Specifies table style. Table style is identified by an integer number.
 .TP
 .I \-c, \-\-config <name>
 Use specified configuration instead of the default.
@@ -100,7 +101,11 @@
 
 .TP
 .B create-config [options] <subvolume>
-Create a new configuration for a btrfs subvolume.
+Create a new configuration for a filesystem or subvolume.
+.TP
+\fI\-f, \-\-fstype\fR <fstype>
+Manually set filesystem type. Supported values are btrfs and ext4. Without
+this option snapper detect the filesystem.
 .TP
 \fI\-t, \-\-template\fR <name>
 Name of template for the new configuration file.
@@ -143,6 +148,14 @@
 Delete a snapshot.
 
 .TP
+.B mount <number>
+Mount a snapshot. Not required for all filesystem types.
+
+.TP
+.B umount <number>
+Unmount a snapshot. Not required for all filesystem types.
+
+.TP
 .B diff [options] <number1> <number2>
 Compare two snapshots. This will show a list of files and directories
 that have been created, modified or deleted in the time between the two
@@ -179,6 +192,9 @@
 .TP
 .B /etc/snapper/filters
 Directory containing filter files.
+.TP
+.B /var/log/snapper.log
+Logfile. Please include this file in bug reports.
 
 .SH "HOMEPAGE"
 .LP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/doc/snapper.8.in 
new/snapper-0.0.7/doc/snapper.8.in
--- old/snapper-0.0.7/doc/snapper.8.in  2011-06-15 11:49:47.000000000 +0200
+++ new/snapper-0.0.7/doc/snapper.8.in  2011-08-05 10:26:24.000000000 +0200
@@ -1,7 +1,7 @@
 .TH "snapper" "8" @VERSION@ "snapper" "System Tools"
 .SH "NAME"
 .LP
-snapper - Command\-line program for btrfs snapshot management
+snapper - Command\-line program for filesystem snapshot management
 
 .SH "SYNTAX"
 .LP
@@ -12,16 +12,17 @@
 
 .SH "DESCRIPTION"
 .LP
-Snapper is a command\-line program for btrfs snapshot management. It can
-create, delete and compare snapshots and rollback changes between snapshots.
+Snapper is a command\-line program for filesystem snapshot management. It can
+create, delete and compare snapshots and rollback changes between
+snapshots. Supported filesystems are btrfs and ext4.
 
 .SH CONCEPTS
 
 .SS Configurations
 .LP
-For each btrfs subvolume that should be snapshotted by snapper a configuration
-file is required. The complete setup can be done with the create-config
-command.
+For each filesystem or subvolume that should be snapshotted by snapper a
+configuration file is required. The complete setup can be done with the
+create-config command.
 
 .SS Snapshots
 .LP
@@ -36,7 +37,7 @@
 \fBsingle\fR - These snapshots have no special relationship to other
 snapshots.
 .LP
-Note that btrfs\-wise all three types are the same.
+Note that filesystem\-wise all three types are the same.
 
 .SS Automatic Snapshot Creation
 Next to manual snapshot creation snapshots are also created automatically.
@@ -70,7 +71,7 @@
 Increase verbosity.
 .TP
 .I \-t, \-\-table\-style
-Specifies table style to use. Table style is identified by an integer number.
+Specifies table style. Table style is identified by an integer number.
 .TP
 .I \-c, \-\-config <name>
 Use specified configuration instead of the default.
@@ -100,7 +101,11 @@
 
 .TP
 .B create-config [options] <subvolume>
-Create a new configuration for a btrfs subvolume.
+Create a new configuration for a filesystem or subvolume.
+.TP
+\fI\-f, \-\-fstype\fR <fstype>
+Manually set filesystem type. Supported values are btrfs and ext4. Without
+this option snapper detect the filesystem.
 .TP
 \fI\-t, \-\-template\fR <name>
 Name of template for the new configuration file.
@@ -143,6 +148,14 @@
 Delete a snapshot.
 
 .TP
+.B mount <number>
+Mount a snapshot. Not required for all filesystem types.
+
+.TP
+.B umount <number>
+Unmount a snapshot. Not required for all filesystem types.
+
+.TP
 .B diff [options] <number1> <number2>
 Compare two snapshots. This will show a list of files and directories
 that have been created, modified or deleted in the time between the two
@@ -179,6 +192,9 @@
 .TP
 .B /etc/snapper/filters
 Directory containing filter files.
+.TP
+.B /var/log/snapper.log
+Logfile. Please include this file in bug reports.
 
 .SH "HOMEPAGE"
 .LP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/AppUtil.cc 
new/snapper-0.0.7/snapper/AppUtil.cc
--- old/snapper-0.0.7/snapper/AppUtil.cc        2011-05-18 14:36:24.000000000 
+0200
+++ new/snapper-0.0.7/snapper/AppUtil.cc        2011-08-04 17:59:55.000000000 
+0200
@@ -331,6 +331,18 @@
 
 
     string
+    realpath(const string& path)
+    {
+       char* buf = ::realpath(path.c_str(), NULL);
+       if (!buf)
+           return string();
+       string s(buf);
+       free(buf);
+       return s;
+    }
+
+
+    string
     sformat(const string& format, ...)
     {
        char* result;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/AppUtil.h 
new/snapper-0.0.7/snapper/AppUtil.h
--- old/snapper-0.0.7/snapper/AppUtil.h 2011-05-18 14:36:24.000000000 +0200
+++ new/snapper-0.0.7/snapper/AppUtil.h 2011-08-04 17:59:55.000000000 +0200
@@ -53,6 +53,8 @@
     int readlink(const string& path, string& buf);
     int symlink(const string& oldpath, const string& newpath);
 
+    string realpath(const string& path);
+
 template<class StreamType>
 void classic(StreamType& stream)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/File.cc 
new/snapper-0.0.7/snapper/File.cc
--- old/snapper-0.0.7/snapper/File.cc   2011-07-29 16:34:02.000000000 +0200
+++ new/snapper-0.0.7/snapper/File.cc   2011-08-03 14:55:29.000000000 +0200
@@ -26,6 +26,7 @@
 #include <unistd.h>
 #include <fnmatch.h>
 #include <errno.h>
+#include <boost/algorithm/string.hpp>
 
 #include "snapper/File.h"
 #include "snapper/Snapper.h"
@@ -311,6 +312,36 @@
     }
 
 
+    Files::iterator
+    Files::findAbsolutePath(const string& filename)
+    {
+       string subvolume = getSnapper()->subvolumeDir();
+
+       if (!boost::starts_with(filename, subvolume))
+           return end();
+
+       if (subvolume == "/")
+           return find(filename);
+       else
+           return find(string(filename, subvolume.size()));
+    }
+
+
+    Files::const_iterator
+    Files::findAbsolutePath(const string& filename) const
+    {
+       string subvolume = getSnapper()->subvolumeDir();
+
+       if (!boost::starts_with(filename, subvolume))
+           return end();
+
+       if (subvolume == "/")
+           return find(filename);
+       else
+           return find(string(filename, subvolume.size()));
+    }
+
+
     unsigned int
     File::getPreToSystemStatus()
     {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/File.h 
new/snapper-0.0.7/snapper/File.h
--- old/snapper-0.0.7/snapper/File.h    2011-05-26 15:38:04.000000000 +0200
+++ new/snapper-0.0.7/snapper/File.h    2011-08-03 14:25:59.000000000 +0200
@@ -163,6 +163,9 @@
        iterator find(const string& name);
        const_iterator find(const string& name) const;
 
+       iterator findAbsolutePath(const string& name);
+       const_iterator findAbsolutePath(const string& name) const;
+
     private:
 
        void initialize();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Filesystem.cc 
new/snapper-0.0.7/snapper/Filesystem.cc
--- old/snapper-0.0.7/snapper/Filesystem.cc     2011-07-31 22:32:24.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Filesystem.cc     2011-08-04 11:12:57.000000000 
+0200
@@ -20,9 +20,11 @@
  */
 
 
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <errno.h>
+#include <mntent.h>
 
 #include "snapper/Filesystem.h"
 #include "snapper/Snapper.h"
@@ -52,28 +54,27 @@
     {
        SystemCmd cmd2(BTRFSBIN " subvolume create " + quote(subvolume + 
"/.snapshots"));
        if (cmd2.retcode() != 0)
-       {
            throw AddConfigFailedException("creating btrfs snapshot failed");
-       }
     }
 
 
     string
     Btrfs::infosDir() const
     {
-       return subvolume + "/.snapshots";
+       return (subvolume == "/" ? "" : subvolume) + "/.snapshots";
     }
 
 
     string
     Btrfs::snapshotDir(unsigned int num) const
     {
-       return subvolume + "/.snapshots/" + decString(num) + "/snapshot";
+       return (subvolume == "/" ? "" : subvolume) + "/.snapshots/" +
+           decString(num) + "/snapshot";
     }
 
 
     void
-    Btrfs::createFilesystemSnapshot(unsigned int num) const
+    Btrfs::createSnapshot(unsigned int num) const
     {
        SystemCmd cmd(BTRFSBIN " subvolume snapshot " + quote(subvolume) + " " +
                      quote(snapshotDir(num)));
@@ -83,7 +84,7 @@
 
 
     void
-    Btrfs::deleteFilesystemSnapshot(unsigned int num) const
+    Btrfs::deleteSnapshot(unsigned int num) const
     {
        SystemCmd cmd(BTRFSBIN " subvolume delete " + quote(snapshotDir(num)));
        if (cmd.retcode() != 0)
@@ -91,20 +92,27 @@
     }
 
 
+    bool
+    Btrfs::isSnapshotMounted(unsigned int num) const
+    {
+       return true;
+    }
+
+
     void
-    Btrfs::mountFilesystemSnapshot(unsigned int num) const
+    Btrfs::mountSnapshot(unsigned int num) const
     {
     }
 
 
     void
-    Btrfs::umountFilesystemSnapshot(unsigned int num) const
+    Btrfs::umountSnapshot(unsigned int num) const
     {
     }
 
 
     bool
-    Btrfs::checkFilesystemSnapshot(unsigned int num) const
+    Btrfs::checkSnapshot(unsigned int num) const
     {
        return checkDir(snapshotDir(num));
     }
@@ -122,6 +130,7 @@
        }
        else if (errno != EEXIST)
        {
+           y2err("mkdir failed errno:" << errno << " (" << strerror(errno) << 
")");
            throw AddConfigFailedException("mkdir failed");
        }
 
@@ -134,6 +143,7 @@
        }
        else if (errno != EEXIST)
        {
+           y2err("mkdir failed errno:" << errno << " (" << strerror(errno) << 
")");
            throw AddConfigFailedException("mkdir failed");
        }
     }
@@ -142,7 +152,7 @@
     string
     Ext4::infosDir() const
     {
-       return subvolume + "/.snapshots/.info";
+       return (subvolume == "/" ? "" : subvolume) + "/.snapshots/.info";
     }
 
 
@@ -156,12 +166,12 @@
     string
     Ext4::snapshotFile(unsigned int num) const
     {
-       return subvolume + "/.snapshots/" + decString(num);
+       return (subvolume == "/" ? "" : subvolume) + "/.snapshots/" + 
decString(num);
     }
 
 
     void
-    Ext4::createFilesystemSnapshot(unsigned int num) const
+    Ext4::createSnapshot(unsigned int num) const
     {
        SystemCmd cmd1(TOUCHBIN " " + quote(snapshotFile(num)));
        if (cmd1.retcode() != 0)
@@ -174,26 +184,61 @@
 
 
     void
-    Ext4::deleteFilesystemSnapshot(unsigned int num) const
+    Ext4::deleteSnapshot(unsigned int num) const
     {
        SystemCmd cmd(CHSNAPBIN " -S " + quote(snapshotFile(num)));
        if (cmd.retcode() != 0)
            throw DeleteSnapshotFailedException();
+    }
+
 
-       // TODO
+    bool
+    Ext4::isSnapshotMounted(unsigned int num) const
+    {
+       FILE* f = setmntent("/etc/mtab", "r");
+       if (!f)
+       {
+           y2err("setmntent failed");
+           throw IsSnapshotMountedFailedException();
+       }
+
+       bool mounted = false;
+
+       struct mntent* m;
+       while ((m = getmntent(f)))
+       {
+           if (strcmp(m->mnt_type, "rootfs") == 0)
+               continue;
+
+           if (m->mnt_dir == snapshotDir(num))
+           {
+               mounted = true;
+               break;
+           }
+       }
+
+       endmntent(f);
+
+       return mounted;
     }
 
 
     void
-    Ext4::mountFilesystemSnapshot(unsigned int num) const
+    Ext4::mountSnapshot(unsigned int num) const
     {
+       if (isSnapshotMounted(num))
+           return;
+
        SystemCmd cmd1(CHSNAPBIN " +n " + quote(snapshotFile(num)));
        if (cmd1.retcode() != 0)
            throw MountSnapshotFailedException();
 
        int r1 = mkdir(snapshotDir(num).c_str(), 0755);
        if (r1 != 0 && errno != EEXIST)
+       {
+           y2err("mkdir failed errno:" << errno << " (" << strerror(errno) << 
")");
            throw MountSnapshotFailedException();
+       }
 
        SystemCmd cmd2(MOUNTBIN " -t ext4 -r -o loop,noload " + 
quote(snapshotFile(num)) +
                       " " + quote(snapshotDir(num)));
@@ -203,8 +248,11 @@
 
 
     void
-    Ext4::umountFilesystemSnapshot(unsigned int num) const
+    Ext4::umountSnapshot(unsigned int num) const
     {
+       if (!isSnapshotMounted(num))
+           return;
+
        SystemCmd cmd1(UMOUNTBIN " " + quote(snapshotDir(num)));
        if (cmd1.retcode() != 0)
            throw UmountSnapshotFailedException();
@@ -212,11 +260,13 @@
        SystemCmd cmd2(CHSNAPBIN " -n " + quote(snapshotFile(num)));
        if (cmd2.retcode() != 0)
            throw UmountSnapshotFailedException();
+
+       rmdir(snapshotDir(num).c_str());
     }
 
 
     bool
-    Ext4::checkFilesystemSnapshot(unsigned int num) const
+    Ext4::checkSnapshot(unsigned int num) const
     {
        return checkNormalFile(snapshotFile(num));
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Filesystem.h 
new/snapper-0.0.7/snapper/Filesystem.h
--- old/snapper-0.0.7/snapper/Filesystem.h      2011-07-31 22:32:24.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Filesystem.h      2011-08-04 10:47:10.000000000 
+0200
@@ -51,13 +51,14 @@
        virtual string infosDir() const = 0;
        virtual string snapshotDir(unsigned int num) const = 0;
 
-       virtual void createFilesystemSnapshot(unsigned int num) const = 0;
-       virtual void deleteFilesystemSnapshot(unsigned int num) const = 0;
+       virtual void createSnapshot(unsigned int num) const = 0;
+       virtual void deleteSnapshot(unsigned int num) const = 0;
 
-       virtual void mountFilesystemSnapshot(unsigned int num) const = 0;
-       virtual void umountFilesystemSnapshot(unsigned int num) const = 0;
+       virtual bool isSnapshotMounted(unsigned int num) const = 0;
+       virtual void mountSnapshot(unsigned int num) const = 0;
+       virtual void umountSnapshot(unsigned int num) const = 0;
 
-       virtual bool checkFilesystemSnapshot(unsigned int num) const = 0;
+       virtual bool checkSnapshot(unsigned int num) const = 0;
 
     protected:
 
@@ -79,13 +80,14 @@
        virtual string infosDir() const;
        virtual string snapshotDir(unsigned int num) const;
 
-       virtual void createFilesystemSnapshot(unsigned int num) const;
-       virtual void deleteFilesystemSnapshot(unsigned int num) const;
+       virtual void createSnapshot(unsigned int num) const;
+       virtual void deleteSnapshot(unsigned int num) const;
 
-       virtual void mountFilesystemSnapshot(unsigned int num) const;
-       virtual void umountFilesystemSnapshot(unsigned int num) const;
+       virtual bool isSnapshotMounted(unsigned int num) const;
+       virtual void mountSnapshot(unsigned int num) const;
+       virtual void umountSnapshot(unsigned int num) const;
 
-       virtual bool checkFilesystemSnapshot(unsigned int num) const;
+       virtual bool checkSnapshot(unsigned int num) const;
 
     };
 
@@ -104,13 +106,14 @@
        virtual string snapshotDir(unsigned int num) const;
        virtual string snapshotFile(unsigned int num) const;
 
-       virtual void createFilesystemSnapshot(unsigned int num) const;
-       virtual void deleteFilesystemSnapshot(unsigned int num) const;
+       virtual void createSnapshot(unsigned int num) const;
+       virtual void deleteSnapshot(unsigned int num) const;
 
-       virtual void mountFilesystemSnapshot(unsigned int num) const;
-       virtual void umountFilesystemSnapshot(unsigned int num) const;
+       virtual bool isSnapshotMounted(unsigned int num) const;
+       virtual void mountSnapshot(unsigned int num) const;
+       virtual void umountSnapshot(unsigned int num) const;
 
-       virtual bool checkFilesystemSnapshot(unsigned int num) const;
+       virtual bool checkSnapshot(unsigned int num) const;
 
     };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapper.cc 
new/snapper-0.0.7/snapper/Snapper.cc
--- old/snapper-0.0.7/snapper/Snapper.cc        2011-07-31 22:32:24.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Snapper.cc        2011-08-05 11:21:57.000000000 
+0200
@@ -24,6 +24,7 @@
 #include <sys/types.h>
 #include <glob.h>
 #include <string.h>
+#include <mntent.h>
 #include <boost/algorithm/string.hpp>
 
 #include "config.h"
@@ -542,12 +543,12 @@
 
     void
     Snapper::addConfig(const string& config_name, const string& subvolume,
-                      const string& template_name)
+                      const string& fstype, const string& template_name)
     {
        y2mil("Snapper add-config");
        y2mil("libsnapper version " VERSION);
        y2mil("config_name:" << config_name << " subvolume:" << subvolume <<
-             " template_name:" << template_name);
+             " fstype:" << fstype << " template_name:" << template_name);
 
        if (config_name.empty() || config_name.find_first_of(" \t") != 
string::npos)
        {
@@ -564,6 +565,16 @@
            throw AddConfigFailedException("cannot access template config");
        }
 
+       auto_ptr<Filesystem> filesystem;
+       try
+       {
+           filesystem.reset(Filesystem::create(fstype, subvolume));
+       }
+       catch (const InvalidConfigException& e)
+       {
+           throw AddConfigFailedException("invalid filesystem type");
+       }
+
        try
        {
            SysconfigFile sysconfig(SYSCONFIGFILE);
@@ -593,14 +604,72 @@
        {
            SysconfigFile config(CONFIGSDIR "/" + config_name);
            config.setValue("SUBVOLUME", subvolume);
+           config.setValue("FSTYPE", fstype);
        }
        catch (const FileNotFoundException& e)
        {
            throw AddConfigFailedException("modifying config failed");
        }
 
-       auto_ptr<Filesystem> filesystem(new Btrfs(subvolume));
        filesystem->addConfig();
     }
 
+
+    static bool
+    is_subpath(const string& a, const string& b)
+    {
+       if (b == "/")
+           return true;
+
+       size_t len = b.length();
+
+       if (len > a.length())
+           return false;
+
+       return (len == a.length() || a[len] == '/') && a.compare(0, len, b) == 
0;
+    }
+
+
+    bool
+    Snapper::detectFstype(const string& subvolume, string& fstype)
+    {
+       y2mil("subvolume:" << subvolume);
+
+       if (!boost::starts_with(subvolume, "/") || !checkDir(subvolume))
+           return false;
+
+       FILE* f = setmntent("/etc/mtab", "r");
+       if (!f)
+       {
+           y2err("setmntent failed");
+           return false;
+       }
+
+       fstype.clear();
+
+       string best_match;
+
+       struct mntent* m;
+       while ((m = getmntent(f)))
+       {
+           if (strcmp(m->mnt_type, "rootfs") == 0)
+               continue;
+
+           if (strlen(m->mnt_dir) >= best_match.length() && 
is_subpath(subvolume, m->mnt_dir))
+           {
+               best_match = m->mnt_dir;
+               fstype = m->mnt_type;
+           }
+       }
+
+       endmntent(f);
+
+       if (fstype == "ext4dev")
+           fstype = "ext4";
+
+       y2mil("fstype:" << fstype);
+
+       return !best_match.empty();
+    }
+
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapper.h 
new/snapper-0.0.7/snapper/Snapper.h
--- old/snapper-0.0.7/snapper/Snapper.h 2011-07-29 16:34:02.000000000 +0200
+++ new/snapper-0.0.7/snapper/Snapper.h 2011-08-02 12:19:16.000000000 +0200
@@ -140,7 +140,9 @@
 
        static list<ConfigInfo> getConfigs();
        static void addConfig(const string& config_name, const string& 
subvolume,
-                             const string& template_name);
+                             const string& fstype, const string& 
template_name);
+
+       static bool detectFstype(const string& subvolume, string& fstype);
 
        const Filesystem* getFilesystem() const { return filesystem; }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapshot.cc 
new/snapper-0.0.7/snapper/Snapshot.cc
--- old/snapper-0.0.7/snapper/Snapshot.cc       2011-08-01 12:30:45.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Snapshot.cc       2011-08-04 10:47:10.000000000 
+0200
@@ -149,7 +149,7 @@
 
            getChildValue(node, "cleanup", snapshot.cleanup);
 
-           if (!snapper->getFilesystem()->checkFilesystemSnapshot(num))
+           if (!snapper->getFilesystem()->checkSnapshot(num))
            {
                y2err("snapshot check failed. not adding snapshot " << num);
                continue;
@@ -274,15 +274,21 @@
     unsigned int
     Snapshots::nextNumber()
     {
-       unsigned int num = entries.empty() ? 1 : entries.rbegin()->num + 1;
+       unsigned int num = entries.empty() ? 0 : entries.rbegin()->num;
 
-       int r;
-       while ((r = mkdir((snapper->infosDir() + "/" + decString(num)).c_str(), 
0777)) == -1 &&
-              errno == EEXIST)
+       while (true)
+       {
            ++num;
 
-       if (r != 0)
-       {
+           if (snapper->getFilesystem()->checkSnapshot(num))
+               continue;
+
+           if (mkdir((snapper->infosDir() + "/" + decString(num)).c_str(), 
0777) == 0)
+               break;
+
+           if (errno == EEXIST)
+               continue;
+
            y2err("mkdir failed errno:" << errno << " (" << strerror(errno) << 
")");
            throw IOErrorException();
        }
@@ -322,28 +328,41 @@
     void
     Snapshot::mountFilesystemSnapshot() const
     {
-       snapper->getFilesystem()->mountFilesystemSnapshot(num);
+       if (isCurrent())
+           return;
+
+       snapper->getFilesystem()->mountSnapshot(num);
     }
 
 
     void
     Snapshot::umountFilesystemSnapshot() const
     {
-       snapper->getFilesystem()->umountFilesystemSnapshot(num);
+       if (isCurrent())
+           return;
+
+       snapper->getFilesystem()->umountSnapshot(num);
     }
 
 
     void
     Snapshot::createFilesystemSnapshot() const
     {
-       snapper->getFilesystem()->createFilesystemSnapshot(num);
+       if (isCurrent())
+           throw IllegalSnapshotException();
+
+       snapper->getFilesystem()->createSnapshot(num);
     }
 
 
     void
     Snapshot::deleteFilesystemSnapshot() const
     {
-       snapper->getFilesystem()->deleteFilesystemSnapshot(num);
+       if (isCurrent())
+           throw IllegalSnapshotException();
+
+       snapper->getFilesystem()->umountSnapshot(num);
+       snapper->getFilesystem()->deleteSnapshot(num);
     }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper/Snapshot.h 
new/snapper-0.0.7/snapper/Snapshot.h
--- old/snapper-0.0.7/snapper/Snapshot.h        2011-07-29 19:50:42.000000000 
+0200
+++ new/snapper-0.0.7/snapper/Snapshot.h        2011-08-04 10:47:10.000000000 
+0200
@@ -54,6 +54,12 @@
     };
 
 
+    struct IsSnapshotMountedFailedException : public std::exception
+    {
+       explicit IsSnapshotMountedFailedException() throw() {}
+       virtual const char* what() const throw() { return "is snapshot mounted 
failed"; }
+    };
+
     struct MountSnapshotFailedException : public std::exception
     {
        explicit MountSnapshotFailedException() throw() {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/snapper.spec.in 
new/snapper-0.0.7/snapper.spec.in
--- old/snapper-0.0.7/snapper.spec.in   2011-07-04 16:20:45.000000000 +0200
+++ new/snapper-0.0.7/snapper.spec.in   2011-08-05 12:36:14.000000000 +0200
@@ -61,8 +61,9 @@
 %package -n libsnapper@LIBVERSION_MAJOR@
 Summary:       Library for filesystem snapshot management
 Group:         System/Libraries
-Requires:      btrfsprogs diffutils util-linux
+Requires:      diffutils util-linux
 PreReq:                %fillup_prereq
+Supplements:   btrfsprogs
 
 %description -n libsnapper@LIBVERSION_MAJOR@
 This package contains libsnapper, a library for filesystem snapshot management.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.0.7/tools/snapper.cc 
new/snapper-0.0.7/tools/snapper.cc
--- old/snapper-0.0.7/tools/snapper.cc  2011-08-01 12:33:33.000000000 +0200
+++ new/snapper-0.0.7/tools/snapper.cc  2011-08-04 21:12:47.000000000 +0200
@@ -1,3 +1,24 @@
+/*
+ * Copyright (c) 2011 Novell, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program 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, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
 
 #include <stdlib.h>
 #include <string.h>
@@ -89,6 +110,7 @@
         << _("\tsnapper create-config <subvolume>") << endl
         << endl
         << _("    Options for 'create-config' command:") << endl
+        << _("\t--fstype, -f <fstype>\t\tManually set filesystem type.") << 
endl
         << _("\t--template, -t <name>\t\tName of config template to use.") << 
endl
         << endl;
 }
@@ -98,6 +120,7 @@
 command_create_config()
 {
     const struct option options[] = {
+       { "fstype",             required_argument,      0,      'f' },
        { "template",           required_argument,      0,      't' },
        { 0, 0, 0, 0 }
     };
@@ -109,18 +132,33 @@
        exit(EXIT_FAILURE);
     }
 
-    string subvolume = getopts.popArg();
+    string subvolume = realpath(getopts.popArg());
+    if (subvolume.empty())
+    {
+       cerr << _("Invalid subvolume.") << endl;
+       exit(EXIT_FAILURE);
+    }
 
+    string fstype = "";
     string template_name = "default";
 
     GetOpts::parsed_opts::const_iterator opt;
 
+    if ((opt = opts.find("fstype")) != opts.end())
+       fstype = opt->second;
+
     if ((opt = opts.find("template")) != opts.end())
        template_name = opt->second;
 
+    if (fstype.empty() && !Snapper::detectFstype(subvolume, fstype))
+    {
+       cerr << _("Detecting filesystem type failed.") << endl;
+       exit(EXIT_FAILURE);
+    }
+
     try
     {
-       Snapper::addConfig(config_name, subvolume, template_name);
+       Snapper::addConfig(config_name, subvolume, fstype, template_name);
     }
     catch (const AddConfigFailedException& e)
     {
@@ -441,6 +479,60 @@
 
 
 void
+help_mount()
+{
+    cout << _("  Mount snapshot:") << endl
+        << _("\tsnapper mount <number>") << endl
+        << endl;
+}
+
+
+void
+command_mount()
+{
+    getopts.parse("mount", GetOpts::no_options);
+    if (!getopts.hasArgs())
+    {
+       cerr << _("Command 'mount' needs at least one argument.") << endl;
+       exit(EXIT_FAILURE);
+    }
+
+    while (getopts.hasArgs())
+    {
+       Snapshots::iterator snapshot = readNum(getopts.popArg());
+       snapshot->mountFilesystemSnapshot();
+    }
+}
+
+
+void
+help_umount()
+{
+    cout << _("  Umount snapshot:") << endl
+        << _("\tsnapper umount <number>") << endl
+        << endl;
+}
+
+
+void
+command_umount()
+{
+    getopts.parse("mount", GetOpts::no_options);
+    if (!getopts.hasArgs())
+    {
+       cerr << _("Command 'mount' needs at least one argument.") << endl;
+       exit(EXIT_FAILURE);
+    }
+
+    while (getopts.hasArgs())
+    {
+       Snapshots::iterator snapshot = readNum(getopts.popArg());
+       snapshot->umountFilesystemSnapshot();
+    }
+}
+
+
+void
 help_diff()
 {
     cout << _("  Comparing snapshots:") << endl
@@ -482,7 +574,7 @@
 
     if ((opt = opts.find("file")) != opts.end())
     {
-       tmp = files.find(opt->second);
+       tmp = files.findAbsolutePath(opt->second);
        if (tmp == files.end())
        {
            cerr << sformat(_("File '%s' not included in diff."), 
opt->second.c_str()) << endl;
@@ -505,7 +597,8 @@
     if (tmp == files.end())
     {
        for (Files::const_iterator it = files.begin(); it != files.end(); ++it)
-           fprintf(file, "%s %s\n", 
statusToString(it->getPreToPostStatus()).c_str(), it->getName().c_str());
+           fprintf(file, "%s %s\n", 
statusToString(it->getPreToPostStatus()).c_str(),
+                   it->getAbsolutePath(LOC_SYSTEM).c_str());
     }
     else
     {
@@ -589,7 +682,7 @@
                name.erase(0, pos + 1);
            }
 
-           Files::iterator it = files.find(name);
+           Files::iterator it = files.findAbsolutePath(name);
            if (it == files.end())
            {
                cerr << sformat(_("File '%s' not found in diff."), 
name.c_str()) << endl;
@@ -693,6 +786,8 @@
     help_create();
     help_modify();
     help_delete();
+    help_mount();
+    help_umount();
     help_diff();
     help_rollback();
     help_cleanup();
@@ -744,6 +839,8 @@
     cmds["create"] = command_create;
     cmds["modify"] = command_modify;
     cmds["delete"] = command_delete;
+    cmds["mount"] = command_mount;
+    cmds["umount"] = command_umount;
     cmds["diff"] = command_diff;
     cmds["rollback"] = command_rollback;
     cmds["cleanup"] = command_cleanup;


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to