حل خطای Reload daemon failed و پر شدن پوشه /run
حل خطای Reload daemon failed و پر شدن پوشه /run
اگر مدیریت یک سرور لینوکسی را بر عهده دارید، احتمالاً تا به حال با سناریویی مواجه شدهاید که قصد دارید یک سرویس را ریاستارت کنید یا تغییراتی در فایلهای .service اعمال کنید، اما هنگام اجرای دستور systemctl daemon-reload با خطای ترسناک و طولانی زیر مواجه میشوید:
Reload daemon failed: Refusing to reload, not enough space available on /run/systemd/. Currently, 0B are free, but a safety buffer of 16M is enforced.
این خطا در نگاه اول ممکن است شما را به وحشت بیندازد، زیرا سیستم به شما میگوید هیچ فضای خالی (0B) وجود ندارد! اما نگران نباشید، هارد دیسک سرور شما پر نشده است. در این مقاله آموزشی، به صورت گامبهگام و با زبانی ساده بررسی میکنیم که این خطا چرا رخ میدهد، چگونه مقصر اصلی را پیدا کنیم و چطور بدون نیاز به ریبوت کردن سرور، این مشکل را برای همیشه حل کنیم.
درک مفهوم: پوشه /run چیست و چرا پر میشود؟
برای حل این مشکل، ابتدا باید بدانیم لینوکس چگونه کار میکند. میتوانید ساختار دایرکتوری های لینوکس را مطالعه کنید اما دایرکتوری /run در لینوکس یک فایلسیستم معمولی روی هارد دیسک شما نیست؛ بلکه یک فایلسیستم موقت از نوع tmpfs است. این یعنی تمام محتویات پوشه /run مستقیماً روی حافظه رم (RAM) سیستم ذخیره میشود.
لینوکس از این پوشه برای ذخیره فایلهای موقتیِ سرویسهای در حال اجرا (Daemonها)، فایلهای قفل (Lock files) و اطلاعات وضعیت سیستم (State) استفاده میکند. از آنجایی که ظرفیت اختصاص یافته به /run محدود است، اگر یک برنامه یا سرویس دچار اختلال شود و فایلهای موقت بیشماری بسازد، این پوشه به سرعت به ظرفیت ۱۰۰٪ میرسد.
هنگامی که این پوشه پر میشود، ابزار systemd (که مدیر اصلی سرویسها در لینوکس است) از بارگذاری مجدد خودداری میکند، زیرا طبق پروتکلهای امنیتی خود، برای عملکرد صحیح حداقل به ۱۶ مگابایت فضای رزرو شده (Safety Buffer) نیاز دارد.
گام اول: تایید مشکل و بررسی فضای اشغال شده
وقتی با این خطا مواجه میشوید، اولین قدم این است که مطمئن شوید واقعاً مشکل از پر شدن پوشه /run است. ترمینال خود را باز کنید و دستور زیر را اجرا کنید:
df -h /run
اگر در ستون Use% عدد 100% را مشاهده کردید، یعنی این پوشه کاملاً پر شده است و باید فوراً آن را پاکسازی کنیم.
گام دوم: پیدا کردن مقصر اصلی (چه چیزی فضا را بلعیده است؟)
حالا باید بگردیم و ببینیم کدام سرویس در حال تولید فایلهای هرز است. از آنجا که فایلها زیاد هستند، ما با استفاده از دستور du بزرگترین دایرکتوریها را استخراج میکنیم. دستور زیر را اجرا کنید:
sudo du -ah /run 2>/dev/null | sort -hr | head -n 20
این دستور ۲۰ فایل یا پوشهای که بیشترین حجم را در دایرکتوری /run اشغال کردهاند، به ترتیب از بزرگ به کوچک لیست میکند. در اینجا شما معمولاً با دو سناریوی اصلی مواجه میشوید:
سناریوی اول: پر شدن لاگهای Journald
اگر دیدید پوشه /run/systemd/journal حجم بالایی (مثلاً چند صد مگابایت) دارد، مشکل از لاگهای سیستم است. این حالت معمولاً زمانی رخ میدهد که یک برنامه در حال چاپ کردن مداوم ارور در پسزمینه است. راه حل: با اجرای دستور زیر، لاگهای قدیمی را پاک کنید تا فضا آزاد شود:
sudo journalctl –vacuum-time=1d
سناریوی دوم (مشکل پیچیدهتر): پر شدن پوشه /run/udev/data
اگر پس از اجرای دستور بررسی حجم، متوجه شدید که پوشه /run/udev/data حجم عظیمی (مثلاً ۷۰۰ مگابایت یا بیشتر) را اشغال کرده است، شما با یک مشکل شبکهای روبرو هستید! پوشه udev مربوط به مدیریت سختافزارها و رابطهای مجازی در لینوکس است. اگر داخل این پوشه را نگاه کنید، صدها هزار فایل را میبینید که نام آنها با حرف n شروع میشود (مانند n594792).
اما این فایلها چه هستند؟ هر فایل که با n شروع میشود، نماینده یک “کارت شبکه مجازی” است. این اتفاق معمولاً زمانی رخ میدهد که شما از ابزارهای گذر از تحریم، برنامههای تونلزنی (مانند پنلهای Xray/V2ray در حالت TUN، وایرگارد یا OpenVPN) استفاده میکنید که به صورت Daemon اجرا میشوند. اگر این سرویسها به دلیل اختلال اینترنت مدام قطع و وصل شوند (Crash Loop)، با هر بار اتصال یک کارت شبکه مجازی جدید میسازند، اما هنگام قطع شدن، فایل موقت آن را از پوشه /run پاک نمیکنند. روی هم تلنبار شدنِ صدها هزار از این فایلها، رم شما را پر میکند!
گام سوم: پاکسازی اصولی (عبور از خطای Argument list too long)
ممکن است وسوسه شوید که برای پاک کردن این فایلهای مزاحم از یک دستور ساده مثل rm -f /run/udev/data/n* استفاده کنید. اما وقتی تعداد فایلها به صدها هزار عدد میرسد، هسته لینوکس نمیتواند این دستور را پردازش کند و شما با خطای معروف زیر مواجه میشوید:
/usr/bin/rm: Argument list too long
دلیل این خطا این است که خط فرمان (Bash) ظرفیت محدودی برای دریافت آرگومانها در یک خط دارد و نمیتواند نام ۶۰۰ هزار فایل را یکجا به دستور rm پاس بدهد.
راه حل جادویی: استفاده از دستور Find برای دور زدن این محدودیت، ما باید عملیات حذف را به صورت تکبهتک و در پسزمینه انجام دهیم. دستور زیر بهترین و ایمنترین روش برای پاکسازی این فایلهاست:
sudo find /run/udev/data/ -type f -name “n*” -delete
نکته: بسته به تعداد فایلها و قدرت سرور شما، اجرای این دستور ممکن است از چند ثانیه تا چند دقیقه طول بکشد. صبور باشید تا خط فرمان دوباره در دسترس قرار گیرد.
گام چهارم: اعمال تغییرات و حل نهایی خطا
پس از اینکه دستور find تمام فایلهای هرز شبکه را پاک کرد، فضای رم شما آزاد میشود. حالا باید سرویس مدیریت سختافزار را متوجه این تغییر کنیم و سپس دیمن را ریلود کنیم:
ابتدا سرویس udev را ریاستارت کنید تا دیتابیس خود را بهروز کند:
sudo systemctl restart systemd-udevd
حالا دستور ریلود سرویس ها را وارد کنید:
sudo systemctl daemon-reload
تبریک میگویم! خطا کاملاً برطرف شد و حالا سیستم به درستی کار میکند.
توصیهای برای جلوگیری از تکرار مشکل
پاک کردن فایلها صرفاً درمان علائم بیماری بود. برای اینکه هفته آینده دوباره با همین خطا مواجه نشوید، باید ریشه مشکل را حل کنید. اگر متوجه شدید مشکل از ساخته شدن کارت شبکههای مجازی (فایلهای n) بوده است، باید لاگهای سرویسهای پروکسی یا VPN خود را در سرور بررسی کنید. دستور sudo dmesg | grep tun به شما نشان میدهد کدام نرمافزار در حال ساخت و تخریب مداوم کارت شبکه است. با رفع خطای کانفیگ آن سرویس یا جلوگیری از کرش کردن مداوم آن، این مشکل برای همیشه از سرور شما رخت برخواهد بست.