From d49d95df0a260aaca9a3fdd1e6ce535592a53bca Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 6 Nov 2024 04:37:55 +0900 Subject: [PATCH 1/2] mount-util: introduce path_is_network_fs_harder() It also detects e.g. glusterfs or mounts with "_netdev" option. --- src/shared/mount-util.c | 68 ++++++++++++++++++++++++++++++++++++++ src/shared/mount-util.h | 2 ++ src/test/test-mount-util.c | 7 ++++ 3 files changed, 77 insertions(+) diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 3c89a18790..8ef952a035 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -19,6 +19,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "fstab-util.h" #include "glyph-util.h" #include "hashmap.h" #include "initrd-util.h" @@ -1820,3 +1821,70 @@ char* umount_and_unlink_and_free(char *p) { (void) unlink(p); return mfree(p); } + +static int path_get_mount_info( + const char *path, + char **ret_fstype, + char **ret_options) { + + _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; + _cleanup_free_ char *fstype = NULL, *options = NULL; + struct libmnt_fs *fs; + int r; + + assert(path); + + table = mnt_new_table(); + if (!table) + return -ENOMEM; + + r = mnt_table_parse_mtab(table, /* filename = */ NULL); + if (r < 0) + return r; + + fs = mnt_table_find_mountpoint(table, path, MNT_ITER_FORWARD); + if (!fs) + return -EINVAL; + + if (ret_fstype) { + fstype = strdup(strempty(mnt_fs_get_fstype(fs))); + if (!fstype) + return -ENOMEM; + } + + if (ret_options) { + options = strdup(strempty(mnt_fs_get_options(fs))); + if (!options) + return -ENOMEM; + } + + if (ret_fstype) + *ret_fstype = TAKE_PTR(fstype); + if (ret_options) + *ret_options = TAKE_PTR(options); + + return 0; +} + +int path_is_network_fs_harder(const char *path) { + _cleanup_free_ char *fstype = NULL, *options = NULL; + int r, ret; + + assert(path); + + ret = path_is_network_fs(path); + if (ret > 0) + return true; + + r = path_get_mount_info(path, &fstype, &options); + if (r < 0) + return RET_GATHER(ret, r); + + if (fstype_is_network(fstype)) + return true; + + if (fstab_test_option(options, "_netdev\0")) + return true; + + return false; +} diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index eb068d5b44..067ed0e4d9 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -180,3 +180,5 @@ unsigned long credentials_fs_mount_flags(bool ro); int mount_credentials_fs(const char *path, size_t size, bool ro); int make_fsmount(int error_log_level, const char *what, const char *type, unsigned long flags, const char *options, int userns_fd); + +int path_is_network_fs_harder(const char *path); diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c index 4f6da39f48..28d171de33 100644 --- a/src/test/test-mount-util.c +++ b/src/test/test-mount-util.c @@ -537,4 +537,11 @@ TEST(bind_mount_submounts) { assert_se(umount_recursive(b, 0) >= 0); } +TEST(path_is_network_fs_harder) { + ASSERT_OK(path_is_network_fs_harder("/")); + ASSERT_OK_ZERO(path_is_network_fs_harder("/dev")); + ASSERT_OK_ZERO(path_is_network_fs_harder("/sys")); + ASSERT_OK_ZERO(path_is_network_fs_harder("/run")); +} + DEFINE_TEST_MAIN(LOG_DEBUG); From c0323de6cab40a443964047c31620cb265d79b75 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 6 Nov 2024 04:42:16 +0900 Subject: [PATCH 2/2] network: use path_is_network_fs_harder() Closes #32426. --- src/network/networkd-manager.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 476e02fd28..38013994c8 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -31,6 +31,7 @@ #include "fs-util.h" #include "initrd-util.h" #include "local-addresses.h" +#include "mount-util.h" #include "netlink-util.h" #include "network-internal.h" #include "networkd-address-label.h" @@ -59,7 +60,6 @@ #include "selinux-util.h" #include "set.h" #include "signal-util.h" -#include "stat-util.h" #include "strv.h" #include "sysctl-util.h" #include "tclass.h" @@ -508,9 +508,11 @@ static int manager_set_keep_configuration(Manager *m) { return 0; } - r = path_is_network_fs("/"); - if (r < 0) - return log_error_errno(r, "Failed to detect if root is network filesystem: %m"); + r = path_is_network_fs_harder("/"); + if (r < 0) { + log_warning_errno(r, "Failed to detect if root is network filesystem, assuming not: %m"); + return 0; + } if (r == 0) { m->keep_configuration = _KEEP_CONFIGURATION_INVALID; return 0;