Мой юниксвейный mnt. Часть 3: укрощение сидишника и немного GUI.

Начало здесь:
Часть 1: Системный диск, имена и группы.
Часть 2: Флешки, диски и прочие карточки.

3.1. CD/DVD и их специфика.

В прошлый раз я остановился на том, что CD/DVD-привод – устройство весьма специфическое. И это действительно так!

С одной стороны, он всегда предсказуемо /dev/sr0 (если вы вдруг не завели две штуки, что вряд ли); он уже в группе optical, и для этого не надо придумывать своих правил udev. Казалось бы, записать его в fstab с опциями "user,noauto" будет уже достаточно.

Но с другой стороны, у сидишника есть свои очень неприятные особенности:
1) очень большое и не очень предсказуемое время опознавания диска, нередко побивающее все системные таймауты.
2) уже после успешного монтирования, ядро может внезапно и без объявления войны пересоздать устройство sr0, и диск снова окажется не смонтированным.
3) мелочь, но неприятно: на дисках могут быть разные ФС, и даже стандартные iso9660 и UDF не вполне совместимы между собой по специфическим опциям монтирования, а значит fstab уже не совсем подходит.

В результате был написан скрипт mcd , который делает попытки монтирования диска до победного конца, а после этого ещё и проверяет, не надо ли начинать всё с начала.

Чтобы решить проблему с разными опциями, я использовал в нём уже описанный в предыдущей части smount, который для каждой ФС берёт из конфига отдельный набор опций монтирования.

Для отмонтирования я использую либо команду umcd (симлинк на mcd), либо (чаще) просто eject
Поскольку диск смонтирован, eject вызывает от пользователя стандартную команду umount, а из неё, благодаря использованной при монтировании опции "uhelper=smount", вызывается команда отмонтирования по симлинку /usr/bin/umount.smount -> /usr/local/bin/smount , после чего eject успешно отрабатывает извлечение диска.

Выглядит это примерно так. Вставляю и монтирую. Очевидно, это дивиди-видео, поэтому UDF:
$ mcd
Файловая система Тип  Размер Использовано  Дост Использовано% Cмонтировано в
/dev/sr0         udf    7.5G         7.5G     0          100% /media/cdrom
$ ls /media/cdrom/
VIDEO_TS
Можно посмотреть, с какими опциями он смонтировался:
$ grep sr0 /proc/mounts 
/dev/sr0 /media/cdrom udf ro,nosuid,nodev,noexec,relatime,uid=1000,gid=100,mode=644,dmode=755,utf8 0 0
$ grep sr0 /run/mount/utab
SRC=/dev/sr0 TARGET=/media/cdrom ROOT=/ OPTS=user,helper=smount,uhelper=smount
И если я сделаю eject, он нормально отмонтируется и извлечётся.

Пробую другой диск:
$ mcd
Файловая система Тип     Размер Использовано  Дост Использовано% Cмонтировано в
/dev/sr0         iso9660   1.6G         1.6G     0          100% /media/cdrom
$ ls -l /media/cdrom/
итого 2502
-rw-r--r-- 1 user users     134 апр 25  2012 autorun.inf
drwxr-xr-x 1 user users    2048 апр 25  2012 boot
drwxr-xr-x 1 user users    2048 апр 25  2012 casper
drwxr-xr-x 1 user users    2048 апр 25  2012 dists
drwxr-xr-x 1 user users    2048 апр 25  2012 efi
drwxr-xr-x 1 user users    2048 апр 25  2012 install
drwxr-xr-x 1 user users   18432 апр 25  2012 isolinux
-rw-r--r-- 1 user users   21922 апр 25  2012 md5sum.txt
drwxr-xr-x 1 user users    2048 апр 25  2012 pics
drwxr-xr-x 1 user users    2048 апр 25  2012 pool
drwxr-xr-x 1 user users    2048 апр 25  2012 preseed
-rw-r--r-- 1 user users     234 апр 25  2012 README.diskdefines
lr-xr-xr-x 1 user users       1 апр 25  2012 ubuntu -> .
-rw-r--r-- 1 user users 2504112 апр 24  2012 wubi.exe
Старый установочник убунты, ISO9660 с юниксовыми расширениями RockRidge.
Смотрим опции:
$ grep sr0 /proc/mounts 
/dev/sr0 /media/cdrom iso9660 ro,nosuid,nodev,noexec,relatime,mode=0644,dmode=0755,utf8,overriderockperm,uid=1000,gid=100 0 0
$ grep sr0 /run/mount/utab
SRC=/dev/sr0 TARGET=/media/cdrom ROOT=/ OPTS=user,helper=smount,uhelper=smount
Как видите, для ISO9660 установлены уже несколько другие опции, включая overriderockperm , которая принудительно устанавливает заданные атрибуты mode=0644,dmode=0755 даже для такого диска, и если скопировать оттуда какие-то файлы, они уже НЕ будут "только для чтения". Мелочь, а приятно :)

