Fichye deskriptè nan Linux ak egzanp

Yon fwa, pandan yon entèvyou, mwen te mande, kisa ou pral fè si ou jwenn yon sèvis ki pa travay akòz lefèt ke disk la te fini nan espas?

Natirèlman, mwen te reponn ke mwen ta wè sa ki te okipe pa kote sa a epi, si sa posib, mwen ta netwaye kote a.
Lè sa a, entèvyou a te mande, e si pa gen okenn espas gratis sou patisyon an, men ou menm tou ou pa wè okenn dosye ki ta pran tout espas la?

Pou sa a mwen te di ke ou ka toujou gade nan deskriptè dosye louvri, pou egzanp ak lòd la lsof, epi konprann ki aplikasyon ki te pran tout espas ki disponib, epi Lè sa a, ou ka aji selon sikonstans yo, tou depann de si done yo bezwen. .

Entèvyou a entèwonp mwen sou dènye mo a, ajoute nan kesyon li a: "Sipoze nou pa bezwen done yo, li se jis yon boutèy demi lit, men aplikasyon an pa travay paske li pa ka ekri yon debug"?

"Oke," mwen te reponn, "nou ka fèmen debug nan konfigirasyon aplikasyon an epi rekòmanse li."
Entèvyou a te fè objeksyon: "Non, nou pa ka rekòmanse aplikasyon an, nou toujou gen done enpòtan ki estoke nan memwa, ak kliyan enpòtan yo konekte ak sèvis la li menm, ke nou pa ka fòse rekonekte ankò."

"Oke," mwen te di, "si nou pa ka rekòmanse aplikasyon an epi done yo pa enpòtan pou nou, Lè sa a, nou ka tou senpleman netwaye dosye sa a louvri atravè deskriptè dosye a, menm si nou pa wè li nan lòd ls la. sou sistèm dosye a."

Entèvyou a te kontan, men mwen pa t '.

Lè sa a, mwen te panse, poukisa moun nan teste konesans mwen an pa fouye pi fon? Men, e si done yo enpòtan apre tout? E si nou pa ka rekòmanse yon pwosesis, epi pwosesis la ekri nan sistèm dosye a sou yon patisyon ki pa gen espas gratis? E si nou pa ka pèdi non sèlman done ki deja ekri yo, men tou done pwosesis sa a ekri oswa eseye ekri?

Tuzik

Byen bonè nan karyè mwen, mwen te eseye kreye yon ti aplikasyon ki te bezwen sere enfòmasyon itilizatè. Lè sa a, mwen te panse, ki jan mwen ka matche ak itilizatè a done li yo. Pou egzanp, mwen gen Ivanov Ivan Ivanovich, epi li gen kèk enfòmasyon, men ki jan mwen ka fè zanmi ak yo? Mwen ka fè remake dirèkteman ke chen yo te rele "Tuzik" fè pati Ivan sa a. Men, e si li chanje non l 'ak olye pou yo Ivan vin, pou egzanp, Olya? Lè sa a, li pral vire ke Olya Ivanovna Ivanova nou an p ap gen yon chen ankò, ak Tuzik nou an ap toujou fè pati Ivan ki pa egziste. Yon baz done ki te bay chak itilizatè yon idantifyan inik (ID) te ede rezoud pwoblèm sa a, epi Tuzik mwen an te mare ak ID sa a, ki, an reyalite, te jis yon nimewo seri. Se konsa, pwopriyetè ace a te gen nimewo ID 2, ak nan kèk pwen nan tan Ivan te anba ID sa a, ak Lè sa a, Olya te vin anba menm ID la. Pwoblèm limanite ak elvaj bèt te pratikman rezoud.

Deskriptè dosye

