Gentoo Logo

Uwaga: Ten dokument zawiera błędy lub nie jest już aktualizowany.


System plików urządzeń (Device File System)

Spis treści:

1.  Co to jest devfs?

Stare (dobre?) czasy

Ostrzeżenie: devfs jest przestarzały i został usunięty ze źródeł kernela serii 2.6 w wydaniu 2.6.13. Użytkownicy nowych jąder powinni przemigrować na system udev. Informacje o nim można znaleźć w tekście o Praca z udev w Gentoo.

Tradycyjne implementacje Linuksa dostarczają użytkownikom abstrakcyjną ścieżkę urządzeń nazwaną /dev. Wewnątrz tej ścieżki użytkownik znajdzie device nodes, specjalne pliki, które reprezentują urządzenia w systemie. Na przykład, /dev/hda reprezentuje pierwsze urządzenie IDE w systemie. Dzięki udostępnieniu plików urządzeń użytkownikom, można zamiast tworzyć specjalne API, tworzyć programy, które współdziałają z hardwarem tak, jakby urządzenia były zwykłymi plikami.

Pliki urządzeń podzielone są na dwie grupy, nazwane urządzeniami znakowymi i urządzeniami blokowymi. Pierwsza grupa składa się z urządzeń, do których czytanie/pisanie nie jest buforowane. Naturalnie, druga grupa składa się z urządzeń, do których czytanie/pisanie jest buforowane. Z obu urządzeń można czytać dane w blokach lub znak po znaku. Dlatego też, ich nazwy mogą wprowadzać w błąd i istocie są złe.

Jeśli zajrzysz do jakiegoś pliku urządzenia, znajdziesz w nim coś takiego:

Listing 1.1: Sprawdzenie informacji w pliku urządzenia

# ls -l /dev/hda
brw-rw----    1 root     disk       3,   0 Jul  5  2000 /dev/hda

W poprzednim przykładzie dowiedzieliśmy się, że /dev/hda jest urządzeniem blokowym. Ważniejsze jednak jest, że są do niego przypisane dwie specjalne liczby: 3, 0. Para ta nazywana jest parą major-minor. Używana jest przez jądro, do przypisania pliku urządzenia do urządzenia rzeczywistego. Major odpowiada pewnemu urządzeniu, minor urządzeniu podrzędnemu. Dziwne? Wcale nie.

Przykładami niech będą /dev/hda4 i /dev/tty5. Pierwszy plik odpowiada czwartej partycji na pierwszym urządzeniu IDE. Jego parą major-minor jest 3, 4. Innymi słowy, minor odpowiada partycji, a major odpowiada urządzeniu. Drugi przykład ma 4, 5, jako parę major-minor. W tym przypadku major odpowiada driverowi terminala, a minor odpowiada numerowi terminala (w tym przypadku piąty terminal).

Problemy

Jeśli rzucisz okiem na katalog /dev, zobaczysz, że są tam nie tylko wszystkie twoje urządzenia, ale wszystkie możliwe urządzenia, jakie możesz sobie wyobrazić. Innymi słowy, znajdziesz tam pliki dla urządzeń, których w ogóle nie masz. Administrowanie taką grupą urządzeń jest co najmniej niezręczne. Wyobraźmy sobie, że mamy zmienić prawa dostępu do wszystkich plików urządzeń, które mają odpowiadające im urządzenia w systemie, a resztę plików zostawić, jakimi są.

Jeśli dodajesz nowy sprzęt do swojego systemu, a nie miał on wcześniej pliku urządzenia, musisz go utworzyć. Zaawansowani użytkownicy wiedzą, że zadanie to można wykonać przy pomocy ./MAKEDEV w drzewie /dev, ale czy od razu wiesz, jakie urządzenie utworzyć?

Jeśli masz programy współdziałające ze sprzętem używającym plików urządzeń, nie możesz zamontować partycji głównej tylko to odczytu, chcąc zamontować ją później do odczytu i zapisu. Nie możesz mieć też /dev na oddzielnej partycji, bo mount potrzebuje /dev do zamontowania partycji.

Rozwiązania

Jak możesz sobie wyobrazić, hakerzy znaleźli sporo rozwiązań powyższych problemów. Jednak wiele z nich ma inne usterki, co opisano w http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html#faq-why. Nie chcemy rozprawiać o tych implementacjach, ale wskazać na jedną z nich, która znajduje się w oficjalnych źródłach jądra: devfs.

devfs zwycięzca wszechwag?

devfs rozwiązuje wszystkie opisane problemy. Dostarcza użytkownikowi tylko istniejące urządzenia, dodaje nowe węzły, jeśli znaleziono nowe urządzenia i umożliwia zamontowanie głównego systemu plików tylko do odczytu. Rozwiązuje jeszcze wiele problemów, o których nie mówiliśmy wcześniej, bo są mniej interesujące dla użytkowników...

