在Linux中创建虚拟文件

时间:2015-12-01 17:21:29

标签: linux file-io filesystems virtual

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

foo=bar
x=param1

foo=bar
x=param2

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

1 个答案:

答案 0 :(得分:1)

(发布作为答案,因为评论太长了。)

您可能会发现使用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()声明为varargs函数,但最初C没有原型,因此所有函数都事实上 vararg函数。 open()调用仅在需要时访问mode参数,因此open()并不总是需要传递mode参数。使用当前的C,唯一的方法是使用vararg函数。这使得#include文件对此代码有问题,因为open()的任何声明都将是vararg,这将导致代码无法编译。为了编译,您可能需要将mode_t替换为int(或者typedef的任何内容)。

使用cc [-m64|-m32] -shared source.c -ldl -o mylib.so编译。您需要在-ldl中链接dlsym(),并且需要正确的-m64-m32选项才能获得与您的应用匹配的64位或32位库。< / p>

然后将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()的多线程访问的问题。