Pwoblèm nan nan dosye a ak pwogram nan ki travay ak dosye sa a se apeprè menm jan ak sa yo ki nan chen nou an ak moun. Sipoze mwen te louvri yon fichye ki rele ivan.txt epi mwen te kòmanse ekri mo tuzik la nan li, men sèlman jere yo ekri premye lèt "t" nan dosye a, epi yon moun te chanje non fichye sa a, pou egzanp, olya.txt. Men, dosye a rete menm jan an, e mwen toujou vle anrejistre as mwen an ladan l. Chak fwa yon dosye louvri pa yon apèl sistèm ouvri nan nenpòt lang pwogramasyon mwen resevwa yon ID inik ki montre m 'nan yon fichye, ID sa a se deskriptè dosye a. Epi li pa enpòtan ditou kisa ak ki moun ki fè ak dosye sa a apre, li ka efase, li ka chanje non, mèt kay la ka chanje, oswa dwa pou li ak ekri yo ka retire, mwen pral toujou gen aksè. pou li, paske nan moman ouvèti fichye a, mwen te gen dwa pou li ak/oswa ekri li e mwen te rive kòmanse travay ak li, sa vle di mwen dwe kontinye fè sa.

Nan Linux, bibliyotèk libc la louvri 3 fichye deskriptè pou chak aplikasyon k ap kouri (pwosesis), ki nimewote 0,1,2. Ou ka jwenn plis enfòmasyon sou lyen yo man stdio и man stdout

  • Deskriptè dosye 0 yo rele STDIN epi li asosye ak opinyon aplikasyon an
  • Fichye deskriptè 1 yo rele STDOUT epi aplikasyon yo itilize pou pwodiksyon done, tankou kòmandman enprime
  • Deskriptè dosye 2 yo rele STDERR epi aplikasyon yo itilize pou bay mesaj erè.

Si nan pwogram ou an ou louvri nenpòt dosye pou li oswa ekri, Lè sa a, gen plis chans ou pral jwenn premye ID gratis la epi li pral nimewo 3.

Ou ka wè lis deskriptè dosye yo pou nenpòt pwosesis si w konnen PID li yo.

Pou egzanp, ann louvri konsole bash la epi gade nan PID pwosesis nou an

[user@localhost ]$ echo $$
15771

Nan dezyèm konsole ann kouri

