Hard va symbolic link’lar
Linux’da faylning nomi ma’lumotning o'zi emas. Katalog yozuvi nomni inode bilan bog'laydi, inode esa faylning metama’lumotlarini saqlaydi va uning ma’lumot bloklariga ishora qiladi. Nom va ma’lumot alohida bo'lgani uchun bitta inode bir nechta nomga ega bo'lishi yoki bitta nom butunlay boshqa joyga ishora qilishi mumkin. Birinchi holat hard link, ikkinchisi symbolic link (qisqacha symlink) deyiladi.
Bu mavzuni tushunish Disk va fayl tizimi asoslari maqolasida tanishtirilgan inode modeliga bog'liq. Yo'llar qanday aniqlanishini eslash kerak bo'lsa, shu modulning keyingi qismidagi Yo'llar va fayl turlari maqolasi buni chuqurroq yoritadi. Misollarda Ubuntu Server LTS’dagi GNU Coreutils’ning ln buyrug'i ishlatiladi. Quyida hard link va symbolic link o'rtasidagi ichki farqni ko'ramiz; ikkalasini ln, stat, readlink va find bilan yaratib, tekshiramiz; nisbiy symlink maqsadi aslida qayerdan boshlab aniqlanishini bilib olamiz; nom o'chirilgandan keyin ma’lumot qachon saqlanib qolishini tushunamiz. Oxirida buzilgan link, turli fayl tizimlari orasidagi holat va noto'g'ri reliz ko'rsatkichini tashxislaymiz, shuningdek link’lar zaxira nusxa olish va production’da versiya almashtirish paytida qanday xavf tug'dirishini baholaymiz.
Katalogdagi nom, inode va ma’lumot
Oddiy faylning soddalashtirilgan ko'rinishi:
Inode faylning turi, egasi, ruxsatlari, vaqt tamg'alari, havolalar soni va ma’lumot bloklariga ko'rsatkichlarni saqlaydi. Fayl nomi odatda inode ichida umuman saqlanmaydi — u katalog yozuvida turadi. Shuning uchun ikkita katalog yozuvi bitta inode’ga ishora qilishi mumkin.
Bular ikkita hard link. Texnik jihatdan ulardan birini "asl", ikkinchisini "nusxa" deb bo'lmaydi: ikkalasi ham bitta faylning teng huquqli nomlari.
Hard link’lar
ln sukut bo'yicha hard link yaratadi:
Masalan:
Natijani tekshirish:
ls -li settings.conf settings.backup
stat -c 'inode=%i link=%h name=%n' settings.conf settings.backup
Namunaviy natija:
10542 -rw-r--r-- 2 user user 10 Jul 29 11:00 settings.backup
10542 -rw-r--r-- 2 user user 10 Jul 29 11:00 settings.conf
inode=10542 link=2 name=settings.conf
inode=10542 link=2 name=settings.backup
Ikkala nomning inode raqami bir xil, havolalar soni esa 2. Bir nom orqali mazmunni o'zgartirsangiz, bu ikkinchi nom orqali darhol ko'rinadi:
Bu nusxa emas. Diskda ikkita mustaqil ma’lumot bloklari to'plami yo'q.
Nom o'chirilganda nima bo'ladi?
rm odatda ma’lumot bloklarini to'g'ridan-to'g'ri "o'chirmaydi": u katalogdagi nomni inode’dan uzib qo'yadi. Inode’ning havolalar soni bittaga kamayadi. Oxirgi hard link o'chirilgach va faylni hech bir jarayon ochiq ushlab turmagan bo'lsa, kernel uning joyini qayta ishlatishi mumkin.
settings.backup ishlashda davom etadi, havolalar soni esa 1 ga tushadi. Ishlab turgan jarayon log faylni ochiq ushlab turgan bo'lsa, u o'chirilgandan keyin disk joyi darhol bo'shamasligi ham aynan shu xususiyat bilan tushuntiriladi. Bu holatni keyinroq lsof +L1 bilan tekshirishingiz mumkin.
Hard link’ning cheklovlari
Hard link:
- faqat mavjud inode’ga yaratiladi;
- fayl tizimi chegarasidan o'ta olmaydi;
- odatda oddiy foydalanuvchi tomonidan katalogga ishora qiladigan qilib yaratilmaydi;
- maqsadi ko'chirilganda "buzilmaydi", chunki u yo'l satriga emas, inode’ga bog'langan.
Turli fayl tizimlari o'rtasida hard link yaratishga urinish Invalid cross-device link xatosini (EXDEV) beradi. Ikki yo'l bitta diskda turgandek ko'rinsa ham, alohida mount qilingan fayl tizimlariga tegishli bo'lishi mumkin:
Agar ikkala natijadagi fayl tizimi yoki qurilma identifikatori farq qilsa, u yerda hard link yaratib bo'lmaydi — buning o'rniga symbolic link yoki haqiqiy nusxa kerak.
Symbolic link’lar
Symbolic link — o'z maqsadini matn satri sifatida saqlaydigan alohida fayl turi:
U ln -s bilan yaratiladi:
Masalan:
Natijani tekshirish:
ls -li settings.current settings.backup
readlink settings.current
readlink -f settings.current
stat -c 'inode=%i type=%F name=%n' settings.current
stat -Lc 'inode=%i type=%F name=%n' settings.current
readlink link ichida saqlangan matnni aynan o'zicha chiqaradi; readlink -f esa to'liq aniqlangan kanonik yo'lni chiqaradi. GNU stat odatda link’ning o'zi haqida ma’lumot beradi, -L bilan esa uning maqsadi ortidan boradi. Natijadagi ikki inode raqami har xil bo'ladi.
Nisbiy maqsad qayerdan boshlab aniqlanadi?
Eng muhim qoida: symbolic link ichida saqlangan nisbiy yo'l terminalning joriy ish katalogiga nisbatan emas, link’ning o'zi turgan katalogga nisbatan aniqlanadi.
Quyidagi tuzilmani olaylik:
/srv/demo/current link’i releases/v2 satrini saqlaydi. Kernel uni /srv/demo ga nisbatan aniqlaydi va natijada /srv/demo/releases/v2 ga yetib boradi.
Bu buyruqni qaysi katalogdan ishga tushirganingiz keyinchalik maqsad qanday aniqlanishiga ta’sir qilmaydi. Lekin link yaratish paytida yo'lni noto'g'ri yozib qo'yish oson. GNU ln maqsaddan link’ning o'z joyigacha bo'lgan to'g'ri nisbiy yo'lni avtomatik hisoblash uchun -r opsiyasini taklif qiladi:
-r — GNU Coreutils kengaytmasi, u har qanday POSIX muhitida mavjud emas.
Absolyut yoki nisbiy symbolic link?
/srv/demo/releases/v2 kabi absolyut link tizimdagi qat’iy nuqtadan boshlanadi. Link turgan katalog ko'chirilsa ham, u o'sha joyga ishora qilishda davom etadi, lekin butun katalog daraxti boshqa ildiz, chroot, konteyner yoki serverga ko'chirilsa, buzilishi mumkin.
Nisbiy link birgalikda bitta butun sifatida ko'chiriladigan katalog daraxtlari uchun qulay. Lekin link’ning o'zi boshqa joyga ko'chirilsa, maqsadining ma’nosi o'zgaradi. Tanlovni sizda haqiqatan mavjud deploy tuzilmasiga qarab qiling.
Osilib qolgan (dangling) symbolic link
Agar maqsad mavjud bo'lmasa, natija osilib qolgan (buzilgan) link bo'ladi. Uni yaratishga ruxsat beriladi:
ls va readlink link’ning o'zini ko'radi; realpath -e esa maqsadni aniqlab bo'lmagani uchun xato beradi. test -L link’ning o'zi mavjudligini, test -e esa uning maqsadi aniqlanishini tekshiradi:
test -L broken && printf 'the link exists\n'
test -e broken || printf 'but the target does not exist\n'
Hard link va symbolic link farqi
| Xususiyat | Hard link | Symbolic link |
|---|---|---|
| Nimaga bog'lanadi | Bitta fayl tizimidagi inode’ga | Maqsad yo'lini saqlaydigan satrga |
| O'z inode’i bormi? | Yo'q, maqsadning inode’ini ulashadi | Ha |
| Fayl tizimlari chegarasidan o'ta oladimi? | Yo'q | Ha |
| Katalogga ishora qila oladimi? | Odatda yo'q | Ha |
| Mavjud bo'lmagan maqsadga ishora qila oladimi? | Yo'q | Ha |
| Maqsad nomi o'chirilsa | Boshqa hard link ishlashda davom etadi | Link buziladi |
ls -l ko'rsatadigan tur |
Maqsadning o'z turi | l |
"O'z inode’i bormi?" qatori symbolic link’ning o'zini tavsiflaydi. Ko'p dasturlar link ortidan avtomatik borib, uning maqsadi ustida ishlaydi; rm link kabi ba’zi amallar esa link’ning o'ziga ta’sir qiladi.
Xavfsiz laboratoriya
Bu laboratoriya faqat mktemp yaratgan katalog ichida ishlaydi. Quyida ko'rsatilgan $lab o'zgaruvchisini qayta o'rnatmasdan boshqa terminal sessiyasida ishlatmang.
Boshlang'ich holat
Ikkala turdagi link’ni yaratish
Natijani tekshirish:
ls -li "$lab"
stat -c 'dev=%d inode=%i link=%h type=%F name=%n' "$lab/original.txt" "$lab/hard.txt"
readlink "$lab/symlink.txt"
original.txt va hard.txt da dev, inode va havolalar soni bir xil chiqishi kerak. symlink.txt ning inode’i boshqa va u original.txt satrini saqlaydi.
Mazmun va nom bir-biridan mustaqil
Ikkala buyruq ham alpha va beta ni chiqaradi. Endi asl nomni interaktiv rejimda o'chiring:
Tasdiqlagandan keyin:
cat "$lab/hard.txt"
readlink "$lab/symlink.txt"
test -L "$lab/symlink.txt" && printf 'the symlink still exists\n'
test ! -e "$lab/symlink.txt" && printf 'but its target is gone\n'
Hard link mazmunni hali ham ochadi; symbolic link esa mavjud, lekin endi maqsadini topa olmaydi.
Faylga tegishli barcha hard link’larni topish
-samefile berilgan fayl bilan bir xil inode’ga bog'langan barcha nomlarni topadi. -xdev boshqa fayl tizimiga o'tishning oldini oladi. Bu mantiqli, chunki inode raqamlari faqat o'z fayl tizimi ichida yagona bo'ladi.
Tozalash
printf 'directory to remove: %q\n' "$lab"
find "$lab" -maxdepth 1 -ls
rm -rI -- "$lab"
test ! -e "$lab" && printf 'cleaned up\n'
Warning
Agar rm ga berilgan yo'l symbolic link’ning o'zi bo'lsa, rm odatda maqsadni emas, link’ni o'chiradi. Lekin rekursiv vositalar va oxiridagi / kabi sintaksis tafsilotlari maqsad ortidan borishga sabab bo'lishi mumkin. Production’da symbolic link ustida rekursiv amalni uning maqsadini avval readlink, realpath va stat bilan tekshirmasdan bajarmang.
Amaliy vaziyat: buzilgan reliz ko'rsatkichi
Deploy jarayoni /srv/myapp/current ni faol relizga yo'naltiradi. Xizmat qayta ishga tushgandan keyin o'z konfiguratsiyasini topa olmayapti.
Tekshiruv
Avval hech narsani o'zgartirmasdan link’ni tahlil qiling.
namei -l yo'lning har bir qismini alohida ko'rsatadi, shunda aniqlash aynan qayerda uzilishini ko'rish mumkin bo'ladi. readlink -f va namei ning yo'l diagnostikasi o'rtasidagi farq shu modulning keyingi qismidagi Yo'llar va fayl turlari maqolasida chuqurroq yoritilgan.
ls -ld /srv/myapp/current
readlink /srv/myapp/current
readlink -f /srv/myapp/current
namei -l /srv/myapp/current/config/app.ini
findmnt -T /srv/myapp/current
Masalan, readlink releases/v3 ni chiqarsa-yu, readlink -f hech narsa chiqarmasa, demak /srv/myapp/releases/v3 yo mavjud emas, yo yo'lning biror qismi aniqlanmayapti. namei aynan qaysi qism buzilganini ko'rsatadi.
Xavfsiz almashtirish
Production’dagi mavjud current link’ini majburan ustidan yozishdan oldin yangi reliz va rollback maqsadini qayd eting:
Quyidagi haqiqiy o'zgarish faqat ruxsatlari va zaxira siyosati tekshirilgan test VM’da yoki tasdiqlangan deploy jarayonining bir qismi sifatida bajarilishi kerak:
current.new xuddi shu katalogda yaratilgani uchun yakuniy qayta nomlash bitta fayl tizimi ichida atomar bo'ladi: kuzatayotgan jarayon yo eski nomni, yo yangisini ko'radi, ular orasida bo'shliq bo'lmaydi. Bu jarayon allaqachon ochib qo'ygan fayl deskriptorlarini yoki allaqachon ishga tushgan jarayonning konfiguratsiyasini avtomatik yangilamaydi.
Rollback:
cd /srv/myapp
ln -s releases/<previous-version> current.rollback
readlink -f current.rollback
mv -T current.rollback current
<previous-version> ni tekshiruv bosqichida qayd etgan qiymatingiz bilan almashtiring. sudo faqat buyruqni bajarayotgan hisobda /srv/myapp ga yozish huquqi bo'lmasa va deploy siyosati uni ishlatishga ruxsat bersa kerak bo'ladi; u noto'g'ri maqsadni xavfsiz qilib qo'ymaydi.
Danger
ln -sfn ni ko'r-ko'rona ishlatish mavjud yo'lni jimgina almashtirib yuborishi mumkin. Maqsad katalogmi, oddiy faylmi yoki boshqa symbolic link’mi — buni stat, readlink va namei bilan tekshiring. Muhim bo'lgan har qanday deploy uchun reliz katalogining zaxira nusxasini yoki VM snapshot oling va rollback uchun eski link qiymatini qayd eting.
Zaxira nusxa, nusxalash va xavfsizlik
Arxiv link’ni saqlaydimi yoki maqsadnimi?
Zaxira nusxa vositangizning link’lar bo'yicha siyosatini tekshiring. Masalan, GNU cp -a odatda symbolic link’ni symbolic link sifatida saqlaydi, cp -L esa uning maqsadi ortidan boradi. Hard link’lar zaxira formati va ishlatilgan opsiyalarga qarab yo bitta umumiy inode sifatida, yo alohida nusxalar sifatida tiklanishi mumkin.
Tiklagandan keyin faqat fayllar sonini emas, ko'proq narsani tekshiring:
Ishonchsiz katalogdagi symbolic link
Hamma yoza oladigan katalogda boshqa foydalanuvchi link’ni almashtirib, yuqoriroq huquqli jarayonni kutilmagan maqsadga yo'naltirishi mumkin. Dasturlash darajasida bu muammoni lstat, openat2 cheklovlari yoki O_NOFOLLOW kabi vositalar hal qiladi. Administrator sifatida esa:
- xavfsiz vaqtinchalik fayl uchun
mktempdan foydalaning; - hujumchi o'zgartira oladigan katalogda maqsadni tekshirish va uni ishlatish o'rtasida vaqt oralig'i qoldirmang;
- rekursiv nusxalash vositasiga tayanishdan oldin uning
-H,-L,-Pqoidalarini tekshiring; - symlink egasi va katalogning sticky bit siyosatini e’tiborsiz qoldirmang.
Keng tarqalgan xatolar
- Hard link’ni nusxa deb hisoblash.
- Bir nechta hard link orasidan "aslini" topishga urinish — bunday farq yo'q.
- Nisbiy symlink maqsadini link’ning o'z katalogiga emas, joriy ish katalogiga nisbatan aniqlash.
- Osilib qolgan symlink uchun
test -enatijasini link’ning o'zi mavjud emasligining isboti deb hisoblash —test -eaniqlangan maqsadni tekshiradi; link’ning o'zi uchuntest -Ldan foydalaning. - Inode raqamini faqat o'z fayl tizimi ichida yagona bo'lgan identifikator emas, global noyob identifikator deb hisoblash.
Mashqlar
- Vaqtinchalik katalogda bitta fayl va unga ikkita hard link yarating. Har bir qadamdan keyin havolalar sonini
stat -c '%i %h %n'bilan qayd eting. - Ikkita symbolic link yarating: birining maqsadi absolyut, ikkinchisiniki nisbiy bo'lsin. Katalog daraxtini boshqa vaqtinchalik joyga ko'chiring va qaysi link hali ham ishlashini va nima uchunligini aniqlang.
- Osilib qolgan symlink yarating.
ls -l,test -L,test -e,readlinkvarealpath -enatijalarini solishtiring. - Ikkita alohida fayl tizimi bor test VM’da turli fayl tizimlari orasida hard link yaratishga urinishdan oldin farqni
findmnt -Tvastat -c '%d'bilan isbotlang. Kutilgan xato nomini qayd eting; buni production’da sinab ko'rmang. - Test deploy daraxtida
currentsymlink’ini vaqtinchalik nom vamv -Tyordamida almashtiring. Qayd etilgan maqsad yordamida oldingi qiymatga rollback qiling.
Mashqni bajardim deyish uchun: hard link’lar uchun qurilma va inode qiymatlari bir xil ekanini, symbolic link’lar uchun esa saqlangan maqsad satrini ham, to'liq aniqlangan yo'lni ham ko'rsata olishingiz kerak.
Manbalar
- GNU Coreutils qo'llanmasi:
lninvocation: https://www.gnu.org/software/coreutils/manual/html_node/ln-invocation.html - Linux man-pages:
link(2): https://man7.org/linux/man-pages/man2/link.2.html - Linux man-pages:
symlink(7): https://man7.org/linux/man-pages/man7/symlink.7.html - Linux man-pages:
path_resolution(7): https://man7.org/linux/man-pages/man7/path_resolution.7.html - GNU Coreutils qo'llanmasi:
cpinvocation va symbolic link’lar: https://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html - Linux man-pages:
openat2(2): https://man7.org/linux/man-pages/man2/openat2.2.html