مقدمهای بر فرایند بوت لینوکس
فرایند راهاندازی یا بوت یک سیستم عامل لینوکس، اغلب به اشتباه به عنوان یک عملیات واحد و یکپارچه در نظر گرفته میشود. اما در واقع، این فرایند مجموعهای از انتقالهای کنترل متوالی بین بخشهای مختلف است که هر یک وظایف خاص خود را بر عهده دارند و تجربه کاربری شما را در استفاده از محیطهای مختلف، از ایستگاه کاری روزمره تا سرورهای میزبان وبسایتهای پرترافیک مانند وردپرس، تحت تأثیر قرار میدهند. درک این مراحل برای هر توسعهدهندهای که به دنبال بهینهسازی کارایی سیستم عامل خود یا عیبیابی مشکلات مربوط به زمان راهاندازی است، حیاتی است. ابزارهایی مانند systemd-analyze میتوانند دیدی دقیق از این مراحل ارائه دهند و به شما کمک کنند تا گلوگاههای عملکردی را شناسایی کنید.
فرایند بوت لینوکس: چهار انتقال کلیدی
برخلاف تصور رایج، فرایند بوت لینوکس چهار مرحله اصلی و مجزا دارد که به صورت پیدرپی و یکطرفه کنترل را به یکدیگر واگذار میکنند. هر جزء پس از انجام وظیفه خود، از حافظه خارج شده و جزء بعدی را فعال میکند. این چهار مرحله به ترتیب عبارتند از:
- فریمور (Firmware): از روی تراشهای روی مادربرد اجرا میشود. وظیفه آن پیدا کردن یک دستگاه قابل بوت و شروع آن است.
- بوتلودر (Bootloader): پس از دریافت کنترل از فریمور، وظیفه بوتلودر یافتن کرنل، بارگذاری آن به همراه یک فایلسیستم اولیه (initramfs) در حافظه و سپس پرش به کرنل است.
- کرنل (Kernel): هسته اصلی سیستم عامل. سختافزار را راهاندازی میکند، فایلسیستم ریشه را مونت کرده و دقیقاً یک فرایند فضای کاربری را آغاز میکند (PID 1).
- فضای کاربری (Userspace) و PID 1: اولین فرایند فضای کاربری (معمولاً systemd)، مسئول راهاندازی تمامی سرویسها و برنامههای دیگر است که منجر به رسیدن به صفحه ورود میشود.
این انتقالهای یکطرفه توضیح میدهند که چرا زمانبندیهای مختلفی که توسط systemd-analyze گزارش میشود، توسط اجزای متفاوتی اندازهگیری شده و معانی مختلفی دارند. برای مثال، در یک لپتاپ خاص، کل زمان راهاندازی ممکن است ۲۹.۶۱۳ ثانیه باشد که شامل ۵.۸۵۵ ثانیه برای فریمور، ۸.۴۶۹ ثانیه برای بوتلودر، ۳.۱۰۶ ثانیه برای کرنل و ۱۲.۱۸۱ ثانیه برای فضای کاربری است. ۱۴ ثانیه از این زمان، قبل از اینکه لینوکس اصلاً شروع به کار کند، صرف میشود.
از فریمور تا راهاندازی کرنل: مراحل اولیه بوت
اولین مرحله، یعنی فریمور، تقریباً ۶ ثانیه از زمان بوت را به خود اختصاص میدهد و تنها بخشی است که لینوکس مستقیماً آن را اندازهگیری نمیکند. این زمان شامل آموزش حافظه، شناسایی دستگاهها و اجرای کدهای خاص فروشنده سختافزار است. این اطلاعات توسط فریمور در یک جدول ACPI به نام FPDT (Firmware Performance Data Table) ثبت میشود و کرنل آن را از طریق مسیر /sys/firmware/acpi/fpdt/boot/bootloader_launch_ns در اختیار قرار میدهد. عدم وجود FPDT، به ویژه در ماشینهای مجازی، میتواند منجر به عدم گزارش این فاز توسط systemd-analyze شود.
پس از فریمور، بوتلودر کنترل را در دست میگیرد. این مرحله که میتواند تا ۸.۵ ثانیه طول بکشد، اغلب شامل یک تأخیر قابل توجه است که توسط کاربر قابل تنظیم است. برای مثال، پارامتر GRUB_TIMEOUT="5" در فایل /etc/default/grub میتواند ۵ ثانیه از این زمان را به انتظار برای ورودی کاربر اختصاص دهد. این یک انتخاب پیکربندی است که تأثیر مستقیمی بر کارایی سرور و سرعت راهاندازی دارد. بوتلودر همچنین خط فرمان کرنل (/proc/cmdline) و initramfs را بارگذاری میکند، که یک فایلسیستم کوچک و فشرده حاوی درایورهای ضروری برای دسترسی کرنل به فایلسیستم ریشه واقعی است. این مرحله نقش حیاتی در بهینهسازی هاستینگ و تجربه نهایی مدیریت سرور ایفا میکند.
کرنل در حدود ۳ ثانیه راهاندازی میشود. در این فاز، کرنل خود را از حالت فشرده خارج میکند، مدیریت حافظه را راهاندازی، CPUها را فعال، درایورها را مقداردهی اولیه کرده و به دنبال فایلسیستم ریشه میگردد. کرنل در ابتدا فایلسیستم ریشه را به صورت فقط خواندنی (read-only) مونت میکند تا امکان بررسی ایمنی آن وجود داشته باشد و سپس توسط فضای کاربری به حالت خواندن/نوشتن (read-write) تغییر میکند. این مرحله نهایتاً با راهاندازی اولین فرایند فضای کاربری، یعنی PID 1 (که در سیستمهای مدرن همان systemd است)، به پایان میرسد. در طول این فرایند، کرنل به سرویسدهی به سیستم ادامه میدهد اما تصمیمگیریهای اصلی به فضای کاربری واگذار میشود.
فضای کاربری و systemd: کنترل نهایی بوت
با شروع systemd به عنوان PID 1، کنترل کامل به فضای کاربری منتقل میشود. این مرحله که بیشترین زمان را در فرایند بوت به خود اختصاص میدهد (حدود ۱۲ ثانیه در مثال ما)، شامل راهاندازی تمامی سرویسها و وابستگیهای لازم برای رسیدن به صفحه ورود است. systemd با ساخت یک گراف وابستگی، سرویسها را به صورت موازی راهاندازی میکند و تنها در جایی که یک وابستگی واقعی وجود دارد، منتظر میماند. این موازیسازی باعث میشود تحلیل بوت پیچیدهتر شود.
برای توسعهدهندگان و مدیران سیستم که به دنبال بهینهسازی کارایی هستند، درک این فاز اهمیت زیادی دارد. دستور systemd-analyze blame، که زمان راهاندازی هر واحد را نشان میدهد، ممکن است گمراهکننده باشد زیرا سرویسهایی را نیز شامل میشود که خارج از مسیر حیاتی بوت هستند و ممکن است زمان طولانیتری داشته باشند اما تأثیری بر زمان رسیدن به صفحه ورود ندارند. به عنوان مثال، سرویسهایی مانند fstrim.service یا plocate-updatedb.service اغلب توسط زمانسنجها (timers) فعال میشوند و جزو مسیر بوت نیستند.
ابزار دقیقتر برای بررسی مسیر بوت، systemd-analyze critical-chain graphical.target است. این دستور زنجیره حیاتی وابستگیها را نشان میدهد که مستقیماً به صفحه ورود یا هدف نهایی شما منجر میشوند. سرویسهایی مانند docker.service یا NetworkManager-wait-online.service معمولاً زمانبرترین اجزا در این مرحله هستند، به خصوص NetworkManager-wait-online.service که تا زمانی که اتصال شبکه برقرار نشده، بوت را مسدود میکند. مدیریت سرور و هاستینگ وبسایتهایی مانند وردپرس، مستلزم درک این وابستگیها برای کاهش زمان توقف و بهبود تجربه کاربری است. با بررسی دقیق این مراحل، میتوان زمان بوت را به شکل چشمگیری کاهش داد و به کارایی بالاتری دست یافت.
فریمور و بوتلودر: اولین گامها
فرآیند راهاندازی یک سیستم لینوکس، برخلاف آنچه از واژه “بوت” برمیآید، یک جریان واحد نیست، بلکه مجموعهای از چهار مرحله مستقل است که هر یک وظیفه خاص خود را دارند و کنترل را به مرحله بعدی واگذار میکنند. در این بخش، به دو مرحله ابتدایی و حیاتی خواهیم پرداخت: فریمور (Firmware) و بوتلودر (Bootloader). این دو، پایههایی هستند که پیش از شروع به کار هسته لینوکس، وظیفه آمادهسازی اولیه سختافزار و بارگذاری سیستمعامل را بر عهده دارند. با استفاده از ابزارهایی مانند systemd-analyze میتوانیم زمان سپری شده در هر یک از این مراحل را به دقت اندازهگیری کنیم و برای بهینهسازی عملکرد سرورهای لینوکسی یا حتی محیط توسعه وردپرس خود، اطلاعات ارزشمندی به دست آوریم.
نقش فریمور در راهاندازی سیستم
فریمور اولین جزئی است که پس از فشردن دکمه پاور شروع به کار میکند. این نرمافزار کوچک بر روی یک تراشه در مادربورد قرار دارد و وظیفه اصلی آن یافتن یک محیط قابل بوت و سپس راهاندازی آن است. پس از انجام وظایف خود، کنترل را به بوتلودر واگذار کرده و از حافظه خارج میشود. زمان صرف شده در این مرحله، مانند ۵.۸۵۵ ثانیه در مثال مقاله مرجع، تنها عددی است که لینوکس مستقیماً آن را اندازهگیری نمیکند، بلکه این اطلاعات توسط خود فریمور در یک جدول ACPI به نام FPDT (Firmware Performance Data Table) ثبت و سپس توسط هسته لینوکس در مسیر /sys/firmware/acpi/fpdt/boot/bootloader_launch_ns در دسترس قرار میگیرد.
در طول مرحله فریمور، عملیات مهمی مانند آموزش حافظه (memory training)، شمارش و شناسایی دستگاهها (device enumeration) و اجرای کدهای خاص سازنده سختافزار انجام میشود. این مرحله غالباً طولانیترین بخش از فرآیند بوت است، به ویژه در سیستمهایی با رم زیاد یا دستگاههای USB متعدد که نیاز به شناسایی دارند. به عنوان توسعهدهندگان یا مدیران سیستم، باید توجه داشت که دستکاری یا بهینهسازی این مرحله از داخل لینوکس تقریباً غیرممکن است. اگرچه برخی فریمورها گزینههای “بوت سریع” را ارائه میدهند که با صرفنظر از برخی مراحل شناسایی، زمان راهاندازی را کاهش میدهند. این گزینه میتواند برای سرورهای هاستینگ که پایداری و سرعت در آنها اهمیت بالایی دارد، مفید باشد.
بوتلودر: پلی به هسته لینوکس
پس از اتمام کار فریمور، کنترل به بوتلودر واگذار میشود. وظیفه بوتلودر، مانند GRUB، یافتن هسته لینوکس، بارگذاری آن به همراه یک فایلسیستم اولیه (initramfs) در حافظه و سپس پرش به نقطه شروع هسته است. در نمونه مورد بررسی، مرحله بوتلودر ۸.۴۶۹ ثانیه طول کشیده که تقریباً سه برابر زمان راهاندازی هسته است. نکته حائز اهمیت اینجاست که بخش قابل توجهی از این زمان، به عنوان مثال ۵ ثانیه از آن، مربوط به شمارش معکوس GRUB و انتظار برای دریافت ورودی از کاربر است. این یک انتخاب پیکربندی است که معمولاً توسط نصاب سیستم تعیین میشود و اغلب بدون بازبینی رها میگردد. برای بهینهسازی زمان بارگذاری سیستم، تغییر GRUB_TIMEOUT به مقداری کمتر، مثلاً ۱ ثانیه، یکی از سادهترین و مؤثرترین راهکارها است.
بوتلودر اطلاعات مورد نیاز هسته را از طریق خط فرمان هسته (kernel command line) به آن منتقل میکند. این خط فرمان در فایل /proc/cmdline قابل مشاهده است و شامل پارامترهایی مانند BOOT_IMAGE (مشخصکننده هسته بارگذاری شده)، root=UUID=... (نام فایلسیستم ریشه بر اساس UUID)، ro (که درخواست میکند فایلسیستم ریشه در ابتدا به صورت فقط خواندنی mount شود) و splash (برای نمایش صفحه گرافیکی بوت) میشود. GRUB دو فایل کلیدی را در حافظه بارگذاری میکند: هسته لینوکس و initramfs (فایلسیستم اولیه رم). پس از بارگذاری موفقیتآمیز و انتقال کنترل، بوتلودر نیز از حافظه محو میشود و دیگر وجود ندارد.
بهینهسازی اولین گامها برای عملکرد بهتر
همانطور که مشاهده شد، در سیستم مثال، تقریباً ۱۴ ثانیه پیش از آنکه هسته لینوکس شروع به کار کند، صرف مراحل فریمور و بوتلودر میشود. این زمان، بخش قابل توجهی از کل زمان راهاندازی سیستم است و در بسیاری از موارد، فرصتهای بزرگی برای بهینهسازی و افزایش عملکرد کلی سیستم فراهم میآورد. به عنوان مثال، کاهش زمان شمارش معکوس GRUB از ۵ ثانیه به ۱ ثانیه میتواند بلافاصله منجر به صرفهجویی ۴ ثانیه در فرآیند بوت شود که برای سرورهای وردپرس یا هر سیستم لینوکسی که نیاز به دسترسی سریع دارد، بسیار ارزشمند است. این تغییر ساده، به خصوص برای کسانی که به ندرت سیستم خود را ریبوت میکنند، میتواند تفاوت محسوسی در تجربه کاربری ایجاد کند.
در نهایت، درک چگونگی عملکرد فریمور و بوتلودر و تأثیر آنها بر زمان راهاندازی، به توسعهدهندگان و مدیران سیستم کمک میکند تا نقاط ضعف احتمالی را شناسایی کرده و با اعمال تنظیمات مناسب، از جمله تنظیم مجدد GRUB_TIMEOUT، تجربه کاربری را بهبود بخشند. این دانش نه تنها برای افزایش سرعت بوت، بلکه برای حل مشکلات احتمالی راهاندازی و اطمینان از پایداری زیرساختهای لینوکسی، از جمله مواردی که برای هاستینگ وبسایتهای وردپرس استفاده میشوند، حیاتی است.
کرنل و Initramfs: قلب سیستم عامل
درک فرایند بوت لینوکس برای هر توسعهدهنده، ادمین سیستم یا حتی کاربران حرفهای اهمیت بالایی دارد. پس از اینکه firmware و بوتلودر وظایف خود را به انجام رساندند و کنترل را واگذار کردند، نوبت به یکی از مهمترین بخشهای سیستم عامل، یعنی کرنل (Kernel) میرسد. این مرحله که طبق گزارش ابزارهایی مانند systemd-analyze میتواند حدود 3.1 ثانیه به طول بیانجامد، قلب تپنده لینوکس را بیدار میکند. کرنل وظیفه راهاندازی سختافزارها و آمادهسازی سیستم را بر عهده دارد و در این میان، نقش initramfs برای حل یک معمای اساسی در فرایند بوت، حیاتی است. این دو جزء با همکاری یکدیگر، زیربنای لازم برای عملکرد روان سیستم عامل را فراهم میکنند. آگاهی از جزئیات کارکرد آنها به شما کمک میکند تا عملکرد سرورهای خود را، بهویژه آنهایی که میزبان وبسایتهای سنگین و محبوب مانند WordPress هستند، بهتر تحلیل و بهینهسازی کنید و از پایداری و سرعت بالای آنها اطمینان حاصل نمایید.
مرحله کرنل: از راهاندازی تا واگذاری کنترل
هنگامی که بوتلودر، کرنل را در حافظه بارگذاری کرده و کنترل را به آن میدهد، کرنل لینوکس با سرعت شروع به کار میکند. اولین اقدامات شامل فشردهسازی خود، تنظیم مدیریت حافظه، راهاندازی پردازندهها و مقداردهی اولیه درایورهاست. این عملیاتها در زمان 0.000000 ثانیه (از دید کرنل) آغاز میشوند و زمانبندی دقیق آن توسط خود کرنل ثبت میگردد. برای مشاهده لاگهای مربوط به این فاز، میتوان از دستور journalctl -k -b -o short-monotonic استفاده کرد که پیامهای کرنل را با زمانبندی دقیق از لحظه شروع آن نمایش میدهد. لازم به ذکر است که dmesg ممکن است در برخی سیستمها به دلیل تنظیمات امنیتی مانند kernel.dmesg_restrict = 1، خروجی کامل را برای کاربران عادی نمایش ندهد؛ این اقدام عمدی برای جلوگیری از افشای آدرسهای حافظه کرنل و افزایش امنیت سیستمها، بهویژه در محیطهای سرور یا توسعه، حیاتی است.
یکی از نکات مهم در این فاز، نحوه مونت شدن سیستم فایل ریشه (root filesystem) است. کرنل ابتدا سیستم فایل ریشه را به صورت read-only (فقط خواندنی) مونت میکند. این کار به این دلیل انجام میشود که بتوان یک بررسی سالم و ایمن روی سیستم فایل انجام داد و از هرگونه آسیب احتمالی به دادهها جلوگیری کرد؛ چرا که بررسی یک سیستم فایل در حالی که پروسهها در حال نوشتن روی آن هستند، میتواند یک مشکل کوچک را به یک فاجعه بزرگ تبدیل کند و پایداری وبسایت یا اپلیکیشن شما را تحت تأثیر قرار دهد. پس از اتمام موفقیتآمیز این بررسی، userspace (فضای کاربری) همان سیستم فایل را به صورت read-write (قابل خواندن و نوشتن) دوباره در جای خود مونت میکند. گزینه errors=remount-ro تضمین میکند که در صورت بروز خطای سیستم فایل در آینده، کرنل به حالت فقط خواندنی بازگردد تا از آسیب بیشتر جلوگیری شود. در نهایت، پس از حدود 3.1 ثانیه، کرنل اولین خط لاگ PID 1 را ثبت میکند و کنترل را به systemd (اولین پروسه فضای کاربری) واگذار مینماید. از این نقطه به بعد، کرنل به ابتکار خود کاری انجام نمیدهد و تنها به system calls (درخواستهای سیستمی) پاسخ میدهد و به عنوان یک زیرساخت حیاتی عمل میکند.
Initramfs: حل معمای “جوجه و تخممرغ” راهاندازی
در دل آن فعالیتهای اولیه کرنل، یک مرحله حیاتی پنهان شده که برای بسیاری از کاربران ابهامآمیز است و به آن “مشکل جوجه و تخممرغ” میگویند. برای اینکه کرنل بتواند سیستم فایل ریشه شما را مونت کند، به درایورهای مختلفی نیاز دارد: درایور کنترلر ذخیرهسازی، درایور مربوط به نوع سیستم فایل (مانند ext4)، و شاید کدهای لازم برای مونتاژ آرایههای RAID، باز کردن ولومهای رمزنگاری شده یا فعالسازی LVM. اما مشکل اینجاست که این درایورها به صورت ماژولهایی در خود سیستم فایل ریشه قرار دارند، سیستمی که کرنل هنوز نتوانسته آن را مونت کند. راهحل هوشمندانه این معما، initramfs (initial RAM filesystem) است. این یک سیستم فایل کوچک، کامل و مستقل است که بوتلودر آن را همراه با کرنل، مستقیماً در حافظه رم بارگذاری میکند.
برای مشاهده محتویات initramfs، میتوانید از ابزارهایی مانند lsinitramfs (در اوبونتو/دبیان) یا lsinitrd (در فدورا) استفاده کنید. یک initramfs معمولی در اوبونتو ممکن است حدود 76 مگابایت حجم داشته باشد و شامل هزاران فایل، از جمله بیش از هزار ماژول کرنل باشد. هدف اصلی آن، فراهم کردن حداقل درایورهای لازم برای پیدا کردن و مونت کردن سیستم فایل ریشه اصلی است. نکته جالب اینجاست که initramfs پس از انجام وظیفه خود، هرگز به طور معمول خارج نمیشود. در عوض، سیستم فایل ریشه واقعی را جایگزین خود میکند، خودش را از مسیر کنار میزند و سپس /sbin/init واقعی را اجرا میکند، بدون اینکه یک درخت پروسه جدید آغاز شود. به این ترتیب، PID 1 هویت خود را در میانه مسیر بوت تغییر میدهد و ID پروسه خود را حفظ میکند. توزیعهایی مانند اوبونتو، initramfs عمومی و نسبتاً بزرگی میسازند که حاوی درایورهای زیادی است تا روی هر سختافزاری بوت شود؛ این رویکرد یک تعادل بین اندازه و قابلیت حمل ایجاد میکند و برای مدیریت سرورهای متنوع یا محیطهای ابری، مانند آنهایی که میزبان چندین سایت WordPress هستند، میتواند بسیار مفید باشد.
اهمیت بهینهسازی کرنل و Initramfs برای عملکرد سیستم
فاز کرنل و initramfs، اگرچه تنها بخشی از زمان کلی بوت را تشکیل میدهند (در مثال ذکر شده حدود 3.1 ثانیه)، اما نقش حیاتی در پایداری و عملکرد اولیه سیستم ایفا میکنند. بهینهسازی این مراحل میتواند به کاهش زمان کلی بوت کمک شایانی کند، که این موضوع برای سیستمهایی با نیازهای بالا، مانند سرورهای وب که میزبان وبسایتها و پلتفرمهای وردپرسی هستند، از اهمیت ویژهای برخوردار است. هر میلیثانیه کاهش در زمان بوت، به معنای دسترسی سریعتر به خدمات و کاهش احتمالی downtime است. اندازه و پیچیدگی initramfs به طور مستقیم بر زمان بوت کرنل تأثیر میگذارد؛ هرچه ماژولها و فایلهای غیرضروری کمتری در آن وجود داشته باشد و بهصورت تخصصیتر برای سختافزار مورد نظر پیکربندی شده باشد، سریعتر میتواند کار خود را انجام داده و سیستم را آماده کند. این دقیقاً همان دلیلی است که initramfsهای توزیعهای عمومی مانند اوبونتو (که برای پوشش طیف وسیعی از سختافزارها طراحی شدهاند) ممکن است نسبت به یک initramfs سفارشیسازی شده برای یک ماشین خاص، زمان بیشتری برای بوت نیاز داشته باشند.
برای مثال، اگر سیستم فایل ریشه شما رمزنگاری شده باشد، بخشی از زمان فاز کرنل در واقع صرف وارد کردن رمز عبور توسط کاربر میشود. بنابراین، برای بهینهسازی نهایی و دستیابی به حداکثر سرعت، بهخصوص در سرورها یا ماشینهای مجازی که وظایف حیاتی مانند میزبانی وبسایتهای وردپرسی را بر عهده دارند، درک عمیق از این مراحل و توانایی سفارشیسازی initramfs میتواند گامی مؤثر باشد. با درک دقیق این مراحل و ابزارهای مرتبط، میتوانید گلوگاههای عملکردی را شناسایی کرده و تجربهای سریعتر و مطمئنتر از لینوکس خود داشته باشید. این دانش عمیق، به شما امکان میدهد تا سیستمهای خود را فراتر از تنظیمات پیشفرض، برای نیازهای خاص خود بهینه کنید و کنترل بیشتری بر عملکرد آنها داشته باشید و در نتیجه، پایداری و کارایی خدمات خود را افزایش دهید.
فضای کاربری (Userspace) و systemd
پس از اینکه هستهٔ لینوکس (kernel) با موفقیت بارگذاری شد و وظایف اولیهٔ خود از جمله راهاندازی سختافزار، مدیریت حافظه، و شناسایی ریشهفایلسیستم را به پایان رساند، کنترل را به اولین فرآیند فضای کاربری (Userspace) منتقل میکند. این نقطه، که در سیستمهای مدرن لینوکس معمولاً به وسیلهٔ systemd و PID 1 مدیریت میشود، مرحلهای حیاتی و اغلب طولانیترین بخش از فرآیند راهاندازی است. در مثال ارائه شده، هسته در حدود 3.1 ثانیه وظیفهٔ خود را به پایان رسانده و حدود 12 ثانیهٔ باقیمانده تا رسیدن به صفحهٔ ورود به فضای کاربری اختصاص دارد.
نقش PID 1 و مدیریت systemd
هنگامی که هستهٔ لینوکس بارگذاری کامل شد، تنها یک فرآیند در فضای کاربری را آغاز میکند که به آن PID 1 یا “init” گفته میشود. در توزیعهای مدرن لینوکس مانند اوبونتو، دبیان، فدورا و آرچ، systemd این نقش را بر عهده دارد. وظیفهٔ systemd فراتر از صرفاً اجرای برنامههاست؛ این سیستم یک مدل مدیریت هدفمحور را پیادهسازی میکند. به جای اینکه فرآیندها را به صورت ترتیبی و خطی آغاز کند، یک “هدف” (target) مانند graphical.target (برای محیط گرافیکی) یا multi-user.target (برای سرورهای بدون GUI، ایدهآل برای یک سرور وردپرس) تعیین شده و systemd یک نمودار وابستگی (dependency graph) از تمام سرویسها و واحدهای مورد نیاز میسازد. سپس، تمامی این واحدها را تا حد امکان به صورت موازی شروع میکند و فقط در مواردی که وابستگی واقعی وجود دارد، منتظر میماند.
این موازیسازی باعث میشود که تجزیه و تحلیل زمان راهاندازی پیچیدهتر از آنچه به نظر میرسد باشد، زیرا دهها اتفاق به طور همزمان رخ میدهند و زمان کل، صرفاً مجموع زمانهای هر بخش نیست. برای مثال، در یک سیستم لینوکس با systemd، ممکن است صدها فایل واحد نصب شده و دهها سرویس در حال اجرا باشند که هر یک به دیگری وابسته است یا مستقل عمل میکند. ابزارهایی مانند systemctl به ما امکان میدهند تا اهداف پیشفرض و لیست سرویسهای فعال را مشاهده کنیم و درک بهتری از آنچه در حال راهاندازی است، پیدا کنیم.
ابزارهای تجزیه و تحلیل زمان بوت در systemd
برای درک بهتر زمانبندی راهاندازی سیستم، systemd-analyze ابزاری قدرتمند است. اما باید به درستی از آن استفاده کرد. بسیاری از کاربران در ابتدا به سراغ دستور systemd-analyze blame میروند که لیست زمان آغاز به کار هر واحد را ارائه میدهد. این دستور، در نگاه اول، ممکن است سرویسهایی را با زمانهای بسیار طولانی نمایش دهد (مانند fstrim.service با چند دقیقه یا plocate-updatedb.service با دهها ثانیه). با این حال، این اعداد میتواند گمراهکننده باشد؛ blame تمامی واحدهای شروع شده را، صرفنظر از اینکه آیا در مسیر حیاتی راهاندازی تا صفحهٔ ورود شما بودهاند یا خیر، لیست میکند. بسیاری از سرویسهای با زمان طولانی توسط تایمرها فعال میشوند و در زمان بوت اصلی، به طور مستقیم بر روی زمان ورود کاربر تأثیر نمیگذارند.
برای مثال، در سیستم مرجع، سرویسهایی مانند fstrim.service، plocate-updatedb.service، و apt-daily.service با زمانهای طولانی در خروجی blame ظاهر میشوند، اما بررسی دقیقتر نشان میدهد که این سرویسها توسط تایمرها فعال شده و نه توسط مسیر بوت اصلی. بنابراین، برای بهینهسازی زمان راهاندازی یک سرور که ممکن است میزبانی وردپرس باشد، باید از دستور صحیح استفاده کرد.
شناسایی مسیر بحرانی (Critical Chain)
دستور صحیح برای پاسخ به سوال “چه چیزی راهاندازی سیستم را کند میکند؟” systemd-analyze critical-chain graphical.target (یا multi-user.target برای سرور) است. این دستور، زنجیرهٔ وابستگیهای حیاتی را که مستقیماً بر روی زمان رسیدن به هدف نهایی تأثیر میگذارند، نمایش میدهد. در خروجی این دستور، @ نشاندهندهٔ زمانی است که یک واحد فعال شده، و + نشاندهندهٔ مدت زمان لازم برای شروع آن است. با استفاده از این اطلاعات، میتوان سرویسهای کندی را که در مسیر حیاتی بوت قرار دارند، شناسایی کرد.
برای مثال، در سیستم مرجع، docker.service با 4.875 ثانیه و NetworkManager-wait-online.service با 4.106 ثانیه، بخش قابل توجهی از 12 ثانیهٔ فضای کاربری را به خود اختصاص دادهاند. این دو سرویس به صورت سریالی اجرا میشوند، زیرا داکر برای شروع به یک شبکهٔ فعال نیاز دارد. NetworkManager-wait-online.service به ویژه در لپتاپها که منتظر اتصال Wi-Fi هستند، میتواند عامل تأخیر باشد. برای سرورها یا سیستمهای رومیزی که نیاز مبرمی به این تضمین ندارند (مثلاً یک سرور وردپرس که شبکه آن همیشه بالا است)، ممکن است غیرفعال کردن یا تنظیم این سرویس باعث بهبود چشمگیر زمان بوت شود. اما همیشه باید مطمئن شد که حذف یک سرویس، بر روی وابستگیهای سایر سرویسهای ضروری تأثیر منفی نمیگذارد. زمان فضای کاربری به دلیل نرمافزارهای نصب شده، مانند داکر یا سرویسهای مرتبط با یک سایت وردپرسی، میتواند بین سیستمهای مختلف بسیار متفاوت باشد.
بهینهسازی و تحلیل زمان بوت
درک عمیق فرآیند بوت لینوکس نه تنها برای عیبیابی مشکلات ضروری است، بلکه ابزاری قدرتمند برای بهینهسازی زمان بالا آمدن سیستم فراهم میکند. بسیاری از کاربران تصور میکنند زمان بوت فقط به سرعت پردازنده یا حافظه بستگی دارد، اما واقعیت پیچیدهتر است. با استفاده از ابزارهایی مانند systemd-analyze میتوانیم هر مرحله از بوت را بهطور دقیق بررسی کرده و گلوگاهها را شناسایی کنیم. این فرآیند از چهار مرحله اصلی تشکیل شده است: فریمور، بوتلودر، هسته لینوکس (کرنل) و فضای کاربر (یوزراسپیس)، که هر کدام مسئولیتها و زمانبندیهای خاص خود را دارند و بهصورت یکطرفه کنترل را به مرحله بعدی واگذار میکنند.
درک مراحل بوت و ابزارهای تحلیل
اولین گام در تحلیل زمان بوت، اجرای دستور ساده systemd-analyze در ترمینال است. خروجی این دستور، زمان صرف شده در چهار مرحله اصلی بوت را نشان میدهد؛ به عنوان مثال: Startup finished in 5.855s (firmware) + 8.469s (loader) + 3.106s (kernel) + 12.181s (userspace) = 29.613s. زمان فریمور (مانند 5.855s) تنها عددی است که لینوکس مستقیماً آن را اندازهگیری نمیکند، بلکه این اطلاعات توسط فریمور در جدول ACPI FPDT ثبت شده و از طریق مسیر /sys/firmware/acpi/fpdt/boot/bootloader_launch_ns قابل دسترسی است. این مرحله شامل آموزش حافظه و شمارش دستگاههاست که عمدتاً خارج از کنترل لینوکس است. مرحله بوتلودر (مانند 8.469s) اغلب شامل یک شمارش معکوس است که توسط کاربر قابل تنظیم است. سپس هسته لینوکس (kernel) شروع به کار میکند و در این مدت خود را فشردهسازی، مدیریت حافظه را راهاندازی، درایورها را فعال کرده و به دنبال فایلسیستم روت میگردد. برای مشاهده وقایع این مرحله با زمانبندی دقیق از لحظه شروع هسته، میتوان از دستور journalctl -k -b -o short-monotonic استفاده کرد. در نهایت، کنترل به PID 1 (معمولاً systemd) در فضای کاربر منتقل میشود که مسئول راهاندازی تمامی سرویسها و برنامههای دیگر تا رسیدن به صفحه ورود کاربر است.
تفسیر دقیق خروجی systemd-analyze
بسیاری از کاربران برای شناسایی سرویسهای کند، از دستور systemd-analyze blame استفاده میکنند، اما این دستور میتواند گمراهکننده باشد. blame لیستی از زمان شروع هر واحد را نشان میدهد، صرفنظر از اینکه آیا آن واحد بخشی از مسیر حیاتی به صفحه ورود کاربر بوده است یا خیر. به عنوان مثال، سرویسهایی مانند fstrim.service یا apt-daily.service که ممکن است زمان زیادی را صرف کنند، اغلب توسط تایمرها فعال میشوند و نه در مسیر بوت اصلی. این سرویسها، حتی اگر ساعتها طول بکشند، تأثیری بر زمان رسیدن شما به صفحه ورود ندارند. برای تحلیل دقیقتر، دستور systemd-analyze critical-chain graphical.target را اجرا کنید. این دستور، زنجیره وابستگیهای حیاتی را که مستقیماً به هدف نهایی (مانند graphical.target برای صفحه ورود گرافیکی) منجر میشوند، نمایش میدهد. در خروجی این دستور، علامت @ نشاندهنده زمان فعال شدن یک واحد و علامت + نشاندهنده مدت زمان فعال بودن آن است. این ابزار به شما کمک میکند تا سرویسهای واقعی که زمان بوت را طولانی میکنند، مانند docker.service یا NetworkManager-wait-online.service، را شناسایی کنید. لازم به ذکر است که critical-chain تنها یک زنجیره را نشان میدهد و وابستگیها را به ترتیب نمایش میدهد، نه لزوماً ترتیب زمانی وقوع رویدادها.
عوامل موثر بر زمان بوت و نکات بهینهسازی
زمان بوت لینوکس به عوامل متعددی بستگی دارد که برخی از آنها قابل کنترل و برخی دیگر خارج از کنترل کاربر هستند. زمان فریمور به شدت متغیر است و به سختافزار (مانند میزان RAM و تعداد دستگاههای USB) و تنظیمات BIOS/UEFI بستگی دارد. فعال کردن گزینه «Fast Boot» در فریمور میتواند با صرفنظر از مراحل شمارش دستگاه، این زمان را کاهش دهد. زمان بوتلودر عمدتاً به مقدار GRUB_TIMEOUT در فایل /etc/default/grub بستگی دارد. کاهش این زمان به یک ثانیه میتواند تاثیر قابل توجهی در کاهش زمان کلی بوت داشته باشد. زمان هسته تحت تاثیر میزان سختافزار و حجم initramfs است. یک initramfs عمومی (مانند آنچه در اوبونتو استفاده میشود) بزرگتر از یک initramfs مخصوص سختافزار شماست و زمان بارگذاری بیشتری نیاز دارد. همچنین، اگر فایلسیستم روت شما رمزگذاری شده باشد، وارد کردن رمز عبور نیز به زمان هسته اضافه میشود. زمان فضای کاربر بیشترین تفاوت را بین سیستمها دارد، زیرا مستقیماً به سرویسها و برنامههایی که نصب کردهاید بستگی دارد. سرویسهایی مانند docker.service یا NetworkManager-wait-online.service اغلب از جمله عوامل اصلی تاخیر هستند؛ بهویژه NetworkManager-wait-online که منتظر برقراری کامل اتصال شبکه میماند. با غیرفعال کردن سرویسهای غیرضروری یا تنظیم آنها برای اجرا در زمانهای دیگر، میتوان زمان بوت را بهینهسازی کرد. همچنین، زمان بوت میتواند در اجراهای مختلف روی یک سیستم یکسان متفاوت باشد، بنابراین برای نتیجهگیری صحیح، بهتر است چندین بار سیستم را بوت کرده و میانگین زمانها را در نظر بگیرید.
جمعبندی و توصیههای نهایی
با درک عمیق مراحل بوت لینوکس و استفاده صحیح از ابزارهای تحلیل systemd-analyze، میتوانید زمان بالا آمدن سیستم خود را بهطور قابل توجهی بهبود بخشید. به یاد داشته باشید که زمانبندی systemd-analyze blame اغلب گمراهکننده است و باید بر تحلیل زنجیره حیاتی (critical-chain) تمرکز کنید. برای بهینهسازی فوری، میتوانید زمان شمارش معکوس GRUB را به یک ثانیه کاهش دهید؛ برای این کار، GRUB_TIMEOUT=”1″ را در /etc/default/grub تنظیم کرده و سپس sudo update-grub (در دبیان/اوبونتو) یا sudo grub2-mkconfig -o /boot/grub2/grub.cfg (در فدورا) را اجرا کنید. همچنین، با اجرای دستور systemd-analyze plot > boot.svg میتوانید یک نمای گرافیکی و موازی از فرآیند بوت را در مرورگر خود مشاهده کنید که درک وابستگیها و گلوگاهها را آسانتر میکند. بررسی کنید که آیا سرویس NetworkManager-wait-online.service واقعاً برای سیستم شما ضروری است یا خیر، چرا که در بسیاری از دسکتاپها و لپتاپها، این سرویس بدون دلیل معقولی زمان زیادی را مصرف میکند و غیرفعال کردن آن میتواند به سرعت بوت کمک کند.