[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

Ou ka san danje inyore deskriptè dosye nimewo 255 pou rezon atik sa a; li te louvri pou bezwen li pa bash tèt li, epi li pa pa bibliyotèk ki lye a.

Koulye a, tout 3 fichye deskriptè yo asosye ak aparèy tèminal pseudo a /dev/pts, men nou ka toujou manipile yo, pou egzanp, kouri yo nan yon dezyèm konsole

[user@localhost ]$ echo "hello world" > /proc/15771/fd/0

Ak nan premye konsole a nou pral wè

[user@localhost ]$ hello world

Redireksyon ak tiyo

Ou ka fasilman depase 3 fichye deskriptè sa yo nan nenpòt pwosesis, tankou nan bash, pou egzanp atravè yon tiyo ki konekte de pwosesis, gade.

[user@localhost ]$ cat /dev/zero | sleep 10000

Ou ka kouri lòd sa a tèt ou ak strace -f epi gade sa k ap pase andedan, men mwen pral di ou yon ti tan.

Pwosesis bash paran nou an ak PID 15771 analize kòmandman nou an epi konprann egzakteman konbyen kòmandman nou vle kouri, nan ka nou an gen de nan yo: chat ak dòmi. Bash konnen ke li bezwen kreye de pwosesis timoun, ak rantre yo nan yon sèl tiyo. An total, bash ap bezwen 2 pwosesis pitit ak yon tiyo.

Bash kouri yon apèl sistèm anvan kreye pwosesis pitit tiyo epi li resevwa nouvo deskriptè dosye sou tanpon tiyo tanporè a, men tanpon sa a poko konekte de pwosesis pitit nou yo.

Pou pwosesis paran an, li sanble ke gen deja yon tiyo, men pa gen okenn pwosesis pitit ankò:

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

Lè sa a, itilize apèl sistèm lan script bash kreye de pwosesis pitit, ak twa pwosesis nou yo pral sanble sa a:

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

Pa bliye ke klonaj klonaj pwosesis la ansanm ak tout deskriptè dosye yo, kidonk yo pral menm jan an nan pwosesis paran an ak nan sa yo timoun yo. Travay paran pwosesis la ak PID 15771 se kontwole pwosesis timoun yo, kidonk li tou senpleman tann pou yon repons nan men timoun yo.

Se poutèt sa, li pa bezwen tiyo, epi li fèmen deskriptè dosye ki nimero 3 ak 4.

Nan pwosesis bach premye pitit la ak PID 9004, sistèm apèl la dup2, chanje deskriptè dosye STDOUT nimewo 1 nou an nan yon deskriptè fichye ki lonje dwèt sou tiyo, nan ka nou an li se nimewo 3. Kidonk, tout sa premye pitit pwosesis la ak PID 9004 ekri nan STDOUT pral otomatikman fini nan tanpon tiyo a.

Nan pwosesis dezyèm pitit la ak PID 9005, bash sèvi ak dup2 pou chanje dosye a deskriptè STDIN nimewo 0. Koulye a, tout sa ki dezyèm bash nou an ak PID 9005 pral li yo pral li nan tiyo a.

Apre sa, deskriptè dosye ki nimewote 3 ak 4 yo fèmen tou nan pwosesis timoun yo, paske yo pa itilize yo ankò.

Mwen fè espre inyore deskriptè dosye 255; li se itilize pou rezon entèn pa bash tèt li epi yo pral fèmen tou nan pwosesis timoun yo.

Apre sa, nan pwosesis premye pitit la ak PID 9004, bash kòmanse itilize yon apèl sistèm Egzekitif fichye ègzekutabl ke nou espesifye sou liy lòd la, nan ka nou an li se /usr/bin/cat.

Nan dezyèm pwosesis pitit la ak PID 9005, bash kouri dezyèm ègzekutabl nou espesifye a, nan ka nou an /usr/bin/sleep.

Rele sistèm exec la pa fèmen manch dosye sof si yo te louvri ak drapo O_CLOEXEC nan moman apèl la louvri yo te fè. Nan ka nou an, apre yo fin lanse dosye ègzèkutabl yo, tout deskriptè dosye aktyèl yo pral sove.

Tcheke nan konsole a:

[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

Kòm ou ka wè, nimewo inik nan tiyo nou an se menm bagay la tou nan tou de pwosesis. Kidonk nou gen yon koneksyon ant de pwosesis diferan ak menm paran an.

Pou moun ki pa abitye ak sistèm apèl ki bash itilize yo, mwen trè rekòmande kouri kòmandman yo atravè strace epi wè sa k ap pase anndan an, pou egzanp tankou sa a:

strace -s 1024 -f bash -c "ls | grep hello"

Ann tounen nan pwoblèm nou an nan kouri soti nan espas ki gen kapasite ak ap eseye sove done san yo pa rekòmanse pwosesis la. Ann ekri yon ti pwogram ki pral ekri apeprè 1 megabyte pou chak segonn sou disk. Anplis, si pou kèk rezon nou pa t 'kapab ekri done sou disk la, nou pral tou senpleman inyore sa a epi eseye ekri done yo ankò nan yon segonn. Nan egzanp mwen ap itilize Python, ou ka itilize nenpòt lòt langaj pwogramasyon.

[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

Ann kouri pwogram nan epi gade deskriptè dosye yo

[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

Kòm ou ka wè, nou gen 3 deskriptè dosye estanda nou yo ak yon lòt ke nou louvri. Ann tcheke gwosè dosye a:

[user@localhost ]$ ls -lah 123.txt 
-rw-rw-r-- 1 user user 117M Oct  7 16:30 123.txt

Done yo ap ekri, nou eseye chanje otorizasyon yo sou dosye a:

[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

Nou wè ke done yo toujou ap ekri, byenke itilizatè nou an pa gen pèmisyon pou ekri nan dosye a. Ann eseye retire li:

[user@localhost ]$ sudo rm 123.txt 
[user@localhost ]$ ls 123.txt
ls: cannot access 123.txt: No such file or directory

Ki kote done yo ekri? E yo ekri tout? Nou tcheke:

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

Wi, deskriptè dosye nou an toujou egziste epi nou ka trete deskriptè fichye sa a tankou ansyen dosye nou an, nou ka li, klè epi kopye li.

Ann gade gwosè dosye a:

[user@localhost ]$ lsof | grep 123.txt
python    31083             user    3w      REG                8,5   19923457   2621522 /home/user/123.txt

Gwosè fichye a se 19923457. Ann eseye netwaye fichye a:

[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

Kòm ou ka wè, gwosè dosye a ap ogmante sèlman epi kòf nou an pa t travay. Ann gade nan dokiman apèl sistèm lan ouvri. Si nou itilize drapo O_APPEND lè nou ouvri yon fichye, lè sa a ak chak ekriti, sistèm operasyon an tcheke gwosè fichye a epi ekri done jiska fen fichye a, epi fè sa atomikman. Sa a pèmèt plizyè fil oswa pwosesis yo ekri nan menm dosye a. Men, nan kòd nou an nou pa sèvi ak drapo sa a. Nou ka wè yon gwosè fichye diferan nan lsof apre kòf sèlman si nou louvri fichye a pou plis ekri, ki vle di nan kòd nou an pito.

with open("123.txt", "w") as f:

nou dwe mete

with open("123.txt", "a") as f:

Tcheke ak drapo "w".

[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

ak drapo "yon".

[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

Pwogramasyon yon pwosesis ki deja kouri

Souvan pwogramè yo, lè yo kreye ak tès pwogram yo, sèvi ak debogaj (pa egzanp GDB) oswa divès nivo nan antre nan aplikasyon an. Linux bay kapasite pou aktyèlman ekri ak chanje yon pwogram ki deja kouri, pou egzanp, chanje valè yo nan varyab, mete yon breakpoint, elatriye, elatriye.

Retounen nan kesyon orijinal la sou pa ase espas disk yo ekri yon dosye, an n eseye simulation pwoblèm nan.

Ann kreye yon dosye pou patisyon nou an, ke nou pral monte kòm yon disk separe:

[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 ~]$

Ann kreye yon sistèm dosye:

[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 ~]$

Monte sistèm fichye a:

[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

Nou kreye yon anyè ak pwopriyetè nou an:

[user@localhost ~]$ sudo mkdir /mnt/logs
[user@localhost ~]$ sudo chown user: /mnt/logs

Ann louvri dosye a pou ekri sèlman nan pwogram nou an:

with open("/mnt/logs/123.txt", "w") as f:

Lanse

[user@localhost ]$ python openforwrite.py 

Nou tann kèk segond

[user@localhost ~]$ df -h | grep mnt
/dev/loop0      8.7M  8.0M     0 100% /mnt

Se konsa, nou gen pwoblèm ki dekri nan kòmansman atik sa a. Espas gratis 0, 100% okipe.

Nou sonje ke selon kondisyon travay la, nou ap eseye anrejistre done trè enpòtan ki pa ka pèdi. Ak an menm tan an, nou bezwen ranje sèvis la san yo pa rekòmanse pwosesis la.

Ann di nou toujou gen espas disk, men nan yon patisyon diferan, pou egzanp nan /home.

Ann eseye "repwograme sou vole" kòd nou an.

Ann gade nan PID pwosesis nou an, ki te manje tout espas disk la:

[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

Konekte ak pwosesis la atravè gdb

[user@localhost ~]$ gdb -p 10078
...
(gdb) 

Ann gade deskriptè dosye yo louvri:

(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

Nou gade enfòmasyon sou dosye deskriptè nimewo 3, ki enterese nou

(gdb) shell cat /proc/10078/fdinfo/3
pos:    8189952
flags:  0100001
mnt_id: 482

Kenbe nan tèt ou ki apèl sistèm Python fè (gade pi wo a ki kote nou kouri strace epi jwenn apèl la louvri), lè w ap trete kòd nou an pou ouvri yon fichye, nou fè menm bagay la pou tèt nou sou non pwosesis nou an, men nou bezwen O_WRONLY|O_CREAT| Bits O_TRUNC ranplase ak yon valè nimerik. Pou fè sa, louvri sous nwayo yo, pou egzanp isit la epi gade ki drapo ki responsab pou kisa

#defini O_WRONLY 00000001
#defini O_CREAT 00000100
#defini O_TRUNC 00001000

Nou konbine tout valè yo nan yon sèl, nou jwenn 00001101

Nou kouri apèl nou soti nan gdb

(gdb) call open("/home/user/123.txt", 00001101,0666)
$1 = 4

Se konsa, nou te resevwa yon nouvo deskriptè dosye ak nimewo 4 ak yon nouvo dosye louvri sou yon lòt patisyon, nou tcheke:

(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

Nou sonje egzanp lan ak tiyo - ki jan bash chanje deskriptè dosye, epi nou te deja aprann apèl sistèm dup2 la.

Nou eseye ranplase yon deskriptè dosye ak yon lòt

(gdb) call dup2(4,3)
$2 = 3

Nou tcheke:

(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

Nou fèmen deskriptè dosye 4, paske nou pa bezwen li:

(gdb) call close (4)
$1 = 0

Epi sòti 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

Tcheke nouvo dosye a:

[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

Kòm ou ka wè, done yo ekri nan yon nouvo dosye, ann tcheke ansyen an:

[user@localhost ~]$ ls -lah /mnt/logs/123.txt 
-rw-rw-r-- 1 user user 7.9M Oct  8 11:08 /mnt/logs/123.txt

Pa gen okenn done ki pèdi, aplikasyon an ap travay, mòso bwa yo ekri nan yon nouvo kote.

Ann konplike travay la yon ti kras

Ann imajine ke done yo enpòtan pou nou, men nou pa gen espas disk nan nenpòt nan patisyon yo epi nou pa ka konekte disk la.

Ki sa nou ka fè se redireksyon done nou yo yon kote, pou egzanp nan tiyo, ak nan vire redireksyon done ki soti nan tiyo nan rezo a atravè kèk pwogram, pou egzanp netcat.
Nou ka kreye yon tiyo non ak lòd mkfifo. Li pral kreye yon pseudo fichye sou sistèm dosye a menm si pa gen okenn espas gratis sou li.

Rekòmanse aplikasyon an epi tcheke:

[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

Pa gen espas disk, men nou avèk siksè kreye yon tiyo ki rele la:

[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

Koulye a, nou bezwen yon jan kanmenm vlope tout done ki ale nan tiyo sa a nan yon lòt sèvè atravè rezo a; menm netcat la apwopriye pou sa.

Sou sèvè remote-server.example.com nou lanse

[user@localhost ~]$ nc -l 7777 > 123.txt 

Sou sèvè pwoblèm nou an nou lanse nan yon tèminal separe

[user@localhost ~]$ nc remote-server.example.com 7777 < /mnt/logs/megapipe 

Koulye a, tout done ki fini nan tiyo a pral otomatikman ale nan stdin nan netcat, ki pral voye li nan rezo a sou pò 7777.

Tout sa nou dwe fè se kòmanse ekri done nou yo nan tiyo sa a ki rele.

Nou deja gen aplikasyon an ap kouri:

[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

Nan tout drapo yo, nou sèlman bezwen O_WRONLY paske dosye a deja egziste e nou pa bezwen netwaye li.

[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

Tcheke sèvè aleka remote-server.example.com

[user@localhost ~]$ ls -lah 123.txt 
-rw-rw-r-- 1 user user 38M Oct  8 14:21 123.txt

Done yo ap vini, nou tcheke sèvè pwoblèm nan

[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

Done yo sove, pwoblèm nan rezoud.

Mwen pwofite di bonjou ak kòlèg mwen yo nan Degiro.
Koute podcasts Radio-T.

Bon nan tout.

Kòm devwa, mwen sijere ou panse sou sa ki pral nan pwosesis dosye deskriptè chat ak dòmi si ou kouri lòd sa a:

[user@localhost ~]$ cat /dev/zero 2>/dev/null| sleep 10000

Sous: www.habr.com

Add nouvo kòmantè