We have a system that aims to do an atomic update of the complete contents in a directory by accessing the directory via a symlink and updating the symlink when the update should happen.
However, when modifying a symlink on a volume outside the container, the container sees an outdated symlink. This happens if the symlink is modified while the container is running and also when an entirely new container is started.
Reproduce
Run this script twice. The first run will work, but the second run will fail to list the contents behind the symlink initially and then recover once the upper directory is listed.
#!/bin/bash
set -eux
mkdir -p vol
cat > vol/test.sh << 'EOF'
#!/bin/sh
set -ux
counter=0
while true; do
ls -il /vol/data/symlink
counter=$((counter + 1))
if [ $((counter % 5)) -eq 0 ]; then
echo "ls the top dir"
ls -il /vol/data/
fi
sleep 2
done;
EOF
chmod +x vol/test.sh
TARGET="vol/data"
mkdir -p "$TARGET"
NEW_CONTENTS=$RANDOM
RANDOM_TMP_SYMLINK=$RANDOM
mkdir "$TARGET"/"$NEW_CONTENTS"
echo "some contents" > "$TARGET"/"$NEW_CONTENTS/contentfile"
ln -s "$NEW_CONTENTS" "$TARGET"/"$RANDOM_TMP_SYMLINK"
mv -hf "$TARGET"/"$RANDOM_TMP_SYMLINK" "$TARGET"/symlink
cat << 'EOF'
Running a docker container to expose that the symlink manipulated from outside the container is broken
until the /vol/data/ is accessed either in the host or within the container
EOF
docker run --rm -v "$(pwd)"/vol:/vol debian:bookworm bash /vol/test.sh
The output of two runs of this script:
❯ ./host-test.sh
+ mkdir -p vol
+ cat
+ chmod +x vol/test.sh
+ TARGET=vol/data
+ mkdir -p vol/data
+ NEW_CONTENTS=14875
+ RANDOM_TMP_SYMLINK=4614
+ mkdir vol/data/14875
+ echo 'some contents'
+ ln -s 14875 vol/data/4614
+ mv -hf vol/data/4614 vol/data/symlink
+ cat
Running a docker container to expose that the symlink manipulated from outside the container is broken
until the /vol/data/ is accessed either in the host or within the container
++ pwd
+ docker run --rm -v /Users/rauhahe/f/ifc/packages/docker-testing/vol:/vol debian:bookworm bash /vol/test.sh
+ counter=0
+ true
+ ls -il /vol/data/symlink
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink -> 14875
+ counter=1
+ '[' 1 -eq 0 ']'
+ sleep 2
+ true
+ ls -il /vol/data/symlink
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink -> 14875
+ counter=2
+ '[' 2 -eq 0 ']'
+ sleep 2
^C+ true
+ ls -il /vol/data/symlink
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink -> 14875
+ counter=3
+ '[' 3 -eq 0 ']'
+ sleep 2
^C^C
got 3 SIGTERM/SIGINTs, forcefully exiting
❯ ./host-test.sh
+ mkdir -p vol
+ cat
+ chmod +x vol/test.sh
+ TARGET=vol/data
+ mkdir -p vol/data
+ NEW_CONTENTS=5731
+ RANDOM_TMP_SYMLINK=6926
+ mkdir vol/data/5731
+ echo 'some contents'
+ ln -s 5731 vol/data/6926
+ mv -hf vol/data/6926 vol/data/symlink
+ cat
Running a docker container to expose that the symlink manipulated from outside the container is broken
until the /vol/data/ is accessed either in the host or within the container
++ pwd
+ docker run --rm -v /Users/rauhahe/f/ifc/packages/docker-testing/vol:/vol debian:bookworm bash /vol/test.sh
+ counter=0
+ true
+ ls -il /vol/data/symlink
ls: cannot read symbolic link '/vol/data/symlink': Invalid argument
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink
+ counter=1
+ '[' 1 -eq 0 ']'
+ sleep 2
+ true
+ ls -il /vol/data/symlink
ls: cannot read symbolic link '/vol/data/symlink': Invalid argument
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink
+ counter=2
+ '[' 2 -eq 0 ']'
+ sleep 2
+ true
+ ls -il /vol/data/symlink
ls: cannot read symbolic link '/vol/data/symlink': Invalid argument
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink
+ counter=3
+ '[' 3 -eq 0 ']'
+ sleep 2
+ true
+ ls -il /vol/data/symlink
ls: cannot read symbolic link '/vol/data/symlink': Invalid argument
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink
+ counter=4
+ '[' 4 -eq 0 ']'
+ sleep 2
+ true
+ ls -il /vol/data/symlink
ls: cannot read symbolic link '/vol/data/symlink': Invalid argument
235 lrwxr-xr-x 1 root root 5 Oct 7 08:11 /vol/data/symlink
+ counter=5
+ '[' 0 -eq 0 ']'
+ echo 'ls the top dir'
+ ls -il /vol/data/
ls the top dir
total 0
233 drwxr-xr-x 3 root root 96 Oct 7 08:11 14875
236 drwxr-xr-x 3 root root 96 Oct 7 08:12 5731
238 lrwxr-xr-x 1 root root 4 Oct 7 08:12 symlink -> 5731
+ sleep 2
+ true
+ ls -il /vol/data/symlink
238 lrwxr-xr-x 1 root root 4 Oct 7 08:12 /vol/data/symlink -> 5731
+ counter=6
+ '[' 1 -eq 0 ']'
+ sleep 2
^C+ true
+ ls -il /vol/data/symlink
238 lrwxr-xr-x 1 root root 4 Oct 7 08:12 /vol/data/symlink -> 5731
+ counter=7
+ '[' 2 -eq 0 ']'
+ sleep 2
^C^C
got 3 SIGTERM/SIGINTs, forcefully exiting
Expected behavior
ls -il /vol/data/symlink
should always be able to list the contents within the symlinked directory.
docker version
Client:
Version: 27.2.0
API version: 1.47
Go version: go1.21.13
Git commit: 3ab4256
Built: Tue Aug 27 14:14:45 2024
OS/Arch: darwin/arm64
Context: desktop-linux
Server: Docker Desktop 4.34.2 (167172)
Engine:
Version: 27.2.0
API version: 1.47 (minimum version 1.24)
Go version: go1.21.13
Git commit: 3ab5c7d
Built: Tue Aug 27 14:15:41 2024
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.7.20
GitCommit: 8fc6bcff51318944179630522a095cc9dbf9f353
runc:
Version: 1.1.13
GitCommit: v1.1.13-0-g58aa920
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Description
We have a system that aims to do an atomic update of the complete contents in a directory by accessing the directory via a symlink and updating the symlink when the update should happen.
However, when modifying a symlink on a volume outside the container, the container sees an outdated symlink. This happens if the symlink is modified while the container is running and also when an entirely new container is started.
Reproduce
Run this script twice. The first run will work, but the second run will fail to list the contents behind the symlink initially and then recover once the upper directory is listed.
The output of two runs of this script:
Expected behavior
should always be able to list the contents within the symlinked directory.
docker version
docker info
Diagnostics ID
B8D5CF04-AD4D-4D98-B753-237BAB63AA98/20241007080524
Additional Info
No response