Тавсифи файл дар Linux бо мисолҳо

Боре ҳангоми мусоҳиба аз ман пурсиданд, ки агар шумо хидматеро пайдо кунед, ки бо сабаби кам шудани ҷой дар диск кор намекунад, шумо чӣ кор мекунед?

Албатта, чавоб додам, ки ин чо чиро ишгол кардааст, мебинам ва агар имкон бошад, он чоро тоза мекунам.
Сипас мусоҳиба пурсид, ки агар дар қисмат фазои холӣ набошад, аммо шумо инчунин ягон файлеро намебинед, ки тамоми ҷойро ишғол кунад?

Ба ин ман гуфтам, ки шумо ҳамеша метавонед ба дескрипторҳои файли кушода назар кунед, масалан, бо фармони lsof ва бифаҳмед, ки кадом барнома тамоми фазои дастрасро ишғол кардааст ва пас шумо метавонед мувофиқи вазъият амал кунед, вобаста ба он ки маълумот лозим аст ё не. .

Мусоҳиба дар сухани охирин сухани маро бурида, ба саволи худ илова кард: "Фарз мекунем, ки мо ба маълумот ниёз надорем, ин танҳо як сабти ислоҳ аст, аммо барнома кор намекунад, зеро он ислоҳро навишта наметавонад"?

"Хуб," ман ҷавоб додам, "мо метавонем дебагро дар конфигуратсияи барнома хомӯш кунем ва онро бозоғоз кунем."
Мусоҳиб эътироз кард: "Не, мо наметавонем барномаро аз нав оғоз кунем, мо то ҳол маълумоти муҳимро дар хотира нигоҳ дорем ва муштариёни муҳим ба худи хидмат пайвастанд, ки мо наметавонем онро дубора дубора пайваст кунем."

"Хуб," ман гуфтам, "агар мо барномаро аз нав оғоз карда натавонем ва маълумот барои мо муҳим набошад, мо метавонем ин файли кушодаро тавассути тасвири файл тоза кунем, ҳатто агар мо онро дар фармони ls набинем. дар системаи файлӣ."

Мусоҳиб хушҳол шуд, аммо ман не.

Сипас фикр кардам, ки чаро шахсе, ки дониши маро месанҷад, амиқтар намекобад? Аммо чӣ мешавад, агар маълумот дар ниҳоят муҳим бошад? Чӣ мешавад, агар мо равандро аз нав оғоз карда натавонем ва ин раванд ба системаи файлӣ дар қисмате, ки фазои холӣ надорад, менависад? Чӣ мешавад, агар мо на танҳо маълумоте, ки аллакай навишта шудааст, балки маълумотеро, ки ин раванд менависад ё навиштан мехоҳад, гум карда натавонем?

Тузик

Дар оғози касб ман кӯшиш кардам, ки як барномаи хурде созам, ки барои нигоҳ доштани маълумоти корбар лозим буд. Ва он гоҳ ман фикр кардам, ки чӣ гуна метавонам корбарро бо маълумоти ӯ мувофиқат кунам. Масалан, ман Иванов Иван Иванович дорам, вай як кадар маълумот дорад, вале бо онхо чй тавр дуст шуда метавонам? Рост гуфта метавонам, ки саги «Тузик» махз ба хамин Иван тааллук дорад. Аммо чӣ мешавад, агар ӯ номашро иваз кунад ва ба ҷои Иван, масалан, Оля шавад? Он гох маълум мешавад, ки Оля Ивановна Ивановаи мо дигар саг надорад, Тузики мо хам аз они Ивани нест. Махзани маълумоте, ки ба ҳар як корбар идентификатори (ID) нодир дода буд, ба ҳалли ин мушкилот мусоидат кард ва Тузики ман ба ин ID, ки воқеан танҳо рақами силсилавӣ буд, баста шуд. Ҳамин тариқ, соҳиби ace ID рақами 2 дошт ва дар як вақт Иван зери ин ID буд ва баъд Оля зери ҳамон ID шуд. Масъалаи одамгарй ва чорводорй амалан хал карда шуд.

Тавсифи файл

