]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shutdown/umount.c
Merge pull request #13365 from keszybz/fix-commits-from-pr-13246
[thirdparty/systemd.git] / src / shutdown / umount.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2010 ProFUSION embedded systems
4 ***/
5
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <linux/dm-ioctl.h>
9 #include <linux/loop.h>
10 #include <string.h>
11 #include <sys/mount.h>
12 #include <sys/swap.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16
17 #include "sd-device.h"
18
19 #include "alloc-util.h"
20 #include "blockdev-util.h"
21 #include "def.h"
22 #include "device-util.h"
23 #include "escape.h"
24 #include "fd-util.h"
25 #include "fstab-util.h"
26 #include "libmount-util.h"
27 #include "mount-setup.h"
28 #include "mount-util.h"
29 #include "mountpoint-util.h"
30 #include "path-util.h"
31 #include "process-util.h"
32 #include "signal-util.h"
33 #include "string-util.h"
34 #include "strv.h"
35 #include "umount.h"
36 #include "util.h"
37 #include "virt.h"
38
39 static void mount_point_free(MountPoint **head, MountPoint *m) {
40 assert(head);
41 assert(m);
42
43 LIST_REMOVE(mount_point, *head, m);
44
45 free(m->path);
46 free(m->remount_options);
47 free(m);
48 }
49
50 void mount_points_list_free(MountPoint **head) {
51 assert(head);
52
53 while (*head)
54 mount_point_free(head, *head);
55 }
56
57 int mount_points_list_get(const char *mountinfo, MountPoint **head) {
58 _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
59 _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
60 int r;
61
62 assert(head);
63
64 r = libmount_parse(mountinfo, NULL, &table, &iter);
65 if (r < 0)
66 return log_error_errno(r, "Failed to parse %s: %m", mountinfo);
67
68 for (;;) {
69 struct libmnt_fs *fs;
70 const char *path, *fstype;
71 _cleanup_free_ char *options = NULL;
72 unsigned long remount_flags = 0u;
73 _cleanup_free_ char *remount_options = NULL;
74 bool try_remount_ro;
75 _cleanup_free_ MountPoint *m = NULL;
76
77 r = mnt_table_next_fs(table, iter, &fs);
78 if (r == 1)
79 break;
80 if (r < 0)
81 return log_error_errno(r, "Failed to get next entry from %s: %m", mountinfo);
82
83 path = mnt_fs_get_target(fs);
84 if (!path)
85 continue;
86
87 fstype = mnt_fs_get_fstype(fs);
88
89 /* Combine the generic VFS options with the FS-specific
90 * options. Duplicates are not a problem here, because the only
91 * options that should come up twice are typically ro/rw, which
92 * are turned into MS_RDONLY or the inversion of it.
93 *
94 * Even if there are duplicates later in mount_option_mangle()
95 * they shouldn't hurt anyways as they override each other.
96 */
97 if (!strextend_with_separator(&options, ",",
98 mnt_fs_get_vfs_options(fs),
99 NULL))
100 return log_oom();
101 if (!strextend_with_separator(&options, ",",
102 mnt_fs_get_fs_options(fs),
103 NULL))
104 return log_oom();
105
106 /* Ignore mount points we can't unmount because they
107 * are API or because we are keeping them open (like
108 * /dev/console). Also, ignore all mounts below API
109 * file systems, since they are likely virtual too,
110 * and hence not worth spending time on. Also, in
111 * unprivileged containers we might lack the rights to
112 * unmount these things, hence don't bother. */
113 if (mount_point_is_api(path) ||
114 mount_point_ignore(path) ||
115 PATH_STARTSWITH_SET(path, "/dev", "/sys", "/proc"))
116 continue;
117
118 /* If we are in a container, don't attempt to
119 * read-only mount anything as that brings no real
120 * benefits, but might confuse the host, as we remount
121 * the superblock here, not the bind mount.
122 *
123 * If the filesystem is a network fs, also skip the
124 * remount. It brings no value (we cannot leave
125 * a "dirty fs") and could hang if the network is down.
126 * Note that umount2() is more careful and will not
127 * hang because of the network being down. */
128 try_remount_ro = detect_container() <= 0 &&
129 !fstype_is_network(fstype) &&
130 !fstype_is_api_vfs(fstype) &&
131 !fstype_is_ro(fstype) &&
132 !fstab_test_yes_no_option(options, "ro\0rw\0");
133
134 if (try_remount_ro) {
135 /* mount(2) states that mount flags and options need to be exactly the same
136 * as they were when the filesystem was mounted, except for the desired
137 * changes. So we reconstruct both here and adjust them for the later
138 * remount call too. */
139
140 r = mnt_fs_get_propagation(fs, &remount_flags);
141 if (r < 0) {
142 log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path);
143 continue;
144 }
145
146 r = mount_option_mangle(options, remount_flags, &remount_flags, &remount_options);
147 if (r < 0) {
148 log_warning_errno(r, "mount_option_mangle failed for %s, ignoring: %m", path);
149 continue;
150 }
151
152 /* MS_BIND is special. If it is provided it will only make the mount-point
153 * read-only. If left out, the super block itself is remounted, which we want. */
154 remount_flags = (remount_flags|MS_REMOUNT|MS_RDONLY) & ~MS_BIND;
155 }
156
157 m = new0(MountPoint, 1);
158 if (!m)
159 return log_oom();
160
161 m->path = strdup(path);
162 if (!m->path)
163 return log_oom();
164
165 m->remount_options = TAKE_PTR(remount_options);
166 m->remount_flags = remount_flags;
167 m->try_remount_ro = try_remount_ro;
168
169 LIST_PREPEND(mount_point, *head, TAKE_PTR(m));
170 }
171
172 return 0;
173 }
174
175 int swap_list_get(const char *swaps, MountPoint **head) {
176 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
177 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
178 int r;
179
180 assert(head);
181
182 t = mnt_new_table();
183 i = mnt_new_iter(MNT_ITER_FORWARD);
184 if (!t || !i)
185 return log_oom();
186
187 r = mnt_table_parse_swaps(t, swaps);
188 if (r < 0)
189 return log_error_errno(r, "Failed to parse %s: %m", swaps);
190
191 for (;;) {
192 struct libmnt_fs *fs;
193 _cleanup_free_ MountPoint *swap = NULL;
194 const char *source;
195
196 r = mnt_table_next_fs(t, i, &fs);
197 if (r == 1)
198 break;
199 if (r < 0)
200 return log_error_errno(r, "Failed to get next entry from %s: %m", swaps);
201
202 source = mnt_fs_get_source(fs);
203 if (!source)
204 continue;
205
206 swap = new0(MountPoint, 1);
207 if (!swap)
208 return -ENOMEM;
209
210 swap->path = strdup(source);
211 if (!swap->path)
212 return -ENOMEM;
213
214 LIST_PREPEND(mount_point, *head, TAKE_PTR(swap));
215 }
216
217 return 0;
218 }
219
220 static int loopback_list_get(MountPoint **head) {
221 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
222 sd_device *d;
223 int r;
224
225 assert(head);
226
227 r = sd_device_enumerator_new(&e);
228 if (r < 0)
229 return r;
230
231 r = sd_device_enumerator_allow_uninitialized(e);
232 if (r < 0)
233 return r;
234
235 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
236 if (r < 0)
237 return r;
238
239 r = sd_device_enumerator_add_match_sysname(e, "loop*");
240 if (r < 0)
241 return r;
242
243 r = sd_device_enumerator_add_match_sysattr(e, "loop/backing_file", NULL, true);
244 if (r < 0)
245 return r;
246
247 FOREACH_DEVICE(e, d) {
248 _cleanup_free_ char *p = NULL;
249 const char *dn;
250 MountPoint *lb;
251
252 if (sd_device_get_devname(d, &dn) < 0)
253 continue;
254
255 p = strdup(dn);
256 if (!p)
257 return -ENOMEM;
258
259 lb = new(MountPoint, 1);
260 if (!lb)
261 return -ENOMEM;
262
263 *lb = (MountPoint) {
264 .path = TAKE_PTR(p),
265 };
266
267 LIST_PREPEND(mount_point, *head, lb);
268 }
269
270 return 0;
271 }
272
273 static int dm_list_get(MountPoint **head) {
274 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
275 sd_device *d;
276 int r;
277
278 assert(head);
279
280 r = sd_device_enumerator_new(&e);
281 if (r < 0)
282 return r;
283
284 r = sd_device_enumerator_allow_uninitialized(e);
285 if (r < 0)
286 return r;
287
288 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
289 if (r < 0)
290 return r;
291
292 r = sd_device_enumerator_add_match_sysname(e, "dm-*");
293 if (r < 0)
294 return r;
295
296 FOREACH_DEVICE(e, d) {
297 _cleanup_free_ char *p = NULL;
298 const char *dn;
299 MountPoint *m;
300 dev_t devnum;
301
302 if (sd_device_get_devnum(d, &devnum) < 0 ||
303 sd_device_get_devname(d, &dn) < 0)
304 continue;
305
306 p = strdup(dn);
307 if (!p)
308 return -ENOMEM;
309
310 m = new(MountPoint, 1);
311 if (!m)
312 return -ENOMEM;
313
314 *m = (MountPoint) {
315 .path = TAKE_PTR(p),
316 .devnum = devnum,
317 };
318
319 LIST_PREPEND(mount_point, *head, m);
320 }
321
322 return 0;
323 }
324
325 static int delete_loopback(const char *device) {
326 _cleanup_close_ int fd = -1;
327 int r;
328
329 assert(device);
330
331 fd = open(device, O_RDONLY|O_CLOEXEC);
332 if (fd < 0)
333 return errno == ENOENT ? 0 : -errno;
334
335 r = ioctl(fd, LOOP_CLR_FD, 0);
336 if (r >= 0)
337 return 1;
338
339 /* ENXIO: not bound, so no error */
340 if (errno == ENXIO)
341 return 0;
342
343 return -errno;
344 }
345
346 static int delete_dm(dev_t devnum) {
347
348 struct dm_ioctl dm = {
349 .version = {
350 DM_VERSION_MAJOR,
351 DM_VERSION_MINOR,
352 DM_VERSION_PATCHLEVEL
353 },
354 .data_size = sizeof(dm),
355 .dev = devnum,
356 };
357
358 _cleanup_close_ int fd = -1;
359
360 assert(major(devnum) != 0);
361
362 fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
363 if (fd < 0)
364 return -errno;
365
366 if (ioctl(fd, DM_DEV_REMOVE, &dm) < 0)
367 return -errno;
368
369 return 0;
370 }
371
372 static bool nonunmountable_path(const char *path) {
373 return path_equal(path, "/")
374 #if ! HAVE_SPLIT_USR
375 || path_equal(path, "/usr")
376 #endif
377 || path_startswith(path, "/run/initramfs");
378 }
379
380 static int remount_with_timeout(MountPoint *m, int umount_log_level) {
381 pid_t pid;
382 int r;
383
384 BLOCK_SIGNALS(SIGCHLD);
385
386 assert(m);
387
388 /* Due to the possibility of a remount operation hanging, we
389 * fork a child process and set a timeout. If the timeout
390 * lapses, the assumption is that that particular remount
391 * failed. */
392 r = safe_fork("(sd-remount)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
393 if (r < 0)
394 return r;
395 if (r == 0) {
396 log_info("Remounting '%s' read-only in with options '%s'.", m->path, m->remount_options);
397
398 /* Start the mount operation here in the child */
399 r = mount(NULL, m->path, NULL, m->remount_flags, m->remount_options);
400 if (r < 0)
401 log_full_errno(umount_log_level, errno, "Failed to remount '%s' read-only: %m", m->path);
402
403 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
404 }
405
406 r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
407 if (r == -ETIMEDOUT) {
408 log_error_errno(r, "Remounting '%s' timed out, issuing SIGKILL to PID " PID_FMT ".", m->path, pid);
409 (void) kill(pid, SIGKILL);
410 } else if (r == -EPROTO)
411 log_debug_errno(r, "Remounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", m->path, pid);
412 else if (r < 0)
413 log_error_errno(r, "Remounting '%s' failed unexpectedly, couldn't wait for child process " PID_FMT ": %m", m->path, pid);
414
415 return r;
416 }
417
418 static int umount_with_timeout(MountPoint *m, int umount_log_level) {
419 pid_t pid;
420 int r;
421
422 BLOCK_SIGNALS(SIGCHLD);
423
424 assert(m);
425
426 /* Due to the possibility of a umount operation hanging, we
427 * fork a child process and set a timeout. If the timeout
428 * lapses, the assumption is that that particular umount
429 * failed. */
430 r = safe_fork("(sd-umount)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &pid);
431 if (r < 0)
432 return r;
433 if (r == 0) {
434 log_info("Unmounting '%s'.", m->path);
435
436 /* Start the mount operation here in the child Using MNT_FORCE
437 * causes some filesystems (e.g. FUSE and NFS and other network
438 * filesystems) to abort any pending requests and return -EIO
439 * rather than blocking indefinitely. If the filesysten is
440 * "busy", this may allow processes to die, thus making the
441 * filesystem less busy so the unmount might succeed (rather
442 * then return EBUSY).*/
443 r = umount2(m->path, MNT_FORCE);
444 if (r < 0)
445 log_full_errno(umount_log_level, errno, "Failed to unmount %s: %m", m->path);
446
447 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
448 }
449
450 r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
451 if (r == -ETIMEDOUT) {
452 log_error_errno(r, "Unmounting '%s' timed out, issuing SIGKILL to PID " PID_FMT ".", m->path, pid);
453 (void) kill(pid, SIGKILL);
454 } else if (r == -EPROTO)
455 log_debug_errno(r, "Unmounting '%s' failed abnormally, child process " PID_FMT " aborted or exited non-zero.", m->path, pid);
456 else if (r < 0)
457 log_error_errno(r, "Unmounting '%s' failed unexpectedly, couldn't wait for child process " PID_FMT ": %m", m->path, pid);
458
459 return r;
460 }
461
462 /* This includes remounting readonly, which changes the kernel mount options.
463 * Therefore the list passed to this function is invalidated, and should not be reused. */
464 static int mount_points_list_umount(MountPoint **head, bool *changed, int umount_log_level) {
465 MountPoint *m;
466 int n_failed = 0;
467
468 assert(head);
469 assert(changed);
470
471 LIST_FOREACH(mount_point, m, *head) {
472 if (m->try_remount_ro) {
473 /* We always try to remount directories
474 * read-only first, before we go on and umount
475 * them.
476 *
477 * Mount points can be stacked. If a mount
478 * point is stacked below / or /usr, we
479 * cannot umount or remount it directly,
480 * since there is no way to refer to the
481 * underlying mount. There's nothing we can do
482 * about it for the general case, but we can
483 * do something about it if it is aliased
484 * somewhere else via a bind mount. If we
485 * explicitly remount the super block of that
486 * alias read-only we hence should be
487 * relatively safe regarding keeping a dirty fs
488 * we cannot otherwise see.
489 *
490 * Since the remount can hang in the instance of
491 * remote filesystems, we remount asynchronously
492 * and skip the subsequent umount if it fails. */
493 if (remount_with_timeout(m, umount_log_level) < 0) {
494 /* Remount failed, but try unmounting anyway,
495 * unless this is a mount point we want to skip. */
496 if (nonunmountable_path(m->path)) {
497 n_failed++;
498 continue;
499 }
500 }
501 }
502
503 /* Skip / and /usr since we cannot unmount that
504 * anyway, since we are running from it. They have
505 * already been remounted ro. */
506 if (nonunmountable_path(m->path))
507 continue;
508
509 /* Trying to umount */
510 if (umount_with_timeout(m, umount_log_level) < 0)
511 n_failed++;
512 else
513 *changed = true;
514 }
515
516 return n_failed;
517 }
518
519 static int swap_points_list_off(MountPoint **head, bool *changed) {
520 MountPoint *m, *n;
521 int n_failed = 0;
522
523 assert(head);
524 assert(changed);
525
526 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
527 log_info("Deactivating swap %s.", m->path);
528 if (swapoff(m->path) == 0) {
529 *changed = true;
530 mount_point_free(head, m);
531 } else {
532 log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
533 n_failed++;
534 }
535 }
536
537 return n_failed;
538 }
539
540 static int loopback_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) {
541 MountPoint *m, *n;
542 int n_failed = 0, k;
543 struct stat root_st;
544
545 assert(head);
546 assert(changed);
547
548 k = lstat("/", &root_st);
549
550 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
551 int r;
552 struct stat loopback_st;
553
554 if (k >= 0 &&
555 major(root_st.st_dev) != 0 &&
556 lstat(m->path, &loopback_st) >= 0 &&
557 root_st.st_dev == loopback_st.st_rdev) {
558 n_failed++;
559 continue;
560 }
561
562 log_info("Detaching loopback %s.", m->path);
563 r = delete_loopback(m->path);
564 if (r >= 0) {
565 if (r > 0)
566 *changed = true;
567
568 mount_point_free(head, m);
569 } else {
570 log_full_errno(umount_log_level, errno, "Could not detach loopback %s: %m", m->path);
571 n_failed++;
572 }
573 }
574
575 return n_failed;
576 }
577
578 static int dm_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) {
579 MountPoint *m, *n;
580 int n_failed = 0, r;
581 dev_t rootdev;
582
583 assert(head);
584 assert(changed);
585
586 r = get_block_device("/", &rootdev);
587 if (r <= 0)
588 rootdev = 0;
589
590 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
591
592 if (major(rootdev) != 0 && rootdev == m->devnum) {
593 n_failed ++;
594 continue;
595 }
596
597 log_info("Detaching DM %u:%u.", major(m->devnum), minor(m->devnum));
598 r = delete_dm(m->devnum);
599 if (r >= 0) {
600 *changed = true;
601 mount_point_free(head, m);
602 } else {
603 log_full_errno(umount_log_level, errno, "Could not detach DM %s: %m", m->path);
604 n_failed++;
605 }
606 }
607
608 return n_failed;
609 }
610
611 static int umount_all_once(bool *changed, int umount_log_level) {
612 int r;
613 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head);
614
615 assert(changed);
616
617 LIST_HEAD_INIT(mp_list_head);
618 r = mount_points_list_get(NULL, &mp_list_head);
619 if (r < 0)
620 return r;
621
622 return mount_points_list_umount(&mp_list_head, changed, umount_log_level);
623 }
624
625 int umount_all(bool *changed, int umount_log_level) {
626 bool umount_changed;
627 int r;
628
629 assert(changed);
630
631 /* Retry umount, until nothing can be umounted anymore. Mounts are
632 * processed in order, newest first. The retries are needed when
633 * an old mount has been moved, to a path inside a newer mount. */
634 do {
635 umount_changed = false;
636
637 r = umount_all_once(&umount_changed, umount_log_level);
638 if (umount_changed)
639 *changed = true;
640 } while (umount_changed);
641
642 return r;
643 }
644
645 int swapoff_all(bool *changed) {
646 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, swap_list_head);
647 int r;
648
649 assert(changed);
650
651 LIST_HEAD_INIT(swap_list_head);
652
653 r = swap_list_get(NULL, &swap_list_head);
654 if (r < 0)
655 return r;
656
657 return swap_points_list_off(&swap_list_head, changed);
658 }
659
660 int loopback_detach_all(bool *changed, int umount_log_level) {
661 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, loopback_list_head);
662 int r;
663
664 assert(changed);
665
666 LIST_HEAD_INIT(loopback_list_head);
667
668 r = loopback_list_get(&loopback_list_head);
669 if (r < 0)
670 return r;
671
672 return loopback_points_list_detach(&loopback_list_head, changed, umount_log_level);
673 }
674
675 int dm_detach_all(bool *changed, int umount_log_level) {
676 _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, dm_list_head);
677 int r;
678
679 assert(changed);
680
681 LIST_HEAD_INIT(dm_list_head);
682
683 r = dm_list_get(&dm_list_head);
684 if (r < 0)
685 return r;
686
687 return dm_points_list_detach(&dm_list_head, changed, umount_log_level);
688 }