File descriptor sa Linux nga adunay mga pananglitan

Kausa, sa usa ka interbyu, gipangutana ako, unsa ang imong buhaton kung makit-an nimo ang usa ka serbisyo nga wala molihok tungod sa kamatuoran nga ang disk nahutdan sa wanang?

Siyempre, mitubag ako nga tan-awon nako kung unsa ang giokupahan niini nga lugar ug, kung mahimo, limpyohan nako ang lugar.
Dayon nangutana ang tig-interbyu, unsa kaha kung walay libre nga luna sa partisyon, apan wala ka usab makakita sa bisan unsang mga file nga mokuha sa tanang luna?

Niini giingon ko nga mahimo nimong tan-awon kanunay ang bukas nga mga deskriptor sa file, pananglitan sa lsof command, ug sabton kung unsang aplikasyon ang nakakuha sa tanan nga magamit nga wanang, ug pagkahuman mahimo ka molihok sumala sa mga kahimtang, depende kung gikinahanglan ang datos. .

Ang tig-interbyu mibalda kanako sa kataposang pulong, nga midugang sa iyang pangutana: "Pananglit dili nato kinahanglan ang datos, kini usa lamang ka debug log, apan ang aplikasyon dili molihok tungod kay kini dili makasulat sa usa ka debug"?

"Okay," mitubag ko, "mahimo natong i-off ang debug sa application config ug i-restart kini."
Ang tig-interbyu misupak: "Dili, dili namo ma-restart ang aplikasyon, aduna pa kami'y importanteng datos nga gitipigan sa memorya, ug ang importante nga mga kliyente konektado sa serbisyo mismo, nga dili namo mapugos sa pagkonektar pag-usab."

"okay," ingon ko, "kung dili namo ma-restart ang aplikasyon ug ang data dili importante kanamo, nan mahimo namong hawanan kining bukas nga file pinaagi sa file descriptor, bisan kung wala namo kini makita sa ls command sa file system.”

Ang tig-interbyu nalipay, apan ako dili.

Unya nakahunahuna ko, nganong dili man mosulay og lawom ang tawo sa akong kahibalo? Apan unsa man kung ang datos hinungdanon sa tanan? Unsa kaha kung dili naton ma-restart ang usa ka proseso, ug ang proseso nagsulat sa file system sa usa ka partisyon nga wala’y libre nga wanang? Unsa kaha kung dili naton mawala dili lamang ang mga datos nga nasulat na, apan usab ang datos nga gisulat o gisulayan sa pagsulat niini nga proseso?

Tuzik

Sa sayong bahin sa akong karera, gisulayan nako ang paghimo og gamay nga aplikasyon nga kinahanglan nga tipigan ang kasayuran sa tiggamit. Ug unya naghunahuna ko, unsaon nako pagpares sa tiggamit sa iyang datos. Pananglitan, ako adunay Ivanov Ivan Ivanovich, ug siya adunay pipila ka impormasyon, apan unsaon nako pagpakighigala kanila? Direkta nakong itudlo nga ang iro nga ginganlag "Tuzik" iya ni Ivan. Apan komosta kon iyang usbon ang iyang ngalan ug imbes nga si Ivan mahimong, pananglitan, si Olya? Unya mogawas nga ang atong Olya Ivanovna Ivanova wala nay iro, ug ang atong Tuzik mahisakop gihapon sa wala nga Ivan. Ang usa ka database nga naghatag sa matag user og usa ka talagsaon nga identifier (ID) nakatabang sa pagsulbad niini nga problema, ug ang akong Tuzik nahigot niini nga ID, nga, sa pagkatinuod, usa lamang ka serial number. Busa, ang tag-iya sa ace adunay ID number 2, ug sa usa ka punto sa panahon si Ivan ubos niini nga ID, ug dayon si Olya nahimong ubos sa samang ID. Ang problema sa katawhan ug pag-atiman sa hayop halos nasulbad.

Deskriptor sa file

