Как программно «дернуть сетевой кабель» в большом приложении Linux? - PullRequest
4 голосов
/ 15 февраля 2012

У меня есть большое приложение C ++ в Linux со множеством собственных и сторонних библиотек, созданных и связанных с ними.

Существуют определенные части приложения, которые должны выполняться без доступа к файловой системе или сети (особенно для загрузкисетевые файлы).Периодически мы обнаруживаем, что эта операция действительно загружает файлы, как правило, из-за ошибки программиста.

Как я могу применить это в коде?Например, что-то вроде:

try {
  lockFileSystem();
  Application->DoImportantOperation();
  unlockFileSystem();
} catch ( InvalidFileSystemAccess )
{ 
 // bad programmer, no pizza
}

Или, альтернативно, существует ли какой-то обратный вызов более низкого уровня, который приложение может перехватить при открытии файла?

Примечание. Мне известно об удивительностикак правило, но дошло до того, что это необходимо применять как часть выполнения приложения, а не как специальный ручной тест.

Ответы [ 2 ]

5 голосов
/ 15 февраля 2012

Это зависит от того, что именно код пытается законно сделать, но вы могли бы сделать это с setrlimit() s RLIMIT_NOFILE.

Примерно так должно работать:

#include <sys/resource.h>

struct scoped_fd_blocker {
    rlim_t prev;
    scoped_fd_blocker() {
        rlimit lim;
        getrlimit(RLIMIT_NOFILE, &lim); // get the current limit
        prev = lim.rlim_cur; // save old limit
        lim.rlim_cur = 0; // set the soft limit to 0
        setrlimit(RLIMIT_NOFILE, &lim); // do the set
    }

    ~scoped_fd_blocker() {
        rlimit lim;
        getrlimit(RLIMIT_NOFILE, &lim); // get the current limit
        lim.rlim_cur = prev; // reset the soft limit to the previous value
        setrlimit(RLIMIT_NOFILE, &lim); // do the set
    }
};


// Example Usage:
void do_stuff() {
    scoped_fd_blocker blocker;
    Application->DoImportantOperation();
}

По сути, это говорит ОС не разрешать вашему процессу открывать дескриптор файла , даже если существующий закрыт, путем обнуления лимита дескриптора мягкого открытия файла процесса.Обратите внимание, что это больше, чем просто файлы и может иметь некоторые непредвиденные последствия.Это будет включать файлы, сокеты, объекты событий, каталоги, общие ресурсы, каналы, а также будет препятствовать тому, чтобы C-библиотеки открывали файлы.(Некоторые библиотеки C используют блокировки файлов и прочее для управления параллелизмом.) Подумайте обо всех вещах, которые открывают файлы (например, dlopen).

Любая попытка открыть дескриптор файла не удастся (возврат-1) и для errno будет установлено значение EMFILE, что означает «Ошибка 24: слишком много открытых файлов».

Я поместил все это в структуру, чтобы она была строго исключительной.

2 голосов
/ 15 февраля 2012

Не очень элегантно, но вы можете подключить, например, open () и направить его через свой собственный вызов типа proxy_open (), который имеет состояние.Если состояние "файловая система не разрешена!"затем вы просто возвращаете соответствующую ошибку и / или обрабатываете ее так, как вам нравится.

...