那个设定
假设我有一个可执行文件,我们称之为program
,其源代码不可用(可能是专有/遗留)。
每次执行该程序时,它都会生成一个文件,我们将其称为file.txt
,始终具有相同的名称并且始终位于同一目录,具体取决于传递给 的命令行参数program
。
问题
我想program
同时执行多个实例。这可能发生program
在服务器正在侦听program
来自客户端的执行请求的上下文中。
问题是,这似乎是不可能的,只要两个实例都会写入同一个file.txt
,因此该文件最终可能会被损坏。
可能的解决方案想法
- 我可以以某种方式将
program
的输出重定向到具有唯一名称的文件(请记住源已丢失)吗? - 我可以以某种方式“沙箱”
program
使它的行为就像在单独的文件系统上执行一样(开销可以忽略不计)吗? - 我听说过
LD_PRELOAD
,但我不知道它是否只适用于重写 C 标准库函数,或者它是否也适用于一般的重写 Linux 系统调用。
任何想法?
答案1
每次执行该程序时,它都会生成一个文件,我们将其称为“file.txt”,始终具有相同的名称并且始终位于同一目录中,该文件根据传递给程序的命令行参数而有所不同。
如果程序是动态可执行文件,您可以通过以下方式使用函数插入LD_PRELOAD
使其将文件写入不同的位置(例如,由环境变量指定的位置)。这意味着拦截对 的调用open
,检查该open
调用是否针对file.txt
,然后运行适当的替代方案。
如果程序作为 systemd 服务启动,则可以使用PrivateMounts
选项在自己的挂载命名空间中运行它,并挂载一个可以在其中写入file.txt
.
正如 @glennjackman 在评论中建议的那样,您还可以安排在容器中运行该进程:这实际上与之前的解决方案相同,但您使用的是 Docker 或 Podman 等容器运行时来设置,而不是 systemd挂载命名空间。
在上述选项中,在容器内运行它可能是操作上最简单的。
我听说过“LD_PRELOAD”,但我不知道它是否只适用于覆盖 C 标准库函数,或者它是否也适用于一般的覆盖 Linux 系统调用。
函数插入viaLD_PRELOAD
仅允许您拦截函数调用,而不是系统调用。但这通常很好:当您的代码调用 时open
,它并不是直接调用系统调用open
;而是调用 syscall 。它调用一个 glibc 包装函数,该函数又调用系统调用。