V zásadě tedy existují dva různé typy věcí:
- Normální souborové systémy, které uchovávají soubory v adresářích s daty a metadaty známým způsobem (včetně měkkých odkazů, pevných odkazů a tak dále). Ty jsou často, ale ne vždy, podporovány blokovým zařízením pro trvalé úložiště (tmpfs žije pouze v RAM, ale jinak je identický s normálním souborovým systémem). Jejich sémantika je známá; číst, psát, přejmenovávat a tak dále, vše funguje tak, jak očekáváte.
- Virtuální souborové systémy různých druhů.
/proc
a/sys
jsou zde příklady, stejně jako vlastní souborové systémy FUSE jakosshfs
neboifuse
. Je v nich mnohem větší rozmanitost, protože ve skutečnosti jen odkazují na souborový systém se sémantikou, která je v určitém smyslu „vlastní“. Tedy, když čtete ze souboru pod/proc
, ve skutečnosti nepřistupujete ke konkrétní části dat, která byla uložena něčím jiným, co je zapsalo dříve, jako v běžném souborovém systému. V podstatě provádíte volání jádra a požadujete nějaké informace, které se generují za běhu. A tento kód může dělat, co chce, protože je to jen nějaká funkce někde implementujícíread
sémantika. Máte tedy podivné chování souborů pod/proc
, jako je například předstírání symbolických odkazů, když ve skutečnosti nejsou.
Klíčem je, že /dev
je ve skutečnosti obvykle jedním z prvního druhu. V moderních distribucích je normální mít /dev
být něco jako tmpfs, ale ve starších systémech bylo normální, že to byl prostý adresář na disku, bez jakýchkoliv speciálních atributů. Klíčem je, že soubory pod /dev
jsou uzly zařízení, typ speciálního souboru podobný FIFO nebo Unix socketům; uzel zařízení má hlavní a vedlejší číslo a jejich čtení nebo zápis je voláním ovladače jádra, podobně jako čtení nebo zápis FIFO volá jádro, aby vyrovnalo váš výstup do roury. Tento ovladač si může dělat co chce, ale většinou se nějak dotkne hardwaru, např. pro přístup k pevnému disku nebo přehrávání zvuku v reproduktorech.
Chcete-li odpovědět na původní otázky:
-
Existují dvě otázky týkající se toho, zda „soubor existuje“ či nikoli; jde o to, zda soubor uzlu zařízení doslova existuje a zda má smysl kód jádra, který jej podporuje. První z nich je vyřešen stejně jako cokoli na normálním souborovém systému. Moderní systémy používají
udev
nebo něco podobného, abyste sledovali hardwarové události a automaticky vytvořili a zničili uzly zařízení pod/dev
podle toho. Ale starší systémy nebo lehká vlastní sestavení mohou mít všechny uzly zařízení doslova na disku, vytvořené předem. Mezitím, když čtete tyto soubory, voláte kód jádra, který je určen hlavním a vedlejším číslem zařízení; pokud to není rozumné (například se pokoušíte přečíst blokové zařízení, které neexistuje), dostanete prostě nějakou chybu I/O. -
Způsob, jakým se zjistí, jaký kód jádra volat pro který soubor zařízení, se liší. Pro virtuální souborové systémy jako
/proc
, implementují vlastníread
awrite
funkce; jádro prostě volá tento kód podle toho, ve kterém přípojném bodu se nachází, a o zbytek se postará implementace souborového systému. U souborů zařízení se odesílá na základě hlavních a vedlejších čísel zařízení.
Zde je seznam souborů /dev/sda1
na mém téměř aktuálním serveru Arch Linux:
% ls -li /dev/sda1
1294 brw-rw---- 1 root disk 8, 1 Nov 9 13:26 /dev/sda1
Takže položka adresáře v /dev/
pro sda
má číslo inodu, 1294. Je to skutečný soubor na disku.
Podívejte se, kde se obvykle zobrazuje velikost souboru. Místo toho se zobrazí "8, 1". Toto je hlavní a vedlejší číslo zařízení. Všimněte si také „b“ v oprávněních k souboru.
Soubor /usr/include/ext2fs/ext2_fs.h
obsahuje tuto (fragment) strukturu C:
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
Tato struktura nám ukazuje strukturu inodu souboru na disku. V této struktuře je spousta zajímavých věcí; dlouze se na to podívejte.
i_mode
prvek struct ext2_inode
má 16 bitů a používá pouze 9 pro oprávnění uživatele/skupinu/ostatní, čtení/zápis/spouštění a další 3 pro setuid, setgid a sticky. Má 4 bity pro rozlišení mezi typy, jako je „prostý soubor“, „odkaz“, „adresář“, „pojmenovaný kanál“, „zásuvka rodiny Unix“ a „blokovací zařízení“.
Linuxové jádro se může řídit obvyklým algoritmem pro vyhledávání adresářů a poté se rozhodnout na základě oprávnění a příznaků v i_mode
živel. U souborů blokových zařízení 'b' dokáže najít hlavní a vedlejší čísla zařízení a tradičně používá hlavní číslo zařízení k vyhledání ukazatele na nějakou funkci jádra (ovladač zařízení), která se zabývá disky. Vedlejší číslo zařízení se obvykle používá jako číslo zařízení sběrnice SCSI nebo číslo zařízení EIDE nebo něco podobného.
Některá další rozhodnutí o tom, jak naložit se souborem, jako je /proc/cpuinfo
jsou vytvořeny na základě typu souborového systému. Pokud uděláte:
% mount | grep proc
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
můžete vidět, že /proc
má typ souborového systému "proc". Čtení ze souboru v /proc
způsobí, že jádro udělá něco jiného v závislosti na typu souborového systému, stejně jako otevření souboru v souborovém systému ReiserFS nebo DOS by způsobilo, že jádro použije různé funkce k vyhledání souborů a vyhledání dat souborů.
Na konci dne jsou to všechny soubory pro Unix, v tom je krása abstrakce.
Způsob, jakým jádro zpracovává soubory, je nyní jiný příběh.
/proc a dnes /dev a /run (aka /var/run) jsou virtuální souborové systémy v RAM. /proc je rozhraní/okna k proměnným a strukturám jádra.
Doporučuji přečíst si The Linux Kernel http://tldp.org/LDP/tlk/tlk.html and Linux Device Drivers, Third Edition https://lwn.net/Kernel/LDD3/.
Také se mi líbilo Návrh a implementace operačního systému FreeBSD http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Podívejte se na příslušnou stránku, která se týká vaší otázky.
http://www.tldp.org/LDP/tlk/dd/drivers.html