Na przykład, z devfs, nie musisz się martwić o pary major/minor. Dalej są obsługiwane (dla zgodności wstecz), ale nie są wymagane. Umożliwia to Linuksowi obsługę jeszcze większej ilości urządzeń, ponieważ nie ma już ograniczeń (liczby zawsze mają granice :)

Choć devfs ma swoje własne problemy; dla użytkowników końcowych nie są one w istocie widoczne, ale dla programiści jądra uznali te problemy za wystarczająco duże, aby oznaczyć devfs jako obsolete na korzyść udev (które Gentoo też obsługuje) i który jest domyślny na większości architektur dla jądra 2.6, począwszy od wydania 2005.0.

Więcej informacji, dlaczego devfs jest oznaczone jako przestarzałe, przeczytaj w udev FAQ and udev versus devfs document.

2.  Nawigacja w drzewie urządzeń

Katalogi

Jedną z pierwszych rzeczy jakie możesz zauważyć jest, że devfs używa katalogów do grupowania urządzeń. Zwiększa to czytelność, ponieważ wszystkie związane ze sobą urządzenia są wewnątrz wspólnego katalogu.

Na przykład, wszystkie związane poprzez IDE urządzenia są w katalogu /dev/ide/, a urządzenia SCSI są w /dev/scsi/. Dyski SCSI i IDE są widziane w ten sam sposób, co oznacza, że mają takie same struktury podkatalogów.

Dyskami IDE i SCSI zarządza adapter (na płycie albo oddzielnej karcie), nazywany hostem. Każdy adapter może mieć kilka kanałów. Kanał nazywany jest bus. Na każdym kanale możesz być kilka ID. Takie ID identyfikuje dysk. ID nazywane jest target. Niektóre urządzenia SCSI mogą mieć wielokrotne luns (Logical Unit Numbers - Numer logiczny jednostki), na przykład urządzenia obsługujące jednocześnie madia wielokrotne (hi-end tapedrives). Najczęściej masz tylko pojedynczy lun, lun0/.

Poprzednio używaliśmy /dev/hda4, a teraz mamy /dev/ide/host0/bus0/target0/lun0/part4. To jest daleko prostsze... nie, nie kłóć się ze mną... to jest łatwiejsze... jednak! :)

Uwaga: Możesz też używać dla dysków nazewnictwa bardziej Unixo-podobnego, takiego jak c0b0t0u0p2. Mogą być one znalezione w /dev/ide/hd, /dev/scsi/hd etc.

Aby dać ci pojęcie o katalogach, pokażę ci listing katalogów na moim laptopie:

Listing 2.1: Katalogi w /dev

cdroms/     cpu/        discs/          floppy/
ide/        input/      loop/           misc/
netlink/    printers/   pts/            pty/
scsi/       sg/         shm/            sound/
sr/         usb/        vc/             vcc/

Zgodność wstecz, przy użyciu devfs

Używanie nowego schematu wygląda dziwnie, ale część narzędzi i programów używa poprzedniego, starego schematu. Aby zapewnić, że żaden system nie padnie, stworzony został program devfsd. Demon ten tworzy dowiązania symboliczne ze starymi nazwami, wskazujące na nowe plików urządzeń.

Listing 2.2: Utworzone dowiązania symboliczne

$ ls -l /dev/hda4
lr-xr-xr-x    1 root     root           33 Aug 25 12:08 /dev/hda4 -> ide/host0/bus0/target0/lun0/part4

Przy pomocy devfsd, możesz również ustawić prawa dostępu, utworzyć pliki nowych urządzeń, określić działania, itd. To wszystko zostanie opisane w następnym rozdziale.

3.  Administrowanie drzewem urządzeń

Ponowne uruchomienie devfsd

Gdy zmieniasz plik /etc/devfsd.conf i chcesz, aby zmiany zostały przekazane do systemu, nie musisz go uruchamiać ponownie. Zależnie od tego, czego oczekujesz, możesz użyć jednego z dwóch następujących sygnałów:

SIGHUP ponownie przeczyta pliki konfiguracji devfsd, załaduje ponownie obiekty dzielone i wygeneruje zdarzenia REGISTER dla każdego wierzchołka w drzewie urządzeń.

SIGUSR1 zrobi to samo, ale nie wygeneruje zdarzeń REGISTER.

Aby wysłać sygnał, użyj po prostu kill albo killall:

Listing 3.1: Wysyłanie sygnału SIGHUP do devfsd

# kill -s SIGHUP `pidof devfsd`
albo
# killall -s SIGHUP devfsd

Usuwanie dowiązań dla zgodności

Ostrzeżenie: Aktualnie, Gentoo nie może istnieć bez dowiązań symbolicznych dla zgodności.

Jeśli chcesz usunąć dowiązania symboliczne dla zgodności, które zaśmiecają twój system /dev (Gentoo uruchamia je domyślnie), wejdź do pliku /etc/devfsd.conf i usuń następujące dwie linie:

