LimitNPROC بمقابلہ TasksMax: ایک OpenVPN یونٹ کیا گنتا ہے
LimitNPROC ایک صارف کے عمل کو پورے نظام میں گنتا ہے؛ TasksMax ایک یونٹ کے cgroup کو محدود کرتا ہے۔ ان میں سے کسی کو بڑھانے سے پہلے موثر اقدار پڑھیں۔
ناکام OpenVPN آغاز اکثر وسائل کی شکایت اور حد بڑھانے کی نیک نیتی پر مبنی تجویز کے ساتھ آتا ہے، اور یہ تجویز صرف تقریباً آدھے معاملات میں کام کرتی ہے۔ ان ناکامیوں کے پیچھے دو غیر متعلق شمار کنندہ ہیں۔ ایک حقیقی صارف ID کی ملکیت والے کاموں کی تعداد پر کرنل کی حد ہے، اور عمل چلانے پر یہ وراثت میں ملتی ہے۔ دوسرا cgroup بجٹ ہے جو سروس مینیجر ایک یونٹ اور اس سے fork ہونے والی ہر چیز پر لاگو کرتا ہے۔ اصل میں چلنے والے یونٹ کے لیے ہر ایک کی موثر قدر پڑھنا ایک اندازے سے کم خرچ ہے۔
دو شمار کنندہ، دو سوال
LimitNPROC systemd نام کے تحت RLIMIT_NPROC ہے، اور اس کی گنتی کی اکائی حقیقی صارف ID ہے۔ اس صارف کی ملکیت والا ہر عمل اسی کل میں گنا جاتا ہے، جس میں دیگر یونٹس، لاگ اِن سیشن یا شیڈیولر کام کا شروع کردہ کام بھی شامل ہے۔ اس لیے یہ حد خدمت کے حساب سے الگ حد نہیں ہے، چاہے وہ کسی سروس یونٹ کے اندر مقرر ہو، اور وہ خدمت جو ہر کلائنٹ کے لیے ایک مددگار fork کرتی ہے، اسی اکاؤنٹ کے تحت چلنے والی باقی ہر چیز سے مقابلہ کرتی ہے۔ اسی صارف کے تحت ایک مصروف cron کام VPN یونٹ کو ایسی لکیر سے آگے دھکیل سکتا ہے جسے اس نے خود کبھی نہیں عبور کیا۔
TasksMax کا ایک اور مالک ہے: یونٹ کے cgroup پر pids کنٹرولر، جو عمل کے بجائے کام گنتا ہے۔ تھریڈز کام ہیں، اس لیے ایک تھریڈ جیسا نظر آنے والا مگر ورکر پول رکھنے والا ڈیمن ایسا بجٹ خرچ کر سکتا ہے جو پہلی نظر میں اس کے عمل کی تعداد سے کہیں بڑا لگتا ہے۔ EffectiveTasksMax بتاتا ہے کہ والدین سلائسز کے اپنی بات کہنے کے بعد cgroup درجہ بندی واقعی کس چیز کی اجازت دیتی ہے۔
root کی استثنا جواب کیوں بدلتی ہے
کرنل RLIMIT_NPROC ایسے عمل پر لاگو نہیں کرتا جس کے پاس CAP_SYS_RESOURCE یا CAP_SYS_ADMIN ہو، اسی لیے بغیر استحقاق چھوڑے root کے طور پر چلنے والا یونٹ اس ترتیب کے تحت عملاً بے حد ہوتا ہے۔ یہی واحد استثنا وہ متضاد مشورے سمجھاتا ہے جو لوگ ایک دوسرے کو دیتے ہیں: LimitNPROC بڑھانا ایسی تعیناتی کو درست کرتا ہے جس نے استحقاق چھوڑ دیے تھے اور ایسی تعیناتی کے لیے کچھ نہیں کرتا جو مستحق رہی۔ اس ترتیب کو داد یا الزام دینے سے پہلے User= اور یہ دیکھیں کہ ڈیمن آغاز کے بعد اپنی شناخت بدلتا ہے یا نہیں۔ مستحق یونٹ جو بعد میں غیر مستحق اکاؤنٹ میں جاتا ہے، تبدیلی کے لمحے دوبارہ حد کے نیچے آ جاتا ہے، جس سے ناکامی کی زمانی ترتیب بھی پڑھنے کے قابل ہوتی ہے۔
ناکامی کا مرحلہ اسے مزید تنگ کرتا ہے۔ عمل درآمد کی تیاری کے دوران انکار، خود ڈیمن کی بتائی ہوئی fork خرابی، اور cgroup کے اندر مسترد شدہ کام کی تخلیق مختلف journal سطریں پیدا کرتے ہیں، اور ان میں سے صرف ایک کا جواب بڑے بجٹ سے ملتا ہے۔
موثر اقدار پڑھیں، شیل کی نہیں
انٹرایکٹو شیل کا ulimit -u اسی شیل کو بیان کرتا ہے۔ یہ نہیں بتاتا کہ سروس مینیجر نے ڈیمن کو کیا دیا، اور cgroup حساب کے بارے میں کچھ نہیں کہتا۔ اس کے بجائے یونٹ سے پوچھیں، کسی گائیڈ کی مثال کے بجائے میزبان پر موجود انسٹانس نام استعمال کرتے ہوئے۔
systemctl show [email protected] -p User -p LimitNPROC -p TasksCurrent -p TasksMax -p EffectiveTasksMax
cat /proc/$(systemctl show -p MainPID --value [email protected])/limits | grep -i processes
کنٹینر کے اندر جواب کے لیے مزید دو مطالعے درکار ہیں، کیونکہ infinity کی اندرونی قدر صرف مہمان کا نظریہ بیان کرتی ہے۔ میزبان کے مالک سے کنٹینر کی اپنی pids حد پوچھیں، اور تصدیق کریں کہ اندرونی سروس مینیجر وہ کنٹرولر بالکل سونپ سکتا ہے یا نہیں۔ نیسٹڈ یونٹ ایسا بجٹ نہیں رکھ سکتا جو اس کے والدین cgroup نے کبھی دیا ہی نہ ہو۔
اصلاح کا حجم ناپیں اور بوجھ کے نیچے اسے ثابت کریں
عدد غلطی کے متن سے نہیں، کام کے بوجھ سے منتخب کریں۔ ڈیمن ہر منسلک کلائنٹ یا ہر مددگار کال پر کتنے عمل شروع کرتا ہے گنیں، تعیناتی کو جتنی ہم وقتی برداشت کرنی ہے اس سے ضرب دیں، انتظامی سیشن کے لیے تھوڑا حاشیہ شامل کریں، اور پھر اس عدد کا دو موثر اقدار سے موازنہ کریں۔ مقامی drop-in اوور رائیڈ تبدیلی کو قابلِ جائزہ رکھتا ہے اور پیکیج اپ گریڈ کے بعد بھی قائم رہتا ہے، جبکہ شپ شدہ یونٹ فائل میں ترمیم تبدیلی کو اگلی اپ ڈیٹ کے اسے بدلنے تک چھپائے رکھتی ہے۔ اوور رائیڈ کے ساتھ حساب لکھیں، کیونکہ آگے اسے بڑھانے یا گھٹانے والے کو حتمی عدد نہیں، مفروضے درکار ہوتے ہیں۔
بجٹ کی تبدیلیاں عمل درآمد کے وقت لاگو ہوتی ہیں، اس لیے صرف دوبارہ لوڈ کرنا پہلے سے چل رہے عمل کا حجم نہیں بدلتا۔ یونٹ کو اس کے معمول کے زندگی کے چکر سے دوبارہ شروع کریں، سیشن کی مداخلت قبول کریں، اور نئی انسٹانس پر شمار کنندہ دوبارہ پڑھیں۔
sudo systemctl daemon-reload
sudo systemctl restart [email protected]
systemctl show [email protected] -p TasksCurrent -p EffectiveTasksMax
sudo journalctl -u [email protected] -b --no-pager | tail -n 20
اصلاح کو ثابت کرتا ہے وہ دوبارہ شروع کیا گیا یونٹ جس کے کاموں کی تعداد مطلوبہ بوجھ اٹھاتے ہوئے بھی دونوں حدوں سے نیچے رہتی ہے، ساتھ ہی ایسا journal جو اسی مرحلے پر اب کام یا fork کے ختم ہونے کی اطلاع نہیں دیتا۔ تبدیلی کے ساتھ پہلے اور بعد کے اعداد رکھیں تاکہ اگلی تحقیق اسی مشورے سے نہیں، کسی پیمائش سے شروع ہو۔ اگر تعداد اب بھی حد تک پہنچتی ہے تو حساب ہی غلط تھا، حد اتفاقاً بہت کم نہیں تھی، اور اگلی ری اسٹارٹ سے پہلے یہ فرق جاننا مناسب ہے۔