Как я могу (легко) сопоставить узел блока устройств с каталогом, на котором он установлен?

Мне нужно найти (на C или C ++) используемое пространство в файловой системе (Linux), если оно предоставляется только с именем устройства диска и номером раздела.

Для большинства файловых систем я могу:

  • Создайте имя разработчика как /dev/<block><part> или /dev/<block>p</part> зависимости от того, что существует
  • Поиск /proc/mounts mount для этого устройства и получение точки монтирования
  • Используйте statvfs() для этой точки монтирования

Хотя это кажется немного длинным, это достаточно. Однако есть предостережение:

Мой корень монтируется из /dev/root а не в имя реального блочного устройства. Кроме того, нет /dev/root – узел не существует. Теперь я могу разыменовать это имя блока /dev/<whatever> , используя stat("/"...) чтобы получить идентификатор устройства и разбить его на основные / младшие номера, затем посмотреть /sys/dev/block/<maj>:<min>/uevent для записи DEVNAME= .

Сохраняя полностью универсальную функцию, метод затем расширялся до:

  1. Создайте правильное имя устройства /dev/<block><part> или /dev/<block>p<part> , в зависимости от того, что существует
  2. Для каждой записи в /proc/mounts :
    1. Извлечь точку монтирования
    2. Получить основную / младшую пару из stat()
    3. Найдите имя родительского устройства из /sys/dev/block/<maj>:0/uevent
    4. Сравните это имя устройства с именем блока устройства и младшим с номером раздела
    5. Если это совпадение, то получите использованное пространство из statvfs()

Сейчас это очень затянуто, и мне это не нравится. Да, это должно сработать, но это далеко не идеально.

Итак – есть ли более простой интерфейс для этого? Какой-то способ непосредственного взаимодействия с таблицей монтирования в ядре? Какой-то способ получить для каждой смонтированной файловой системы блок-устройство (майор / минор будет в порядке) и путь, на котором он монтируется (вместе с другой информацией, вероятно) в структуре?

Я знаю, что есть функции mount() и umount() , но есть ли функция "tell me what is mounted"() ?

One Solution collect form web for “Как я могу (легко) сопоставить узел блока устройств с каталогом, на котором он установлен?”

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

Метод, который вы предлагаете, выглядит достаточно тщательным, и я думаю, что он поймает все случаи.

О поиске ip in /sys/dev/block :

  • Вы не ищете <maj>:0 как вы заявляете. Вы ищете <major>:<minor> .
  • Будьте готовы к случаю, когда вы его не найдете. Некоторые файловые системы, такие как /proc , и тип tmpfs и nfs имеют соответствующего устройства. Вы захотите проигнорировать их, поскольку они не могут соответствовать интересующему вас блочному устройству.

При поиске имени устройства не сканируйте /sys/dev/block/<major>:<minor>/uevent . Вместо этого в readlink() on /sys/dev/block/<major>:<minor> и возьмите базовое имя результата. Вы должны получить тот же результат, но он немного чище и эффективнее.

Если вы хотите найти несколько устройств, вы должны сканировать /proc/mounts и выполнять поиск всего /sys только один раз и кэшировать результаты для следующего поиска устройства.

Системного вызова show_me_mounts() . В Linux это то, для чего /proc/mounts . Но, как вы заметили, это не идеально. Как правило, вы не увидите проблему виртуального / несуществующего /dev/root хотя с полной загрузкой на основе initramfs.

Измените в соответствии с вашим требованием найти весь диск, соответствующий каждому разделу.

Для получения «внешнего» блочного устройства (= целого диска) с учетом «внутреннего» блочного устройства (= раздел) вы не можете просто изменить номер младшего устройства на 0.

Правильный способ сделать это, если вы найдете основные 8 и младшие 1, – это посмотреть в этом файле:

 /sys/dev/block/8:1/../dev 

Это приведет к 8:0 , но без неправильного предположения, что младший идентификатор устройства всегда может быть переключен на 0.

Если вы пытаетесь открыть ENOENT , это связано с тем, что тип рассматриваемого блочного устройства не имеет внутренней / внешней иерархии, или младший идентификатор устройства не соответствует внутреннему устройству.

  • Посмотрите документацию по типам C?
  • Неопределенная ссылочная ошибка для компонентов glip даже с включенным glib
  • Ошибка файла conio.h
  • Построить log4cxx
  • Как я могу скомпилировать minix при внесении изменений в библиотеки
  • Где исходный код реализации «scanf»?
  • Выполнение общей библиотеки
  • Я хочу участвовать в разработке ядра Linux, где я могу найти то, что нужно сделать?
  • Как разрешить обратные пространства в небуферизованном / неканоническом режиме?
  • лучший язык программирования для интенсивных задач ввода / вывода
  • Запуск скомпилированной программы на C ++ в фоновом режиме и отправка ввода при необходимости
  • Linux и Unix - лучшая ОС в мире.