Журнал LinuxFormat - перейти на главную

LXF165-166: Ад­минист­ри­ро­вание: Udev

Материал из Linuxformat
Перейти к: навигация, поиск


Udev: От­шлифуй­те свой ком­пь­ю­тер

Сис­тем­ное ад­ми­ни­ст­ри­ро­ва­ние: На­строй­те свое «же­ле­зо» дивным ме­нед­же­ром уст­ройств

Есть ме­сто, в ко­то­ром Linux пря­чет свои са­мые глу­бо­кие и тем­ные сек­ре­ты. Нейл Бот­вик за­гля­ды­ва­ет ту­да. Сно­ва.

(thumbnail)
Наш эксперт. У Ней­ла Бот­ви­ка по ком­пь­ю­те­ру в ка­ж­дой ком­на­те, но по со­об­ра­же­ни­ям безо­пас­но­сти он ни за что не ка­жет, где на­хо­дит­ся цен­траль­ный сер­вер.

Кре­до Unix «Все яв­ля­ет­ся фай­лом» от­но­сит­ся и к уст­рой­ст­вам. Когда вы встав­ляе­те флэш­ку или под­клю­чае­те web-ка­ме­ру, в ка­та­ло­ге /dev по­яв­ля­ет­ся узел уст­рой­ст­ва (файл), но как он ту­да по­па­да­ет? В ста­рые до­б­рые вре­ме­на нуж­но бы­ло при­бе­гать к тай­ным за­кли­наниям mknod и об­ра­щать­ся к свя­щен­но­му спи­ску стар­ших и млад­ших но­ме­ров уст­ройств; те­перь под­клю­чить уст­рой­ст­во доста­точ­но про­сто. Но­вая вол­шеб­ная ко­ман­да – udev – ра­бо­та­ет как ди­на­ми­че­­ская фай­ло­вая сис­те­ма и как менед­жер уст­ройств. При за­груз­ке сис­те­мы udev соз­да­ет в ка­та­ло­ге /dev вир­ту­аль­ную фай­ло­вую сис­те­му вро­де /proc или /sys, с фай­ла­ми уст­ройств для всей периферии, об­на­ру­жен­ной ядром. За­тем она слу­ша­ет со­бы­тия го­ря­че­го под­клю­чения, по­сту­паю­щие от яд­ра, и на ле­ту соз­да­ет или уда­ля­ет фай­лы уст­ройств для на­ко­пи­те­лей, се­те­вых адап­те­ров, уст­ройств для ра­бо­ты с ви­део и все­го, что мож­но под­клю­чить «на ле­ту», когда эти уст­рой­ст­ва под­клю­ча­ют­ся или от­клю­ча­ют­ся от ком­пь­ю­те­ра.

На пер­вый взгляд она ничем не от­ли­ча­ет­ся от сво­ей пред­ше­ст­венницы devfs, но udev ра­бо­та­ет пол­но­стью в про­стран­ст­ве поль­зо­ва­те­ля, а не как про­цесс яд­ра. Яд­ро об­на­ру­жи­ва­ет уст­рой­ст­во, но не соз­да­ет файл уст­рой­ст­ва, пе­ре­да­вая от­вет­ст­вен­ность udev. Это оз­на­ча­ет, что udev мо­жет вы­пол­нять ка­кие-то дей­ст­вия до соз­дания фай­ла уст­рой­ст­ва.

Все это ра­бо­та­ет под управ­лением пра­вил – тек­сто­вых фай­лов, где опи­са­ны усло­вия и дей­ст­вия: ес­ли уст­рой­ст­во со­от­вет­ст­ву­ет усло­ви­ям, то дей­ст­вия вы­пол­ня­ют­ся. Пра­ви­ла на­хо­дят­ся в двух ка­та­ло­гах: /lib/udev/rules.d и /etc/udev/rules.d. Пер­вый со­дер­жит пра­ви­ла, уста­нов­лен­ные udev и дру­ги­ми па­ке­та­ми – на­при­мер, с SANE уста­нав­ли­ва­ет­ся ог­ром­ный файл пра­вил, где оп­ре­де­ля­ют­ся дей­ст­вия, вы­пол­няе­мые при об­на­ру­жении раз­лич­ных сканеров. Фай­лы в /etc/udev/rules.d со­дер­жит пра­ви­ла, уста­нав­ли­вае­мые дру­ги­ми па­ке­та­ми, и поль­зо­ва­тель­ские пра­ви­ла – имен­но они нас ин­те­ре­су­ют. Пре­ж­де чем на­чи­нать экс­пе­ри­мен­ты с фай­ла­ми в этом ка­та­ло­ге, уч­ти­те, что все фай­лы в нем уже уста­нов­ле­ны ка­ки­ми-то па­ке­та­ми и мо­гут быть пе­ре­за­пи­са­ны при об­нов­лении па­ке­та, по­это­му помещай­те все свои пра­ви­ла в от­дель­ный файл. Име­на фай­лов име­ют зна­чение; они долж­ны за­кан­чи­вать­ся на .rules и счи­ты­вать­ся в оп­ре­де­лен­ном по­ряд­ке, по­это­му на­чи­на­ют­ся с чис­ла. В рас­чет бе­рет­ся толь­ко имя фай­ла, а не путь, так что фай­лы

