summary refs log tree commit diff
path: root/src/platform/nm-linux-platform.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-10-20 22:07:24 +0200
committerMichael Biebl <biebl@debian.org>2020-10-20 22:07:24 +0200
commitf2ddac4cbc895837ddcc55015fae112f9859cd0a (patch)
tree774424baed3e65adb78c34e25874cf4e781ac005 /src/platform/nm-linux-platform.c
parentaafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (diff)
New upstream version 1.27.91 upstream/1.27.91
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 05125fa8..3fa70bbc 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,