четверг, 28 апреля 2011 г.

Метки разделов и выравнивание в gpart


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

Первый патч предназначен для решения проблемы с метками разделов, которые, как известно, реализуются сейчас классом GEOM_LABEL. Основная проблема в том, что для приемлемой работы с метками GEOM_LABEL предъявляет некоторые требования к провайдерам. Например, обнаружение меток GEOM_LABEL выполняет только во время tasting. Изменение меток может быть обнаружено только при условии использования механизма spoiling с последующим retaste. Что при существующей реализации класса GEOM_PART не представляется возможным.
Класс GEOM_PART управляет таблицей разделов и метки этих разделов хранятся в таблице, а не на провайдере раздела. Поэтому, при изменении метки механизм spoiling'а не запускается для провайдера раздела.

Предлагаемый мной патч отключает реализацию меток gpt/gptid в GEOM_LABEL и добавляет новый класс PART::LABEL. Он тесно связан с классом PART и, кроме того, имеет несколько функциональных отличий от GEOM_LABEL. Во-первых, он не использует механизм tasting, объекты класса и его провайдеры создаются по инициативе класса PART. Во-вторых, он не использует механизм spoiling, поэтому его провайдеры существуют всё время, а не исчезают, когда какой либо связанный провайдер начинает использоваться. Благодаря этому устраняется проблема с изменением меток, которые становятся видны сразу после изменения. И, на мой взгляд, удобнее, когда метки в /dev существуют всегда. К тому же, кроме реализации gpt/gptid я добавил поддержку меток в схемы PC98 и APM.

Я планирую включить этот патч в head/ примерно через неделю. Второй патч не вносит изменений в ядро. Он добавляет к утилите gpart(8) новую опцию "-а alignment", при использовании которой gpart выполняет выравнивание создаваемых разделов на заданную величину. Например так:

# gpart create -s gpt md0
md0 created
# gpart show md0
=>    34  409533  md0  GPT  (200M)
      34  409533       - free -  (200M)

# gpart add -t freebsd-boot -s 128k -a 4k md0
md0p1 added
# gpart add -t freebsd-ufs -s 60m -a 4k md0
md0p2 added
# gpart add -t freebsd-ufs -a 4k md0
md0p3 added
# gpart show md0
=>    34  409533  md0  GPT  (200M)
      34       6       - free -  (3.0K)
      40     256    1  freebsd-boot  (128K)
     296  122880    2  freebsd-ufs  (60M)
  123176  286384    3  freebsd-ufs  (139M)
  409560       7       - free -  (3.5K)

четверг, 14 апреля 2011 г.

web-камера в skype во FreeBSD - теперь работает!

Использование Web-камеры во FreeBSD некоторое время назад было довольно больной темой. Проблема частично решилась с появлением webcamd и cuse4bsd. Нет, конечно в портах было несколько модулей ядра, реализующих поддержку небольшого списка web-камер, но, к сожалению, такие камеры редко ставят на ноутбуки, да и в продаже их найти сложно.

Два проекта cuse4bsd и webcamd добавили поддержку огромного количества различных камер во FreeBSD. Cuse4bsd - это модуль ядра и библиотека, предоставляющая программный интерфейс для работы с этим модулем. Если вкратце, то используя эту библиотеку в своём приложении вы можете создать псевдоустройство (в нашем случае это /dev/video0), к которому могут обращаться другие программы. Все обращения к этому устройству, такие как ioctl, read, write, и другие через libcuse4bsd перенаправляются к вашему приложению. Вы можете их обработать и отправить результат обратно.

Точно так же webcamd использует эту библиотеку и модуль ядра. Сам же webcamd довольно интересное приложение - он включает в себя часть ядра linux. Если взглянуть в его исходный код, то можно найти кучу обёрток для различных функций, типов, макросов, структур ядра linux, которые позволяют скомпилировать драйверы различных устройств и использовать их в приложении.
Webcamd через libusb может обращаться к различным камерам и тюнерам, которые подключены в системе. В то же время, он создаёт устройства /dev/videoX и используя драйверы, что взяты из ядра linux, выполняет их на уровне пользователя.  Другими словами webcamd  организует взаимодействие между linux-драйвером, реальным устройством и приложениями, которые обращаются из FreeBSD к /dev/videoX.

Всё бы хорошо, большинство web-камер работает, к ним можно обращаться из pwcview, mplayer, vlc и других програм, кроме skype. Это бинарник для linux и он ни в какую не хочет работать с современными камерами. Причин несколько. Skype использует только video4linux1 API и от камеры хочет данные только в определённом формате. Кстати, эти проблемы не специфичные для FreeBSD, в linux они тоже присутствуют.
Но в linux есть решение - пакет libv4l, который включает в себя несколько библиотек - v4l2convert и v4l1compat. Первая осуществляет конвертацию форматов данных, вторая предназначена для приложений, использующих устаревший API video4linux1.

Так вот, используя эти библиотеки в linux можно заставить skype работать с современными камерами. Но во FreeBSD режим эмуляции linux не поддерживает API Video4Linux2, поэтому использовать libv4l не получится.
Системные вызовы (в данном случае это ioctl с кодами V4L2), которые будут идти от libv4l к ядру FreeBSD не будут обработаны, так как они не реализованы.

Но! :)
Мы можем поблагодарить Juergen Lock (nox@). Он выложил патчи, реализующие V4L2 в режиме linux эмуляции. Теперь, используя libv4l камеры работают и в skype, а так же и во Flash в браузере.

Патчи есть для 8-ки и 9-ки. libv4l для linux в портах вроде пока ещё нет, но думаю это вопрос времени. Я нашёл в поисковике такой пакет libv4l-0.6.2-1.fc10.i386.rpm и установил его как учат вот тут.
После этого слегка модифицировал стартовый скрипт skype:

!/bin/sh
export LD_PRELOAD=/usr/lib/libv4l/v4l2convert.so
/usr/local/share/skype/skype --resources=/usr/local/share/skype $@



PS. Вы конечно поняли, что про webcamd я не просто так рассказывал, он у меня тоже установлен и настроен.