Co się dzieje, gdy piszę cat /proc/cpuinfo
. Czy to nazwany potok (lub coś innego) do systemu operacyjnego, który odczytuje informacje o procesorze w locie i generuje ten tekst za każdym razem, gdy go nazywam?
Co się dzieje, gdy piszę cat /proc/cpuinfo
. Czy to nazwany potok (lub coś innego) do systemu operacyjnego, który odczytuje informacje o procesorze w locie i generuje ten tekst za każdym razem, gdy go nazywam?
Odpowiedzi:
Ilekroć czytasz plik poniżej /proc
, wywołuje to pewien kod w jądrze, który oblicza tekst do odczytania jako zawartość pliku. Fakt, że treść jest generowana w locie, wyjaśnia, dlaczego prawie wszystkie pliki zgłaszają swój czas jak teraz, a ich rozmiar zgłaszany jest jako 0 - tutaj powinieneś przeczytać 0 jako „nie wiem”. W przeciwieństwie do zwykłych systemów plików, system plików, który jest zamontowany /proc
, zwany procfs , nie ładuje danych z dysku lub innego nośnika pamięci (takiego jak FAT, ext2, zfs,…) lub przez sieć (jak NFS, Samba,…) i nie wywołuje kodu użytkownika (w przeciwieństwie do FUSE ).
Procfs jest obecny w większości jednorożców spoza BSD. Rozpoczął swoje życie w Bell Labs AT&T w 8 edycji UNIX jako sposób na raportowanie informacji o procesach (i ps
często jest ładną drukarką do odczytu informacji /proc
). Większość implementacji procfs ma plik lub katalog wywoływany w /proc/123
celu raportowania informacji o procesie za pomocą PID 123. Linux rozszerza system plików proc o wiele więcej pozycji, które raportują stan systemu, w tym twój przykład /proc/cpuinfo
.
W przeszłości Linux /proc
uzyskiwał różne pliki, które dostarczają informacji o sterownikach, ale to użycie jest obecnie przestarzałe na korzyść /sys
i /proc
rozwija się powoli. Wpisy lubią /proc/bus
i /proc/fs/ext4
pozostają tam, gdzie są dla kompatybilności wstecznej, ale tworzone są nowsze podobne interfejsy /sys
. W tej odpowiedzi skupię się na Linuksie.
Twój pierwszy i drugi punkt wejścia do dokumentacji /proc
na temat systemu Linux to:
proc(5)
strona podręcznika ;/proc
plików w dokumentacji jądra .Twoim trzecim punktem wejścia, gdy dokumentacja go nie obejmuje, jest czytanie źródła . Możesz pobrać źródło na swój komputer, ale jest to ogromny program, a LXR , odnośnik do Linuksa, jest dużą pomocą. (Istnieje wiele wariantów LXR; ten, na którym działa, lxr.linux.no
jest zdecydowanie najładniejszy, ale niestety strona często nie działa.) Wymagana jest niewielka znajomość C, ale nie musisz być programistą, aby wyśledzić tajemniczą wartość .
Podstawowa obsługa /proc
wpisów znajduje się w fs/proc
katalogu. Każdy kierowca może zarejestrować wpisy w /proc
(choć jak wskazano powyżej, jest to obecnie nieaktualne na korzyść /sys
), więc jeśli nie znajdziesz tego, czego szukasz fs/proc
, poszukaj wszędzie. Funkcje wywoływania sterowników zadeklarowane w include/linux/proc_fs.h
. Wersje jądra do 3.9 zapewniają funkcje create_proc_entry
i niektóre opakowania (szczególnie create_proc_read_entry
), a wersje jądra 3.10 i nowsze zapewniają tylko proc_create
i proc_create_data
(i kilka innych).
Biorąc /proc/cpuinfo
jako przykład, poszukiwanie "cpuinfo"
prowadzi do połączenia się proc_create("cpuinfo, …")
w fs/proc/cpuinfo.c
. Widać, że kod jest w zasadzie kodem wzorcowym: ponieważ większość plików /proc
po prostu zrzuca niektóre dane tekstowe, istnieją do tego funkcje pomocnicze. Jest tylko seq_operations
struktura, a prawdziwe mięso znajduje się w cpuinfo_op
strukturze danych, która jest zależna od architektury, zwykle zdefiniowana w arch/<architecture>/kernel/setup.c
(lub czasem innym pliku). Biorąc za przykład x86, jesteśmy do tego doprowadzeni arch/x86/kernel/cpu/proc.c
. Tam główną funkcją jestshow_cpuinfo
, który drukuje żądaną zawartość pliku; reszta infrastruktury służy do dostarczania danych do procesu odczytu z żądaną prędkością. Możesz zobaczyć dane gromadzone w locie z danych w różnych zmiennych w jądrze, w tym kilka liczb obliczanych w locie, takich jak częstotliwość procesora .
Duża część /proc
to informacje o poszczególnych procesach w /proc/<PID>
. Wpisy te są zarejestrowane fs/proc/base.c
w tgid_base_stuff
tablicy ; niektóre zarejestrowane tutaj funkcje są zdefiniowane w innych plikach. Spójrzmy na kilka przykładów generowania tych wpisów:
cmdline
jest generowany przez proc_pid_cmdline
w tym samym pliku. Lokalizuje te dane w procesie i drukuje je.clear_refs
, w przeciwieństwie do wpisów, które widzieliśmy do tej pory, jest zapisywalny, ale nieczytelny. Dlatego proc_clear_refs_operations
struktury definiują clear_refs_write
funkcję, ale nie funkcję odczytu.cwd
jest zadeklarowanym przez proc_cwd_link
, dowiązaniem symbolicznym (nieco magicznym), który wyszukuje bieżący katalog procesu i zwraca go jako treść linku.fd
jest podkatalogiem. Operacje na samym katalogu są zdefiniowane w proc_fd_operations
strukturze danych (są one kafelkami, z wyjątkiem funkcji, która wylicza wpisy proc_readfd
, która wylicza otwarte pliki procesu), podczas gdy operacje na wpisach są w `proc_fd_inode_operations .Innym ważnym obszarem /proc
znaczy /proc/sys
, co jest bezpośrednim interfejsem sysctl
. Odczytywanie z pozycji w tej hierarchii zwraca wartość odpowiedniej wartości sysctl, a zapisywanie ustawia wartość sysctl. Punkty wejścia dla sysctl znajdują się w fs/proc/proc_sysctl.c
. Sysctls mają własny system rejestracji register_sysctl
i znajomych.
Kiedy próbujesz uzyskać wgląd w to, jaka magia dzieje się za kulisami, twoim najlepszym przyjacielem jest strace
. Nauka obsługi tego narzędzia jest jedną z najlepszych rzeczy, które możesz zrobić, aby lepiej zrozumieć, co dzieje się za kulisami szalonej magii.
$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536) = 0
close(3) = 0
...
Z powyższych danych wyjściowych widać, że /proc/cpuinfo
jest to zwykły plik, a przynajmniej wydaje się być jednym. Więc zagłębmy się głębiej.
Patrząc na sam plik, wydaje się, że jest to „tylko plik”.
$ ls -l /proc/cpuinfo
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo
Ale przyjrzyj się bliżej. Otrzymujemy naszą pierwszą wskazówkę, że jest ona specjalna, zwróć uwagę, że rozmiar pliku to 0 bajtów.
# 2 - ze stat ..Jeśli teraz spojrzymy na plik za pomocą stat
, możemy uzyskać następną wskazówkę, że jest w tym coś wyjątkowego /proc/cpuinfo
.
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
Birth: -
uruchom # 2
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
Birth: -
Zwróć uwagę na czasy dostępu, modyfikacji i zmiany? Zmieniają się przy każdym dostępie. Jest to bardzo niezwykłe, że wszystkie 3 zmieniłyby się w ten sposób. Chyba że edytowano atrybuty znacznika czasu pliku zwykle pozostają takie same.
# 3 - z plikiem ..Jeszcze jedna wskazówka, że ten plik nie jest zwykłym plikiem:
$ file /proc/cpuinfo
/proc/cpuinfo: empty
Gdyby to był jakiś przejaw nazwanego potoku, wyglądałby podobnie do jednego z tych plików:
$ ls -l /dev/initctl /dev/zero
prw-------. 1 root root 0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero
$ file /dev/initctl /dev/zero
/dev/initctl: fifo (named pipe)
/dev/zero: character special
Jeśli dotkniemy emptyfile
, /proc/cpuinfo
wygląda bardziej jak plik niż rura:
$ touch emptyfile
$ ls -l emptyfile
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile
emptyfile: empty
# 4 - z uchwytem ..
W tym momencie musimy zrobić krok do tyłu i nieco pomniejszyć. Patrzymy na konkretny plik, ale być może powinniśmy spojrzeć na system plików, w którym znajduje się ten plik. I do tego możemy użyć mount
polecenia.
$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
OK, więc typ systemu plików jest typu proc
. Więc /proc
jest inny typ systemu plików, to nasza wskazówka, że pliki poniżej /proc
są wyjątkowe. To nie tylko twoja seria plików młyna. Dowiedzmy się więc więcej o tym, co czyni proc
system plików wyjątkowym.
Spojrzenie na mount
stronę podręcznika użytkownika:
System plików proc nie jest powiązany ze specjalnym urządzeniem, a podczas montowania go można użyć dowolnego słowa kluczowego, takiego jak proc, zamiast specyfikacji urządzenia. (Zwykle wybór jest mniej szczęśliwy: komunikat o błędzie „brak zajętości” z umount może być mylący).
A jeśli spojrzymy na proc
stronę manuala:
System plików proc to pseudo-system plików używany jako interfejs do struktur danych jądra. Jest zwykle montowany w / proc. Większość z nich jest tylko do odczytu, ale niektóre pliki pozwalają na zmianę zmiennych jądra.
Nieco dalej na tej samej stronie podręcznika:
/ proc / cpuinfo
Jest to zbiór elementów zależnych od procesora i architektury systemu, dla każdej obsługiwanej architektury inna lista. Dwa wspólne wpisy to procesor, który podaje numer procesora i bogomips; stała systemowa obliczana podczas inicjalizacji jądra. Maszyny SMP mają informacje dla każdego procesora. Komenda lscpu (1) zbiera informacje z tego pliku.
U dołu strony podręcznika znajduje się odniesienie do dokumentu jądra, który można znaleźć tutaj, zatytułowanego: THE / proc FILESYSTEM . Cytowanie z tego dokumentu:
System plików proc działa jako interfejs do wewnętrznych struktur danych w jądrze. Można go użyć do uzyskania informacji o systemie i zmiany niektórych parametrów jądra w czasie wykonywania (sysctl).
Czego się tutaj nauczyliśmy? Biorąc pod uwagę, że /proc
jest to określane jako pseudo system plików, a także „interfejs do wewnętrznych struktur danych”, prawdopodobnie bezpiecznie jest założyć, że elementy w nim nie są rzeczywistymi plikami, ale raczej manifestacjami stworzonymi tak, aby wyglądały jak pliki, ale tak naprawdę nie są.
Zakończę ten cytat, który podobno był w poprzedniej wersji man 5 proc
z około 2004 roku, ale z jakiegokolwiek powodu nie jest już uwzględniony. UWAGA: Nie jestem pewien, dlaczego został usunięty, ponieważ bardzo ładnie opisuje, co /proc
to jest:
Katalog / proc w systemach GNU / Linux zapewnia interfejs podobny do systemu plików do jądra. Pozwala to aplikacjom i użytkownikom na pobieranie informacji i ustawianie wartości w jądrze przy użyciu normalnej operacji we / wy systemu plików.
System plików proc jest czasami nazywany pseudo-systemem plików informacji o procesie. Nie zawiera `` prawdziwych '' plików, ale raczej informacje o środowisku wykonawczym (np. Pamięć systemowa, podłączone urządzenia, konfiguracja sprzętu itp.). Z tego powodu może być traktowane jako centrum kontroli i informacji dla jądra. W rzeczywistości całkiem sporo narzędzi systemowych to po prostu wywołania plików w tym katalogu. Na przykład polecenie lsmod, które wyświetla moduły ładowane przez jądro, jest w zasadzie takie samo jak „cat / proc / modules”, podczas gdy lspci, który wyświetla urządzenia podłączone do szyny PCI systemu, jest taki sam jak „cat / proc / pci ”. Zmieniając pliki znajdujące się w tym katalogu, możesz zmienić parametry jądra podczas działania systemu.
Źródło: pseudo-system plików proc
strace -o catcpuproc.txt cat /proc/cpuinfo
Odpowiedź udzielona przez @slm jest bardzo wyczerpująca, ale myślę, że prostsze wyjaśnienie może pochodzić ze zmiany perspektywy.
W codziennym użytkowaniu możemy myśleć o plikach jako o rzeczach fizycznych, tj. fragmenty danych przechowywane na niektórych urządzeniach. To sprawia, że pliki takie jak / proc / cpuinfo są bardzo tajemnicze i mylące. Wszystko to jednak ma sens, jeśli myślimy o plikach jako interfejsie ; sposób wysyłania danych do i z niektórych programów.
Programy, które wysyłają i odbierają dane w ten sposób, to systemy plików lub sterowniki (w zależności od sposobu zdefiniowania tych terminów, które mogą być zbyt szerokie lub zbyt wąskie). Ważne jest to, że niektóre z tych programów używają urządzenia sprzętowego do przechowywania i pobierania danych wysyłanych przez ten interfejs; ale nie wszystko.
Niektóre przykłady systemów plików, które nie korzystają z urządzenia pamięci masowej (przynajmniej bezpośrednio):
System operacyjny Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) jest ekstremalnym przykładem użycia plików jako ogólnego interfejsu programistycznego.