]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- use mount system call instead of program
authorArvin Schnell <aschnell@suse.de>
Thu, 30 Aug 2012 09:15:52 +0000 (11:15 +0200)
committerArvin Schnell <aschnell@suse.de>
Thu, 30 Aug 2012 09:15:52 +0000 (11:15 +0200)
doc/snapper.8.in
snapper/Filesystem.cc
snapper/SnapperDefines.h

index b5a7b952eebdd017ec8b90f9bf5cffbfadaf1508..01620505d8373b0c2fdec3962ef5e9333d1d991c 100644 (file)
@@ -114,8 +114,8 @@ will likely need the global option \fI--config\fR, see \fBGLOBAL OPTIONS\fR and
 .TP
 \fI\-f, \-\-fstype\fR <fstype>
 Manually set filesystem type. Supported values are btrfs, ext4 and lvm. For
-lvm snapper used LVM thin-provisioned snapshots. The filesystem type on top of
-LVM can be provided in parentheses, e.g. lvm(xfs). This is required for XFS.
+lvm snapper uses LVM thin-provisioned snapshots. The filesystem type on top of
+LVM must be provided in parentheses, e.g. lvm(xfs).
 
 Without this option snapper tries to detect the filesystem.
 
index a32918d2651b5e51bf1299e13b2aceedb703a317..62fe7e7e78e091a4c32bbaa06db2bec92529bc2c 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/mount.h>
 #include <errno.h>
 #include <unistd.h>
 #include <mntent.h>
@@ -69,27 +70,70 @@ struct btrfs_ioctl_vol_args_v2
 namespace snapper
 {
 
+    vector<string>
+    filter_mount_options(vector<string>& options)
+    {
+       static const char* ign_opt[] = { "ro", "rw", "suid", "nosuid", "exec", "noexec",
+                                        "atime", "noatime", "diratime", "nodiratime",
+                                        "relatime", "norelatime", "strictatime",
+                                        "nostrictatime" };
+
+       vector<string> ret = options;
+
+       for (size_t i = 0; i < lengthof(ign_opt); ++i)
+           ret.erase(remove(ret.begin(), ret.end(), ign_opt[i]), ret.end());
+
+       return ret;
+    }
+
+
     bool
-    mount(const string& device, const string& mount_point, const string& mount_type,
-         const vector<string>& options)
+    mount(const string& device, int fd, const string& mount_type, const vector<string>& options)
     {
-       string cmd_line = MOUNTBIN " -t " + mount_type + " --read-only";
+       unsigned long mount_flags = MS_RDONLY | MS_NOATIME | MS_NODIRATIME | MS_NOEXEC | MS_NOSUID;
 
-       if (!options.empty())
-           cmd_line += " -o " + boost::join(options, ",");
+       string mount_data = boost::join(options, ",");
 
-       cmd_line += " " + quote(device) + " " + quote(mount_point);
+       int r1 = fchdir(fd);
+       if (r1 != 0)
+       {
+           y2err("fchdir failed errno:" << errno << " (" << stringerror(errno) << ")");
+           return false;
+       }
+
+       int r2 = ::mount(device.c_str(), ".", mount_type.c_str(), mount_flags, mount_data.c_str());
+       if (r2 != 0)
+       {
+           y2err("mount failed errno:" << errno << " (" << stringerror(errno) << ")");
+           chdir("/");
+           return false;
+       }
 
-       SystemCmd cmd(cmd_line);
-       return cmd.retcode() == 0;
+       chdir("/");
+       return true;
     }
 
 
     bool
-    umount(const string& mount_point)
+    umount(int fd, const string& mount_point)
     {
-       SystemCmd cmd(UMOUNTBIN " " + quote(mount_point));
-       return cmd.retcode() == 0;
+       int r1 = fchdir(fd);
+       if (r1 != 0)
+       {
+           y2err("fchdir failed errno:" << errno << " (" << stringerror(errno) << ")");
+           return false;
+       }
+
+       int r2 = umount2(mount_point.c_str(), UMOUNT_NOFOLLOW);
+       if (r2 != 0)
+       {
+           y2err("umount failed errno:" << errno << " (" << stringerror(errno) << ")");
+           chdir("/");
+           return false;
+       }
+
+       chdir("/");
+       return true;
     }
 
 
@@ -376,10 +420,7 @@ namespace snapper
            throw InvalidConfigException();
        }
 
