acheronfail/repgrep

failed to persist temporary file path

Closed this issue · 9 comments

replacement fails with following error :

Failed to make all replacements: failed to persist temporary file path: Invalid cross-device link (os error 18)
An error occurred during replacement: Failed to perform all replacements, see log
Logs available at: /tmp/.repgrep

no logs are avaiable at /tmp/.repgrep

same

Also getting this. I can work around it, though, by setting TMPDIR to point to a directory on the same file system as the files I'm working on.

It might work to swap out NamedTempFile::new() for NamedTempFile::new_in(path_buf.parent.as_path()) but I haven't confirmed this.

Interesting - can I get any more information?

  • what OS?
  • what type of mount is your /tmp dir? (run mount | grep '/tmp')

My OS is Arch Linux

mount | grep 'tmp' 
/dev/disk/by-uuid/3c6182b4-8f62-4c93-aa76-246fbaa495f6 on /tmp type tmpfs (rw,relatime,inode64)

Ah, so your /tmp directory is on a separate disk to where you're running rgr? I'll see if I can reproduce it on my machine.

I can't seem to reproduce this, I've even tried installing Arch in a VM with /tmp mounted on a separate disk and even with a different filesystem to where rgr is running, and it all just works.

Is there any more information about your system you can give me?

My machine is Debian 11, running in a WSL2 VM.

❯ mount | grep '/tmp'
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
tmpfs on /home/jwest/tmp type tmpfs (rw,nosuid,nodev,noatime)

Other non-relevant entries elided.

For clarity, my TMPDIR is normally set to /home/jwest/tmp

The file system that the files on which I'm trying rgr are on:

❯ mount | grep sdc
/dev/sdc on / type ext4 (rw,relatime,discard,errors=remount-ro,data=ordered)

If I run rgr with TMPDIR set to /home/jwest/tmp, I get the same failure the OP did. I also get the same failure the OP did if I set TMPDIR to /tmp before running rgr. A way I've found to succeed is to set TMPDIR=. then run rgr.

Another way I've found is in replace.rs to change line 112 from:

let mut temp_file = NamedTempFile::new()?;

to:

let mut temp_file = NamedTempFile::new_in(path_buf.parent().unwrap())?;

Ahh, thanks for bringing that up change again, I looked into it some more and discovered this in the temp_file crate's documentation:

Note: Temporary files cannot be persisted across filesystems. Also neither the file contents nor the containing directory are synchronized, so the update may not yet have reached the disk when persist returns.

Now I know where the error is, I'll see if I can perform the replacement atomically in a different way...

After reading tempfile's documentation and their issue tracker, I think @jwest23's suggestion aligns with how that crate should be used, so I'll go with that.

Thanks for all your input!