Linux, gerçek ve varolmayan (örneğin: aygıt) dosyaları arasında nasıl farklılaşır?


28

Bu oldukça düşük seviye bir sorudur ve sorulacak en iyi yer olmayabilir. Ancak, diğer tüm SE sitelerinden daha uygun görünüyordu, işte burada.

Linux dosya sisteminde bazı dosyaların gerçekten var olduğunu biliyorum, örneğin: /usr/bin/bashvar olanı. Ancak, (bildiğim kadarıyla anladığım kadarıyla), bazıları da aslında daha aynı şekilde varlığını meyen, fakat sanal dosyaları, örneğin: /dev/sda, /proc/cpuinfovb Sorularım şunlardır (iki, ama çok yakından ayrı soru olmak ilişkin):

  • Linux çekirdeği, bu dosyaların gerçek olup olmadığına (ve dolayısıyla bunları diskten okuyabildiğine) ya da bir okuma komutu (ya da böyle bir) verildiğinde nasıl işler?
  • Dosya gerçek değilse: bir örnek olarak, bir okuma /dev/randomrasgele veriyi döndürür ve bir okuma /dev/nullgeri döner EOF. Bu sanal dosyadan hangi verilerin okunacağının (ve dolayısıyla sanal dosyaya yazılan verilerin ne zaman / eğer ne yapılacağının) nasıl işleyeceği - her dosya için uygun okuma / yazma komutlarını ayırmak için işaretçiler içeren bir tür harita var mı? hatta sanal dizinin kendisi için bile? Yani, bir giriş /dev/nullsadece bir döndürebilir EOF.

1
Dosya oluşturulduğunda, çekirdek türünü kaydeder. Düzenli disk dosyaları daha sonra sembolik işaretlerden, blok aygıtlarından, karakter aygıtlarından, dizinlerden, soketlerden, FIFO'lardan vb. Farklı şekilde muamele görür.
Jonathan Leffler

mknod için erkek oyuncu görmek
Jasen

Bu, "Bir ışık anahtarı ışığın açık olup olmadığını nasıl biliyor?" Diye sormaya benzer. Işık anahtarı, ışığın açılıp açılmadığına karar vermekle sorumludur.
Monica

Yanıtlar:


25