Ang problema sa file ug sa programa nga nagtrabaho uban niini nga file mao ang gibana-bana nga sama sa sa atong iro ug tawo. Ibutang ta nga giablihan nako ang usa ka file nga gitawag og ivan.txt ug gisugdan ang pagsulat sa pulong nga tuzik niini, apan nakahimo lamang sa pagsulat sa unang letra nga "t" sa file, ug kini nga file giilisan og ngalan sa usa ka tawo, pananglitan, sa olya.txt. Apan ang file nagpabilin nga pareho, ug gusto ko gihapon nga irekord ang akong ace niini. Matag higayon nga ang usa ka file maablihan pinaagi sa usa ka tawag sa sistema bukas sa bisan unsa nga programming language nakadawat ko og talagsaon nga ID nga nagpunting kanako sa usa ka file, kini nga ID mao ang file descriptor. Ug dili igsapayan kung unsa ug kinsa ang sunod nga buhaton sa kini nga file, mahimo kini matangtang, mahimo’g mabag-o ang ngalan, mabag-o ang tag-iya, o mahimo’g makuha ang mga katungod sa pagbasa ug pagsulat, ako adunay access niini, tungod kay sa panahon sa pag-abli sa file, ako adunay mga katungod sa pagbasa ug/o pagsulat niini ug ako nakahimo sa pagsugod sa pagtrabaho uban niini, nga nagpasabot nga ako kinahanglan nga magpadayon sa pagbuhat sa ingon.

Sa Linux, ang libc library nag-abli sa 3 ka descriptor files alang sa matag running application (proseso), nga may numero nga 0,1,2. Dugang nga impormasyon makita sa mga link tawo stdio ΠΈ tawo stdout

  • Ang file descriptor 0 gitawag nga STDIN ug gilambigit sa aplikasyon input
  • Ang file descriptor 1 gitawag nga STDOUT ug gigamit sa mga aplikasyon sa pag-output sa datos, sama sa print commands
  • Ang file descriptor 2 gitawag nga STDERR ug gigamit sa mga aplikasyon sa pag-output sa mga mensahe sa sayup.

Kung sa imong programa ablihan nimo ang bisan unsang file para sa pagbasa o pagsulat, nan lagmit makuha nimo ang una nga libre nga ID ug kini ang numero 3.

Ang lista sa mga deskriptor sa file mahimong tan-awon alang sa bisan unsang proseso kung nahibal-an nimo ang PID niini.

Pananglitan, atong ablihan ang bash console ug tan-awon ang PID sa atong proseso

[user@localhost ]$ echo $$
15771

Sa ikaduha nga console kita modagan

