چیزی در مورد inode

به طور دوره‌ای، برای انتقال به مرکز توزیع مرکزی، با شرکت‌های بزرگ مختلف، عمدتاً در سن پترزبورگ و مسکو، برای یک موقعیت DevOps مصاحبه می‌کنم. من متوجه شدم که بسیاری از شرکت ها (بسیاری از شرکت های خوب، به عنوان مثال Yandex) دو سوال مشابه می پرسند:

  • inode چیست;
  • به چه دلایلی می توانید خطای نوشتن دیسک دریافت کنید (یا به عنوان مثال: چرا ممکن است فضای دیسک شما تمام شود، ماهیت یکسان است).

همانطور که اغلب اتفاق می افتد، مطمئن بودم که این موضوع را به خوبی می دانم، اما به محض اینکه شروع به توضیح کردم، شکاف هایی در دانش آشکار شد. برای اینکه دانش خود را نظام مند کنم، شکاف ها را پر کنم و دیگر خود را خجالت ندهم، این مقاله را می نویسم، شاید برای شخص دیگری مفید باشد.

من از پایین شروع می کنم، یعنی. از یک هارد دیسک (ما درایوهای فلش، SSD و سایر چیزهای مدرن را کنار می گذاریم؛ برای مثال، اجازه دهید هر درایو قدیمی 20 یا 80 گیگ را در نظر بگیریم، زیرا اندازه بلوک در آنجا 512 بایت است).

هارد دیسک نمی داند چگونه بایت به بایت فضای خود را آدرس دهی کند؛ به طور مشروط به بلوک ها تقسیم می شود. شماره گذاری بلوک از 0 شروع می شود. (این LBA نامیده می شود، جزئیات در اینجا: ru.wikipedia.org/wiki/LBA)

چیزی در مورد inode

همانطور که از شکل مشخص است، من بلوک های LBA را به عنوان سطح HDD تعیین کردم. به هر حال، می توانید ببینید که دیسک شما چه اندازه بلوکی دارد مانند این:

root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512

سطح بالا یک پارتیشن است، یکی برای کل دیسک (دوباره برای سادگی). اغلب از دو نوع نشانه گذاری پارتیشن استفاده می شود: msdos و gpt. بر این اساس، msdos یک فرمت قدیمی است که از دیسک‌های تا 2 ترابایت پشتیبانی می‌کند، gpt فرمت جدیدی است که می‌تواند تا 1 زتابایت بلوک 512 بایتی را آدرس‌دهی کند. در مورد ما، ما یک پارتیشن از نوع msdos داریم، همانطور که از شکل مشخص است، پارتیشن با بلوک شماره 1 شروع می شود، در حالی که صفر برای MBR استفاده می شود.

در پارتیشن اول که یک فایل سیستم ext2 ایجاد کردم، اندازه بلوک پیش فرض آن 4096 بایت است که در شکل نیز منعکس شده است. شما می توانید اندازه بلوک سیستم فایل را به صورت زیر مشاهده کنید:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          a600bf40-f660-41f6-a3e6-96c303995479
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              65536
Block count:              261888
Reserved block count:     13094
Free blocks:              257445
Free inodes:              65525
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      63
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Filesystem created:       Fri Aug  2 15:02:13 2019
Last mount time:          n/a
Last write time:          Fri Aug  2 15:02:14 2019
Mount count:              0
Maximum mount count:      -1
Last checked:             Fri Aug  2 15:02:13 2019
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Default directory hash:   half_md4
Directory Hash Seed:      c0155456-ad7d-421f-afd1-c898746ccd76

پارامتر مورد نیاز ما "اندازه بلوک" است.

حال قسمت جالب این است که چگونه فایل /home/serp/testfile را بخوانیم؟ یک فایل شامل یک یا چند بلوک سیستم فایل است که داده های آن در آن ذخیره می شود. با دانستن نام فایل، چگونه آن را پیدا کنیم؟ کدام بلوک ها را باید بخوانم؟

اینجاست که inode ها به کار می آیند. سیستم فایل ext2fs دارای یک "جدول" است که حاوی اطلاعات برای همه inode ها است. تعداد inode ها در مورد ext2fs هنگام ایجاد سیستم فایل تنظیم می شود. ما به اعداد مورد نیاز در پارامتر "Inode count" خروجی tune2fs نگاه می کنیم، یعنی. ما 65536 قطعه داریم. inode حاوی اطلاعاتی است که ما نیاز داریم: لیستی از بلوک های سیستم فایل برای فایلی که به دنبال آن هستیم. چگونه شماره inode یک فایل مشخص را پیدا کنیم؟

نام و شماره inode مربوطه در دایرکتوری موجود است و دایرکتوری در ext2fs نوع خاصی از فایل است. همچنین شماره ایند مخصوص به خود را دارد. برای شکستن این دایره باطل، یک عدد inode "ثابت" "2" به دایرکتوری ریشه اختصاص داده شد. بیایید به محتویات inode شماره 2 نگاه کنیم:

root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs:  stat <2>