-       mount_options = mtab_data.options;
-       mount_options.erase(remove(mount_options.begin(), mount_options.end(), "rw"),
-                           mount_options.end());
-       mount_options.push_back("noatime");
+       mount_options = filter_mount_options(mtab_data.options);
        mount_options.push_back("loop");
        mount_options.push_back("noload");
     }
@@ -522,8 +563,8 @@ namespace snapper
            throw MountSnapshotFailedException();
        }
 
-       if (!mount(snapshotFile(num), snapshotDir(num), "ext4", mount_options))
-           throw MountSnapshotFailedException();
+       // if (!mount(snapshotFile(num), snapshotDir(num), "ext4", mount_options))
+       // throw MountSnapshotFailedException();
     }
 
 
@@ -533,8 +574,8 @@ namespace snapper
        if (!isSnapshotMounted(num))
            return;
 
-       if (!umount(snapshotDir(num)))
-           throw UmountSnapshotFailedException();
+       // if (!umount(snapshotDir(num)))
+       // throw UmountSnapshotFailedException();
 
        SystemCmd cmd1(CHSNAPBIN " -n " + quote(snapshotFile(num)));
        if (cmd1.retcode() != 0)
@@ -557,9 +598,6 @@ namespace snapper
     Filesystem*
     Lvm::create(const string& fstype, const string& subvolume)
     {
-       if (fstype == "lvm")
-           return new Lvm(subvolume, "auto");
-
        Regex rx("^lvm\\(([_a-z0-9]+)\\)$");
        if (rx.match(fstype))
            return new Lvm(subvolume, rx.cap(1));
@@ -591,10 +629,7 @@ namespace snapper
        if (!detectLvmNames(mtab_data))
            throw InvalidConfigException();
 
-       mount_options = mtab_data.options;
-       mount_options.erase(remove(mount_options.begin(), mount_options.end(), "rw"),
-                           mount_options.end());
-       mount_options.push_back("noatime");
+       mount_options = filter_mount_options(mtab_data.options);
        if (mount_type == "xfs")
            mount_options.push_back("nouuid");
     }
@@ -740,7 +775,9 @@ namespace snapper
        if (isSnapshotMounted(num))
            return;
 
-       if (!mount(getDevice(num), snapshotDir(num), mount_type, mount_options))
+       SDir snapshot_dir = openSnapshotDir(num);
+
+       if (!mount(getDevice(num), snapshot_dir.fd(), mount_type, mount_options))
            throw MountSnapshotFailedException();
     }
 
@@ -751,7 +788,9 @@ namespace snapper
        if (!isSnapshotMounted(num))
            return;
 
-       if (!umount(snapshotDir(num)))
+       SDir info_dir = openInfoDir(num);
+
+       if (!umount(info_dir.fd(), "snapshot"))
            throw UmountSnapshotFailedException();
     }
 
index 024977814b1c47d7cfdcb390d47186c6d7b019e7..3d453df903bf9e350a5d3e616c83e3c45f394d30 100644 (file)
@@ -46,9 +46,6 @@
 #define DIFFBIN "/usr/bin/diff"
 #define CHATTRBIN "/usr/bin/chattr"
 
-#define MOUNTBIN "/bin/mount"
-#define UMOUNTBIN "/bin/umount"
-
 #define LVCREATE "/sbin/lvcreate"
 #define LVREMOVE "/sbin/lvremove"