1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 ProFUSION embedded systems
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/mount.h>
28 #include <linux/loop.h>
29 #include <linux/dm-ioctl.h>
32 #include "mount-setup.h"
34 #include "path-util.h"
38 #include "udev-util.h"
40 typedef struct MountPoint {
43 LIST_FIELDS(struct MountPoint, mount_point);
46 static void mount_point_free(MountPoint **head, MountPoint *m) {
50 LIST_REMOVE(mount_point, *head, m);
56 static void mount_points_list_free(MountPoint **head) {
60 mount_point_free(head, *head);
63 static int mount_points_list_get(MountPoint **head) {
64 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
69 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
70 if (!proc_self_mountinfo)
74 _cleanup_free_ char *path = NULL;
79 k = fscanf(proc_self_mountinfo,
80 "%*s " /* (1) mount id */
81 "%*s " /* (2) parent id */
82 "%*s " /* (3) major:minor */
84 "%ms " /* (5) mount point */
85 "%*s" /* (6) mount options */
86 "%*[^-]" /* (7) optional fields */
87 "- " /* (8) separator */
88 "%*s " /* (9) file system type */
89 "%*s" /* (10) mount source */
90 "%*s" /* (11) mount options 2 */
91 "%*[^\n]", /* some rubbish at the end */
97 log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
105 /* Ignore mount points we can't unmount because they
106 * are API or because we are keeping them open (like
107 * /dev/console). Also, ignore all mounts below API
108 * file systems, since they are likely virtual too,
109 * and hence not worth spending time on. Also, in
110 * unprivileged containers we might lack the rights to
111 * unmount these things, hence don't bother. */
112 if (mount_point_is_api(p) ||
113 mount_point_ignore(p) ||
114 path_startswith(p, "/dev") ||
115 path_startswith(p, "/sys") ||
116 path_startswith(p, "/proc")) {
121 m = new0(MountPoint, 1);
128 LIST_PREPEND(mount_point, *head, m);
134 static int swap_list_get(MountPoint **head) {
135 _cleanup_fclose_ FILE *proc_swaps = NULL;
140 if (!(proc_swaps = fopen("/proc/swaps", "re")))
141 return (errno == ENOENT) ? 0 : -errno;
143 (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n");
147 char *dev = NULL, *d;
150 if ((k = fscanf(proc_swaps,
151 "%ms " /* device/file */
152 "%*s " /* type of swap */
153 "%*s " /* swap size */
155 "%*s\n", /* priority */
161 log_warning("Failed to parse /proc/swaps:%u.", i);
167 if (endswith(dev, " (deleted)")) {
179 if (!(swap = new0(MountPoint, 1))) {
185 LIST_PREPEND(mount_point, *head, swap);
191 static int loopback_list_get(MountPoint **head) {
192 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
193 struct udev_list_entry *item = NULL, *first = NULL;
194 _cleanup_udev_unref_ struct udev *udev = NULL;
203 e = udev_enumerate_new(udev);
207 r = udev_enumerate_add_match_subsystem(e, "block");
211 r = udev_enumerate_add_match_sysname(e, "loop*");
215 r = udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL);
219 r = udev_enumerate_scan_devices(e);
223 first = udev_enumerate_get_list_entry(e);
224 udev_list_entry_foreach(item, first) {
226 _cleanup_udev_device_unref_ struct udev_device *d;
230 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
234 dn = udev_device_get_devnode(d);
242 lb = new0(MountPoint, 1);
249 LIST_PREPEND(mount_point, *head, lb);
255 static int dm_list_get(MountPoint **head) {
256 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
257 struct udev_list_entry *item = NULL, *first = NULL;
258 _cleanup_udev_unref_ struct udev *udev = NULL;
267 e = udev_enumerate_new(udev);
271 r = udev_enumerate_add_match_subsystem(e, "block");
275 r = udev_enumerate_add_match_sysname(e, "dm-*");
279 r = udev_enumerate_scan_devices(e);
283 first = udev_enumerate_get_list_entry(e);
284 udev_list_entry_foreach(item, first) {
286 _cleanup_udev_device_unref_ struct udev_device *d;
291 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
295 devnum = udev_device_get_devnum(d);
296 dn = udev_device_get_devnode(d);
297 if (major(devnum) == 0 || !dn)
304 m = new(MountPoint, 1);
312 LIST_PREPEND(mount_point, *head, m);
318 static int delete_loopback(const char *device) {
319 _cleanup_close_ int fd = -1;
322 fd = open(device, O_RDONLY|O_CLOEXEC);
324 return errno == ENOENT ? 0 : -errno;
326 r = ioctl(fd, LOOP_CLR_FD, 0);
330 /* ENXIO: not bound, so no error */
337 static int delete_dm(dev_t devnum) {
338 _cleanup_close_ int fd = -1;
340 struct dm_ioctl dm = {
341 .version = {DM_VERSION_MAJOR,
343 DM_VERSION_PATCHLEVEL},
344 .data_size = sizeof(dm),
348 assert(major(devnum) != 0);
350 fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC);
354 r = ioctl(fd, DM_DEV_REMOVE, &dm);
355 return r >= 0 ? 0 : -errno;
358 static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
364 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
366 /* If we are in a container, don't attempt to
367 read-only mount anything as that brings no real
368 benefits, but might confuse the host, as we remount
369 the superblock here, not the bind mound. */
370 if (detect_container(NULL) <= 0) {
371 /* We always try to remount directories
372 * read-only first, before we go on and umount
375 * Mount points can be stacked. If a mount
376 * point is stacked below / or /usr, we
377 * cannot umount or remount it directly,
378 * since there is no way to refer to the
379 * underlying mount. There's nothing we can do
380 * about it for the general case, but we can
381 * do something about it if it is aliased
382 * somehwere else via a bind mount. If we
383 * explicitly remount the super block of that
384 * alias read-only we hence should be
385 * relatively safe regarding keeping the fs we
386 * can otherwise not see dirty. */
387 mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
390 /* Skip / and /usr since we cannot unmount that
391 * anyway, since we are running from it. They have
392 * already been remounted ro. */
393 if (path_equal(m->path, "/")
394 #ifndef HAVE_SPLIT_USR
395 || path_equal(m->path, "/usr")
400 /* Trying to umount. We don't force here since we rely
401 * on busy NFS and FUSE file systems to return EBUSY
402 * until we closed everything on top of them. */
403 log_info("Unmounting %s.", m->path);
404 if (umount2(m->path, 0) == 0) {
408 mount_point_free(head, m);
409 } else if (log_error) {
410 log_warning_errno(errno, "Could not unmount %s: %m", m->path);
418 static int swap_points_list_off(MountPoint **head, bool *changed) {
424 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
425 log_info("Deactivating swap %s.", m->path);
426 if (swapoff(m->path) == 0) {
430 mount_point_free(head, m);
432 log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
440 static int loopback_points_list_detach(MountPoint **head, bool *changed) {
447 k = lstat("/", &root_st);
449 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
451 struct stat loopback_st;
454 major(root_st.st_dev) != 0 &&
455 lstat(m->path, &loopback_st) >= 0 &&
456 root_st.st_dev == loopback_st.st_rdev) {
461 log_info("Detaching loopback %s.", m->path);
462 r = delete_loopback(m->path);
464 if (r > 0 && changed)
467 mount_point_free(head, m);
469 log_warning_errno(errno, "Could not detach loopback %s: %m", m->path);
477 static int dm_points_list_detach(MountPoint **head, bool *changed) {
484 k = lstat("/", &root_st);
486 LIST_FOREACH_SAFE(mount_point, m, n, *head) {
490 major(root_st.st_dev) != 0 &&
491 root_st.st_dev == m->devnum) {
496 log_info("Detaching DM %u:%u.", major(m->devnum), minor(m->devnum));
497 r = delete_dm(m->devnum);
502 mount_point_free(head, m);
504 log_warning_errno(errno, "Could not detach DM %s: %m", m->path);
512 int umount_all(bool *changed) {
515 LIST_HEAD(MountPoint, mp_list_head);
517 LIST_HEAD_INIT(mp_list_head);
518 r = mount_points_list_get(&mp_list_head);
522 /* retry umount, until nothing can be umounted anymore */
524 umount_changed = false;
526 mount_points_list_umount(&mp_list_head, &umount_changed, false);
530 } while (umount_changed);
532 /* umount one more time with logging enabled */
533 r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
538 mount_points_list_free(&mp_list_head);
543 int swapoff_all(bool *changed) {
545 LIST_HEAD(MountPoint, swap_list_head);
547 LIST_HEAD_INIT(swap_list_head);
549 r = swap_list_get(&swap_list_head);
553 r = swap_points_list_off(&swap_list_head, changed);
556 mount_points_list_free(&swap_list_head);
561 int loopback_detach_all(bool *changed) {
563 LIST_HEAD(MountPoint, loopback_list_head);
565 LIST_HEAD_INIT(loopback_list_head);
567 r = loopback_list_get(&loopback_list_head);
571 r = loopback_points_list_detach(&loopback_list_head, changed);
574 mount_points_list_free(&loopback_list_head);
579 int dm_detach_all(bool *changed) {
581 LIST_HEAD(MountPoint, dm_list_head);
583 LIST_HEAD_INIT(dm_list_head);
585 r = dm_list_get(&dm_list_head);
589 r = dm_points_list_detach(&dm_list_head, changed);
592 mount_points_list_free(&dm_list_head);