Pytania rekrutacyjne: procesy, start systemu, dyski
Po tej lekcji: kursant odpowiada na głos na dwanaście pytań o procesy, sygnały, obciążenie, pamięć, start systemu i dyski, i przy każdym umie pokazać komendę, którą by to sprawdził.
Wstęp
„Co to jest proces zombie i jak go zabić?”
To pytanie pada tak często, że powinno mieć własny numer PID. I ma pułapkę w drugiej części. Bo prawidłowa odpowiedź na „jak go zabić” brzmi: nie da się. I to jest dokładnie ten moment, w którym rekruter sprawdza, czy rozumiesz, czy tylko pamiętasz.
Dziś procesy, start systemu i dyski. Ta sama formuła co ostatnio: definicja, obraz, komenda, kiedy to ma znaczenie w pracy. Maksymalnie minuta.
Pytanie 1: „Czym się różni proces od wątku?”
Odpowiedź na głos: Proces to uruchomiony program z własną pamięcią, własnymi otwartymi plikami i własnym numerem PID. Wątek to kolejny wykonawca w środku tego samego procesu: dzieli z innymi wątkami pamięć i pliki, ma tylko własny stos i własne miejsce w kolejce do procesora. Jak kuchnia: proces to cała kuchnia z lodówką, a wątki to kucharze w tej jednej kuchni. Dwa procesy to dwie osobne kuchnie. Dlatego wątki tworzy się taniej i szybciej się komunikują, ale jeden pijany kucharz potrafi zepsuć obiad całej kuchni.
ps -o pid,nlwp,comm -p 1
ps -L -o pid,lwp,comm -p <PID> PID NLWP COMMAND
2463 4 python3
PID LWP COMMAND
2463 2463 python3
2463 2464 python3
2463 2465 python3
2463 2466 python3Jeden proces Pythona, cztery wątki. NLWP to liczba wątków.
Czego rekruter naprawdę szuka: słowa „wspólna pamięć”.
Zła odpowiedź: „Wątek to mały proces.” Trochę tak, jak pokój to mały dom.
Pytanie 2: „Co to jest proces zombie, a co sierota? Jak zabić zombie?”
Odpowiedź na głos: Zombie to proces, który już się zakończył, ale jego rodzic jeszcze nie odebrał kodu wyjścia przez wait(). Nie zużywa procesora ani pamięci, zostaje tylko wpis w tabeli procesów. Jak rachunek gościa, który wyszedł, a kelner jeszcze go nie zamknął. Zombie nie da się zabić, bo on już nie żyje. Trzeba szturchnąć rodzica, żeby odebrał wynik, a jeśli rodzic jest zepsuty, zatrzymać rodzica. Wtedy zombie przechodzi pod PID 1, a ten sprząta. Sierota to odwrotność: dziecko żyje, a rodzic umarł. Sierotę adoptuje PID 1 i to nie jest żadna awaria.
bash -c 'sleep 1 & exec sleep 20' &
ps -o pid,ppid,stat,cmd --ppid <PID_RODZICA> -p <PID_RODZICA>
kill -9 <PID_ZOMBIE> PID PPID STAT CMD
1264 1263 SN sleep 20
1266 1264 ZN [sleep] <defunct>Rodzic sleep 20 nie umie czekać na dzieci, więc dziecko po sekundzie zostaje zombie: litera Z i napis <defunct>. kill -9 na nie? Nic. Zombie dalej stoi. Zabijam rodzica i zombie znika.
A sierota:
dziecko: 1278, rodzic: 1277
PID PPID STAT CMD
1278 1 S sleep 25Rodzic się skończył, a PPID dziecka zmienił się na 1. Adopcja w trybie natychmiastowym.
Czego rekruter naprawdę szuka: „zombie nie da się zabić, trzeba zająć się rodzicem” i tego, że jeden zombie nie jest problemem. Problemem są tysiące, bo kończą się numery PID.
Zła odpowiedź: „kill -9 na zombie.” Strzelanie do ducha. Nawet amunicja się nie zużywa.
Pytanie 3: „Czym się różni kill -15 od kill -9? A co, jeśli -9 nie działa?”
Odpowiedź na głos: kill -15 to SIGTERM, grzeczna prośba o zamknięcie lokalu. Program może ją złapać, zapisać dane, zamknąć połączenia z bazą, posprzątać pliki tymczasowe. To jest domyślny sygnał komendy kill. kill -9 to SIGKILL, wyłączenie prądu. Programu nikt nie pyta, jądro go po prostu usuwa. Nie da się go złapać ani zignorować. Dlatego najpierw zawsze 15, odczekać, a 9 dopiero na końcu. Jeśli nawet 9 nie działa, to proces jest zombie albo wisi w stanie D, czyli czeka na dysk albo sieciowy system plików wewnątrz jądra. Sygnał dotrze, kiedy operacja się skończy. Wtedy szukam zepsutego dysku albo NFS-a, a nie mocniejszego sygnału.
Skrypt „lokal”, który sprząta przy SIGTERM:
#!/bin/bash
trap 'echo "SIGTERM: zamykam kasę, zapisuję stan"; exit 0' TERM
echo "Lokal otwarty, PID $$"
while true; do sleep 1; doneLokal otwarty, PID 1297
SIGTERM: zamykam kasę, zapisuję stan
kod: 0
Lokal otwarty, PID 1300
bash: line 3: 1300 Killed ./e107/lokal.sh
kod: 137Po -15 skrypt posprzątał i wyszedł z kodem 0. Po -9 nie zdążył powiedzieć ani słowa, a kod to 137, czyli 128 plus numer sygnału 9.
Czego rekruter naprawdę szuka: kolejności „najpierw 15, potem 9” i stanu D. To drugie odróżnia juniora, który czytał, od juniora, który coś widział.
Zła odpowiedź: „Zawsze używam -9, bo jest pewniejsze.” Pewniejsze jest też wyrywanie wtyczki z serwera bazy danych. Do czasu.
Pytanie 4: „Co mierzy load average? Load 4 to dużo?”
Odpowiedź na głos: Load average to trzy liczby: średnia liczba procesów, które w ostatniej minucie, pięciu i piętnastu minutach chciały pracować. Na Linuksie liczą się procesy w stanie R, czyli gotowe do biegu albo biegnące, i w stanie D, czyli czekające na dysk. To jak kolejka do kas w Biedronce. Czy 4 to dużo? Zależy od liczby kas. Na czterech rdzeniach to pełne obłożenie bez kolejki, na jednym rdzeniu to trzy osoby czekające za każdym, kto płaci. Zawsze porównuję z nproc. A jeśli load jest wysoki, a procesor się nudzi, winny jest zwykle dysk albo sieciowy system plików, czyli procesy w D.
uptime
cat /proc/loadavg
nproc
ps -eo stat | cut -c1 | sort | uniq -c 22:38:39 up 6:20, 0 user, load average: 0.63, 0.57, 0.37
0.63 0.57 0.37 2/131 1306
2
39 I
1 R
54 SDwa rdzenie, load 0,63. Sklep pusty, kasjerki grają w kółko i krzyżyk. Trzy liczby czytaj od lewej: ostatnia minuta wyższa niż piętnaście minut znaczy „robi się coraz tłoczniej”.
Czego rekruter naprawdę szuka: „porównuję z liczbą rdzeni” i „na Linuksie liczy się też stan D”. To drugie wyjaśnia klasyczną zagadkę: load 30, a procesor w 70 procentach bezczynny.
Zła odpowiedź: „Load average to procent użycia procesora.” Nie, to nie procent. Load 3 nie znaczy trzech procent, choć bardzo by chciał.
Pytanie 5: „Co to jest OOM killer i jak poznasz, że zadziałał?”
Odpowiedź na głos: OOM to „out of memory”. Kiedy jądru kończy się pamięć i nie ma już czego oddać, nawet ze swapu i z cache, uruchamia OOM killera. Ten wybiera jeden proces i go zabija sygnałem 9, żeby uratować resztę. Wybiera według punktacji, która rośnie z ilością zajmowanej pamięci, a admin może ją przesunąć przez oom_score_adj w zakresie od minus tysiąca, czyli „nigdy mnie nie zabijaj”, do plus tysiąca. Poznam po wpisie w logu jądra „Out of memory: Killed process” i po tym, że usługa zniknęła bez żadnego błędu w swoim własnym logu. Potem szukam przyczyny: wyciek pamięci, za mało RAM-u, za duży limit w konfiguracji.
Pokaz bezpieczny: proces w wydzielonej grupie z limitem 50 MB próbuje zająć 200 MB. Zginie tylko on.
python3 -c 'x = bytearray(200*1024*1024); print("przeżyłem")'
echo "kod wyjścia: $?"
sudo dmesg | grep -i "out of memory" | tail -1kod wyjścia: 137
[22824.301090] Memory cgroup out of memory: Killed process 1251 (python3) total-vm:245936kB, anon-rss:50944kB, file-rss:8032kB, shmem-rss:0kB, UID:0 pgtables:196kB oom_score_adj:0„przeżyłem” się nie wypisało. Kod 137, znowu sygnał 9. Na prawdziwym serwerze to samo znajdziesz przez journalctl -k | grep -i oom.
cat /proc/<PID>/oom_score
cat /proc/<PID>/oom_score_adjCzego rekruter naprawdę szuka: gdzie szukać śladu (dmesg, journalctl -k) i że OOM to objaw, a nie przyczyna.
Zła odpowiedź: „OOM killer to wirus.” Nie. To bramkarz, który wyrzuca najgrubszego gościa, żeby klub się nie zawalił.
Pytanie 6: „Co to jest swap? Czy serwer go potrzebuje?”
Odpowiedź na głos: Swap to miejsce na dysku, na które jądro wyrzuca rzadko używane strony pamięci, kiedy RAM-u brakuje. Jak magazyn za sklepem: towar, który się nie sprzedaje, leży z tyłu, a na półkach jest miejsce na to, co schodzi. Swap ratuje przed OOM killerem przy chwilowym skoku, ale jest dużo wolniejszy od RAM-u. Jeśli system ciągle przerzuca strony tam i z powrotem, wszystko staje się powolne. To się nazywa thrashing. Mały swap na serwerze zwykle się przydaje, ale ciągłe, intensywne swapowanie znaczy, że trzeba dołożyć pamięci albo znaleźć program, który ją zjada. Skłonność do swapowania reguluje vm.swappiness, domyślnie 60.
free -h
swapon --show
cat /proc/sys/vm/swappiness
vmstat 1 5 total used free shared buff/cache available
Mem: 7.8Gi 1.0Gi 4.6Gi 15Mi 2.6Gi 6.9Gi
Swap: 0B 0B 0B
60U mnie swapu brak, a swapon --show milczy. W vmstat patrz na kolumny si i so: ile na sekundę wjeżdża ze swapu i wyjeżdża do niego. Kilka liczb od czasu do czasu to nic. Ciągle duże to thrashing.
Czego rekruter naprawdę szuka: że zajęty swap to nie to samo co aktywne swapowanie. Swap zajęty w 30 procentach przy si/so równych zero to spokojny magazyn, nie pożar.
Zła odpowiedź: „Swap to zło, zawsze wyłączam.” A potem pierwszy skok ruchu i OOM killer zabiera bazę danych na spacer.
Pytanie 7: „Opowiedz, jak startuje Linux, od przycisku do ekranu logowania.”
Odpowiedź na głos: Pięć etapów. Raz: firmware, czyli BIOS albo UEFI, sprawdza sprzęt i szuka programu rozruchowego. Dwa: program rozruchowy, najczęściej GRUB, pokazuje menu i ładuje do pamięci jądro oraz initramfs. Trzy: jądro startuje, rozpakowuje initramfs, czyli mały tymczasowy system w pamięci ze sterownikami potrzebnymi, żeby znaleźć prawdziwy dysk główny. Cztery: jądro montuje główny system plików i uruchamia pierwszy proces, PID 1, dziś prawie zawsze systemd. Pięć: systemd montuje resztę dysków z fstab, odpala usługi według zależności i dochodzi do celu, na serwerze multi-user.target, i pojawia się logowanie.
Na maszynie wirtualnej z systemd:
systemd-analyze
systemd-analyze blame | head
systemctl get-default
journalctl -b -p errsystemd-analyze mówi, ile trwał każdy etap, a blame wskazuje usługę, która startuje najdłużej. journalctl -b -p err pokazuje błędy z bieżącego startu.
Czego rekruter naprawdę szuka: kolejności i słowa „initramfs”. Bonus: gdzie byś szukał, gdy start się wysypuje. Odpowiedź: journalctl -b -1 pokazuje logi z poprzedniego startu, jeśli dziennik jest trwały.
Zła odpowiedź: „Naciskam przycisk i się włącza.” Zgadza się. Tylko że to rozmowa na admina, a nie na użytkownika.
Pytanie 8: „Czym się różni init od systemd?”
Odpowiedź na głos: Oba są pierwszym procesem, kierownikiem zmiany, który uruchamia resztę. Klasyczny SysV init odpalał po kolei skrypty powłoki z folderów przypisanych do poziomów pracy, czyli runleveli: 3 to tryb wieloużytkownikowy z siecią, 5 z grafiką. Wolno i bez śledzenia, co się dalej dzieje z usługą. systemd opisuje usługi w plikach jednostek, zna zależności między nimi, startuje je równolegle, pilnuje ich przez cgroups, restartuje po awarii i zbiera logi w dzienniku journald. Zamiast runleveli ma cele, czyli targety. Dziś RHEL, Ubuntu i Debian domyślnie używają systemd.
ps -p 1 -o comm=
ls -l /usr/lib/systemd/system/runlevel3.target/usr/lib/systemd/system/runlevel3.target -> multi-user.targetStare nazwy runleveli zostały jako drogowskazy: runlevel3.target to multi-user.target, runlevel5.target to graphical.target, runlevel1.target to rescue.target.
Czego rekruter naprawdę szuka: „równolegle, zależności, pilnowanie usług, dziennik” i mapowania runlevel na target.
Zła odpowiedź: długi wywód o tym, że systemd jest zły, bo jest za duży. Możesz mieć zdanie, ale na rozmowie najpierw pokaż, że umiesz go używać. Flame war zostaw na forum.
Pytanie 9: „Usługa nie wstaje. Co robisz?”
Odpowiedź na głos: Najpierw systemctl status nazwa, bo pokazuje stan, kod wyjścia i ostatnie linijki logu. Potem pełny log: journalctl -u nazwa -b albo -e, żeby skoczyć na koniec. Jeśli zmieniałem konfigurację, sprawdzam ją narzędziem programu, na przykład nginx -t, apachectl configtest, sshd -t. Patrzę też, czy port nie jest zajęty, czy są uprawnienia do plików i, na RHEL, czy nie blokuje SELinux. Po poprawce systemctl restart, a jeśli zmieniałem sam plik jednostki, najpierw systemctl daemon-reload.
systemctl status nginx
journalctl -u nginx -b --no-pager | tail -30
sudo nginx -t
systemctl --failedCzego rekruter naprawdę szuka: że zaczynasz od czytania, a nie od restartowania w kółko. I daemon-reload, o którym połowa kandydatów zapomina.
Zła odpowiedź: „Restartuję serwer.” Gratulacje, teraz nie działa ta sama usługa, tylko po dwóch minutach przerwy.
Pytanie 10: „Co jest w /etc/fstab? Co się stanie, jak zrobisz w nim literówkę?”
Odpowiedź na głos: fstab to lista dysków do zamontowania przy starcie. Każda linijka ma sześć pól: co montować, najlepiej przez UUID, gdzie, jaki system plików, opcje, pole dla starego programu dump, zwykle 0, i kolejność sprawdzania przez fsck: 1 dla dysku głównego, 2 dla reszty, 0 żeby nie sprawdzać. Literówka może skończyć się tym, że system nie wstanie i wyląduje w trybie awaryjnym, bo w systemd nieudane zamontowanie lokalnego dysku wywraca cel local-fs.target. Dlatego po każdej zmianie robię findmnt --verify i mount -a, a dyski, bez których system ma wstać, oznaczam nofail.
findmnt --verify --tab-file fstab.zly
sudo mount -a -T fstab.zly [W] etx4 seems unsupported by the current kernel
[W] etx4 does not match with on-disk ext4
mount: /home/eryk/mnt: unknown filesystem type 'etx4'.A teraz podchwytliwa część: druga wersja pliku miała literówkę w opcjach, defualts zamiast defaults. findmnt --verify jej nie zauważył, bo opcji nie sprawdza. Wyszło dopiero przy mount -a:
mount: /home/eryk/mnt: wrong fs type, bad option, bad superblock on /dev/loop1, missing codepage or helper program, or other error.Dlatego robię obie komendy, a nie jedną. [Pamiętaj: zmiany w prawdziwym /etc/fstab testuj na maszynie wirtualnej i z otwartą konsolą, nie tylko z SSH.]
Czego rekruter naprawdę szuka: UUID zamiast /dev/sdb1 (nazwy dysków potrafią się zamienić po restarcie), mount -a przed restartem i nofail.
Zła odpowiedź: „Dopisuję linijkę i restartuję, żeby sprawdzić.” Odważnie. Szczególnie o trzeciej w nocy na serwerze w innym mieście.
Pytanie 11: „Co to jest LVM i po co go używać?”
Odpowiedź na głos: LVM to warstwa między dyskami a systemem plików. Dyski albo partycje zamieniam w fizyczne woluminy, PV, wrzucam je do wspólnej puli, czyli grupy woluminów, VG, a z puli wycinam woluminy logiczne, LV, na których zakładam system plików. Jak regały na kółkach: nie są przykręcone do ściany, mogę je przesuwać i dostawiać. Korzyści: powiększam wolumin bez wyłączania serwera, dokładam nowy dysk do puli, robię migawki przed ryzykowną zmianą. Typowa operacja to lvextend -r, które powiększa wolumin i od razu system plików.
sudo pvcreate /dev/loop2
sudo vgcreate vg_dane /dev/loop2
sudo vgs vg_dane Physical volume "/dev/loop2" successfully created.
Volume group "vg_dane" successfully created
VG #PV #LV #SN Attr VSize VFree
vg_dane 1 0 0 wz--n- 296.00m 296.00mDalej, na maszynie wirtualnej:
sudo lvcreate -n dane -L 100M vg_dane
sudo mkfs.ext4 /dev/vg_dane/dane
sudo lvextend -r -L +50M /dev/vg_dane/daneCzego rekruter naprawdę szuka: PV, VG, LV w dobrej kolejności, -r przy lvextend i to, że LVM to nie backup. Migawka leży na tych samych dyskach.
Zła odpowiedź: „LVM to taki RAID.” Nie. RAID chroni przed awarią dysku, LVM daje elastyczność. Można mieć jedno, drugie albo oba.
Pytanie 12: „df pokazuje pełny dysk, a du nie może się doliczyć. Co się dzieje?”
Odpowiedź na głos: df pyta system plików, ile bloków jest zajętych. du chodzi po folderach i sumuje pliki, które widzi. Najczęstsza przyczyna rozjazdu: ktoś usunął duży plik, na przykład log, ale proces dalej trzyma go otwartego. Nazwa zniknęła, więc du go nie widzi, ale dane zostają na dysku, dopóki proces nie zamknie pliku. Szukam przez lsof +L1, czyli otwarte pliki z liczbą linków zero. Naprawa: restart albo przeładowanie procesu, a jeśli nie można, wyzerowanie pliku przez /proc/PID/fd/numer. Druga, rzadsza przyczyna: pliki schowane pod punktem montowania.
dd if=/dev/zero of=mnt/wielki.log bs=1M count=10 status=none
sleep 120 < mnt/wielki.log &
rm mnt/wielki.log
df -h mnt; du -sh mnt
sudo lsof +L1
: > /proc/<PID>/fd/0
df -h mnt== df
/dev/loop1 16M 11M 4.6M 69% /home/eryk/mnt
== du
20K mnt
== lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
sleep 1707 root 0r REG 7,1 10485760 0 12 /home/eryk/mnt/wielki.log (deleted)
== df po wyzerowaniu
/dev/loop1 16M 24K 15M 1% /home/eryk/mntdf: 11 MB zajęte. du: 20 KB. lsof pokazuje winowajcę z dopiskiem (deleted) i NLINK równym 0. To jest ten licznik linków z lekcji 106. Po wyzerowaniu miejsce wraca bez zabijania procesu.
Czego rekruter naprawdę szuka: lsof +L1 albo lsof | grep deleted i lekcji na przyszłość: logów się nie usuwa przy działającym programie, tylko się je zeruje albo rotuje przez logrotate.
Zła odpowiedź: „du się pomylił.” Narzędzia rzadko się mylą. Częściej się mylimy co do tego, co mierzą.
Jak to działa pod spodem
Wszystkie dzisiejsze pytania kręcą się wokół jądra, które jest kierownikiem całej restauracji.
- Każdy proces ma wpis w tabeli procesów: numer, rodzica, stan. Stany, które musisz znać:
Rbiegnie albo czeka na procesor,Sśpi i czeka na coś, co można przerwać,Dczeka w jądrze, zwykle na dysk, i nie da się go przerwać,Tzatrzymany,Zzombie. - Proces kończy się, jądro zostawia jego kod wyjścia w tabeli i wysyła rodzicowi sygnał SIGCHLD. Dopiero
wait()rodzica usuwa wpis. Między jednym a drugim mamy zombie. - Sygnały to kartki podawane procesom. Większość program może przechwycić. SIGKILL i SIGSTOP obsługuje samo jądro, programu nikt nie pyta.
- Pamięć jądro rozdaje z zapasem, bo programy rzadko zużywają wszystko, o co poprosiły. Kiedy wszyscy naraz przyjdą odebrać zamówienie, a magazyn i swap są puste, wkracza OOM killer.
- Plik jest usuwany z dysku dopiero wtedy, gdy licznik nazw spadnie do zera i ostatni proces go zamknie. Stąd
dfkontradu.
A przy starcie systemu wszystko zaczyna się od jednego procesu z numerem 1. Jeśli on zginie, jądro panikuje. Dlatego kierownik zmiany ma w umowie, że nie może wyjść na papierosa.
Ściąga flag
| Komenda | Flaga | Co robi |
|---|---|---|
ps | -o pid,ppid,stat,cmd | wybrane kolumny, w tym rodzic i stan |
ps | -L | pokazuje wątki |
kill | -15 / -9 / -l | SIGTERM / SIGKILL / lista sygnałów |
uptime | — | czas pracy i load average |
nproc | — | liczba rdzeni |
free | -h | pamięć i swap po ludzku |
swapon | --show | aktywne obszary swap |
vmstat | 1 5 | co sekundę, pięć razy; kolumny si/so |
dmesg | -T | log jądra z ludzkimi datami |
journalctl | -k / -b / -b -1 / -u usługa | jądro / ten start / poprzedni start / jedna usługa |
systemctl | status / --failed / daemon-reload | stan / co padło / przeładowanie plików jednostek |
systemd-analyze | blame | co najdłużej startowało |
findmnt | --verify | sprawdza fstab |
mount | -a | montuje wszystko z fstab |
lvextend | -r -L +5G | powiększa wolumin i system plików |
lsof | +L1 | otwarte pliki, które już usunięto |
du | -sh / -x | suma po ludzku / bez innych systemów plików |
⚠ Typowy błąd
Kandydat słyszy „serwer ma load 12” i od razu mówi „trzeba dołożyć procesorów”.
A serwer ma 16 rdzeni, czyli load 12 to przyjemny, pracowity dzień. Albo ma 4 rdzenie, ale procesor jest w 90 procentach bezczynny, bo 12 procesów stoi w stanie D i czeka na dysk sieciowy, który właśnie umarł. Dołożenie procesorów pomoże tu tak, jak dołożenie kas w sklepie, w którym zepsuła się winda z towarem.
Naprawa: zanim coś zaproponujesz, zadaj jedno pytanie. „Ile rdzeni ma ten serwer i co pokazuje top w linijce z wa?” Rekruterzy uwielbiają kandydatów, którzy dopytują. To znaczy, że w pracy też nie będą zgadywać.
✎ Zadanie
- Odpowiedz na głos na pytania 2, 3 i 12. Każde maksymalnie 60 sekund.
- Na maszynie wirtualnej zrób w swoim folderze plik 100 MB (
dd), otwórz go procesem w tle (sleep 600 < plik &), usuń plik i pokaż, żedfidusię nie zgadzają. Znajdź winowajcę przezlsof +L1i odzyskaj miejsce bez zabijania procesu. - Sprawdź load average i liczbę rdzeni swojej maszyny i powiedz jednym zdaniem, czy jest tłoczno.
Pokaż rozwiązanie
Punkt pierwszy, czyli zombie, sygnały i df kontra du na głos, oceniasz sam. Jeśli przy zombie powiedziałeś „nie da się go zabić, trzeba zająć się rodzicem”, to masz najważniejsze zdanie.
Punkt drugi. Zrobiłem to na osobnym, świeżym systemie plików 200 MB, żeby różnica była widoczna gołym okiem:
dd if=/dev/zero of=plik bs=1M count=100 status=none
sleep 600 < plik &
P=$!
rm plik
df -h .
du -sh .
sudo lsof +L1
: > /proc/$P/fd/0
df -h ./dev/loop2 172M 101M 58M 64% /home/eryk/zad
20K .
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
sleep 17114 root 0r REG 7,2 104857600 0 12 /home/eryk/zad/plik (deleted)
/dev/loop2 172M 24K 158M 1% /home/eryk/zaddf mówi 101 MB, du mówi 20 KB, lsof +L1 pokazuje sleep z plikiem (deleted). Wyzerowanie przez /proc oddaje miejsce, a proces dalej żyje i nawet nie zauważył, że mu wyczyszczono talerz.
Punkt trzeci: uptime i nproc. Jeśli load jest mniejszy od liczby rdzeni, w sklepie luźno. Jeśli większy, ktoś stoi w kolejce, a Ty już wiesz, że to może być kolejka do dysku, nie do procesora.
Co dalej
W następnej lekcji pytania o sieć i bezpieczeństwo: jak działa DNS, TCP kontra UDP, który proces słucha na porcie, zapora, SSH, które „dalej pyta o hasło”, utwardzanie serwera, SELinux kontra AppArmor i ulimit.