2 This file is part of systemd.
4 Copyright 2010 ProFUSION embedded systems
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <linux/loop.h>
24 #include <sys/mount.h>
29 #include "alloc-util.h"
32 #include "fstab-util.h"
33 #include "linux-3.13/dm-ioctl.h"
35 #include "mount-setup.h"
36 #include "path-util.h"
37 #include "string-util.h"
38 #include "udev-util.h"
40 #include "mount-util.h"
44 typedef struct MountPoint
{
49 LIST_FIELDS(struct MountPoint
, mount_point
);
52 static void mount_point_free(MountPoint
**head
, MountPoint
*m
) {
56 LIST_REMOVE(mount_point
, *head
, m
);
62 static void mount_points_list_free(MountPoint
**head
) {
66 mount_point_free(head
, *head
);
69 static int mount_points_list_get(MountPoint
**head
) {
70 _cleanup_fclose_
FILE *proc_self_mountinfo
= NULL
;
76 proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
77 if (!proc_self_mountinfo
)
81 _cleanup_free_
char *path
= NULL
, *options
= NULL
, *type
= NULL
;
86 k
= fscanf(proc_self_mountinfo
,
87 "%*s " /* (1) mount id */
88 "%*s " /* (2) parent id */
89 "%*s " /* (3) major:minor */
91 "%ms " /* (5) mount point */
92 "%*s" /* (6) mount flags */
93 "%*[^-]" /* (7) optional fields */
94 "- " /* (8) separator */
95 "%ms " /* (9) file system type */
96 "%*s" /* (10) mount source */
97 "%ms" /* (11) mount options */
98 "%*[^\n]", /* some rubbish at the end */
99 &path
, &type
, &options
);
104 log_warning("Failed to parse /proc/self/mountinfo:%u.", i
);
108 r
= cunescape(path
, UNESCAPE_RELAX
, &p
);
112 /* Ignore mount points we can't unmount because they
113 * are API or because we are keeping them open (like
114 * /dev/console). Also, ignore all mounts below API
115 * file systems, since they are likely virtual too,
116 * and hence not worth spending time on. Also, in
117 * unprivileged containers we might lack the rights to
118 * unmount these things, hence don't bother. */
119 if (mount_point_is_api(p
) ||
120 mount_point_ignore(p
) ||
121 path_startswith(p
, "/dev") ||
122 path_startswith(p
, "/sys") ||
123 path_startswith(p
, "/proc")) {
128 m
= new0(MountPoint
, 1);
135 m
->options
= options
;
140 LIST_PREPEND(mount_point
, *head
, m
);
146 static int swap_list_get(MountPoint
**head
) {
147 _cleanup_fclose_
FILE *proc_swaps
= NULL
;
153 proc_swaps
= fopen("/proc/swaps", "re");
155 return (errno
== ENOENT
) ? 0 : -errno
;
157 (void) fscanf(proc_swaps
, "%*s %*s %*s %*s %*s\n");
161 char *dev
= NULL
, *d
;
164 k
= fscanf(proc_swaps
,
165 "%ms " /* device/file */
166 "%*s " /* type of swap */
167 "%*s " /* swap size */
169 "%*s\n", /* priority */
176 log_warning("Failed to parse /proc/swaps:%u.", i
);
181 if (endswith(dev
, " (deleted)")) {
186 r
= cunescape(dev
, UNESCAPE_RELAX
, &d
);
191 swap
= new0(MountPoint
, 1);
198 LIST_PREPEND(mount_point
, *head
, swap
);
204 static int loopback_list_get(MountPoint
**head
) {
205 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
206 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
207 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
216 e
= udev_enumerate_new(udev
);
220 r
= udev_enumerate_add_match_subsystem(e
, "block");
224 r
= udev_enumerate_add_match_sysname(e
, "loop*");
228 r
= udev_enumerate_add_match_sysattr(e
, "loop/backing_file", NULL
);
232 r
= udev_enumerate_scan_devices(e
);
236 first
= udev_enumerate_get_list_entry(e
);
237 udev_list_entry_foreach(item
, first
) {
239 _cleanup_udev_device_unref_
struct udev_device
*d
;
243 d
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
247 dn
= udev_device_get_devnode(d
);
255 lb
= new0(MountPoint
, 1);
262 LIST_PREPEND(mount_point
, *head
, lb
);
268 static int dm_list_get(MountPoint
**head
) {
269 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
270 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
271 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
280 e
= udev_enumerate_new(udev
);
284 r
= udev_enumerate_add_match_subsystem(e
, "block");
288 r
= udev_enumerate_add_match_sysname(e
, "dm-*");
292 r
= udev_enumerate_scan_devices(e
);
296 first
= udev_enumerate_get_list_entry(e
);
297 udev_list_entry_foreach(item
, first
) {
299 _cleanup_udev_device_unref_
struct udev_device
*d
;
304 d
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
308 devnum
= udev_device_get_devnum(d
);
309 dn
= udev_device_get_devnode(d
);
310 if (major(devnum
) == 0 || !dn
)
317 m
= new(MountPoint
, 1);
325 LIST_PREPEND(mount_point
, *head
, m
);
331 static int delete_loopback(const char *device
) {
332 _cleanup_close_
int fd
= -1;
335 fd
= open(device
, O_RDONLY
|O_CLOEXEC
);
337 return errno
== ENOENT
? 0 : -errno
;
339 r
= ioctl(fd
, LOOP_CLR_FD
, 0);
343 /* ENXIO: not bound, so no error */
350 static int delete_dm(dev_t devnum
) {
352 struct dm_ioctl dm
= {
356 DM_VERSION_PATCHLEVEL
358 .data_size
= sizeof(dm
),
362 _cleanup_close_
int fd
= -1;
364 assert(major(devnum
) != 0);
366 fd
= open("/dev/mapper/control", O_RDWR
|O_CLOEXEC
);
370 if (ioctl(fd
, DM_DEV_REMOVE
, &dm
) < 0)
376 static bool nonunmountable_path(const char *path
) {
377 return path_equal(path
, "/")
379 || path_equal(path
, "/usr")
381 || path_startswith(path
, "/run/initramfs");
384 static int mount_points_list_umount(MountPoint
**head
, bool *changed
, bool log_error
) {
390 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
392 /* If we are in a container, don't attempt to
393 read-only mount anything as that brings no real
394 benefits, but might confuse the host, as we remount
395 the superblock here, not the bind mount.
396 If the filesystem is a network fs, also skip the
397 remount. It brings no value (we cannot leave
398 a "dirty fs") and could hang if the network is down. */
399 if (detect_container() <= 0 &&
400 !fstype_is_network(m
->type
)) {
401 _cleanup_free_
char *options
= NULL
;
402 /* MS_REMOUNT requires that the data parameter
403 * should be the same from the original mount
404 * except for the desired changes. Since we want
405 * to remount read-only, we should filter out
406 * rw (and ro too, because it confuses the kernel) */
407 (void) fstab_filter_options(m
->options
, "rw\0ro\0", NULL
, NULL
, &options
);
409 /* We always try to remount directories
410 * read-only first, before we go on and umount
413 * Mount points can be stacked. If a mount
414 * point is stacked below / or /usr, we
415 * cannot umount or remount it directly,
416 * since there is no way to refer to the
417 * underlying mount. There's nothing we can do
418 * about it for the general case, but we can
419 * do something about it if it is aliased
420 * somehwere else via a bind mount. If we
421 * explicitly remount the super block of that
422 * alias read-only we hence should be
423 * relatively safe regarding keeping dirty an fs
424 * we cannot otherwise see. */
425 log_info("Remounting '%s' read-only with options '%s'.", m
->path
, options
);
426 if (mount(NULL
, m
->path
, NULL
, MS_REMOUNT
|MS_RDONLY
, options
) < 0) {
428 log_notice_errno(errno
, "Failed to remount '%s' read-only: %m", m
->path
);
429 if (nonunmountable_path(m
->path
))
434 /* Skip / and /usr since we cannot unmount that
435 * anyway, since we are running from it. They have
436 * already been remounted ro. */
437 if (nonunmountable_path(m
->path
))
440 /* Trying to umount. We don't force here since we rely
441 * on busy NFS and FUSE file systems to return EBUSY
442 * until we closed everything on top of them. */
443 log_info("Unmounting %s.", m
->path
);
444 if (umount2(m
->path
, 0) == 0) {
448 mount_point_free(head
, m
);
451 log_warning_errno(errno
, "Could not unmount %s: %m", m
->path
);
459 static int swap_points_list_off(MountPoint
**head
, bool *changed
) {
465 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
466 log_info("Deactivating swap %s.", m
->path
);
467 if (swapoff(m
->path
) == 0) {
471 mount_point_free(head
, m
);
473 log_warning_errno(errno
, "Could not deactivate swap %s: %m", m
->path
);
481 static int loopback_points_list_detach(MountPoint
**head
, bool *changed
) {
488 k
= lstat("/", &root_st
);
490 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
492 struct stat loopback_st
;
495 major(root_st
.st_dev
) != 0 &&
496 lstat(m
->path
, &loopback_st
) >= 0 &&
497 root_st
.st_dev
== loopback_st
.st_rdev
) {
502 log_info("Detaching loopback %s.", m
->path
);
503 r
= delete_loopback(m
->path
);
505 if (r
> 0 && changed
)
508 mount_point_free(head
, m
);
510 log_warning_errno(errno
, "Could not detach loopback %s: %m", m
->path
);
518 static int dm_points_list_detach(MountPoint
**head
, bool *changed
) {
525 r
= get_block_device("/", &rootdev
);
529 LIST_FOREACH_SAFE(mount_point
, m
, n
, *head
) {
531 if (major(rootdev
) != 0)
532 if (rootdev
== m
->devnum
) {
537 log_info("Detaching DM %u:%u.", major(m
->devnum
), minor(m
->devnum
));
538 r
= delete_dm(m
->devnum
);
543 mount_point_free(head
, m
);
545 log_warning_errno(errno
, "Could not detach DM %s: %m", m
->path
);
553 int umount_all(bool *changed
) {
556 LIST_HEAD(MountPoint
, mp_list_head
);
558 LIST_HEAD_INIT(mp_list_head
);
559 r
= mount_points_list_get(&mp_list_head
);
563 /* retry umount, until nothing can be umounted anymore */
565 umount_changed
= false;
567 mount_points_list_umount(&mp_list_head
, &umount_changed
, false);
571 } while (umount_changed
);
573 /* umount one more time with logging enabled */
574 r
= mount_points_list_umount(&mp_list_head
, &umount_changed
, true);
579 mount_points_list_free(&mp_list_head
);
584 int swapoff_all(bool *changed
) {
586 LIST_HEAD(MountPoint
, swap_list_head
);
588 LIST_HEAD_INIT(swap_list_head
);
590 r
= swap_list_get(&swap_list_head
);
594 r
= swap_points_list_off(&swap_list_head
, changed
);
597 mount_points_list_free(&swap_list_head
);
602 int loopback_detach_all(bool *changed
) {
604 LIST_HEAD(MountPoint
, loopback_list_head
);
606 LIST_HEAD_INIT(loopback_list_head
);
608 r
= loopback_list_get(&loopback_list_head
);
612 r
= loopback_points_list_detach(&loopback_list_head
, changed
);
615 mount_points_list_free(&loopback_list_head
);
620 int dm_detach_all(bool *changed
) {
622 LIST_HEAD(MountPoint
, dm_list_head
);
624 LIST_HEAD_INIT(dm_list_head
);
626 r
= dm_list_get(&dm_list_head
);
630 r
= dm_points_list_detach(&dm_list_head
, changed
);
633 mount_points_list_free(&dm_list_head
);