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>
27 #include <linux/loop.h>
28 #include <linux/dm-ioctl.h>
31 #include "mount-setup.h"
33 #include "path-util.h"
37 #include "udev-util.h"
39 typedef struct MountPoint
{
42 LIST_FIELDS(struct MountPoint
, mount_point
);
45 static void mount_point_free(MountPoint
**head
, MountPoint
*m
) {
49 LIST_REMOVE(mount_point
, *head
, m
);
55 static void mount_points_list_free(MountPoint
**head
) {
59 mount_point_free(head
, *head
);
62 static int mount_points_list_get(MountPoint
**head
) {
63 _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
);
101 r
= cunescape(path
, UNESCAPE_RELAX
, &p
);
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
;
141 proc_swaps
= fopen("/proc/swaps", "re");
143 return (errno
== ENOENT
) ? 0 : -errno
;
145 (void) fscanf(proc_swaps
, "%*s %*s %*s %*s %*s\n");
149 char *dev
= NULL
, *d
;
152 k
= fscanf(proc_swaps
,
153 "%ms " /* device/file */
154 "%*s " /* type of swap */
155 "%*s " /* swap size */
157 "%*s\n", /* priority */
164 log_warning("Failed to parse /proc/swaps:%u.", i
);
169 if (endswith(dev
, " (deleted)")) {
174 r
= cunescape(dev
, UNESCAPE_RELAX
, &d
);
179 swap
= new0(MountPoint
, 1);
186 LIST_PREPEND(mount_point
, *head
, swap
);
192 static int loopback_list_get(MountPoint
**head
) {
193 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
194 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
195 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
204 e
= udev_enumerate_new(udev
);
208 r
= udev_enumerate_add_match_subsystem(e
, "block");
212 r
= udev_enumerate_add_match_sysname(e
, "loop*");
216 r
= udev_enumerate_add_match_sysattr(e
, "loop/backing_file", NULL
);
220 r
= udev_enumerate_scan_devices(e
);
224 first
= udev_enumerate_get_list_entry(e
);
225 udev_list_entry_foreach(item
, first
) {
227 _cleanup_udev_device_unref_
struct udev_device
*d
;
231 d
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
235 dn
= udev_device_get_devnode(d
);
243 lb
= new0(MountPoint
, 1);
250 LIST_PREPEND(mount_point
, *head
, lb
);
256 static int dm_list_get(MountPoint
**head
) {
257 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
258 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
259 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
268 e
= udev_enumerate_new(udev
);
272 r
= udev_enumerate_add_match_subsystem(e
, "block");
276 r
= udev_enumerate_add_match_sysname(e
, "dm-*");
280 r
= udev_enumerate_scan_devices(e
);
284 first
= udev_enumerate_get_list_entry(e
);
285 udev_list_entry_foreach(item
, first
) {
287 _cleanup_udev_device_unref_
struct udev_device
*d
;
292 d
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
296 devnum
= udev_device_get_devnum(d
);
297 dn
= udev_device_get_devnode(d
);
298 if (major(devnum
) == 0 || !dn
)
305 m
= new(MountPoint
, 1);
313 LIST_PREPEND(mount_point
, *head
, m
);
319 static int delete_loopback(const char *device
) {
320 _cleanup_close_
int fd
= -1;
323 fd
= open(device
, O_RDONLY
|O_CLOEXEC
);
325 return errno
== ENOENT
? 0 : -errno
;
327 r
= ioctl(fd
, LOOP_CLR_FD
, 0);
331 /* ENXIO: not bound, so no error */
338 static int delete_dm(dev_t devnum
) {
339 _cleanup_close_
int fd
= -1;
341 struct dm_ioctl dm
= {
342 .version
= {DM_VERSION_MAJOR
,
344 DM_VERSION_PATCHLEVEL
},
345 .data_size
= sizeof(dm
),
349 assert(major(devnum
) != 0);
351 fd
= open("/dev/mapper/control", O_RDWR
|O_CLOEXEC
);
355 r
= ioctl(fd
, DM_DEV_REMOVE
, &dm
);
356 return r
>= 0 ? 0 : -errno
;
359 static int mount_points_list_umount(MountPoint
**head
, bool *changed
, bool log_error
) {
365 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
367 /* If we are in a container, don't attempt to
368 read-only mount anything as that brings no real
369 benefits, but might confuse the host, as we remount
370 the superblock here, not the bind mound. */
371 if (detect_container(NULL
) <= 0) {
372 /* We always try to remount directories
373 * read-only first, before we go on and umount
376 * Mount points can be stacked. If a mount
377 * point is stacked below / or /usr, we
378 * cannot umount or remount it directly,
379 * since there is no way to refer to the
380 * underlying mount. There's nothing we can do
381 * about it for the general case, but we can
382 * do something about it if it is aliased
383 * somehwere else via a bind mount. If we
384 * explicitly remount the super block of that
385 * alias read-only we hence should be
386 * relatively safe regarding keeping the fs we
387 * can otherwise not see dirty. */
388 (void) mount(NULL
, m
->path
, NULL
, MS_REMOUNT
|MS_RDONLY
, NULL
);
391 /* Skip / and /usr since we cannot unmount that
392 * anyway, since we are running from it. They have
393 * already been remounted ro. */
394 if (path_equal(m
->path
, "/")
395 #ifndef HAVE_SPLIT_USR
396 || path_equal(m
->path
, "/usr")
401 /* Trying to umount. We don't force here since we rely
402 * on busy NFS and FUSE file systems to return EBUSY
403 * until we closed everything on top of them. */
404 log_info("Unmounting %s.", m
->path
);
405 if (umount2(m
->path
, 0) == 0) {
409 mount_point_free(head
, m
);
410 } else if (log_error
) {
411 log_warning_errno(errno
, "Could not unmount %s: %m", m
->path
);
419 static int swap_points_list_off(MountPoint
**head
, bool *changed
) {
425 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
426 log_info("Deactivating swap %s.", m
->path
);
427 if (swapoff(m
->path
) == 0) {
431 mount_point_free(head
, m
);
433 log_warning_errno(errno
, "Could not deactivate swap %s: %m", m
->path
);
441 static int loopback_points_list_detach(MountPoint
**head
, bool *changed
) {
448 k
= lstat("/", &root_st
);
450 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
452 struct stat loopback_st
;
455 major(root_st
.st_dev
) != 0 &&
456 lstat(m
->path
, &loopback_st
) >= 0 &&
457 root_st
.st_dev
== loopback_st
.st_rdev
) {
462 log_info("Detaching loopback %s.", m
->path
);
463 r
= delete_loopback(m
->path
);
465 if (r
> 0 && changed
)
468 mount_point_free(head
, m
);
470 log_warning_errno(errno
, "Could not detach loopback %s: %m", m
->path
);
478 static int dm_points_list_detach(MountPoint
**head
, bool *changed
) {
485 k
= lstat("/", &root_st
);
487 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
491 major(root_st
.st_dev
) != 0 &&
492 root_st
.st_dev
== m
->devnum
) {
497 log_info("Detaching DM %u:%u.", major(m
->devnum
), minor(m
->devnum
));
498 r
= delete_dm(m
->devnum
);
503 mount_point_free(head
, m
);
505 log_warning_errno(errno
, "Could not detach DM %s: %m", m
->path
);
513 int umount_all(bool *changed
) {
516 LIST_HEAD(MountPoint
, mp_list_head
);
518 LIST_HEAD_INIT(mp_list_head
);
519 r
= mount_points_list_get(&mp_list_head
);
523 /* retry umount, until nothing can be umounted anymore */
525 umount_changed
= false;
527 mount_points_list_umount(&mp_list_head
, &umount_changed
, false);
531 } while (umount_changed
);
533 /* umount one more time with logging enabled */
534 r
= mount_points_list_umount(&mp_list_head
, &umount_changed
, true);
539 mount_points_list_free(&mp_list_head
);
544 int swapoff_all(bool *changed
) {
546 LIST_HEAD(MountPoint
, swap_list_head
);
548 LIST_HEAD_INIT(swap_list_head
);
550 r
= swap_list_get(&swap_list_head
);
554 r
= swap_points_list_off(&swap_list_head
, changed
);
557 mount_points_list_free(&swap_list_head
);
562 int loopback_detach_all(bool *changed
) {
564 LIST_HEAD(MountPoint
, loopback_list_head
);
566 LIST_HEAD_INIT(loopback_list_head
);
568 r
= loopback_list_get(&loopback_list_head
);
572 r
= loopback_points_list_detach(&loopback_list_head
, changed
);
575 mount_points_list_free(&loopback_list_head
);
580 int dm_detach_all(bool *changed
) {
582 LIST_HEAD(MountPoint
, dm_list_head
);
584 LIST_HEAD_INIT(dm_list_head
);
586 r
= dm_list_get(&dm_list_head
);
590 r
= dm_points_list_detach(&dm_list_head
, changed
);
593 mount_points_list_free(&dm_list_head
);