The std.file rename method fails in the docker environment.

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Mar 13 22:14:38 UTC 2024


On Wednesday, March 13, 2024 3:49:55 PM MDT zoujiaqing via Digitalmars-d-learn 
wrote:
> On Wednesday, 13 March 2024 at 21:21:21 UTC, Jonathan M Davis
>
> wrote:
> > On Wednesday, March 13, 2024 3:03:30 PM MDT zoujiaqing via
> >
> > Digitalmars-d-learn wrote:
> >> upload file to server in docker, but upload directory volume
> >> to host machine.
> >>
> >> Exception error:
> >> ```
> >> Invalid cross-device link
> >> ```
> >>
> >> Have other function like move(a, b) ?
> >>
> >> https://github.com/huntlabs/hunt-framework/blob/master/source/hunt/framew
> >> ork /file/File.d#L102>
> > Well, the subject of your post mentions std.file, and then you
> > link to a framework that does basically the same thing. So, I
> > don't know what you're actually using.
> >
> > However, both of those functions use the OS function, rename,
> > which renames the file within a file system, but it can't move
> > files across file systems. Strictly speaking, it's not possible
> > to move a file across file systems. What a program like mv does
> > when the destination is on a different file system from the
> > source file is copy the file and then delete the original. So,
> > if you want to "move" a file across file systems within your
> > program, you'll have to do the same thing.
> >
> > There may be a projcet on code.dlang.org which has a function
> > which tries to move the file within the file system and then
> > does a copy and remove instead if moving within the file system
> > doesn't work, but otherwise, you'll have to implement that
> > yourself, which could be as simple as catching the any
> > exceptions from move and then attempting to copy the file and
> > then remove it if an exception was thrown.
> >
> > - Jonathan M Davis
>
> this is bug in D.
>
> Docker run app code:
> ```d
> reanme("/tmp/aaa", "/data/attachments/aaa");
> ```
>
> docker volume path:
> ```txt
> VOLUME /data/attachments
> ```
>
> docker compose yml:
> ```yml
>      volumes:
>        - /data/attachments:/data/attachments
> ```
>
> Error exception:
> ```
> Invalid cross-device link
> ```

How is it a bug in D? You are attempting to rename a file across
filesystems, and that's not possible. The error is coming from the OS
function - https://www.man7.org/linux/man-pages/man2/rename.2.html - and
it's telling you what the problem is. You are attempting to rename a file
across devices / filesystems, which rename does not support. Linux's rename
doesn't even support renaming across different mount points if that
filesystem is mounted in multiple places. It's designed to do an atomic move
within a filesystem, and that's it.

The documentation for std.file's rename even explains that it won't work
across filesystems / mount points / drives:

https://dlang.org/phobos/std_file.html#rename

If you want to move a file between two separate filesystems, then you need
to copy the file, not rename it, and then if you want the original to be
gone, you can then remove it.

You may not like that, but you're trying to use rename to do something that
it does not support, because the OS function that it's a wrapper for does
not support it. std.file could theoretically add a higher level wrapper that
attempted to use rename and then copied the file and removed the original if
rename failed, but std.file does not currently provide such a function, and
rename is not intended to be that function. It's just a cross-platform
wrapper around the OS function, rename.

So, while rename may not do what you want, it is working as intended, and
it's not a bug.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list