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