summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-11-05 20:37:55 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-11-05 20:58:55 +0100
commitd49d95df0a260aaca9a3fdd1e6ce535592a53bca (patch)
tree2e6c0d39f73c2ddea296ccad63ad81b1bf31df09
parenttree-wide: time-out → timeout (diff)
downloadsystemd-d49d95df0a260aaca9a3fdd1e6ce535592a53bca.tar.xz
systemd-d49d95df0a260aaca9a3fdd1e6ce535592a53bca.zip
mount-util: introduce path_is_network_fs_harder()
It also detects e.g. glusterfs or mounts with "_netdev" option.
-rw-r--r--src/shared/mount-util.c68
-rw-r--r--src/shared/mount-util.h2
-rw-r--r--src/test/test-mount-util.c7
3 files changed, 77 insertions, 0 deletions
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);