2015-12-01 3 views
2

Я работаю с каким-то существующим программным обеспечением, которое я не могу изменить, и он загружает свои данные конфигурации из группы конфигурационных файлов, все следуют одной и той же схеме именования - скажем, file_param1.conf, file_param2 .conf, file_param3.conf и т.д. разница между содержанием файлов просто param1 против Param2 против param3, поэтому типичный конфигурационный файл будет выглядетьСоздание виртуального файла в Linux

foo=bar 
x=param1 

или

foo=bar 
x=param2 

есть ли примеры в любом месте создания виртуального fs в Linux, что позволило бы мне получить доступ к file_param1.conf динамически генерирует файл с соответствующей переменной param? Я знаю о скриптах, но не о каких-либо учебниках по его использованию.

ответ

1

(Проводка в качестве ответа, потому что это слишком долго для комментария.)

Вы можете найти его проще использовать LD_PRELOAD библиотеки и вставляет на точном вызове библиотеки в open()/fopen()/open64() или любого (s) ваше существующее программное обеспечение использует для доступа к вашему конфигурационному файлу и заменяет имя файла, предоставленного приложением, на тот, который указывает на файл, который вы хотите использовать.

Этот код с верхней части моей головы, и я не пробовал его компиляции:

#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)); 
} 

Этот код основан на том факте, что, хотя open() объявлена ​​как функция с переменным числом аргументов из-за ограничений, налагаемых на текущий C-код, первоначально C не имел прототипов, поэтому все функции были de facto функции vararg. При вызове open() доступ только к аргументу mode, поэтому open() не всегда должен быть передан аргумент mode. С текущим C единственный способ сделать это с помощью функции vararg. Это делает файлы #include проблематичными с этим кодом, поскольку любое объявление open() будет vararg, и это приведет к тому, что код не будет компилироваться. Возможно, вам придется заменить mode_t на int (или что бы то ни было, typedef 'd) для компиляции.

Скомпилируйте это с помощью cc [-m64|-m32] -shared source.c -ldl -o mylib.so. Вам понадобится -ldl для связи в dlsym(), и вам понадобится подходящая опция -m64 или -m32, чтобы получить 64- или 32-разрядную библиотеку в соответствии с вашим приложением.

Затем установите LD_PRELOAD ваш .so файл:

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

Затем запустите приложение с LD_PRELOAD набором. Вы также должны быть очень осторожны, чтобы любые дочерние процессы, порожденные вашим приложением, были одинаковыми 32- или 64-разрядными, поскольку установлен общий объект LD_PRELOAD. Если вам не нужны смешанные 32- и 64-битные процессы для рассмотрения, прочитайте man page for ld.so и обратите особое внимание на раздел $ PLATFORM.

Обратите внимание, что код не является реентерабельным из-за состояния гонки, изменяя real_open и может иметь проблемы с многопоточным доступом к open().