Мушкилоти файл ва барномае, ки бо ин файл кор мекунад, тақрибан яксони сагу одами мост. Фарз мекунем, ки ман файлеро бо номи ivan.txt кушодам ва ба навиштани калимаи tuzik дар он шурӯъ кардам, аммо танҳо тавонистам ҳарфи аввали “t”-ро дар файл нависам ва ин файлро касе, масалан, ба olya.txt иваз кардааст. Аммо файл бетағйир боқӣ мемонад ва ман то ҳол мехоҳам аси худро дар он сабт кунам. Ҳар дафъае, ки файл тавассути занги система кушода мешавад кушодан дар ҳама гуна забони барномасозӣ ман ID-и беназире мегирам, ки маро ба файл нишон медиҳад, ин ID тавсифкунандаи файл аст. Ва умуман муҳим нест, ки минбаъд бо ин файл чӣ кор мекунад ва кӣ мекунад, онро нест кардан мумкин аст, номи онро тағир додан мумкин аст, соҳиби онро тағир додан мумкин аст ё ҳуқуқи хондану навиштанро гирифтан мумкин аст, ман ҳоло ҳам дастрасӣ дорам ба он, зеро дар вақти кушодани файл, ман ҳуқуқи хондан ва/ё навиштани онро доштам ва ман тавонистам бо он кор кунам, яъне ман бояд ин корро идома диҳам.

Дар Linux, китобхонаи libc барои ҳар як замимаи (раванди) иҷрошаванда 3 файли тавсифкунандаро мекушояд, ки рақами 0,1,2 дорад. Маълумоти бештарро дар пайвандҳо пайдо кардан мумкин аст man stdio и мард stdout

  • Дескриптори файл 0 STDIN номида мешавад ва бо вуруди барнома алоқаманд аст
  • Дескриптори файл 1 STDOUT номида мешавад ва аз ҷониби барномаҳо барои баровардани маълумот, ба монанди фармонҳои чоп истифода мешавад
  • Дескриптори файл 2 STDERR номида мешавад ва аз ҷониби барномаҳо барои баровардани паёмҳои хатогӣ истифода мешавад.

Агар дар барномаи худ шумо ягон файлро барои хондан ё навиштан кушоед, пас эҳтимоли зиёд шумо аввалин ID-и ройгонро мегиред ва он рақами 3 хоҳад буд.

Рӯйхати дескрипторҳои файлро барои ҳама гуна раванд дидан мумкин аст, агар шумо PID-и онро бидонед.

Масалан, биёед консоли bash -ро кушоем ва ба PID-и раванди мо назар кунем

[user@localhost ]$ echo $$
15771

Дар консоли дуюм биёед кор кунем