Yani burada temel olarak iki farklı şey var:

  1. Dosyaları veri ve meta veri içeren dizinlerde tanıdık bir şekilde (yumuşak bağlantılar, sabit bağlantılar vb. Dahil) tutan normal dosya sistemleri. Bunlar genellikle, ancak her zaman değil, kalıcı depolama için bir blok aygıtı tarafından desteklenir (bir tmpfs yalnızca RAM'de yaşar, ancak normal bir dosya sistemiyle aynıdır). Bunların anlambilimi tanıdık; okumak, yazmak, yeniden adlandırmak ve diğerleri, beklediğiniz gibi çalışır.
  2. Çeşitli türlerde sanal dosya sistemleri. /procve /sysburada, FUSE gibi sshfsveya özel dosya sistemlerinde örnek olarak verilebilir ifuse. Bunlarda çok daha fazla çeşitlilik var, çünkü gerçekten sadece bir anlamda 'özel' olan anlambilimsel bir dosya sistemine atıfta bulunuyorlar. Bu nedenle, altındaki bir dosyadan okuduğunuzda, /procnormal bir dosya sisteminde olduğu gibi, daha önce yazan başka bir şeyin depoladığı belirli bir verilere erişemezsiniz. Esasen çekirdek çağrısı yapıyorsunuz ve anında oluşturulan bazı bilgileri istiyorsunuz. Ve bu kod sevdiği her şeyi yapabilir, çünkü sadece readanlambilimi uygulayan bir fonksiyondur . Böylece, dosyaların altında tuhaf /procdavranırsınız, örneğin, oldukları sırada sembolik bağlantılar yapıyormuş gibi davranırlar.

Anahtar, /devaslında, genellikle ilk türden biridir. Modern dağıtımlarda /devtmpfs gibi bir şey olması normaldir , ancak eski sistemlerde, herhangi bir özel öznitelik olmadan diskte düz bir dizin olması normaldir. Anahtar, altındaki dosyaların /devcihaz düğümleri, FIFO'lara veya Unix soketlerine benzer bir tür özel dosya; Bir aygıt düğümü büyük ve küçük bir sayıya sahiptir ve bunları okumak veya yazmak, bir FIFO okumak veya yazmak gibi çekirdeği bir çekirdeğe çağrı yapmak gibi çekirdeği bir boruya çıktısını almak için çekirdeği çağırıyor. Bu sürücü ne isterse yapabilir, ancak genellikle bir şekilde donanıma dokunur, örneğin bir sabit diske erişmek veya hoparlörlerden ses çalmak için.

Orijinal soruları cevaplamak için:

  1. 'Dosyanın olup olmadığı' ile ilgili iki soru vardır; bunlar aygıt düğümü dosyasının tam anlamıyla var olup olmadığı ve onu destekleyen çekirdek kodunun anlamlı olup olmadığıdır. Eski normal bir dosya sistemindeki herhangi bir şey gibi çözülür. Modern sistemler udevdonanım olaylarını izlemek için kullanır ya da onun gibi bir şey kullanır ve /devbuna göre cihaz düğümlerini otomatik olarak oluşturur ve yok eder . Ancak, eski sistemler veya hafif özel yapılar, tüm cihaz düğümlerini tam anlamıyla önceden oluşturulmuş diskte alabilir. Bu arada, bu dosyaları okurken, ana ve küçük cihaz numaraları tarafından belirlenen çekirdek koduna bir çağrı yapıyorsunuz; bunlar makul değilse (örneğin, mevcut olmayan bir blok cihazını okumaya çalışıyorsunuzdur), sadece bir tür G / Ç hatası alırsınız.

  2. Hangi aygıt dosyası için hangi çekirdek kodunun çağrılacağına karar verilir. Gibi sanal dosya sistemleri için /proc, kendi readve writeişlevlerini uygularlar; çekirdek, hangi bağlama noktasına bağlı olduğuna bağlı olarak bu kodu çağırır ve dosya sistemi uygulaması gerisini halleder. Cihaz dosyaları için, ana ve küçük cihaz numaralarına göre gönderilir.


Öyleyse, diyelim ki, eski bir sistemin gücü kesildiyse, içindeki dosyalar /devhala orada olacaktı, ancak sistem başladığında temizleneceklerini sanırım?
Joe,

2
Eski bir sistem (herhangi bir dinamik cihaz oluşturulmadan), normal veya anormal şekilde kapatılmış olsaydı, cihaz düğümleri herhangi bir dosya gibi diskte kalırdı. Sonra bir sonraki açılış olduğunda, onlar da diskte kalacaktı ve siz bunları normal şekilde kullanabilirsiniz. Sadece modern sistemlerde, cihaz düğümleri oluşturup yok ederek özel bir şey olur.
Tom Hunt,

Bu yüzden, kullanmayacağınız daha modern bir sistem, tmpfsgerektiğinde dinamik olarak bunları oluşturacak ve silecektir, örneğin: açılış ve kapanma?
Joe,

3
devtmpfs, /devModern Linux dosya sistemi, bir benzer tmpfs, ancak destek için bazı farklılıklar vardır udev. (Çekirdek, udevdaha az karmaşık hale getirmek için teslim edilmeden önce bazı otomatik düğüm oluşturma işlemlerini kendi başına yapar.) Tüm bu durumlarda, aygıt düğümleri yalnızca RAM'de yaşar ve donanımın gerektirdiği şekilde dinamik olarak oluşturulur ve yok edilir. Muhtemelen udevdiskte sıradan bir diskte de kullanabilirsiniz /dev, ancak bunu daha önce hiç görmedim ve bunun için iyi bir sebep görünmüyor.
Tom Hunt,

17

İşte /dev/sda1neredeyse güncel Arch Linux sunucumun bir listesi:

% ls -li /dev/sda1
1294 brw-rw---- 1 root disk 8, 1 Nov  9 13:26 /dev/sda1

Bu nedenle, dizin girişi /dev/için sda1294 inode numarası vardır. Diskte gerçek bir dosyadır.

Dosya boyutunun genellikle nerede göründüğüne bakın. Bunun yerine "8, 1" belirir. Bu büyük ve küçük bir cihaz numarasıdır. Ayrıca dosya izinlerindeki 'b'yi not edin.

Dosya /usr/include/ext2fs/ext2_fs.hbu (fragment) C yapıyı içerir:

/*
 * Structure of an inode on the disk
 */
struct ext2_inode {
    __u16   i_mode;     /* File mode */

Bu yapı bize bir dosyanın inode'unun disk üzerindeki yapısını gösterir. Çok sayıda ilginç şey bu yapı içinde; uzun bir göz atın.

i_modeElemanı struct ext2_inode16 bit sahiptir ve diğer kullanıcı / grup / sadece 9 kullanır / yazma / yürütme izinlerini okumak ve setuid, setgid ve yapışkan olan bir 3. "Düz dosya", "link", "dizin", "adlandırılmış yöneltme", "Unix aile soketi" ve "blok aygıtı" gibi türler arasında ayrım yapmak için 4 bit var.

Linux çekirdeği normal dizin arama algoritmasını izleyebilir, ardından i_modeelemandaki izinlere ve bayraklara dayanarak bir karar verebilir . 'B' için, aygıt dosyalarını engelle, büyük ve küçük aygıt numaralarını bulabilir ve geleneksel olarak, büyük aygıt numarasını, disklerle ilgilenen bazı çekirdek işlevlerine (aygıt sürücüsü) işaretçi aramak için kullanır. Küçük cihaz numarası genellikle, SCSI veri yolu cihaz numarası veya EIDE cihaz numarası veya benzeri bir şey olarak kullanılır.

Bir dosyayla nasıl başa çıkılacağına ilişkin bazı diğer kararlar /proc/cpuinfodosya sistemi türüne göre verilir. Eğer bir şey yaparsan:

% mount | grep proc 
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

Bunun /proc"proc" dosya sistemi türüne sahip olduğunu görebilirsiniz . Bir dosyadan okumak /proc, çekirdeğin bir ReiserFS veya DOS dosya sisteminde bir dosyayı açmak gibi, çekirdeğin dosyaları bulmak ve farklı verileri bulmak için çekirdeğin farklı işlevler kullanmasına neden olur. Dosyalar.


Sadece "diskteki gerçek dosyaların" görüntülenen inode numarasına sahip olduğundan emin misiniz? 4026531975 -r--r--r-- 1 root root 0 Nov 14 18:41 /proc/mdstatAçıkça "gerçek bir dosya" olmadığını anlıyorum .
guntbert

7

Günün sonunda, hepsi Unix'in dosyaları, soyutlamanın güzelliği bu.

Dosyaların çekirdek tarafından işlenme şekli, şimdi bu farklı bir hikaye.

/ proc ve günümüzde / dev ve / run (aka / var / run) RAM'deki sanal dosya sistemleridir. / proc, çekirdek değişkenleri ve yapıları için bir arayüz / pencerelerdir.

Linux Çekirdeğini http://tldp.org/LDP/tlk/tlk.html ve Linux Aygıt Sürücüleri, Üçüncü Basım https://lwn.net/Kernel/LDD3/ okumanızı tavsiye ederim .

Ben de Tasarım ve FreeBSD İşletim Sisteminin Uygulanmasına zevk http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1

Sorunuzla ilgili ilgili sayfaya bir göz atın.

http://www.tldp.org/LDP/tlk/dd/drivers.html


teşekkürler, siz bunu yorumladıktan sonra ilk soruyu biraz değiştirdim.
Joe

Lütfen son yorumu okuyun.
Rui F Ribeiro

5

@ RuiFRibeiro ve @ BruceEdiger'in cevaplarına ek olarak, yaptığınız ayrım tam olarak çekirdeğin yaptığı fark değildir. Aslında, çeşitli dosyalarınız var: normal dosyalar, dizinler, sembolik bağlantılar, cihazlar, yuvalar (ve her zaman bir kaçını unuturum, böylece tam bir liste yapmaya çalışmam). Bir dosyanın türüyle ilgili bilgilere sahip olabilirsiniz ls: satırdaki ilk karakter. Örneğin:

$ls -la /dev/sda
brw-rw---- 1 root disk 8, 0 17 nov.  08:29 /dev/sda

En başında 'b' bu dosyanın bir blok cihaz olduğunu belirtir. Bir çizgi, normal bir dosya anlamına gelir, 'ben' sembolik bir bağlantı vb. Bu bilgiler dosyanın meta verilerinde saklanır ve statörneğin sistem çağrısı yoluyla erişilebilir , böylece çekirdek farklı bir dosyayı ve örneğin sembolik bir linki okuyabilir.

Daha sonra, "gerçek dosyalar" gibi /bin/bashve "sanal dosyalar" gibi başka bir ayrım yaparsınız, /proc/cpuinfoancak lsher ikisini de normal dosyalar olarak rapor edersiniz ;

ls -la /proc/cpuinfo /bin/bash
-rwxr-xr-x 1 root root  829792 24 août  10:58 /bin/bash
-r--r--r-- 1 root wheel      0 20 nov.  16:50 /proc/cpuinfo

Olan, farklı dosya sistemlerine ait olmaları. /procsözde bir dosya sisteminin montaj noktası procfsise /bin/bashnormal bir disk dosya sistemindedir. Linux bir dosyayı açtığında (dosya sistemine bağlı olarak çok farklı bir şey yaparsa) file, diğerlerinin yanı sıra, bu dosyanın nasıl kullanılacağını açıklayan birkaç fonksiyon işaretçisinin yapısına sahip olan bir veri yapısı doldurur . Bu nedenle, farklı tür dosyalar için farklı davranışlar uygulayabilir.

Örneğin, bunlar reklam verenler /proc/meminfo:

static int meminfo_proc_open(struct inode *inode, struct file *file)
{
    return single_open(file, meminfo_proc_show, NULL);
}

static const struct file_operations meminfo_proc_fops = {
    .open       = meminfo_proc_open,
    .read       = seq_read,
    .llseek     = seq_lseek,
    .release    = single_release,
};

Tanımına bakarsanız, meminfo_proc_openbu işlevin, işlevi meminfo_proc_showbellek kullanımı hakkında veri toplamak olan , işlev tarafından döndürülen bilgilerle bellekte bir arabellek doldurduğunu görebilirsiniz . Bu bilgi daha sonra normal bir şekilde okunabilir. Dosyayı her açtığınızda, işlev meminfo_proc_opençağrılır ve bellekle ilgili bilgiler yenilenir.


3

Bir dosya sistemindeki tüm dosyalar, dosya G / Ç'ye izin verdikleri anlamında "gerçek" tir. Bir dosyayı açtığınızda, çekirdek bir dosya gibi davranan bir nesne (nesne yönelimli programlama anlamında) olan bir dosya tanımlayıcısı oluşturur. Dosyayı okursanız, dosya tanımlayıcısı okuma yöntemini uygular; bu da dosya sisteminden (sysfs, ext4, nfs, vb.) Dosyadaki verileri ister. Dosya sistemleri kullanıcı alanına tek tip bir arayüz sunar ve okuma ve yazma işlemlerinde ne yapılması gerektiğini bilir. Dosya sistemleri sırayla diğer katmanlardan taleplerini gerçekleştirmelerini ister. Bir ext4 dosya sistemi hakkında düzenli bir dosya için, bu, dosya sisteminin veri yapılarında (disk okumaları da içerebilir) ve sonunda verileri okuma arabelleğine kopyalamak için diskten (veya önbellek) bir okumadan ibarettir. Sysfs'deki bir dosya için, Bu genellikle sadece sprintf () 'nin arabellek için bir şey. Bir blok dev düğümü için, disk sürücüsünden bazı blokları okumasını ve bunları ara belleğe kopyalamasını ister (büyük ve küçük sayılar, dosya sistemine hangi sürücünün talep edeceğini söyler).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.