spb-archlinux at ICFPC 2010
Our team spb-archlinux is taking part in the ICFP Programming Contest 2010.
Members
Results
- Score: 175.356 (68th)
- Others' cars solved: 500
- Cars submitted: 36
Languages
- Human
- Russian, English
- Programming
- Java, Haskell, Python
Source Code
- http://bitbucket.org/vlasovskikh/icfpc10/ (private repo)
Мышь через Bluetooth
- Авторы:
- Вадим Цесько
- Андрей Власовских
Это небольшое HOWTO по подключению мыши Bluetooth. Всё, описанное здесь, тестировалось на мыши Lenovo Bluetooth Laser Mouse и ноутбуке Lenovo ThinkPad X200s.
Требуемый софт
Понадобятся следующие пакеты:
bluezdbusblueman/gnome-bluetooth(для настройки автоматического соединения)
Включение передатчика
Встроенный передатчик включается способом, зависящим от харда и ACPI.
На IBM/Lenovo Thinkpad:
$ echo 1 > /proc/acpi/ibm/bluetooth
Настройка демона bluetooth
В конфигурационном файле /etc/conf.d/bluetooth необходимо включить подсистему
hidd:
HIDD_ENABLE=true
Запустим демон:
$ /etc/rc.d/bluetooth start
Установка соединения
Нажмите на мыши кнопку connect и запустите поиск устройств (с правами root):
# sudo hidd --search
Всё, мышь должна работать.
Проблемы и их решения
Основная проблема — отсутствие автоматического пересоединения с мышью при:
- Перезагрузке демона
bluetooth - Переходе в/из спящего/ждущего режима
- Переходе мыши в/из режима экономии энергии
- Выключении/включении мыши
Решение 1: использовать графические утилиты из пакетов blueman или
gnome-bluetooth для настройки параметров собственной видимости и безграничного
доверия мыши.
Решение 2: добавить мышь в список доверенных устройств вручную, тогда она
автоматически будет подхватываться демоном hidd при включении или выходе или
из режима экономии.
Для этого нужно узнать MAC-адрес подключённой мыши (здесь — 00:11:22:33:44:55):
$ hidd 00:11:22:33:44:55 BlueTooth Mouse [1220:0010] connected
и добавить в файл /var/lib/bluetooth/<BT-MAC-компьютера>/trusts такую запись:
00:11:22:33:44:55 [all]
Внешние ссылки
Настройка обработчиков специальных клавиш
- Автор:
- Вадим Цесько
Это небольшое HOWTO по настройке обработчиков специальных клавиш. Всё,
описанное здесь, тестировалось на ноутбуке Lenovo ThinkPad X200s. Ноутбуки
Lenovo, как и многие другие ноутбуки, характеризуются наличием специальных
клавиш, активируемых по нажатию Fn + F*, Fn + <стрелка>, или даже
аппаратных специальных клавиш (у меня это Volume Mute, Volume Up/Down,
Forward, Next).
Условно можно разделить обработчики нажатий на такие клавиши на два класса:
- обрабатываемые при помощи
acpid - обрабатываемые при помощи
Xmodmap/Xbindkeys
При помощи acpid обрабатываются нажатия на такие клавиши как:
- переход в ждущий/спящий режим
- включение/выключение внешнего монитора
- включение/выключение WiFi/Bluetooth
При помощи Xmodmap/Xbindkeys обрабатываются:
- регулировка громкости звука
- мультимедийные клавиши (
Fn + <стрелка>) - клавиши навигации вперёд/назад
Требуемый софт
Понадобятся следующие пакеты:
acpiacpidacpitoolxorg-server-utilsxbindkeys
Настройка ACPI
После установки пакета acpi укажите в /etc/rc.conf ACPI-модуль для
Вашей машины. У меня это thinkpad_acpi.
Настройка обработчиков нажатий осуществляется в файле /etc/acpi/handler.sh.
Демон ACPI перенаправляет события ACPI этому скрипту. Мой скрипт выглядит
следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #!/bin/sh # Default acpi script that takes an entry for all actions set $* case "$1" in ibm/hotkey) case "$2" in HKEY) case "$4" in 00001004) # Suspend to RAM /usr/sbin/pm-suspend ;; 00001008) # Switch Bluetooth if [ "$(grep "status.*enabled" /proc/acpi/ibm/bluetooth)" ]; then /etc/rc.d/bluetooth stop echo "disable" > /proc/acpi/ibm/bluetooth else echo "enable" > /proc/acpi/ibm/bluetooth /etc/rc.d/bluetooth start fi ;; 00001007) # Toggle external display if [ "$(xrandr -q | grep "VGA connected")" ]; then if [ "$(xrandr -q | grep "VGA connected [0-9]")" ]; then xrandr --output VGA --off else xrandr --output VGA --auto fi else xrandr --output VGA --off fi ;; 0000100c) # Hibernate /usr/sbin/pm-hibernate ;; esac ;; esac ;; esac |
Посмотреть номера клавиш можно при помощи утилиты acpi_listen, например:
$ acpi_listen ibm/hotkey HKEY 00000080 00001003 ^C
Скрипт /etc/acpi/handler.sh по частям обрабатывает код события (разбивая
строку на параметры при помощи set $*) и выполняет соответствующие им
действия. Таким образом Вы можете добавлять новые обработчики.
Настройка Xmodmap
Сервер X ведёт свою таблицу символов. Посмотреть какой символ соответствует
нажатию специальной клавиши можно при помощи утилиты xev. Для клавиш,
которым сервер X самостоятельно не сопоставил правильных символов, можно
задать символы при помощи утилиты Xmodmap в файле ~/.Xmodmap:
keycode 121 = XF86AudioMute keycode 122 = XF86AudioLowerVolume keycode 123 = XF86AudioRaiseVolume keycode 166 = XF86Back keycode 167 = XF86Forward
Список символов можно посмотреть в файле /usr/include/X11/keysymdef.h.
Не забудьте прописать запуск Xmodmap при старте менеджера окон в ~/.xinitrc:
xmodmap ~/.Xmodmap xbindkeys while : do wmii done
Настройка Xbindkeys
Опишите действия, которые нужно выполнять при обработке символов X в файле
~/.xbindkeysrc:
"mocp -G" XF86AudioPlay "mocp -s" XF86AudioStop "mocp -r" XF86AudioPrev "mocp -f" XF86AudioNext "amixer sset Master 5%-" XF86AudioLowerVolume "amixer sset Master 5%+" XF86AudioRaiseVolume "amixer sset Master toggle" XF86AudioMute "xbacklight -inc 10" XF86MonBrightnessUp "xbacklight -dec 10" XF86MonBrightnessDown
Как легко понять, клавиши мультимедиа управляют демоном mocp, клавиши
регулировки громкости управляют микшером ALSA, а клавиши регулировки яркости
вызывают утилиту xbacklight.
Так же как и в случае Xmodmap, не забудьте запустить xbindkeys при старте
менеджера окон (см. ~/.xinitrc выше).
Внешние ссылки
Встреча spb-archlinux 2010-03
2010-03-01 в баре Tower Pub (59.936259, 30.322906) прошла очередная встреча группы spb-archlinux.
Обсуждаемые темы:
- Переход на Windows, причины перехода, взаимодействие с линуксовыми средствами
- Система MPS, решаемые с её помощью задачи, кривая обучения, способ работы с MPS, связь с предметно-ориентированными языками на Lisp
- Отдельные баги и случаи из статического анализа
- Работа и программирование на уровне API, хранение пользовательских объектов «без сериализации» и форматов файлов как альтернатива подходу Unix: использование Unix API как нижнего уровня, файлы как массивы байтов, универсальные средства для бинарных и текстовых форматов. Smalltalk vs. raw files
- JSON как единица хранения в файловой системе (с эффективным доступом, индексацией) и передачи данных по сети. Насколько это нормально? Лучше ли, чем файлы как массивы байтов? Какие будут последствия?
- Красота программного кода и красота в программировании. Непосредственно воспринимаемая органами чувств vs. понимаемая, «математическая» красота. Простота как один из критериев красоты. Простота — только «экономический» термин (проще использовать, получить выгоду)? Есть ли другая природа ценности простоты? Насколько связаны простота и новизна?
Автомонтирование через udev
- Автор:
- Андрей Власовских
- Источник:
- http://vlan.tumblr.com/post/275906821/udev-automount
На днях настроил автомонтирование накопителей USB через udev в Arch Linux и
Ubuntu. Ниже я буду описывать детали для Arch Linux и udev версии 146. В
каждом дистрибутиве немного свои правила /etc/udev/rules.d, а в версиях udev
менялись названия утилит и опций.
Сначала я расскажу о том, как работает udev, а затем приведу мои файлы
конфигов и программки для монтирования накопителей USB.
Вкратце udev работает так. В ядро Linux 2.6 входит файловая система информации
об устройствах sysfs. Она обычно монтируется в скриптах загрузки системы в
каталог /sys. Эта система отображает объекты ядра, называемые kobjects.
Объекты отражают устройства и драйверы. Каталоги представляют собой объекты, а
файлы — их атрибуты, хранящиеся обычно в текстовом виде. Некоторые атрибуты
можно менять.
В принципе, смонтированной системы sysfs было бы достаточно для обнаружения
подключения и отключения устройств, особенно если бы в ней был динамический файл
с событиями на манер Plan 9 или wmii. Но разработчики решили использовать для
извещения сокеты семейства netlink(7). Замечу, что inotify(7) здесь не
помог бы из-за большого числа файлов в /sys (порядка 10000). Ниже я ещё скажу
об исходниках моей программы, показывающей, что же там посылает ядро в
пользовательское пространство.
Итак, через специальный сокет с помощью группового вещания ядро рассылает
уведомления об изменениях в sysfs. Эти события обрабатываются демоном
udevd(8) с помощью языка правил udev(7). Правила обычно лежат в
каталоге /etc/udev/rules.d в виде специальных файлов.
Каждое событие активизирует несколько правил. Начальные правила обычно создают
нужные файлы устройств в /dev, символьные ссылки на устройства. Следующие
правила запускают внешние программы для пополнения информации события. Например,
при добавлении блочного устройства на USB запускается программа определения
файловой системы, метки диска и т. д. Информация от программ попадает в
переменные окружения, доступные последующим правилам.
Для автомонтирования, собственно, достаточно написать новый файл правил udev,
который на основании собранной информации о подключаемом накопителе выдаст
команды монтирования и создания удобных символьных ссылок.
За основу при написании правил я взял этот пост, но кое-что пришлось дохачить. Я столкнулся с такими сложностями:
- Некоторые из моих флешек имели файловую систему на всём диске, а не на разделе
- Один из моих компьютеров грузится с флешки, так что её нужно игнорировать, чтобы не испортить процесс загрузки
- В разных дистрибутивах Linux и версиях
udevотличаются переменные и программы получения информации для правилudev - Нужно было обеспечить монтирование ФС
vfatс файлами от UID текущего пользователя - Я хотел разобраться в деталях написания правил, чтобы можно было писать
правила самому для любых задач, связанных с
udev
Все эти сложности удалось решить. Ниже приводится само решение, а если нужны какие-то пояснения — пишите.
Но вначале всё же пара советов. Методика отладки udev — используйте
udevadm(8): udevadm monitor, udevadm info, udevadm test. Ими можно
посмотреть почти всё необходимое. Если что-то не понятно — то тогда
strace(1). Накопители с файловыми системами на всём диске использовать
можно, но лучше переформатировать системы на разделы, например, с помощью
fdisk(8). Наконец, очень удобно иметь пользовательское имя-метку диска.
Изменить метку ext2 можно с помощью e2label(8), а для изменения метки
vfat потребуется форматирование с помощью mkdosfs(8).
Итак, сами файлы автомонтирования. Вначале файл правил
70-mount-usb-storage.rules (заметьте отсутствие переносов строк в правилах),
который кладётся в /etc/udev/rules.d:
# Добавление ACTION=="add", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", ATTRS{serial}!="0123456789012", RUN+="/bin/mkdir -p /mnt/%k", IMPORT{program}="/usr/local/bin/active_uid" ACTION=="add", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", ATTRS{serial}!="0123456789012", ENV{ID_FS_TYPE}=="vfat", RUN+="/bin/mount -t vfat -o rw,users,exec,noauto,noatime,fmask=113,dmask=002,uid=$env{ACTIVE_UID},gid=100,utf8 /dev/%k /mnt/%k" ACTION=="add", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", ATTRS{serial}!="0123456789012", ENV{ID_FS_TYPE}=="ext2", RUN+="/bin/mount -t ext2 -o rw,nosuid,noatime /dev/%k /mnt/%k" ACTION=="add", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", RUN+="/bin/ln -s /mnt/%k /media/$env{ID_FS_LABEL_ENC}" # Удаление ACTION=="remove", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", ATTRS{serial}!="0123456789012", RUN+="/bin/umount /dev/%k" ACTION=="remove", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", ATTRS{serial}!="0123456789012", RUN+="/usr/bin/unlink /media/$env{ID_FS_LABEL_ENC}" ACTION=="remove", KERNEL=="sd[a-z][0-9]", ENV{ID_USB_DRIVER}=="usb-storage", ATTRS{serial}!="0123456789012", RUN+="/bin/rmdir /mnt/%k"
Этот файл обеспечит монтирование накопителя в /mnt/<имя-устройства> и создание
символьной ссылки в /media/<метка-диска>, а также удаление всего этого при
отключении накопителя.
Файл использует мой скрипт active_uid, определяющий имя активного пользователя
в системе. Он очень простой и делает следующее. Если имена всех вошедших
пользователей совпадают, то этот пользователь и есть активный. Иначе это UID
root. Скрипт кладётся куда угодно и прописывается в правилах выше:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/bin/bash uids () { users | tr " " "\n" | uniq } if [ `uids | wc -l` == 1 ]; then uid=`uids` else uid="0" fi echo ACTIVE_UID="$uid" |
Наконец, поскольку всё же интересно, как работает udevd и что сообщает ему
ядро, я написал программу, выводящую дамп разобранных сообщений ядра. Исходники
программы лежат в pastebin.org. Запускать её нужно от root, т. к. нужна
привилегия CAP_NET_ADMIN.
