OpenBSD/ cd(4) hotplug

19.03.2010

Недавно возникла задача научить любимую жену пользоваться моим лаптопом с OpenBSD. OpenBSD — система аскетичная и весьма недоверчиво относится к женщинам. Для снижения недоверчивасти был настроен графический вход через xdm(1), сделаны красивые ярлыки на браузер и прочие полезные программы, настроен hotplugd(8) для автомонтирования USB-флешек. Осталась только одна проблема — компакт-диски, в OpenBSD до сих пор нету их автоматического монтирования и размонтирования.

Нету, значит нужно сделать. Первоначальная идея была очень простой: пусть драйвер cd(4) каждые несколько секунд посылает в привод SCSI команду Test Unit Ready. Если диск есть, команда отработает нормально, если диска нет — вернется с ошибкой. Идея оказалась вполне рабочей. Но коллеги по цеху сказали, что метод так себе. Более того, они высказали опасения, что на некоторых старых машинах это может привести к неожиданным результатам. Например Miod вспомнил, что у него есть дисковод, который открывает лоток при получении команды TUR.

Тогда я еще почитал описание SCSI команд и нашел то, что мне нужно. Команда Get Event/Status Notification позволяет узнать, какие события происходили с дисководом, в частности был ли вставлен новый диск или нажата кнопка выемки диска. Новая версия патча заработала отлично и в целом возражений не встретила. Но и явного одобрения тоже, поэтому в OpenBSD 4.7 этой возможности не будет. Думаю, к 4.8 я ее протолкну, если не лень будет. А пока любители пересобрать ядро могут поиграться с патчем.

Понятно, что к патчу должно прилагаться правильное содержимое /etc/hotplug. Например такое.

attach:

#!/bin/sh

DEVCLASS=$1
DEVNAME=$2

case $DEVCLASS in
2)
	# disk
	case $DEVNAME in
	cd*)
		mount -o nodev,nosuid /dev/${DEVNAME}a /mnt/cdrom
		test -d /mnt/cdrom/VIDEO_TS && umount /mnt/cdrom
		;;
	sd*)
		mount -o nodev,nosuid /dev/${DEVNAME}i /mnt/flash
		;;
	esac
esac

detach:

#!/bin/sh

DEVCLASS=$1
DEVNAME=$2

case $DEVCLASS in
2)
	# disk
	case $DEVNAME in
	cd*)
		umount -f /mnt/cdrom
		eject /dev/${DEVNAME}c
		;;
	esac
esac
,