summaryrefslogtreecommitdiff
path: root/src/platform/nm-linux-platform.c
diff options
context:
space:
mode:
authorAlfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>2020-10-05 18:43:21 +0200
committerThomas Haller <thaller@redhat.com>2020-10-06 19:01:24 +0200
commit9c8275bedcc98d789fa83d2817b9e8ff58f3e7b6 (patch)
tree9ea57ed2f5de3fe6e92bd20f9290e3745b4d8001 /src/platform/nm-linux-platform.c
parent441f9b3c14cf7bb2c4d31049a27512a0b207c2b6 (diff)
downloadNetworkManager-9c8275bedcc98d789fa83d2817b9e8ff58f3e7b6.tar.gz
platform: use also statvfs() to check for udevd
Check whether or not there is a running udevd by using statvfs() on "/sys" and use access() as a fallback. This is in line with what is done by systemd [1] and helps in case NM is not really running in a container but has been confined by a MAC so it does not have full access to sysfs (access() returns EACCES). [1] https://github.com/systemd/systemd/blob/v246/src/basic/stat-util.c#L132 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/639
Diffstat (limited to 'src/platform/nm-linux-platform.c')
-rw-r--r--src/platform/nm-linux-platform.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 05125fa836..3fa70bbc30 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -26,6 +26,7 @@
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/statvfs.h>
#include <unistd.h>
#include "nm-std-aux/unaligned.h"
@@ -9523,12 +9524,34 @@ constructed(GObject *_object)
}
}
+/* Similar to systemd's path_is_read_only_fs(), at
+ * https://github.com/systemd/systemd/blob/v246/src/basic/stat-util.c#L132 */
+static int
+path_is_read_only_fs(const char *path)
+{
+ struct statvfs st;
+
+ if (statvfs(path, &st) < 0)
+ return -errno;
+
+ if (st.f_flag & ST_RDONLY)
+ return TRUE;
+
+ /* On NFS, statvfs() might not reflect whether we can actually
+ * write to the remote share. Let's try again with
+ * access(W_OK) which is more reliable, at least sometimes. */
+ if (access(path, W_OK) < 0 && errno == EROFS)
+ return TRUE;
+
+ return FALSE;
+}
+
NMPlatform *
nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support)
{
gboolean use_udev = FALSE;
- if (nmp_netns_is_initial() && access("/sys", W_OK) == 0)
+ if (nmp_netns_is_initial() && path_is_read_only_fs("/sys") == FALSE)
use_udev = TRUE;
return g_object_new(NM_TYPE_LINUX_PLATFORM,