Subject: Re: bug#70165: D-Bus system service breaks reconfiguration when /var/run/dbus is present + /run and /var/run are on separate file systems.

From: Ludovic Courtès <[email-masked]>
Date: Thu, 23 May 2024 11:10:06 +0200

Liliana Marie Prikler <[email-masked]> skribis:

> Am Freitag, dem 05.04.2024 um 09:53 +0800 schrieb Hilton Chain:

[...]

>>            0 (rename-file "/tmp/tmp.9wyzRfQ28l/test" "/tmp/test")
>> 
>> ERROR: In procedure rename-file:
>> In procedure rename-file: Invalid cross-device link
>> --8<---------------cut here---------------end--------------->8---
> If I understand this reproducer correctly, there aren't even symbolic
> links involved, are there?
>
> Adding Ludo to CC, because this looks like a Guile bug to me.

‘rename-file’ merely wraps rename(2), which errors out with EXDEV
(“Invalid cross-link device”) when the source and targets are on
different file systems.

So the case above is behaving as expected.

What that means is that probably we shouldn’t be using ‘rename-file’
directly in cases where the source and target might be on different file
systems, and instead do something like:

  (define (rename-file* old new)
    ;; Like rename-file, but handle the case when OLD and NEW are on
    ;; different file systems.
    (catch 'system-error
      (lambda ()
        (rename-file old new))
      (lambda args
        (if (= EXDEV (system-error-errno args))
            (begin
              (copy-file old new)
              (delete-file old))
            (apply throw args)))))

(Untested.)

HTH!

Ludo’.