From: Arvin Schnell Date: Thu, 30 Aug 2012 09:15:52 +0000 (+0200) Subject: - use mount system call instead of program X-Git-Tag: v0.1.3~131 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=c2f2ba1da2d1995095812b422fcd096beb2cd0c0;p=thirdparty%2Fsnapper.git - use mount system call instead of program --- diff --git a/doc/snapper.8.in b/doc/snapper.8.in index b5a7b952..01620505 100644 --- a/doc/snapper.8.in +++ b/doc/snapper.8.in @@ -114,8 +114,8 @@ will likely need the global option \fI--config\fR, see \fBGLOBAL OPTIONS\fR and .TP \fI\-f, \-\-fstype\fR 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. diff --git a/snapper/Filesystem.cc b/snapper/Filesystem.cc index a32918d2..62fe7e7e 100644 --- a/snapper/Filesystem.cc +++ b/snapper/Filesystem.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -69,27 +70,70 @@ struct btrfs_ioctl_vol_args_v2 namespace snapper { + vector + filter_mount_options(vector& options) + { + static const char* ign_opt[] = { "ro", "rw", "suid", "nosuid", "exec", "noexec", + "atime", "noatime", "diratime", "nodiratime", + "relatime", "norelatime", "strictatime", + "nostrictatime" }; + + vector 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& options) + mount(const string& device, int fd, const string& mount_type, const vector& 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(); } diff --git a/snapper/SnapperDefines.h b/snapper/SnapperDefines.h index 02497781..3d453df9 100644 --- a/snapper/SnapperDefines.h +++ b/snapper/SnapperDefines.h @@ -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"