mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
There is a case that confuses systemd-shutdown: a filesystem has been moved to a mount point which is part of another filesystem from an image from that former filesystem. systemd-shutdown cannot unmount any of those two filesystems. It needs first to move the filesystem containing the image of the other out of the tree of that image. Here we move leaf mount points when they are busy so that they do not block parent mounts. We can only move leafs at each iteration since moving mount points also move sub mount points which would invalidate we read from `/proc/self/mountinfo`.
60 lines
1.7 KiB
C
60 lines
1.7 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "libmount-util.h"
|
|
|
|
int libmount_parse(
|
|
const char *path,
|
|
FILE *source,
|
|
struct libmnt_table **ret_table,
|
|
struct libmnt_iter **ret_iter) {
|
|
|
|
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
int r;
|
|
|
|
/* Older libmount seems to require this. */
|
|
assert(!source || path);
|
|
|
|
table = mnt_new_table();
|
|
iter = mnt_new_iter(MNT_ITER_FORWARD);
|
|
if (!table || !iter)
|
|
return -ENOMEM;
|
|
|
|
/* If source or path are specified, we use on the functions which ignore utab.
|
|
* Only if both are empty, we use mnt_table_parse_mtab(). */
|
|
|
|
if (source)
|
|
r = mnt_table_parse_stream(table, source, path);
|
|
else if (path)
|
|
r = mnt_table_parse_file(table, path);
|
|
else
|
|
r = mnt_table_parse_mtab(table, NULL);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
*ret_table = TAKE_PTR(table);
|
|
*ret_iter = TAKE_PTR(iter);
|
|
return 0;
|
|
}
|
|
|
|
int libmount_is_leaf(
|
|
struct libmnt_table *table,
|
|
struct libmnt_fs *fs) {
|
|
int r;
|
|
|
|
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter_children = NULL;
|
|
iter_children = mnt_new_iter(MNT_ITER_FORWARD);
|
|
if (!iter_children)
|
|
return log_oom();
|
|
|
|
/* We care only whether it exists, it is unused */
|
|
_unused_ struct libmnt_fs *child;
|
|
r = mnt_table_next_child_fs(table, iter_children, fs, &child);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
return r == 1;
|
|
}
|