Существует процесс apache, который регистрирует доступ и журнал ошибок. Два файла журнала были удалены, но процесс apache не был перезапущен или перезагружен, поэтому у него все еще есть открытые дескрипторы файлов для этих файлов журнала.

Я могу получить доступ к содержимому файла, прочитав дескриптор файла из каталога /proc :

$ sudo lsof +p 30304
...
rotatelog 30304 root    4w   REG  251,0 22480405     265346 /var/log/httpd/error_log-2014-09-11 (deleted)

Если я затем проверяю файловые дескрипторы для этого процесса, я вижу файл:

$ ls -l /proc/30304/fd
...
l-wx------ 1 root root 64 2014-09-11 10:18 4 -> /var/log/httpd/error_log-2014-09-11 (deleted)

Я также вижу индекс для этого файла:

$ ls -i /proc/30304/fd/4
1936760177 /proc/30304/fd/4

Я могу скопировать этот файл, чтобы получить текущий контент, но любые будущие сообщения журнала не будут отображаться в скопированном файле. Есть ли способ создать файл с таким номером инода?

Это похоже на использование ln для создания жесткой ссылки на файл, но без ссылки на существующий файл.

1 ответ1

1

У вас есть существующий файл справки - один в /proc/30304/fd Использовать его немного сложно, так как обычная ссылка () не принимает его. Вам нужно будет использовать linkat ().

Написать небольшую программу на Си. Поместите это в foo.c:

#include <fcntl.h>
#include <err.h>

int main(int argc, char *argv[]) {
    char *src, *dstdir, *dstname;
    int dirfd, r;

    if (argc < 4)
        errx(2, "not enough parameters");

    src = argv[1]; dstdir = argv[2]; dstname = argv[3];

    dirfd = open(dstdir, O_DIRECTORY);
    if (dirfd < 0)
        err(1, "open(%s) failed", dstdir);

    r = linkat(AT_FDCWD, src, dirfd, dstname, AT_SYMLINK_FOLLOW);
    if (r < 0)
        err(1, "linkat(%s, %s/%s) failed", src, dstdir, dstname);

    return 0;
}

Запустите это как:

make foo
./foo '/proc/30304/fd/4' '/var/log' 'recovered.log'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .