strace bilan dasturiy ta'minotni joylashtirishni disk raskadrovka

strace bilan dasturiy ta'minotni joylashtirishni disk raskadrovka

Mening kundalik ishim asosan dasturiy ta'minotni joylashtirishdan iborat, ya'ni men ko'p vaqtimni quyidagi savollarga javob berishga sarflayman:

  • Ushbu dastur ishlab chiquvchi uchun ishlaydi, lekin men uchun emas. Nega?
  • Kecha bu dastur men uchun ishladi, lekin bugun u emas. Nega?

Bu nosozliklarni tuzatishning bir turi bo'lib, oddiy dasturiy ta'minotni tuzatishdan biroz farq qiladi. Muntazam disk raskadrovka kod mantig'i bilan bog'liq, lekin joylashtirishni tuzatish kod va atrof-muhit o'rtasidagi o'zaro ta'sirga tegishli. Muammoning ildizi mantiqiy xato bo'lsa ham, hamma narsa bir mashinada emas, balki boshqa mashinada ishlaydi, bu muammo qandaydir tarzda muhitda ekanligini anglatadi.

Shunday qilib, odatdagidek disk raskadrovka vositalari o'rniga gdb Menda nosozliklarni tuzatish uchun boshqa vositalar to'plami bor. Va muammoni hal qilish uchun eng sevimli vositam "Nega bu dastur men uchun ishlamaydi?" chaqirdi zo'riqish.

strace nima?

zo'riqish "tizimli qo'ng'iroqlarni kuzatish" uchun vositadir. U dastlab Linux uchun yaratilgan, ammo bir xil disk raskadrovka fokuslari boshqa tizimlar uchun vositalar bilan ham amalga oshirilishi mumkin (DTraktsiya yoki ktrace).

Asosiy dastur juda oddiy. Siz shunchaki har qanday buyruq bilan strace-ni ishga tushirishingiz kerak va u barcha tizim qo'ng'iroqlarini o'chiradi (garchi birinchi navbatda uni o'zingiz o'rnatishingiz kerak bo'ladi. zo'riqish):

$ strace echo Hello
...Snip lots of stuff...
write(1, "Hellon", 6)                  = 6
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Ushbu tizim chaqiruvlari nima? Bu operatsion tizim yadrosi uchun API kabi narsa. Bir vaqtlar dasturiy ta'minot o'zi ishlaydigan apparatga to'g'ridan-to'g'ri kirish imkoniyatiga ega edi. Agar, masalan, ekranda biror narsani ko'rsatish kerak bo'lsa, u portlar yoki video qurilmalar uchun xotira xaritasi bilan o'ynadi. Ko'p vazifali kompyuter tizimlari mashhur bo'lganda, turli xil ilovalar apparat ustida kurashayotganda tartibsizlik hukm surdi. Bitta dasturdagi xatolar butun tizim bo'lmasa, boshqalarni buzishi mumkin. Keyin CPUda imtiyoz rejimlari (yoki "ring himoyasi") paydo bo'ldi. Yadro eng imtiyozli bo'ldi: u apparatga to'liq kirish huquqiga ega bo'lib, tizim qo'ng'iroqlari orqali apparat bilan o'zaro ishlash uchun yadrodan kirishni so'rashi kerak bo'lgan kamroq imtiyozli ilovalarni tug'dirdi.

Ikkilik darajada tizim chaqiruvi oddiy funktsiya chaqiruvidan biroz farq qiladi, lekin ko'pchilik dasturlar standart kutubxonada o'ramdan foydalanadi. Bular. POSIX C standart kutubxonasida funksiya chaqiruvi mavjud yozish (), unda tizim chaqiruvi uchun barcha arxitekturaga xos kod mavjud yozish.

strace bilan dasturiy ta'minotni joylashtirishni disk raskadrovka

