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/>.
24 #include <linux/dm-ioctl.h>
25 #include <linux/loop.h>
27 #include <sys/mount.h>
34 #include "mount-setup.h"
35 #include "path-util.h"
36 #include "string-util.h"
37 #include "udev-util.h"
42 typedef struct MountPoint
{
45 LIST_FIELDS(struct MountPoint
, mount_point
);
48 static void mount_point_free(MountPoint
**head
, MountPoint
*m
) {
52 LIST_REMOVE(mount_point
, *head
, m
);
58 static void mount_points_list_free(MountPoint
**head
) {
62 mount_point_free(head
, *head
);
65 static int mount_points_list_get(MountPoint
**head
) {
66 _cleanup_fclose_
FILE *proc_self_mountinfo
= NULL
;
72 proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
73 if (!proc_self_mountinfo
)
77 _cleanup_free_
char *path
= NULL
;
82 k
= fscanf(proc_self_mountinfo
,
83 "%*s " /* (1) mount id */
84 "%*s " /* (2) parent id */
85 "%*s " /* (3) major:minor */
87 "%ms " /* (5) mount point */
88 "%*s" /* (6) mount options */
89 "%*[^-]" /* (7) optional fields */
90 "- " /* (8) separator */
91 "%*s " /* (9) file system type */
92 "%*s" /* (10) mount source */
93 "%*s" /* (11) mount options 2 */
94 "%*[^\n]", /* some rubbish at the end */
100 log_warning("Failed to parse /proc/self/mountinfo:%u.", i
);
104 r
= cunescape(path
, UNESCAPE_RELAX
, &p
);
108 /* Ignore mount points we can't unmount because they
109 * are API or because we are keeping them open (like
110 * /dev/console). Also, ignore all mounts below API
111 * file systems, since they are likely virtual too,
112 * and hence not worth spending time on. Also, in
113 * unprivileged containers we might lack the rights to
114 * unmount these things, hence don't bother. */
115 if (mount_point_is_api(p
) ||
116 mount_point_ignore(p
) ||
117 path_startswith(p
, "/dev") ||
118 path_startswith(p
, "/sys") ||
119 path_startswith(p
, "/proc")) {
124 m
= new0(MountPoint
, 1);
131 LIST_PREPEND(mount_point
, *head
, m
);
137 static int swap_list_get(MountPoint
**head
) {
138 _cleanup_fclose_
FILE *proc_swaps
= NULL
;
144 proc_swaps
= fopen("/proc/swaps", "re");
146 return (errno
== ENOENT
) ? 0 : -errno
;
148 (void) fscanf(proc_swaps
, "%*s %*s %*s %*s %*s\n");
152 char *dev
= NULL
, *d
;
155 k
= fscanf(proc_swaps
,
156 "%ms " /* device/file */
157 "%*s " /* type of swap */
158 "%*s " /* swap size */
160 "%*s\n", /* priority */
167 log_warning("Failed to parse /proc/swaps:%u.", i
);
172 if (endswith(dev
, " (deleted)")) {
177 r
= cunescape(dev
, UNESCAPE_RELAX
, &d
);
182 swap
= new0(MountPoint
, 1);
189 LIST_PREPEND(mount_point
, *head
, swap
);
195 static int loopback_list_get(MountPoint
**head
) {
196 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
197 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
198 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
207 e
= udev_enumerate_new(udev
);
211 r
= udev_enumerate_add_match_subsystem(e
, "block");
215 r
= udev_enumerate_add_match_sysname(e
, "loop*");
219 r
= udev_enumerate_add_match_sysattr(e
, "loop/backing_file", NULL
);
223 r
= udev_enumerate_scan_devices(e
);
227 first
= udev_enumerate_get_list_entry(e
);
228 udev_list_entry_foreach(item
, first
) {
230 _cleanup_udev_device_unref_
struct udev_device
*d
;
234 d
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
238 dn
= udev_device_get_devnode(d
);
246 lb
= new0(MountPoint
, 1);
253 LIST_PREPEND(mount_point
, *head
, lb
);
259 static int dm_list_get(MountPoint
**head
) {
260 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
261 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
262 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
271 e
= udev_enumerate_new(udev
);
275 r
= udev_enumerate_add_match_subsystem(e
, "block");
279 r
= udev_enumerate_add_match_sysname(e
, "dm-*");
283 r
= udev_enumerate_scan_devices(e
);
287 first
= udev_enumerate_get_list_entry(e
);
288 udev_list_entry_foreach(item
, first
) {
290 _cleanup_udev_device_unref_
struct udev_device
*d
;
295 d
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
299 devnum
= udev_device_get_devnum(d
);
300 dn
= udev_device_get_devnode(d
);
301 if (major(devnum
) == 0 || !dn
)
308 m
= new(MountPoint
, 1);
316 LIST_PREPEND(mount_point
, *head
, m
);
322 static int delete_loopback(const char *device
) {
323 _cleanup_close_
int fd
= -1;
326 fd
= open(device
, O_RDONLY
|O_CLOEXEC
);
328 return errno
== ENOENT
? 0 : -errno
;
330 r
= ioctl(fd
, LOOP_CLR_FD
, 0);
334 /* ENXIO: not bound, so no error */
341 static int delete_dm(dev_t devnum
) {
342 _cleanup_close_
int fd
= -1;
344 struct dm_ioctl dm
= {
345 .version
= {DM_VERSION_MAJOR
,
347 DM_VERSION_PATCHLEVEL
},
348 .data_size
= sizeof(dm
),
352 assert(major(devnum
) != 0);
354 fd
= open("/dev/mapper/control", O_RDWR
|O_CLOEXEC
);
358 r
= ioctl(fd
, DM_DEV_REMOVE
, &dm
);
359 return r
>= 0 ? 0 : -errno
;
362 static int mount_points_list_umount(MountPoint
**head
, bool *changed
, bool log_error
) {
368 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
370 /* If we are in a container, don't attempt to
371 read-only mount anything as that brings no real
372 benefits, but might confuse the host, as we remount
373 the superblock here, not the bind mound. */
374 if (detect_container() <= 0) {
375 /* We always try to remount directories
376 * read-only first, before we go on and umount
379 * Mount points can be stacked. If a mount
380 * point is stacked below / or /usr, we
381 * cannot umount or remount it directly,
382 * since there is no way to refer to the
383 * underlying mount. There's nothing we can do
384 * about it for the general case, but we can
385 * do something about it if it is aliased
386 * somehwere else via a bind mount. If we
387 * explicitly remount the super block of that
388 * alias read-only we hence should be
389 * relatively safe regarding keeping the fs we
390 * can otherwise not see dirty. */
391 (void) mount(NULL
, m
->path
, NULL
, MS_REMOUNT
|MS_RDONLY
, NULL
);
394 /* Skip / and /usr since we cannot unmount that
395 * anyway, since we are running from it. They have
396 * already been remounted ro. */
397 if (path_equal(m
->path
, "/")
398 #ifndef HAVE_SPLIT_USR
399 || path_equal(m
->path
, "/usr")
404 /* Trying to umount. We don't force here since we rely
405 * on busy NFS and FUSE file systems to return EBUSY
406 * until we closed everything on top of them. */
407 log_info("Unmounting %s.", m
->path
);
408 if (umount2(m
->path
, 0) == 0) {
412 mount_point_free(head
, m
);
413 } else if (log_error
) {
414 log_warning_errno(errno
, "Could not unmount %s: %m", m
->path
);
422 static int swap_points_list_off(MountPoint
**head
, bool *changed
) {
428 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
429 log_info("Deactivating swap %s.", m
->path
);
430 if (swapoff(m
->path
) == 0) {
434 mount_point_free(head
, m
);
436 log_warning_errno(errno
, "Could not deactivate swap %s: %m", m
->path
);
444 static int loopback_points_list_detach(MountPoint
**head
, bool *changed
) {
451 k
= lstat("/", &root_st
);
453 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
455 struct stat loopback_st
;
458 major(root_st
.st_dev
) != 0 &&
459 lstat(m
->path
, &loopback_st
) >= 0 &&
460 root_st
.st_dev
== loopback_st
.st_rdev
) {
465 log_info("Detaching loopback %s.", m
->path
);
466 r
= delete_loopback(m
->path
);
468 if (r
> 0 && changed
)
471 mount_point_free(head
, m
);
473 log_warning_errno(errno
, "Could not detach loopback %s: %m", m
->path
);
481 static int dm_points_list_detach(MountPoint
**head
, bool *changed
) {
488 k
= lstat("/", &root_st
);
490 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
494 major(root_st
.st_dev
) != 0 &&
495 root_st
.st_dev
== m
->devnum
) {
500 log_info("Detaching DM %u:%u.", major(m
->devnum
), minor(m
->devnum
));
501 r
= delete_dm(m
->devnum
);
506 mount_point_free(head
, m
);
508 log_warning_errno(errno
, "Could not detach DM %s: %m", m
->path
);
516 int umount_all(bool *changed
) {
519 LIST_HEAD(MountPoint
, mp_list_head
);
521 LIST_HEAD_INIT(mp_list_head
);
522 r
= mount_points_list_get(&mp_list_head
);
526 /* retry umount, until nothing can be umounted anymore */
528 umount_changed
= false;
530 mount_points_list_umount(&mp_list_head
, &umount_changed
, false);
534 } while (umount_changed
);
536 /* umount one more time with logging enabled */
537 r
= mount_points_list_umount(&mp_list_head
, &umount_changed
, true);
542 mount_points_list_free(&mp_list_head
);
547 int swapoff_all(bool *changed
) {
549 LIST_HEAD(MountPoint
, swap_list_head
);
551 LIST_HEAD_INIT(swap_list_head
);
553 r
= swap_list_get(&swap_list_head
);
557 r
= swap_points_list_off(&swap_list_head
, changed
);
560 mount_points_list_free(&swap_list_head
);
565 int loopback_detach_all(bool *changed
) {
567 LIST_HEAD(MountPoint
, loopback_list_head
);
569 LIST_HEAD_INIT(loopback_list_head
);
571 r
= loopback_list_get(&loopback_list_head
);
575 r
= loopback_points_list_detach(&loopback_list_head
, changed
);
578 mount_points_list_free(&loopback_list_head
);
583 int dm_detach_all(bool *changed
) {
585 LIST_HEAD(MountPoint
, dm_list_head
);
587 LIST_HEAD_INIT(dm_list_head
);
589 r
= dm_list_get(&dm_list_head
);
593 r
= dm_points_list_detach(&dm_list_head
, changed
);
596 mount_points_list_free(&dm_list_head
);