From: Ondrej Kozina Date: Fri, 9 Aug 2013 10:00:43 +0000 (+0200) Subject: - make snapper capable handling inactive lvm snapshots X-Git-Tag: v0.1.7~8^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f800175bfdc4d30f201e5382f942aa7d59e57e27;p=thirdparty%2Fsnapper.git - make snapper capable handling inactive lvm snapshots --- diff --git a/configure.ac b/configure.ac index 51b07be9..b6c4f222 100644 --- a/configure.ac +++ b/configure.ac @@ -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" diff --git a/snapper/Lvm.cc b/snapper/Lvm.cc index 930c6688..dc061cb8 100644 --- a/snapper/Lvm.cc +++ b/snapper/Lvm.cc @@ -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; + } + } diff --git a/snapper/Lvm.h b/snapper/Lvm.h index a853921b..20aab449 100644 --- a/snapper/Lvm.h +++ b/snapper/Lvm.h @@ -23,12 +23,31 @@ #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;