10

I am using docker bind mount to map the host /dev/serial/ folder generated by Ubuntu (which contains identifying symlinks to serial devices such as /dev/ttyUSB0). The full docker container run command I am using is

docker run -d --restart always --privileged=true -v /dev/serial:/dev/serial DOCKER_IMAGE_NAME

This works fine at first run, however if the serial device is disconnected and reconnected, the symlinks are recreated. This change does not propagate into the docker container and instead the docker container finds an empty /dev/serial folder. I tested manually creating a file on the host and within the docker container in this directory as well, and strangely the change on one was not updated in the other in both cases.

The volume is shown as

{
    "Type": "bind",
    "Source": "/dev/serial",
    "Destination": "/dev/serial",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
}

EDIT: Ubuntu creates the symlinks within two directories, by-path and by-id underneath the /dev/serial folder.

Jetkov
  • 103
  • 1
  • 1
  • 6
  • In my case the mounthing is shown perfectly ie Source and Destination are correct but the folder content does not get updated. Restarting Docker finally exposes the files ie Bind mount connection is again established. Note : I am mounting Windows location to a linux container – Shubhanshu Rastogi Sep 25 '19 at 07:14

2 Answers2

18

Bind mounts are based on inodes and when the file is deleted and recreated then the bind-mount is broken. These changes aren't propagated to the bind-mount until a container restart so it picks the new inode.

A solution for this case (files are deleted and recreated) is to mount the parent directory instead, so in your case you can mount using -v /dev:/dev. Of course this will expose /dev to the container so handle it with care.

codestation
  • 2,938
  • 1
  • 22
  • 22
  • Thanks for the reply. I didn't realize that when the device is unplugged Ubuntu would not only remove the symlinks in the subdirectories under `/dev/serial` but also the `/dev/serial` directory itself. Mounting `/dev` works well. – Jetkov Nov 30 '18 at 00:25
  • Even if I mount the directory where the file exists rather than the file itself, the file still does not receive new data from the container if the file is deleted and recreated while the container is running. It may still be an "inode" issue, but the solution presented does not work. – Ken Roy Dec 16 '21 at 13:37
  • @KenRoy how did you solve that? – anatol Jun 16 '23 at 04:51
  • @anatol, instead of letting the host delete the file that is mounted by a container, I set it so the host only empties the file. So the file's inode never changes. – Ken Roy Aug 31 '23 at 14:03
3

The issue exists with Previous versions of Docker. The reason for the same has been clearly explained by Sebastian Van

This looks like a race condition; the problem here is that, when using the -v : option, docker will automatically create if the path does not exist. This functionality was marked for deprecation at some point (exactly because of these issues), but it was considered too much of a breaking change to change (see moby/moby#21666, and issues linked from that issue).

Docker for Windows (when running Linux containers) runs the docker daemon in a VM. Files/directories shared from your local (Windows) machine are shared with the VM using a shared mount, and I suspect that mount is not yet present when the container is started.

Because of that, the %USERPROFILE%/docker_shared directory is not found inside the VM, so the daemon creates that path (as an empty directory). Later, when the shared mount (from the Windows host) is present, it's mounted "on top" of the %USERPROFILE% directory inside the VM, but at that point, the container is already started.

Restarting (docker stop, docker start) resolves the situation because at that point, the shared mount is available, and the container will mount the correct path.

follow the Thread: https://github.com/docker/for-win/issues/1192 for better understanding. The issue was resolved in the Docker version 2.0.4.0 (Edge Channel) and later in the stable release.

Community
  • 1
  • 1
Shubhanshu Rastogi
  • 2,133
  • 1
  • 20
  • 30