1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-19 22:50:17 +03:00

fstab-util: port use of setmntent() and friends to libmount (#36489)

This commit is contained in:
Daan De Meyer 2025-02-23 12:21:19 +01:00 committed by GitHub
commit 012fd82d43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 39 deletions

View File

@ -8,8 +8,8 @@
#include "device-nodes.h"
#include "fstab-util.h"
#include "initrd-util.h"
#include "libmount-util.h"
#include "macro.h"
#include "mount-util.h"
#include "nulstr-util.h"
#include "parse-util.h"
#include "path-util.h"
@ -37,28 +37,33 @@ bool fstab_enabled_full(int enabled) {
}
int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
assert(fstype);
if (!fstab_enabled())
return false;
f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
r = libmount_parse_fstab(&table, &iter);
if (r == -ENOENT)
return false;
if (r < 0)
return r;
for (;;) {
errno = 0;
m = getmntent(f);
if (!m)
return errno != 0 ? -errno : false;
struct libmnt_fs *fs;
if (streq(m->mnt_type, fstype))
r = mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return r;
if (r > 0) /* EOF */
return false;
if (streq_ptr(mnt_fs_get_fstype(fs), fstype))
return true;
}
return false;
}
bool fstab_is_extrinsic(const char *mount, const char *opts) {
@ -105,10 +110,12 @@ static int fstab_is_same_node(const char *what_fstab, const char *path) {
return false;
}
int fstab_has_mount_point_prefix_strv(char **prefixes) {
_cleanup_endmntent_ FILE *f = NULL;
int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
assert(prefixes);
assert(!strv_isempty(prefixes));
/* This function returns true if at least one entry in fstab has a mount point that starts with one
* of the passed prefixes. */
@ -116,25 +123,34 @@ int fstab_has_mount_point_prefix_strv(char **prefixes) {
if (!fstab_enabled())
return false;
f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
r = libmount_parse_fstab(&table, &iter);
if (r == -ENOENT)
return false;
if (r < 0)
return r;
for (;;) {
struct mntent *me;
struct libmnt_fs *fs;
const char *path;
errno = 0;
me = getmntent(f);
if (!me)
return errno != 0 ? -errno : false;
r = mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return r;
if (r > 0) /* EOF */
return false;
if (path_startswith_strv(me->mnt_dir, prefixes))
path = mnt_fs_get_target(fs);
if (!path)
continue;
if (path_startswith_strv(path, prefixes))
return true;
}
}
int fstab_is_mount_point_full(const char *where, const char *path) {
_cleanup_endmntent_ FILE *f = NULL;
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
assert(where || path);
@ -142,25 +158,28 @@ int fstab_is_mount_point_full(const char *where, const char *path) {
if (!fstab_enabled())
return false;
f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
r = libmount_parse_fstab(&table, &iter);
if (r == -ENOENT)
return false;
if (r < 0)
return r;
for (;;) {
struct mntent *me;
struct libmnt_fs *fs;
errno = 0;
me = getmntent(f);
if (!me)
return errno != 0 ? -errno : false;
r = mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return r;
if (r > 0) /* EOF */
return false;
if (where && !path_equal(where, me->mnt_dir))
if (where && !path_equal(mnt_fs_get_target(fs), where))
continue;
if (!path)
return true;
r = fstab_is_same_node(me->mnt_fsname, path);
r = fstab_is_same_node(mnt_fs_get_source(fs), path);
if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r)))
return r;
}
@ -235,9 +254,11 @@ int fstab_filter_options(
return r;
}
filtered = strv_join_full(filtered_strv, ",", NULL, /* escape_separator = */ true);
if (!filtered)
return -ENOMEM;
if (ret_filtered) {
filtered = strv_join_full(filtered_strv, ",", NULL, /* escape_separator = */ true);
if (!filtered)
return -ENOMEM;
}
} else
for (const char *word = opts;;) {
const char *end = word;

View File

@ -25,7 +25,7 @@ static inline int fstab_has_node(const char *path) {
return fstab_is_mount_point_full(NULL, path);
}
int fstab_has_mount_point_prefix_strv(char **prefixes);
int fstab_has_mount_point_prefix_strv(char * const *prefixes);
int fstab_filter_options(
const char *opts,

View File

@ -4,6 +4,7 @@
/* This needs to be after sys/mount.h */
#include <libmount.h>
#include "fstab-util.h"
#include "macro.h"
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_table*, mnt_free_table, NULL);
@ -30,6 +31,13 @@ static inline int libmount_parse_with_utab(
return libmount_parse_full(NULL, NULL, ret_table, ret_iter);
}
static inline int libmount_parse_fstab(
struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) {
return libmount_parse_full(fstab_path(), NULL, ret_table, ret_iter);
}
int libmount_is_leaf(
struct libmnt_table *table,
struct libmnt_fs *fs);