[action] [PR:4365] Fix migrate_sonic_packages() crash on symlink resolv.conf#4380
Merged
mssonicbld merged 1 commit intosonic-net:202511from Mar 20, 2026
Merged
Conversation
<!--
Please make sure you've read and understood our contributing guidelines:
https://github.com/Azure/SONiC/blob/gh-pages/CONTRIBUTING.md
** Make sure all your commits include a signature generated with `git commit -s` **
If this is a bug fix, make sure your description includes "closes #xxxx",
"fixes #xxxx" or "resolves #xxxx" so that GitHub automatically closes the related
issue when the PR is merged.
If you are adding/modifying/removing any command or utility script, please also
make sure to add/modify/remove any unit tests from the tests
directory as appropriate.
If you are modifying or removing an existing 'show', 'config' or 'sonic-clear'
subcommand, or you are adding a new subcommand, please make sure you also
update the Command Line Reference Guide (doc/Command-Reference.md) to reflect
your changes.
Please provide the following information:
-->
#### What I did
Fixed `sonic-installer install` failing during `migrate_sonic_packages()` when `/etc/resolv.conf` in the new image is a symlink to `/run/resolvconf/resolv.conf`.
The failure occurs because the `cp` command at `main.py:386` follows the symlink through the overlay mount. Since the symlink target is an absolute path, it resolves to the **host's** `/run/resolvconf/resolv.conf` — the same file as the source. `cp` detects same source and destination inode and exits with:
```
cp: '/etc/resolv.conf' and '/tmp/image-<version>-fs/etc/resolv.conf' are the same file
```
This was introduced by the `build_debian.sh` change that replaced `touch` with `ln -sf /run/resolvconf/resolv.conf` for `/etc/resolv.conf` in the image filesystem.
#### How I did it
Check whether `/etc/resolv.conf` in the chroot is a symlink or a regular file, and handle each case appropriately:
- **Symlink** (images with `resolvconf` package installed): Read the symlink target via `readlink` (e.g. `/run/resolvconf/resolv.conf`), then create the target file inside the chroot with the host's DNS content. The symlink then resolves correctly inside the chroot. This avoids touching the symlink itself, so the overlay upper dir's `etc/resolv.conf` is never modified and the new image boots with the symlink intact. No cleanup is needed — the target lives under `/run`, which is a tmpfs recreated at every boot.
- **Regular file** (images without `resolvconf`, or where the build process explicitly creates a regular file via `touch`): Overwrite directly with the host's DNS content. No backup/restore is needed — the original file is empty (cleared during build), and after reboot the `resolv-config` service reconfigures DNS from CONFIG_DB.
The previous backup-overwrite-restore pattern has been removed since it is unnecessary in both cases.
#### How to verify it
1. Start with a switch running an image where `/etc/resolv.conf` is a symlink:
```bash
# Confirm symlink exists
ls -la /etc/resolv.conf
# Expected: /etc/resolv.conf -> /run/resolvconf/resolv.conf
# Ensure only one image is installed (clean state)
sudo sonic-installer list
# If the target image is already present, remove it:
sudo sonic-installer remove <target-image> -y
```
2. Run `sonic-installer install` with an image that also has the symlink:
```bash
sudo sonic-installer install <image-path> -y
```
3. Verify:
- Installation completes without `cp: ... are the same file` error
- `sonic-installer list` shows the new image as default
- After reboot, `/etc/resolv.conf` is still a symlink to `/run/resolvconf/resolv.conf`
- DNS resolution works
Signed-off-by: Sonic Build Admin <sonicbld@microsoft.com>
#### Previous command output (if the output of a command-line utility has changed)
#### New command output (if the output of a command-line utility has changed)
Collaborator
Author
|
Original PR: #4365 |
Collaborator
Author
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I did
Fixed
sonic-installer installfailing duringmigrate_sonic_packages()when/etc/resolv.confin the new image is a symlink to/run/resolvconf/resolv.conf.The failure occurs because the
cpcommand atmain.py:386follows the symlink through the overlay mount. Since the symlink target is an absolute path, it resolves to the host's/run/resolvconf/resolv.conf— the same file as the source.cpdetects same source and destination inode and exits with:This was introduced by the
build_debian.shchange that replacedtouchwithln -sf /run/resolvconf/resolv.conffor/etc/resolv.confin the image filesystem.How I did it
Check whether
/etc/resolv.confin the chroot is a symlink or a regular file, and handle each case appropriately:Symlink (images with
resolvconfpackage installed): Read the symlink target viareadlink(e.g./run/resolvconf/resolv.conf), then create the target file inside the chroot with the host's DNS content. The symlink then resolves correctly inside the chroot. This avoids touching the symlink itself, so the overlay upper dir'setc/resolv.confis never modified and the new image boots with the symlink intact. No cleanup is needed — the target lives under/run, which is a tmpfs recreated at every boot.Regular file (images without
resolvconf, or where the build process explicitly creates a regular file viatouch): Overwrite directly with the host's DNS content. No backup/restore is needed — the original file is empty (cleared during build), and after reboot theresolv-configservice reconfigures DNS from CONFIG_DB.The previous backup-overwrite-restore pattern has been removed since it is unnecessary in both cases.
How to verify it
Start with a switch running an image where
/etc/resolv.confis a symlink:Run
sonic-installer installwith an image that also has the symlink:Verify:
cp: ... are the same fileerrorsonic-installer listshows the new image as default/etc/resolv.confis still a symlink to/run/resolvconf/resolv.confSigned-off-by: Sonic Build Admin sonicbld@microsoft.com
Previous command output (if the output of a command-line utility has changed)
New command output (if the output of a command-line utility has changed)