Listing 3.2: /etc/devfsd.conf dla zgodności wstecz

# Wstaw znak komentarza na początku każdego z tych wierszy, aby usunąć dowiązania symboliczne
REGISTER        .*  MKOLDCOMPAT
UNREGISTER      .*  RMOLDCOMPAT

Musisz ponownie załadować system, aby zmiany przyniosły efekt.

Usuwanie funkcjonalności automatycznego ładowania

Kiedy ładujesz moduł, devfs automatycznie utworzy pliki urządzeń. Jeśli takiego zwyczaju nie chcesz, usuń następującą linię z /etc/devfsd.conf:

Listing 3.3: Funkcjonalność /etc/devfsd.conf, przy automatycznym ładowaniu

LOOKUP      .*  MODLOAD

4.  Elementy związane z uprawnieniami

Ustawianie/zmiana uprawnień w devfsd

Ważne: Poniższe instrukcje mają zastosowanie tylko wtedy gdy wyłączona jest pam_console w pliku /etc/pam.d/system-auth. Jeśli pam_console zostanie tam włączone to za prawa dostępu będzie odpowiadała PAM. pam_console to przestarzała technologia, została usunięta z Portage.

Jeśli jednak chcemy przydzielić uprawnienia przy pomocy /etc/devfsd.conf, używamy składni użytej w następujacym przykładzie:

Listing 4.1: Uprawnienia w /etc/devfsd.conf

REGISTER    ^cdroms/.*  PERMISSIONS root.cdrom 0660

Drugie pole, to grupa urządzeń zaczynająca się od /dev. Jest to wyrażenie regularne, można więc podać kilka plików urządzeń w jednej regule.

Czwarte pole określa właściciela pliku urządzeń, a piąte pole zawiera prawa dostępu do pliku urządzenia.

Ręczne ustawianie uprawnień, żeby devfsd je zachowało

Domyślnym zwyczajem w Gentoo jest: Jeśli wykonujesz chown (CHange OWNer - zmień właściciela) albo chmod (CHange MODe - zmień uprawnienia) jakichś plików urządzeń, devfsd zachowa te informacje, gdy zamkniesz system. Zachowa, ponieważ plik /etc/devfsd.conf zawiera następujące wiersze:

Listing 4.2: /etc/devfsd.conf zapamiętuje uprawnienia

REGISTER        ^pt[sy]/.*   IGNORE
CHANGE          ^pt[sy]/.*   IGNORE
CREATE          ^pt[sy]/.*   IGNORE
DELETE          ^pt[sy]      IGNORE
REGISTER        ^log         IGNORE
CHANGE          ^log         IGNORE
CREATE          ^log         IGNORE
DELETE          ^log         IGNORE
REGISTER        .*           COPY    /lib/dev-state/$devname $devpath
CHANGE          .*           COPY    $devpath /lib/dev-state/$devname
CREATE          .*           COPY    $devpath /lib/dev-state/$devname
DELETE          .*           CFUNCTION GLOBAL unlink
/lib/dev-state/$devname
RESTORE         /lib/dev-state

Innymi słowy zmienione pliki urządzeń są kopiowane do /lib/dev-state zaraz po dokonaniu zmian i kopiowane z powrotem do /dev przy ładowaniu systemu.

Inną możliwością jest zamontowanie /lib/dev-state na /dev w czasie ładowania systemu. Aby to zrobić, musisz upewnić się, że devfs nie jest montowane automatycznie (jeżeli tak konieczne jest przekompilowanie jądra) i że /dev/console istnieje. Wtedy, gdzieś na początku skryptu ładowania systemu, umieść:

Listing 4.3: Montowanie /lib/dev-state na /dev

mount --bind /dev /lib/dev-state
mount -t devfs none /dev
devfsd /dev

5.  Źródła

Więcej informacji o devfs, znajdziesz w nastepujacych źródłach.

Strona man devfsd.conf wyjaśnia składnię pliku /etc/devfsd.conf. Aby ją obejrzeć, napisz man devfsd.conf.

Strona devfs FAQ wyjaśnia wszystko o devfs. Zawiera również informacje o wewnętrznej strukturze devfs i w jaki sposób sterowniki mogą obsługiwać devfs.

Na stronie LinuxJournal jest interesujący artykuł o devfs w Zarządzaniu i Administracji.

Daniel Robbins napisał cykl artykułów dla IBM's DeveloperWorks o zaawansowanych systemach plików. Trzy z nich dotyczą devfs:



Drukuj

Zaktualizowano 15 listopada 2007

Podsumowanie: Z tego dokumentu dowiemy się co to jest devfs i jak z nim pracować.

Sven Vermeulen
Autor

Seemant Kulleen
Korekta

Jerzy Pawelec
Tłumaczenie

Donate to support our development efforts.

Copyright 2001-2012 Gentoo Foundation, Inc. Questions, Comments? Contact us.