在 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()
时可能会出现问题。
我正在使用一些我无法更改的现有软件,它从一堆配置文件中加载其配置数据,所有配置文件都遵循相同的命名方案——比方说,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()
时可能会出现问题。