In /usr/lib/portage/pym/portage_checksum.py, there is a function called perform_checksum. If "prelink" is installed, this function copies the file it's checksumming to /var/lib/portage/prelink-checksum.tmp, runs "prelink --undo" on it, and checksums the result. Firstly, that has a bug reported as #42228, "Parallel emerges can conflict during merge phase". Basically, both emerges use the same temporary file: bad! The simplest fix would be to use the current pid in the temporary name. Secondly, it isn't strictly to use a temporary file in that way. Current versions of prelink have "--md5" and "--sha1" options. By running, for example, "prelink --verify --md5 /bin/cat", that will output the MD5 digest of the file before prelinking. (From the man page, you could be lead to believe "prelink --md5" would do something useful by itself, but it seems not). Unfortunately, "prelink --verify --md5" is quite slow because it first undoes the prelink, then redoes it, then compares them, and then only if the undone-redone prelink matches the current file contents does it print the MD5 of the undone contents. This is for security checks, however it is much too slow for the perform_checksum function in portage which is not such a paranoid security check. This is because undoing is very fast, but re-prelinking a single file is quite slow: it opens every library file used by _any_ prelinked executable (it's not obvious why). Also, the command "prelink --verify --md5" does actually use temporary files, two of them, in the same directory as the file being examined, so it's actually worse than what Portage's perform_checksum in several ways. It would be very useful if "prelink --undo --md5" would simply print the MD5 of the contents before prelinking and not actually modify the filesystem. That's an obvious enhancement request to prelink, probably quite an easy one, which portage could then take advantage of. Until then, it's best if perform_checksum duplicates the file and then does "prelink --undo" on it as now, with the following changes: 1. Use a temporary file name including the pid of the portage process, or some other way to ensure parallel emerges or queries can't conflict. 2. Use a hard link when possible (falling back to a copy when across devices). "prelink --undo" is fine with that and will not modify the original file. Reproducible: Always Steps to Reproduce:
That should be locked via a portage_locks.lockfile call iirc... Which version of portage is exhibiting this? I haven't checked the code, but I'd be surprised if it lacked the locks...
It's entirely possible it is protected by a lock. I looked at #42228, I haven't checked if it can really happen. I'd still be inclined to generate a unique name defensively, as even if merging is protected by a lock, the checksum function could be called from other programs eventually as well. (See #67473). The change to use a hard link is still offered as a simple suggestion to make it a bit faster for large binaries.
the faster prelink undo + md5 should be added... aside from that, the prelink tmp file is properly locked.
*** This bug has been marked as a duplicate of 23851 ***