LINUX.ORG.RU

перехватывать mount событие

 , ,


0

2

Есть ли способ в программе перехватывать события монтирования ФС? Читал man 7 inotify но там таких возможностей не предусмотрено. ОС Ubuntu 16.04.6 и ядро 5.1.0-rc5

По возможности хотелось бы обойтись без сторонних пакетов.

★★

Я не отслеживаю изменения в ядре особенно, но, по-моему, такого механизма *пока* нет. Тебе остается только polling. Однако я где-то читал совсем недавно, что кто-то работал над механизмами оповещения в ядре. Там в том числе было оповещение о монтировании. Попробую вспомнить и найти.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

man proc напоминает: в этом вашем линуксе придумали какие-то неймспейсы и увидите вы только то, что лежит в вашем.

anonymous
()
Ответ на: комментарий от Zubok

Ага, нашел. Вот David Howells это делал в прошлом году:

https://lkml.org/lkml/2018/7/23/859

https://lwn.net/Articles/760714/

Спасибо. Интересные патчи, но судя по всему их не приняли в upstream, в нынешнем net-next.git я ничего похожего не вижу.

cruz7 ★★
() автор топика
Ответ на: комментарий от anonymous

udev?

Посмотрел udev и uevent. Открыл netlink-сокет типа NETLINK_KOBJECT_UEVENT, прибиндился, слушаю события, но ничего касающегося файловой системы не наблюдаю. Вижу события от usb подсистемы (когда вставляю/вытаскиваю usb-стик), события от power_supply (аккумулятор на ноуте).

Стал рыть дальше. Нашел что в ядре за посылку uevent отвечает функция kobject_uevent_env(): https://elixir.bootlin.com/linux/v5.1-rc7/source/lib/kobject_uevent.c#L456

Поискал по дереву ядра, этот API используется в drivers/*, sound/* и в fs/gfs2/* (единственное относящееся к ФС).

cruz7 ★★
() автор топика
Ответ на: комментарий от cruz7

(единственное относящееся к ФС).

Ещё вангую, что искать надо не в fs. Ядро посылает сообщение о новом устройстве -> udev в юзерспейсе решает, что на устройстве есть файловая система -> udev монтирует устройство.

anonymous
()
Ответ на: комментарий от anonymous

Ещё вангую, что искать надо не в fs. Ядро посылает сообщение о новом устройстве -> udev в юзерспейсе решает, что на устройстве есть файловая система -> udev монтирует устройство.

Я проверил с помощью «udevadm monitor», получает такие же события что и моя программка. Даже strace-ом проверил как создается и биндится сокет — все так же.

Сделал service udev stop, но это ни на что не повлияло.

Мне как бы нужны события монтирования/демонтирования ФС, все же я склоняюсь к тому что udev для этого не предназначен.

cruz7 ★★
() автор топика
Ответ на: комментарий от cruz7

Мне как бы нужны события монтирования/демонтирования ФС, все же я склоняюсь к тому что udev для этого не предназначен.

Потыкал в udev. udevadm monitor показывает, когда втыкается новое блочное устройство в компьютер. Что логично, т. к. одна из задача udev, afaik — автоматически монтировать подключённые флешки. Если ты руками монтируешь, то он об этом видимо ничего не знает.

На днях была тема про перехватывание сисколов. Попробуй ловить mount/umount.

У меня такое подаёт признаки жизни (если что, я понятия не имею КАК оно работает и насколько тормозит ядро):

bpftrace -e 'tracepoint:syscalls:sys_enter_mount { printf("фиг знает что сюда писать\n"); }'

Вангую, надо ещё проверять был ли сискол успешно выполнен.

anonymous
()
Ответ на: комментарий от anonymous

У меня такое подаёт признаки жизни (если что, я понятия не имею КАК оно работает и насколько тормозит ядро):

bpftrace -e 'tracepoint:syscalls:sys_enter_mount { printf(«фиг знает что сюда писать\n»); }'

Трейсить системные вызовы это IMHO слишком тяжелая артиллерия для моей задачи, но покопать есть смысл. Спасибо.

cruz7 ★★
() автор топика
Ответ на: комментарий от cruz7

Так может просто отредактировать всех, кто может вызывать mount(), чтобы отправляли тебе сообщение? Или сделать LD_PRELOAD= враппер для mount().

anonymous
()
Ответ на: комментарий от anonymous

Или сделать LD_PRELOAD= враппер для mount().

Тут IMHO засада. То что указано в LD_PRELOAD будет загружено до того, как все остальные библиотеки, включая libc, соответственно в этом враппере я не смогу вызвать «оригинальный» mount()

Потому как я вижу это так: враппер вызывает библиотечный mount() , если все успешно выполнилось то, например посылает сигнал, а приложение этот сигнал обрабатывает, т.е. как бы получили событие о монтировании.

cruz7 ★★
() автор топика
Ответ на: комментарий от anonymous

Переписать символ через LD_PRELOAD имеет недостаток, что кто-то может сискол напрямую дёргать и обёртка об этом не узнает.

До меня внезапно допёрло, что можно через LD_PRELOAD устанавливать seccomp-фильтры. Начал я это дело ковырять.

Это поделие пишет каждый вызов mount/umount2 в сислог. Но без параметров.

Это поделие перехватывает все вызовы mount/umount2, которые были сделаны не из функции syscall6. На каждый такой вызов ядро посылает просессу SIGSYS. В обработчике сигнала вызывается нужный сискол через syscall6, которая уже не перехватывается.

Анонимус напоминает: вызывать что-то в обработчике сигналов чревато проблемами.

anonymous
()

Варианты: 1. Получать события от udisks через dbus. 2. Посмотреть, как это делает udisks, сделать аналогично. ЕМНИП через тот же inotify мониторит что-то типа /proc/nounts.

zloy_starper ★★★
()
Ответ на: комментарий от anonymous

До меня внезапно допёрло, что можно через LD_PRELOAD устанавливать seccomp-фильтры. Начал я это дело ковырять.

Спасибо, это интересная идея! Я имел дело с cBPF фильтрами, думаю разберусь.

cruz7 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.