Qisqacha aytganda, dastur va uning muhiti (kompyuter tizimlari) o'rtasidagi har qanday o'zaro ta'sir tizim chaqiruvlari orqali amalga oshiriladi. Shuning uchun, dasturiy ta'minot bir mashinada ishlayotgan bo'lsa, lekin boshqasida emas, tizim qo'ng'iroqlarini kuzatish natijalarini ko'rib chiqish yaxshi bo'lar edi. Aniqroq qilib aytganda, bu erda tizim chaqiruv izi yordamida tahlil qilinishi mumkin bo'lgan odatiy nuqtalar ro'yxati:

  • Konsol kiritish-chiqarish
  • Tarmoq kiritish-chiqarish
  • Fayl tizimiga kirish va fayl kiritish/chiqarish
  • Jarayon oqimining ishlash muddatini boshqarish
  • Past darajadagi xotira boshqaruvi
  • Muayyan qurilma drayverlariga kirish

Strace-dan qachon foydalanish kerak?

Nazariy jihatdan, zo'riqish foydalanuvchi maydonidagi har qanday dastur bilan ishlatiladi, chunki foydalanuvchi maydonidagi har qanday dastur tizim qo'ng'iroqlarini amalga oshirishi kerak. U kompilyatsiya qilingan, past darajadagi dasturlar bilan samaraliroq ishlaydi, lekin agar siz ish vaqti va tarjimondan qo'shimcha shovqinni bartaraf etsangiz, Python kabi yuqori darajali tillar bilan ham ishlaydi.

Barcha ulug'vorligida zo'riqish bir mashinada yaxshi ishlaydigan dasturiy ta'minotni disk raskadrovka qilish paytida o'zini namoyon qiladi, lekin birdaniga boshqasida ishlashni to'xtatadi, fayllar, ruxsatlar yoki ba'zi buyruqlarni yoki boshqa narsalarni bajarishga muvaffaqiyatsiz urinishlar haqida noaniq xabarlarni ishlab chiqaradi... Afsuski, lekin unday emas. sertifikatni tekshirish xatolari kabi yuqori darajadagi muammolar bilan juda yaxshi kombinatsiyalangan. Odatda bu kombinatsiyani talab qiladi zo'riqishba'zan ltrace va undan yuqori darajadagi vositalar (masalan, buyruq qatori vositasi openssl sertifikatni disk raskadrovka qilish).

Misol sifatida biz mustaqil serverdan foydalanamiz, lekin tizim qo'ng'iroqlarini kuzatish ko'pincha murakkabroq joylashtirish platformalarida amalga oshirilishi mumkin. Siz faqat to'g'ri vositalarni tanlashingiz kerak.

Nosozliklarni tuzatishning oddiy misoli

Aytaylik, siz ajoyib server dasturini ishga tushirishni xohlaysiz foo va shu bilan yakun topasiz:

$ foo
Error opening configuration file: No such file or directory

Ko'rinishidan, u siz yozgan konfiguratsiya faylini topa olmadi. Buning sababi, ba'zida paket menejerlari dasturni kompilyatsiya qilganda, ular kutilgan fayl joylarini bekor qiladilar. Va agar siz bitta tarqatish uchun o'rnatish qo'llanmasiga amal qilsangiz, boshqasida siz kutgan joydan butunlay boshqacha fayllarni topasiz. Agar xato xabari konfiguratsiya faylini qayerdan izlash kerakligini aytsa, muammo bir necha soniya ichida hal qilinishi mumkin, ammo unday emas. Xo'sh, qaerga qarash kerak?

Agar manba kodiga kirish imkoningiz bo'lsa, uni o'qib, hamma narsani bilib olishingiz mumkin. Yaxshi zaxira rejasi, lekin eng tezkor yechim emas. Siz kabi bosqichma-bosqich tuzatuvchiga murojaat qilishingiz mumkin gdb va dastur nima qilishini ko'ring, lekin atrof-muhit bilan o'zaro aloqani ko'rsatish uchun maxsus ishlab chiqilgan vositadan foydalanish ancha samaraliroq: zo'riqish.

xulosa zo'riqish ortiqcha bo'lib tuyulishi mumkin, ammo yaxshi xabar shundaki, ularning aksariyatini e'tiborsiz qoldirish mumkin. Ko'pincha kuzatuv natijalarini alohida faylga saqlash uchun -o operatoridan foydalanish foydalidir:

