Deskriptor file dina Linux sareng conto

Sakali, dina wawancara, kuring ditaroskeun naon anu anjeun laksanakeun upami anjeun mendakan jasa anu rusak kusabab kanyataan yén disk parantos kaluar tina rohangan?

Tangtosna, kuring ngawaler yén kuring bakal ningali naon anu dilakukeun ku tempat ieu sareng, upami mungkin, kuring bakal ngabersihan tempat éta.
Teras ngawawancara naros, kumaha upami teu aya rohangan bébas dina partisi, tapi anjeun ogé henteu ningali file anu bakal nyandak sadaya rohangan?

Pikeun ieu, kuring nyarios yén anjeun salawasna tiasa ningali deskriptor file anu kabuka, contona, kalayan paréntah lsof sareng ngartos aplikasi mana anu nyandak sadaya rohangan anu sayogi, teras anjeun tiasa ngalakukeun dumasar kana kaayaan, gumantung kana naha data diperyogikeun. .

The interviewer interrupted kuring dina kecap panungtungan, nambahan kana patarosan na: "Anggap we teu butuh data, éta ngan log debug, tapi aplikasi nu handap sabab teu bisa nulis debug"?

"Ok," jawab kuring, "urang tiasa mareuman debugging dina konfigurasi aplikasi sareng ngabalikan deui."
Wawancara bantahan: "Henteu, kami henteu tiasa ngabalikan deui aplikasi, kami masih gaduh data penting dina mémori, sareng klien penting disambungkeun kana jasa éta sorangan, anu kami henteu tiasa maksakeun nyambungkeun deui."

"Oke," ceuk kuring, "lamun urang teu bisa ngabalikan deui aplikasi tur urang teu paduli ngeunaan data, lajeng urang ngan bisa mupus file kabuka ieu via descriptor file, sanajan urang teu ningali dina ls. paréntah dina sistem file".

Wawancara éta wareg, tapi kuring henteu.

Teras kuring mikir, naha jalma anu nguji pangaweruh kuring henteu ngagali langkung jero? Tapi kumaha lamun data penting sanggeus kabeh? Kumaha upami urang henteu tiasa ngabalikan deui prosésna, sareng dina waktos anu sami prosés ieu nyerat kana sistem file dina partisi anu henteu ngagaduhan rohangan bébas? Kumaha lamun urang teu bisa leungit teu ngan data geus ditulis, tapi ogé data nu prosés ieu nulis atawa nyoba nulis?

Tuzik

Dina awal karir abdi, abdi nyobian nyieun hiji aplikasi leutik nu diperlukeun pikeun nyimpen informasi ngeunaan pamaké. Teras kuring mikir, kumaha kuring tiasa cocog sareng pangguna kana datana. Contona, kuring boga Ivanov Ivan Ivanovich, sarta anjeunna boga sababaraha data, tapi kumaha carana sangkan babaturan sareng maranehna? Abdi tiasa langsung nunjuk kaluar yén anjing ngaranna "Tuzik" milik Ivan sarua. Tapi kumaha upami anjeunna ngarobih namina sareng tinimbang Ivan janten, contona, Olya? Mangka tétéla yén Olya Ivanovna Ivanova urang moal deui boga anjing, sarta Tuzik urang masih bakal milik Ivan non-existent. database mantuan ngajawab masalah ieu, nu masihan unggal pamaké identifier unik (ID), sarta Tuzik abdi ieu dihijikeun ka ID ieu, nu, kanyataanna, éta ngan hiji angka serial. Ku kituna, nu boga tuzik éta kalayan ID nomer 2, sarta di sawatara titik waktos Ivan handapeun ID ieu, lajeng Olya janten handapeun ID sarua. Masalah umat manusa sareng peternakan sacara praktis direngsekeun.

Deskriptor file

Masalah file sareng program anu tiasa dianggo sareng file ieu sami sareng anjing urang sareng manusa. Anggap kuring muka file ngaranna ivan.txt sarta mimiti nulis kecap tuzik kana eta, tapi junun nulis ngan hurup kahiji "t" kana file, sarta file ieu diganti ku batur, contona, mun olya.txt. Tapi filena sami sareng kuring masih hoyong nyerat Ace kuring. Unggal waktos anjeun muka file sareng telepon sistem kabuka dina sagala basa programming, kuring meunang ID unik nu nunjuk kuring ka file, ID ieu descriptor file. Sareng henteu masalah pisan naon sareng saha anu salajengna sareng file ieu, éta tiasa dihapus, tiasa diganti namina, tiasa ngarobih juragan atanapi ngahapus hak maca sareng nyerat, kuring masih bakal ngagaduhan aksés kana éta, sabab dina waktos muka file kuring ngagaduhan hak maca sareng / atanapi nyerat éta sareng kuring junun ngamimitian damel sareng éta, anu hartosna kuring kedah teras-terasan ngalakukeunana.

