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 - aschnell@suse.de
+
+- 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
#include
#include
+#include
#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
#include
#include
#include
+#include
#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
#include
#include
+#include
#include
#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
#include
@@ -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: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org