]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shutdown/umount.c
Merge pull request #26785 from keszybz/udev-distcheck
[thirdparty/systemd.git] / src / shutdown / umount.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
e3478379 2/***
96b2fb93 3 Copyright © 2010 ProFUSION embedded systems
e3478379
FF
4***/
5
6#include <errno.h>
7#include <fcntl.h>
01234e1f 8#include <linux/dm-ioctl.h>
0b220a5f
HK
9#include <linux/major.h>
10#include <linux/raid/md_u.h>
4f5dd394 11#include <linux/loop.h>
e3478379
FF
12#include <sys/mount.h>
13#include <sys/swap.h>
ca78ad1d
ZJS
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
e3478379 17
48f46254
LP
18#if HAVE_VALGRIND_MEMCHECK_H
19#include <valgrind/memcheck.h>
20#endif
21
6bcf00ed 22#include "sd-device.h"
b4bbcaa9 23
b5efdb8a 24#include "alloc-util.h"
18c528e9 25#include "blockdev-util.h"
6dc68a00 26#include "chase-symlinks.h"
28db6fbf 27#include "constants.h"
8437c059 28#include "device-util.h"
20596876 29#include "dirent-util.h"
07630cea 30#include "escape.h"
3ffd4af2 31#include "fd-util.h"
20596876
JJ
32#include "fileio.h"
33#include "fs-util.h"
471b48ed 34#include "fstab-util.h"
fb36b133 35#include "libmount-util.h"
6dc68a00 36#include "mkdir.h"
e3478379 37#include "mount-setup.h"
18c528e9 38#include "mount-util.h"
049af8ad 39#include "mountpoint-util.h"
20596876 40#include "parse-util.h"
9eb977db 41#include "path-util.h"
dccca82b 42#include "process-util.h"
6dc68a00 43#include "random-util.h"
d5641e0d 44#include "signal-util.h"
6dc68a00 45#include "stat-util.h"
07630cea 46#include "string-util.h"
da9fc98d 47#include "strv.h"
bf819d3a 48#include "sync-util.h"
3ffd4af2 49#include "umount.h"
024f268d 50#include "virt.h"
e3478379 51
12aad1d0
LP
52static void mount_point_free(MountPoint **head, MountPoint *m) {
53 assert(head);
54 assert(m);
e3478379 55
71fda00f 56 LIST_REMOVE(mount_point, *head, m);
12aad1d0
LP
57
58 free(m->path);
3bc341be 59 free(m->remount_options);
12aad1d0 60 free(m);
e3478379
FF
61}
62
6fa392bf 63void mount_points_list_free(MountPoint **head) {
12aad1d0
LP
64 assert(head);
65
66 while (*head)
67 mount_point_free(head, *head);
e3478379
FF
68}
69
6fa392bf 70int mount_points_list_get(const char *mountinfo, MountPoint **head) {
13dcfe46
ZJS
71 _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
72 _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
527b7a42 73 int r;
e3478379 74
12aad1d0
LP
75 assert(head);
76
e2857b3d 77 r = libmount_parse(mountinfo, NULL, &table, &iter);
95b862b0 78 if (r < 0)
f795267e 79 return log_error_errno(r, "Failed to parse %s: %m", mountinfo ?: "/proc/self/mountinfo");
95b862b0
ZJS
80
81 for (;;) {
c905aaf6 82 _cleanup_free_ char *options = NULL, *remount_options = NULL;
95b862b0 83 struct libmnt_fs *fs;
66c91c3a 84 const char *path, *fstype;
95b862b0 85 unsigned long remount_flags = 0u;
f11efcbe 86 bool try_remount_ro, is_api_vfs;
9d1b2b22 87 _cleanup_free_ MountPoint *m = NULL;
e3478379 88
13dcfe46 89 r = mnt_table_next_fs(table, iter, &fs);
c905aaf6 90 if (r == 1) /* EOF */
95b862b0 91 break;
527b7a42 92 if (r < 0)
f795267e 93 return log_error_errno(r, "Failed to get next entry from %s: %m", mountinfo ?: "/proc/self/mountinfo");
95b862b0
ZJS
94
95 path = mnt_fs_get_target(fs);
96 if (!path)
97 continue;
98
95b862b0 99 fstype = mnt_fs_get_fstype(fs);
e3478379 100
83f3bf4b
LP
101 /* Combine the generic VFS options with the FS-specific options. Duplicates are not a problem
102 * here, because the only options that should come up twice are typically ro/rw, which are
103 * turned into MS_RDONLY or the inversion of it.
66c91c3a 104 *
83f3bf4b
LP
105 * Even if there are duplicates later in mount_option_mangle() they shouldn't hurt anyways as
106 * they override each other. */
c2bc710b 107 if (!strextend_with_separator(&options, ",", mnt_fs_get_vfs_options(fs)))
66c91c3a 108 return log_oom();
c2bc710b 109 if (!strextend_with_separator(&options, ",", mnt_fs_get_fs_options(fs)))
66c91c3a 110 return log_oom();
111
83f3bf4b
LP
112 /* Ignore mount points we can't unmount because they are API or because we are keeping them
113 * open (like /dev/console). Also, ignore all mounts below API file systems, since they are
114 * likely virtual too, and hence not worth spending time on. Also, in unprivileged containers
115 * we might lack the rights to unmount these things, hence don't bother. */
9d1b2b22
ZJS
116 if (mount_point_is_api(path) ||
117 mount_point_ignore(path) ||
118 PATH_STARTSWITH_SET(path, "/dev", "/sys", "/proc"))
2054a5b8 119 continue;
2054a5b8 120
f11efcbe
LP
121 is_api_vfs = fstype_is_api_vfs(fstype);
122
83f3bf4b
LP
123 /* If we are in a container, don't attempt to read-only mount anything as that brings no real
124 * benefits, but might confuse the host, as we remount the superblock here, not the bind
125 * mount.
1d62d22d 126 *
83f3bf4b
LP
127 * If the filesystem is a network fs, also skip the remount. It brings no value (we cannot
128 * leave a "dirty fs") and could hang if the network is down. Note that umount2() is more
129 * careful and will not hang because of the network being down. */
95b862b0
ZJS
130 try_remount_ro = detect_container() <= 0 &&
131 !fstype_is_network(fstype) &&
f11efcbe 132 !is_api_vfs &&
95b862b0
ZJS
133 !fstype_is_ro(fstype) &&
134 !fstab_test_yes_no_option(options, "ro\0rw\0");
3bc341be 135
95b862b0 136 if (try_remount_ro) {
83f3bf4b
LP
137 /* mount(2) states that mount flags and options need to be exactly the same as they
138 * were when the filesystem was mounted, except for the desired changes. So we
139 * reconstruct both here and adjust them for the later remount call too. */
3bc341be 140
95b862b0
ZJS
141 r = mnt_fs_get_propagation(fs, &remount_flags);
142 if (r < 0) {
143 log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path);
144 continue;
145 }
3bc341be 146
95b862b0
ZJS
147 r = mount_option_mangle(options, remount_flags, &remount_flags, &remount_options);
148 if (r < 0) {
149 log_warning_errno(r, "mount_option_mangle failed for %s, ignoring: %m", path);
150 continue;
151 }
3bc341be
JJ
152
153 /* MS_BIND is special. If it is provided it will only make the mount-point
154 * read-only. If left out, the super block itself is remounted, which we want. */
95b862b0 155 remount_flags = (remount_flags|MS_REMOUNT|MS_RDONLY) & ~MS_BIND;
3bc341be 156 }
471b48ed 157
efc90b98 158 m = new(MountPoint, 1);
95b862b0
ZJS
159 if (!m)
160 return log_oom();
161
6dc68a00
VD
162 r = libmount_is_leaf(table, fs);
163 if (r < 0)
164 return log_error_errno(r, "Failed to get children mounts for %s from %s: %m", path, mountinfo ?: "/proc/self/mountinfo");
165 bool leaf = r;
166
efc90b98
LP
167 *m = (MountPoint) {
168 .remount_options = remount_options,
169 .remount_flags = remount_flags,
170 .try_remount_ro = try_remount_ro,
f11efcbe
LP
171
172 /* Unmount sysfs/procfs/… lazily, since syncing doesn't matter there, and it's OK if
173 * something keeps an fd open to it. */
174 .umount_lazily = is_api_vfs,
6dc68a00 175 .leaf = leaf,
efc90b98
LP
176 };
177
9d1b2b22
ZJS
178 m->path = strdup(path);
179 if (!m->path)
180 return log_oom();
181
efc90b98 182 TAKE_PTR(remount_options);
95b862b0 183
9d1b2b22 184 LIST_PREPEND(mount_point, *head, TAKE_PTR(m));
e3478379
FF
185 }
186
c3544e8d 187 return 0;
e3478379
FF
188}
189
1fd8edb5 190int swap_list_get(const char *swaps, MountPoint **head) {
71ae04c4
ZJS
191 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
192 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
527b7a42 193 int r;
e3478379 194
12aad1d0
LP
195 assert(head);
196
71ae04c4
ZJS
197 t = mnt_new_table();
198 i = mnt_new_iter(MNT_ITER_FORWARD);
199 if (!t || !i)
200 return log_oom();
e3478379 201
71ae04c4 202 r = mnt_table_parse_swaps(t, swaps);
2cdd0d61
LP
203 if (r == -ENOENT) /* no /proc/swaps is fine */
204 return 0;
71ae04c4 205 if (r < 0)
f795267e 206 return log_error_errno(r, "Failed to parse %s: %m", swaps ?: "/proc/swaps");
71ae04c4
ZJS
207
208 for (;;) {
209 struct libmnt_fs *fs;
9d1b2b22 210 _cleanup_free_ MountPoint *swap = NULL;
71ae04c4 211 const char *source;
71ae04c4
ZJS
212
213 r = mnt_table_next_fs(t, i, &fs);
c905aaf6 214 if (r == 1) /* EOF */
71ae04c4
ZJS
215 break;
216 if (r < 0)
f795267e 217 return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps");
e3478379 218
71ae04c4
ZJS
219 source = mnt_fs_get_source(fs);
220 if (!source)
e3478379 221 continue;
e3478379 222
527b7a42 223 swap = new0(MountPoint, 1);
595c66a3 224 if (!swap)
4e201419 225 return log_oom();
e3478379 226
9d1b2b22
ZJS
227 swap->path = strdup(source);
228 if (!swap->path)
4e201419 229 return log_oom();
9d1b2b22
ZJS
230
231 LIST_PREPEND(mount_point, *head, TAKE_PTR(swap));
e3478379
FF
232 }
233
e1d75803 234 return 0;
e3478379
FF
235}
236
12aad1d0 237static int loopback_list_get(MountPoint **head) {
6bcf00ed
YW
238 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
239 sd_device *d;
06acf2d4 240 int r;
e3478379 241
12aad1d0
LP
242 assert(head);
243
6bcf00ed
YW
244 r = sd_device_enumerator_new(&e);
245 if (r < 0)
246 return r;
e3478379 247
6bcf00ed
YW
248 r = sd_device_enumerator_allow_uninitialized(e);
249 if (r < 0)
250 return r;
e3478379 251
6bcf00ed 252 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
06acf2d4
LP
253 if (r < 0)
254 return r;
255
6bcf00ed 256 r = sd_device_enumerator_add_match_sysname(e, "loop*");
06acf2d4
LP
257 if (r < 0)
258 return r;
259
6bcf00ed 260 r = sd_device_enumerator_add_match_sysattr(e, "loop/backing_file", NULL, true);
06acf2d4
LP
261 if (r < 0)
262 return r;
e3478379 263
8437c059 264 FOREACH_DEVICE(e, d) {
209c6f03 265 _cleanup_free_ char *p = NULL;
6bcf00ed 266 const char *dn;
209c6f03 267 MountPoint *lb;
63135a2d 268 dev_t devnum;
e3478379 269
63135a2d
LP
270 if (sd_device_get_devnum(d, &devnum) < 0 ||
271 sd_device_get_devname(d, &dn) < 0)
2d9a3397 272 continue;
b854a7e7 273
209c6f03
YW
274 p = strdup(dn);
275 if (!p)
276 return -ENOMEM;
277
278 lb = new(MountPoint, 1);
a6dcd229 279 if (!lb)
1ca208fb 280 return -ENOMEM;
e3478379 281
209c6f03
YW
282 *lb = (MountPoint) {
283 .path = TAKE_PTR(p),
63135a2d 284 .devnum = devnum,
209c6f03 285 };
a6dcd229 286
71fda00f 287 LIST_PREPEND(mount_point, *head, lb);
e3478379
FF
288 }
289
1ca208fb 290 return 0;
e3478379
FF
291}
292
12aad1d0 293static int dm_list_get(MountPoint **head) {
6bcf00ed
YW
294 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
295 sd_device *d;
06acf2d4 296 int r;
d48141ba 297
12aad1d0
LP
298 assert(head);
299
6bcf00ed
YW
300 r = sd_device_enumerator_new(&e);
301 if (r < 0)
302 return r;
d48141ba 303
6bcf00ed
YW
304 r = sd_device_enumerator_allow_uninitialized(e);
305 if (r < 0)
306 return r;
d48141ba 307
6bcf00ed 308 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
06acf2d4
LP
309 if (r < 0)
310 return r;
d48141ba 311
6bcf00ed 312 r = sd_device_enumerator_add_match_sysname(e, "dm-*");
06acf2d4
LP
313 if (r < 0)
314 return r;
d48141ba 315
8437c059 316 FOREACH_DEVICE(e, d) {
209c6f03 317 _cleanup_free_ char *p = NULL;
6bcf00ed 318 const char *dn;
209c6f03 319 MountPoint *m;
6bcf00ed 320 dev_t devnum;
d48141ba 321
209c6f03
YW
322 if (sd_device_get_devnum(d, &devnum) < 0 ||
323 sd_device_get_devname(d, &dn) < 0)
6bcf00ed 324 continue;
d48141ba 325
209c6f03
YW
326 p = strdup(dn);
327 if (!p)
328 return -ENOMEM;
d48141ba 329
209c6f03 330 m = new(MountPoint, 1);
a6dcd229 331 if (!m)
1ca208fb 332 return -ENOMEM;
d48141ba 333
209c6f03
YW
334 *m = (MountPoint) {
335 .path = TAKE_PTR(p),
336 .devnum = devnum,
337 };
a6dcd229 338
71fda00f 339 LIST_PREPEND(mount_point, *head, m);
d48141ba
LP
340 }
341
1ca208fb 342 return 0;
d48141ba
LP
343}
344
0b220a5f
HK
345static int md_list_get(MountPoint **head) {
346 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
347 sd_device *d;
348 int r;
349
350 assert(head);
351
352 r = sd_device_enumerator_new(&e);
353 if (r < 0)
354 return r;
355
356 r = sd_device_enumerator_allow_uninitialized(e);
357 if (r < 0)
358 return r;
359
360 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
361 if (r < 0)
362 return r;
363
364 r = sd_device_enumerator_add_match_sysname(e, "md*");
365 if (r < 0)
366 return r;
367
3a3b022d
MT
368 /* Filter out partitions. */
369 r = sd_device_enumerator_add_match_property(e, "DEVTYPE", "disk");
370 if (r < 0)
371 return r;
372
0b220a5f
HK
373 FOREACH_DEVICE(e, d) {
374 _cleanup_free_ char *p = NULL;
3a3b022d 375 const char *dn, *md_level;
0b220a5f
HK
376 MountPoint *m;
377 dev_t devnum;
378
379 if (sd_device_get_devnum(d, &devnum) < 0 ||
380 sd_device_get_devname(d, &dn) < 0)
381 continue;
382
3a3b022d
MT
383 r = sd_device_get_property_value(d, "MD_LEVEL", &md_level);
384 if (r < 0) {
385 log_warning_errno(r, "Failed to get MD_LEVEL property for %s, ignoring: %m", dn);
386 continue;
387 }
388
83f3bf4b
LP
389 /* MD "containers" are a special type of MD devices, used for external metadata. Since it
390 * doesn't provide RAID functionality in itself we don't need to stop it. */
3a3b022d
MT
391 if (streq(md_level, "container"))
392 continue;
393
0b220a5f
HK
394 p = strdup(dn);
395 if (!p)
396 return -ENOMEM;
397
398 m = new(MountPoint, 1);
399 if (!m)
400 return -ENOMEM;
401
402 *m = (MountPoint) {
403 .path = TAKE_PTR(p),
404 .devnum = devnum,
405 };
406
407 LIST_PREPEND(mount_point, *head, m);
408 }
409
410 return 0;
411}
412
e3478379 413static int delete_loopback(const char *device) {
254d1313 414 _cleanup_close_ int fd = -EBADF;
b877c3b0 415 struct loop_info64 info;
e3478379 416
0494cae0
JJ
417 assert(device);
418
03e334a1 419 fd = open(device, O_RDONLY|O_CLOEXEC);
4534b32c
LP
420 if (fd < 0) {
421 log_debug_errno(errno, "Failed to open loopback device %s: %m", device);
c4f8bd1a 422 return errno == ENOENT ? 0 : -errno;
4534b32c
LP
423 }
424
425 /* Loopback block devices don't sync in-flight blocks when we clear the fd, hence sync explicitly
426 * first */
427 if (fsync(fd) < 0)
428 log_debug_errno(errno, "Failed to sync loop block device %s, ignoring: %m", device);
e3478379 429
b877c3b0
LP
430 if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
431 if (errno == ENXIO) /* Nothing bound, didn't do anything */
432 return 0;
433
4ca8072f
LP
434 if (errno != EBUSY)
435 return log_debug_errno(errno, "Failed to clear loopback device %s: %m", device);
436
437 if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {
438 if (errno == ENXIO) /* What? Suddenly detached after all? That's fine by us then. */
439 return 1;
440
441 log_debug_errno(errno, "Failed to invoke LOOP_GET_STATUS64 on loopback device %s, ignoring: %m", device);
442 return -EBUSY; /* propagate original error */
443 }
444
48f46254
LP
445#if HAVE_VALGRIND_MEMCHECK_H
446 VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
447#endif
448
4ca8072f
LP
449 if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) /* someone else already set LO_FLAGS_AUTOCLEAR for us? fine by us */
450 return -EBUSY; /* propagate original error */
451
452 info.lo_flags |= LO_FLAGS_AUTOCLEAR;
453 if (ioctl(fd, LOOP_SET_STATUS64, &info) < 0) {
454 if (errno == ENXIO) /* Suddenly detached after all? Fine by us */
455 return 1;
456
457 log_debug_errno(errno, "Failed to set LO_FLAGS_AUTOCLEAR flag for loop device %s, ignoring: %m", device);
458 } else
459 log_debug("Successfully set LO_FLAGS_AUTOCLEAR flag for loop device %s.", device);
460
461 return -EBUSY;
b877c3b0
LP
462 }
463
464 if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {
465 /* If the LOOP_CLR_FD above succeeded we'll see ENXIO here. */
466 if (errno == ENXIO)
467 log_debug("Successfully detached loopback device %s.", device);
468 else
469 log_debug_errno(errno, "Failed to invoke LOOP_GET_STATUS64 on loopback device %s, ignoring: %m", device); /* the LOOP_CLR_FD at least worked, let's hope for the best */
470
12aad1d0 471 return 1;
b877c3b0 472 }
12aad1d0 473
48f46254
LP
474#if HAVE_VALGRIND_MEMCHECK_H
475 VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
476#endif
477
b877c3b0
LP
478 /* Linux makes LOOP_CLR_FD succeed whenever LO_FLAGS_AUTOCLEAR is set without actually doing
479 * anything. Very confusing. Let's hence not claim we did anything in this case. */
480 if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR))
481 log_debug("Successfully called LOOP_CLR_FD on a loopback device %s with autoclear set, which is a NOP.", device);
482 else
483 log_debug("Weird, LOOP_CLR_FD succeeded but the device is still attached on %s.", device);
12aad1d0 484
b877c3b0 485 return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */
e3478379
FF
486}
487
e55299da 488static int delete_dm(MountPoint *m) {
254d1313 489 _cleanup_close_ int fd = -EBADF;
e55299da 490 int r;
cf139e60 491
e55299da
LP
492 assert(m);
493 assert(major(m->devnum) != 0);
494 assert(m->path);
d48141ba 495
e62d8c39
ZJS
496 fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
497 if (fd < 0)
d48141ba
LP
498 return -errno;
499
e55299da
LP
500 r = fsync_path_at(AT_FDCWD, m->path);
501 if (r < 0)
502 log_debug_errno(r, "Failed to sync DM block device %s, ignoring: %m", m->path);
503
7c248223 504 return RET_NERRNO(ioctl(fd, DM_DEV_REMOVE, &(struct dm_ioctl) {
e55299da
LP
505 .version = {
506 DM_VERSION_MAJOR,
507 DM_VERSION_MINOR,
508 DM_VERSION_PATCHLEVEL
509 },
510 .data_size = sizeof(struct dm_ioctl),
511 .dev = m->devnum,
7c248223 512 }));
d48141ba
LP
513}
514
0b220a5f 515static int delete_md(MountPoint *m) {
254d1313 516 _cleanup_close_ int fd = -EBADF;
0b220a5f 517
1a269c4e 518 assert(m);
0b220a5f 519 assert(major(m->devnum) != 0);
1a269c4e 520 assert(m->path);
0b220a5f
HK
521
522 fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL);
523 if (fd < 0)
524 return -errno;
525
32c4626c
LP
526 if (fsync(fd) < 0)
527 log_debug_errno(errno, "Failed to sync MD block device %s, ignoring: %m", m->path);
528
7c248223 529 return RET_NERRNO(ioctl(fd, STOP_ARRAY, NULL));
0b220a5f
HK
530}
531
c826cd3f
ZJS
532static bool nonunmountable_path(const char *path) {
533 return path_equal(path, "/")
349cc4a5 534#if ! HAVE_SPLIT_USR
c826cd3f
ZJS
535 || path_equal(path, "/usr")
536#endif
537 || path_startswith(path, "/run/initramfs");
538}
539
20596876 540static void log_umount_blockers(const char *mnt) {
05768ae3
LP
541 _cleanup_free_ char *blockers = NULL;
542 int r;
543
20596876
JJ
544 _cleanup_closedir_ DIR *dir = opendir("/proc");
545 if (!dir)
05768ae3 546 return (void) log_warning_errno(errno, "Failed to open /proc/: %m");
20596876
JJ
547
548 FOREACH_DIRENT_ALL(de, dir, break) {
549 if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
550 continue;
551
552 pid_t pid;
553 if (parse_pid(de->d_name, &pid) < 0)
554 continue;
555
05768ae3
LP
556 _cleanup_free_ char *fdp = path_join(de->d_name, "fd");
557 if (!fdp)
558 return (void) log_oom();
20596876 559
05768ae3
LP
560 _cleanup_closedir_ DIR *fd_dir = xopendirat(dirfd(dir), fdp, 0);
561 if (!fd_dir) {
562 if (errno != ENOENT) /* process gone by now? */
563 log_debug_errno(errno, "Failed to open /proc/%s/, ignoring: %m",fdp);
20596876 564 continue;
05768ae3 565 }
20596876 566
05768ae3 567 bool culprit = false;
20596876 568 FOREACH_DIRENT(fd_de, fd_dir, break) {
05768ae3 569 _cleanup_free_ char *open_file = NULL;
20596876 570
05768ae3
LP
571 r = readlinkat_malloc(dirfd(fd_dir), fd_de->d_name, &open_file);
572 if (r < 0) {
573 if (r != -ENOENT) /* fd closed by now */
574 log_debug_errno(r, "Failed to read link /proc/%s/%s, ignoring: %m", fdp, fd_de->d_name);
20596876 575 continue;
05768ae3 576 }
20596876 577
05768ae3
LP
578 if (path_startswith(open_file, mnt)) {
579 culprit = true;
580 break;
581 }
582 }
20596876 583
05768ae3
LP
584 if (!culprit)
585 continue;
20596876 586
05768ae3
LP
587 _cleanup_free_ char *comm = NULL;
588 r = get_process_comm(pid, &comm);
589 if (r < 0) {
590 if (r != -ESRCH) /* process gone by now */
591 log_debug_errno(r, "Failed to read process name of PID " PID_FMT ": %m", pid);
592 continue;
593 }
20596876 594
05768ae3
LP
595 if (!strextend_with_separator(&blockers, ", ", comm))
596 return (void) log_oom();
20596876 597
05768ae3
LP
598 if (!strextend(&blockers, "(", de->d_name, ")"))
599 return (void) log_oom();
20596876
JJ
600 }
601
602 if (blockers)
603 log_warning("Unmounting '%s' blocked by: %s", mnt, blockers);
604}
605
5125b677 606static int remount_with_timeout(MountPoint *m, bool last_try) {
b293bb23
LP
607 _cleanup_(close_pairp) int pfd[2] = PIPE_EBADF;
608 _cleanup_(sigkill_nowaitp) pid_t pid = 0;
d5641e0d
KW
609 int r;
610
611 BLOCK_SIGNALS(SIGCHLD);
612
0494cae0 613 assert(m);
0494cae0 614
b293bb23
LP
615 r = pipe2(pfd, O_CLOEXEC|O_NONBLOCK);
616 if (r < 0)
617 return r;
618
273d76f4
YW
619 /* Due to the possibility of a remount operation hanging, we fork a child process and set a
620 * timeout. If the timeout lapses, the assumption is that the particular remount failed. */
911f8f01
YW
621 r = safe_fork_full("(sd-remount)",
622 NULL,
623 pfd, ELEMENTSOF(pfd),
624 FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
4c253ed1 625 if (r < 0)
b6e1fff1 626 return r;
4c253ed1 627 if (r == 0) {
b293bb23
LP
628 pfd[0] = safe_close(pfd[0]);
629
b85c1905 630 log_info("Remounting '%s' read-only with options '%s'.", m->path, strempty(m->remount_options));
d5641e0d
KW
631
632 /* Start the mount operation here in the child */
3bc341be 633 r = mount(NULL, m->path, NULL, m->remount_flags, m->remount_options);
d5641e0d 634 if (r < 0)
5125b677
JJ
635 log_full_errno(last_try ? LOG_ERR : LOG_INFO,
636 errno,
637 "Failed to remount '%s' read-only: %m",
638 m->path);
d5641e0d 639
b293bb23 640 (void) write(pfd[1], &r, sizeof(r)); /* try to send errno up */
d5641e0d
KW
641 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
642 }
643
b293bb23
LP
644 pfd[1] = safe_close(pfd[1]);
645
d5641e0d 646 r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
b293bb23 647 if (r == -ETIMEDOUT)
00adeed9 648 log_error_errno(r, "Remounting '%s' timed out, issuing SIGKILL to PID " PID_FMT ".", m->path, pid);
b293bb23
LP
649 else if (r == -EPROTO) {
650 /* Try to read error code from child */
651 if (read(pfd[0], &r, sizeof(r)) == sizeof(r))
652 log_debug_errno(r, "Remounting '%s' failed abnormally, child process " PID_FMT " failed: %m", m->path, pid);
653 else
5afaf407 654 r = log_debug_errno(EPROTO, "Remounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", m->path, pid);
b293bb23
LP
655 TAKE_PID(pid); /* child exited (just not as we expected) hence don't kill anymore */
656 } else if (r < 0)
00adeed9 657 log_error_errno(r, "Remounting '%s' failed unexpectedly, couldn't wait for child process " PID_FMT ": %m", m->path, pid);
d5641e0d
KW
658
659 return r;
660}
661
5125b677 662static int umount_with_timeout(MountPoint *m, bool last_try) {
b293bb23
LP
663 _cleanup_(close_pairp) int pfd[2] = PIPE_EBADF;
664 _cleanup_(sigkill_nowaitp) pid_t pid = 0;
d5641e0d
KW
665 int r;
666
667 BLOCK_SIGNALS(SIGCHLD);
668
0494cae0
JJ
669 assert(m);
670
b293bb23
LP
671 r = pipe2(pfd, O_CLOEXEC|O_NONBLOCK);
672 if (r < 0)
673 return r;
674
273d76f4
YW
675 /* Due to the possibility of a umount operation hanging, we fork a child process and set a
676 * timeout. If the timeout lapses, the assumption is that the particular umount failed. */
911f8f01
YW
677 r = safe_fork_full("(sd-umount)",
678 NULL,
679 pfd, ELEMENTSOF(pfd),
680 FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
4c253ed1 681 if (r < 0)
b6e1fff1 682 return r;
4c253ed1 683 if (r == 0) {
b293bb23
LP
684 pfd[0] = safe_close(pfd[0]);
685
d5641e0d
KW
686 log_info("Unmounting '%s'.", m->path);
687
83f3bf4b
LP
688 /* Start the mount operation here in the child Using MNT_FORCE causes some filesystems
689 * (e.g. FUSE and NFS and other network filesystems) to abort any pending requests and return
690 * -EIO rather than blocking indefinitely. If the filesysten is "busy", this may allow
691 * processes to die, thus making the filesystem less busy so the unmount might succeed
692 * (rather than return EBUSY). */
f11efcbe
LP
693 r = RET_NERRNO(umount2(m->path,
694 UMOUNT_NOFOLLOW | /* Don't follow symlinks: this should never happen unless our mount list was wrong */
695 (m->umount_lazily ? MNT_DETACH : MNT_FORCE)));
20596876
JJ
696 if (r < 0) {
697 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Failed to unmount %s: %m", m->path);
698
699 if (r == -EBUSY && last_try)
700 log_umount_blockers(m->path);
701 }
d5641e0d 702
b293bb23 703 (void) write(pfd[1], &r, sizeof(r)); /* try to send errno up */
d5641e0d
KW
704 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
705 }
706
b293bb23
LP
707 pfd[1] = safe_close(pfd[1]);
708
d5641e0d 709 r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
b293bb23 710 if (r == -ETIMEDOUT)
00adeed9 711 log_error_errno(r, "Unmounting '%s' timed out, issuing SIGKILL to PID " PID_FMT ".", m->path, pid);
b293bb23
LP
712 else if (r == -EPROTO) {
713 /* Try to read error code from child */
714 if (read(pfd[0], &r, sizeof(r)) == sizeof(r))
715 log_debug_errno(r, "Unmounting '%s' failed abnormally, child process " PID_FMT " failed: %m", m->path, pid);
716 else
717 r = log_debug_errno(EPROTO, "Unmounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", m->path, pid);
718 TAKE_PID(pid); /* It died, but abnormally, no purpose in killing */
719 } else if (r < 0)
00adeed9 720 log_error_errno(r, "Unmounting '%s' failed unexpectedly, couldn't wait for child process " PID_FMT ": %m", m->path, pid);
d5641e0d
KW
721
722 return r;
723}
724
49f80dce
LP
725/* This includes remounting readonly, which changes the kernel mount options. Therefore the list passed to
726 * this function is invalidated, and should not be reused. */
5125b677 727static int mount_points_list_umount(MountPoint **head, bool *changed, bool last_try) {
6dc68a00
VD
728 int n_failed = 0, r;
729 _cleanup_free_ char *resolved_mounts_path = NULL;
e3478379 730
12aad1d0 731 assert(head);
0494cae0 732 assert(changed);
12aad1d0 733
116e6d96 734 LIST_FOREACH(mount_point, m, *head) {
1d62d22d 735 if (m->try_remount_ro) {
49f80dce 736 /* We always try to remount directories read-only first, before we go on and umount
93bd1577
LP
737 * them.
738 *
49f80dce
LP
739 * Mount points can be stacked. If a mount point is stacked below / or /usr, we
740 * cannot umount or remount it directly, since there is no way to refer to the
741 * underlying mount. There's nothing we can do about it for the general case, but we
742 * can do something about it if it is aliased somewhere else via a bind mount. If we
743 * explicitly remount the super block of that alias read-only we hence should be
744 * relatively safe regarding keeping a dirty fs we cannot otherwise see.
d5641e0d 745 *
49f80dce
LP
746 * Since the remount can hang in the instance of remote filesystems, we remount
747 * asynchronously and skip the subsequent umount if it fails. */
5125b677 748 if (remount_with_timeout(m, last_try) < 0) {
8645ffd1
JJ
749 /* Remount failed, but try unmounting anyway,
750 * unless this is a mount point we want to skip. */
751 if (nonunmountable_path(m->path)) {
c826cd3f 752 n_failed++;
8645ffd1
JJ
753 continue;
754 }
c826cd3f 755 }
93bd1577
LP
756 }
757
49f80dce
LP
758 /* Skip / and /usr since we cannot unmount that anyway, since we are running from it. They
759 * have already been remounted ro. */
c826cd3f 760 if (nonunmountable_path(m->path))
e3478379
FF
761 continue;
762
d5641e0d 763 /* Trying to umount */
6dc68a00
VD
764 r = umount_with_timeout(m, last_try);
765 if (r < 0)
d5641e0d 766 n_failed++;
0494cae0
JJ
767 else
768 *changed = true;
6dc68a00
VD
769
770 /* If a mount is busy, we move it to not keep parent mount points busy.
771 * If a mount point is not a leaf, moving it would invalidate our mount table.
772 * More moving will occur in next iteration with a fresh mount table.
773 */
774 if (r != -EBUSY || !m->leaf)
775 continue;
776
777 _cleanup_free_ char *dirname = NULL;
778
779 r = path_extract_directory(m->path, &dirname);
780 if (r < 0) {
781 n_failed++;
782 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Cannot find directory for %s: %m", m->path);
783 continue;
784 }
785
786 /* We need to canonicalize /run/shutdown/mounts. We cannot compare inodes, since /run
787 * might be bind mounted somewhere we want to unmount. And we need to move all mounts in
788 * /run/shutdown/mounts from there.
789 */
790 if (!resolved_mounts_path)
791 (void) chase_symlinks("/run/shutdown/mounts", NULL, 0, &resolved_mounts_path, NULL);
792 if (!path_equal(dirname, resolved_mounts_path)) {
793 char newpath[STRLEN("/run/shutdown/mounts/") + 16 + 1];
794
795 xsprintf(newpath, "/run/shutdown/mounts/%016" PRIx64, random_u64());
796
797 /* on error of is_dir, assume directory */
798 if (is_dir(m->path, true) != 0) {
799 r = mkdir_p(newpath, 0000);
800 if (r < 0) {
801 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not create directory %s: %m", newpath);
802 continue;
803 }
804 } else {
805 r = touch_file(newpath, /* parents= */ true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0700);
806 if (r < 0) {
807 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not create file %s: %m", newpath);
808 continue;
809 }
810 }
811
812 log_info("Moving mount %s to %s.", m->path, newpath);
813
814 r = RET_NERRNO(mount(m->path, newpath, NULL, MS_MOVE, NULL));
815 if (r < 0) {
816 n_failed++;
817 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not move %s to %s: %m", m->path, newpath);
818 } else
819 *changed = true;
820 }
e3478379
FF
821 }
822
12aad1d0 823 return n_failed;
e3478379
FF
824}
825
12aad1d0 826static int swap_points_list_off(MountPoint **head, bool *changed) {
12aad1d0
LP
827 int n_failed = 0;
828
829 assert(head);
0494cae0 830 assert(changed);
e3478379 831
80a226b2 832 LIST_FOREACH(mount_point, m, *head) {
735e0712 833 log_info("Deactivating swap %s.", m->path);
88287615 834 if (swapoff(m->path) < 0) {
56f64d95 835 log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
12aad1d0 836 n_failed++;
88287615 837 continue;
e3478379 838 }
88287615
LP
839
840 *changed = true;
841 mount_point_free(head, m);
e3478379
FF
842 }
843
12aad1d0 844 return n_failed;
e3478379
FF
845}
846
5125b677 847static int loopback_points_list_detach(MountPoint **head, bool *changed, bool last_try) {
63135a2d
LP
848 int n_failed = 0, r;
849 dev_t rootdev = 0;
12aad1d0
LP
850
851 assert(head);
0494cae0 852 assert(changed);
12aad1d0 853
63135a2d 854 (void) get_block_device("/", &rootdev);
7fc942b2 855
80a226b2 856 LIST_FOREACH(mount_point, m, *head) {
63135a2d 857 if (major(rootdev) != 0 && rootdev == m->devnum) {
313cefa1 858 n_failed++;
7fc942b2
LP
859 continue;
860 }
e3478379 861
735e0712 862 log_info("Detaching loopback %s.", m->path);
bce93b7a 863 r = delete_loopback(m->path);
88287615 864 if (r < 0) {
5125b677 865 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not detach loopback %s: %m", m->path);
12aad1d0 866 n_failed++;
88287615 867 continue;
e3478379 868 }
88287615
LP
869 if (r > 0)
870 *changed = true;
871
872 mount_point_free(head, m);
e3478379
FF
873 }
874
12aad1d0 875 return n_failed;
e3478379
FF
876}
877
5125b677 878static int dm_points_list_detach(MountPoint **head, bool *changed, bool last_try) {
33e8d8af 879 int n_failed = 0, r;
63135a2d 880 dev_t rootdev = 0;
12aad1d0
LP
881
882 assert(head);
0494cae0 883 assert(changed);
12aad1d0 884
63135a2d 885 (void) get_block_device("/", &rootdev);
7fc942b2 886
80a226b2 887 LIST_FOREACH(mount_point, m, *head) {
0494cae0
JJ
888 if (major(rootdev) != 0 && rootdev == m->devnum) {
889 n_failed ++;
890 continue;
891 }
7fc942b2 892
88287615 893 log_info("Detaching DM %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum));
e55299da 894 r = delete_dm(m);
88287615 895 if (r < 0) {
5125b677 896 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not detach DM %s: %m", m->path);
12aad1d0 897 n_failed++;
88287615 898 continue;
d48141ba 899 }
88287615
LP
900
901 *changed = true;
902 mount_point_free(head, m);
d48141ba
LP
903 }
904
12aad1d0 905 return n_failed;
d48141ba
LP
906}
907
5125b677 908static int md_points_list_detach(MountPoint **head, bool *changed, bool last_try) {
0b220a5f
HK
909 int n_failed = 0, r;
910 dev_t rootdev = 0;
911
912 assert(head);
913 assert(changed);
914
915 (void) get_block_device("/", &rootdev);
916
80a226b2 917 LIST_FOREACH(mount_point, m, *head) {
0b220a5f
HK
918 if (major(rootdev) != 0 && rootdev == m->devnum) {
919 n_failed ++;
920 continue;
921 }
922
923 log_info("Stopping MD %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum));
924 r = delete_md(m);
925 if (r < 0) {
5125b677 926 log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not stop MD %s: %m", m->path);
0b220a5f
HK
927 n_failed++;
928 continue;
929 }
930
931 *changed = true;
932 mount_point_free(head, m);
933 }
934
935 return n_failed;
936}
937
5125b677 938static int umount_all_once(bool *changed, bool last_try) {
a6dcd229 939 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head);
88287615 940 int r;
e3478379 941
0494cae0
JJ
942 assert(changed);
943
71fda00f 944 LIST_HEAD_INIT(mp_list_head);
6fa392bf 945 r = mount_points_list_get(NULL, &mp_list_head);
e3478379 946 if (r < 0)
a6dcd229 947 return r;
116e6d96 948
5125b677 949 return mount_points_list_umount(&mp_list_head, changed, last_try);
116e6d96
AJ
950}
951
5125b677 952int umount_all(bool *changed, bool last_try) {
116e6d96
AJ
953 bool umount_changed;
954 int r;
955
0494cae0
JJ
956 assert(changed);
957
83f3bf4b
LP
958 /* Retry umount, until nothing can be umounted anymore. Mounts are processed in order, newest
959 * first. The retries are needed when an old mount has been moved, to a path inside a newer mount. */
6f7f51f7
HH
960 do {
961 umount_changed = false;
3e085b6c 962
5125b677 963 r = umount_all_once(&umount_changed, last_try);
6f7f51f7
HH
964 if (umount_changed)
965 *changed = true;
3e085b6c
LP
966 } while (umount_changed);
967
e3478379
FF
968 return r;
969}
970
12aad1d0 971int swapoff_all(bool *changed) {
a6dcd229 972 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, swap_list_head);
e3478379 973 int r;
e3478379 974
0494cae0
JJ
975 assert(changed);
976
71fda00f 977 LIST_HEAD_INIT(swap_list_head);
e3478379 978
1fd8edb5 979 r = swap_list_get(NULL, &swap_list_head);
e3478379 980 if (r < 0)
a6dcd229 981 return r;
e3478379 982
a6dcd229 983 return swap_points_list_off(&swap_list_head, changed);
e3478379
FF
984}
985
5125b677 986int loopback_detach_all(bool *changed, bool last_try) {
a6dcd229 987 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, loopback_list_head);
e3478379 988 int r;
e3478379 989
0494cae0
JJ
990 assert(changed);
991
71fda00f 992 LIST_HEAD_INIT(loopback_list_head);
e3478379
FF
993
994 r = loopback_list_get(&loopback_list_head);
995 if (r < 0)
a6dcd229 996 return r;
e3478379 997
5125b677 998 return loopback_points_list_detach(&loopback_list_head, changed, last_try);
e3478379 999}
d48141ba 1000
5125b677 1001int dm_detach_all(bool *changed, bool last_try) {
a6dcd229 1002 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, dm_list_head);
d48141ba 1003 int r;
d48141ba 1004
0494cae0
JJ
1005 assert(changed);
1006
71fda00f 1007 LIST_HEAD_INIT(dm_list_head);
d48141ba
LP
1008
1009 r = dm_list_get(&dm_list_head);
1010 if (r < 0)
a6dcd229 1011 return r;
d48141ba 1012
5125b677 1013 return dm_points_list_detach(&dm_list_head, changed, last_try);
d48141ba 1014}
0b220a5f 1015
5125b677 1016int md_detach_all(bool *changed, bool last_try) {
0b220a5f
HK
1017 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, md_list_head);
1018 int r;
1019
1020 assert(changed);
1021
1022 LIST_HEAD_INIT(md_list_head);
1023
1024 r = md_list_get(&md_list_head);
1025 if (r < 0)
1026 return r;
1027
5125b677 1028 return md_points_list_detach(&md_list_head, changed, last_try);
0b220a5f 1029}