لماذا تبدأ وحدة VPN قبل الشبكة ثم تموت
الوحدة التي تبدأ قبل أن تحصل الوصلة على عنوان تفشل بطريقة تبدو عشوائية. أثبت الترتيب من السجل، ثم أضف الانتظار وإعادة المحاولة.
أقلع الجهاز وسجّل الدخول، ثم اكتشف أن النفق صعد ومات بعد بضع ثوانٍ. كان الملف الشخصي سليمًا، وكانت الشهادة سليمة، والأثر الوحيد المتبقي هو السجل من ذلك الإقلاع. ما حدث عادةً هو سباق: بدأت الوحدة قبل أن يحصل الجهاز على عنوان، والترتيب الذي أعلنته لم يكن يعني ما يبدو عليه. كل ما يلي يدور حول إثبات ذلك السباق من الأدلة وإغلاقه بشكل صحيح.
الهدف نقطة التقاء، لا مديرًا
network-online.target لا يعرف شيئًا عن الشبكة. إنه نقطة تنسيق تجمع أي خدمة يُفترض أن تؤخر بدء التشغيل حتى تصبح الوصلة قابلة للاستخدام، ويُفوّض التعريف إلى مدير الشبكة الذي يملك الجهاز. على معظم الحواسيب والخوادم يعني ذلك خدمة انتظار الاتصال التي توفرها NetworkManager أو systemd-networkd. لا تفعّل أيًّا منهما فيصبح الهدف بلا شيء ينتظره، وبذلك يكتمل في اللحظة التي يسحبه فيها شيء ما، وقد يكون ذلك قبل أن يجيب DHCP بوقت طويل. سطر الترتيب في وحدتك كان صادقًا ومع ذلك عديم الفائدة.
السؤال الأول إذن ليس ما تعلنه وحدتك. بل هل هناك فعلًا شيء على هذا الجهاز يقوم بالانتظار.
اقرأ آخر إقلاع بدلًا من ملف الوحدة
ملفات الوحدات تصف النية، والسجل يصف ما حدث. اطلب ذلك الإقلاع وحده، بطوابع زمنية رتيبة حتى تكون كل رسالة على ساعة واحدة. ثم ابحث عن سطرين: لحظة بدء وحدة النفق، ولحظة ظهور العنوان أو انتهاء خدمة انتظار الاتصال. رتّب هذين الرقمين فيكون السباق إما مؤكدًا أو مستبعدًا.
عرض التبعيات يؤكد ذلك. إذا كانت سلسلة حرجة لوحدة النفق لا تحتوي على خدمة انتظار الاتصال، فلم يؤخر شيء في ذلك المسار بدء التشغيل، ولم يفعل الهدف العمل الذي افترضته. عرضان، استنتاج واحد.
systemctl list-units --type=service --state=running | grep wait-online
journalctl -b -o short-monotonic -u openvpn-client@office
أضف الانتظار، ثم إعادة المحاولة
استخدم ملف drop-in بدلًا من تعديل وحدة معبأة، حتى لا يتجاهل تحديث الحزمة التغيير بصمت. يهم توجيهان: يجب أن تُرتّب الوحدة بعد الهدف، ويجب أن تسحب الهدف إلى المعاملة نفسها. الترتيب وحده لا يستدعي الهدف؛ الرغبة فيه هي التي تفعل.
وحدة عميل OpenVPN المعبأة تحمل كليهما بالفعل. الوحدات المكتوبة يدويًا تحمل عادةً واحدًا أو لا شيء، وهذا يستحق التحقق قبل أن تضيف أي شيء.
[Service]
Restart=on-failure
RestartSec=15
لماذا يكون النوم الثابت فخًا
النوم في ExecStartPre يبدو كإصلاح للترتيب ويتصرف كتأخير مع خطوات إضافية. إنه يبطئ كل إقلاع، بما في ذلك الإقلاعات التي كانت سليمة، ومع ذلك يخسر عندما تستغرق الوصلة وقتًا أطول من الرقم الذي اخترته.
والأسوأ أنه يخفي ما إذا كانت خدمة انتظار الاتصال تعمل، فيظهر الفشل التالي كمشكلة جديدة تمامًا بدلًا من المشكلة نفسها بتوقيت مختلف. تأخير إعادة تشغيل قصير هو الأداة الأفضل: لا يكلف شيئًا في إقلاع سليم ويحوّل سباقًا خاسرًا إلى محاولة أخرى. أبقِ الفترة متواضعة واترك الوحدة تنجح. إذا كانت تعيد التشغيل إلى الأبد، فالملف الشخصي معطوب ولن يغيّر أي قدر من إعادة المحاولة ذلك، لذا اقرأ السجل بدلًا من رفع الفترة.
حين يكون الترتيب صحيحًا وتظل الأسماء تفشل
وحدة نشطة مع مسار نفق تعني أن الترتيب أدى عمله وأن العطل المتبقي يقع في طبقة أعلى. الشكل المعتاد هو إعداد مُحلِّل يطبقه سكربت up الخاص بالنفق قبل أن تكون الوصلة أو المحلل جاهزًا للاحتفاظ به. قارن حالة المحلل أثناء الفشل بحالته بعد إعادة تشغيل وحدة النفق.
إذا أصلحت إعادة التشغيل عمليات البحث، فلديك عيب في ترتيب بدء التشغيل وليس خادم DNS خاطئًا، وهذان يحتاجان إصلاحين مختلفين. ثم أثبت الأمر كله بإقلاع بارد بدلًا من إعادة تشغيل الخدمة، لأن إعادة التشغيل تعمل على شبكة قائمة بالفعل وستخفي بالضبط العيب الذي تطارده. كرّر ذلك مع وصلة بطيئة عن قصد، واعتبر الوحدة التي تعمل فقط عندما تكون الشبكة سريعة لا تزال معطوبة.