Что такое файловый дескриптор, какая информация в нем бывает?devops-50

Что такое файловый дескриптор?

Файловый дескриптор (File Descriptor, FD) — это неотрицательное целое число, которое ядро Linux использует для идентификации открытых файловых объектов в процессе. Это абстракция для работы с:

  • Обычными файлами
  • Каталогами
  • Сетевыми сокетами
  • Каналами (pipes)
  • Устройствами

Технически — это индекс в таблице файловых дескрипторов процесса.

Структура файлового дескриптора

Каждый FD содержит метаданные о подключенном ресурсе:

КомпонентОписание
Указатель на файлСсылка на объект в ядре (struct file)
Флаги доступаРежим открытия: O_RDONLY, O_WRONLY, O_RDWR
Позиция в файлеТекущее смещение (offset) для операций чтения/записи
Inode объектаИнформация о файле в файловой системе
Операции файлаУказатели на функции (read, write, poll и др.)

Типы информации в файловом дескрипторе

1. Базовые атрибуты

  • Тип объекта:

    ls -l /proc/<PID>/fd/
    # Вывод:
    lrwx------ 1 user user 64 Jan 1 10:00 0 -> /dev/pts/0
    

    Возможные типы:

    • regular file — обычный файл
    • directory — каталог
    • socket — сетевой сокет
    • pipe — канал IPC
  • Права доступа:

    • Чтение (R)
    • Запись (W)
    • Исключительный доступ (O_EXCL)

2. Состояние дескриптора

  • Флаги статуса:

    • O_CLOEXEC — закрывать при exec()
    • O_NONBLOCK — неблокирующий режим
    • O_APPEND — запись в конец файла
  • Блокировки:

    • advisory-блокировки (fcntl)
    • POSIX-блокировки

3. Сетевые параметры

  • Локальный/удаленный адрес
  • Состояние соединения
  • Таймауты

Как просмотреть информацию о дескрипторах?

1. Через /proc

Для процесса с PID=12345:

ls -l /proc/12345/fd  # Список всех FD
cat /proc/12345/fdinfo/3  # Детали FD 3

2. Утилиты

lsof -p <PID>  # Все открытые файлы процесса
ss -pln  # Сокеты с PID владельца

3. Программный доступ

Пример на Python:

import os
print(os.fstat(0))  # Информация о stdin (FD 0)

Ограничения и лимиты

  1. Проверка текущих лимитов:
ulimit -n  # Максимальное число открытых FD
cat /proc/sys/fs/file-max  # Системный лимит
  1. Типичные проблемы:
  • "Too many open files" — исчерпание лимитов
  • Утечки дескрипторов (не закрытые сокеты/файлы)
  1. Увеличение лимитов:
ulimit -n 65536  # Для текущей сессии
# Постоянное изменение:
echo "* soft nofile 65535" >> /etc/security/limits.conf

Примеры использования в программировании

1. Создание нового FD

int fd = open("file.txt", O_RDWR | O_CREAT, 0644);
if (fd == -1) {
    perror("open failed");
}

2. Дублирование дескриптора

int new_fd = dup(old_fd);  # Создает копию

3. Неблокирующий режим

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

Особенности для DevOps

  1. Контейнеры:

    • Каждый контейнер имеет свою таблицу FD
    • Лимиты задаются через cgroups:
      docker run --ulimit nofile=1024:1024 ...
      
  2. Мониторинг:

    • Prometheus метрика:
      process_open_fds{job="node"}
      
  3. Отладка:

    • Поиск утечек:
      watch -n 1 'ls /proc/<PID>/fd | wc -l'
      

Резюмируем:

  • Файловый дескриптор — целочисленный идентификатор открытого ресурса
  • Содержит указатели, флаги, позицию и операции ввода-вывода
  • Типы файлы, сокеты, каналы, устройства
  • Критично контролировать лимиты и утечки
  • Инструменты lsof, /proc, ss, системные вызовы

Профессиональный совет: Всегда закрывайте дескрипторы явно и обрабатывайте ошибки операций ввода-вывода!