在 Linux 中制作虚拟文件

Making a virtual file in Linux

我正在使用一些我无法更改的现有软件,它从一堆配置文件中加载其配置数据,所有配置文件都遵循相同的命名方案——比方说,file_param1.conf、file_param2.conf、file_param3.conf 等。文件内容之间的区别只是 param1 vs param2 vs param3,因此典型的配置文件看起来像

foo=bar
x=param1

foo=bar
x=param2

是否有任何关于在 Linux 中创建虚拟文件系统的示例,可以让我在访问 file_param1.conf 时使用适当的参数变量动态生成文件?我知道 scriptfs 但不知道有关使用它的任何教程。

(作为答案发布,因为这对于评论来说太长了。)

您可能会发现使用 LD_PRELOAD 库并插入 open()/fopen()/open64() 或您现有的任何确切的库调用更容易软件用于访问您的配置文件,并将应用程序提供的文件名替换为指向您要使用的文件的文件名。

这段代码不在我的脑海中,我还没有尝试编译它:

#include <dlfcn.h>

// don't want to #include anything else or we're likely to get
// the vararg prototype for open()
int strcmp( const char *s1, const char *s2 );

// typedef a function pointer
typedef int ( *open_func_ptr_t )( const char *, int, mode_t );
static open_func_ptr_t real_open = NULL;

int open( const char *pathname, int flags, mode_t mode )
{
    // find the real open() call
    if ( real_open == NULL )
    {
        real_open = ( open_func_ptr_t ) dlsym( RTLD_NEXT, "open" );
    }

    if ( 0 == strcmp( pathname, "/path/to/config/file" );
    {
        pathname = "/path/to/replacement/config/file";
    }

    return( real_open( pathname, flags, mode ) );
}

该代码依赖于这样一个事实,尽管由于对当前 C 代码的限制,open() 被声明为可变参数函数,但最初 C 没有原型,因此所有函数都是 事实上 可变参数函数。 open() 调用仅在需要时访问 mode 参数,因此 open() 并不总是需要传递 mode 参数。对于当前的 C,唯一的方法是使用 vararg 函数。这使得 #include 文件与此代码有问题,因为 open() 的任何声明都将是 vararg 声明,这将导致代码无法编译。您可能需要将 mode_t 替换为 int(或 typedef 的任何内容)才能编译。

cc [-m64|-m32] -shared source.c -ldl -o mylib.so 编译它。您需要 dlsym() 中的 -ldl 到 link,并且您需要正确的 -m64-m32 选项来获取 64 位或 32 位库以匹配你的申请。

然后将 LD_PRELOAD 设置为您的 .so 文件:

LD_PRELOAD=/path/to/mylib.so
export LD_PRELOAD

然后 运行 您的应用程序设置为 LD_PRELOAD。您还需要非常小心,您的应用程序生成的任何子进程都与共享对象 LD_PRELOAD 设置的相同 32 位或 64 位。如果您不想混合处理 32 位和 64 位进程,请阅读 man page for ld.so 并特别注意 $PLATFORM 部分。

另请注意,由于竞态条件修改 real_open,代码不可重入,并且多线程访问 open() 时可能会出现问题。