Итак, mcd
#!/bin/bash

#config defaults
DEV=/dev/sr0
MN=cdrom
TIMEO=30

err() {
 echo "$@" >&2
 exit 1
}

timesec() {
 TIME=`date +%s`
 [[ -n "$1" ]] && START=$TIME
 let SEC=TIME-START
 ((SEC>0)) && printf "%s\r" $SEC
}

NAME="${0##*/}"

sw=
while read -a C ; do
 c="${C[0]}"
 case "$c" in
 \[cd\]|\[CD\])
  sw=cd
  ;;
 \[*)
  sw=
  ;;
 \#*|'')
  ;;
 *)
  case "$sw" in
  cd)
   o="${C[1]}"
   case "$c" in
   device)
    DEV="$o"
    ;;
   mount)
    MN="$o"
    ;;
   timeout)
    TIMEO="$o"
    ;;
   esac
   ;;
  *)
   ;;
  esac
  ;;
 esac
done < /etc/mnt.conf

MNT="smount $DEV $MN"

case "$NAME" in
mcd)
 timesec start
 while ((SEC<TIMEO)) ; do
  $MNT 2>&-
  sleep 0.5
  if grep -q "$DEV" /proc/mounts ; then
   df -hT "$DEV"
   exit 0
  fi
  ((SEC==0)) && eject -t "$DEV"
  sleep 0.5
  timesec
 done
 $MNT
 ;;
umcd)
 usmount "$DEV"
 ;;
*)
 err Unknown command "$NAME"
 ;;
esac

3.2. Автоматическое отмонтирование CD

Я не пользуюсь автоматическим монтированием, а автоматическое отмонтирование флешек – задача и вовсе безнадёжная, поскольку после физического выдёргивания носителя, отмонтировать его уже поздно.
CD/DVD-привод – фактически единственное устройство, для которого автоматическое отмонтирование действительно реализуемо, что я и сделал.

С некоторых пор встроенное правило UDEV 60-cdrom_id.rules автоматически блокирует лоток CD, чтобы при нажатии на кнопку извлечения диска получить от привода сигнал "DISK_EJECT_REQUEST". После нажатия на кнопку это же правило автоматически разблокирует и выдвигает лоток, нисколько не заботясь об отмонтировании ФС.

Чтобы изменить такое поведение UDEV, я создал правило, дав ему номер 21, то есть расположив его в очереди раньше встроенного, чтобы перехватить сигнал от кнопки привода:
/etc/udev/rules.d/21-eject-cd.rules
KERNEL=="sr*", ACTION=="change", ENV{DISK_EJECT_REQUEST}=="?*", GOTO="cd_eject"
GOTO="cd_end"

LABEL="cd_eject"
# сбрасываем сигнал, чтобы встроенное правило
ENV{DISK_EJECT_REQUEST}="" # не открыло лоток без разрешения
RUN+="/usr/bin/systemctl --no-block start eject-cd@%k" # и вызываем собственный обработчик

LABEL="cd_end"
В этом же правиле я очищаю переменную DISK_EJECT_REQUEST, чтобы штатный обработчик UDEV не получил сигнал от кнопки, и не открыл лоток без отмонтирования.

Чтобы не тормозить работу UDEV, и чтобы обойти лимит времени выполнения дочерних процессов UDEV, я вызываю свой обработчик события через systemctl. Советую этот способ для всех аналогичных случаев, когда вызываемый из правила процесс может затянуться, чтобы UDEV не счёл его "зависшим" и не убил раньше времени.

Сам по себе юнит-обработчик предельно прост. Просто вызываем eject:
/etc/systemd/system/[email protected]
[Unit]
Description=Eject CD %I

[Service]
Type=oneshot
ExecStart=/usr/bin/eject %I
Всё остальное делает сам eject – проверяет наличие смонтированной ФС и пытается отмонтировать.
Если диск смонтирован с помощью smount – этот скрипт автоматически запускается через опцию helper=smount (здесь eject запускается от рута, поэтому имеет значение именно опция helper, а не uhelper), отмонтирует ФС и очищает точку монтирования..
Если диск не был смонтирован, или был отмонтирован успешно, eject сам разблокирует и открывает лоток, если нет – диск остаётся на месте, как и положено.

3.3. немножко GUI.

Я не пользуюсь файл-менеджерами. Совсем. Управление серверами по ssh приучило к консоли, а некоторые эксцессы в MC отучили совмещать его с командами в консоли, что снизило для меня его ценность практически до нуля. Если надо что-то скопировать с флешки или на флешку, я просто пишу в консоли mnt , потом cp -p или cp -a что-то там куда-то там, благо автодополнение по TAB позволяет не набирать имена файлов и каталогов целиком, а потом umt и выдёргиваю.

