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