- Make rpmfiConfigConflict() consider any existing %ghost %config
as "modified". This causes them to be left alone on erasure to match
long-standing rpm behavior (whether the behavior is intended or not...)
Ghost config testcase passes again, talk about flip-flop. Sigh.
- Legacy behavior had an extra twist which we are intentionally NOT
restoring: if a non-empty %ghost exists at build-time, its digest
is stored in the header despite the file not being present in
the payload. With previous versions of rpm, the contents of an
existing %ghost %config would be compared to the one in header and
resulting in different behavior on erasure: if the contents matched
that of build-time, the file would be removed, otherwise it would
be preserved. Ghosts remembering their identity from previous life
goes a little bit too far into the land of paranormal for me...
(cherry picked from commit
233e4573d1d21a36d06874fea6c594428033802e)
struct stat sb;
int rc = 0;
- /* Non-configs and ghosts are not config conflicts. */
- if (!(flags & RPMFILE_CONFIG) || (flags & RPMFILE_GHOST))
+ /* Non-configs are not config conflicts. */
+ if (!(flags & RPMFILE_CONFIG))
return 0;
/* Only links and regular files can be %config, this is kinda moot */
if (lstat(fn, &sb))
goto exit;
+ /*
+ * Preserve legacy behavior: an existing %ghost %config is considered
+ * "modified" but unlike regular %config, its never removed and
+ * never backed up. Whether this actually makes sense is a whole
+ * another question, but this is very long-standing behavior that
+ * people might be depending on. The resulting FA_ALTNAME etc action
+ * is special-cased in FSM to avoid actually creating backups on ghosts.
+ */
+ if (flags & RPMFILE_GHOST) {
+ rc = 1;
+ goto exit;
+ }
+
/* Files of different types obviously are not identical */
diskWhat = rpmfiWhatis((rpm_mode_t)sb.st_mode);
if (diskWhat != newWhat) {