kisslinux / kiss

KISS Linux - Package Manager
https://kisslinux.github.io
MIT License
464 stars 62 forks source link

kiss fails if sees loop/dangling symlinks #232

Closed illiliti closed 3 years ago

illiliti commented 3 years ago

This bug is reproducible in latest rootfs release -> https://github.com/kisslinux/repo/releases/tag/2021.7-5

  1. build and install libudev-zero 0.4.8
  2. build and install libudev-zero 0.5.2
dylanaraps commented 3 years ago

What is the last version this works in? Has the install function ever handled this correctly?

dylanaraps commented 3 years ago

In master:

-> libudev-zero Checking if manifest valid
-> libudev-zero Checking if package installable
-> libudev-zero Checking for package conflicts
-> libudev-zero Installing package (libudev-zero@0.5.2-1.tar.zst)
mv: can't stat '/usr/lib/libudev.so.1': Symbolic link loop
-> libudev-zero Verifying installation
mv: can't stat '/usr/lib/libudev.so': Symbolic link loop
-> libudev-zero Failed to install package.
ERROR libudev-zero Filesystem now dirty, manual repair needed.

Running a second time:

-> Using 'ssu' (to become root) 
-> libudev-zero Checking if manifest valid
-> libudev-zero Checking if package installable
-> libudev-zero Checking for package conflicts
-> libudev-zero Installing package (libudev-zero@0.5.2-1.tar.zst)
mv: can't stat '/usr/lib/libudev.so': Symbolic link loop
-> libudev-zero Verifying installation
cp: can't stat '/usr/lib/__kiss-tmp-libudev-zero-libudev.so-4350': Symbolic link loop
mv: can't stat '/usr/lib/libudev.so': Symbolic link loop
-> libudev-zero Failed to install package.
ERROR libudev-zero Filesystem now dirty, manual repair needed.
dylanaraps commented 3 years ago

Here's a non-ideal solution but a solution nonetheless. Posting here just to archive it. Proper solution will make its way into master (once I figure out how to mimic mv -T without leaving a window of brokenness open)..


diff --git a/kiss b/kiss
index 2da238d..3a3d8b2 100755
--- a/kiss
+++ b/kiss
@@ -1101,6 +1101,17 @@ pkg_install_files() {
                     # temporary name created above.
                     cp -fP "$2$file" "$__tmp"

+                    # If the file is a symbolic link, remove it before
+                    # moving the file to avoid issues with link loops.
+                    #
+                    # NOTE: This creates a small window when installing
+                    # symbolic links where the link does not exist.
+                    #
+                    # Fixing this issue requires GNU mv's -T flag to
+                    # treat the destination as a normal file. A POSIX
+                    # compliant solution is being sought.
+                    ! [ -h "$_file" ] || rm -f "$_file"
+
                     # Atomically move the temporary file to its final
                     # destination. The running processes will either get
                     # the old file or the new one.```
dylanaraps commented 3 years ago

Let me know if this fixes the issue. I can no longer reproduce here.