| File: | build-scan/../src/basic/mount-util.c |
| Warning: | line 98, column 17 Value stored to 'h' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
| 2 | |
| 3 | #include <errno(*__errno_location ()).h> |
| 4 | #include <stdio_ext.h> |
| 5 | #include <stdlib.h> |
| 6 | #include <string.h> |
| 7 | #include <sys/mount.h> |
| 8 | #include <sys/stat.h> |
| 9 | #include <sys/statvfs.h> |
| 10 | #include <unistd.h> |
| 11 | |
| 12 | /* Include later */ |
| 13 | #include <libmount.h> |
| 14 | |
| 15 | #include "alloc-util.h" |
| 16 | #include "escape.h" |
| 17 | #include "extract-word.h" |
| 18 | #include "fd-util.h" |
| 19 | #include "fileio.h" |
| 20 | #include "fs-util.h" |
| 21 | #include "hashmap.h" |
| 22 | #include "mount-util.h" |
| 23 | #include "parse-util.h" |
| 24 | #include "path-util.h" |
| 25 | #include "set.h" |
| 26 | #include "stdio-util.h" |
| 27 | #include "string-util.h" |
| 28 | #include "strv.h" |
| 29 | |
| 30 | /* This is the original MAX_HANDLE_SZ definition from the kernel, when the API was introduced. We use that in place of |
| 31 | * any more currently defined value to future-proof things: if the size is increased in the API headers, and our code |
| 32 | * is recompiled then it would cease working on old kernels, as those refuse any sizes larger than this value with |
| 33 | * EINVAL right-away. Hence, let's disconnect ourselves from any such API changes, and stick to the original definition |
| 34 | * from when it was introduced. We use it as a start value only anyway (see below), and hence should be able to deal |
| 35 | * with large file handles anyway. */ |
| 36 | #define ORIGINAL_MAX_HANDLE_SZ128 128 |
| 37 | |
| 38 | int name_to_handle_at_loop( |
| 39 | int fd, |
| 40 | const char *path, |
| 41 | struct file_handle **ret_handle, |
| 42 | int *ret_mnt_id, |
| 43 | int flags) { |
| 44 | |
| 45 | _cleanup_free___attribute__((cleanup(freep))) struct file_handle *h = NULL((void*)0); |
| 46 | size_t n = ORIGINAL_MAX_HANDLE_SZ128; |
| 47 | |
| 48 | /* We need to invoke name_to_handle_at() in a loop, given that it might return EOVERFLOW when the specified |
| 49 | * buffer is too small. Note that in contrast to what the docs might suggest, MAX_HANDLE_SZ is only good as a |
| 50 | * start value, it is not an upper bound on the buffer size required. |
| 51 | * |
| 52 | * This improves on raw name_to_handle_at() also in one other regard: ret_handle and ret_mnt_id can be passed |
| 53 | * as NULL if there's no interest in either. */ |
| 54 | |
| 55 | for (;;) { |
| 56 | int mnt_id = -1; |
| 57 | |
| 58 | h = malloc0(offsetof(struct file_handle, f_handle) + n)(calloc(1, (__builtin_offsetof(struct file_handle, f_handle) + n))); |
| 59 | if (!h) |
| 60 | return -ENOMEM12; |
| 61 | |
| 62 | h->handle_bytes = n; |
| 63 | |
| 64 | if (name_to_handle_at(fd, path, h, &mnt_id, flags) >= 0) { |
| 65 | |
| 66 | if (ret_handle) |
| 67 | *ret_handle = TAKE_PTR(h)({ typeof(h) _ptr_ = (h); (h) = ((void*)0); _ptr_; }); |
| 68 | |
| 69 | if (ret_mnt_id) |
| 70 | *ret_mnt_id = mnt_id; |
| 71 | |
| 72 | return 0; |
| 73 | } |
| 74 | if (errno(*__errno_location ()) != EOVERFLOW75) |
| 75 | return -errno(*__errno_location ()); |
| 76 | |
| 77 | if (!ret_handle && ret_mnt_id && mnt_id >= 0) { |
| 78 | |
| 79 | /* As it appears, name_to_handle_at() fills in mnt_id even when it returns EOVERFLOW when the |
| 80 | * buffer is too small, but that's undocumented. Hence, let's make use of this if it appears to |
| 81 | * be filled in, and the caller was interested in only the mount ID an nothing else. */ |
| 82 | |
| 83 | *ret_mnt_id = mnt_id; |
| 84 | return 0; |
| 85 | } |
| 86 | |
| 87 | /* If name_to_handle_at() didn't increase the byte size, then this EOVERFLOW is caused by something |
| 88 | * else (apparently EOVERFLOW is returned for untriggered nfs4 mounts sometimes), not by the too small |
| 89 | * buffer. In that case propagate EOVERFLOW */ |
| 90 | if (h->handle_bytes <= n) |
| 91 | return -EOVERFLOW75; |
| 92 | |
| 93 | /* The buffer was too small. Size the new buffer by what name_to_handle_at() returned. */ |
| 94 | n = h->handle_bytes; |
| 95 | if (offsetof(struct file_handle, f_handle)__builtin_offsetof(struct file_handle, f_handle) + n < n) /* check for addition overflow */ |
| 96 | return -EOVERFLOW75; |
| 97 | |
| 98 | h = mfree(h); |
Value stored to 'h' is never read | |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id) { |
| 103 | char path[STRLEN("/proc/self/fdinfo/")(sizeof("""/proc/self/fdinfo/""") - 1) + DECIMAL_STR_MAX(int)(2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 : sizeof (int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof(int[-2 *(sizeof(int) > 8)])))]; |
| 104 | _cleanup_free___attribute__((cleanup(freep))) char *fdinfo = NULL((void*)0); |
| 105 | _cleanup_close___attribute__((cleanup(closep))) int subfd = -1; |
| 106 | char *p; |
| 107 | int r; |
| 108 | |
| 109 | if ((flags & AT_EMPTY_PATH0x1000) && isempty(filename)) |
| 110 | xsprintf(path, "/proc/self/fdinfo/%i", fd)do { if ((__builtin_expect(!!(!(((size_t) snprintf(path, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (path), typeof(&*(path))), sizeof(path)/sizeof((path)[0]) , ((void)0))), "/proc/self/fdinfo/%i", fd) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (path), typeof(&*(path))), sizeof(path)/sizeof((path)[0]) , ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("xsprintf: " "path" "[] must be big enough"), "../src/basic/mount-util.c" , 110, __PRETTY_FUNCTION__); } while (0); |
| 111 | else { |
| 112 | subfd = openat(fd, filename, O_CLOEXEC02000000|O_PATH010000000|(flags & AT_SYMLINK_FOLLOW0x400 ? 0 : O_NOFOLLOW0400000)); |
| 113 | if (subfd < 0) |
| 114 | return -errno(*__errno_location ()); |
| 115 | |
| 116 | xsprintf(path, "/proc/self/fdinfo/%i", subfd)do { if ((__builtin_expect(!!(!(((size_t) snprintf(path, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (path), typeof(&*(path))), sizeof(path)/sizeof((path)[0]) , ((void)0))), "/proc/self/fdinfo/%i", subfd) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (path), typeof(&*(path))), sizeof(path)/sizeof((path)[0]) , ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("xsprintf: " "path" "[] must be big enough"), "../src/basic/mount-util.c" , 116, __PRETTY_FUNCTION__); } while (0); |
| 117 | } |
| 118 | |
| 119 | r = read_full_file(path, &fdinfo, NULL((void*)0)); |
| 120 | if (r == -ENOENT2) /* The fdinfo directory is a relatively new addition */ |
| 121 | return -EOPNOTSUPP95; |
| 122 | if (r < 0) |
| 123 | return r; |
| 124 | |
| 125 | p = startswith(fdinfo, "mnt_id:"); |
| 126 | if (!p) { |
| 127 | p = strstr(fdinfo, "\nmnt_id:"); |
| 128 | if (!p) /* The mnt_id field is a relatively new addition */ |
| 129 | return -EOPNOTSUPP95; |
| 130 | |
| 131 | p += 8; |
| 132 | } |
| 133 | |
| 134 | p += strspn(p, WHITESPACE" \t\n\r"); |
| 135 | p[strcspn(p, WHITESPACE" \t\n\r")] = 0; |
| 136 | |
| 137 | return safe_atoi(p, mnt_id); |
| 138 | } |
| 139 | |
| 140 | int fd_is_mount_point(int fd, const char *filename, int flags) { |
| 141 | _cleanup_free___attribute__((cleanup(freep))) struct file_handle *h = NULL((void*)0), *h_parent = NULL((void*)0); |
| 142 | int mount_id = -1, mount_id_parent = -1; |
| 143 | bool_Bool nosupp = false0, check_st_dev = true1; |
| 144 | struct stat a, b; |
| 145 | int r; |
| 146 | |
| 147 | assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/basic/mount-util.c" , 147, __PRETTY_FUNCTION__); } while (0); |
| 148 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/basic/mount-util.c" , 148, __PRETTY_FUNCTION__); } while (0); |
| 149 | |
| 150 | /* First we will try the name_to_handle_at() syscall, which |
| 151 | * tells us the mount id and an opaque file "handle". It is |
| 152 | * not supported everywhere though (kernel compile-time |
| 153 | * option, not all file systems are hooked up). If it works |
| 154 | * the mount id is usually good enough to tell us whether |
| 155 | * something is a mount point. |
| 156 | * |
| 157 | * If that didn't work we will try to read the mount id from |
| 158 | * /proc/self/fdinfo/<fd>. This is almost as good as |
| 159 | * name_to_handle_at(), however, does not return the |
| 160 | * opaque file handle. The opaque file handle is pretty useful |
| 161 | * to detect the root directory, which we should always |
| 162 | * consider a mount point. Hence we use this only as |
| 163 | * fallback. Exporting the mnt_id in fdinfo is a pretty recent |
| 164 | * kernel addition. |
| 165 | * |
| 166 | * As last fallback we do traditional fstat() based st_dev |
| 167 | * comparisons. This is how things were traditionally done, |
| 168 | * but unionfs breaks this since it exposes file |
| 169 | * systems with a variety of st_dev reported. Also, btrfs |
| 170 | * subvolumes have different st_dev, even though they aren't |
| 171 | * real mounts of their own. */ |
| 172 | |
| 173 | r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags); |
| 174 | if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-38, -13, -1, -75, -22})/sizeof(int)]; switch (r) { case -38: case -13: case -1: case -75: case -22: _found = 1; break; default: break; } _found; })) |
| 175 | /* This kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall was blocked |
| 176 | * (EACCES/EPERM; maybe through seccomp, because we are running inside of a container?), or the mount |
| 177 | * point is not triggered yet (EOVERFLOW, think nfs4), or some general name_to_handle_at() flakiness |
| 178 | * (EINVAL): fall back to simpler logic. */ |
| 179 | goto fallback_fdinfo; |
| 180 | else if (r == -EOPNOTSUPP95) |
| 181 | /* This kernel or file system does not support name_to_handle_at(), hence let's see if the upper fs |
| 182 | * supports it (in which case it is a mount point), otherwise fallback to the traditional stat() |
| 183 | * logic */ |
| 184 | nosupp = true1; |
| 185 | else if (r < 0) |
| 186 | return r; |
| 187 | |
| 188 | r = name_to_handle_at_loop(fd, "", &h_parent, &mount_id_parent, AT_EMPTY_PATH0x1000); |
| 189 | if (r == -EOPNOTSUPP95) { |
| 190 | if (nosupp) |
| 191 | /* Neither parent nor child do name_to_handle_at()? We have no choice but to fall back. */ |
| 192 | goto fallback_fdinfo; |
| 193 | else |
| 194 | /* The parent can't do name_to_handle_at() but the directory we are interested in can? If so, |
| 195 | * it must be a mount point. */ |
| 196 | return 1; |
| 197 | } else if (r < 0) |
| 198 | return r; |
| 199 | |
| 200 | /* The parent can do name_to_handle_at() but the |
| 201 | * directory we are interested in can't? If so, it |
| 202 | * must be a mount point. */ |
| 203 | if (nosupp) |
| 204 | return 1; |
| 205 | |
| 206 | /* If the file handle for the directory we are |
| 207 | * interested in and its parent are identical, we |
| 208 | * assume this is the root directory, which is a mount |
| 209 | * point. */ |
| 210 | |
| 211 | if (h->handle_bytes == h_parent->handle_bytes && |
| 212 | h->handle_type == h_parent->handle_type && |
| 213 | memcmp(h->f_handle, h_parent->f_handle, h->handle_bytes) == 0) |
| 214 | return 1; |
| 215 | |
| 216 | return mount_id != mount_id_parent; |
| 217 | |
| 218 | fallback_fdinfo: |
| 219 | r = fd_fdinfo_mnt_id(fd, filename, flags, &mount_id); |
| 220 | if (IN_SET(r, -EOPNOTSUPP, -EACCES, -EPERM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-95, -13, -1})/sizeof(int)]; switch(r) { case -95: case -13: case -1: _found = 1; break; default: break ; } _found; })) |
| 221 | goto fallback_fstat; |
| 222 | if (r < 0) |
| 223 | return r; |
| 224 | |
| 225 | r = fd_fdinfo_mnt_id(fd, "", AT_EMPTY_PATH0x1000, &mount_id_parent); |
| 226 | if (r < 0) |
| 227 | return r; |
| 228 | |
| 229 | if (mount_id != mount_id_parent) |
| 230 | return 1; |
| 231 | |
| 232 | /* Hmm, so, the mount ids are the same. This leaves one |
| 233 | * special case though for the root file system. For that, |
| 234 | * let's see if the parent directory has the same inode as we |
| 235 | * are interested in. Hence, let's also do fstat() checks now, |
| 236 | * too, but avoid the st_dev comparisons, since they aren't |
| 237 | * that useful on unionfs mounts. */ |
| 238 | check_st_dev = false0; |
| 239 | |
| 240 | fallback_fstat: |
| 241 | /* yay for fstatat() taking a different set of flags than the other |
| 242 | * _at() above */ |
| 243 | if (flags & AT_SYMLINK_FOLLOW0x400) |
| 244 | flags &= ~AT_SYMLINK_FOLLOW0x400; |
| 245 | else |
| 246 | flags |= AT_SYMLINK_NOFOLLOW0x100; |
| 247 | if (fstatat(fd, filename, &a, flags) < 0) |
| 248 | return -errno(*__errno_location ()); |
| 249 | |
| 250 | if (fstatat(fd, "", &b, AT_EMPTY_PATH0x1000) < 0) |
| 251 | return -errno(*__errno_location ()); |
| 252 | |
| 253 | /* A directory with same device and inode as its parent? Must |
| 254 | * be the root directory */ |
| 255 | if (a.st_dev == b.st_dev && |
| 256 | a.st_ino == b.st_ino) |
| 257 | return 1; |
| 258 | |
| 259 | return check_st_dev && (a.st_dev != b.st_dev); |
| 260 | } |
| 261 | |
| 262 | /* flags can be AT_SYMLINK_FOLLOW or 0 */ |
| 263 | int path_is_mount_point(const char *t, const char *root, int flags) { |
| 264 | _cleanup_free___attribute__((cleanup(freep))) char *canonical = NULL((void*)0), *parent = NULL((void*)0); |
| 265 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; |
| 266 | int r; |
| 267 | |
| 268 | assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("t"), "../src/basic/mount-util.c", 268, __PRETTY_FUNCTION__ ); } while (0); |
| 269 | assert((flags & ~AT_SYMLINK_FOLLOW) == 0)do { if ((__builtin_expect(!!(!((flags & ~0x400) == 0)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("(flags & ~AT_SYMLINK_FOLLOW) == 0" ), "../src/basic/mount-util.c", 269, __PRETTY_FUNCTION__); } while (0); |
| 270 | |
| 271 | if (path_equal(t, "/")) |
| 272 | return 1; |
| 273 | |
| 274 | /* we need to resolve symlinks manually, we can't just rely on |
| 275 | * fd_is_mount_point() to do that for us; if we have a structure like |
| 276 | * /bin -> /usr/bin/ and /usr is a mount point, then the parent that we |
| 277 | * look at needs to be /usr, not /. */ |
| 278 | if (flags & AT_SYMLINK_FOLLOW0x400) { |
| 279 | r = chase_symlinks(t, root, CHASE_TRAIL_SLASH, &canonical); |
| 280 | if (r < 0) |
| 281 | return r; |
| 282 | |
| 283 | t = canonical; |
| 284 | } |
| 285 | |
| 286 | parent = dirname_malloc(t); |
| 287 | if (!parent) |
| 288 | return -ENOMEM12; |
| 289 | |
| 290 | fd = openat(AT_FDCWD-100, parent, O_DIRECTORY0200000|O_CLOEXEC02000000|O_PATH010000000); |
| 291 | if (fd < 0) |
| 292 | return -errno(*__errno_location ()); |
| 293 | |
| 294 | return fd_is_mount_point(fd, last_path_component(t), flags); |
| 295 | } |
| 296 | |
| 297 | int path_get_mnt_id(const char *path, int *ret) { |
| 298 | int r; |
| 299 | |
| 300 | r = name_to_handle_at_loop(AT_FDCWD-100, path, NULL((void*)0), ret, 0); |
| 301 | if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-95, -38, -13, -1, -75, -22})/sizeof(int )]; switch(r) { case -95: case -38: case -13: case -1: case - 75: case -22: _found = 1; break; default: break; } _found; })) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */ |
| 302 | return fd_fdinfo_mnt_id(AT_FDCWD-100, path, 0, ret); |
| 303 | |
| 304 | return r; |
| 305 | } |
| 306 | |
| 307 | int umount_recursive(const char *prefix, int flags) { |
| 308 | bool_Bool again; |
| 309 | int n = 0, r; |
| 310 | |
| 311 | /* Try to umount everything recursively below a |
| 312 | * directory. Also, take care of stacked mounts, and keep |
| 313 | * unmounting them until they are gone. */ |
| 314 | |
| 315 | do { |
| 316 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *proc_self_mountinfo = NULL((void*)0); |
| 317 | |
| 318 | again = false0; |
| 319 | r = 0; |
| 320 | |
| 321 | proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); |
| 322 | if (!proc_self_mountinfo) |
| 323 | return -errno(*__errno_location ()); |
| 324 | |
| 325 | (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLERFSETLOCKING_BYCALLER); |
| 326 | |
| 327 | for (;;) { |
| 328 | _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0), *p = NULL((void*)0); |
| 329 | int k; |
| 330 | |
| 331 | k = fscanf(proc_self_mountinfo, |
| 332 | "%*s " /* (1) mount id */ |
| 333 | "%*s " /* (2) parent id */ |
| 334 | "%*s " /* (3) major:minor */ |
| 335 | "%*s " /* (4) root */ |
| 336 | "%ms " /* (5) mount point */ |
| 337 | "%*s" /* (6) mount options */ |
| 338 | "%*[^-]" /* (7) optional fields */ |
| 339 | "- " /* (8) separator */ |
| 340 | "%*s " /* (9) file system type */ |
| 341 | "%*s" /* (10) mount source */ |
| 342 | "%*s" /* (11) mount options 2 */ |
| 343 | "%*[^\n]", /* some rubbish at the end */ |
| 344 | &path); |
| 345 | if (k != 1) { |
| 346 | if (k == EOF(-1)) |
| 347 | break; |
| 348 | |
| 349 | continue; |
| 350 | } |
| 351 | |
| 352 | r = cunescape(path, UNESCAPE_RELAX, &p); |
| 353 | if (r < 0) |
| 354 | return r; |
| 355 | |
| 356 | if (!path_startswith(p, prefix)) |
| 357 | continue; |
| 358 | |
| 359 | if (umount2(p, flags) < 0) { |
| 360 | r = log_debug_errno(errno, "Failed to umount %s: %m", p)({ int _level = ((7)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/basic/mount-util.c", 360, __func__ , "Failed to umount %s: %m", p) : -abs(_e); }); |
| 361 | continue; |
| 362 | } |
| 363 | |
| 364 | log_debug("Successfully unmounted %s", p)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 364, __func__, "Successfully unmounted %s" , p) : -abs(_e); }); |
| 365 | |
| 366 | again = true1; |
| 367 | n++; |
| 368 | |
| 369 | break; |
| 370 | } |
| 371 | |
| 372 | } while (again); |
| 373 | |
| 374 | return r ? r : n; |
| 375 | } |
| 376 | |
| 377 | static int get_mount_flags(const char *path, unsigned long *flags) { |
| 378 | struct statvfs buf; |
| 379 | |
| 380 | if (statvfs(path, &buf) < 0) |
| 381 | return -errno(*__errno_location ()); |
| 382 | *flags = buf.f_flag; |
| 383 | return 0; |
| 384 | } |
| 385 | |
| 386 | /* Use this function only if do you have direct access to /proc/self/mountinfo |
| 387 | * and need the caller to open it for you. This is the case when /proc is |
| 388 | * masked or not mounted. Otherwise, use bind_remount_recursive. */ |
| 389 | int bind_remount_recursive_with_mountinfo(const char *prefix, bool_Bool ro, char **blacklist, FILE *proc_self_mountinfo) { |
| 390 | _cleanup_set_free_free___attribute__((cleanup(set_free_freep))) Set *done = NULL((void*)0); |
| 391 | _cleanup_free___attribute__((cleanup(freep))) char *cleaned = NULL((void*)0); |
| 392 | int r; |
| 393 | |
| 394 | assert(proc_self_mountinfo)do { if ((__builtin_expect(!!(!(proc_self_mountinfo)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("proc_self_mountinfo"), "../src/basic/mount-util.c" , 394, __PRETTY_FUNCTION__); } while (0); |
| 395 | |
| 396 | /* Recursively remount a directory (and all its submounts) read-only or read-write. If the directory is already |
| 397 | * mounted, we reuse the mount and simply mark it MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write |
| 398 | * operation). If it isn't we first make it one. Afterwards we apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to |
| 399 | * all submounts we can access, too. When mounts are stacked on the same mount point we only care for each |
| 400 | * individual "top-level" mount on each point, as we cannot influence/access the underlying mounts anyway. We |
| 401 | * do not have any effect on future submounts that might get propagated, they migt be writable. This includes |
| 402 | * future submounts that have been triggered via autofs. |
| 403 | * |
| 404 | * If the "blacklist" parameter is specified it may contain a list of subtrees to exclude from the |
| 405 | * remount operation. Note that we'll ignore the blacklist for the top-level path. */ |
| 406 | |
| 407 | cleaned = strdup(prefix); |
| 408 | if (!cleaned) |
| 409 | return -ENOMEM12; |
| 410 | |
| 411 | path_simplify(cleaned, false0); |
| 412 | |
| 413 | done = set_new(&path_hash_ops)internal_set_new(&path_hash_ops ); |
| 414 | if (!done) |
| 415 | return -ENOMEM12; |
| 416 | |
| 417 | for (;;) { |
| 418 | _cleanup_set_free_free___attribute__((cleanup(set_free_freep))) Set *todo = NULL((void*)0); |
| 419 | bool_Bool top_autofs = false0; |
| 420 | char *x; |
| 421 | unsigned long orig_flags; |
| 422 | |
| 423 | todo = set_new(&path_hash_ops)internal_set_new(&path_hash_ops ); |
| 424 | if (!todo) |
| 425 | return -ENOMEM12; |
| 426 | |
| 427 | rewind(proc_self_mountinfo); |
| 428 | |
| 429 | for (;;) { |
| 430 | _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0), *p = NULL((void*)0), *type = NULL((void*)0); |
| 431 | int k; |
| 432 | |
| 433 | k = fscanf(proc_self_mountinfo, |
| 434 | "%*s " /* (1) mount id */ |
| 435 | "%*s " /* (2) parent id */ |
| 436 | "%*s " /* (3) major:minor */ |
| 437 | "%*s " /* (4) root */ |
| 438 | "%ms " /* (5) mount point */ |
| 439 | "%*s" /* (6) mount options (superblock) */ |
| 440 | "%*[^-]" /* (7) optional fields */ |
| 441 | "- " /* (8) separator */ |
| 442 | "%ms " /* (9) file system type */ |
| 443 | "%*s" /* (10) mount source */ |
| 444 | "%*s" /* (11) mount options (bind mount) */ |
| 445 | "%*[^\n]", /* some rubbish at the end */ |
| 446 | &path, |
| 447 | &type); |
| 448 | if (k != 2) { |
| 449 | if (k == EOF(-1)) |
| 450 | break; |
| 451 | |
| 452 | continue; |
| 453 | } |
| 454 | |
| 455 | r = cunescape(path, UNESCAPE_RELAX, &p); |
| 456 | if (r < 0) |
| 457 | return r; |
| 458 | |
| 459 | if (!path_startswith(p, cleaned)) |
| 460 | continue; |
| 461 | |
| 462 | /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall |
| 463 | * operate on. */ |
| 464 | if (!path_equal(cleaned, p)) { |
| 465 | bool_Bool blacklisted = false0; |
| 466 | char **i; |
| 467 | |
| 468 | STRV_FOREACH(i, blacklist)for ((i) = (blacklist); (i) && *(i); (i)++) { |
| 469 | |
| 470 | if (path_equal(*i, cleaned)) |
| 471 | continue; |
| 472 | |
| 473 | if (!path_startswith(*i, cleaned)) |
| 474 | continue; |
| 475 | |
| 476 | if (path_startswith(p, *i)) { |
| 477 | blacklisted = true1; |
| 478 | log_debug("Not remounting %s, because blacklisted by %s, called for %s", p, *i, cleaned)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 478, __func__, "Not remounting %s, because blacklisted by %s, called for %s" , p, *i, cleaned) : -abs(_e); }); |
| 479 | break; |
| 480 | } |
| 481 | } |
| 482 | if (blacklisted) |
| 483 | continue; |
| 484 | } |
| 485 | |
| 486 | /* Let's ignore autofs mounts. If they aren't |
| 487 | * triggered yet, we want to avoid triggering |
| 488 | * them, as we don't make any guarantees for |
| 489 | * future submounts anyway. If they are |
| 490 | * already triggered, then we will find |
| 491 | * another entry for this. */ |
| 492 | if (streq(type, "autofs")(strcmp((type),("autofs")) == 0)) { |
| 493 | top_autofs = top_autofs || path_equal(cleaned, p); |
| 494 | continue; |
| 495 | } |
| 496 | |
| 497 | if (!set_contains(done, p)) { |
| 498 | r = set_consume(todo, p); |
| 499 | p = NULL((void*)0); |
| 500 | if (r == -EEXIST17) |
| 501 | continue; |
| 502 | if (r < 0) |
| 503 | return r; |
| 504 | } |
| 505 | } |
| 506 | |
| 507 | /* If we have no submounts to process anymore and if |
| 508 | * the root is either already done, or an autofs, we |
| 509 | * are done */ |
| 510 | if (set_isempty(todo) && |
| 511 | (top_autofs || set_contains(done, cleaned))) |
| 512 | return 0; |
| 513 | |
| 514 | if (!set_contains(done, cleaned) && |
| 515 | !set_contains(todo, cleaned)) { |
| 516 | /* The prefix directory itself is not yet a mount, make it one. */ |
| 517 | if (mount(cleaned, cleaned, NULL((void*)0), MS_BINDMS_BIND|MS_RECMS_REC, NULL((void*)0)) < 0) |
| 518 | return -errno(*__errno_location ()); |
| 519 | |
| 520 | orig_flags = 0; |
| 521 | (void) get_mount_flags(cleaned, &orig_flags); |
| 522 | orig_flags &= ~MS_RDONLYMS_RDONLY; |
| 523 | |
| 524 | if (mount(NULL((void*)0), prefix, NULL((void*)0), orig_flags|MS_BINDMS_BIND|MS_REMOUNTMS_REMOUNT|(ro ? MS_RDONLYMS_RDONLY : 0), NULL((void*)0)) < 0) |
| 525 | return -errno(*__errno_location ()); |
| 526 | |
| 527 | log_debug("Made top-level directory %s a mount point.", prefix)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 527, __func__, "Made top-level directory %s a mount point." , prefix) : -abs(_e); }); |
| 528 | |
| 529 | x = strdup(cleaned); |
| 530 | if (!x) |
| 531 | return -ENOMEM12; |
| 532 | |
| 533 | r = set_consume(done, x); |
| 534 | if (r < 0) |
| 535 | return r; |
| 536 | } |
| 537 | |
| 538 | while ((x = set_steal_first(todo))) { |
| 539 | |
| 540 | r = set_consume(done, x); |
| 541 | if (IN_SET(r, 0, -EEXIST)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){0, -17})/sizeof(int)]; switch(r) { case 0 : case -17: _found = 1; break; default: break; } _found; })) |
| 542 | continue; |
| 543 | if (r < 0) |
| 544 | return r; |
| 545 | |
| 546 | /* Deal with mount points that are obstructed by a later mount */ |
| 547 | r = path_is_mount_point(x, NULL((void*)0), 0); |
| 548 | if (IN_SET(r, 0, -ENOENT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){0, -2})/sizeof(int)]; switch(r) { case 0 : case -2: _found = 1; break; default: break; } _found; })) |
| 549 | continue; |
| 550 | if (r < 0) |
| 551 | return r; |
| 552 | |
| 553 | /* Try to reuse the original flag set */ |
| 554 | orig_flags = 0; |
| 555 | (void) get_mount_flags(x, &orig_flags); |
| 556 | orig_flags &= ~MS_RDONLYMS_RDONLY; |
| 557 | |
| 558 | if (mount(NULL((void*)0), x, NULL((void*)0), orig_flags|MS_BINDMS_BIND|MS_REMOUNTMS_REMOUNT|(ro ? MS_RDONLYMS_RDONLY : 0), NULL((void*)0)) < 0) |
| 559 | return -errno(*__errno_location ()); |
| 560 | |
| 561 | log_debug("Remounted %s read-only.", x)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 561, __func__, "Remounted %s read-only." , x) : -abs(_e); }); |
| 562 | } |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | int bind_remount_recursive(const char *prefix, bool_Bool ro, char **blacklist) { |
| 567 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *proc_self_mountinfo = NULL((void*)0); |
| 568 | |
| 569 | proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); |
| 570 | if (!proc_self_mountinfo) |
| 571 | return -errno(*__errno_location ()); |
| 572 | |
| 573 | (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLERFSETLOCKING_BYCALLER); |
| 574 | |
| 575 | return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo); |
| 576 | } |
| 577 | |
| 578 | int mount_move_root(const char *path) { |
| 579 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/basic/mount-util.c", 579 , __PRETTY_FUNCTION__); } while (0); |
| 580 | |
| 581 | if (chdir(path) < 0) |
| 582 | return -errno(*__errno_location ()); |
| 583 | |
| 584 | if (mount(path, "/", NULL((void*)0), MS_MOVEMS_MOVE, NULL((void*)0)) < 0) |
| 585 | return -errno(*__errno_location ()); |
| 586 | |
| 587 | if (chroot(".") < 0) |
| 588 | return -errno(*__errno_location ()); |
| 589 | |
| 590 | if (chdir("/") < 0) |
| 591 | return -errno(*__errno_location ()); |
| 592 | |
| 593 | return 0; |
| 594 | } |
| 595 | |
| 596 | bool_Bool fstype_is_network(const char *fstype) { |
| 597 | const char *x; |
| 598 | |
| 599 | x = startswith(fstype, "fuse."); |
| 600 | if (x) |
| 601 | fstype = x; |
| 602 | |
| 603 | return STR_IN_SET(fstype,(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 604 | "afs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 605 | "cifs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 606 | "smb3",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 607 | "smbfs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 608 | "sshfs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 609 | "ncpfs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 610 | "ncp",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 611 | "nfs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 612 | "nfs4",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 613 | "gfs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 614 | "gfs2",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 615 | "glusterfs",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 616 | "pvfs2", /* OrangeFS */(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 617 | "ocfs2",(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))) |
| 618 | "lustre")(!!strv_find((((char**) ((const char*[]) { "afs", "cifs", "smb3" , "smbfs", "sshfs", "ncpfs", "ncp", "nfs", "nfs4", "gfs", "gfs2" , "glusterfs", "pvfs2", "ocfs2", "lustre", ((void*)0) }))), ( fstype))); |
| 619 | } |
| 620 | |
| 621 | bool_Bool fstype_is_api_vfs(const char *fstype) { |
| 622 | return STR_IN_SET(fstype,(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 623 | "autofs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 624 | "bpf",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 625 | "cgroup",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 626 | "cgroup2",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 627 | "configfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 628 | "cpuset",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 629 | "debugfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 630 | "devpts",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 631 | "devtmpfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 632 | "efivarfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 633 | "fusectl",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 634 | "hugetlbfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 635 | "mqueue",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 636 | "proc",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 637 | "pstore",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 638 | "ramfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 639 | "securityfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 640 | "sysfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 641 | "tmpfs",(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))) |
| 642 | "tracefs")(!!strv_find((((char**) ((const char*[]) { "autofs", "bpf", "cgroup" , "cgroup2", "configfs", "cpuset", "debugfs", "devpts", "devtmpfs" , "efivarfs", "fusectl", "hugetlbfs", "mqueue", "proc", "pstore" , "ramfs", "securityfs", "sysfs", "tmpfs", "tracefs", ((void* )0) }))), (fstype))); |
| 643 | } |
| 644 | |
| 645 | bool_Bool fstype_is_ro(const char *fstype) { |
| 646 | /* All Linux file systems that are necessarily read-only */ |
| 647 | return STR_IN_SET(fstype,(!!strv_find((((char**) ((const char*[]) { "DM_verity_hash", "iso9660" , "squashfs", ((void*)0) }))), (fstype))) |
| 648 | "DM_verity_hash",(!!strv_find((((char**) ((const char*[]) { "DM_verity_hash", "iso9660" , "squashfs", ((void*)0) }))), (fstype))) |
| 649 | "iso9660",(!!strv_find((((char**) ((const char*[]) { "DM_verity_hash", "iso9660" , "squashfs", ((void*)0) }))), (fstype))) |
| 650 | "squashfs")(!!strv_find((((char**) ((const char*[]) { "DM_verity_hash", "iso9660" , "squashfs", ((void*)0) }))), (fstype))); |
| 651 | } |
| 652 | |
| 653 | bool_Bool fstype_can_discard(const char *fstype) { |
| 654 | return STR_IN_SET(fstype,(!!strv_find((((char**) ((const char*[]) { "btrfs", "ext4", "vfat" , "xfs", ((void*)0) }))), (fstype))) |
| 655 | "btrfs",(!!strv_find((((char**) ((const char*[]) { "btrfs", "ext4", "vfat" , "xfs", ((void*)0) }))), (fstype))) |
| 656 | "ext4",(!!strv_find((((char**) ((const char*[]) { "btrfs", "ext4", "vfat" , "xfs", ((void*)0) }))), (fstype))) |
| 657 | "vfat",(!!strv_find((((char**) ((const char*[]) { "btrfs", "ext4", "vfat" , "xfs", ((void*)0) }))), (fstype))) |
| 658 | "xfs")(!!strv_find((((char**) ((const char*[]) { "btrfs", "ext4", "vfat" , "xfs", ((void*)0) }))), (fstype))); |
| 659 | } |
| 660 | |
| 661 | bool_Bool fstype_can_uid_gid(const char *fstype) { |
| 662 | |
| 663 | /* All file systems that have a uid=/gid= mount option that fixates the owners of all files and directories, |
| 664 | * current and future. */ |
| 665 | |
| 666 | return STR_IN_SET(fstype,(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 667 | "adfs",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 668 | "fat",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 669 | "hfs",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 670 | "hpfs",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 671 | "iso9660",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 672 | "msdos",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 673 | "ntfs",(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))) |
| 674 | "vfat")(!!strv_find((((char**) ((const char*[]) { "adfs", "fat", "hfs" , "hpfs", "iso9660", "msdos", "ntfs", "vfat", ((void*)0) }))) , (fstype))); |
| 675 | } |
| 676 | |
| 677 | int repeat_unmount(const char *path, int flags) { |
| 678 | bool_Bool done = false0; |
| 679 | |
| 680 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/basic/mount-util.c", 680 , __PRETTY_FUNCTION__); } while (0); |
| 681 | |
| 682 | /* If there are multiple mounts on a mount point, this |
| 683 | * removes them all */ |
| 684 | |
| 685 | for (;;) { |
| 686 | if (umount2(path, flags) < 0) { |
| 687 | |
| 688 | if (errno(*__errno_location ()) == EINVAL22) |
| 689 | return done; |
| 690 | |
| 691 | return -errno(*__errno_location ()); |
| 692 | } |
| 693 | |
| 694 | done = true1; |
| 695 | } |
| 696 | } |
| 697 | |
| 698 | const char* mode_to_inaccessible_node(mode_t mode) { |
| 699 | /* This function maps a node type to a corresponding inaccessible file node. These nodes are created during |
| 700 | * early boot by PID 1. In some cases we lacked the privs to create the character and block devices (maybe |
| 701 | * because we run in an userns environment, or miss CAP_SYS_MKNOD, or run with a devices policy that excludes |
| 702 | * device nodes with major and minor of 0), but that's fine, in that case we use an AF_UNIX file node instead, |
| 703 | * which is not the same, but close enough for most uses. And most importantly, the kernel allows bind mounts |
| 704 | * from socket nodes to any non-directory file nodes, and that's the most important thing that matters. */ |
| 705 | |
| 706 | switch(mode & S_IFMT0170000) { |
| 707 | case S_IFREG0100000: |
| 708 | return "/run/systemd/inaccessible/reg"; |
| 709 | |
| 710 | case S_IFDIR0040000: |
| 711 | return "/run/systemd/inaccessible/dir"; |
| 712 | |
| 713 | case S_IFCHR0020000: |
| 714 | if (access("/run/systemd/inaccessible/chr", F_OK0) == 0) |
| 715 | return "/run/systemd/inaccessible/chr"; |
| 716 | return "/run/systemd/inaccessible/sock"; |
| 717 | |
| 718 | case S_IFBLK0060000: |
| 719 | if (access("/run/systemd/inaccessible/blk", F_OK0) == 0) |
| 720 | return "/run/systemd/inaccessible/blk"; |
| 721 | return "/run/systemd/inaccessible/sock"; |
| 722 | |
| 723 | case S_IFIFO0010000: |
| 724 | return "/run/systemd/inaccessible/fifo"; |
| 725 | |
| 726 | case S_IFSOCK0140000: |
| 727 | return "/run/systemd/inaccessible/sock"; |
| 728 | } |
| 729 | return NULL((void*)0); |
| 730 | } |
| 731 | |
| 732 | #define FLAG(name)(flags & name ? "name" "|" : "") (flags & name ? STRINGIFY(name)"name" "|" : "") |
| 733 | static char* mount_flags_to_string(long unsigned flags) { |
| 734 | char *x; |
| 735 | _cleanup_free___attribute__((cleanup(freep))) char *y = NULL((void*)0); |
| 736 | long unsigned overflow; |
| 737 | |
| 738 | overflow = flags & ~(MS_RDONLYMS_RDONLY | |
| 739 | MS_NOSUIDMS_NOSUID | |
| 740 | MS_NODEVMS_NODEV | |
| 741 | MS_NOEXECMS_NOEXEC | |
| 742 | MS_SYNCHRONOUSMS_SYNCHRONOUS | |
| 743 | MS_REMOUNTMS_REMOUNT | |
| 744 | MS_MANDLOCKMS_MANDLOCK | |
| 745 | MS_DIRSYNCMS_DIRSYNC | |
| 746 | MS_NOATIMEMS_NOATIME | |
| 747 | MS_NODIRATIMEMS_NODIRATIME | |
| 748 | MS_BINDMS_BIND | |
| 749 | MS_MOVEMS_MOVE | |
| 750 | MS_RECMS_REC | |
| 751 | MS_SILENTMS_SILENT | |
| 752 | MS_POSIXACLMS_POSIXACL | |
| 753 | MS_UNBINDABLEMS_UNBINDABLE | |
| 754 | MS_PRIVATEMS_PRIVATE | |
| 755 | MS_SLAVEMS_SLAVE | |
| 756 | MS_SHAREDMS_SHARED | |
| 757 | MS_RELATIMEMS_RELATIME | |
| 758 | MS_KERNMOUNTMS_KERNMOUNT | |
| 759 | MS_I_VERSIONMS_I_VERSION | |
| 760 | MS_STRICTATIMEMS_STRICTATIME | |
| 761 | MS_LAZYTIMEMS_LAZYTIME); |
| 762 | |
| 763 | if (flags == 0 || overflow != 0) |
| 764 | if (asprintf(&y, "%lx", overflow) < 0) |
| 765 | return NULL((void*)0); |
| 766 | |
| 767 | x = strjoin(FLAG(MS_RDONLY),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 768 | FLAG(MS_NOSUID),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 769 | FLAG(MS_NODEV),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 770 | FLAG(MS_NOEXEC),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 771 | FLAG(MS_SYNCHRONOUS),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 772 | FLAG(MS_REMOUNT),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 773 | FLAG(MS_MANDLOCK),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 774 | FLAG(MS_DIRSYNC),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 775 | FLAG(MS_NOATIME),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 776 | FLAG(MS_NODIRATIME),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 777 | FLAG(MS_BIND),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 778 | FLAG(MS_MOVE),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 779 | FLAG(MS_REC),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 780 | FLAG(MS_SILENT),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 781 | FLAG(MS_POSIXACL),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 782 | FLAG(MS_UNBINDABLE),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 783 | FLAG(MS_PRIVATE),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 784 | FLAG(MS_SLAVE),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 785 | FLAG(MS_SHARED),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 786 | FLAG(MS_RELATIME),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 787 | FLAG(MS_KERNMOUNT),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 788 | FLAG(MS_I_VERSION),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 789 | FLAG(MS_STRICTATIME),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 790 | FLAG(MS_LAZYTIME),strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)) |
| 791 | y)strjoin_real(((flags & MS_RDONLY ? "MS_RDONLY" "|" : "")) , (flags & MS_NOSUID ? "MS_NOSUID" "|" : ""), (flags & MS_NODEV ? "MS_NODEV" "|" : ""), (flags & MS_NOEXEC ? "MS_NOEXEC" "|" : ""), (flags & MS_SYNCHRONOUS ? "MS_SYNCHRONOUS" "|" : ""), (flags & MS_REMOUNT ? "MS_REMOUNT" "|" : ""), (flags & MS_MANDLOCK ? "MS_MANDLOCK" "|" : ""), (flags & MS_DIRSYNC ? "MS_DIRSYNC" "|" : ""), (flags & MS_NOATIME ? "MS_NOATIME" "|" : ""), (flags & MS_NODIRATIME ? "MS_NODIRATIME" "|" : ""), (flags & MS_BIND ? "MS_BIND" "|" : ""), (flags & MS_MOVE ? "MS_MOVE" "|" : ""), (flags & MS_REC ? "MS_REC" "|" : ""), (flags & MS_SILENT ? "MS_SILENT" "|" : ""), ( flags & MS_POSIXACL ? "MS_POSIXACL" "|" : ""), (flags & MS_UNBINDABLE ? "MS_UNBINDABLE" "|" : ""), (flags & MS_PRIVATE ? "MS_PRIVATE" "|" : ""), (flags & MS_SLAVE ? "MS_SLAVE" "|" : ""), (flags & MS_SHARED ? "MS_SHARED" "|" : ""), ( flags & MS_RELATIME ? "MS_RELATIME" "|" : ""), (flags & MS_KERNMOUNT ? "MS_KERNMOUNT" "|" : ""), (flags & MS_I_VERSION ? "MS_I_VERSION" "|" : ""), (flags & MS_STRICTATIME ? "MS_STRICTATIME" "|" : ""), (flags & MS_LAZYTIME ? "MS_LAZYTIME" "|" : "" ), y, ((void*)0)); |
| 792 | if (!x) |
| 793 | return NULL((void*)0); |
| 794 | if (!y) |
| 795 | x[strlen(x) - 1] = '\0'; /* truncate the last | */ |
| 796 | return x; |
| 797 | } |
| 798 | |
| 799 | int mount_verbose( |
| 800 | int error_log_level, |
| 801 | const char *what, |
| 802 | const char *where, |
| 803 | const char *type, |
| 804 | unsigned long flags, |
| 805 | const char *options) { |
| 806 | |
| 807 | _cleanup_free___attribute__((cleanup(freep))) char *fl = NULL((void*)0), *o = NULL((void*)0); |
| 808 | unsigned long f; |
| 809 | int r; |
| 810 | |
| 811 | r = mount_option_mangle(options, flags, &f, &o); |
| 812 | if (r < 0) |
| 813 | return log_full_errno(error_log_level, r,({ int _level = ((error_log_level)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 815, __func__, "Failed to mangle mount options %s: %m" , strempty(options)) : -abs(_e); }) |
| 814 | "Failed to mangle mount options %s: %m",({ int _level = ((error_log_level)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 815, __func__, "Failed to mangle mount options %s: %m" , strempty(options)) : -abs(_e); }) |
| 815 | strempty(options))({ int _level = ((error_log_level)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 815, __func__, "Failed to mangle mount options %s: %m" , strempty(options)) : -abs(_e); }); |
| 816 | |
| 817 | fl = mount_flags_to_string(f); |
| 818 | |
| 819 | if ((f & MS_REMOUNTMS_REMOUNT) && !what && !type) |
| 820 | log_debug("Remounting %s (%s \"%s\")...",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 821, __func__, "Remounting %s (%s \"%s\")..." , where, strnull(fl), strempty(o)) : -abs(_e); }) |
| 821 | where, strnull(fl), strempty(o))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 821, __func__, "Remounting %s (%s \"%s\")..." , where, strnull(fl), strempty(o)) : -abs(_e); }); |
| 822 | else if (!what && !type) |
| 823 | log_debug("Mounting %s (%s \"%s\")...",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 824, __func__, "Mounting %s (%s \"%s\")..." , where, strnull(fl), strempty(o)) : -abs(_e); }) |
| 824 | where, strnull(fl), strempty(o))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 824, __func__, "Mounting %s (%s \"%s\")..." , where, strnull(fl), strempty(o)) : -abs(_e); }); |
| 825 | else if ((f & MS_BINDMS_BIND) && !type) |
| 826 | log_debug("Bind-mounting %s on %s (%s \"%s\")...",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 827, __func__, "Bind-mounting %s on %s (%s \"%s\")..." , what, where, strnull(fl), strempty(o)) : -abs(_e); }) |
| 827 | what, where, strnull(fl), strempty(o))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 827, __func__, "Bind-mounting %s on %s (%s \"%s\")..." , what, where, strnull(fl), strempty(o)) : -abs(_e); }); |
| 828 | else if (f & MS_MOVEMS_MOVE) |
| 829 | log_debug("Moving mount %s → %s (%s \"%s\")...",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 830, __func__, "Moving mount %s → %s (%s \"%s\")..." , what, where, strnull(fl), strempty(o)) : -abs(_e); }) |
| 830 | what, where, strnull(fl), strempty(o))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 830, __func__, "Moving mount %s → %s (%s \"%s\")..." , what, where, strnull(fl), strempty(o)) : -abs(_e); }); |
| 831 | else |
| 832 | log_debug("Mounting %s on %s (%s \"%s\")...",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 833, __func__, "Mounting %s on %s (%s \"%s\")..." , strna(type), where, strnull(fl), strempty(o)) : -abs(_e); } ) |
| 833 | strna(type), where, strnull(fl), strempty(o))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 833, __func__, "Mounting %s on %s (%s \"%s\")..." , strna(type), where, strnull(fl), strempty(o)) : -abs(_e); } ); |
| 834 | if (mount(what, where, type, f, o) < 0) |
| 835 | return log_full_errno(error_log_level, errno,({ int _level = ((error_log_level)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/basic/mount-util.c" , 837, __func__, "Failed to mount %s on %s (%s \"%s\"): %m", strna (type), where, strnull(fl), strempty(o)) : -abs(_e); }) |
| 836 | "Failed to mount %s on %s (%s \"%s\"): %m",({ int _level = ((error_log_level)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/basic/mount-util.c" , 837, __func__, "Failed to mount %s on %s (%s \"%s\"): %m", strna (type), where, strnull(fl), strempty(o)) : -abs(_e); }) |
| 837 | strna(type), where, strnull(fl), strempty(o))({ int _level = ((error_log_level)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/basic/mount-util.c" , 837, __func__, "Failed to mount %s on %s (%s \"%s\"): %m", strna (type), where, strnull(fl), strempty(o)) : -abs(_e); }); |
| 838 | return 0; |
| 839 | } |
| 840 | |
| 841 | int umount_verbose(const char *what) { |
| 842 | log_debug("Umounting %s...", what)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/basic/mount-util.c", 842, __func__, "Umounting %s..." , what) : -abs(_e); }); |
| 843 | if (umount(what) < 0) |
| 844 | return log_error_errno(errno, "Failed to unmount %s: %m", what)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/basic/mount-util.c", 844, __func__ , "Failed to unmount %s: %m", what) : -abs(_e); }); |
| 845 | return 0; |
| 846 | } |
| 847 | |
| 848 | const char *mount_propagation_flags_to_string(unsigned long flags) { |
| 849 | |
| 850 | switch (flags & (MS_SHAREDMS_SHARED|MS_SLAVEMS_SLAVE|MS_PRIVATEMS_PRIVATE)) { |
| 851 | case 0: |
| 852 | return ""; |
| 853 | case MS_SHAREDMS_SHARED: |
| 854 | return "shared"; |
| 855 | case MS_SLAVEMS_SLAVE: |
| 856 | return "slave"; |
| 857 | case MS_PRIVATEMS_PRIVATE: |
| 858 | return "private"; |
| 859 | } |
| 860 | |
| 861 | return NULL((void*)0); |
| 862 | } |
| 863 | |
| 864 | int mount_propagation_flags_from_string(const char *name, unsigned long *ret) { |
| 865 | |
| 866 | if (isempty(name)) |
| 867 | *ret = 0; |
| 868 | else if (streq(name, "shared")(strcmp((name),("shared")) == 0)) |
| 869 | *ret = MS_SHAREDMS_SHARED; |
| 870 | else if (streq(name, "slave")(strcmp((name),("slave")) == 0)) |
| 871 | *ret = MS_SLAVEMS_SLAVE; |
| 872 | else if (streq(name, "private")(strcmp((name),("private")) == 0)) |
| 873 | *ret = MS_PRIVATEMS_PRIVATE; |
| 874 | else |
| 875 | return -EINVAL22; |
| 876 | return 0; |
| 877 | } |
| 878 | |
| 879 | int mount_option_mangle( |
| 880 | const char *options, |
| 881 | unsigned long mount_flags, |
| 882 | unsigned long *ret_mount_flags, |
| 883 | char **ret_remaining_options) { |
| 884 | |
| 885 | const struct libmnt_optmap *map; |
| 886 | _cleanup_free___attribute__((cleanup(freep))) char *ret = NULL((void*)0); |
| 887 | const char *p; |
| 888 | int r; |
| 889 | |
| 890 | /* This extracts mount flags from the mount options, and store |
| 891 | * non-mount-flag options to '*ret_remaining_options'. |
| 892 | * E.g., |
| 893 | * "rw,nosuid,nodev,relatime,size=1630748k,mode=700,uid=1000,gid=1000" |
| 894 | * is split to MS_NOSUID|MS_NODEV|MS_RELATIME and |
| 895 | * "size=1630748k,mode=700,uid=1000,gid=1000". |
| 896 | * See more examples in test-mount-utils.c. |
| 897 | * |
| 898 | * Note that if 'options' does not contain any non-mount-flag options, |
| 899 | * then '*ret_remaining_options' is set to NULL instread of empty string. |
| 900 | * Note that this does not check validity of options stored in |
| 901 | * '*ret_remaining_options'. |
| 902 | * Note that if 'options' is NULL, then this just copies 'mount_flags' |
| 903 | * to '*ret_mount_flags'. */ |
| 904 | |
| 905 | assert(ret_mount_flags)do { if ((__builtin_expect(!!(!(ret_mount_flags)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret_mount_flags"), "../src/basic/mount-util.c" , 905, __PRETTY_FUNCTION__); } while (0); |
| 906 | assert(ret_remaining_options)do { if ((__builtin_expect(!!(!(ret_remaining_options)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret_remaining_options"), "../src/basic/mount-util.c" , 906, __PRETTY_FUNCTION__); } while (0); |
| 907 | |
| 908 | map = mnt_get_builtin_optmap(MNT_LINUX_MAP); |
| 909 | if (!map) |
| 910 | return -EINVAL22; |
| 911 | |
| 912 | p = options; |
| 913 | for (;;) { |
| 914 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); |
| 915 | const struct libmnt_optmap *ent; |
| 916 | |
| 917 | r = extract_first_word(&p, &word, ",", EXTRACT_QUOTES); |
| 918 | if (r < 0) |
| 919 | return r; |
| 920 | if (r == 0) |
| 921 | break; |
| 922 | |
| 923 | for (ent = map; ent->name; ent++) { |
| 924 | /* All entries in MNT_LINUX_MAP do not take any argument. |
| 925 | * Thus, ent->name does not contain "=" or "[=]". */ |
| 926 | if (!streq(word, ent->name)(strcmp((word),(ent->name)) == 0)) |
| 927 | continue; |
| 928 | |
| 929 | if (!(ent->mask & MNT_INVERT(1 << 1))) |
| 930 | mount_flags |= ent->id; |
| 931 | else if (mount_flags & ent->id) |
| 932 | mount_flags ^= ent->id; |
| 933 | |
| 934 | break; |
| 935 | } |
| 936 | |
| 937 | /* If 'word' is not a mount flag, then store it in '*ret_remaining_options'. */ |
| 938 | if (!ent->name && !strextend_with_separator(&ret, ",", word, NULL((void*)0))) |
| 939 | return -ENOMEM12; |
| 940 | } |
| 941 | |
| 942 | *ret_mount_flags = mount_flags; |
| 943 | *ret_remaining_options = TAKE_PTR(ret)({ typeof(ret) _ptr_ = (ret); (ret) = ((void*)0); _ptr_; }); |
| 944 | |
| 945 | return 0; |
| 946 | } |