1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
use crate::errno::Errno;
use crate::{NixPath, Result};
use libc::{self, c_int, c_ulong};
libc_bitflags!(
/// Used with [`mount`].
pub struct MsFlags: c_ulong {
/// Mount read-only
MS_RDONLY;
/// Ignore suid and sgid bits
MS_NOSUID;
/// Disallow access to device special files
MS_NODEV;
/// Disallow program execution
MS_NOEXEC;
/// Writes are synced at once
MS_SYNCHRONOUS;
/// Alter flags of a mounted FS
MS_REMOUNT;
/// Allow mandatory locks on a FS
MS_MANDLOCK;
/// Directory modifications are synchronous
MS_DIRSYNC;
/// Do not update access times
MS_NOATIME;
/// Do not update directory access times
MS_NODIRATIME;
/// Linux 2.4.0 - Bind directory at different place
MS_BIND;
/// Move an existing mount to a new location
MS_MOVE;
/// Used to create a recursive bind mount.
MS_REC;
/// Suppress the display of certain kernel warning messages.
MS_SILENT;
/// VFS does not apply the umask
MS_POSIXACL;
/// The resulting mount cannot subsequently be bind mounted.
MS_UNBINDABLE;
/// Make this mount point private.
MS_PRIVATE;
/// If this is a shared mount point that is a member of a peer group
/// that contains other members, convert it to a slave mount.
MS_SLAVE;
/// Make this mount point shared.
MS_SHARED;
/// When a file on this filesystem is accessed, update the file's
/// last access time (atime) only if the current value of atime is
/// less than or equal to the file's last modification time (mtime) or
/// last status change time (ctime).
MS_RELATIME;
/// Mount request came from within the kernel
#[deprecated(since = "0.27.0", note = "Should only be used in-kernel")]
MS_KERNMOUNT;
/// Update inode I_version field
MS_I_VERSION;
/// Always update the last access time (atime) when files on this
/// filesystem are accessed.
MS_STRICTATIME;
/// Reduce on-disk updates of inode timestamps (atime, mtime, ctime) by
/// maintaining these changes only in memory.
MS_LAZYTIME;
#[deprecated(since = "0.27.0", note = "Should only be used in-kernel")]
#[allow(missing_docs)] // Not documented in Linux
MS_ACTIVE;
#[deprecated(since = "0.27.0", note = "Should only be used in-kernel")]
#[allow(missing_docs)] // Not documented in Linux
MS_NOUSER;
#[allow(missing_docs)] // Not documented in Linux; possibly kernel-only
MS_RMT_MASK;
#[allow(missing_docs)] // Not documented in Linux; possibly kernel-only
MS_MGC_VAL;
#[allow(missing_docs)] // Not documented in Linux; possibly kernel-only
MS_MGC_MSK;
}
);
libc_bitflags!(
/// Used with [`umount2].
pub struct MntFlags: c_int {
/// Attempt to unmount even if still in use, aborting pending requests.
MNT_FORCE;
/// Lazy unmount. Disconnect the file system immediately, but don't
/// actually unmount it until it ceases to be busy.
MNT_DETACH;
/// Mark the mount point as expired.
MNT_EXPIRE;
/// Don't dereference `target` if it is a symlink.
UMOUNT_NOFOLLOW;
}
);
/// Mount a file system.
///
/// # Arguments
/// - `source` - Specifies the file system. e.g. `/dev/sd0`.
/// - `target` - Specifies the destination. e.g. `/mnt`.
/// - `fstype` - The file system type, e.g. `ext4`.
/// - `flags` - Optional flags controlling the mount.
/// - `data` - Optional file system specific data.
///
/// # See Also
/// [`mount`](https://man7.org/linux/man-pages/man2/mount.2.html)
pub fn mount<
P1: ?Sized + NixPath,
P2: ?Sized + NixPath,
P3: ?Sized + NixPath,
P4: ?Sized + NixPath,
>(
source: Option<&P1>,
target: &P2,
fstype: Option<&P3>,
flags: MsFlags,
data: Option<&P4>,
) -> Result<()> {
fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
where
P: ?Sized + NixPath,
F: FnOnce(*const libc::c_char) -> T,
{
match p {
Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
None => Ok(f(std::ptr::null())),
}
}
let res = with_opt_nix_path(source, |s| {
target.with_nix_path(|t| {
with_opt_nix_path(fstype, |ty| {
with_opt_nix_path(data, |d| unsafe {
libc::mount(
s,
t.as_ptr(),
ty,
flags.bits(),
d as *const libc::c_void,
)
})
})
})
})????;
Errno::result(res).map(drop)
}
/// Unmount the file system mounted at `target`.
pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
let res =
target.with_nix_path(|cstr| unsafe { libc::umount(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
/// Unmount the file system mounted at `target`.
///
/// See also [`umount`](https://man7.org/linux/man-pages/man2/umount.2.html)
pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
let res = target.with_nix_path(|cstr| unsafe {
libc::umount2(cstr.as_ptr(), flags.bits())
})?;
Errno::result(res).map(drop)
}
|