remount-fs: port to libmount parser

This commit is contained in:
Mike Yuan
2025-09-18 20:25:15 +02:00
parent 7ebb2b3349
commit 9d05015bb9
2 changed files with 26 additions and 16 deletions
+1
View File
@@ -4,5 +4,6 @@ executables += [
libexec_template + {
'name' : 'systemd-remount-fs',
'sources' : files('remount-fs.c'),
'dependencies' : libmount,
},
]
+25 -16
View File
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <mntent.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -11,6 +10,7 @@
#include "format-util.h"
#include "fstab-util.h"
#include "hashmap.h"
#include "libmount-util.h"
#include "log.h"
#include "main-func.h"
#include "mount-setup.h"
@@ -70,10 +70,10 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) {
}
static int remount_by_fstab(Hashmap **ret_pids) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
_cleanup_hashmap_free_ Hashmap *pids = NULL;
_cleanup_endmntent_ FILE *f = NULL;
bool has_root = false;
struct mntent* me;
int r;
assert(ret_pids);
@@ -81,24 +81,33 @@ static int remount_by_fstab(Hashmap **ret_pids) {
if (!fstab_enabled())
return 0;
f = setmntent(fstab_path(), "re");
if (!f) {
if (errno != ENOENT)
return log_error_errno(errno, "Failed to open %s: %m", fstab_path());
r = libmount_parse_fstab(&table, &iter);
if (r == -ENOENT)
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to parse fstab: %m");
while ((me = getmntent(f))) {
/* Remount the root fs, /usr, and all API VFSs */
if (!mount_point_is_api(me->mnt_dir) &&
!PATH_IN_SET(me->mnt_dir, "/", "/usr"))
for (;;) {
struct libmnt_fs *fs;
r = mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return log_error_errno(r, "Failed to get next entry from fstab: %m");
if (r > 0) /* EOF */
break;
const char *target = mnt_fs_get_target(fs);
if (!target)
continue;
if (path_equal(me->mnt_dir, "/"))
has_root = true;
/* Remount the root fs, /usr/, and all API VFSs */
r = do_remount(me->mnt_dir, /* force_rw = */ false, &pids);
if (path_equal(target, "/"))
has_root = true;
else if (!path_equal(target, "/usr") && !mount_point_is_api(target))
continue;
r = do_remount(target, /* force_rw = */ false, &pids);
if (r < 0)
return r;
}