Apache Mesos
fs.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __FS_HPP__
18 #define __FS_HPP__
19 
20 #include <mntent.h>
21 
22 #include <sys/mount.h>
23 #include <sys/types.h>
24 #include <sys/vfs.h>
25 
26 #include <string>
27 #include <vector>
28 
29 #include <stout/nothing.hpp>
30 #include <stout/option.hpp>
31 #include <stout/try.hpp>
32 
33 // Define relevant MS_* flags for old includes.
34 // This is taken from the enum in sys/mount.h.
35 #ifndef MS_RDONLY
36 #define MS_RDONLY 1
37 #endif
38 
39 #ifndef MS_NOSUID
40 #define MS_NOSUID 2
41 #endif
42 
43 #ifndef MS_NODEV
44 #define MS_NODEV 4
45 #endif
46 
47 #ifndef MS_NOEXEC
48 #define MS_NOEXEC 8
49 #endif
50 
51 #ifndef MS_SYNCHRONOUS
52 #define MS_SYNCHRONOUS 16
53 #endif
54 
55 #ifndef MS_REMOUNT
56 #define MS_REMOUNT 32
57 #endif
58 
59 #ifndef MS_MANDLOCK
60 #define MS_MANDLOCK 64
61 #endif
62 
63 #ifndef MS_DIRSYNC
64 #define MS_DIRSYNC 128
65 #endif
66 
67 #ifndef MS_NOATIME
68 #define MS_NOATIME 1024
69 #endif
70 
71 #ifndef MS_NODIRATIME
72 #define MS_NODIRATIME 2048
73 #endif
74 
75 #ifndef MS_BIND
76 #define MS_BIND 4096
77 #endif
78 
79 #ifndef MS_MOVE
80 #define MS_MOVE 8192
81 #endif
82 
83 #ifndef MS_REC
84 #define MS_REC 16384
85 #endif
86 
87 #ifndef MS_SILENT
88 #define MS_SILENT 32768
89 #endif
90 
91 #ifndef MS_POSIXACL
92 #define MS_POSIXACL (1 << 16)
93 #endif
94 
95 #ifndef MS_UNBINDABLE
96 #define MS_UNBINDABLE (1 << 17)
97 #endif
98 
99 #ifndef MS_PRIVATE
100 #define MS_PRIVATE (1 << 18)
101 #endif
102 
103 #ifndef MS_SLAVE
104 #define MS_SLAVE (1 << 19)
105 #endif
106 
107 #ifndef MS_SHARED
108 #define MS_SHARED (1 << 20)
109 #endif
110 
111 #ifndef MS_RELATIME
112 #define MS_RELATIME (1 << 21)
113 #endif
114 
115 #ifndef MS_KERNMOUNT
116 #define MS_KERNMOUNT (1 << 22)
117 #endif
118 
119 #ifndef MS_I_VERSION
120 #define MS_I_VERSION (1 << 23)
121 #endif
122 
123 #ifndef MS_STRICTATIME
124 #define MS_STRICTATIME (1 << 24)
125 #endif
126 
127 #ifndef MS_ACTIVE
128 #define MS_ACTIVE (1 << 30)
129 #endif
130 
131 #ifndef MS_NOUSER
132 #define MS_NOUSER (1 << 31)
133 #endif
134 
135 #ifndef MNT_FORCE
136 #define MNT_FORCE 1
137 #endif
138 
139 #ifndef MNT_DETACH
140 #define MNT_DETACH 2
141 #endif
142 
143 #ifndef MNT_EXPIRE
144 #define MNT_EXPIRE 4
145 #endif
146 
147 #ifndef UMOUNT_NOFOLLOW
148 #define UMOUNT_NOFOLLOW 8
149 #endif
150 
151 // Define FS_MAGIC_* flags for filesystem types.
152 // http://man7.org/linux/man-pages/man2/fstatfs64.2.html
153 #define FS_TYPE_AUFS 0x61756673
154 #define FS_TYPE_BTRFS 0x9123683E
155 #define FS_TYPE_CRAMFS 0x28cd3d45
156 #define FS_TYPE_ECRYPTFS 0xf15f
157 #define FS_TYPE_EXTFS 0x0000EF53
158 #define FS_TYPE_F2FS 0xF2F52010
159 #define FS_TYPE_GPFS 0x47504653
160 #define FS_TYPE_JFFS2FS 0x000072b6
161 #define FS_TYPE_JFS 0x3153464a
162 #define FS_TYPE_NFSFS 0x00006969
163 #define FS_TYPE_RAMFS 0x858458f6
164 #define FS_TYPE_REISERFS 0x52654973
165 #define FS_TYPE_SMBFS 0x0000517B
166 #define FS_TYPE_SQUASHFS 0x73717368
167 #define FS_TYPE_TMPFS 0x01021994
168 #define FS_TYPE_VXFS 0xa501fcf5
169 #define FS_TYPE_XFS 0x58465342
170 #define FS_TYPE_ZFS 0x2fc12fc1
171 #define FS_TYPE_OVERLAY 0x794C7630
172 
173 namespace mesos {
174 namespace internal {
175 namespace fs {
176 
177 // Detect whether the given file system is supported by the kernel.
178 Try<bool> supported(const std::string& fsname);
179 
180 
181 // Detect whether the given file system supports `d_type`
182 // in `struct dirent`.
183 // @directory must not be empty for correct `d_type` detection.
184 // It is the caller's responsibility to ensure this holds.
185 Try<bool> dtypeSupported(const std::string& directory);
186 
187 
188 // Returns a filesystem type id, given a directory.
189 // http://man7.org/linux/man-pages/man2/fstatfs64.2.html
190 Try<uint32_t> type(const std::string& path);
191 
192 
193 // Returns the filesystem type name, given a filesystem type id.
194 Try<std::string> typeName(uint32_t fsType);
195 
196 // TODO(idownes): These different variations of mount information
197 // should be consolidated and moved to stout, along with mount and
198 // umount.
199 
200 // Structure describing the per-process mounts as found in
201 // /proc/[pid]/mountinfo. In particular, entries in this table specify
202 // the propagation properties of mounts, information not present in
203 // the MountTable or /etc/fstab. Entry order is preserved when
204 // parsing /proc/[pid]/mountinfo.
206  // Structure describing an individual /proc/[pid]/mountinfo entry.
207  // See the /proc/[pid]/mountinfo section in 'man proc' for further
208  // details on each field.
209  struct Entry {
210  static Try<Entry> parse(const std::string& s);
211 
212  Entry() {}
213 
214  // Returns the ID of the peer group in which this mount resides.
215  // Returns none if this mount is not a shared mount.
216  Option<int> shared() const;
217 
218  // Returns the ID of the peer group in which this mount's master
219  // resides in. Returns none if this mount is not a slave mount.
220  Option<int> master() const;
221 
222  int id; // mountinfo[1]: mount ID.
223  int parent; // mountinfo[2]: parent ID.
224  dev_t devno; // mountinfo[3]: st_dev.
225 
226  std::string root; // mountinfo[4]: root of the mount.
227  std::string target; // mountinfo[5]: mount point.
228 
229  // Filesystem independent (VFS) options, e.g., "rw,noatime".
230  std::string vfsOptions; // mountinfo[6]: per-mount options.
231  // Filesystem dependent options, e.g., "rw,memory" for a memory
232  // cgroup filesystem.
233  std::string fsOptions; // mountinfo[11]: per-block options.
234 
235  // Current possible optional fields include shared:X, master:X,
236  // propagate_from:X, unbindable.
237  std::string optionalFields; // mountinfo[7]: optional fields.
238 
239  // mountinfo[8] is a separator.
240 
241  std::string type; // mountinfo[9]: filesystem type.
242  std::string source; // mountinfo[10]: source dev, other.
243  };
244 
245  // Read the mountinfo table for a process.
246  // @param pid The `pid` of the process for which we should
247  // read the mountinfo table. If `pid` is None(),
248  // then "self" is used, i.e., the mountinfo table
249  // for the calling process.
250  // @param hierarchicalSort
251  // A boolean indicating whether the entries in the
252  // mountinfo table should be sorted according to
253  // their parent / child relationship (as opposed to
254  // the temporal ordering of when they were
255  // mounted). The two orderings may differ (for
256  // example) if a filesystem is remounted after some
257  // of its children have been mounted.
258  // @return An instance of MountInfoTable if success.
259  static Try<MountInfoTable> read(
260  const Option<pid_t>& pid = None(),
261  bool hierarchicalSort = true);
262 
263  // Read a mountinfo table from a string.
264  // @param lines The contents of a mountinfo table represented as
265  // a string. Different entries in the string are
266  // separated by a newline.
267  // @param hierarchicalSort
268  // A boolean indicating whether the entries in the
269  // mountinfo table should be sorted according to
270  // their parent / child relationship (as opposed to
271  // the temporal ordering of when they were
272  // mounted). The two orderings may differ (for
273  // example) if a filesystem is remounted after some
274  // of its children have been mounted.
275  // @return An instance of MountInfoTable if success.
276  static Try<MountInfoTable> read(
277  const std::string& lines,
278  bool hierarchicalSort = true);
279 
280  // Find the mount table entry by the given target path. If there is
281  // no mount table entry that matches the exact target path, return
282  // the mount table entry that is the immediate parent of the given
283  // target path (similar to `findmnt --target [TARGET]`).
284  Try<Entry> findByTarget(const std::string& target);
285 
286  std::vector<Entry> entries;
287 };
288 
289 
290 // Structure describing a mount table (e.g. /etc/mtab or /proc/mounts).
291 struct MountTable {
292  // Structure describing a mount table entry. This is a wrapper for struct
293  // mntent defined in <mntent.h>.
294  struct Entry {
295  Entry() : freq(0), passno(0) {}
296 
297  Entry(const std::string& _fsname,
298  const std::string& _dir,
299  const std::string& _type,
300  const std::string& _opts,
301  int _freq,
302  int _passno)
303  : fsname(_fsname),
304  dir(_dir),
305  type(_type),
306  opts(_opts),
307  freq(_freq),
308  passno(_passno)
309  {}
310 
311  // Check whether a given mount option exists in a mount table entry.
312  // @param option The given mount option.
313  // @return Whether the given mount option exists.
314  bool hasOption(const std::string& option) const;
315 
316  std::string fsname; // Device or server for filesystem.
317  std::string dir; // Directory mounted on.
318  std::string type; // Type of filesystem: ufs, nfs, etc.
319  std::string opts; // Comma-separated options for fs.
320  int freq; // Dump frequency (in days).
321  int passno; // Pass number for `fsck'.
322  };
323 
324  // Read the mount table from a file.
325  // @param path The path of the file storing the mount table.
326  // @return An instance of MountTable if success.
327  static Try<MountTable> read(const std::string& path);
328 
329  std::vector<Entry> entries;
330 };
331 
332 
333 // Mount a file system.
334 // @param source Specify the file system (often a device name but
335 // it can also be a directory for a bind mount).
336 // If None(), nullptr will be passed as a dummy
337 // argument to mount(), i.e., it is not used for
338 // the specified mount operation. For example, you
339 // can mount a filesystem specified in /etc/fstab
340 // by just specifying the target.
341 // @param target Directory to be attached to.
342 // @param type File system type (listed in /proc/filesystems).
343 // If None(), nullptr will be passed as a dummy
344 // argument to mount(), i.e., it is not used for
345 // the specified mount operation. For example, it
346 // should be None() for a bind mount as it will
347 // inherit the type of the source.
348 // @param flags Mount flags.
349 // @param data Extra data interpreted by different file systems.
350 // @return Whether the mount operation succeeds.
351 //
352 // Note that if this is a read-only bind mount (both the MS_BIND
353 // and MS_READONLY flags are set), the target will automatically
354 // be remounted in read-only mode.
356  const std::string& target,
357  const Option<std::string>& type,
358  unsigned long flags,
359  const void* data);
360 
361 
362 // Alternate version of mount which passes an option string as
363 // additional data for the filesystem mount.
365  const std::string& target,
366  const Option<std::string>& type,
367  unsigned long flags,
368  const Option<std::string>& options);
369 
370 
371 // Unmount a file system.
372 // @param target The (topmost) directory where the file system attaches.
373 // @param flags Unmount flags.
374 // @return Whether the unmount operation succeeds.
375 Try<Nothing> unmount(const std::string& target, int flags = 0);
376 
377 
378 // Unmount a file system and all mounts under that file system.
379 // @param target The (topmost) directory where the file system attaches.
380 // @param flags Unmount flags.
381 // @return Whether the unmountAll operation succeeds.
382 Try<Nothing> unmountAll(const std::string& target, int flags = 0);
383 
384 
385 // Change the root filesystem.
386 Try<Nothing> pivot_root(const std::string& newRoot, const std::string& putOld);
387 
388 namespace chroot {
389 
390 // Clone a device node to a target directory. Intermediate directory paths
391 // are created in the target.
393  const std::string& device, const std::string& target);
394 
395 // Enter a 'chroot' environment. The caller should be in a new mount
396 // unmounted. The root path must have already been provisioned by
397 // calling `prepare`()`.
398 Try<Nothing> enter(const std::string& root);
399 
400 } // namespace chroot {
401 
402 } // namespace fs {
403 } // namespace internal {
404 } // namespace mesos {
405 
406 
407 #endif // __FS_HPP__
Definition: path.hpp:26
std::vector< Entry > entries
Definition: fs.hpp:329
Definition: check.hpp:33
Try< std::string > typeName(uint32_t fsType)
std::string root
Definition: fs.hpp:226
int passno
Definition: fs.hpp:321
std::string dir
Definition: fs.hpp:317
std::string type
Definition: fs.hpp:241
Try< Entry > findByTarget(const std::string &target)
int freq
Definition: fs.hpp:320
Definition: fs.hpp:29
dev_t devno
Definition: fs.hpp:224
std::string vfsOptions
Definition: fs.hpp:230
std::string fsOptions
Definition: fs.hpp:233
Try< Nothing > unmount(const std::string &target, int flags=0)
std::vector< Entry > entries
Definition: fs.hpp:286
Definition: spec.hpp:26
Try< Nothing > enter(const std::string &root)
Try< Nothing > chroot(const std::string &directory)
Definition: chroot.hpp:28
Try< Nothing > unmountAll(const std::string &target, int flags=0)
std::string fsname
Definition: fs.hpp:316
std::string opts
Definition: fs.hpp:319
std::string target
Definition: fs.hpp:227
Definition: none.hpp:27
Definition: attributes.hpp:24
static Try< Entry > parse(const std::string &s)
Definition: fs.hpp:291
static Try< MountInfoTable > read(const Option< pid_t > &pid=None(), bool hierarchicalSort=true)
std::string optionalFields
Definition: fs.hpp:237
std::string type
Definition: fs.hpp:318
Try< uint32_t > type(const std::string &path)
Try< bool > supported(const std::string &fsname)
Try< bool > dtypeSupported(const std::string &directory)
Try< Nothing > mount(const Option< std::string > &source, const std::string &target, const Option< std::string > &type, unsigned long flags, const void *data)
Try< Nothing > copyDeviceNode(const std::string &device, const std::string &target)
Entry(const std::string &_fsname, const std::string &_dir, const std::string &_type, const std::string &_opts, int _freq, int _passno)
Definition: fs.hpp:297
Definition: parse.hpp:33
Try< Nothing > pivot_root(const std::string &newRoot, const std::string &putOld)
std::string source
Definition: fs.hpp:242