Zbigniew Jędrzejewski-Szmek d4d36e
From 83492cce79c0cda1ea634abe4ad6519aa69e2fdc Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek d4d36e
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek d4d36e
Date: Wed, 7 Mar 2018 23:36:44 +0100
Zbigniew Jędrzejewski-Szmek d4d36e
Subject: [PATCH] basic/fs-util: skip fsync_directory_of_file() if
Zbigniew Jędrzejewski-Szmek d4d36e
 /proc/self/fd/ is not available
Zbigniew Jędrzejewski-Szmek d4d36e
Zbigniew Jędrzejewski-Szmek d4d36e
When systemd is running under lorax (in Fedora compose process), it'd think that
Zbigniew Jędrzejewski-Szmek d4d36e
it failed to write /etc/machine-id, even though the write succeeded, because
Zbigniew Jędrzejewski-Szmek d4d36e
fsync_directory_of_file() would fail, because /proc/self/fd/ is not available.
Zbigniew Jędrzejewski-Szmek d4d36e
fsync_directory_of_file() is mostly an additional safety net, so I think it's best
Zbigniew Jędrzejewski-Szmek d4d36e
to just silently ignore the error.
Zbigniew Jędrzejewski-Szmek d4d36e
Zbigniew Jędrzejewski-Szmek d4d36e
Strace of pid1:
Zbigniew Jędrzejewski-Szmek d4d36e
35791 stat("/etc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/etc/machine-id", O_RDWR|O_CREAT|O_NOCTTY|O_CLOEXEC, 0444) = 3
Zbigniew Jędrzejewski-Szmek d4d36e
35791 umask(022)                        = 000
Zbigniew Jędrzejewski-Szmek d4d36e
35791 read(3, "", 38)                   = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/var/lib/dbus/machine-id", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file o
Zbigniew Jędrzejewski-Szmek d4d36e
r directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/sys/class/dmi/id/product_name", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/sys/class/dmi/id/sys_vendor", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/sys/class/dmi/id/board_vendor", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/sys/class/dmi/id/bios_vendor", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 access("/proc/xen", F_OK)         = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/sys/hypervisor/type", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/proc/cpuinfo", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 getrandom("\xb8\x82\xed\xd4\x35\x11\xd0\xeb\xa6\x79\xd7\x31\x6e\x7b\x99\xce", 16, GRND_NONBLOCK) = 16
Zbigniew Jędrzejewski-Szmek d4d36e
35791 writev(2, [{iov_base="Initializing machine ID from random generator.", iov_len=46}, {iov_base="\n", iov_len=1}],
Zbigniew Jędrzejewski-Szmek d4d36e
 2) = 47
Zbigniew Jędrzejewski-Szmek d4d36e
35791 lseek(3, 0, SEEK_SET)             = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 ftruncate(3, 0)                   = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 write(3, "b882edd4351140eba679d7316e7b99ce\n", 33) = 33
Zbigniew Jędrzejewski-Szmek d4d36e
35791 fsync(3)                          = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 fstat(3, {st_mode=S_IFREG|0444, st_size=33, ...}) = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 readlinkat(AT_FDCWD, "/proc/self/fd/3", 0x564df8c694c0, 99) = -1 ENOENT (No such file or directory)
Zbigniew Jędrzejewski-Szmek d4d36e
35791 close(3)                          = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 umask(022)                        = 022
Zbigniew Jędrzejewski-Szmek d4d36e
35791 openat(AT_FDCWD, "/run/machine-id", O_WRONLY|O_CREAT|O_NOCTTY|O_TRUNC|O_CLOEXEC, 0444) = 3
Zbigniew Jędrzejewski-Szmek d4d36e
35791 write(3, "b882edd4351140eba679d7316e7b99ce\n", 33) = 33
Zbigniew Jędrzejewski-Szmek d4d36e
35791 close(3)                          = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 umask(022)                        = 022
Zbigniew Jędrzejewski-Szmek d4d36e
35791 mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL) = 0
Zbigniew Jędrzejewski-Szmek d4d36e
35791 writev(2, [{iov_base="Installed transient /etc/machine-id file.", iov_len=41}, {iov_base="\n", iov_len=1}], 2) = 42
Zbigniew Jędrzejewski-Szmek d4d36e
35791 mount(NULL, "/etc/machine-id", NULL, MS_RDONLY|MS_REMOUNT|MS_BIND, NULL) = 0
Zbigniew Jędrzejewski-Szmek d4d36e
Zbigniew Jędrzejewski-Szmek d4d36e
https://bugzilla.redhat.com/show_bug.cgi?id=1552843
Zbigniew Jędrzejewski-Szmek d4d36e
---
Zbigniew Jędrzejewski-Szmek d4d36e
 src/basic/fd-util.c | 15 +++++++++++----
Zbigniew Jędrzejewski-Szmek d4d36e
 src/basic/fs-util.c |  5 +++++
