]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shutdown/umount.c
Merge pull request #22791 from keszybz/bootctl-invert-order
[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"
d5641e0d 26#include "def.h"
8437c059 27#include "device-util.h"
07630cea 28#include "escape.h"
3ffd4af2 29#include "fd-util.h"
471b48ed 30#include "fstab-util.h"
fb36b133 31#include "libmount-util.h"
e3478379 32#include "mount-setup.h"
18c528e9 33#include "mount-util.h"
049af8ad 34#include "mountpoint-util.h"
9eb977db 35#include "path-util.h"
dccca82b 36#include "process-util.h"
d5641e0d 37#include "signal-util.h"
07630cea 38#include "string-util.h"
da9fc98d 39#include "strv.h"
bf819d3a 40#include "sync-util.h"
3ffd4af2 41#include "umount.h"
e3478379 42#include "util.h"
024f268d 43#include "virt.h"
e3478379 44
12aad1d0
LP
45static void mount_point_free(MountPoint **head, MountPoint *m) {
46 assert(head);
47 assert(m);
e3478379 48
71fda00f 49 LIST_REMOVE(mount_point, *head, m);
12aad1d0
LP
50
51 free(m->path);
3bc341be 52 free(m->remount_options);
12aad1d0 53 free(m);
e3478379
FF
54}
55
6fa392bf 56void mount_points_list_free(MountPoint **head) {
12aad1d0
LP
57 assert(head);
58
59 while (*head)
60 mount_point_free(head, *head);
e3478379
FF
61}
62
6fa392bf 63int mount_points_list_get(const char *mountinfo, MountPoint **head) {
13dcfe46
ZJS
64 _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
65 _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
527b7a42 66 int r;
e3478379 67
12aad1d0
LP
68 assert(head);
69
e2857b3d 70 r = libmount_parse(mountinfo, NULL, &table, &iter);
95b862b0 71 if (r < 0)
f795267e 72 return log_error_errno(r, "Failed to parse %s: %m", mountinfo ?: "/proc/self/mountinfo");
95b862b0
ZJS
73
74 for (;;) {
75 struct libmnt_fs *fs;
66c91c3a 76 const char *path, *fstype;
77 _cleanup_free_ char *options = NULL;
95b862b0
ZJS
78 unsigned long remount_flags = 0u;
79 _cleanup_free_ char *remount_options = NULL;
80 bool try_remount_ro;
9d1b2b22 81 _cleanup_free_ MountPoint *m = NULL;
e3478379 82
13dcfe46 83 r = mnt_table_next_fs(table, iter, &fs);
95b862b0
ZJS
84 if (r == 1)
85 break;
527b7a42 86 if (r < 0)
f795267e 87 return log_error_errno(r, "Failed to get next entry from %s: %m", mountinfo ?: "/proc/self/mountinfo");
95b862b0
ZJS
88
89 path = mnt_fs_get_target(fs);
90 if (!path)
91 continue;
92
95b862b0 93 fstype = mnt_fs_get_fstype(fs);
e3478379 94
66c91c3a 95 /* Combine the generic VFS options with the FS-specific
96 * options. Duplicates are not a problem here, because the only
97 * options that should come up twice are typically ro/rw, which
9d1b2b22 98 * are turned into MS_RDONLY or the inversion of it.
66c91c3a 99 *
100 * Even if there are duplicates later in mount_option_mangle()
9d1b2b22 101 * they shouldn't hurt anyways as they override each other.
66c91c3a 102 */
c2bc710b 103 if (!strextend_with_separator(&options, ",", mnt_fs_get_vfs_options(fs)))
66c91c3a 104 return log_oom();
c2bc710b 105 if (!strextend_with_separator(&options, ",", mnt_fs_get_fs_options(fs)))
66c91c3a 106 return log_oom();
107
46108b3b
LP
108 /* Ignore mount points we can't unmount because they
109 * are API or because we are keeping them open (like
874d3404
LP
110 * /dev/console). Also, ignore all mounts below API
111 * file systems, since they are likely virtual too,
112 * and hence not worth spending time on. Also, in
113 * unprivileged containers we might lack the rights to
114 * unmount these things, hence don't bother. */
9d1b2b22
ZJS
115 if (mount_point_is_api(path) ||
116 mount_point_ignore(path) ||
117 PATH_STARTSWITH_SET(path, "/dev", "/sys", "/proc"))
2054a5b8 118 continue;
2054a5b8 119
1d62d22d
JJ
120 /* If we are in a container, don't attempt to
121 * read-only mount anything as that brings no real
122 * benefits, but might confuse the host, as we remount
123 * the superblock here, not the bind mount.
124 *
125 * If the filesystem is a network fs, also skip the
126 * remount. It brings no value (we cannot leave
127 * a "dirty fs") and could hang if the network is down.
128 * Note that umount2() is more careful and will not
129 * hang because of the network being down. */
95b862b0
ZJS
130 try_remount_ro = detect_container() <= 0 &&
131 !fstype_is_network(fstype) &&
132 !fstype_is_api_vfs(fstype) &&
133 !fstype_is_ro(fstype) &&
134 !fstab_test_yes_no_option(options, "ro\0rw\0");
3bc341be 135
95b862b0 136 if (try_remount_ro) {
3bc341be
JJ
137 /* mount(2) states that mount flags and options need to be exactly the same
138 * as they were when the filesystem was mounted, except for the desired
139 * changes. So we reconstruct both here and adjust them for the later
140 * remount call too. */
141
95b862b0
ZJS
142 r = mnt_fs_get_propagation(fs, &remount_flags);
143 if (r < 0) {
144 log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path);
145 continue;
146 }
3bc341be 147
95b862b0
ZJS
148 r = mount_option_mangle(options, remount_flags, &remount_flags, &remount_options);
149 if (r < 0) {
150 log_warning_errno(r, "mount_option_mangle failed for %s, ignoring: %m", path);
151 continue;
152 }
3bc341be
JJ
153
154 /* MS_BIND is special. If it is provided it will only make the mount-point
155 * read-only. If left out, the super block itself is remounted, which we want. */
95b862b0 156 remount_flags = (remount_flags|MS_REMOUNT|MS_RDONLY) & ~MS_BIND;
3bc341be 157 }
471b48ed 158
95b862b0
ZJS
159 m = new0(MountPoint, 1);
160 if (!m)
161 return log_oom();
162
9d1b2b22
ZJS
163 m->path = strdup(path);
164 if (!m->path)
165 return log_oom();
166
167 m->remount_options = TAKE_PTR(remount_options);
95b862b0
ZJS
168 m->remount_flags = remount_flags;
169 m->try_remount_ro = try_remount_ro;
170
9d1b2b22 171 LIST_PREPEND(mount_point, *head, TAKE_PTR(m));
e3478379
FF
172 }
173
c3544e8d 174 return 0;
e3478379
FF
175}
176
1fd8edb5 177int swap_list_get(const char *swaps, MountPoint **head) {
71ae04c4
ZJS
178 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
179 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
527b7a42 180 int r;
e3478379 181
12aad1d0
LP
182 assert(head);
183
71ae04c4
ZJS
184 t = mnt_new_table();
185 i = mnt_new_iter(MNT_ITER_FORWARD);
186 if (!t || !i)
187 return log_oom();
e3478379 188
71ae04c4 189 r = mnt_table_parse_swaps(t, swaps);
2cdd0d61
LP
190 if (r == -ENOENT) /* no /proc/swaps is fine */
191 return 0;
71ae04c4 192 if (r < 0)
f795267e 193 return log_error_errno(r, "Failed to parse %s: %m", swaps ?: "/proc/swaps");
71ae04c4
ZJS
194
195 for (;;) {
196 struct libmnt_fs *fs;
9d1b2b22 197 _cleanup_free_ MountPoint *swap = NULL;
71ae04c4 198 const char *source;
71ae04c4
ZJS
199
200 r = mnt_table_next_fs(t, i, &fs);
201 if (r == 1)
202 break;
203 if (r < 0)
f795267e 204 return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps");
e3478379 205
71ae04c4
ZJS
206 source = mnt_fs_get_source(fs);
207 if (!source)
e3478379 208 continue;
e3478379 209
527b7a42 210 swap = new0(MountPoint, 1);
595c66a3 211 if (!swap)
4e201419 212 return log_oom();
e3478379 213
9d1b2b22
ZJS
214 swap->path = strdup(source);
215 if (!swap->path)
4e201419 216 return log_oom();
9d1b2b22
ZJS
217
218 LIST_PREPEND(mount_point, *head, TAKE_PTR(swap));
e3478379
FF
219 }
220
e1d75803 221 return 0;
e3478379
FF
222}
223
12aad1d0 224static int loopback_list_get(MountPoint **head) {
6bcf00ed
YW
225 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
226 sd_device *d;
06acf2d4 227 int r;
e3478379 228
12aad1d0
LP
229 assert(head);
230
6bcf00ed
YW
231 r = sd_device_enumerator_new(&e);
232 if (r < 0)
233 return r;
e3478379 234
6bcf00ed
YW
235 r = sd_device_enumerator_allow_uninitialized(e);
236 if (r < 0)
237 return r;
e3478379 238
6bcf00ed 239 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
06acf2d4
LP
240 if (r < 0)
241 return r;
242
6bcf00ed 243 r = sd_device_enumerator_add_match_sysname(e, "loop*");
06acf2d4
LP
244 if (r < 0)
245 return r;
246
6bcf00ed 247 r = sd_device_enumerator_add_match_sysattr(e, "loop/backing_file", NULL, true);
06acf2d4
LP
248 if (r < 0)
249 return r;
e3478379 250
8437c059 251 FOREACH_DEVICE(e, d) {
209c6f03 252 _cleanup_free_ char *p = NULL;
6bcf00ed 253 const char *dn;
209c6f03 254 MountPoint *lb;
63135a2d 255 dev_t devnum;
e3478379 256
63135a2d
LP
257 if (sd_device_get_devnum(d, &devnum) < 0 ||
258 sd_device_get_devname(d, &dn) < 0)
2d9a3397 259 continue;
b854a7e7 260
209c6f03
YW
261 p = strdup(dn);
262 if (!p)
263 return -ENOMEM;
264
265 lb = new(MountPoint, 1);
a6dcd229 266 if (!lb)
1ca208fb 267 return -ENOMEM;
e3478379 268
209c6f03
YW
269 *lb = (MountPoint) {
270 .path = TAKE_PTR(p),
63135a2d 271 .devnum = devnum,
209c6f03 272 };
a6dcd229 273
71fda00f 274 LIST_PREPEND(mount_point, *head, lb);
e3478379
FF
275 }
276
1ca208fb 277 return 0;
e3478379
FF
278}
279
12aad1d0 280static int dm_list_get(MountPoint **head) {
6bcf00ed
YW
281 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
282 sd_device *d;
06acf2d4 283 int r;
d48141ba 284
12aad1d0
LP
285 assert(head);
286
6bcf00ed
YW
287 r = sd_device_enumerator_new(&e);
288 if (r < 0)
289 return r;
d48141ba 290
6bcf00ed
YW
291 r = sd_device_enumerator_allow_uninitialized(e);
292 if (r < 0)
293 return r;
d48141ba 294
6bcf00ed 295 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
06acf2d4
LP
296 if (r < 0)
297 return r;
d48141ba 298
6bcf00ed 299 r = sd_device_enumerator_add_match_sysname(e, "dm-*");
06acf2d4
LP
300 if (r < 0)
301 return r;
d48141ba 302
8437c059 303 FOREACH_DEVICE(e, d) {
209c6f03 304 _cleanup_free_ char *p = NULL;
6bcf00ed 305 const char *dn;
209c6f03 306 MountPoint *m;
6bcf00ed 307 dev_t devnum;
d48141ba 308
209c6f03
YW
309 if (sd_device_get_devnum(d, &devnum) < 0 ||
310 sd_device_get_devname(d, &dn) < 0)
6bcf00ed 311 continue;
d48141ba 312
209c6f03
YW
313 p = strdup(dn);
314 if (!p)
315 return -ENOMEM;
d48141ba 316
209c6f03 317 m = new(MountPoint, 1);
a6dcd229 318 if (!m)
1ca208fb 319 return -ENOMEM;
d48141ba 320
209c6f03
YW
321 *m = (MountPoint) {
322 .path = TAKE_PTR(p),
323 .devnum = devnum,
324 };
a6dcd229 325
71fda00f 326 LIST_PREPEND(mount_point, *head, m);
d48141ba
LP
327 }
328
1ca208fb 329 return 0;
d48141ba
LP
330}
331
0b220a5f
HK
332static int md_list_get(MountPoint **head) {
333 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
334 sd_device *d;
335 int r;
336
337 assert(head);
338
339 r = sd_device_enumerator_new(&e);
340 if (r < 0)
341 return r;
342
343 r = sd_device_enumerator_allow_uninitialized(e);
344 if (r < 0)
345 return r;
346
347 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
348 if (r < 0)
349 return r;
350
351 r = sd_device_enumerator_add_match_sysname(e, "md*");
352 if (r < 0)
353 return r;
354
355 FOREACH_DEVICE(e, d) {
356 _cleanup_free_ char *p = NULL;
357 const char *dn;
358 MountPoint *m;
359 dev_t devnum;
360
361 if (sd_device_get_devnum(d, &devnum) < 0 ||
362 sd_device_get_devname(d, &dn) < 0)
363 continue;
364
365 p = strdup(dn);
366 if (!p)
367 return -ENOMEM;
368
369 m = new(MountPoint, 1);
370 if (!m)
371 return -ENOMEM;
372
373 *m = (MountPoint) {
374 .path = TAKE_PTR(p),
375 .devnum = devnum,
376 };
377
378 LIST_PREPEND(mount_point, *head, m);
379 }
380
381 return 0;
382}
383
e3478379 384static int delete_loopback(const char *device) {
03e334a1 385 _cleanup_close_ int fd = -1;
b877c3b0 386 struct loop_info64 info;
e3478379 387
0494cae0
JJ
388 assert(device);
389
03e334a1 390 fd = open(device, O_RDONLY|O_CLOEXEC);
4534b32c
LP
391 if (fd < 0) {
392 log_debug_errno(errno, "Failed to open loopback device %s: %m", device);
c4f8bd1a 393 return errno == ENOENT ? 0 : -errno;
4534b32c
LP
394 }
395
396 /* Loopback block devices don't sync in-flight blocks when we clear the fd, hence sync explicitly
397 * first */
398 if (fsync(fd) < 0)
399 log_debug_errno(errno, "Failed to sync loop block device %s, ignoring: %m", device);
e3478379 400
b877c3b0
LP
401 if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
402 if (errno == ENXIO) /* Nothing bound, didn't do anything */
403 return 0;
404
4ca8072f
LP
405 if (errno != EBUSY)
406 return log_debug_errno(errno, "Failed to clear loopback device %s: %m", device);
407
408 if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {
409 if (errno == ENXIO) /* What? Suddenly detached after all? That's fine by us then. */
410 return 1;
411
412 log_debug_errno(errno, "Failed to invoke LOOP_GET_STATUS64 on loopback device %s, ignoring: %m", device);
413 return -EBUSY; /* propagate original error */
414 }
415
48f46254
LP
416#if HAVE_VALGRIND_MEMCHECK_H
417 VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
418#endif
419
4ca8072f
LP
420 if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) /* someone else already set LO_FLAGS_AUTOCLEAR for us? fine by us */
421 return -EBUSY; /* propagate original error */
422
423 info.lo_flags |= LO_FLAGS_AUTOCLEAR;
424 if (ioctl(fd, LOOP_SET_STATUS64, &info) < 0) {
425 if (errno == ENXIO) /* Suddenly detached after all? Fine by us */
426 return 1;
427
428 log_debug_errno(errno, "Failed to set LO_FLAGS_AUTOCLEAR flag for loop device %s, ignoring: %m", device);
429 } else
430 log_debug("Successfully set LO_FLAGS_AUTOCLEAR flag for loop device %s.", device);
431
432 return -EBUSY;
b877c3b0
LP
433 }
434
435 if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) {
436 /* If the LOOP_CLR_FD above succeeded we'll see ENXIO here. */
437 if (errno == ENXIO)
438 log_debug("Successfully detached loopback device %s.", device);
439 else
440 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 */
441
12aad1d0 442 return 1;
b877c3b0 443 }
12aad1d0 444
48f46254
LP
445#if HAVE_VALGRIND_MEMCHECK_H
446 VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
447#endif
448
b877c3b0
LP
449 /* Linux makes LOOP_CLR_FD succeed whenever LO_FLAGS_AUTOCLEAR is set without actually doing
450 * anything. Very confusing. Let's hence not claim we did anything in this case. */
451 if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR))
452 log_debug("Successfully called LOOP_CLR_FD on a loopback device %s with autoclear set, which is a NOP.", device);
453 else
454 log_debug("Weird, LOOP_CLR_FD succeeded but the device is still attached on %s.", device);
12aad1d0 455
b877c3b0 456 return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */
e3478379
FF
457}
458
e55299da 459static int delete_dm(MountPoint *m) {
cf139e60 460 _cleanup_close_ int fd = -1;
e55299da 461 int r;
cf139e60 462
e55299da
LP
463 assert(m);
464 assert(major(m->devnum) != 0);
465 assert(m->path);
d48141ba 466
e62d8c39
ZJS
467 fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
468 if (fd < 0)
d48141ba
LP
469 return -errno;
470
e55299da
LP
471 r = fsync_path_at(AT_FDCWD, m->path);
472 if (r < 0)
473 log_debug_errno(r, "Failed to sync DM block device %s, ignoring: %m", m->path);
474
7c248223 475 return RET_NERRNO(ioctl(fd, DM_DEV_REMOVE, &(struct dm_ioctl) {
e55299da
LP
476 .version = {
477 DM_VERSION_MAJOR,
478 DM_VERSION_MINOR,
479 DM_VERSION_PATCHLEVEL
480 },
481 .data_size = sizeof(struct dm_ioctl),
482 .dev = m->devnum,
7c248223 483 }));
d48141ba
LP
484}
485
0b220a5f 486static int delete_md(MountPoint *m) {
0b220a5f
HK
487 _cleanup_close_ int fd = -1;
488
1a269c4e 489 assert(m);
0b220a5f 490 assert(major(m->devnum) != 0);
1a269c4e 491 assert(m->path);
0b220a5f
HK
492
493 fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL);
494 if (fd < 0)
495 return -errno;
496
32c4626c
LP
497 if (fsync(fd) < 0)
498 log_debug_errno(errno, "Failed to sync MD block device %s, ignoring: %m", m->path);
499
7c248223 500 return RET_NERRNO(ioctl(fd, STOP_ARRAY, NULL));
0b220a5f
HK
501}
502
c826cd3f
ZJS
503static bool nonunmountable_path(const char *path) {
504 return path_equal(path, "/")
349cc4a5 505#if ! HAVE_SPLIT_USR
c826cd3f
ZJS
506 || path_equal(path, "/usr")
507#endif
508 || path_startswith(path, "/run/initramfs");
509}
510
456b2199 511static int remount_with_timeout(MountPoint *m, int umount_log_level) {
d5641e0d
KW
512 pid_t pid;
513 int r;
514
515 BLOCK_SIGNALS(SIGCHLD);
516
0494cae0 517 assert(m);
0494cae0 518
273d76f4
YW
519 /* Due to the possibility of a remount operation hanging, we fork a child process and set a
520 * timeout. If the timeout lapses, the assumption is that the particular remount failed. */
0b1f3c76 521 r = safe_fork("(sd-remount)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
4c253ed1 522 if (r < 0)
b6e1fff1 523 return r;
4c253ed1 524 if (r == 0) {
b85c1905 525 log_info("Remounting '%s' read-only with options '%s'.", m->path, strempty(m->remount_options));
d5641e0d
KW
526
527 /* Start the mount operation here in the child */
3bc341be 528 r = mount(NULL, m->path, NULL, m->remount_flags, m->remount_options);
d5641e0d 529 if (r < 0)
456b2199 530 log_full_errno(umount_log_level, errno, "Failed to remount '%s' read-only: %m", m->path);
d5641e0d
KW
531
532 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
533 }
534
535 r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
536 if (r == -ETIMEDOUT) {
00adeed9 537 log_error_errno(r, "Remounting '%s' timed out, issuing SIGKILL to PID " PID_FMT ".", m->path, pid);
d5641e0d 538 (void) kill(pid, SIGKILL);
00adeed9 539 } else if (r == -EPROTO)
456b2199 540 log_debug_errno(r, "Remounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", m->path, pid);
00adeed9
LP
541 else if (r < 0)
542 log_error_errno(r, "Remounting '%s' failed unexpectedly, couldn't wait for child process " PID_FMT ": %m", m->path, pid);
d5641e0d
KW
543
544 return r;
545}
546
456b2199 547static int umount_with_timeout(MountPoint *m, int umount_log_level) {
d5641e0d
KW
548 pid_t pid;
549 int r;
550
551 BLOCK_SIGNALS(SIGCHLD);
552
0494cae0
JJ
553 assert(m);
554
273d76f4
YW
555 /* Due to the possibility of a umount operation hanging, we fork a child process and set a
556 * timeout. If the timeout lapses, the assumption is that the particular umount failed. */
0b1f3c76 557 r = safe_fork("(sd-umount)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
4c253ed1 558 if (r < 0)
b6e1fff1 559 return r;
4c253ed1 560 if (r == 0) {
d5641e0d
KW
561 log_info("Unmounting '%s'.", m->path);
562
563 /* Start the mount operation here in the child Using MNT_FORCE
564 * causes some filesystems (e.g. FUSE and NFS and other network
565 * filesystems) to abort any pending requests and return -EIO
566 * rather than blocking indefinitely. If the filesysten is
567 * "busy", this may allow processes to die, thus making the
568 * filesystem less busy so the unmount might succeed (rather
7802194a 569 * than return EBUSY). */
d5641e0d
KW
570 r = umount2(m->path, MNT_FORCE);
571 if (r < 0)
456b2199 572 log_full_errno(umount_log_level, errno, "Failed to unmount %s: %m", m->path);
d5641e0d
KW
573
574 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
575 }
576
577 r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
578 if (r == -ETIMEDOUT) {
00adeed9 579 log_error_errno(r, "Unmounting '%s' timed out, issuing SIGKILL to PID " PID_FMT ".", m->path, pid);
d5641e0d 580 (void) kill(pid, SIGKILL);
00adeed9 581 } else if (r == -EPROTO)
456b2199 582 log_debug_errno(r, "Unmounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", m->path, pid);
00adeed9
LP
583 else if (r < 0)
584 log_error_errno(r, "Unmounting '%s' failed unexpectedly, couldn't wait for child process " PID_FMT ": %m", m->path, pid);
d5641e0d
KW
585
586 return r;
587}
588
49f80dce
LP
589/* This includes remounting readonly, which changes the kernel mount options. Therefore the list passed to
590 * this function is invalidated, and should not be reused. */
456b2199 591static int mount_points_list_umount(MountPoint **head, bool *changed, int umount_log_level) {
12aad1d0 592 int n_failed = 0;
e3478379 593
12aad1d0 594 assert(head);
0494cae0 595 assert(changed);
12aad1d0 596
116e6d96 597 LIST_FOREACH(mount_point, m, *head) {
1d62d22d 598 if (m->try_remount_ro) {
49f80dce 599 /* We always try to remount directories read-only first, before we go on and umount
93bd1577
LP
600 * them.
601 *
49f80dce
LP
602 * Mount points can be stacked. If a mount point is stacked below / or /usr, we
603 * cannot umount or remount it directly, since there is no way to refer to the
604 * underlying mount. There's nothing we can do about it for the general case, but we
605 * can do something about it if it is aliased somewhere else via a bind mount. If we
606 * explicitly remount the super block of that alias read-only we hence should be
607 * relatively safe regarding keeping a dirty fs we cannot otherwise see.
d5641e0d 608 *
49f80dce
LP
609 * Since the remount can hang in the instance of remote filesystems, we remount
610 * asynchronously and skip the subsequent umount if it fails. */
456b2199 611 if (remount_with_timeout(m, umount_log_level) < 0) {
8645ffd1
JJ
612 /* Remount failed, but try unmounting anyway,
613 * unless this is a mount point we want to skip. */
614 if (nonunmountable_path(m->path)) {
c826cd3f 615 n_failed++;
8645ffd1
JJ
616 continue;
617 }
c826cd3f 618 }
93bd1577
LP
619 }
620
49f80dce
LP
621 /* Skip / and /usr since we cannot unmount that anyway, since we are running from it. They
622 * have already been remounted ro. */
c826cd3f 623 if (nonunmountable_path(m->path))
e3478379
FF
624 continue;
625
d5641e0d 626 /* Trying to umount */
456b2199 627 if (umount_with_timeout(m, umount_log_level) < 0)
d5641e0d 628 n_failed++;
0494cae0
JJ
629 else
630 *changed = true;
e3478379
FF
631 }
632
12aad1d0 633 return n_failed;
e3478379
FF
634}
635
12aad1d0 636static int swap_points_list_off(MountPoint **head, bool *changed) {
12aad1d0
LP
637 int n_failed = 0;
638
639 assert(head);
0494cae0 640 assert(changed);
e3478379 641
80a226b2 642 LIST_FOREACH(mount_point, m, *head) {
735e0712 643 log_info("Deactivating swap %s.", m->path);
88287615 644 if (swapoff(m->path) < 0) {
56f64d95 645 log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
12aad1d0 646 n_failed++;
88287615 647 continue;
e3478379 648 }
88287615
LP
649
650 *changed = true;
651 mount_point_free(head, m);
e3478379
FF
652 }
653
12aad1d0 654 return n_failed;
e3478379
FF
655}
656
456b2199 657static int loopback_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) {
63135a2d
LP
658 int n_failed = 0, r;
659 dev_t rootdev = 0;
12aad1d0
LP
660
661 assert(head);
0494cae0 662 assert(changed);
12aad1d0 663
63135a2d 664 (void) get_block_device("/", &rootdev);
7fc942b2 665
80a226b2 666 LIST_FOREACH(mount_point, m, *head) {
63135a2d 667 if (major(rootdev) != 0 && rootdev == m->devnum) {
313cefa1 668 n_failed++;
7fc942b2
LP
669 continue;
670 }
e3478379 671
735e0712 672 log_info("Detaching loopback %s.", m->path);
bce93b7a 673 r = delete_loopback(m->path);
88287615
LP
674 if (r < 0) {
675 log_full_errno(umount_log_level, r, "Could not detach loopback %s: %m", m->path);
12aad1d0 676 n_failed++;
88287615 677 continue;
e3478379 678 }
88287615
LP
679 if (r > 0)
680 *changed = true;
681
682 mount_point_free(head, m);
e3478379
FF
683 }
684
12aad1d0 685 return n_failed;
e3478379
FF
686}
687
456b2199 688static int dm_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) {
33e8d8af 689 int n_failed = 0, r;
63135a2d 690 dev_t rootdev = 0;
12aad1d0
LP
691
692 assert(head);
0494cae0 693 assert(changed);
12aad1d0 694
63135a2d 695 (void) get_block_device("/", &rootdev);
7fc942b2 696
80a226b2 697 LIST_FOREACH(mount_point, m, *head) {
0494cae0
JJ
698 if (major(rootdev) != 0 && rootdev == m->devnum) {
699 n_failed ++;
700 continue;
701 }
7fc942b2 702
88287615 703 log_info("Detaching DM %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum));
e55299da 704 r = delete_dm(m);
88287615
LP
705 if (r < 0) {
706 log_full_errno(umount_log_level, r, "Could not detach DM %s: %m", m->path);
12aad1d0 707 n_failed++;
88287615 708 continue;
d48141ba 709 }
88287615
LP
710
711 *changed = true;
712 mount_point_free(head, m);
d48141ba
LP
713 }
714
12aad1d0 715 return n_failed;
d48141ba
LP
716}
717
0b220a5f 718static int md_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) {
0b220a5f
HK
719 int n_failed = 0, r;
720 dev_t rootdev = 0;
721
722 assert(head);
723 assert(changed);
724
725 (void) get_block_device("/", &rootdev);
726
80a226b2 727 LIST_FOREACH(mount_point, m, *head) {
0b220a5f
HK
728 if (major(rootdev) != 0 && rootdev == m->devnum) {
729 n_failed ++;
730 continue;
731 }
732
733 log_info("Stopping MD %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum));
734 r = delete_md(m);
735 if (r < 0) {
736 log_full_errno(umount_log_level, r, "Could not stop MD %s: %m", m->path);
737 n_failed++;
738 continue;
739 }
740
741 *changed = true;
742 mount_point_free(head, m);
743 }
744
745 return n_failed;
746}
747
456b2199 748static int umount_all_once(bool *changed, int umount_log_level) {
a6dcd229 749 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head);
88287615 750 int r;
e3478379 751
0494cae0
JJ
752 assert(changed);
753
71fda00f 754 LIST_HEAD_INIT(mp_list_head);
6fa392bf 755 r = mount_points_list_get(NULL, &mp_list_head);
e3478379 756 if (r < 0)
a6dcd229 757 return r;
116e6d96 758
a6dcd229 759 return mount_points_list_umount(&mp_list_head, changed, umount_log_level);
116e6d96
AJ
760}
761
456b2199 762int umount_all(bool *changed, int umount_log_level) {
116e6d96
AJ
763 bool umount_changed;
764 int r;
765
0494cae0
JJ
766 assert(changed);
767
d5641e0d
KW
768 /* Retry umount, until nothing can be umounted anymore. Mounts are
769 * processed in order, newest first. The retries are needed when
770 * an old mount has been moved, to a path inside a newer mount. */
6f7f51f7
HH
771 do {
772 umount_changed = false;
3e085b6c 773
456b2199 774 r = umount_all_once(&umount_changed, umount_log_level);
6f7f51f7
HH
775 if (umount_changed)
776 *changed = true;
3e085b6c
LP
777 } while (umount_changed);
778
e3478379
FF
779 return r;
780}
781
12aad1d0 782int swapoff_all(bool *changed) {
a6dcd229 783 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, swap_list_head);
e3478379 784 int r;
e3478379 785
0494cae0
JJ
786 assert(changed);
787
71fda00f 788 LIST_HEAD_INIT(swap_list_head);
e3478379 789
1fd8edb5 790 r = swap_list_get(NULL, &swap_list_head);
e3478379 791 if (r < 0)
a6dcd229 792 return r;
e3478379 793
a6dcd229 794 return swap_points_list_off(&swap_list_head, changed);
e3478379
FF
795}
796
456b2199 797int loopback_detach_all(bool *changed, int umount_log_level) {
a6dcd229 798 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, loopback_list_head);
e3478379 799 int r;
e3478379 800
0494cae0
JJ
801 assert(changed);
802
71fda00f 803 LIST_HEAD_INIT(loopback_list_head);
e3478379
FF
804
805 r = loopback_list_get(&loopback_list_head);
806 if (r < 0)
a6dcd229 807 return r;
e3478379 808
a6dcd229 809 return loopback_points_list_detach(&loopback_list_head, changed, umount_log_level);
e3478379 810}
d48141ba 811
456b2199 812int dm_detach_all(bool *changed, int umount_log_level) {
a6dcd229 813 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, dm_list_head);
d48141ba 814 int r;
d48141ba 815
0494cae0
JJ
816 assert(changed);
817
71fda00f 818 LIST_HEAD_INIT(dm_list_head);
d48141ba
LP
819
820 r = dm_list_get(&dm_list_head);
821 if (r < 0)
a6dcd229 822 return r;
d48141ba 823
a6dcd229 824 return dm_points_list_detach(&dm_list_head, changed, umount_log_level);
d48141ba 825}
0b220a5f
HK
826
827int md_detach_all(bool *changed, int umount_log_level) {
828 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, md_list_head);
829 int r;
830
831 assert(changed);
832
833 LIST_HEAD_INIT(md_list_head);
834
835 r = md_list_get(&md_list_head);
836 if (r < 0)
837 return r;
838
839 return md_points_list_detach(&md_list_head, changed, umount_log_level);
840}