From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7) Gecko/20040615 Firefox/0.9 Description of problem: Unless runngin as root, the commands mkdir $HOME/rpmdb rpm --initdb --dbpath $HOME/rpmdb produces the error message error: can't create transaction lock This precludes user installation of relocatable packages. Version-Release number of selected component (if applicable): rpm-4.3.1-0.3 How reproducible: Always Steps to Reproduce: 1. su - $USER # Make sure not running as root 2. rm -rf $HOME/rpmdb; mkdir $HOME/rpmdb # Clean slate 3. rpm --initdb --dbpath $HOME/rpmdb # Fails Actual Results: error: can't create transaction lock Expected Results: create an empty rpm database in $HOME/rpmdb Additional info: The error message comes from the function void *rpmtsAcquireLock(rpmts ts) in lib/rpmlock.c. This function executes the call lock = rpmlock_new(rootDir) This function unconditionally tries to open the file /var/lock/rpm/transaction for read-write. Failing this, it opens it for read instead, but the caller checks how the file was opened, and fails unless the mode incudes write access. I suggest that rpmlock_new, in the case that dbpath has been specified different from the default value, uses a transaction lock file in the dbpath directory.
A better suggestion is perhaps not to use the transaction lock file at all, but rather - do nothing if %{dbpath}/Packages exists (ie. fail) - create it and write-lock it if %{dbpath}/Packages does not exist. As long as Packages does not exist, no transaction can be in progress anyway. Creation should probably be using a different name at first, lock the open file, then rename it. Then the file is locked from the moment it comes into existence under its true name. If the rename fails because another file of that name has appeared in the mean time, the operation should simply fail as if */Packages had existed from the outset. If the locking fails, the operation should fail with an appropriate error message. This should be exceedingly rare.
This bug is probably the same as 129463, but that one is filed against Fedora Core 1, which is probably why I did not see it.
To make matters worse, /var/lock/rpm is also wrapped in an "%ifos linux" which makes RPM 4.3 unportable... Q: Why can't the lock file live in %{dbpath} instead ? Think I will do a quick hack change and try it out.
Created attachment 103528 [details] rpmlock-local.patch Something like this... (just for the discussion)
Created attachment 104131 [details] rpm-4.3-rpmlock.patch Messed up the rpmGetPath in the old patch. This one has been tested and seems to work?
Jeff says that: "-initdb has been unnecessary for years" (probably time to mention this in some documentation ?) Which means that you can just start installing with --dbpath and --root, to test packages somewhere else... Above patch should do much harm then either, I think ? (just create an unnecessary file in the %{dbpath} )
Will this patch make it into the main code base? And just to let you know, this bug does not only affect initdb, it affects any operation requiring writing to a non-root db (install, erase, etc.) We use RPM to distribute packages that install via a non-priveleged user to a private db, and ever since 4.3 this functionality has been broken. Right now to be able to support our clients on Linux with rpm 4.3, we have to re-compile our own rpm distribution packages using the patch above, but it would be very nice if this was no longer necessary. Thank you.
There is a similar patch going to rpm-4_3, rpm-4_4 and HEAD soon: - move global /var/lock/rpm/transaction to dbpath. - permit fcntl path to be configured through rpmlock_path macro.
Fixed in rpm-4.4.1-0.18.