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