Co się stanie, gdy uruchomię polecenie cat / proc / cpuinfo?

Odpowiedzi:

72

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 psczęsto jest ładną drukarką do odczytu informacji /proc). Większość implementacji procfs ma plik lub katalog wywoływany w /proc/123celu 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 /procuzyskiwał różne pliki, które dostarczają informacji o sterownikach, ale to użycie jest obecnie przestarzałe na korzyść /sysi /procrozwija się powoli. Wpisy lubią /proc/busi /proc/fs/ext4pozostają 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 /procna temat systemu Linux to:

  1. proc(5)strona podręcznika ;
  2. System /procplikó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.nojest 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 /procwpisów znajduje się w fs/prockatalogu. 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_entryi niektóre opakowania (szczególnie create_proc_read_entry), a wersje jądra 3.10 i nowsze zapewniają tylko proc_createi proc_create_data(i kilka innych).

Biorąc /proc/cpuinfojako 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 /procpo prostu zrzuca niektóre dane tekstowe, istnieją do tego funkcje pomocnicze. Jest tylko seq_operationsstruktura, a prawdziwe mięso znajduje się w cpuinfo_opstrukturze 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ęść /procto informacje o poszczególnych procesach w /proc/<PID>. Wpisy te są zarejestrowane fs/proc/base.cw tgid_base_stufftablicy ; niektóre zarejestrowane tutaj funkcje są zdefiniowane w innych plikach. Spójrzmy na kilka przykładów generowania tych wpisów:

Innym ważnym obszarem /procznaczy /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_sysctli znajomych.

Gilles
źródło
59

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/cpuinfojest to zwykły plik, a przynajmniej wydaje się być jednym. Więc zagłębmy się głębiej.

Głębsze nurkowanie

# 1 - z ls ..

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.

uruchom numer 1
$ 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/cpuinfowyglą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ć mountpolecenia.

$ 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 /procjest inny typ systemu plików, to nasza wskazówka, że ​​pliki poniżej /procsą wyjątkowe. To nie tylko twoja seria plików młyna. Dowiedzmy się więc więcej o tym, co czyni procsystem plików wyjątkowym.

Spojrzenie na mountstronę 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 procstronę 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).

Wnioski

Czego się tutaj nauczyliśmy? Biorąc pod uwagę, że /procjest 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 procz 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 /procto 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

Bibliografia

slm
źródło
1
Fajnie :) to pierwsza rzecz, którą spróbowałem, gdy zobaczyłem pytanie:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
Niezła odpowiedź! W Linuksie, jeśli chcesz kopać głębiej, źródłem systemu plików proc jest fs / proc w źródle jądra. Zobaczysz, że istnieje plik fs / proc / cpuinfo.c, ale niestety jest raczej pusty, ponieważ ciężkie podnoszenie jest rozłożone na całym łuku /, ponieważ jest zależne od architektury. Dla prostszego przykładu zobacz fs / proc / uptime.c. Spoglądając na plik, możemy domyślić się, że uptime_proc_show to koń roboczy, który dostaje nam potrzebne dane, i moglibyśmy go zbadać bardziej szczegółowo, wywołując funkcje, które wywołuje. Aby zrozumieć interfejs pliku seq_file i sposób jego użycia w procfs, zobacz:
Steven D
1
linux.com/learn/linux-training/... and lwn.net/Articles/22355 (nieco przestarzały)
Steven D
1
@slm: +1, świetna odpowiedź. Ale dla mnie pierwszą wskazówką, że jest to specjalny plik, jest rozmiar ^ ^ 0 bajtów, ale można z niego wyłapać wiele rzeczy (trochę jak niektóre pliki potoków).
Olivier Dulac
@OlivierDulac - dobry punkt. Wprowadziłem dodatkowe zmiany na podstawie Twojej opinii. LMK, jeśli mogę dokonać dalszych ulepszeń. Dzięki.
slm
14

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):

  • Systemy plików wykorzystujące dane przeglądane lub obliczone. Proc jest przykładem, ponieważ pobiera dane z różnych modułów jądra. Skrajnym przykładem jest πfs (github.com/philipl/pifs)
  • Wszystkie systemy plików FUSE, które obsługują dane za pomocą zwykłego programu przestrzeni użytkownika
  • Systemy plików, które przekształcają dane innego systemu plików w locie, na przykład za pomocą szyfrowania, kompresji, a nawet transkodowania dźwięku (khenriks.github.io/mp3fs/)

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.

Warbo
źródło