[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

Mahimo nimo nga luwas nga ibaliwala ang file descriptor number 255 alang sa mga katuyoan sa kini nga artikulo; giablihan kini alang sa mga panginahanglanon pinaagi sa pag-bash mismo, ug dili sa nalambigit nga librarya.

Karon ang tanan nga 3 descriptor files nalangkit sa pseudo terminal device /dev/pts, apan mahimo gihapon nato silang manipulahon, pananglitan, ipadagan kini sa ikaduhang console

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

Ug sa unang console atong makita

[user@localhost ]$ hello world

Pag-redirect ug Pipe

Dali nimong ma-override kining 3 ka descriptor files sa bisan unsang proseso, lakip sa bash, pananglitan pinaagi sa pipe nga nagkonektar sa duha ka proseso, tan-awa.

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

Mahimo nimong ipadagan kini nga mando sa imong kaugalingon laray -f ug tan-awa kung unsa ang nahitabo sa sulod, apan isulti ko kanimo sa makadiyot.

Ang proseso sa pag-bash sa among ginikanan nga adunay PID 15771 nag-parse sa among mando ug nakasabut sa eksakto kung pila ka mga mando ang gusto namon ipadagan, sa among kaso adunay duha niini: iring ug pagkatulog. Nahibal-an ni Bash nga kinahanglan kini maghimo og duha ka proseso sa bata, ug iusa kini sa usa ka tubo. Sa kinatibuk-an, ang bash magkinahanglan og 2 ka proseso sa bata ug usa ka tubo.

Ang Bash nagpadagan sa usa ka tawag sa sistema sa wala pa maghimo mga proseso sa bata tubo ug nakadawat ug bag-ong file descriptor sa temporaryong pipe buffer, apan kini nga buffer wala pa magkonektar sa among duha ka bata nga proseso.

Para sa proseso sa ginikanan, murag naa nay tubo, pero wala pa'y proseso sa bata:

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

Unya gamit ang tawag sa sistema clone Ang bash nagmugna og duha ka proseso sa bata, ug ang among tulo ka proseso mahimong sama niini:

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

Ayaw kalimti nga ang pag-clone sa proseso kauban ang tanan nga mga deskriptor sa file, aron parehas sila sa proseso sa ginikanan ug sa mga bata. Ang trabaho sa proseso sa ginikanan nga adunay PID 15771 mao ang pag-monitor sa mga proseso sa bata, busa naghulat lang kini sa tubag gikan sa mga bata.

Busa, wala kini magkinahanglan og tubo, ug kini nagsira sa mga deskriptor sa file nga numero 3 ug 4.

Sa unang proseso sa bash sa bata nga adunay PID 9004, ang tawag sa sistema dup2, nagbag-o sa among STDOUT file descriptor number 1 ngadto sa file descriptor nga nagpunting sa pipe, sa among kaso kini numero 3. Busa, ang tanan nga ang unang proseso sa bata nga adunay PID 9004 misulat sa STDOUT awtomatik nga mahuman sa pipe buffer.

Sa ikaduhang proseso sa bata nga adunay PID 9005, ang bash naggamit sa dup2 aron mausab ang file descriptor STDIN number 0. Karon ang tanan nga mabasa sa among ikaduhang bash nga adunay PID 9005 mabasa gikan sa pipe.

Pagkahuman niini, ang mga deskriptor sa file nga adunay numero 3 ug 4 gisirhan usab sa mga proseso sa bata, tungod kay wala na sila gigamit.

Ako tinuyo nga wala magtagad sa file descriptor 255; kini gigamit alang sa internal nga mga katuyoan pinaagi sa bash mismo ug sirado usab sa mga proseso sa bata.

Sunod, sa unang proseso sa bata nga adunay PID 9004, ang bash nagsugod sa paggamit sa usa ka tawag sa sistema exec ang executable file nga among gipiho sa command line, sa among kaso kini /usr/bin/cat.

Sa ikaduhang proseso sa bata nga adunay PID 9005, ang bash nagpadagan sa ikaduhang executable nga among gitakda, sa among kaso /usr/bin/sleep.

Ang exec system call dili magsira sa mga file handle gawas kung kini giablihan gamit ang O_CLOEXEC flag sa panahon nga ang open call gihimo. Sa among kaso, pagkahuman sa paglansad sa mga executable nga mga file, ang tanan nga karon nga mga deskriptor sa file maluwas.

Susiha ang console:

[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

Sama sa imong makita, ang talagsaon nga gidaghanon sa among tubo parehas sa duha ka proseso. Sa ingon kita adunay koneksyon tali sa duha ka lainlaing mga proseso nga adunay parehas nga ginikanan.

Alang sa mga dili pamilyar sa mga tawag sa sistema nga gigamit sa bash, girekomenda nako ang pagpadagan sa mga mando pinaagi sa strace ug pagtan-aw kung unsa ang nahitabo sa sulod, pananglitan sama niini:

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

Atong balikan ang atong problema sa ubos nga disk space ug naningkamot sa pagluwas sa data nga walay pagsugod pag-usab sa proseso. Magsulat kita og gamay nga programa nga mosulat og gibana-bana nga 1 megabyte kada segundo sa disk. Dugang pa, kung tungod sa usa ka hinungdan dili kami makasulat sa data sa disk, dili na lang namo ibaliwala kini ug sulayan nga isulat pag-usab ang datos sa usa ka segundo. Sa pananglitan nga akong gigamit sa Python, mahimo nimong gamiton ang bisan unsang ubang programming language.

[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

Atong pagdagan ang programa ug tan-awon ang mga deskriptor sa file

[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

Sama sa imong nakita, kami adunay among 3 nga standard nga mga deskriptor sa file ug usa pa nga among giablihan. Atong susihon ang gidak-on sa file:

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

Gisulat ang datos, gisulayan namon nga usbon ang mga pagtugot sa file:

[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

Nakita namon nga ang datos gisulat pa, bisan kung ang among tiggamit wala’y pagtugot sa pagsulat sa file. Atong sulayan ang pagtangtang niini:

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

Asa gisulat ang datos? Ug sila ba nahisulat sa tanan? Atong susihon:

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

Oo, ang among file descriptor naglungtad gihapon ug mahimo namon kining tagdon nga file descriptor sama sa among daan nga file, mahimo namon kini basahon, klarohon ug kopyahon.

Atong tan-awon ang gidak-on sa file:

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

Ang gidak-on sa payl 19923457. Atong sulayan ang paghawan sa file:

[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

Sama sa imong nakita, ang gidak-on sa file nagkadaghan ug ang among punoan wala molihok. Atong tan-awon ang dokumentasyon sa tawag sa sistema bukas. Kung atong gamiton ang O_APPEND nga bandera sa pag-abli sa usa ka file, unya sa matag pagsulat, ang operating system magsusi sa gidak-on sa file ug mosulat sa datos ngadto sa katapusan sa file, ug buhaton kini sa atomically. Gitugotan niini ang daghang mga hilo o proseso sa pagsulat sa parehas nga file. Apan sa among code wala namo gigamit kini nga bandila. Makita nato ang lain-laing gidak-on sa file sa lsof human sa trunk kon atong ablihan ang file para sa dugang nga pagsulat, nga nagpasabot sa atong code.

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

kinahanglan natong ibutang

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

Pagsusi gamit ang "w" nga bandila

[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

ug uban sa "a" nga bandila

[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

Pagprograma nga nagdagan na nga proseso

Kasagaran ang mga programmer, sa paghimo ug pagsulay sa mga programa, mogamit sa mga debugger (pananglitan GDB) o lainlaing lebel sa pag-log in sa aplikasyon. Naghatag ang Linux og abilidad sa aktuwal nga pagsulat ug pagbag-o sa usa ka nagdagan nga programa, pananglitan, pagbag-o sa mga kantidad sa mga variable, pagbutang usa ka breakpoint, ug uban pa.

Pagbalik sa orihinal nga pangutana bahin sa dili igo nga wanang sa disk aron magsulat usa ka file, sulayan naton nga i-simulate ang problema.

Maghimo kita og usa ka file alang sa atong partition, nga atong i-mount isip usa ka bulag nga disk:

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

Maghimo kita ug file system:

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

I-mount ang file system:

[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

Naghimo kami usa ka direktoryo sa among tag-iya:

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

Atong ablihan ang file para sa pagsulat lamang sa atong programa:

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

Paglusad

[user@localhost ]$ python openforwrite.py 

Naghulat kami pipila ka segundo

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

Busa, kita adunay problema nga gihulagway sa sinugdanan niini nga artikulo. Libre nga luna 0, 100% okupar.

Nahinumdom kami nga sumala sa mga kondisyon sa buluhaton, kami naningkamot sa pagrekord sa importante kaayo nga datos nga dili mawala. Ug sa parehas nga oras, kinahanglan namon nga ayohon ang serbisyo nga wala i-restart ang proseso.

Ingnon ta nga naa pa miy disk space, pero sa lahi nga partition, pananglitan sa /home.

Atong sulayan nga "reprogram on the fly" ang atong code.

Atong tan-awon ang PID sa atong proseso, nga mikaon sa tanang disk space:

[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

Sumpaysumpaya ang proseso pinaagi sa gdb

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

Atong tan-awon ang bukas nga mga deskriptor sa file:

(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

Gitan-aw namon ang kasayuran bahin sa file descriptor number 3, nga nakapainteres kanamo

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

Hinumdomi kung unsa ang sistema sa tawag nga gihimo sa Python (tan-awa sa ibabaw kung diin kami nagdagan sa strace ug nakit-an ang bukas nga tawag), kung giproseso ang among code aron maablihan ang usa ka file, gibuhat namon ang parehas sa among kaugalingon alang sa among proseso, apan kinahanglan namon ang O_WRONLY|O_CREAT| Ang O_TRUNC bits gipulihan og numeric value. Aron mahimo kini, ablihi ang mga gigikanan sa kernel, pananglitan dinhi ug tan-awa kung unsang mga bandila ang responsable sa unsa

#define O_WRONLY 00000001
#define O_CREAT 00000100
#define O_TRUNC 00001000

Gihiusa namon ang tanan nga mga kantidad sa usa, nakuha namon ang 00001101

Gipadagan namo ang among tawag gikan sa gdb

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

Busa nakakuha kami usa ka bag-ong file descriptor nga adunay numero 4 ug usa ka bag-ong bukas nga file sa lain nga partisyon, among gisusi:

(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

Nahinumdom kami sa panig-ingnan sa pipe - kung giunsa pagbag-o sa bash ang mga deskriptor sa file, ug nahibal-an na namon ang tawag sa sistema sa dup2.

Gisulayan namon nga ilisan ang usa ka deskriptor sa file sa lain

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

Pagsusi:

(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

Gisira namo ang file descriptor 4, tungod kay wala namo kini kinahanglana:

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

Ug exit 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

Pagsusi sa bag-ong file:

[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

Sama sa imong makita, ang datos gisulat sa usa ka bag-ong file, atong susihon ang daan:

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

Wala’y nawala nga datos, nagtrabaho ang aplikasyon, gisulat ang mga troso sa usa ka bag-ong lokasyon.

Pakomplikado ta gamay sa buluhaton

Atong hunahunaon nga ang datos importante kanato, apan wala kitay disk space sa bisan asa sa mga partisyon ug dili nato makonektar ang disk.

Ang mahimo namong buhaton mao ang pag-redirect sa among data sa usa ka dapit, pananglitan ngadto sa pipe, ug sa baylo i-redirect ang data gikan sa pipe ngadto sa network pinaagi sa pipila ka programa, pananglitan netcat.
Makahimo kita og usa ka ginganlan nga tubo nga adunay mkfifo nga sugo. Maghimo kini usa ka pseudo file sa file system bisan kung wala’y libre nga wanang niini.

I-restart ang aplikasyon ug susiha:

[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

Walay disk space, apan malampuson kami nga naghimo og usa ka ginganlan nga tubo didto:

[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

Karon kinahanglan natong ibalot ang tanan nga datos nga mosulod niini nga tubo ngadto sa laing server pinaagi sa network; ang sama nga netcat angay alang niini.

Sa server remote-server.example.com among gilusad

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

Sa among problema nga server naglansad kami sa usa ka bulag nga terminal

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

Karon ang tanan nga mga datos nga natapos sa tubo awtomatikong moadto sa stdin sa netcat, nga ipadala kini sa network sa port 7777.

Ang kinahanglan namong buhaton mao ang pagsugod sa pagsulat sa among datos sa kini nga ginganlan nga tubo.

Naa na namo ang aplikasyon nga nagdagan:

[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

Sa tanan nga mga bandila, kinahanglan ra namon ang O_WRONLY tungod kay ang file naglungtad na ug dili na namon kinahanglan nga limpyohan kini.

[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

Pagsusi sa 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

Ang datos moabut, among gisusi ang problema sa 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

Ang datos naluwas, ang problema nasulbad.

Gipahimuslan nako kini nga higayon aron mangumusta sa akong mga kauban gikan sa Degiro.
Paminaw sa mga podcast sa Radio T.

Ang tanan nga labing maayo.

Isip homework, gisugyot ko nga hunahunaon nimo kung unsa ang naa sa proseso nga mga deskriptor sa file nga pusa ug matulog kung imong gipadagan ang mosunud nga mando:

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

Source: www.habr.com

Idugang sa usa ka comment