Eemol, an engem Interview, gouf ech gefrot wat géift Dir maachen wann Dir e futtis Service fannt wéinst der Tatsaach datt d'Plaz aus dem Disk leeft?
Natierlech hunn ech geäntwert datt ech géif kucken wat dës Plaz mécht a wa méiglech d'Plaz botzen.
Dunn huet den Interviewer gefrot, wat wann et kee fräie Raum op der Partition ass, awer Dir gesitt och net d'Fichier'en déi all Plaz ophuelen?
Zu dësem hunn ech gesot datt Dir ëmmer op oppene Dateideskriptoren kuckt, zum Beispill mam lsof Kommando a verstitt wéi eng Applikatioun all verfügbare Raum geholl huet, an da kënnt Dir no den Ëmstänn handelen, ofhängeg ob d'Donnéeën gebraucht ginn .
Den Interviewer huet mech um leschte Wuert ënnerbrach, a seng Fro bäigefüügt: "Ugeholl datt mir d'Donnéeën net brauchen, et ass just en Debug-Logbuch, awer d'Applikatioun ass erof well et den Debug net kann schreiwen"?
"Ok," hunn ech geäntwert, "mir kënnen Debugging an der Applikatiounskonfiguratioun ausschalten an et nei starten."
Den Interviewer huet dogéint: "Nee, mir kënnen d'Applikatioun net nei starten, mir hunn nach ëmmer wichteg Donnéeën an der Erënnerung, a wichteg Clientë si mam Service selwer verbonnen, wat mir net forcéiere kënnen nei ze konnektéieren."
"Ok," sot ech, "wa mir d'Applikatioun net kënnen nei starten a mir egal vun den Donnéeën, da kënne mir dës oppe Datei einfach iwwer de Dateidescriptor läschen, och wa mir se net an der ls gesinn Kommando am Dateiesystem."
Den Interviewer war zefridden, awer ech war net.
Dunn hunn ech geduecht, firwat gräift déi Persoun déi mäi Wëssen ausprobéiert net méi déif? Awer wat wann d'Donnéeën iwwerhaapt wichteg sinn? Wat wa mir de Prozess net kënnen nei starten, a gläichzäiteg schreift dëse Prozess an de Dateiesystem op enger Partition déi kee fräie Raum huet? Wat wa mir net nëmmen d'Donnéeën déi scho geschriwwe sinn, awer och d'Donnéeën verléieren, déi dëse Prozess schreift oder probéiert ze schreiwen?
Tuzik
Am Ufank vu menger Carrière hunn ech probéiert eng kleng Applikatioun ze kreéieren déi Informatioun iwwer d'Benotzer muss späicheren. An dunn hunn ech geduecht, wéi kann ech dem Benotzer seng Donnéeë passen. Zum Beispill, Ech hunn Ivanov Ivan Ivanovich, an hien huet e puer Donnéeën, mä wéi Frënn mat hinnen ze maachen? Ech kann direkt drop hiweisen datt den Hond mam Numm "Tuzik" dem selwechten Ivan gehéiert. Awer wat wann hien säin Numm ännert an amplaz vum Ivan gëtt, zum Beispill, Olya? Da wäert et erausstellen datt eis Olya Ivanovna Ivanova keen Hond méi wäert hunn, an eis Tuzik wäert nach ëmmer dem net existéierenden Ivan gehéieren. D'Datebank huet gehollef dëse Problem ze léisen, deen all Benotzer en eenzegaartegen Identifizéierer (ID) ginn huet, a meng Tuzik war un dës ID gebonnen, déi tatsächlech just eng Seriennummer war. Sou war de Besëtzer vun der tuzik mat ID Nummer 2, an iergendwann war Ivan ënner dëser ID, an dann Olya gouf ënner der selwechter ID. De Problem vun der Mënschheet an der Déierewirtschaft gouf praktesch geléist.
Datei Beschreiwung
De Problem vun engem Dossier an engem Programm, dee mat dësem Fichier funktionnéiert, ass ongeféier d'selwecht wéi eisen Hond a Mënsch. Ugeholl datt ech e Fichier mam Numm ivan.txt opgemaach hunn an ugefaang d'Wuert tuzik an et ze schreiwen, awer et fäerdeg bruecht nëmmen den éischte Bréif "t" an d'Datei ze schreiwen, an dës Datei gouf vun engem ëmbenannt, zum Beispill op olya.txt. Mä de Fichier ass déi selwecht an ech wëll nach meng Ace ze schreiwen. All Kéier wann Dir eng Datei mat engem Systemruff opmaacht
Op Linux mécht d'libc-Bibliothéik 3 Deskriptordateien fir all lafend Applikatioun (Prozess) op, mat Zuelen 0,1,2. Méi Informatioun fannt Dir op de Linken
- Datei Descriptor 0 gëtt STDIN genannt an ass mat der Uwendungsinput assoziéiert.
- Dateibeschreiwung 1 gëtt STDOUT genannt a gëtt vun Ausgangsapplikatiounen wéi Dréckbefehle benotzt.
- Datei Descriptor 2 gëtt STDERR genannt a gëtt vun Uwendungen benotzt fir Fehlermeldungen auszeginn.
Wann Dir an Ärem Programm all Datei opmaacht fir ze liesen oder ze schreiwen, da kritt Dir héchstwahrscheinlech déi éischt gratis ID an et wäert d'Nummer 3 sinn.
Dir kënnt d'Lëscht vun Dateideskriptoren fir all Prozess gesinn wann Dir seng PID kennt.
Zum Beispill, loosst eis eng Konsole mat Bash opmaachen an de PID vun eisem Prozess gesinn
[user@localhost ]$ echo $$
15771
An der zweeter Konsole lafen
[user@localhost ]$ ls -lah /proc/15771/fd/
total 0
dr-x------ 2 user user 0 Oct 7 15:42 .
dr-xr-xr-x 9 user user 0 Oct 7 15:42 ..
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
Dir kënnt sécher de Fichier Descriptor mat Nummer 255 am Kader vun dësem Artikel ignoréieren, et gouf fir Är Bedierfnesser vum Bash selwer opgemaach, an net vun der verlinkter Bibliothéik.
Elo sinn all 3 Deskriptordateien mat dem Pseudo-Terminalapparat assoziéiert
[user@localhost ]$ echo "hello world" > /proc/15771/fd/0
An an der éischter Konsole wäerte mir gesinn
[user@localhost ]$ hello world
Redirect a Pipe
Dir kënnt dës 3 Deskriptordateien einfach an all Prozess iwwerschreiden, och am Bash, zum Beispill, duerch e Päif (Päif) déi zwee Prozesser verbënnt, kuckt
[user@localhost ]$ cat /dev/zero | sleep 10000
Dir kënnt dëst Kommando selwer lafen mat streck -f a kucke wat dobannen lass ass, mee ech maachen et kuerz.
Eis Elterebash-Prozess mat PID 15771 parséiert eise Kommando a versteet genau wéi vill Kommandoe mir wëllen ausféieren, an eisem Fall sinn et zwee vun hinnen: Kaz a Schlof. Bash weess datt et muss zwee Kannerprozesser erstellen an se an eng Päif fusionéieren. Am Ganzen brauch Bash 2 Kannerprozesser an eng Päif.
Ier Dir Kannerprozesser erstellt, leeft bash e Systemruff
Fir den Elterenprozess gesäit et aus wéi wann d'Päif schonn do ass, awer et gi nach keng Kannerprozesser:
PID command
15771 bash
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
Da benotzt de System Uruff
PID command
15771 bash
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
PID command
9004 bash
lrwx------ 1 user user 64 Oct 7 15:57 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 255 -> /dev/pts/21
PID command
9005 bash
lrwx------ 1 user user 64 Oct 7 15:57 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 255 -> /dev/pts/21
Vergiesst net datt Klonen de Prozess zesumme mat all Dateideskriptoren klonen, sou datt se d'selwecht sinn am Elterenprozess an an de Kanner. D'Aufgab vum Elterendeel mam PID 15771 ass d'Kandprozesser ze iwwerwaachen, also waart et just op eng Äntwert vun de Kanner.
Dofir brauch hien net e Päif, an hie mécht d'Dateibeschreiwunge mat den Zuelen 3 a 4 zou.
Am éischte Bash Kand Prozess mat PID 9004, de System Opruff
Am zweete Kand Prozess mat PID 9005, bash dup2s der Datei ze STDIN Descriptor Nummer 0. Elo alles wat eis zweet Bash mat PID 9005 liesen wäert aus der Päif liesen.
Duerno ginn och Dateidescriptoren mat den Zuelen 3 a 4 a Kannerprozesser zougemaach, well se net méi benotzt ginn.
Ech ignoréieren bewosst Fichier Descriptor 255, et gëtt intern vun Bash selwer benotzt a wäert och an Kand Prozesser zougemaach ginn.
Als nächst, am éischte Kand Prozess mat PID 9004, fänkt bash mat engem System Opruff
Am zweete Kannerprozess mat PID 9005 leeft bash den zweeten Ausführbar, dee mir spezifizéiert hunn, an eisem Fall /usr/bin/sleep.
Den Exec System Uruff schléisst keng Dateideskriptoren zou, ausser se goufen mam O_CLOEXEC Fändel opgemaach an der Zäit wou den oppene Ruff ausgefouert gouf. An eisem Fall, nodeems Dir déi ausführbar Dateien ausgeführt hutt, ginn all aktuell Dateideskriptoren gespäichert.
Iwwerpréift an der Konsole:
[user@localhost ]$ pgrep -P 15771
9004
9005
[user@localhost ]$ ls -lah /proc/15771/fd/
total 0
dr-x------ 2 user user 0 Oct 7 15:42 .
dr-xr-xr-x 9 user user 0 Oct 7 15:42 ..
lrwx------ 1 user user 64 Oct 7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:42 255 -> /dev/pts/21
[user@localhost ]$ ls -lah /proc/9004/fd
total 0
dr-x------ 2 user user 0 Oct 7 15:57 .
dr-xr-xr-x 9 user user 0 Oct 7 15:57 ..
lrwx------ 1 user user 64 Oct 7 15:57 0 -> /dev/pts/21
l-wx------ 1 user user 64 Oct 7 15:57 1 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
lr-x------ 1 user user 64 Oct 7 15:57 3 -> /dev/zero
[user@localhost ]$ ls -lah /proc/9005/fd
total 0
dr-x------ 2 user user 0 Oct 7 15:57 .
dr-xr-xr-x 9 user user 0 Oct 7 15:57 ..
lr-x------ 1 user user 64 Oct 7 15:57 0 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct 7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct 7 15:57 2 -> /dev/pts/21
[user@localhost ]$ ps -up 9004
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 9004 0.0 0.0 107972 620 pts/21 S+ 15:57 0:00 cat /dev/zero
[user@localhost ]$ ps -up 9005
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 9005 0.0 0.0 107952 360 pts/21 S+ 15:57 0:00 sleep 10000
Wéi Dir kënnt gesinn, ass déi eenzegaarteg Zuel vun eisem Päif déiselwecht a béide Prozesser. Also hu mir eng Verbindung tëscht zwee verschiddene Prozesser mam selwechten Elterendeel.
Fir déi, déi net vertraut sinn mat de System Uriff, déi de Bash benotzt, ech recommandéieren d'Befehle duerch Strace ze lafen a kuckt wat dobannen geschitt, zum Beispill, sou:
strace -s 1024 -f bash -c "ls | grep hello"
Loosst eis zréck op eise Problem mam Lafen aus dem Disk Space a probéieren Daten ze späicheren ouni de Prozess nei ze starten. Loosst eis e klenge Programm schreiwen, deen ongeféier 1 Megabyte pro Sekonn op Disk schreift. Ausserdeem, wa mir aus irgendege Grënn keng Daten op Disk schreiwen konnten, ignoréiere mir dëst einfach a probéieren d'Donnéeën an enger Sekonn erëm ze schreiwen. Am Beispill benotzen ech Python, Dir kënnt all aner Programméierungssprooch benotzen.
[user@localhost ]$ cat openforwrite.py
import datetime
import time
mystr="a"*1024*1024+"n"
with open("123.txt", "w") as f:
while True:
try:
f.write(str(datetime.datetime.now()))
f.write(mystr)
f.flush()
time.sleep(1)
except:
pass
Run de Programm a kuckt op d'Datei Descriptoren
[user@localhost ]$ python openforwrite.py &
[1] 3762
[user@localhost ]$ ps axuf | grep [o]penforwrite
user 3762 0.0 0.0 128600 5744 pts/22 S+ 16:28 0:00 | _ python openforwrite.py
[user@localhost ]$ ls -la /proc/3762/fd
total 0
dr-x------ 2 user user 0 Oct 7 16:29 .
dr-xr-xr-x 9 user user 0 Oct 7 16:29 ..
lrwx------ 1 user user 64 Oct 7 16:29 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 7 16:29 3 -> /home/user/123.txt
Wéi Dir gesitt, hu mir eis 3 Standard Dateideskriptoren an en aneren deen mir opgemaach hunn. Loosst eis d'Dateigréisst kontrolléieren:
[user@localhost ]$ ls -lah 123.txt
-rw-rw-r-- 1 user user 117M Oct 7 16:30 123.txt
d'Donnéeën geschriwwe ginn, mir probéieren d'Rechter op d'Datei z'änneren:
[user@localhost ]$ sudo chown root: 123.txt
[user@localhost ]$ ls -lah 123.txt
-rw-rw-r-- 1 root root 168M Oct 7 16:31 123.txt
[user@localhost ]$ ls -lah 123.txt
-rw-rw-r-- 1 root root 172M Oct 7 16:31 123.txt
Mir gesinn datt d'Donnéeën nach ëmmer geschriwwe ginn, obwuel eise Benotzer net d'Recht huet fir de Fichier ze schreiwen. Loosst eis probéieren et ze läschen:
[user@localhost ]$ sudo rm 123.txt
[user@localhost ]$ ls 123.txt
ls: cannot access 123.txt: No such file or directory
Wou sinn d'Donnéeë geschriwwen? A si se iwwerhaapt geschriwwen? Mir kontrolléieren:
[user@localhost ]$ ls -la /proc/3762/fd
total 0
dr-x------ 2 user user 0 Oct 7 16:29 .
dr-xr-xr-x 9 user user 0 Oct 7 16:29 ..
lrwx------ 1 user user 64 Oct 7 16:29 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 7 16:29 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 7 16:29 3 -> /home/user/123.txt (deleted)
Jo, eise Fichier Descriptor existéiert nach ëmmer, a mir kënne mat dësem Fichier Descriptor schaffen wéi eis al Datei, mir kënnen et liesen, botzen a kopéieren.
Kuckt d'Dateigréisst:
[user@localhost ]$ lsof | grep 123.txt
python 31083 user 3w REG 8,5 19923457 2621522 /home/user/123.txt
D'Dateigréisst ass 19923457. Probéiert de Fichier ze läschen:
[user@localhost ]$ truncate -s 0 /proc/31083/fd/3
[user@localhost ]$ lsof | grep 123.txt
python 31083 user 3w REG 8,5 136318390 2621522 /home/user/123.txt
Wéi Dir gesitt, geet d'Dateigréisst nëmmen erop an eise Trunk huet net geschafft. Loosst eis op d'Dokumentatioun iwwer de Systemruff goen
with open("123.txt", "w") as f:
mir mussen setzen
with open("123.txt", "a") as f:
Iwwerpréift mat "w" Fändel
[user@localhost ]$ strace -e trace=open python openforwrite.py 2>&1| grep 123.txt
open("123.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
a mat "e" Fändel
[user@localhost ]$ strace -e trace=open python openforwrite.py 2>&1| grep 123.txt
open("123.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
Programméiere vun engem scho lafende Prozess
Dacks, wann Dir e Programm erstellt an testen, benotzen d'Programméierer Debugger (zum Beispill GDB) oder verschidde Niveaue vum Logbuch an der Applikatioun. Linux bitt d'Fäegkeet fir e scho lafende Programm tatsächlech ze schreiwen an z'änneren, sou wéi d'Wäerter vun de Variablen z'änneren, e Breakpoint astellen, asw.
Zréck op déi ursprénglech Fro iwwer de Mangel u Plaatz fir eng Datei ze schreiwen, loosst eis probéieren de Problem ze simuléieren.
Loosst eis eng Datei fir eis Partition erstellen, déi mir als separat Drive montéieren:
[user@localhost ~]$ dd if=/dev/zero of=~/tempfile_for_article.dd bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00525929 s, 2.0 GB/s
[user@localhost ~]$
Loosst eis e Dateiesystem erstellen:
[user@localhost ~]$ mkfs.ext4 ~/tempfile_for_article.dd
mke2fs 1.42.9 (28-Dec-2013)
/home/user/tempfile_for_article.dd is not a block special device.
Proceed anyway? (y,n) y
...
Writing superblocks and filesystem accounting information: done
[user@localhost ~]$
Loosst eis de Dateisystem montéieren:
[user@localhost ~]$ sudo mount ~/tempfile_for_article.dd /mnt/
[sudo] password for user:
[user@localhost ~]$ df -h | grep mnt
/dev/loop0 8.7M 172K 7.9M 3% /mnt
Erstellt e Verzeechnes mat eisem Besëtzer:
[user@localhost ~]$ sudo mkdir /mnt/logs
[user@localhost ~]$ sudo chown user: /mnt/logs
Loosst eis d'Datei opmaachen fir nëmmen an eisem Programm ze schreiwen:
with open("/mnt/logs/123.txt", "w") as f:
Lancéiere
[user@localhost ]$ python openforwrite.py
Waarde fir e puer Sekonnen
[user@localhost ~]$ df -h | grep mnt
/dev/loop0 8.7M 8.0M 0 100% /mnt
Also hu mir de Problem am Ufank vun dësem Artikel beschriwwen. Fräi Plaz 0, besat 100%.
Mir erënneren, datt laut de Konditioune vum Problem, mir probéieren ganz wichteg Donnéeën opzehuelen, déi net verluer kënne ginn. An dofir musse mir de Service fixéieren ouni de Prozess nei ze starten.
Loosst eis soen datt mir nach ëmmer Disk Space hunn, awer an enger anerer Partition, zum Beispill an / doheem.
Loosst eis probéieren eise Code "op der Flucht ze reprogramméieren".
Mir kucken de PID vun eisem Prozess, deen all Disk Space giess huet:
[user@localhost ~]$ ps axuf | grep [o]penfor
user 10078 27.2 0.0 128600 5744 pts/22 R+ 11:06 0:02 | _ python openforwrite.py
Verbindung mat engem Prozess mat gdb
[user@localhost ~]$ gdb -p 10078
...
(gdb)
Mir kucken op oppene Dateideskriptoren:
(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user 0 Oct 8 11:06 .
dr-xr-xr-x 9 user user 0 Oct 8 11:06 ..
lrwx------ 1 user user 64 Oct 8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:09 3 -> /mnt/logs/123.txt
Mir kucken d'Informatiounen iwwer de Fichier Descriptor mat Nummer 3, déi eis interesséiert
(gdb) shell cat /proc/10078/fdinfo/3
pos: 8189952
flags: 0100001
mnt_id: 482
Bedenkt wat de System Uruff Python mécht (kuckt hei uewen wou mir Strace lafen an en oppenen Uruff fonnt hunn), wärend eise Code veraarbecht fir eng Datei opzemaachen, maache mir datselwecht selwer am Numm vun eisem Prozess, awer mir brauchen den O_WRONLY|O_CREAT| O_TRUNC Bits ersetzen mat engem numeresche Wäert. Fir dëst ze maachen, öffnen zum Beispill d'Kernelquellen
#definéieren O_WRONLY 00000001
#definéieren O_CREAT 00000100
#definéieren O_TRUNC 00001000
Mir kombinéieren all Wäerter an een, mir kréien 00001101
Lafen eisen Uruff vun gdb
(gdb) call open("/home/user/123.txt", 00001101,0666)
$1 = 4
Also hu mir en neien Dateideskriptor mat Nummer 4 an eng nei oppene Datei op enger anerer Partition, kontrolléiert:
(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user 0 Oct 8 11:06 .
dr-xr-xr-x 9 user user 0 Oct 8 11:06 ..
lrwx------ 1 user user 64 Oct 8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:09 3 -> /mnt/logs/123.txt
l-wx------ 1 user user 64 Oct 8 11:15 4 -> /home/user/123.txt
Mir erënnere mech un d'Beispill mat Päif - wéi Bash Dateideskriptoren ännert, an hu schonn den dup2 System Uruff geléiert.
Probéiert een Dateideskriptor mat engem aneren ze ersetzen
(gdb) call dup2(4,3)
$2 = 3
Mir iwwerpréiwen:
(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user 0 Oct 8 11:06 .
dr-xr-xr-x 9 user user 0 Oct 8 11:06 ..
lrwx------ 1 user user 64 Oct 8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:09 3 -> /home/user/123.txt
l-wx------ 1 user user 64 Oct 8 11:15 4 -> /home/user/123.txt
Zoumaachen Datei Descriptor 4, well mir et net brauchen:
(gdb) call close (4)
$1 = 0
An erausgoen gdb
(gdb) quit
A debugging session is active.
Inferior 1 [process 10078] will be detached.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 10078
Iwwerpréift déi nei Datei:
[user@localhost ~]$ ls -lah /home/user/123.txt
-rw-rw-r-- 1 user user 5.1M Oct 8 11:18 /home/user/123.txt
[user@localhost ~]$ ls -lah /home/user/123.txt
-rw-rw-r-- 1 user user 7.1M Oct 8 11:18 /home/user/123.txt
Wéi Dir gesitt, sinn d'Donnéeën an eng nei Datei geschriwwe ginn, mir kontrolléieren déi al:
[user@localhost ~]$ ls -lah /mnt/logs/123.txt
-rw-rw-r-- 1 user user 7.9M Oct 8 11:08 /mnt/logs/123.txt
D'Donnéeë ginn net verluer, d'Applikatioun funktionnéiert, d'Logbicher ginn op eng nei Plaz geschriwwe.
Loosst eis d'Saache e bësse méi schwéier maachen
Stellt Iech vir datt d'Donnéeën fir eis wichteg sinn, awer mir hunn keen Disk Space an enger vun de Partitionen a mir kënnen d'Disk net verbannen.
Wat mir maache kënnen ass eis Donnéeën iergendwou viruleeden, zum Beispill op eng Päif, an d'Daten aus der Päif an d'Netzwierk duerch e puer Programm, wéi netcat, viruleeden.
Mir kënnen e genannte Päif mam mkfifo Kommando erstellen. Et wäert eng Pseudo-Datei am Dateiesystem erstellen, och wann et kee fräie Raum drop ass.
Restart d'Applikatioun a kontrolléiert:
[user@localhost ]$ python openforwrite.py
[user@localhost ~]$ ps axuf | grep [o]pen
user 5946 72.9 0.0 128600 5744 pts/22 R+ 11:27 0:20 | _ python openforwrite.py
[user@localhost ~]$ ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/123.txt
[user@localhost ~]$ df -h | grep mnt
/dev/loop0 8.7M 8.0M 0 100% /mnt
Et gëtt keen Disk Space, awer mir erstellen erfollegräich e genannte Pipe do:
[user@localhost ~]$ mkfifo /mnt/logs/megapipe
[user@localhost ~]$ ls -lah /mnt/logs/megapipe
prw-rw-r-- 1 user user 0 Oct 8 11:28 /mnt/logs/megapipe
Elo musse mir iergendwéi all d'Donnéeën, déi an dësem Päif op en anere Server duerch d'Netz kommen, wéckelen, dee selwechte Netcat ass fir dëst gëeegent.
Um Remote-server.example.com Server, lafen
[user@localhost ~]$ nc -l 7777 > 123.txt
Op eisem Problem Server, lafen an engem separaten Terminal
[user@localhost ~]$ nc remote-server.example.com 7777 < /mnt/logs/megapipe
Elo ginn all d'Donnéeën, déi an d'Päif kommen, automatesch op stdin an netcat goen, wat se an d'Netzwierk um Port 7777 schéckt.
Alles wat mir maache mussen ass eis Donnéeën un dës genannt Päif ze schreiwen.
Mir hu schonn eng lafend Applikatioun:
[user@localhost ~]$ ps axuf | grep [o]pen
user 5946 99.8 0.0 128600 5744 pts/22 R+ 11:27 169:27 | _ python openforwrite.py
[user@localhost ~]$ ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/123.txt
Vun all de Fändelen brauche mir nëmmen O_WRONLY well de Fichier schonn existéiert a mir brauche se net ze läschen
[user@localhost ~]$ gdb -p 5946
...
(gdb) call open("/mnt/logs/megapipe", 00000001,0666)
$1 = 4
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/123.txt
l-wx------ 1 user user 64 Oct 8 14:20 4 -> /mnt/logs/megapipe
(gdb) call dup2(4,3)
$2 = 3
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/megapipe
l-wx------ 1 user user 64 Oct 8 14:20 4 -> /mnt/logs/megapipe
(gdb) call close(4)
$3 = 0
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user 0 Oct 8 11:27 .
dr-xr-xr-x 9 user user 0 Oct 8 11:27 ..
lrwx------ 1 user user 64 Oct 8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct 8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct 8 11:28 3 -> /mnt/logs/megapipe
(gdb) quit
A debugging session is active.
Inferior 1 [process 5946] will be detached.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 5946
Kontrolléiert de Remote Server Remote-server.example.com
[user@localhost ~]$ ls -lah 123.txt
-rw-rw-r-- 1 user user 38M Oct 8 14:21 123.txt
Daten kommen, mir kontrolléieren de Problem Server
[user@localhost ~]$ ls -lah /mnt/logs/
total 7.9M
drwxr-xr-x 2 user user 1.0K Oct 8 11:28 .
drwxr-xr-x 4 root root 1.0K Oct 8 10:55 ..
-rw-rw-r-- 1 user user 7.9M Oct 8 14:17 123.txt
prw-rw-r-- 1 user user 0 Oct 8 14:22 megapipe
D'Donnéeë ginn gespäichert, de Problem ass geléist.
Ech profitéieren vun dëser Geleeënheet fir de Kollege vum Degiro ze soen.
Lauschtert Radio-T Podcasts.
Gutt un all.
Als Hausaufgaben proposéieren ech ze denken iwwer wat an de Dateibeschreiwunge vum Kaz a Schlofprozess wäert sinn wann Dir de folgende Kommando ausféiert:
[user@localhost ~]$ cat /dev/zero 2>/dev/null| sleep 10000
Source: will.com