For testing the following works: ln -s actual /tmp/sym in testapp-1's src_install(): mkdir -p "${D}/tmp/sym"; touch "${D}/tmp/sym/file" in testapp-2's src_install(): mkdir -p "${D}/tmp/actual"; touch "${D}/tmp/actual/file" Now downgrading from testapp-2 to testapp-1 does: >>> /tmp/sym/file * pkg_postinst testapp-1 >>> sys-apps/testapp-1 merged. sys-apps/testapp selected: 2 protected: 1 omitted: none >>> 'Selected' packages are slated for removal. >>> 'Protected' and 'omitted' packages will not be removed. >>> Unmerging sys-apps/testapp-2... * pkg_prerm testapp-2 No package files given... Grabbing a set. <<< obj /tmp/actual/file --- !owned dir /tmp <<< dir /tmp/actual so it ends up removing the file it just installed, because it does not realise /tmp/actual/file and /tmp/sym/file are the same file (and apparently there is no mtime check). Upgrading from testapp-1 to testapp-2 has the same problem. I'm marking this critical because you can hit this with python when upgrading from 2.4.3 to 2.4.4-r4 on amd64 with /usr/lib a symlink to /usr/lib64 or vice versa. Older pythons installed their pure-python files in /usr/lib64, newer pythons install them in /usr/lib. So when you upgrade between those versions using this version of portage, most of python gets wiped.
Created attachment 122367 [details, diff] use device/inode numbers are used to determine ownership This should solve the problem. It uses the same code that collision-protect uses to prevent false negatives when determining ownership.
This has been released in 2.1.3_rc4.