Тем не менее, так как настраивать линукс мне приходится не только для себя, я стал задумываться, а нельзя ли избавиться от udisks и там? К сожалению, в большинстве известных мне файлменеджеров udisks прибиты гвоздиками, но тут я вспомнил про spacefm – клон pcmanfm, который позволяет настраивать команды монтирования по вкусу.

Специально для встраивания в файлменеджер, поддерживающий только одну общую команду для монтирования только одного, но любого устройства, и одну такую же для отмонтирования, я сделал mntcmd – небольшой скрипт-обёртку для mnt и mcd , выбирающий нужную команду в зависимости от заданного устройства.

В меню spacefm "Устройства – Настройки – Команда монтирования" я вписал
mntcmd %v
а в "Устройства – Настройки – Команда размонтирования"
mntcmd -u %v
spacefm успешно монтирует и отмонтирует флешки и CD/DVD.

Вот сам скрипт mntcmd
#!/bin/bash

sw=
while read -a C ; do
 c="${C[0]}"
 case "$c" in
 \[cd\]|\[CD\])
  sw=cd
  ;;
 \[*)
  sw=
  ;;
 \#*|'')
  ;;
 *)
  case "$sw" in
  cd)
   o="${C[1]}"
   case "$c" in
   device)
    DEV="$o"
    ;;
   esac
   ;;
  *)
   ;;
  esac
  ;;
 esac
done < /etc/mnt.conf

M=m
D=f
if [[ "$1" = '-u' ]] ; then
 M=u
 shift
fi
[[ "$1" = "$DEV" ]] && D=c

case "$M$D" in
mf)
 mnt "$1"
 ;;
uf)
 umt "$1"
 ;;
mc)
 mcd
 ;;
uc)
 umcd
 ;;
esac

На этом я заканчиваю рассказ о моих скриптах монтирования. До новых скриптов :)
Надеюсь, вам было интересно.
Надеюсь, вам было интересно.

Интересно очень!
И огромное спасибо за труд!
конечно, простите за некомпетентность, с линуксом знаком совсем недавно, и может чуть-чуть ни к месту)). А смысл вот этого всего? Если нет толклм никакой автоматизации... какие то команды пачками, пока во всём разберёшся и так все параметры mount и umount наизусть выучишь и mount -t auto без ошибчно определяет фс. Да и посмотреть как в /dev определилась флэшка не вижу проблемы (был казус когда фс была поямо на /dev/sdb)).
Кароче вопрос почему это не работает через udev? на вики написанно что то про защищённые фс (русская вики вобще в отрыве от жтзни), и тп. Но в интернете много примеров с ntfs и тп. Значит когда то оно работало? Может кто нить ответить?
Ошибки в тексте-неповторимый стиль автора©
А смысл вот этого всего?
ind.indeviral, не видишь смысла, забей, оно тебе не нужно!
и mount -t auto без ошибчно определяет фс
зачем -t auto? оно и без этого все определяет без ошибочно (даже без прописывания в fstab, как многие это еще до сих пор делают), при условии что все правильно сделано.
Псевдографический инсталлятор Arch Linux ver. 3.8.2
Благодарности принимаются на ЯД 410012815723874
Я не знал как конкретно задать вопрос поэтому трохи переборщил с ненужным текстом...
Вопрос в том почему нельзя использовать udev (скорее даже почему не сделают поддержку ntfs, exfat и тп), а не запускать самому вообще никаких скриптов (треть функционала которых это функции которые "в моём понимании" должны идти через udev), почему эту фишку никто не юзают, а парятся с написанием килотон скриптов?

p.s. можно даже ссылочку куда мне идти))
mount -t auto это как бы значение по умолчанию ( -t auto можно неписать), когда исполняется mount type fs используется auto если не указано другого...
Ошибки в тексте-неповторимый стиль автора©
"Зачем оно надо и почему не через удев." Помнится Натрио где то на форуме ругался в извращенной литературной форме что удев от версии к версии работает всё хуже. Из за того что из него сделали этакого монстра. Подробностей уже не помню. Потому и скрипт параноидально проверяющий наличие диска в приводе. И скрипт косвенными признаками проверяющий плохой контакт на флешках(стерлась позолота. Вроде в тексте все написано)
Да пребудет с вами знание ip адреса
ind.indeviral, вы, пожалуй, действительно переборщили с текстом. Вместо всего этого можно было просто спросить – почему тут нет автомонтирования?