Inode: 2   Type: directory    Mode:  0755   Flags: 0x0
Generation: 0    Version: 0x00000000:00000002
User:     0   Group:     0   Size: 4096
File ACL: 0    Directory ACL: 0
Links: 3   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Fri Aug  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fri Aug  2 15:02:14 2019
Size of extra inode fields: 28
BLOCKS:
(0):579
TOTAL: 1

همانطور که می بینید، دایرکتوری مورد نیاز ما در بلوک شماره 579 قرار دارد. در آن شماره گره را برای پوشه خانه پیدا می کنیم، و به همین ترتیب در زنجیره ادامه می دهیم تا در دایرکتوری serp شماره گره فایل درخواستی را مشاهده کنیم. اگر ناگهان کسی بخواهد بررسی کند که آیا شماره صحیح است و آیا اطلاعات لازم وجود دارد یا خیر، دشوار نیست. ما انجام می دهیم:

root@ubuntu:/# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 records in
1+0 records out
4096 bytes (4,1 kB) copied, 0,000184088 s, 22,3 MB/s
root@ubuntu:/# hexdump -c /home/serp/dd_image

در خروجی می توانید نام فایل های موجود در دایرکتوری را بخوانید.

بنابراین من به سوال اصلی می رسم: "به چه دلایلی ممکن است خطای ضبط رخ دهد؟"

به طور طبیعی، اگر هیچ بلوک رایگانی در سیستم فایل باقی نماند، این اتفاق می افتد. در این صورت چه می توان کرد؟ علاوه بر واضح "حذف هر چیزی غیر ضروری"، باید به خاطر داشته باشید که در سیستم های فایل ext2,3،4 و 13094 چیزی به نام "تعداد بلوک های رزرو شده" وجود دارد. اگر به لیست بالا نگاه کنید، ما "XNUMX" چنین بلوک هایی را داریم. این بلوک ها فقط توسط کاربر ریشه قابل نوشتن هستند. اما اگر نیاز به حل سریع مشکل دارید، به عنوان یک راه حل موقت می توانید آنها را در دسترس همه قرار دهید و در نتیجه فضای خالی ایجاد کنید:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)

آن ها به طور پیش فرض، شما 5 درصد از فضای دیسک را برای نوشتن در دسترس ندارید، و با توجه به حجم دیسک های مدرن، این می تواند صدها گیگابایت باشد.

چه چیز دیگری می تواند باشد؟ همچنین ممکن است بلوک های رایگان وجود داشته باشد، اما گره دیگری وجود نداشته باشد. این معمولاً زمانی اتفاق می‌افتد که تعداد زیادی فایل در سیستم فایل خود داشته باشید که کوچکتر از اندازه بلوک سیستم فایل هستند. با توجه به اینکه 1 inode روی 1 فایل یا دایرکتوری صرف می شود و در کل ما (برای یک سیستم فایل معین) 65536 داریم - وضعیت بیش از حد واقعی است. این را می توان به وضوح از خروجی دستور df مشاهده کرد:

serp@ubuntu:~$ df -hi
Filesystem     Inodes IUsed IFree IUse% Mounted on
udev             493K   480  492K    1% /dev
tmpfs            493K   425  493K    1% /run
/dev/xvda1       512K  240K  273K   47% /
none             493K     2  493K    1% /sys/fs/cgroup
none             493K     2  493K    1% /run/lock
none             493K     1  493K    1% /run/shm
none             493K     2  493K    1% /run/user
/dev/xvdc1       320K  4,1K  316K    2% /var
/dev/xvdb1        64K   195   64K    1% /home
/dev/xvdh1       4,0M  3,1M  940K   78% /var/www
serp@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            2,0G  4,0K  2,0G   1% /dev
tmpfs           395M  620K  394M   1% /run
/dev/xvda1      7,8G  2,9G  4,6G  39% /
none            4,0K     0  4,0K   0% /sys/fs/cgroup
none            5,0M     0  5,0M   0% /run/lock
none            2,0G     0  2,0G   0% /run/shm
none            100M     0  100M   0% /run/user
/dev/xvdc1      4,8G  2,6G  2,0G  57% /var
/dev/xvdb1      990M  4,0M  919M   1% /home
/dev/xvdh1       63G   35G   25G  59% /var/www

همانطور که به وضوح در پارتیشن /var/www قابل مشاهده است، تعداد بلوک های آزاد در سیستم فایل و تعداد گره های آزاد بسیار متفاوت است.

اگر اینودها تمام شود، هیچ طلسمی به شما نمی گویم، زیرا ... هیچ کدام وجود ندارد (اگر اشتباه می کنم، به من اطلاع دهید). بنابراین برای پارتیشن هایی که فایل های کوچک در آنها تکثیر می شوند، باید سیستم فایل را هوشمندانه انتخاب کنید. به عنوان مثال، btrfs inodes نمی تواند پایان یابد، زیرا در صورت لزوم، موارد جدید به صورت پویا ایجاد می شوند.

منبع: www.habr.com

اضافه کردن نظر