Bug 2223220

Summary: Cannot install texlive-base if multimarkdown is installed (infinite loop in scriptlet)
Product: [Fedora] Fedora Reporter: Stewart Smith <trawets>
Component: texlive-baseAssignee: Tom "spot" Callaway <spotrh>
Status: NEW --- QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: urgent Docs Contact:
Priority: unspecified    
Version: 38CC: spotrh, than
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Stewart Smith 2023-07-16 20:13:56 UTC
When constructing a container with multiple layers, one of which installs `multimarkdown`, and the subsequent one tries to install `texlive-base`, the scriptlet in texlive-base enters an infinite loop, uses 100% CPU in DNF and never installs the package.

If you try and install both of them in one transaction, it succeeds, although the texlive-base scriptlet is run first in that scenario.

Reproducible: Always

Steps to Reproduce:
1. Create a Dockerfile with the following three lines:
FROM fedora
RUN dnf install -y multimarkdown
RUN dnf install -y texlive-base
2. mkdir /tmp/empty
3. podman build -f Dockerfile /tmp/empty
4 Note how it gets stuck at "running scriptlet" for texlive-base.

I have reproduced on ppc64le with a fedora 38 host. I have not managed to narrow down if this is container specific or not, nor if it is somewhat architecture specific.

It appears to also reproduce with docker rather than podman too.
Actual Results:  
"Running scriptlet: texlive-base-10:20220321-72.fc38.ppc64le" hangs, with `dnf` consuming 100% in a loop that indicates the scriptlet is stuck in an infinite loop of attempting to do the rename:

newfstatat(AT_FDCWD, "/usr/share/texmf", {st_mode=S_IFDIR|0755, st_size=17, ...}, AT_SYMLINK_NOFOLLOW) = 0
rename("/usr/share/texmf", "/usr/share/texmf.rpmmoved") = -1 EXDEV (Invalid cross-device link)
rename("/usr/share/texmf.rpmmoved", "/usr/share/texmf.rpmmoved.1") = -1 ENOENT (No such file or directory)
rename("/usr/share/texmf.rpmmoved", "/usr/share/texmf.rpmmoved.2") = -1 ENOENT (No such file or directory)
rename("/usr/share/texmf.rpmmoved", "/usr/share/texmf.rpmmoved.3") = -1 ENOENT (No such file or directory)
rename("/usr/share/texmf.rpmmoved", "/usr/share/texmf.rpmmoved.4") = -1 ENOENT (No such file or directory)

etc

Expected Results:  
texlive-base is installed as normal

This does not reproduce with the vfs storage driver, e.g.

podman --root vfs-storage --storage-driver=vfs build -f Dockerfile /tmp/empty

will not reproduce. It is thus possible that other storage drivers also aren't affected, and it's somewhat limited to overlay.

Looking at the texlive-base.spec, it's obvious where we are stuck:

# SCRIPTLETS

%pretrans -p <lua>
path = "/usr/share/texmf"
st = posix.stat(path)
if st and st.type == "directory" then
  status = os.rename(path, path .. ".rpmmoved")
  if not status then
    suffix = 0
    while not status do
      suffix = suffix + 1
      status = os.rename(path .. ".rpmmoved", path .. ".rpmmoved." .. suffix)
    end
    os.rename(path, path .. ".rpmmoved")
  end
end