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