/lib/udev/rules.d/10-foo.rules

/etc/udev/rules.d/20-bar.rules

/lib/udev/rules.d/30-stuff.rules

бу­дут про­чи­та­ны имен­но в этом по­ряд­ке. При на­ли­чии двух фай­лов с оди­на­ко­вым именем ис­поль­зу­ет­ся толь­ко файл из /etc. Нач­ните имя фай­ла с 10, ес­ли пра­ви­ла долж­ны вы­пол­нять­ся пер­вы­ми, или с 90, ес­ли по­следними. По­ря­док име­ет зна­чение, так как бо­лее поздние пра­ви­ла пе­ре­гру­жа­ют бо­лее ранние.

Ус­ло­вия и при­сваи­вания

Ка­ж­дое пра­ви­ло – од­на стро­ка в фай­ле, ко­то­рая со­дер­жит несколь­ко пар «ключ – зна­чение». На прак­ти­ке нуж­ны как минимум две па­ры: усло­вие и при­сваи­вание. Ес­ли все усло­вия вер­ны, вы­пол­ня­ет­ся при­сваи­вание. Вот при­мер:

DRIVERS==”sd”, ATTRS{vendor}==”Google”, SYMLINK=”android”

Пер­вая часть до за­пя­той – усло­вие; она сравнива­ет зна­чения с по­мо­щью опе­ра­то­ра == и про­ве­ря­ет, яв­ля­ет­ся ли уст­рой­ст­во уст­рой­ст­вом хранения дан­ных. Ес­ли это так, про­ве­ря­ет­ся сле­дую­щая часть ATTRS{vendor}, по­ле стан­дарт­но­го ат­ри­бу­та, и ес­ли оно рав­но «Google», зна­чит, это те­ле­фон Android. Ес­ли вто­рое усло­вие вер­но, вы­пол­ня­ет­ся при­сваи­вание, ко­то­рое на­страи­ва­ет сим­во­ли­че­скую ссыл­ку с имени уст­рой­ст­ва, на­зна­че­нного ядром – ска­жем, с /dev/sdc на /dev/android. Пре­крас­но, ска­же­те вы, но как уз­нать, на что имен­но делать про­ве­рку? Udev по­мо­жет нам и с этим, бла­го­да­ря ко­ман­де udevadm. Вставь­те флэш­ку, от­меть­те имя по­яв­ляю­ще­го­ся уст­рой­ст­ва, на­при­мер, /dev/sdb1, за­тем вы­полните ко­ман­ду

udevadm info --name /dev/sdb1

Она вы­даст по­лез­ную ин­фор­ма­цию об уст­рой­ст­ве, из ко­то­рой вы мо­же­те по­нять, что надо ис­поль­зо­вать для сравнения, но это не фор­мат пра­ви­ла udev. Что­бы по­лу­чить ее в нуж­ном фор­ма­те, ско­ман­дуй­те

udevadm info --attribute-walk --name /dev/sdb1 | less

То, что мы про­пуска­ем вы­вод ко­ман­ды че­рез less, намекает, что ко­ман­да вы­да­ет боль­шой объ­ем ин­фор­ма­ции. Она вы­во­дит не толь­ко ин­фор­ма­цию об уст­рой­ст­ве, но и про­хо­дит по де­ре­ву, по­ка­зы­вая ат­ри­бу­ты ка­ж­до­го из его ро­ди­те­лей, от /dev/sdb до USB-кон­трол­ле­ра. Для про­вер­ки мож­но вы­брать лю­бое из них, но нас на са­мом де­ле ин­те­ре­су­ют толь­ко один или два верхних бло­ка. В фай­ле с пра­ви­лом udev нам ну­жен фор­мат вы­во­да, по­это­му мож­но вста­вить со­от­вет­ст­вую­щую стро­ку в файл с пра­ви­лом. Ес­ли нуж­но сравнивать с несколь­ки­ми ат­ри­бу­та­ми, все они долж­ны быть в од­ном и том же бло­ке. Что­бы пра­ви­ло сра­бо­та­ло, все усло­вия долж­ны быть вер­ны. Ес­ли доста­точ­но, что­бы бы­ло вер­ным толь­ко од­но усло­вие, при­дет­ся до­ба­вить от­дель­ное пра­ви­ло для ка­ж­до­го усло­вия.

