To pytanie na niskim poziomie i rozumiem, że może nie być to najlepsze miejsce do zadawania pytań. Ale to wydawało się bardziej odpowiednie niż jakakolwiek inna strona SE, więc proszę.
Wiem, że w systemie plików Linux niektóre pliki faktycznie istnieją , na przykład: /usr/bin/bash
jest taki, który istnieje. Jednak (o ile dobrze rozumiem), niektóre także w rzeczywistości nie istnieją jako takie i są bardziej wirtualnych plików, np: /dev/sda
, /proc/cpuinfo
, itd. Moje pytania są (są dwa, ale zbyt ściśle związane odrębne pytania):
- W jaki sposób jądro Linuksa sprawdza, czy te pliki są prawdziwe (i dlatego odczytują je z dysku), czy nie po wydaniu polecenia odczytu (lub takiego)?
- Jeśli plik nie jest prawdziwy: na przykład odczyt z
/dev/random
zwróci losowe dane, a odczyt z/dev/null
zwróciEOF
. Jak to działa, jakie dane należy odczytać z tego pliku wirtualnego (a zatem co zrobić, gdy / jeśli dane zapisane również do pliku wirtualnego) - czy istnieje jakaś mapa ze wskaźnikami do oddzielania poleceń odczytu / zapisu odpowiednich dla każdego pliku, a nawet sam katalog wirtualny? Więc wpis dla/dev/null
może po prostu zwrócićEOF
.
Odpowiedzi:
Istnieją więc w zasadzie dwa różne rodzaje rzeczy:
/proc
i/sys
są tutaj przykładami, podobnie jak niestandardowe systemy plików FUSE, takie jaksshfs
lubifuse
. Jest w nich znacznie więcej różnorodności, ponieważ tak naprawdę odnoszą się one do systemu plików z semantyką, który jest w pewnym sensie „niestandardowy”. Tak więc, kiedy czytasz z pliku pod/proc
, tak naprawdę nie uzyskujesz dostępu do określonego fragmentu danych, który został zapisany przez coś innego, co zapisuje go wcześniej, jak w normalnym systemie plików. Zasadniczo wykonujesz wywołanie jądra, żądając informacji generowanych w locie. I ten kod może robić, co tylko zechce, ponieważ jest to tylko jakaś funkcja gdzieś implementującaread
semantykę. Tak więc masz dziwne zachowanie plików/proc
, na przykład udając, że są dowiązaniami symbolicznymi, gdy nie sąKluczem jest to, że w
/dev
rzeczywistości jest to zwykle jeden z pierwszych rodzajów. Współczesne dystrybucje/dev
są czymś w rodzaju tmpfs, ale w starszych systemach zwykłym katalogiem na dysku jest brak specjalnych atrybutów. Kluczem jest to, że pliki poniżej/dev
to węzły urządzeń, rodzaj specjalnych plików podobnych do FIFO lub gniazd Unix; węzeł urządzenia ma główny i podrzędny numer, a ich odczytywanie lub zapisywanie wywołuje sterownik jądra, podobnie jak odczytywanie lub zapisywanie FIFO wywołuje jądro w celu buforowania danych wyjściowych w potoku. Ten sterownik może robić, co chce, ale zwykle w jakiś sposób dotyka sprzętu, np. Aby uzyskać dostęp do dysku twardego lub odtwarzać dźwięk w głośnikach.Aby odpowiedzieć na oryginalne pytania:
Istnieją dwa pytania dotyczące tego, czy „plik istnieje”, czy nie; chodzi o to, czy plik węzła urządzenia istnieje dosłownie i czy ma znaczenie sens kopii zapasowej jądra. Ten pierwszy rozwiązano tak jak wszystko w normalnym systemie plików. Nowoczesne systemy używają
udev
lub coś w tym rodzaju do wyszukiwania zdarzeń sprzętowych i automatycznego tworzenia i niszczenia odpowiednio węzłów urządzeń/dev
. Ale starsze systemy lub lekkie niestandardowe wersje mogą po prostu mieć wszystkie swoje węzły urządzeń dosłownie na dysku, utworzone wcześniej. Tymczasem, kiedy czytasz te pliki, wykonujesz wywołanie do kodu jądra, który jest określony przez główne i podrzędne numery urządzeń; jeśli to nie jest rozsądne (na przykład próbujesz odczytać urządzenie blokowe, które nie istnieje), po prostu pojawi się jakiś błąd we / wy.Sposób, w jaki działa, jaki kod jądra ma być wywoływany, dla którego pliku urządzenia się zmienia. W przypadku wirtualnych systemów plików
/proc
, implementują własneread
iwrite
funkcje; jądro po prostu wywołuje ten kod w zależności od tego, w którym punkcie montowania jest, a reszta zajmuje się implementacją systemu plików. W przypadku plików urządzeń wysyłany jest na podstawie głównych i podrzędnych numerów urządzeń.źródło
/dev
zostałby odłączony, pliki nadal byłyby dostępne, ale myślę, że zostałyby usunięte po uruchomieniu systemu?tmpfs
dynamicznie tworzyłby je i usuwał w razie potrzeby, np .: uruchamianie i zamykanie?devtmpfs
,/dev
system plików we współczesnym systemie Linux jest podobny dotmpfs
, ale ma pewne różnice w obsłudzeudev
. (Jądro wykonuje pewne automatyczne tworzenie węzłów przed przekazaniem doudev
, aby uprościć rozruch). We wszystkich tych przypadkach węzły urządzeń żyją tylko w pamięci RAM i są tworzone i niszczone dynamicznie, gdy wymaga tego sprzęt. Prawdopodobnie możesz także użyćudev
na zwykłym dysku/dev
, ale nigdy tego nie widziałem i nie ma żadnych dobrych powodów.Oto lista plików
/dev/sda1
mojego prawie aktualnego serwera Arch Linux:Więc wpis w katalogu
/dev/
dlasda
ma numer i-węzła, 1294. To prawdziwy plik na dysku.Zobacz, gdzie zwykle pojawia się rozmiar pliku. Zamiast tego pojawia się „8, 1”. Jest to główny i mniejszy numer urządzenia. Zwróć także uwagę na „b” w uprawnieniach do plików.
Plik
/usr/include/ext2fs/ext2_fs.h
zawiera tę (fragment) strukturę C:Ta struktura pokazuje nam strukturę dyskową i-węzła pliku. W tej strukturze jest wiele interesujących rzeczy; spójrz na to długo.
i_mode
Elementemstruct ext2_inode
ma 16 bitów i używa tylko 9 dla użytkownika / grupy / pozostałych, odczyt / zapis / wykonanie uprawnień, a kolejne 3 do setuid, setgid i lepkie. Ma 4 bity, aby rozróżnić typy, takie jak „zwykły plik”, „link”, „katalog”, „nazwany potok”, „gniazdo rodziny Unix” i „urządzenie blokujące”.Jądro Linux może postępować zgodnie ze zwykłym algorytmem wyszukiwania katalogów, a następnie podejmować decyzje na podstawie uprawnień i flag w
i_mode
elemencie. W przypadku „b”, blokuj pliki urządzeń, może znaleźć główne i podrzędne numery urządzeń, i tradycyjnie, użyj głównego numeru urządzenia, aby wyszukać wskaźnik do funkcji jądra (sterownika urządzenia), która zajmuje się dyskami. Podrzędny numer urządzenia zwykle jest używany, jak powiedzmy, numer urządzenia magistrali SCSI, numer urządzenia EIDE lub coś w tym rodzaju.Niektóre inne decyzje dotyczące sposobu postępowania z plikiem typu
/proc/cpuinfo
są podejmowane na podstawie typu systemu plików. Jeśli wykonasz:widać, że
/proc
ma system plików typu „proc”. Czytanie z pliku/proc
powoduje, że jądro robi coś innego w zależności od typu systemu plików, podobnie jak otwarcie pliku w systemie plików ReiserFS lub DOS spowodowałoby, że jądro użyłoby różnych funkcji do zlokalizowania plików i zlokalizowania danych pliki.źródło
4026531975 -r--r--r-- 1 root root 0 Nov 14 18:41 /proc/mdstat
co wyraźnie nie jest „prawdziwym plikiem”.Na koniec wszystkie są plikami dla Uniksa, to jest piękno abstrakcji.
Sposób, w jaki pliki są obsługiwane przez jądro, teraz jest inna historia.
/ proc, a obecnie / dev i / run (aka / var / run) to wirtualne systemy plików w pamięci RAM. / proc to interfejs / windows do zmiennych i struktur jądra.
Polecam przeczytać jądro Linux http://tldp.org/LDP/tlk/tlk.html i sterowniki urządzeń Linux, wydanie trzecie https://lwn.net/Kernel/LDD3/ .
Podobał mi się także projekt i wdrożenie systemu operacyjnego FreeBSD http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Zajrzyj na odpowiednią stronę dotyczącą twojego pytania.
http://www.tldp.org/LDP/tlk/dd/drivers.html
źródło
Oprócz odpowiedzi @ RuiFRibeiro i @ BruceEdiger, twoje rozróżnienie nie jest dokładnie tym, co robi jądro. W rzeczywistości masz różne rodzaje plików: zwykłe pliki, katalogi, dowiązania symboliczne, urządzenia, gniazda (i zawsze zapominam o kilku, więc nie będę próbował stworzyć pełnej listy). Możesz uzyskać informacje o typie pliku za pomocą
ls
: jest to pierwszy znak w linii. Na przykład:„B” na samym początku sygnalizuje, że ten plik jest urządzeniem blokowym. Myślnik oznacza zwykły plik, „l” symboliczny link i tak dalej. Informacje te są przechowywane w metadanych pliku i są dostępne
stat
na przykład poprzez wywołanie systemowe , dzięki czemu jądro może na przykład inaczej odczytać plik i dowiązanie symboliczne.Następnie dokonujesz kolejnego rozróżnienia między „plikami rzeczywistymi”
/bin/bash
i „plikami wirtualnymi”,/proc/cpuinfo
alels
zgłaszasz oba jako zwykłe pliki, więc różnica jest inna:Dzieje się tak, ponieważ należą one do różnych systemów plików.
/proc
jest punktem montażowym pseudo-systemu plików,procfs
podczas gdy/bin/bash
znajduje się na zwykłym systemie plików dysku. Kiedy Linux otwiera plik (robi to inaczej w zależności od systemu plików), zapełnia strukturę danych,file
która ma, między innymi, strukturę kilku wskaźników funkcji, które opisują sposób korzystania z tego pliku. Dlatego może implementować różne zachowania dla różnego rodzaju plików.Na przykład są to operacje reklamowane przez
/proc/meminfo
:Patrząc na definicję
meminfo_proc_open
, można zauważyć, że ta funkcja zapełnia bufor w pamięci informacjami zwracanymi przez funkcjęmeminfo_proc_show
, której zadaniem jest zbieranie danych o zużyciu pamięci. Informacje te można następnie odczytać normalnie. Przy każdym otwarciu pliku funkcjameminfo_proc_open
jest wywoływana, a informacje o pamięci są odświeżane.źródło
Wszystkie pliki w systemie plików są „rzeczywiste” w tym sensie, że pozwalają na operacje wejścia / wyjścia plików. Po otwarciu pliku jądro tworzy deskryptor pliku, który jest obiektem (w sensie programowania obiektowego), który działa jak plik. Jeśli czytasz plik, deskryptor pliku wykonuje metodę odczytu, która z kolei poprosi system plików (sysfs, ext4, nfs itp.) O dane z pliku. Systemy plików stanowią jednolity interfejs do przestrzeni użytkownika i wiedzą, co zrobić, aby obsłużyć odczyty i zapisy. Z kolei systemy plików proszą inne warstwy o obsługę swoich żądań. W przypadku zwykłego pliku, powiedzmy systemu plików ext4, będzie to wymagało wyszukiwania w strukturach danych systemu plików (co może obejmować odczyt dysku), a ostatecznie odczytu z dysku (lub pamięci podręcznej) w celu skopiowania danych do bufora odczytu. W przypadku pliku powiedzmy sysfs, generalnie po prostu sprintf () s coś do bufora. W przypadku węzła tworzenia bloków poprosi sterownik dysku o odczytanie niektórych bloków i skopiowanie ich do bufora (numery główne i podrzędne informują system plików, do którego sterownika należy kierować żądania).
źródło