Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alternatives-symlinks-relative breaks symlink creation when recipes disagree on the symlink's location #3

Open
AI0867 opened this issue Sep 12, 2024 · 1 comment

Comments

@AI0867
Copy link

AI0867 commented Sep 12, 2024

Previously reported at yocto bugzilla, but now here as alternatives-symlinks-relative appears to be a karo-fork feature.

Busybox tells update-alternatives that start-stop-daemon should be located /sbin/start-stop-daemon, and could be linked to /bin/busybox.nosuid

Dpkg's subpackage dpkg-start-stop tells update-alternatives that start-stop-daemon should be located at /usr/sbin/start-stop-daemon, and could be linked to /usr/sbin/start-stop-daemon.dpkg

Busybox appears to be installed first (this might be a race condition), resulting in the link location being /sbin/start-stop-daemon

This in itself wouldn't be a problem, but when combined with DISTRO_FEATURES alternatives-symlinks-relative, this results in a relative symlink alternative being generated for the dpkg version, in the same directory as its target.

So:

  1. /usr/sbin/start-stop-daemon.dpkg and /usr/sbin/start-stop-daemon are in the same directory
  2. So the dpkg alternative relative symlink is just start-stop-daemon.dpkg
  3. But the actual link location is /sbin/start-stop-daemon
  4. update-alternatives then is instructed to create a link from /sbin/start-stop-daemon to start-stop-daemon.dpkg (effectively /sbin/start-stop-daemon.dpkg)
  5. But as /sbin/start-stop-daemon.dpkg doesn't exist, update-alternatives refuses to do this, resulting in /sbin/start-stop-daemon being missing from the resulting system.

This is a combination of several things:

  • Disagreement between two packages on the correct location of the symlink
  • The relative symlink target being generated based on the specified symlink location, rather than the actual one
  • update-alternatives not warning about conficting symlink locations
  • update-alternatives refusing to create a link (without a warning I could easily find) when the highest-priority target doesn't actually exist

The final result is an image that does not have start-stop-daemon in either /sbin or /usr/sbin, despite having both busybox and start-stop-daemon.dpkg installed.

I've locally fixed this by putting the following in busybox_%.bbappend:

do_install:append() {
        sed -i "s:^/sbin/start-stop-daemon:/usr/sbin/start-stop-daemon:" ${D}${sysconfdir}/busybox.links.nosuid
}
@AI0867
Copy link
Author

AI0867 commented Sep 13, 2024

I'm writing a patch to add checks to update-alternatives.bbclass to catch things like this, and I immediately found the following:

Running groupadd commands...
NOTE: busybox: Performing groupadd with [ --system utmp]
NOTE: busybox: group utmp already exists, not re-creating it
update-alternatives: Linking /usr/bin/arch to arch.coreutils
update-alternatives: renaming base32 link from /usr/bin/base32 to /bin/base32
update-alternatives: Linking /bin/base32 to base32.coreutils
warning: %post(busybox-1.36.1-r0.armv8a) scriptlet failed, exit status 1
root@device:~# ls -l /bin/base32
lrwxrwxrwx 1 root root 16 Sep 13 13:40 /bin/base32 -> base32.coreutils
root@device:~# ls -l /bin/base32.coreutils
ls: cannot access '/bin/base32.coreutils': No such file or directory

It's the same issue: coreutils installs /usr/bin/base32.coreutils, trying to link to it from /usr/bin/base32 and busybox tries to link from /bin/base32 to /bin/busybox.nosuid, but both are configured in /usr/lib/opkg/alternatives/base32, which breaks when using relative symlinks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant