Bug 707668

Summary: rpm does chroot's different for install vs. remove transactions
Product: [Fedora] Fedora Reporter: James Antill <james.antill>
Component: rpmAssignee: Panu Matilainen <pmatilai>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 15CC: ffesti, herrold, jnovy, pmatilai
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-03-31 07:06:05 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description James Antill 2011-05-25 17:01:06 UTC
Description of problem:

If you do:

strace -o /tmp/abcd.in yum --releasever=15 --installroot=/tmp/i-rm --disablerepo=google-talkplugin in zsh

strace -o /tmp/abcd.rm yum --releasever=15 --installroot=/tmp/i-rm --disablerepo=google-talkplugin rm zsh

...then grep the output:


% egrep 'chroot\(|transaction-done' /tmp/abcd.in /tmp/abcd.rm
/tmp/abcd.in:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd.in:chroot(".")                             = 0
/tmp/abcd.in:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd.in:chroot(".")                             = 0
/tmp/abcd.in:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd.in:chroot(".")                             = 0
/tmp/abcd.in:open("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:38.36", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 34
/tmp/abcd.in:unlink("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:38.36") = 0

/tmp/abcd.rm:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd.rm:chroot(".")                             = 0
/tmp/abcd.rm:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd.rm:chroot(".")                             = 0
/tmp/abcd.rm:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd.rm:open("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:39.12", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOENT (No such file or directory)
/tmp/abcd.rm:chroot(".")                             = 0
/tmp/abcd.rm:unlink("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:39.12") = -1 ENOENT (No such file or directory)

...as you can see in the install case rpm chroot's back out (presumably so yum can open the rpm file), but in the remove case it does not.

 This appears to be the case in RHEL-5 too, however we don't get a failure for some reason:

% egrep 'chroot\(|transaction-done' /tmp/abcd2.in /tmp/abcd2.rm
/tmp/abcd2.in:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd2.in:chroot(".")                             = 0
/tmp/abcd2.in:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd2.in:chroot(".")                             = 0
/tmp/abcd2.in:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd2.in:chroot(".")                             = 0
/tmp/abcd2.in:open("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:58.46", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 35
/tmp/abcd2.in:unlink("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:58.46") = 0
/tmp/abcd2.rm:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd2.rm:chroot(".")                             = 0
/tmp/abcd2.rm:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd2.rm:chroot(".")                             = 0
/tmp/abcd2.rm:chroot("/tmp/i-rm/")                    = 0
/tmp/abcd2.rm:open("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:59.04", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 27
/tmp/abcd2.rm:chroot(".")                             = 0
/tmp/abcd2.rm:unlink("/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:59.04") = -1 ENOENT (No such file or directory)

Comment 1 James Antill 2011-05-26 04:42:15 UTC
And looking for the obvious, we find that on RHEL-5 we have:

/tmp/i-rm/tmp/i-rm/var/lib/yum/transaction-done.2011-05-25.12:59.04

...which explains why it can successfully open().

Comment 2 Panu Matilainen 2011-05-26 06:28:49 UTC
It's not the chroot's but callback events which are different and asymmetric: on install yum hooks into RPMCALLBACK_INST_OPEN/CLOSE_FILE which happens outside the chroot (it has to), but there are no matching callbacks on erase because there are no package files to open on erase, so yum is using RPMCALLBACK_UNINST_STOP on erase case. Which indeed occurs inside the chroot. And although there is (largely unused) RPMCALLBACK_INST_START, there's no RPMCALLBACK_INST_STOP which would behave similarly (ie inside the chroot) to UNINST_STOP.

Beating some sense into this is part of the "grand callback redesign" that's been in the plans for a couple of years now, sigh... maybe it is about time to actually do it.

In the meanwhile, I'd you open the transaction-done file from something that does behave symmetrically on both cases so you dont need to play guess-games. One possibility is opening the file on RPMCALLBACK_INST_START/RPMCALLBACK_UNINST_START, or simply at the same time as you write transaction-all, ie RPMCALLBACK_TRANS_START, which all occur inside the chroot so you dont need to guess. It's easy enough to detect and remove an empty transaction-done file in the case nothing actually got written to it despite having opened the file at an earlier point.

Comment 3 Panu Matilainen 2012-03-31 07:06:05 UTC
rpm >= 4.9.90 issues RPMCALLBACK_INST_STOP event as well. So the symmetry is there now, these all occur inside the chroot:

RPMCALLBACK_INST_START -> RPMCALLBACK_INST_PROGRESS -> RPMCALLBACK_INST_STOP
RPMCALLBACK_UNINST_START -> RPMCALLBACK_UNINST_PROGRESS -> RPMCALLBACK_UNINST_STOP

Changing yum to take advantage of this when its available is another story...