Skip to content

Conversation

@cachebag
Copy link
Contributor

@cachebag cachebag commented Jan 6, 2026

This PR employs symlink preservation in copy_file and adds it to copy_dir.

PR #1504 added symlink preservation to fix crashes in lldb-preview, which contains internal symlinks (liblldb was loading twice due to broken symlinks). Then, PR #1521 later changed copy_file to create symlinks pointing to the source path (for Homebrew integration), which may have regressed #1504.

This PR restores #1504's behavior: read the symlink target and preserve it. What I'm curious about is what the intended behavior for #1521 was because shouldn't users be able to run rustup-init --no-self-update? Is that not the recommended way to manage rustup via external package managers?

If this PR steers out of scope of the goals of rustup I'm happy to close it but I feel like the former behavior is preferable for most use cases.

@rami3l rami3l self-assigned this Jan 8, 2026
@rami3l
Copy link
Member

rami3l commented Jan 14, 2026

Thanks for making this patch! Reasonable support for external packagers are still expected, and whether a manual setup is required is largely based on the packagers' opinion: https://rust-lang.github.io/rustup/installation/other.html#using-a-package-manager

I have the feeling that we need to somehow support both cases based on whether that's copying the original binary or not...

Copy link
Member

@rami3l rami3l left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a specific use case where rustup is not working as you'd expect, which this PR allows to fix?

If you can find such a case, I agree with using this new implementation except for this:

utils::copy_file(&this_exe_path, &rustup_path)?;

#1521 is probably too widespread as a fix, and it makes perfect sense to use different copy implementations during self installation and during toolchain installation.

Suggest refining the test cases accordingly if going this way.

@cachebag
Copy link
Contributor Author

Do you have a specific use case where rustup is not working as you'd expect, which this PR allows to fix?

I don't, and I only encountered this looking at the code. It's my understanding that copying symlinks breaks their identity and can cause software to load libraries twice (like the crash that was fixed ad-hoc above). It's also just correct behavior afaik; cp -R preserves symlinks by default.

#1521 is probably too widespread as a fix, and it makes perfect sense to use different copy implementations during self installation and during toolchain installation.

I would agree with this and will adjust, so long as you think it's a reasonable patch. I figured at the least I could flag this to note the variance in functionality for copy's.

@rami3l
Copy link
Member

rami3l commented Jan 15, 2026

@cachebag Thanks for your clarification. I think although it has no direct influence now, judging by what I'd expect from the function API then indeed, the old behavior feels more correct to me, and leaving it uncorrected might lead to misuse in the long run.

Looking back there is still a slight possibility that we could be missing other cases apart from self installation, so I'd say let's go on polishing this patch by carefully analyzing the call sites. Please don't hesitate to ask me if you don't feel certain about anything!

@cachebag
Copy link
Contributor Author

@cachebag Thanks for your clarification. I think although it has no direct influence now, judging by what I'd expect from the function API then indeed, the old behavior feels more correct to me, and leaving it uncorrected might lead to misuse in the long run.

Looking back there is still a slight possibility that we could be missing other cases apart from self installation, so I'd say let's go on polishing this patch by carefully analyzing the call sites. Please don't hesitate to ask me if you don't feel certain about anything!

That makes sense to me, thank you!

@cachebag cachebag force-pushed the preserve-symlinks branch 2 times, most recently from 09c35e1 to f4c5445 Compare January 16, 2026 02:24
@cachebag cachebag requested a review from rami3l January 16, 2026 03:20
@cachebag cachebag force-pushed the preserve-symlinks branch 2 times, most recently from 071f34f to 19eada1 Compare January 16, 2026 23:44
@cachebag cachebag requested a review from rami3l January 16, 2026 23:45
@cachebag cachebag force-pushed the preserve-symlinks branch 3 times, most recently from 88ec12e to 99dd89c Compare January 18, 2026 18:25
Copy link
Member

@rami3l rami3l left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo a few lints, many thanks!

@cachebag cachebag force-pushed the preserve-symlinks branch 2 times, most recently from 173dc0c to ddc00b3 Compare January 19, 2026 23:13
@cachebag cachebag requested a review from rami3l January 20, 2026 00:29
Previously, copy_dir would follow symlinks and copy the target contents.
Now it preserves symlinks by reading the link target and creating a
new symlink with the same target.
@cachebag cachebag changed the title fix: copy_dir and copy_file to preserve symlinks instead of following them. fix: copy_dir and copy_file to preserve symlinks instead of following them.\ Jan 20, 2026
@cachebag cachebag changed the title fix: copy_dir and copy_file to preserve symlinks instead of following them.\ fix: copy_dir and copy_file to preserve symlinks instead of following them Jan 20, 2026
- copy_file() preserves symlinks (for component installation)
- copy_file_symlink_to_source() follows symlinks (for self-installation)

Uses copy_file in Transaction::copy_file and modify_file.
Uses copy_file_symlink_to_source in self_update.rs and windows.rs.

Adds regression tests for symlink preservation.
@rami3l rami3l enabled auto-merge January 20, 2026 13:38
@rami3l rami3l added this pull request to the merge queue Jan 20, 2026
Merged via the queue into rust-lang:main with commit 2ba20d7 Jan 20, 2026
56 of 58 checks passed
@cachebag cachebag deleted the preserve-symlinks branch January 20, 2026 15:12
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

Successfully merging this pull request may close these issues.

3 participants