До­ба­вить сим­во­ли­че­­ские ссыл­ки на фай­лы уст­ройств про­сто, но мож­но сде­лать го­раз­до боль­ше. На­при­мер, за­гля­нув в /dev/disk, вы уви­ди­те под­ка­та­ло­ги, та­кие как by-id и by-partlabel. Они со­дер­жат сим­во­ли­че­­ские ссыл­ки для оп­ре­де­ления всех дис­ков и раз­де­лов по их UUID и мет­кам фай­ло­вых сис­тем. Ес­ли у вас в /etc/fstab ис­поль­зу­ют­ся UUID, вы уви­ди­те, на ка­кие ре­аль­ные дис­ко­вые уст­рой­ст­ва они ссы­ла­ют­ся. Эти ссыл­ки ав­то­ма­ти­че­­ски соз­да­ют­ся при за­груз­ке сис­те­мы при за­пуске udev. Дру­гие ти­пы при­сваи­ваний, ко­то­рые мож­но до­ба­вить в пра­ви­ло – OWNER, GROUP и MODE, они из­ме­ня­ют вла­дель­ца и пра­ва досту­па к фай­лу уст­рой­ст­ва. На­при­мер, ес­ли у вас есть сканер, ко­то­рый не мо­гут най­ти SANE и GIMP, но root ви­дит его, обыч­но это ог­раничения прав досту­па к фай­лу уст­рой­ст­ва. Из­менить их мож­но та­ким пра­ви­лом:

ATTRS{product}==”CanoScan”, ATTRS{manufacturer}==”Canon”, GROUP:=”scanner”, MODE:=”0660”, SYMLINK=”scanner”

Это пра­ви­ло, ко­то­рое я до­ба­вил для сканера Canon, об­на­ру­жившего имен­но та­кое по­ве­дение. Пра­ви­ло де­ла­ет груп­пу уст­ройств сканеров доступ­ной на запись, а ее вла­дель­цем ста­но­вит­ся груп­па scanner, по­это­му лю­бой поль­зо­ва­тель в этой груп­пе мо­жет им поль­зо­вать­ся. В од­но­поль­зо­ва­тель­ской сис­те­ме мож­но про­сто уста­но­вить ре­жим в 0666, но груп­па scanner – это об­ще­при­ня­тый спо­соб.

Пе­ре­име­но­вы­вать фай­лы уст­ройств боль­ше нель­зя, но се­те­вые ин­тер­фей­сы – мож­но. Ес­ли у вас несколь­ко се­те­вых карт, на­при­мер, ес­ли ком­пь­ю­тер яв­ля­ет­ся мар­шру­ти­за­то­ром или бранд­мау­эром, бы­ло бы же­ла­тель­но, что­бы им всегда на­зна­чал­ся один и тот же ад­рес. Пе­ре­клю­чение ин­тер­фей­сов на бранд­мау­эре спо­соб­но вы­звать ка­та­ст­ро­фу. В усло­вии udev мож­но ис­поль­зо­вать MAC-ад­рес кар­ты, ука­зан­ный по­сле “ether” в вы­во­де ifconfig; на­при­мер, с его по­мо­щью мож­но соз­дать та­кое пра­ви­ло:

SUBSYSTEM==”net”, ATTR{address}==”e8:11:32:09:63:82”, NAME=”eth0”

SUBSYSTEM==”net”, ATTR{address}==”50:e5:49:bd:1e:45”, NAME=”eth1”

Ес­ли вы когда-нибудь ме­ня­ли се­те­вую кар­ту, воз­мож­но, вам бы­ло ин­те­рес­но, по­че­му но­вая кар­та по­яв­ля­лась в сис­те­ме как eth1. Все де­ло в пра­ви­ле udev, ко­то­рое ав­то­ма­ти­че­­ски соз­да­ет­ся в /etc/udev/rules.d/70-persistent-net.rules, оно очень по­хо­же на пра­ви­ла вы­ше. Так как ста­рый ад­рес был вы­де­лен eth0, но­во­му ад­ре­су бу­дет вы­де­ле­но пер­вое доступ­ное имя уст­рой­ст­ва. По­это­му ес­ли вы за­менили кар­ту на но­вую, ли­бо уда­ли­те ста­рое пра­ви­ло из фай­ла, ли­бо уда­ли­те файл, и он бу­дет вновь соз­дан для но­вой кар­ты при сле­дую­щей пе­ре­за­груз­ке сис­те­мы. По­сто­ян­ные се­те­вые пра­ви­ла бы­ли уда­ле­ны из udev, и ес­ли вы хо­ти­те из­менить се­те­вые име­на на са­мых но­вых ди­ст­ри­бу­ти­вах, по­на­до­бит­ся соз­дать пра­ви­ла вруч­ную в та­ком же фор­ма­те, при ко­то­ром сна­ча­ла про­ве­ря­ет­ся SUBSYSTEM, что­бы убе­дить­ся, что это се­те­вая кар­та, а за­тем MAC-ад­рес.

