Blob Blame History Raw
From 80c5811980c745c373351e52a85f3f847fe08d7b Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Mon, 5 Feb 2018 13:12:44 -0500
Subject: [PATCH] postprocess: Special case NFS state files

Currently in RHELAH 7.4, `systemctl start nfs` fails because we've dropped
`/var/lib/nfs/etab` at least:
https://bugzilla.redhat.com/show_bug.cgi?id=1427537

Things appear to work in Fedora 27 Atomic Host; there's been a lot of changes in
upstream nfs-utils in this area. I didn't fully try to analyze all of them, but
I am guessing it's
http://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=8e98eed42b64aa388c09716e3276a53028a839bf
that made things work here.

For now let's just special case these.  I debated having it in a RHEL-only
build but I often do RHELAH treecomposes from my Fedora dev container, and
eh...I think let's ask the RHEL nfs-utils maintainer to backport the patches
to make this work, then we can drop our hack.

Closes: #1229
Approved by: jlebon
---
 src/libpriv/rpmostree-postprocess.c | 40 +++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/src/libpriv/rpmostree-postprocess.c b/src/libpriv/rpmostree-postprocess.c
index 7e9cde3d..71513134 100644
--- a/src/libpriv/rpmostree-postprocess.c
+++ b/src/libpriv/rpmostree-postprocess.c
@@ -462,12 +462,20 @@ convert_var_to_tmpfiles_d_recurse (GOutputStream *tmpfiles_out,
         case DT_LNK:
           filetype_c = 'L';
           break;
+        case DT_REG:
+          /* nfs-utils in RHEL7; https://bugzilla.redhat.com/show_bug.cgi?id=1427537 */
+          if (g_str_has_prefix (prefix->str, "/var/lib/nfs"))
+            {
+              filetype_c = 'f';
+              break;
+            }
+          /* Fallthrough */
         default:
+          if (!glnx_unlinkat (dfd_iter.fd, dent->d_name, 0, error))
+            return FALSE;
           g_print ("Ignoring non-directory/non-symlink '%s/%s'\n",
                    prefix->str,
                    dent->d_name);
-          if (!glnx_unlinkat (dfd_iter.fd, dent->d_name, 0, error))
-            return FALSE;
           continue;
         }
 
@@ -478,7 +486,7 @@ convert_var_to_tmpfiles_d_recurse (GOutputStream *tmpfiles_out,
       g_string_append_c (tmpfiles_d_buf, '/');
       g_string_append (tmpfiles_d_buf, dent->d_name);
 
-      if (filetype_c == 'd')
+      if (filetype_c == 'd' || filetype_c == 'f')
         {
           struct stat stbuf;
           if (!glnx_fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error))
@@ -493,20 +501,20 @@ convert_var_to_tmpfiles_d_recurse (GOutputStream *tmpfiles_out,
             return glnx_throw (error, "Failed to find group '%u' for %s", stbuf.st_gid, dent->d_name);
           g_string_append_printf (tmpfiles_d_buf, " %s %s - -", user, group);
 
-          /* Push prefix */
-          g_string_append_c (prefix, '/');
-          g_string_append (prefix, dent->d_name);
+          if (filetype_c == 'd')
+            {
+              /* Push prefix */
+              gsize prev_len = prefix->len;
+              g_string_append_c (prefix, '/');
+              g_string_append (prefix, dent->d_name);
 
-          if (!convert_var_to_tmpfiles_d_recurse (tmpfiles_out, dfd, pwdb, prefix,
-                                                  cancellable, error))
-            return FALSE;
+              if (!convert_var_to_tmpfiles_d_recurse (tmpfiles_out, dfd, pwdb, prefix,
+                                                      cancellable, error))
+                return FALSE;
 
-          /* Pop prefix */
-          {
-            char *r = memrchr (prefix->str, '/', prefix->len);
-            g_assert (r != NULL);
-            g_string_truncate (prefix, r - prefix->str);
-          }
+              /* Pop prefix */
+              g_string_truncate (prefix, prev_len);
+            }
         }
       else
         {
@@ -538,6 +546,8 @@ convert_var_to_tmpfiles_d (int            rootfs_dfd,
                            GCancellable  *cancellable,
                            GError       **error)
 {
+  GLNX_AUTO_PREFIX_ERROR ("Converting /var to tmpfiles.d", error);
+
   g_autoptr(RpmOstreePasswdDB) pwdb = rpmostree_passwddb_open (rootfs_dfd, cancellable, error);
   if (!pwdb)
     return FALSE;
-- 
2.14.3