لینوکس ۳۰۳؛ شب ۲۲: وقتی یک برنامه تمام میز را میگیرد
فهرست نوشته
سرویس سالم است، اما یک پردازش پرمصرف تمام حافظه را میبلعد و بقیهٔ کتابخانه از کار میافتد. امشب مصرف منابع را به یک مرز مشخص وصل میکنیم؛ کنترل دسترسی فقط دربارهٔ فایلها نیست.
این جلسه بخشی از دورهٔ لینوکس ۳۰۳ در ۴۰ شب است.
محیط تمرین: Ubuntu 24.04 روی VM با cgroup v2؛ systemd، Python 3 و sudo؛ آزمایش کوچک حافظه.
جایگاه در دوره: هدفهای 332.3 آزمون 303-300.
دو نسل و چند نوع محدودیت#
cgroup یا گروه کنترل، فرآیندها را برای حسابکردن و محدودکردن منابع دستهبندی میکند. در v2 یک hierarchy یکپارچه داریم؛ مسیرها و ابزارهای v1 را عیناً روی آن اجرا نکن. ulimit معمولاً محدودیت یک فرآیند و فرزندانش در shell را تعیین میکند؛ سرویس systemd مستقل، الزاماً تنظیم terminal تو را به ارث نمیبرد.
stat -fc %T /sys/fs/cgroup
cat /proc/cgroups
cat /sys/fs/cgroup/cgroup.controllers
ulimit -a
systemd-cgls
cgroup2fs شاهد mount نسخهٔ دوم است. Slice برای گروهبندی unitها، service برای اجرای مدیریتشده و scope برای گروهبندی فرآیندهایی است که بیرون از سازوکار اجرای service آغاز شدهاند. ابزارهای تاریخی cgmanager و libcgroup را بهعنوان تنها روش مدیریت سیستم امروزی فرض نکن.
محدودیت descriptor در یک subshell#
(
ulimit -n 64
python3 -c 'import resource; print(resource.getrlimit(resource.RLIMIT_NOFILE))'
)
ulimit -n
خروجی داخل subshell باید limit کاهشیافته را نشان دهد؛ shell بیرونی تغییری نکرده است. مقدار hard limit را بیدلیل کاهش نده، چون بازگرداندن آن در همان فرآیند ممکن است مجاز نباشد. در ورودهای PAM، pam_limits.so و /etc/security/limits.conf نقش دارند؛ برای service، directiveهای unit را بررسی کن.
یک ظرف حافظهٔ کوچک#
روی VM و با منابع پایهٔ کافی:
sudo systemd-run --unit=lpic303-memory-probe --wait --pipe \
-p MemoryMax=32M -p MemorySwapMax=0 -p TasksMax=8 \
/usr/bin/python3 -c 'data=bytearray(64*1024*1024); print(len(data))'
این پردازش تنها ۶۴ مگابایت درخواست میکند، ولی ظرف ۳۲ مگابایتی دارد. انتظار پایان ناموفق، MemoryError یا کشتهشدن ناشی از محدودیت را داریم؛ متن دقیق وابسته به محیط است. این تمرین fork bomb یا stress نامحدود نیست.
systemctl status lpic303-memory-probe.service --no-pager
systemctl show lpic303-memory-probe.service -p MemoryMax -p Result
journalctl -u lpic303-memory-probe.service --no-pager
به مقدار limit و نتیجه نگاه کن. CPUQuota سقف مصرف CPU، MemoryHigh فشار نرم و MemoryMax سقف سختتر حافظه را بیان میکنند؛ سهمبندی و سقف یک مفهوم نیستند. systemd-cgtop برای مشاهدهٔ گروهها مفید است.
مأموریت امشب#
برای سرویس کتابخانه، حد حافظهای انتخاب کن که startup و بار عادی را تحمل کند. «کمترین عدد ممکن» الزاماً سیاست خوبی نیست. بعد از ثبت شواهد، unit آزمایشی failed را با systemctl reset-failed lpic303-memory-probe.service پاکوضعیت کن؛ این فرمان دادهٔ برنامه را حذف نمیکند.
منابع: cgroup v2 در کرنل و systemd.resource-control .