[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

Шумо метавонед тасвири файли рақами 255-ро барои мақсадҳои ин мақола беэътиноӣ кунед; он барои эҳтиёҷоти худ аз ҷониби худи bash кушода шудааст, на китобхонаи алоқаманд.

Ҳоло ҳамаи 3 файли тавсифкунанда бо дастгоҳи терминали псевдо алоқаманданд /dev/pts, аммо мо ҳоло ҳам метавонем онҳоро идора кунем, масалан, онҳоро дар консоли дуюм иҷро кунем

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

Ва дар консоли аввал мо мебинем

[user@localhost ]$ hello world

Масир ва қубур

Шумо метавонед ин 3 файли тавсифкунандаро дар ҳама гуна раванд, аз ҷумла дар bash, масалан, тавассути қубуре, ки ду равандро мепайвандад, бекор кунед, нигаред.

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

Шумо метавонед ин фармонро худатон иҷро кунед strace - f ва бубинед, ки дар дохили он чӣ рӯй медиҳад, аммо ман ба шумо мухтасар мегӯям.

Раванди bash волидайни мо бо PID 15771 фармони моро таҳлил мекунад ва аниқ мефаҳмад, ки мо чанд фармонро иҷро кардан мехоҳем, дар ҳолати мо дутои онҳо вуҷуд доранд: гурба ва хоб. Bash медонад, ки ба он лозим аст, ки ду раванди кӯдакро эҷод кунад ва онҳоро дар як қубур муттаҳид кунад. Дар маҷмӯъ, bash ба 2 раванди кӯдак ва як қубур лозим аст.

Bash пеш аз эҷоди равандҳои кӯдак занги системаро иҷро мекунад қубур ва дескрипторҳои нави файлро дар буфери қубури муваққатӣ қабул мекунад, аммо ин буфер ҳанӯз ду раванди кӯдаки моро пайваст намекунад.

Барои раванди волидайн чунин ба назар мерасад, ки аллакай қубур мавҷуд аст, аммо то ҳол равандҳои кӯдакона вуҷуд надоранд:

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

Сипас бо истифода аз занги система Clone bash ду раванди кӯдакро эҷод мекунад ва се раванди мо чунин хоҳад буд:

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

Фаромӯш накунед, ки клон равандро дар баробари ҳамаи тавсифкунандагони файл клон мекунад, аз ин рӯ онҳо дар раванди волидайн ва кӯдакон якхела хоҳанд буд. Вазифаи раванди волидайн бо PID 15771 назорат кардани равандҳои кӯдакон аст, бинобар ин он танҳо интизори посухи кӯдакон аст.

Аз ин рӯ, ба он қубур лозим нест ва он дескрипторҳои файлии рақамҳои 3 ва 4-ро мепӯшонад.

Дар аввалин раванди bash кӯдак бо PID 9004, занги система дуп2, дескриптори файли STDOUT-и рақами 1-и моро ба тасвири файле, ки ба қубур ишора мекунад, иваз мекунад, дар ҳолати мо он рақами 3 аст. Ҳамин тариқ, ҳама чизе, ки аввалин раванди кӯдак бо PID 9004 ба STDOUT менависад, ба таври худкор дар буфери қубур хотима меёбад.

Дар раванди дуюми кӯдак бо PID 9005, bash dup2-ро барои тағир додани дескриптори файли STDIN рақами 0 истифода мебарад. Акнун ҳама чизе, ки bash дуюми мо бо PID 9005 мехонад, аз қубур хонда мешавад.

Пас аз ин, дескрипторҳои файлии рақамҳои 3 ва 4 низ дар равандҳои кӯдак баста мешаванд, зеро онҳо дигар истифода намешаванд.

Ман дидаву дониста дескриптори файли 255-ро сарфи назар мекунам; он аз ҷониби худи bash барои мақсадҳои дохилӣ истифода мешавад ва инчунин дар равандҳои кӯдакон баста мешавад.

Баъдан, дар раванди аввалини кӯдак бо PID 9004, bash занги системаро истифода мебарад exec файли иҷрошавандае, ки мо дар сатри фармон нишон додем, дар ҳолати мо он /usr/bin/cat аст.

Дар раванди дуюми кӯдак бо PID 9005, bash файли дуюми иҷрошавандаро, ки мо муайян кардем, дар ҳолати мо /usr/bin/sleep иҷро мекунад.

Даъвати системаи exec дастаки файлҳоро намепӯшад, агар онҳо дар вақти занги кушода бо парчами O_CLOEXEC кушода нашуда бошанд. Дар ҳолати мо, пас аз оғоз кардани файлҳои иҷрошаванда, ҳамаи дескрипторҳои файли ҷорӣ захира карда мешаванд.

Дар консол санҷед:

[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

Тавре ки шумо мебинед, шумораи нодири қубури мо дар ҳарду раванд яксон аст. Ҳамин тариқ, мо байни ду раванди гуногун бо як волидайн робита дорем.

Барои онҳое, ки бо зангҳои система, ки bash истифода мебарад, ошно нестанд, ман тавсия медиҳам, ки фармонҳоро тавассути strace иҷро кунед ва бубинед, ки дар дохили он чӣ рӯй медиҳад, масалан:

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

Биёед ба мушкилоти худ бо фазои ками диск баргардем ва кӯшиш кунем, ки маълумотро бидуни аз нав оғоз кардани раванд захира кунем. Биёед як барномаи хурде нависем, ки дар як сония ба диск тахминан 1 мегабайт нависад. Гузашта аз ин, агар бо ягон сабаб мо маълумотро ба диск навишта натавонистем, мо инро нодида мегирем ва кӯшиш мекунем, ки маълумотро дар як сония дубора нависем. Дар мисоле, ки ман Python-ро истифода мебарам, шумо метавонед ягон забони барномасозии дигарро истифода баред.

[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

Биёед барномаро иҷро кунем ва ба дескрипторҳои файл назар кунем

[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

Тавре ки шумо мебинед, мо 3 дескриптори файли стандартии худро дорем ва як дигаре, ки кушода будем. Биёед андозаи файлро тафтиш кунем:

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

Маълумот навишта мешавад, мо кӯшиш мекунем, ки иҷозатҳоро дар файл тағир диҳем:

[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

Мо мебинем, ки маълумот ҳоло ҳам навишта мешавад, гарчанде ки корбари мо иҷозати навиштан ба файлро надорад. Биёед кӯшиш кунем, ки онро хориҷ кунем:

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

Маълумот дар куҷо навишта шудааст? Ва оё онҳо умуман навишта шудаанд? Мо тафтиш мекунем:

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

Бале, дескриптори файли мо то ҳол вуҷуд дорад ва мо метавонем ин дескриптори файлро мисли файли кӯҳнаи худ баррасӣ кунем, мо метавонем онро хонем, тоза ва нусхабардорӣ кунем.

Биёед андозаи файлро бубинем:

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

Андозаи файл 19923457 аст. Биёед кӯшиш кунем, ки файлро тоза кунем:

[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

Тавре ки шумо мебинед, андозаи файл танҳо меафзояд ва танаи мо кор намекунад. Биёед ба ҳуҷҷатҳои занги система назар кунем кушодан. Агар ҳангоми кушодани файл парчами O_APPEND-ро истифода барем, пас бо ҳар як навиштан, системаи оператсионӣ андозаи файлро тафтиш мекунад ва маълумотро то охири файл менависад ва ин корро ба таври атомӣ анҷом медиҳад. Ин имкон медиҳад, ки риштаҳо ё равандҳои сершумор ба як файл навишта шаванд. Аммо дар коди худ мо ин парчамро истифода намебарем. Мо андозаи дигари файлро дар lsof пас аз trunk мебинем, агар мо файлро барои навиштани иловагӣ кушоем, ки ин маънои онро дорад, ки дар коди мо ба ҷои он

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

гузоштан лозим аст

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

Санҷиш бо парчами "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

ва бо парчами «а».

[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

Барномасозии раванди аллакай иҷрошаванда

Аксар вақт барномасозон ҳангоми сохтан ва санҷиши барномаҳо ислоҳкунандаҳоро (масалан GDB) ё сатҳҳои гуногуни сабти ном дар барнома истифода мебаранд. Linux қобилияти воқеан навиштан ва тағир додани барномаи аллакай иҷрошавандаро фароҳам меорад, масалан, тағир додани арзишҳои тағирёбанда, нуқтаи қатъшавӣ ва ғайра ва ғайра.

Бозгашт ба саволи аслӣ дар бораи набудани фазои диск барои навиштани файл, биёед кӯшиш кунем, ки мушкилотро тақлид кунем.

Биёед барои қисмати худ файле созем, ки онро ҳамчун диски алоҳида насб мекунем:

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

Биёед системаи файлиро эҷод кунем:

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

Системаи файлиро насб кунед:

[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

Мо бо соҳиби худ директория эҷод мекунем:

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

Биёед файлро барои навиштан танҳо дар барномаи худ кушоем:

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

Оғози

[user@localhost ]$ python openforwrite.py 

Мо чанд сония интизор мешавем

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

Ҳамин тавр, мо мушкилие дорем, ки дар аввали ин мақола тасвир шудааст. Фазои озод 0, 100% ишғол шудааст.

Мо дар хотир дорем, ки мувофиқи шартҳои супориш мо кӯшиш мекунем, ки маълумотҳои хеле муҳимро сабт кунем, ки онҳоро гум кардан мумкин нест. Ва дар айни замон, мо бояд хидматро бидуни дубора оғоз кардани раванд ислоҳ кунем.

Фарз мекунем, ки мо то ҳол фазои диск дорем, аммо дар қисмати дигар, масалан дар /home.

Биёед кӯшиш кунем, ки рамзи худро "дар парвоз дубора барномарезӣ кунем".

Биёед PID-и раванди моро бубинем, ки тамоми фазои дискро хӯрдааст:

[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

Ба раванд тавассути gdb пайваст шавед

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

Биёед ба тавсифи файлҳои кушода назар андозем:

(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

Мо ба маълумот дар бораи дескриптори файли рақами 3 назар мекунем, ки ба мо таваҷҷӯҳ дорад

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

Бо дарназардошти он, ки занги системаи Python чӣ кор мекунад (ба боло нигаред, ки мо дар куҷо strace кардем ва занги кушодро ёфтем), ҳангоми коркарди коди худ барои кушодани файл, мо худамон аз номи раванди худ ҳамин корро мекунем, аммо ба мо лозим аст O_WRONLY|O_CREAT| Битҳои O_TRUNC бо арзиши ададӣ иваз карда мешаванд. Барои ин, масалан, манбаъҳои ядроро кушоед дар ин ҷо ва бубинед, ки кадом байракхо барои чй чавобгаранд

#O_WRONLY 00000001-ро муайян кунед
#O_CREAT 00000100-ро муайян кунед
# O_TRUNC 00001000 -ро муайян кунед

Мо ҳама арзишҳоро ба як муттаҳид мекунем, мо 00001101 мегирем

Мо занги худро аз gdb иҷро мекунем

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

Ҳамин тавр, мо як дескриптори нави файл бо рақами 4 ва файли нави кушода дар қисмати дигар гирифтем, мо тафтиш мекунем:

(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

Мо мисоли қубурро дар хотир дорем - чӣ гуна bash дескрипторҳои файлро тағир медиҳад ва мо аллакай занги системаи dup2-ро омӯхтаем.

Мо кӯшиш мекунем, ки як дескриптори файлро бо дигараш иваз кунем

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

Санҷиш:

(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

Мо дескриптори файли 4-ро мепӯшем, зеро ба мо лозим нест:

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

Ва аз 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

Санҷиши файли нав:

[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

Тавре ки шумо мебинед, маълумот ба файли нав навишта шудааст, биёед файли кӯҳнаро тафтиш кунем:

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

Ягон маълумот гум намешавад, барнома кор мекунад, гузоришҳо ба ҷои нав навишта мешаванд.

Биёед, супоришро каме мураккаб кунем

Биёед тасаввур кунем, ки маълумот барои мо муҳим аст, аммо мо дар ягон қисмҳо фазои диск надорем ва дискро пайваст карда наметавонем.

Мо чӣ кор карда метавонем, ин аст, ки маълумоти моро ба ҷое, масалан ба қубур равона созем ва дар навбати худ маълумотро аз қубур ба шабака тавассути ягон барнома, масалан netcat, масир кунем.
Мо метавонем қубури номдорро бо фармони mkfifo созем. Он дар системаи файлӣ файли псевдо эҷод мекунад, ҳатто агар дар он фазои холӣ мавҷуд набошад.

Барномаро аз нав оғоз кунед ва санҷед:

[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

Фазои диск вуҷуд надорад, аммо мо дар он ҷо бомуваффақият қубури номбаршуда эҷод мекунем:

[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

Ҳоло мо бояд ҳама маълумотеро, ки ба ин қубур ворид мешаванд, тавассути шабака ба сервери дигар гузорем; ҳамон netcat барои ин мувофиқ аст.

Дар сервери remote-server.example.com мо кор мекунем

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

Дар сервери мушкили худ мо дар терминали алоҳида оғоз мекунем

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

Акнун ҳама маълумоте, ки дар қубур ба охир мерасад, ба таври худкор ба stdin дар netcat мегузарад, ки онро ба шабака дар порти 7777 мефиристад.

Мо бояд танҳо ба навиштани маълумоти мо ба ин қубури номбаршуда шурӯъ кунем.

Мо аллакай барномаро иҷро мекунем:

[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

Аз ҳамаи парчамҳо, ба мо танҳо O_WRONLY лозим аст, зеро файл аллакай мавҷуд аст ва ба мо лозим нест, ки онро тоза кунем

[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

Санҷиши сервери дурдаст remote-server.example.com

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

Маълумот омада истодааст, мо сервери мушкилотро тафтиш мекунем

[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

Маълумот захира карда мешавад, мушкилот ҳал карда мешавад.

Ман аз фурсат истифода бурда, ба ҳамкасбони худ аз Дегиро салом мегӯям.
Подкастҳои Radio-T-ро гӯш кунед.

Ба ҳама хуб.

Ҳамчун вазифаи хонагӣ, ман ба шумо тавсия медиҳам, ки дар бораи он фикр кунед, ки агар шумо фармони зеринро иҷро кунед, дар тасвири файли гурба ва хоб чӣ хоҳад буд:

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

Манбаъ: will.com

Илова Эзоҳ