[Rpm-maint] [rpm-software-management/rpm] Installation fails for multiple `Obsoletes` (Issue #2359)

Pawel Winogrodzki notifications at github.com
Thu Jan 19 16:24:27 UTC 2023


Hey there,

I've noticed that RPM may fail to recognize all obsoleted packages depending on the order in which the packages are provided whenever one of these packages obsoletes at least two other ones. This may cause RPM to attempt to install more packages than it should.

## Example

### Packages
- `X`,
- `Y-OLD` (does NOT obsolete `X`),
- `Y-NEW` (obsoletes `X` and is of higher version than `Y-OLD`).

### Expected behaviour

Since `Y-NEW` obsoletes the other two packages, RPM should choose to only install `Y-NEW`.

### Current behaviour

If we try to install the packages in the `Y-OLD X Y-NEW` or the `X Y-OLD Y-NEW` order, RPM will fail to obsolete `Y-OLD` and attempt to install both `Y-OLD` and `Y-NEW`.

```bash
rpm -Uvvh --nodeps --root /fake_root/ --test Y-OLD X Y-NEW

D: ============== Y-OLD.rpm
D: loading keyring from rpmdb
D: PRAGMA secure_delete = OFF: 0
D: PRAGMA case_sensitive_like = ON: 0
warning: Y-OLD.rpm: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: Y-OLD.rpm: Header SHA256 digest: OK
D: Y-OLD.rpm: Header SHA1 digest: OK
D: Plugin: calling hook init in fsverity plugin
D: fsverity_init
D: Plugin: calling hook init in ima plugin
D: Plugin: calling hook init in syslog plugin
D:      added binary package [0]
D: ============== X.rpm
D: X.rpm: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: X.rpm: Header SHA256 digest: OK
D: X.rpm: Header SHA1 digest: OK
D:      added binary package [1]
D: ============== Y-NEW.rpm
D: Y-NEW.rpm: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: Y-NEW.rpm: Header SHA256 digest: OK
D: Y-NEW.rpm: Header SHA1 digest: OK
D: Obsoletes: X <= X_version                           YES (added provide)
warning: package X was already added, replacing with Y-NEW
D:      added binary package [2]
D: found 0 source and 3 binary packages
D: ========== recording tsort relations
D: ========== tsorting packages (order, #predecessors, #succesors, depth)
D:     0    0    0    1   +Y-NEW
D:     1    0    0    1   +Y-OLD
D: installing binary packages
D: sanity checking 2 elements
Verifying...                          ################################# [100%]
D: Plugin: calling hook tsm_pre in selinux plugin
D: Plugin: calling hook tsm_pre in syslog plugin
D: computing 108 file fingerprints
D: entering chroot /fake_root/
Preparing...                          D: computing file dispositions
D: 0x00000049     4096    408832206    120447136 rotational:-1 /
################################# [100%]
D: exiting chroot /fake_root/
D: Plugin: calling hook tsm_post in selinux plugin
D: Plugin: calling hook tsm_post in syslog plugin
        file /usr/lib/Y/Y.file conflicts between attempted installs of Y-OLD and Y-NEW
D: Exit status: 2
```

If we try to install the packages in any other order, RPM will return the correct result.

Example for the `X Y-NEW Y-OLD` order:
```bash
D: ============== X
D: loading keyring from rpmdb
D: PRAGMA secure_delete = OFF: 0
D: PRAGMA case_sensitive_like = ON: 0
warning: X: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: X: Header SHA256 digest: OK
D: X: Header SHA1 digest: OK
D: Plugin: calling hook init in fsverity plugin
D: fsverity_init
D: Plugin: calling hook init in ima plugin
D: Plugin: calling hook init in syslog plugin
D:      added binary package [0]
D: ============== Y-NEW
D: Y-NEW: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: Y-NEW: Header SHA256 digest: OK
D: Y-NEW: Header SHA1 digest: OK
D: Obsoletes: X <= X_version                           YES (added provide)
warning: package X was already added, replacing with Y-NEW
D:      added binary package [1]
D: ============== Y-OLD
D: Y-OLD: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: Y-OLD: Header SHA256 digest: OK
D: Y-OLD: Header SHA1 digest: OK
D: Obsoletes: Y-NEW > Y-OLD_version                   YES (added provide)
warning: package Y-NEW was already added, skipping Y-OLD
D:      added binary package [2]
D: found 0 source and 3 binary packages
D: ========== recording tsort relations
D: ========== tsorting packages (order, #predecessors, #succesors, depth)
D:     0    0    0    1   +Y-NEW
D: installing binary packages
D: sanity checking 1 elements
Verifying...                          ################################# [100%]
D: Plugin: calling hook tsm_pre in selinux plugin
D: Plugin: calling hook tsm_pre in syslog plugin
D: computing 54 file fingerprints
D: entering chroot /fake_root/
Preparing...                          D: computing file dispositions
D: 0x00000049     4096    408816593    120444311 rotational:-1 /
################################# [100%]
D: exiting chroot /fake_root/
D: ========== +++ Y-NEW arch-linux 0x0
D: Y-NEW: Header V4 RSA/SHA256 Signature, key ID 3135ce90: NOKEY
D: Y-NEW: Header SHA256 digest: OK
D: Y-NEW: Header SHA1 digest: OK
D: Plugin: calling hook tsm_post in selinux plugin
D: Plugin: calling hook tsm_post in syslog plugin
D: Exit status: 0
```

### Potential cause

It seems that the [addPackage](https://github.com/rpm-software-management/rpm/blob/c10e1ec1149dec40b6ed11eb8b513992f2af7e62/lib/depends.c#L419) function expects to replace no more than one package. It calls the [findPos](https://github.com/rpm-software-management/rpm/blob/c10e1ec1149dec40b6ed11eb8b513992f2af7e62/lib/depends.c#L328) function once to find the replaced package's index and then newer checks if any additional packages may need to be removed from the set of added packages.

For the failing `Y-OLD X Y-NEW` order from the example, `addPackage` replaces `X` but doesn't consider replacing `Y-OLD`.

For the successful `X Y-NEW Y-OLD` order above, there is always only one package to be replaced/skipped at a time, so everything works as intended.

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

Message ID: <rpm-software-management/rpm/issues/2359 at github.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20230119/3c765b45/attachment-0001.html>


More information about the Rpm-maint mailing list