Zbigniew Jędrzejewski-Szmek d4d36e
 2 files changed, 16 insertions(+), 4 deletions(-)
Zbigniew Jędrzejewski-Szmek d4d36e
Zbigniew Jędrzejewski-Szmek d4d36e
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
Zbigniew Jędrzejewski-Szmek d4d36e
index 678ab12bb8..bb74f6c58e 100644
Zbigniew Jędrzejewski-Szmek d4d36e
--- a/src/basic/fd-util.c
Zbigniew Jędrzejewski-Szmek d4d36e
+++ b/src/basic/fd-util.c
Zbigniew Jędrzejewski-Szmek d4d36e
@@ -361,14 +361,21 @@ bool fdname_is_valid(const char *s) {
Zbigniew Jędrzejewski-Szmek d4d36e
 }
Zbigniew Jędrzejewski-Szmek d4d36e
 
Zbigniew Jędrzejewski-Szmek d4d36e
 int fd_get_path(int fd, char **ret) {
Zbigniew Jędrzejewski-Szmek d4d36e
-        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
Zbigniew Jędrzejewski-Szmek d4d36e
+        _cleanup_close_ int dir = -1;
Zbigniew Jędrzejewski-Szmek d4d36e
+        char fdname[DECIMAL_STR_MAX(int)];
Zbigniew Jędrzejewski-Szmek d4d36e
         int r;
Zbigniew Jędrzejewski-Szmek d4d36e
 
Zbigniew Jędrzejewski-Szmek d4d36e
-        xsprintf(procfs_path, "/proc/self/fd/%i", fd);
Zbigniew Jędrzejewski-Szmek d4d36e
+        dir = open("/proc/self/fd/", O_CLOEXEC | O_DIRECTORY | O_PATH);
Zbigniew Jędrzejewski-Szmek d4d36e
+        if (dir < 0)
Zbigniew Jędrzejewski-Szmek d4d36e
+                /* /proc is not available or not setup up properly, we're most likely
Zbigniew Jędrzejewski-Szmek d4d36e
+                 * in some chroot environment. */
Zbigniew Jędrzejewski-Szmek d4d36e
+                return -EOPNOTSUPP;
Zbigniew Jędrzejewski-Szmek d4d36e
 
Zbigniew Jędrzejewski-Szmek d4d36e
-        r = readlink_malloc(procfs_path, ret);
Zbigniew Jędrzejewski-Szmek d4d36e
+        xsprintf(fdname, "%i", fd);
Zbigniew Jędrzejewski-Szmek d4d36e
 
Zbigniew Jędrzejewski-Szmek d4d36e
-        if (r == -ENOENT) /* If the file doesn't exist the fd is invalid */
Zbigniew Jędrzejewski-Szmek d4d36e
+        r = readlinkat_malloc(dir, fdname, ret);
Zbigniew Jędrzejewski-Szmek d4d36e
+        if (r == -ENOENT)
Zbigniew Jędrzejewski-Szmek d4d36e
+                /* If the file doesn't exist the fd is invalid */
Zbigniew Jędrzejewski-Szmek d4d36e
                 return -EBADF;
Zbigniew Jędrzejewski-Szmek d4d36e
 
Zbigniew Jędrzejewski-Szmek d4d36e
         return r;
Zbigniew Jędrzejewski-Szmek d4d36e
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
Zbigniew Jędrzejewski-Szmek d4d36e
index 85c8070a1b..8d8d986082 100644
Zbigniew Jędrzejewski-Szmek d4d36e
--- a/src/basic/fs-util.c
Zbigniew Jędrzejewski-Szmek d4d36e
+++ b/src/basic/fs-util.c
Zbigniew Jędrzejewski-Szmek d4d36e
@@ -978,6 +978,11 @@ int fsync_directory_of_file(int fd) {
Zbigniew Jędrzejewski-Szmek d4d36e
                 return r;
Zbigniew Jędrzejewski-Szmek d4d36e
 
Zbigniew Jędrzejewski-Szmek d4d36e
         r = fd_get_path(fd, &path);
Zbigniew Jędrzejewski-Szmek d4d36e
+        if (r == -EOPNOTSUPP)
Zbigniew Jędrzejewski-Szmek d4d36e
+                /* If /proc is not available, we're most likely running in some
Zbigniew Jędrzejewski-Szmek d4d36e
+                 * chroot environment, and syncing the directory is not very
Zbigniew Jędrzejewski-Szmek d4d36e
+                 * important in that case. Let's just silently do nothing. */
Zbigniew Jędrzejewski-Szmek d4d36e
+                return 0;
Zbigniew Jędrzejewski-Szmek d4d36e
         if (r < 0)
Zbigniew Jędrzejewski-Szmek d4d36e
                 return r;
Zbigniew Jędrzejewski-Szmek d4d36e