Running `rpmdb --rebuilddb` in a Fedora 37 podman container results in the 
following error:

```
error: failed to replace old database with new database!
error: replace files in /usr/lib/sysimage/rpm with files from 
/usr/lib/sysimage/rpmrebuilddb.12 to recover
```

Investigating further with `strace`, the culprit is actually the following 
rename call:

```
# strace -e rename rpmdb --rebuilddb
rename("/usr/lib/sysimage/rpm", "/usr/lib/sysimage/rpmold.16") = -1 EXDEV 
(Invalid cross-device link)
error: failed to replace old database with new database!
error: replace files in /usr/lib/sysimage/rpm with files from 
/usr/lib/sysimage/rpmrebuilddb.16 to recover
+++ exited with 1 +++
```

Turns out, this is a limitation of overlayfs, as mentioned in 
https://github.com/torvalds/linux/blob/v4.8-rc2/fs/overlayfs/copy_up.c#L318-L322
 (also reported e.g. here: https://github.com/moby/moby/issues/25409):

```
Directory renames only allowed on "pure upper" (already created on
upper filesystem, never copied up).  Directories which are on lower or
are merged may not be renamed.  For these -EXDEV is returned and
userspace has to deal with it.  This means, when copying up a
directory we can rely on it and ancestors being stable.
```

A more low-level reproducer using `bubblewrap` and `fuse-overlayfs` looks like 
this (on Fedora 37):

```
$ sudo dnf install -y --installroot=$PWD/tree --releasever=37 python3
$ sudo chmod u+w tree/
$ sudo chown test: -R tree/
$ mkdir tree/foo  # this will be renamed to reproduce the issue
$ mkdir upper work merged
$ fuse-overlayfs -t overlay overlay -o 
lowerdir=tree,upperdir=upper,workdir=work merged
$ bwrap --unshare-pid --dev-bind $PWD/merged / --dev /dev --proc /proc bash
bash-5.2$ python3
Python 3.11.1 (main, Dec  7 2022, 00:00:00) [GCC 12.2.1 20221121 (Red Hat 
12.2.1-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.rename('/foo', '/bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 18] Invalid cross-device link: '/foo' -> '/bar'
```

Currently, I'm not aware of any workaround.

It seems that the only way to make this work cleanly would be to add 
filesystem-specific code to RPM, however that doesn't sound great either.

Any thoughts?

-- 
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/issues/2355
You are receiving this because you are subscribed to this thread.

Message ID: <rpm-software-management/rpm/issues/2...@github.com>
_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to