Dina Linux, perpustakaan libc muka 3 file deskriptor pikeun tiap aplikasi jalan (prosés), kalawan angka 0,1,2. Inpo nu leuwih lengkep bisa kapanggih dina Tumbu lalaki stdio и lalaki stdout

  • File descriptor 0 disebut STDIN sarta pakait sareng input aplikasi.
  • Deskriptor file 1 disebut STDOUT sareng dianggo ku aplikasi kaluaran sapertos paréntah citak.
  • Deskriptor file 2 dingaranan STDERR sareng dianggo ku aplikasi pikeun kaluaran pesen kasalahan.

Upami dina program anjeun anjeun muka file naon waé pikeun maca atanapi nyerat, maka paling dipikaresep anjeun bakal nampi ID gratis anu munggaran sareng éta nomer 3.

Anjeun tiasa ningali daptar deskriptor file pikeun prosés naon waé upami anjeun terang PID na.

Salaku conto, hayu urang muka konsol nganggo bash sareng ningali PID tina prosés urang

[user@localhost ]$ echo $$
15771

Dina konsol kadua, ngajalankeun

[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

Anjeun tiasa aman malire descriptor file kalawan nomer 255 dina kerangka artikel ieu, éta dibuka pikeun kaperluan anjeun ku bash sorangan, teu ku perpustakaan numbu.

Ayeuna sadaya 3 file deskriptor pakait sareng alat pseudo-terminal /dev/pts, Tapi urang masih bisa ngamanipulasi aranjeunna, contona, ngajalankeun dina konsol kadua

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

Sareng dina konsol munggaran urang bakal ningali

[user@localhost ]$ hello world

Alihan sareng Pipa

Anjeun tiasa sacara gampil nimpa 3 file deskriptor ieu dina prosés naon waé, kalebet dina bash, contona, ngalangkungan pipa (pipa) anu nyambungkeun dua prosés, tingali

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

Anjeun tiasa ngajalankeun paréntah ieu sorangan kalawan jalur -f tur tingal kumaha lumangsung di jero, tapi kuring bakal nyieun pondok.

Prosés bash indungna urang sareng PID 15771 parses paréntah urang sareng ngartos persis sabaraha paréntah anu urang hoyong jalankeun, dina hal urang aya dua di antarana: ucing sareng bobo. Bash terang yén éta kedah nyiptakeun dua prosés anak, sareng ngahijikeun kana hiji pipa. Dina total, bash peryogi 2 prosés anak sareng hiji pipa.

Sateuacan nyiptakeun prosés anak, bash ngajalankeun telepon sistem pipah sarta narima descriptors file anyar dina panyangga pipe samentara, tapi panyangga ieu henteu acan nyambungkeun dua prosés anak urang sagala cara.

Pikeun prosés indungna, sigana pipana parantos aya, tapi teu acan aya prosés anak:

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

Lajeng ngagunakeun panggero sistem clone bash nyiptakeun dua prosés anak, sareng tilu prosés urang bakal siga kieu:

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

Ulah hilap yén clone clone prosés sareng sadaya deskriptor file, ku kituna aranjeunna sami dina prosés indung sareng dina budak. Tugas prosés indungna sareng PID 15771 nyaéta ngawas prosés anak, janten ngan ngantosan tanggapan ti murangkalih.

Ku alatan éta, anjeunna henteu peryogi pipa, sareng anjeunna nutup deskriptor file kalayan nomer 3 sareng 4.

Dina prosés anak bash munggaran kalayan PID 9004, nelepon sistem dup2, Ngarobah kami STDOUT file descriptor angka 1 ka file descriptor ngarah ka pipa, bisi urang éta angka 3. Ku kituna, sagalana yén prosés anak munggaran kalayan PID 9004 nyerat STDOUT bakal otomatis digolongkeun kana panyangga pipe.

Dina prosés anak kadua jeung PID 9005, bash dup2s file ka STDIN descriptor angka 0. Ayeuna sagalana yén bash kadua urang jeung PID 9005 bakal maca bakal maca tina pipe nu.

Saatos éta, deskriptor file kalayan nomer 3 sareng 4 ogé ditutup dina prosés anak, sabab henteu dianggo deui.

Kuring ngahaja malire file descriptor 255, éta dipaké internal ku bash sorangan sarta ogé bakal ditutup dina prosés anak.

Salajengna, dina prosés anak munggaran kalayan PID 9004, bash dimimitian ku panggero sistem exec file executable nu urang dieusian dina garis paréntah, bisi urang éta /usr/bin/cat.

Dina prosés anak kadua sareng PID 9005, bash ngajalankeun eksekusi kadua anu kami jelaskeun, dina kasus urang /usr/bin/sleep.

Sauran sistem exec henteu nutup deskriptor file kecuali dibuka kalayan bandéra O_CLOEXEC dina waktos telepon kabuka dilaksanakeun. Dina kasus urang, saatos ngajalankeun file anu tiasa dieksekusi, sadaya deskriptor file ayeuna bakal disimpen.

Pariksa dina konsol:

[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

Sakumaha anjeun tiasa tingali, jumlah unik pipa kami sami dina duanana prosés. Ku kituna, urang boga sambungan antara dua prosés béda jeung indungna sarua.

Pikeun anu henteu wawuh sareng sistem panggero anu dianggo ku bash, kuring nyarankeun pisan ngajalankeun paréntah ngaliwatan strace sareng ningali naon anu lumangsung di jero, contona, sapertos kieu:

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

Hayu urang balik deui ka masalah urang sareng kaluar tina rohangan disk sareng nyobian nyimpen data tanpa ngamimitian deui prosésna. Hayu urang nyerat program leutik anu bakal nyerat kana disk sakitar 1 megabyte per detik. Sumawona, upami kusabab sababaraha alesan urang henteu tiasa nyerat data kana disk, urang ngan saukur bakal malire ieu sareng nyobian nyerat data deui sadetik. Dina conto anu kuring nganggo Python, anjeun tiasa nganggo basa pamrograman anu sanés.

[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

Jalankeun program sareng tingali deskriptor 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

Sakumaha anjeun tiasa tingali, kami gaduh 3 deskriptor file standar sareng hiji deui anu kami parantos dibuka. Hayu urang pariksa ukuran file:

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

data ditulis, urang nyoba ngarobah hak kana 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

Kami ningali yén data masih ditulis, sanaos pangguna kami henteu ngagaduhan hak nyerat kana file. Hayu urang cobian ngahapus:

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

Dimana data ditulis? Jeung maranéhna ditulis pisan? Urang pariksa:

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

Leres, deskriptor file urang masih aya, sareng urang tiasa damel sareng deskriptor file ieu sapertos file lami urang, urang tiasa maca, ngabersihan sareng nyalin.

Tingali ukuran file:

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

Ukuran koropakna 19923457. Nyobian mupus filena:

[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

Sakumaha anjeun tiasa tingali, ukuran file ukur ningkat sareng batang kami henteu jalan. Hayu urang giliran dokuméntasi dina panggero sistem kabuka. Upami urang nganggo bandéra O_APPEND nalika muka file, teras unggal nyerat, sistem operasi mariksa ukuran file sareng nyerat data dugi ka tungtung file, sareng ngalakukeunana sacara atom. Hal ieu ngamungkinkeun sababaraha threads atawa prosés nulis ka file sarua. Tapi dina kode urang kami henteu nganggo bandéra ieu. Urang tiasa ningali ukuran file anu béda dina lsof saatos batang ngan upami urang muka file pikeun nyerat, anu hartosna dina kode urang, tinimbang

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

urang kudu nempatkeun

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

Mariksa kalayan bendera "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

sarta kalawan "a" bandéra

[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

Programing prosés anu parantos jalan

Seringna, nalika nyiptakeun sareng nguji program, programer nganggo debuggers (contona, GDB) atanapi sababaraha tingkat logging dina aplikasi. Linux nyayogikeun kamampuan pikeun leres-leres nyerat sareng ngarobih program anu parantos dijalankeun, sapertos ngarobih nilai-nilai variabel, netepkeun titik putus, sareng saterasna.

Balik deui ka patarosan aslina ngeunaan kurangna spasi disk pikeun nulis file, hayu urang coba mun simulate masalah.

Hayu urang ngadamel file pikeun partisi urang, anu bakal dipasang salaku drive anu misah:

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

Hayu urang nyieun sistem file:

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

Hayu urang pasang sistem file:

[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

Jieun diréktori jeung nu boga urang:

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

Hayu urang buka file pikeun nulis ngan dina program urang:

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

Ngaluncurkeun

[user@localhost ]$ python openforwrite.py 

Ngadagoan sababaraha detik

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

Janten, urang ngagaduhan masalah anu dijelaskeun dina awal tulisan ieu. rohangan bébas 0, dijajah 100%.

Urang émut yén dumasar kana kaayaan masalah, urang nyobian ngarékam data anu penting pisan anu teu tiasa leungit. Sareng dina ngalakukeunana, urang kedah ngalereskeun jasa tanpa ngamimitian deui prosésna.

Hayu urang nyebutkeun urang masih boga spasi disk, tapi dina partisi béda, contona, dina / imah.

Hayu urang coba "reprogram on the fly" kode urang.

Kami ningali PID tina prosés kami, anu ngahakan sadaya rohangan disk:

[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

Nyambungkeun ka prosés sareng gdb

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

Kami ningali deskriptor file kabuka:

(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

Kami ningali inpormasi ngeunaan deskriptor file kalayan nomer 3, anu dipikaresep ku urang

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

Terus di pikiran naon sistem nelepon Python (tingali luhureun dimana urang lumpat strace sarta kapanggih hiji panggero kabuka), bari ngolah kode urang pikeun muka file, urang ngalakukeun sami sorangan atas nama prosés urang, tapi urang kudu O_WRONLY | O_CREAT | O_TRUNC bit diganti ku nilai numerik. Jang ngalampahkeun ieu, buka sumber kernel, contona di dieu tur tingal nu bandéra jawab naon

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

Urang ngagabungkeun sakabeh nilai kana hiji, urang meunang 00001101

Ngajalankeun telepon kami ti gdb

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

Janten kami ngagaduhan deskriptor file énggal kalayan nomer 4 sareng file kabuka énggal dina partisi anu sanés, pariksa:

(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

Urang émut conto sareng pipa - kumaha bash ngarobih deskriptor file, sareng parantos diajar sistem panggero dup2.

Nyobian ngagentos hiji deskriptor file sareng anu sanés

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

Kami cek:

(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

Tutup deskriptor file 4, sabab kami henteu peryogi:

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

Sareng kaluar 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

Mariksa file anyar:

[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

Sakumaha anjeun tiasa tingali, data ditulis kana file anyar, urang pariksa nu heubeul:

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

Data henteu leungit, aplikasi jalan, log anu ditulis ka lokasi anyar.

Hayu urang nyieun hal saeutik leuwih hese

Bayangkeun yén data penting pikeun kami, tapi kami henteu ngagaduhan rohangan disk dina partisi mana waé sareng kami henteu tiasa nyambungkeun disk.

Anu tiasa urang laksanakeun nyaéta alihan data urang ka mana waé, contona, kana pipa, sareng alihan data tina pipa ka jaringan ngalangkungan sababaraha program, sapertos netcat.
Urang tiasa ngadamel pipa anu namina nganggo paréntah mkfifo. Éta bakal nyiptakeun file pseudo dina sistem file, sanaos henteu aya rohangan bébas dina éta.

Balikan deui aplikasi sareng pariksa:

[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

Henteu aya rohangan disk, tapi kami suksés nyiptakeun pipa anu namina di dinya:

[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

Ayeuna urang kedah kumaha waé mungkus sadaya data anu asup kana pipa ieu ka server anu sanés ngalangkungan jaringan, netcat anu sami cocog pikeun ieu.

Dina server remote-server.example.com, jalankeun

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

Dina server masalah urang, ngajalankeun dina terminal misah

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

Ayeuna sadaya data anu asup kana pipa bakal otomatis angkat ka stdin di netcat, anu bakal dikirim ka jaringan dina port 7777.

Sadaya anu urang kedah laksanakeun nyaéta ngamimitian nyerat data kami kana pipa anu namina ieu.

Kami parantos ngagaduhan aplikasi anu ngajalankeun:

[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

Tina sadaya umbul, urang ngan ukur peryogi O_WRONLY sabab filena parantos aya sareng urang henteu kedah mupus éta

[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

Mariksa server jauh remote-server.example.com

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

Data datang, urang pariksa server masalah

[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

Data disimpen, masalahna direngsekeun.

Kuring nyandak kasempetan ieu pikeun ngucapkeun salam ka kolega kuring ti Degiro.
Dengekeun podcast Radio-T.

Sadayana saé.

Salaku pagawean di imah, kuring ngajukeun mikir ngeunaan naon anu bakal aya dina deskriptor file tina prosés ucing sareng bobo upami anjeun ngajalankeun paréntah di handap ieu:

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

sumber: www.habr.com

Tambahkeun komentar