]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- make snapper capable handling inactive lvm snapshots
authorOndrej Kozina <okozina@redhat.com>
Fri, 9 Aug 2013 10:00:43 +0000 (12:00 +0200)
committerOndrej Kozina <okozina@redhat.com>
Fri, 9 Aug 2013 10:00:43 +0000 (12:00 +0200)
configure.ac
snapper/Lvm.cc
snapper/Lvm.h

index 51b07be9a363df13ecd2dc66363c73a8e16d7514..b6c4f2222a2c9674f772167034c22fa3d9821ccc 100644 (file)
@@ -35,6 +35,7 @@ AC_PATH_PROG([CHATTRBIN], [chattr], [/usr/bin/chattr])
 AC_PATH_PROG([LVCREATEBIN], [lvcreate], [/sbin/lvcreate])
 AC_PATH_PROG([LVREMOVEBIN], [lvremove], [/sbin/lvremove])
 AC_PATH_PROG([LVSBIN], [lvs], [/sbin/lvs])
+AC_PATH_PROG([LVCHANGEBIN], [lvchange], [/sbin/lvchange])
 
 AC_DEFINE_UNQUOTED([CHSNAPBIN], ["$CHSNAPBIN"], [Path of chsnap program.])
 AC_DEFINE_UNQUOTED([CPBIN], ["$CPBIN"], [Path of cp program.])
@@ -45,6 +46,7 @@ AC_DEFINE_UNQUOTED([CHATTRBIN], ["$CHATTRBIN"], [Path of chattr program.])
 AC_DEFINE_UNQUOTED([LVCREATEBIN], ["$LVCREATEBIN"], [Path of lvcreate program.])
 AC_DEFINE_UNQUOTED([LVREMOVEBIN], ["$LVREMOVEBIN"], [Path of lvremove program.])
 AC_DEFINE_UNQUOTED([LVSBIN], ["$LVSBIN"], [Path of lvs program.])
+AC_DEFINE_UNQUOTED([LVCHANGEBIN], ["$LVCHANGEBIN"], [Path of lvchange program.])
 
 dnl Automake 1.11 enables silent compilation
 dnl Disable it by "configure --disable-silent-rules" or "make V=1"
index 930c6688135eaa705f3ad471a5087c216948c541..dc061cb8c3c134d246d6b7349e00c260d9f0844b 100644 (file)
@@ -229,6 +229,16 @@ namespace snapper
        if (isSnapshotMounted(num))
            return;
 
+       try
+       {
+           activateSnapshot(vg_name, snapshotLvName(num));
+       }
+       catch (const LvmActivationException& e)
+       {
+           y2err("Couldn't mount snapshot " << num);
+           throw MountSnapshotFailedException();
+       }
+
        SDir snapshot_dir = openSnapshotDir(num);
 
        if (!mount(getDevice(num), snapshot_dir, mount_type, mount_options))
@@ -246,6 +256,15 @@ namespace snapper
 
        if (!umount(info_dir, "snapshot"))
            throw UmountSnapshotFailedException();
+
+       try
+       {
+           deactivateSnapshot(vg_name, snapshotLvName(num));
+       }
+       catch (const LvmDeactivatationException& e)
+       {
+           y2war("Snapshot #" << num << "deactivation failed");
+       }
     }
 
 
@@ -254,7 +273,8 @@ namespace snapper
     {
        struct stat stat;
        int r1 = ::stat(getDevice(num).c_str(), &stat);
-       return r1 == 0 && S_ISBLK(stat.st_mode);
+
+       return (r1 == 0 && S_ISBLK(stat.st_mode)) || detectInactiveSnapshot(vg_name, snapshotLvName(num));
     }
 
 
@@ -295,4 +315,42 @@ namespace snapper
            boost::replace_all_copy(snapshotLvName(num), "-", "--");
     }
 
+
+    void
+    Lvm::activateSnapshot(const string& vg_name, const string& lv_name) const
+    {
+       SystemCmd cmd(LVCHANGEBIN " -ay -K " + quote(vg_name + "/" + lv_name));
+       switch (cmd.retcode())
+       {
+           case 0:
+               break;
+           case EINVALID_CMD_LINE:
+           {
+               SystemCmd retry_cmd(LVCHANGEBIN " -ay " + quote(vg_name + "/" + lv_name));
+               if (retry_cmd.retcode() == 0)
+                   break;
+           }
+           default:
+               y2err("Couldn't activate snapshot " << vg_name << "/" << lv_name);
+               throw LvmActivationException();
+       }
+    }
+
+
+    void
+    Lvm::deactivateSnapshot(const string& vg_name, const string& lv_name) const
+    {
+       SystemCmd cmd(LVCHANGEBIN " -an " + quote(vg_name + "/" + lv_name));
+       if (cmd.retcode())
+           throw LvmDeactivatationException();
+    }
+
+
+    bool
+    Lvm::detectInactiveSnapshot(const string& vg_name, const string& lv_name) const
+    {
+       SystemCmd cmd(LVSBIN " " + quote(vg_name + "/" + lv_name));
+       return cmd.retcode() == 0;
+    }
+
 }
index a853921bd677de72b8f2ab8cc7cc07e7383a93de..20aab44965be751f62974ba3c5eb2187a4eac37c 100644 (file)
 #ifndef SNAPPER_LVM_H
 #define SNAPPER_LVM_H
 
+/*
+ * tools/errors.h from lvm2 source
+ *
+ * consider adding lvm2-devel dep for lvm2 enabled snapper
+ */
+#define EINVALID_CMD_LINE 3
 
 #include "snapper/Filesystem.h"
 
 
 namespace snapper
 {
+    struct LvmActivationException : public std::exception
+    {
+       explicit LvmActivationException() throw() {}
+       virtual const char* what() const throw() { return "lvm snapshot activation exception"; }
+    };
+
+
+    struct LvmDeactivatationException : public std::exception
+    {
+       explicit LvmDeactivatationException() throw() {}
+       virtual const char* what() const throw() { return "lvm snapshot deactivation exception"; }
+    };
+
 
     class Lvm : public Filesystem
     {
@@ -64,6 +83,10 @@ namespace snapper
 
        bool detectThinVolumeNames(const MtabData& mtab_data);
 
+       void activateSnapshot(const string& vg_name, const string& lv_name) const;
+       void deactivateSnapshot(const string& vg_name, const string& lv_name) const;
+       bool detectInactiveSnapshot(const string& vg_name, const string& lv_name) const;
+
        string getDevice(unsigned int num) const;
 
        string vg_name;