Отвечаю – мне не нужно автомонтирование, потому его и нет. Не всегда мне требуется монтировать то, что я вставляю, а иногда это вообще нежелательно.
Кроме того, отмонтировать (или на худой конец делать sync) всё равно придётся руками, потому что после физического выдёргивания из USB, отмонтировать уже поздно :)
А так, в принципе, сделать автомонтирование совсем не сложно, достаточно сделать юнит для mnt, и повесить на udev запуск этого юнита. (Напрямую запускать из udev монтирование нежелательно, потому что монтирование может длиться довольно долго, а в udev очень короткий таймаут.)


какие то команды пачками, пока во всём разберёшся и так все параметры mount и umount наизусть выучишь
Это потому, что я писал не хауту для начинающих, а развернутую статью в трёх частях с полными текстами всех скриптов и объяснениями, как они работают.
На самом деле весь этот набор скриптов легко можно собрать в один пакет с инсталлятором (для полу/автоматического прописывания в правило udev одного или больше "системных" дисков), и на поверхности останутся в четыре коротких команды, как правило без параметров:
mnt монтирует все флешки и переносные винчестеры,
umt всё это отмонтирует,
mls показывает что подключено и что смонтировано,
mcd монтирует сидишники, и к нему в пару eject, но он штатный и стандартный.

Команды намеренно сделаны такими короткими, и работающими по возможности без параметров, чтобы было удобнее набирать их в консоли.
А о том, что я предпочитаю консоль всяческим файл-менеджерам, я уже писал :)

mount -t auto без ошибчно определяет фс.
nafanja
зачем -t auto? оно и без этого все определяет без ошибочно (даже без прописывания в fstab, как многие это еще до сих пор делают), при условии что все правильно сделано.
Совершенно верно, mount отлично умеет сам определять ФС, только мне нужно определить не только ФС, но и параметры к ней, и не умолчальные, а такие, как нужно мне.

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

Ничего особенного в таком методе работы нет – точно так же работают и pmount, и udisks, и udevil – просто в первых двух вместо конфига список опций намертво захардкодили, что меня категорически не устраивает, а вот у udevil вполне нормальный конфиг, почти как у меня, просто мне было удобнее написать свой скрипт на замену pmount, чем приспосабливать udevil, который работает не совсем так, как мне нужно.

Кстати, если вам нужно автомонтирование, можете попробовать udevil, в нём оно, насколько я помню, предусмотрено.
Natrio
монтирование может длиться довольно долго, а в udev очень короткий таймаут
Спасибо))
Ошибки в тексте-неповторимый стиль автора©
Недавние раскопки в событиях ядра и UDEV, сопровождающих загрузку и извлечение CD, побудили меня добавить обработку кнопки извлечения диска.

С некоторых пор правило udev 60-cdrom_id.rules автоматически блокирует лоток CD, чтобы при нажатии на кнопку извлечения диска получить от привода сигнал "DISK_EJECT_REQUEST":
# import device and media properties and lock tray to
# enable the receiving of media eject button events
IMPORT{program}="cdrom_id --lock-media $devnode"
а после нажатия на кнопку – автоматически разблокирует и выдвигает лоток, нисколько не заботясь об отмонтировании ФС:
# media eject button pressed
ENV{DISK_EJECT_REQUEST}=="?*", RUN+="cdrom_id --eject-media $devnode", GOTO="cdrom_end"

Тем самым разработчики UDEV захватили механизм блокировки лотка, и использовав его не по назначению – всего лишь для получения сигнала от кнопки, лишили все остальные программы возможности блокировать лоток, когда диск на самом деле занят.

Чтобы хотя бы частично исправить это давно надоевшее мне безобразие, а заодно наладить автоматическое отмонтирование диска при нажатии на кнопку, я добавил своё правило 21-eject-cd.rules , которое через systemctl и юнит вызывает не cdrom_id, а нормальный eject, а переменную DISK_EJECT_REQUEST просто очищает, "чтоб не досталась врагу" :)

В отличии от cdrom_id, команда eject обрабатывает запросы на извлечение правильно, то есть проверяет наличие смонтированной ФС, пытается её отмонтировать, и только в случае успеха открывает лоток.

Обновления:
Часть 3: Добавлен раздел "Автоматическое отмонтирование CD" с описанием правила 21-eject-cd.rules и юнита [email protected]
Часть 2: В smount исправлен баг, добавлена обработка umount под рутом, реализована возможность монтирования в разные каталоги вида /run/media/%u (или любые другие, к примеру /home/%u/media ) для разных юзеров с разделением доступа, см. mnt.conf
В mnt улучшена реализация блэклиста, теперь он фильтрует устройства только при монтировании/отмонтировании всех сразу, прямое упоминание устройства позволяет обойти блэклист.
Часть 1: Правило UDEV для именования встроенных дисков почищено и разделено на два – первое (зависимое от конкретных дисков) именует, второе (общее) создаёт по именам и меткам симлинки вида hd, hd1, hd_Label и т.д.
 
Зарегистрироваться или войдите чтобы оставить сообщение.