Не ме­няй­те пра­ви­ла

Не под­да­вай­тесь со­блаз­ну из­ме­нять су­ще­ст­вую­щие фай­лы с пра­ви­ла­ми; они уста­нав­ли­ва­ют­ся менед­же­ром па­ке­тов и мо­гут быть за­менены при об­нов­лениях. Вме­сто это­го соз­да­вай­те соб­ст­вен­ные фай­лы с пра­ви­ла­ми в /etc/udev/rules.d. Ес­ли вы хо­ти­те из­менить су­ще­ст­вую­щее пра­ви­ло, ско­пи­руй­те его в соб­ст­вен­ный файл и вы­полните из­менения там. Ес­ли за­дать фай­лу боль­ший но­мер, чем у су­ще­ст­вую­ще­го фай­ла с пра­ви­лом, у ва­ше­го пра­ви­ла бу­дет пре­иму­ще­ст­во. Так­же, поль­зу­ясь зна­ком := вме­сто =, мож­но за­да­вать при­ори­тет при­сваи­ваний – в этом слу­чае не толь­ко вы­пол­ня­ет­ся при­сваи­вание, но и га­ран­ти­ру­ет­ся, что ни од­ному из по­сле­дую­щих пра­вил не удастся из­менить его на свое.

На­ря­ду с из­менением фай­лов уст­ройств в /dev, udev так­же мо­жет за­пускать про­грам­мы. Про­грам­ма usb_modeswitch для 3G-мо­де­мов ис­поль­зу­ет пра­ви­ла udev для пе­ре­клю­чения уст­рой­ст­ва из ре­жи­ма на­ко­пи­те­ля в ре­жим мо­де­ма, и те­перь про­грам­му боль­ше не нуж­но за­пускать вруч­ную. Помните, что во вре­мя ра­бо­ты про­грам­мы udev бло­ки­ру­ет­ся, по­это­му поль­зуй­тесь им толь­ко для про­грамм, за­вер­шаю­щих­ся бы­ст­ро. Ес­ли нуж­но за­пустить нечто дол­го­сроч­ное, по­мес­ти­те ко­ман­ду в скрипт и вы­зо­ви­те его из пра­ви­ла с &, что­бы он сра­зу вер­нул управ­ление. На­при­мер, в пра­ви­ле

KERNEL==”sd[a-z]1”, ATTRS{model}==”DMC-TZ30”, RUN=”/usr/local/bin/copyphotos.sh $devnode &”

ис­поль­зу­ет­ся па­ра­метр KERNEL для оп­ре­де­ления имени уст­рой­ст­ва и ат­ри­бут model для оп­ре­де­ления кон­крет­ной мо­де­ли ка­ме­ры. При под­клю­чении этой ка­ме­ры пра­ви­ло за­пуска­ет скрипт, пе­ре­да­вая ему в ка­че­­ст­ве ар­гу­мен­та имя уст­рой­ст­ва. Текст скрип­та выглядит та­к:

#!/bin/sh

pmount $1 camera

mv /media/camera/DCIM/100_PANA/*.JPG /home/nelz/photos/new

pumount /media/camera

Скрипт мон­ти­ру­ет ка­ме­ру, ис­поль­зуя имя уст­рой­ст­ва, пе­ре­дан­ное udev, пе­ре­ме­ща­ет фо­то­гра­фии в до­машний ка­та­лог и раз­мон­ти­ру­ет ка­ме­ру. Де­мон udev вы­пол­ня­ет­ся от имени су­пер­поль­зо­ва­те­ля-root, и все за­пу­щен­ные им ко­ман­ды то­же бу­дут вы­пол­нять­ся от имени root. Это сле­ду­ет учи­ты­вать, осо­бен­но для команд мон­ти­ро­вания уст­ройств, по­то­му что обыч­но они долж­ны быть доступ­ны на запись толь­ко root. В этот скрипт мож­но до­ба­вить ко­ман­ду для из­менения вла­дель­ца по­сле ко­пи­ро­вания.

Бо­лее под­роб­ную ин­фор­ма­цию мож­но най­ти на man-странице udev, за­гля­нув в фай­лы пра­вил в сво­ей сис­те­ме и в ру­ко­во­дства в Ин­тернете. Удоб­ное ру­ко­во­дство есть по ссыл­ке www.reactivated.net/udevrules.php. |

Персональные инструменты
купить
подписаться
Яндекс.Метрика