$ strace -o /tmp/trace foo
Error opening configuration file: No such file or directory
$ cat /tmp/trace
execve("foo", ["foo"], 0x7ffce98dc010 /* 16 vars */) = 0
brk(NULL)                               = 0x56363b3fb000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=25186, ...}) = 0
mmap(NULL, 25186, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2f12cf1000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF2113 3 > 1 260A2 "..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1824496, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2f12cef000
mmap(NULL, 1837056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2f12b2e000
mprotect(0x7f2f12b50000, 1658880, PROT_NONE) = 0
mmap(0x7f2f12b50000, 1343488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f2f12b50000
mmap(0x7f2f12c98000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16a000) = 0x7f2f12c98000
mmap(0x7f2f12ce5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7f2f12ce5000
mmap(0x7f2f12ceb000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2f12ceb000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7f2f12cf0500) = 0
mprotect(0x7f2f12ce5000, 16384, PROT_READ) = 0
mprotect(0x56363b08b000, 4096, PROT_READ) = 0
mprotect(0x7f2f12d1f000, 4096, PROT_READ) = 0
munmap(0x7f2f12cf1000, 25186)           = 0
openat(AT_FDCWD, "/etc/foo/config.json", O_RDONLY) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
brk(NULL)                               = 0x56363b3fb000
brk(0x56363b41c000)                     = 0x56363b41c000
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x8), ...}) = 0
write(3, "Error opening configuration file"..., 60) = 60
close(3)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

Chiqishning taxminan butun birinchi sahifasi zo'riqish - Bu odatda ishga tushirish uchun past darajadagi tayyorgarlikdir. (Ko'p qo'ng'iroqlar mmap, himoya qilish, kviling past darajadagi xotirani aniqlash va dinamik kutubxonalarni ko'rsatish kabi narsalar uchun.) Aslida, chiqishni tuzatish paytida zo'riqish Oxiridan o'qigan ma'qul. Quyida tanlov bo'ladi yozish, bu xato xabarini ko'rsatadi. Biz yuqoriga qaraymiz va birinchi noto'g'ri tizim chaqiruvi - qo'ng'iroqni ko'ramiz ochish, bu xatolikka olib keladi ENOENT (“fayl yoki katalog topilmadi”) ochishga harakat qilmoqda /etc/foo/config.json. Bu erda konfiguratsiya fayli bo'lishi kerak.

Bu shunchaki misol edi, lekin men foydalanadigan vaqtning 90 foizini aytaman zo'riqish, bundan ko'ra qiyinroq narsa yo'q. Quyida to'liq bosqichma-bosqich disk raskadrovka qo'llanmasi keltirilgan:

  • Dasturdan tizim xatosi haqidagi noaniq xabar tufayli xafa bo'ling
  • bilan dasturni qayta ishga tushiring zo'riqish
  • Kuzatuv natijalarida xato xabarini toping
  • Birinchi muvaffaqiyatsiz tizim qo'ng'irog'iga tegmaguningizcha yuqoriga chiqing

4-bosqichdagi tizim chaqiruvi nima noto'g'ri bo'lganini ko'rsatishi mumkin.

Maslahatlar

Sizga yanada murakkab disk raskadrovka misolini ko'rsatishdan oldin, men sizga samarali foydalanish uchun bir nechta fokuslarni ko'rsataman zo'riqish:

odam sizning do'stingiz

Ko'pgina *nix tizimlarida yadroga tizim qo'ng'iroqlarining to'liq ro'yxatini ishga tushirish orqali olish mumkin odam tizimi chaqiradi. kabi narsalarni ko'rasiz brk(2), ya'ni ko'proq ma'lumotni ishga tushirish orqali olish mumkin odam 2 brk.

Kichik tirgak: odam 2 vilkalar menga qobiq uchun sahifani ko'rsatadi vilka () в GNU libc, ma'lum bo'lishicha, chaqiruv orqali amalga oshiriladi klon(). Qo'ng'iroq semantikasi Vilkalar yordamida dastur yozsangiz bir xil bo'lib qoladi vilka (), va kuzatuvni bajaring - hech qanday qo'ng'iroqni topa olmayapman Vilkalar, ularning o'rniga bo'ladi klon(). Agar siz manbani chiqish bilan solishtirishni boshlasangiz, bunday tırmıklar sizni chalkashtirib yuboradi zo'riqish.

Chiqishni faylga saqlash uchun -o dan foydalaning

zo'riqish keng ko'lamli natijalarni yaratishi mumkin, shuning uchun ko'pincha kuzatuv natijalarini alohida fayllarda saqlash foydali bo'ladi (yuqoridagi misolda bo'lgani kabi). Bu, shuningdek, dastur chiqishi bilan chiqishni chalkashtirib yubormaslikka yordam beradi zo'riqish konsolda.

Ko'proq argument ma'lumotlarini ko'rish uchun -s dan foydalaning

Yuqoridagi misol izida xato xabarining ikkinchi yarmi ko'rsatilmaganini payqagan bo'lishingiz mumkin. Chunki zo'riqish sukut bo'yicha string argumentining faqat birinchi 32 baytini ko'rsatadi. Agar ko'proq ko'rishni istasangiz, shunga o'xshash narsani qo'shing -128 qo'ng'iroqqa zo'riqish.

-y fayllarni, rozetkalarni va hokazolarni kuzatishni osonlashtiradi.

"Hammasi fayl" degani *nix tizimlari fayl identifikatorlari yordamida barcha kiritish-chiqarishlarni amalga oshiradi, xoh bu faylga, tarmoqqa yoki protsesslararo quvurlarga tegishli bo'ladimi. Bu dasturlash uchun qulay, biroq umumiy ko'rinishni ko'rganingizda, nima sodir bo'layotganini kuzatishni qiyinlashtiradi o'qib и yozish tizim qo'ng'iroqlarini kuzatish natijalarida.

Operator qo'shish orqali -y, siz majbur qilasiz zo'riqish chiqishdagi har bir fayl identifikatoriga nimaga ishora qiluvchi eslatma bilan izohlang.

-p** bilan allaqachon ishlayotgan jarayonga biriktiring

Quyidagi misoldan ko'rib turganingizdek, ba'zida siz allaqachon ishlayotgan dasturni kuzatishingiz kerak bo'ladi. Agar u 1337 jarayon sifatida ishlayotganligi ma'lum bo'lsa (masalan, chiqishdan ps), keyin uni quyidagicha kuzatishingiz mumkin:

$ strace -p 1337
...system call trace output...

Sizga ildiz huquqlari kerak bo'lishi mumkin.

Bolalar jarayonlarini kuzatish uchun -f dan foydalaning

zo'riqish Odatiy bo'lib, u faqat bitta jarayonni kuzatadi. Agar bu jarayon bola jarayonlarini tug'dirsa, u holda bola jarayonini yaratish uchun tizim qo'ng'irog'i ko'rinadi, lekin bola jarayonining tizim qo'ng'iroqlari ko'rsatilmaydi.

Agar xatolik bola jarayonda deb hisoblasangiz, bayonotdan foydalaning -f, bu uni kuzatish imkonini beradi. Buning salbiy tomoni shundaki, chiqish sizni yanada ko'proq chalkashtirib yuboradi. Qachon zo'riqish bir jarayon yoki bitta ipni kuzatadi, u qo'ng'iroq voqealarining yagona oqimini ko'rsatadi. Bir vaqtning o'zida bir nechta jarayonlarni kuzatganda, siz qo'ng'iroqning boshlanishini xabar bilan to'xtatilganini ko'rishingiz mumkin , keyin - boshqa ijro shoxlari uchun bir nechta qo'ng'iroqlar va shundan keyingina - birinchisining oxiri <…fookall qayta tiklandi>. Yoki barcha kuzatuv natijalarini operator yordamida ham turli fayllarga ajrating -ff (tafsilotlar etakchilik haqida zo'riqish).

-e yordamida izlarni filtrlang

Ko'rib turganingizdek, iz natijasi barcha mumkin bo'lgan tizim qo'ng'iroqlarining haqiqiy to'plamidir. Bayroq -e Siz izni filtrlashingiz mumkin (qarang etakchilik haqida zo'riqish). Asosiy afzallik shundaki, to'liq izni bajarishdan ko'ra filtrlangan izni bajarish tezroq grep`da. Rostini aytsam, men deyarli har doim qiziqmayman.

Hamma xatolar yomon emas

Oddiy va keng tarqalgan misol - bir vaqtning o'zida bir nechta joyda faylni qidiradigan dastur, masalan, bajariladigan faylni o'z ichiga olgan katalogni qidiradigan qobiq:

$ strace sh -c uname
...
stat("/home/user/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/bin/uname", {st_mode=S_IFREG|0755, st_size=39584, ...}) = 0
...

"Xato haqida xabar berishdan oldin oxirgi muvaffaqiyatsiz so'rov" kabi evristikalar tegishli xatolarni topishda yaxshi. Qanday bo'lmasin, eng oxiridan boshlash mantiqan to'g'ri.

C dasturlash bo'yicha darsliklar tizim qo'ng'iroqlarini tushunishga yordam beradi.

C kutubxonalariga standart qo'ng'iroqlar tizim qo'ng'iroqlari emas, balki faqat nozik sirt qatlami. Shunday qilib, agar siz hech bo'lmaganda Cda qanday va nima qilishni tushunsangiz, tizim qo'ng'irog'i izi natijalarini tushunishingiz osonroq bo'ladi. Misol uchun, siz tarmoq tizimlariga qo'ng'iroqlarni tuzatishda muammoga duch kelasiz, xuddi shu klassikaga qarang Tarmoq dasturlash bo'yicha Bija qo'llanmasi.

Keyinchalik murakkab disk raskadrovka misoli

Men allaqachon aytdimki, oddiy disk raskadrovka misoli men ishlayotganda asosan nima bilan shug'ullanishim kerakligiga misoldir zo'riqish. Biroq, ba'zida haqiqiy tekshiruv talab etiladi, shuning uchun bu erda yanada rivojlangan nosozliklarni tuzatishning haqiqiy hayotiy misoli.

bcron - vazifalarni qayta ishlash rejalashtiruvchisi, *nix demonining yana bir ilovasi cron. U serverga o'rnatilgan, lekin kimdir jadvalni tahrir qilmoqchi bo'lsa, shunday bo'ladi:

# crontab -e -u logs
bcrontab: Fatal: Could not create temporary file

OK, bu degani bcron ma'lum bir faylni yozishga harakat qildi, lekin bu ish bermadi va u nima uchun ekanligini tan olmaydi. Ochish zo'riqish:

# strace -o /tmp/trace crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
# cat /tmp/trace
...
openat(AT_FDCWD, "bcrontab.14779.1573691864.847933", O_RDONLY) = 3
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
read(3, "#Ansible: logsaggn20 14 * * * lo"..., 8192) = 150
read(3, "", 8192)                       = 0
munmap(0x7f82049b4000, 8192)            = 0
close(3)                                = 0
socket(AF_UNIX, SOCK_STREAM, 0)         = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/bcron-spool"}, 110) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
write(3, "156:Slogs #Ansible: logsaggn20 1"..., 161) = 161
read(3, "32:ZCould not create temporary f"..., 8192) = 36
munmap(0x7f82049b4000, 8192)            = 0
close(3)                                = 0
write(2, "bcrontab: Fatal: Could not creat"..., 49) = 49
unlink("bcrontab.14779.1573691864.847933") = 0
exit_group(111)                         = ?
+++ exited with 111 +++

Oxirida xato xabari bor yozish, lekin bu safar nimadir boshqacha. Birinchidan, tegishli tizim qo'ng'irog'i xatosi yo'q, bu odatda bundan oldin sodir bo'ladi. Ikkinchidan, kimdir xato xabarini allaqachon o'qiganligi aniq. Haqiqiy muammo boshqa joyda bo'lganga o'xshaydi va bcrontab shunchaki xabarni o'ynatadi.

Agar qarasangiz odam 2 o'qidi, siz birinchi argument (3) fayl deskriptori ekanligini ko'rishingiz mumkin, bu *nix barcha kiritish/chiqarish jarayonlari uchun foydalanadi. 3-fayl identifikatori qaysi faylni ifodalashini qanday aniqlash mumkin? Bunday holda, siz yugurishingiz mumkin zo'riqish operator bilan -y (yuqoriga qarang) va u sizga avtomatik ravishda xabar beradi, ammo shunga o'xshash narsalarni aniqlash uchun iz natijalarini qanday o'qish va tahlil qilishni bilish foydalidir.

Fayl identifikatorining manbai ko'plab tizim qo'ng'iroqlaridan biri bo'lishi mumkin (barchasi identifikator nimaga mo'ljallanganligiga bog'liq - konsol, tarmoq rozetkasi, faylning o'zi yoki boshqa narsa), lekin nima bo'lishidan qat'iy nazar, biz qidiramiz. 3 ni qaytarish orqali qo'ng'iroqlar (ya'ni biz kuzatuv natijalarida "= 3" ni qidiramiz). Bu natijada ulardan 2 tasi bor: ochish eng yuqori qismida va soket o'rtasida. ochish faylni ochadi, lekin yaqin(3) keyin yana yopilishini ko'rsatadi. (Rake: fayl deskriptorlari ochilganda va yopilganda qayta ishlatilishi mumkin). Qo'ng'iroq qiling rozetka () mos keladi, chunki u avvalgi oxirgisi o'qing (), va ma'lum bo'lishicha, bcrontab rozetka orqali biror narsa bilan ishlaydi. Keyingi qator fayl deskriptori bilan bog'langanligini ko'rsatadi unix domen soketi yo'lda /var/run/bcron-spool.

Shunday qilib, biz bilan bog'liq jarayonni topishimiz kerak unix rozetkasi boshqa tomondan. Bu maqsadda bir nechta aniq fokuslar mavjud, ularning ikkalasi ham server o'rnatilishini tuzatish uchun foydalidir. Birinchisi - foydalanish netstat yoki yangiroq ss (rozetka holati). Ikkala buyruq ham tizimning faol tarmoq ulanishlarini ko'rsatadi va bayonotni oladi -l tinglash rozetkalarini, shuningdek, operatorni tasvirlash uchun -p mijoz sifatida rozetkaga ulangan dasturlarni ko'rsatish uchun. (Yana ko'p foydali variantlar mavjud, ammo bu ikkisi bu vazifa uchun etarli.)

# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0   128   /var/run/bcron-spool 1466637   * 0   users:(("unixserver",pid=20629,fd=3))

Bu tinglovchining buyruq ekanligini ko'rsatadi inixserver, ID 20629 bilan ishlaydi. (Va tasodifan u rozetka sifatida 3-fayl deskriptoridan foydalanadi.)

Xuddi shu ma'lumotni topish uchun ikkinchi haqiqatan ham foydali vosita deyiladi shunday. Unda tizimdagi barcha ochiq fayllar (yoki fayl identifikatorlari) ro'yxati keltirilgan. Yoki ma'lum bir fayl haqida ma'lumot olishingiz mumkin:

# lsof /var/run/bcron-spool
COMMAND   PID   USER  FD  TYPE  DEVICE              SIZE/OFF  NODE    NAME
unixserve 20629 cron  3u  unix  0x000000005ac4bd83  0t0       1466637 /var/run/bcron-spool type=STREAM

Jarayon 20629 uzoq umr ko'radigan serverdir, shuning uchun uni biriktirishingiz mumkin zo'riqish kabi narsalarni ishlatish strace -o /tmp/trace -p 20629. Agar siz boshqa terminalda cron ishini tahrir qilsangiz, xatolik bilan kuzatuv natijasini olasiz. Va buning natijasi:

accept(3, NULL, NULL)                   = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21181
close(4)                                = 0
accept(3, NULL, NULL)                   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21181, si_uid=998, si_status=0, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 21181
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]})                 = 43
accept(3, NULL, NULL)                   = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21200
close(4)                                = 0
accept(3, NULL, NULL)                   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21200, si_uid=998, si_status=111, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 111}], WNOHANG|WSTOPPED, NULL) = 21200
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]})                 = 43
accept(3, NULL, NULL

(Oxirgi qabul qilish () kuzatishda tugallanmaydi.) Yana, afsuski, bu natijada biz izlayotgan xatolik mavjud emas. Biz bcrontag rozetkaga yuboradigan yoki rozetkadan oladigan xabarlarni ko'rmayapmiz. Buning o'rniga, jarayonni to'liq boshqarish (klon, kuting4, SIGCHLD va hokazo.) Bu jarayon siz taxmin qilganingizdek, haqiqiy ishni bajaradigan bola jarayonini keltirib chiqaradi. Va agar siz uning iziga tushishingiz kerak bo'lsa, qo'ng'iroqqa qo'shing strace -f. Bu xato xabarni strace bilan yangi natijada qidirganimizda topamiz -f -o /tmp/trace -p 20629:

21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) 
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111)                   = ?
21470 +++ exited with 111 +++

Endi, bu nimadir. 21470-jarayon yo'lda fayl yaratishga urinayotganda "kirish taqiqlangan" xatosini oladi tmp/spool.21470.1573692319.854640 (joriy ishchi katalogga tegishli). Agar biz joriy ishchi katalogni bilganimizda, biz to'liq yo'lni ham bilamiz va jarayon nima uchun unda vaqtinchalik faylni yarata olmasligini aniqlay olamiz. Afsuski, jarayon allaqachon tugagan, shuning uchun siz shunchaki foydalana olmaysiz lsof -p 21470 joriy katalogni topish uchun, lekin siz teskari yo'nalishda ishlashingiz mumkin - katalogni o'zgartiradigan PID 21470 tizim qo'ng'iroqlarini qidiring. (Agar yo'q bo'lsa, PID 21470 ularni ota-onasidan meros qilib olgan bo'lishi kerak va bu allaqachon o'tgan lsof -p topib bo'lmadi.) Bu tizim chaqiruvi chdir (buni zamonaviy onlayn qidiruv tizimlari yordamida topish oson). Va bu erda PID 20629 serveriga qadar kuzatuv natijalariga asoslangan teskari qidiruvlar natijasi:

20629 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21470
...
21470 execve("/usr/sbin/bcron-spool", ["bcron-spool"], 0x55d2460807e0 /* 27 vars */) = 0
...
21470 chdir("/var/spool/cron")          = 0
...
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) 
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111)                   = ?
21470 +++ exited with 111 +++

(Agar siz yo'qolgan bo'lsangiz, oldingi postimni o'qishingiz mumkin haqida *nix jarayonini boshqarish va qobiq.) Shunday qilib, PID 20629 serveri yo'lda fayl yaratishga ruxsat olmagan /var/spool/cron/tmp/spool.21470.1573692319.854640. Ehtimol, buning sababi klassik fayl tizimi ruxsat sozlamalari. Keling, tekshiramiz:

# ls -ld /var/spool/cron/tmp/
drwxr-xr-x 2 root root 4096 Nov  6 05:33 /var/spool/cron/tmp/
# ps u -p 20629
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
cron     20629  0.0  0.0   2276   752 ?        Ss   Nov14   0:00 unixserver -U /var/run/bcron-spool -- bcron-spool

It o'sha erda ko'milgan! Server foydalanuvchi cron sifatida ishlaydi, lekin faqat root katalogga yozish uchun ruxsatga ega /var/spool/cron/tmp/. Oddiy buyruq chown cron /var/spool/cron/tmp/ majbur qiladi bcron to'g'ri ishlash. (Agar bu muammo bo'lmasa, keyingi eng shubhali narsa SELinux yoki AppArmor kabi yadro xavfsizligi modulidir, shuning uchun yadro xabarlari jurnalini tekshirib ko'raman. dmesg.)

jami

Tizim qo'ng'iroqlari izlari yangi boshlanuvchilar uchun juda qiyin bo'lishi mumkin, ammo umid qilamanki, ular keng tarqalgan joylashtirish muammolarining butun sinfini tuzatishning tezkor usuli ekanligini ko'rsatdim. Ko'p jarayonni disk raskadrovka qilishga urinayotganingizni tasavvur qiling bcronbosqichma-bosqich tuzatuvchi yordamida.

Tizim qo'ng'iroqlari zanjiri bo'ylab iz natijalarini orqaga qarab tahlil qilish mahorat talab qiladi, lekin aytganimdek, deyarli har doim foydalanish zo'riqish, Men faqat iz natijasini olaman va oxiridan boshlab xatolarni qidiraman. Nima bo'lganda ham, zo'riqish disk raskadrovka uchun ko'p vaqtni tejashga yordam beradi. Umid qilamanki, bu sizga ham foydali bo'ladi.

Manba: www.habr.com

a Izoh qo'shish