tmpfs 挂载后之前占用目录的进程无法发现刚 mount 目录中的文件

2023-11-07 10:16:57 +08:00
 rev1si0n

问题:在终端 A 中 ls -l 只能发现之前创建的两个文件,并不能发现 file03 ,请问,是否有办法在不结束终端 A 且不切换目录的情况下,在终端 A 中显示 file03 ?如果不行,是因为什么?或者,是否有其他替代方法?谢谢各位大佬解答。

过程:开启两个终端

终端 A:

mkdir -p /tmp/workdir
cd /tmp/workdir
touch file01
touch file02
ls -la

终端 B:

sudo mount -t tmpfs tmpfs /tmp/workdir
cd /tmp/workdir

touch file03
ls -la
1059 次点击
所在节点    Linux
27 条回复
maybeonly
2023-11-07 10:20:14 +08:00
可能需要在挂载点变动后重新 cd 进去一下
timewarp
2023-11-07 10:21:49 +08:00
尽管终端 B 在 workdir 上挂了个文件系统,遮蔽了原来的目录视图,但是终端 A 的 shell 的 cwd 仍然指向原始视图,所以 A 只能看到原来的文件列表,你只需要做一次 cd ../ && cd -就能重新做一次路径查找,cwd 会遵循新的视图而设定。
rev1si0n
2023-11-07 10:22:27 +08:00
@maybeonly 感谢解答。更新了一下问题,且不能重新 cd 🤦🏻‍♀️
zhlxsh
2023-11-07 10:23:39 +08:00
1. 重新 cd 一下
2. b 操作在后的话,mount 会把 a 创建的文件屏蔽掉,umount 才恢复
ho121
2023-11-07 10:27:44 +08:00
直接 `bash` 重开一个子 shell
timewarp
2023-11-07 10:27:45 +08:00
@rev1si0n 那就直接敲命令 ls /tmp/workdir 就行了,核心就是你当前这个 A 的 bash 进程的 cwd 已经和原始 workdir 的目录项绑定了,尽管这个目录项现在成了挂载点,但是不重新做一次路径查找的话内核是无法知道这个变动的,要想进行一次路径查找,又不想 cd 目录,那就只能让其他进程代劳了,比如 ls 一下/tmp/workdir
mokiki
2023-11-07 10:29:12 +08:00
你先说出原始需求,才有可能给出替代方法
zbinlin
2023-11-07 10:29:39 +08:00
感觉是 X-Y 问题,你原来的问题是什么?
rev1si0n
2023-11-07 10:34:38 +08:00
@maybeonly
@timewarp
@zhlxsh

感谢解答。这是实际运行程序中的一个问题,我试一下在主进程重新直接 chdir 是否可行,因为有些对象可能已经占有了该目录的**引用**
timewarp
2023-11-07 10:42:27 +08:00
@rev1si0n 无须担心其他进程对此目录的“占用”,这个在内核层面只是加了个引用计数,效果只是删除目录时内核里的数据结构不释放。对路径查找没有影响的,只要重新做查找就会看到新内容。
rev1si0n
2023-11-07 11:00:46 +08:00
@mokiki
@zbinlin
@timewarp

就是重新 cd 这一步可能做不到,因为那部分在第三方 sdk 里,第三方 sdk 在程序开始时就 opendir 了(作为某个静态的对象),所以可能一直使用的都是我 mount 之前的目录结构。刚浅试了一下似乎主进程去 chdir 到 mount 的目录再回来不会影响到这个已经占有 dir 的对象但是又不能重启主进程...
timewarp
2023-11-07 11:31:41 +08:00
@rev1si0n 所以你的需求是 sdk 看到的是旧内容,但是主进程看到的是新内容,你也想让 sdk 现在看到主进程看到的新内容吗
rev1si0n
2023-11-07 11:35:08 +08:00
@timewarp 对的
BlackHole1
2023-11-07 12:48:45 +08:00
尝试挂载成 overlayfs 呢
julyclyde
2023-11-07 12:52:10 +08:00
@timewarp ls 不可能有效吧
timewarp
2023-11-07 12:56:13 +08:00
@julyclyde 有效的,只要重新做路径查找就能看到新的
timewarp
2023-11-07 12:56:44 +08:00
@rev1si0n 你一定要在目录上挂载一个文件系统吗
julyclyde
2023-11-07 12:57:53 +08:00
@timewarp 这一定是你的幻觉
timewarp
2023-11-07 13:00:50 +08:00
为今之计建议再建立一层目录,形成/tmp/common/workdir 的结构,主进程和 sdk 都切换到 common 这一层,然后主进程在 workdir 挂载文件系统,sdk 每次读取时去子目录 workdir 下找文件。这样不管 workdir 怎么被遮盖,sdk 每次都要做目录查找,看到的一定是最新的
timewarp
2023-11-07 13:05:14 +08:00
@julyclyde `ls . `这个命令不会做路径查找,而是直接获取进程 cwd ,所以看到的是老内容,但是 ls /tmp/workdir 需要解析路径,在 open 系统调用时会做 walk path ,路径分量解析到 workdir 这一层发现 dentry 设置了挂载标志,表示这是个挂载点,于是路径查找下降到子文件系统,就看到了新内容。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/989378

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX