نظام جذري للقراءة فقط: حفظ الإعدادات والسجلات وحالة التحديث بأمان
يمكن لنظام ملفات جذري في Linux للقراءة فقط أن يحافظ على ثبات صورة البرنامج أثناء التشغيل المعتاد، لكن المنتج يظل بحاجة إلى حالة قابلة للكتابة. يجب أن تبقى إعدادات الشبكة بعد إعادة التشغيل، وأن تكون للسجلات وجهة محدودة السعة، وأن يحتفظ التحديث بمعلومات كافية للاستعادة. وتتمثل مهمة التصميم في تحديد عمر كل نوع من البيانات، والجهة المسؤولة عنه، وسياسة التعامل مع فشله.
البدء بحصر عمليات الكتابة
لكل خدمة، احصر ما تكتبه، ومتى تكتبه، وأقصى حجم ممكن، وما يحدث عند فشل الكتابة. ضمّن برامج الإقلاع المبكر، وعملاء DHCP، وهوية SSH، وحالة الساعة، وقواعد البيانات، وتفريغات الأعطال. حتى التطبيق الذي يكتب نادرًا قد يمنع بدء التشغيل إذا كان مساره الافتراضي على نقطة تركيب للقراءة فقط.
| فئة البيانات | الموقع المعتاد | السلوك المطلوب |
|---|---|---|
| ملفات النظام الثنائية والإعدادات الافتراضية للمصنع | نظام ملفات جذري للقراءة فقط | استبدالها بتحديث برمجي منضبط |
| مقابس التشغيل وملفات PID والبيانات المؤقتة | tmpfs محدود تحت /run أو /tmp | إعادة إنشائها بعد كل إقلاع |
| إعدادات العميل | مجلد تطبيق دائم | التحقق منها وإدارة إصداراتها وحفظها عبر التحديثات المدعومة |
| هوية الجهاز وبيانات الاعتماد | تخزين دائم مقيّد الوصول أو محمي عتاديًا | تهيئة فريدة وسياسة إعادة ضبط صريحة |
| التشخيصات | منطقة سجلات متطايرة و/أو دائمة محدودة | فرض مدة الاحتفاظ والخصوصية وميزانيات التخزين |
| بيانات التحديث الوصفية ومساحة التحضير | منطقة دائمة محجوزة أو خانة غير نشطة | البقاء عبر انتقالات الاستعادة المطلوبة |
المسارات في الجدول تصف أدوارًا، وليست مخطط تقسيم موحّدًا. تحتاج اللوحة المزودة بـ eMMC، وذاكرة NOR صغيرة، وذاكرة NAND خام إلى تكاملات تخزين مختلفة. اختر نظام الملفات وترتيب التحديث الذي يدعمه BSP ومحمّل الإقلاع وتقنية الذاكرة الفعلية.

اختيار الطبقة غير القابلة للتغيير وحدود الكتابة
SquashFS نظام ملفات مضغوط للقراءة فقط. ويمكن أيضًا تركيب جذر ext4 للقراءة فقط، مع اعتبارات مختلفة للصورة والاستعادة. لا يثبت أي الخيارين وحده أصالة البرنامج الجاري تشغيله. إذا كان التحقق من البرنامج مطلوبًا، فصمّم سلسلة ثقة؛ إذ يتحقق dm-verity من سلامة الكتل مقابل بصمة جذر موثوقة، ويجب دمجه في مسار إقلاع موثوق.
فضّل مسارات قابلة للكتابة خاصة بالتطبيق على جعل /etc بأكمله قابلًا للكتابة. أبقِ الإعدادات الافتراضية داخل الصورة واحفظ تعديلات العميل الصريحة بصورة منفصلة. وبالنسبة إلى البرامج القديمة التي تتطلب مسارًا ثابتًا، يمكن للتركيب الرابط bind mount عرض مجلد التطبيق الدائم في ذلك الموقع. أنشئ نقاط التركيب ضمن الصورة وحدّد الملكية قبل تشغيل الخدمة.
يمكن لطبقة OverlayFS تغطي الجذر كله دعم برامج ذات مسارات كتابة كثيرة مثبتة في الشيفرة، لكنها تضيف سلوكًا يجب مراعاته عند التحديث. فقد يخفي ملف قديم في الطبقة العليا ملفًا مصحّحًا في الصورة السفلى الجديدة. وقد تُبقي علامات الحذف أيضًا منظورًا قديمًا. حدّد ما إذا كانت الطبقة العليا قابلة للإهمال، أو ستُرحّل، أو مرتبطة بجيل محدد من الصورة.
عند استخدام OverlayFS، يجب أن يدعم نظام الملفات العلوي القابل للكتابة السمات الممتدة ومعلومات عناصر المجلد المطلوبة؛ ويجب أن يكون مجلد العمل فارغًا وعلى نظام الملفات نفسه الذي يضم المجلد العلوي. راجع وثائق OverlayFS الخاصة بالنواة وفق النواة المنشورة فعليًا. لا تتعامل مع نسخ نوى المورّدين المختلفة باعتبارها قابلة للاستبدال دون تحقق.
اعتبار ترتيب الإقلاع شرطًا للصحة
ركّب التخزين الدائم، وتحقّق من هويته وتخطيطه المتوقعين، وهيّئ المجلدات المطلوبة، ونفّذ أي ترحيل معتمد، ثم شغّل التطبيقات. لا تنتقل بصمت إلى مجلد RAM فارغ عند غياب إعداد دائم أساسي. اختر وضع استعادة واضحًا أو وضع وظائف محدودة موثّقًا.
في التطبيق القديم، يوضّح المثال التالي علاقة المسارات بعد نجاح تركيب وحدة البيانات. يجب أن يكون المجلدان موجودين مسبقًا وأن تتطابق صلاحياتهما مع حساب الخدمة. ادمج الخطوات في نظام التهيئة المختار بدل تنفيذها في وقت متأخر من الإقلاع.
# /data is the verified, mounted persistent filesystem.
# /etc/myapp is a mount point created in the rootfs image.
mount --bind /data/config/myapp /etc/myapp
# Start myapp only after this mount succeeds.
تعبّر اعتماديات systemd ونصوص BusyBox/SysV عن ترتيب التشغيل بطرق مختلفة. افحص هيكل Buildroot الفعلي واختيار نظام التهيئة ونصوص الخدمات. افحص /proc/mounts على الجهاز لمعرفة ما تم تركيبه فعليًا، بما في ذلك احتمال بقاء مجلد عادي تحت نقطة تركيب فشلت.
حفظ الإعدادات عند انقطاع الكتابة
تحقّق من الإعداد الجديد قبل تفعيله. في تنسيق الملف الواحد، تسلسل تثبيت شائع على مستوى التطبيق هو كتابة ملف مؤقت في المجلد نفسه، ومزامنته مع التخزين، ثم إعادة تسميته ليحل محل الملف الحالي، ثم مزامنة المجلد. افحص كل قيمة إرجاع واحتفظ بجيل معروف السلامة عندما يتطلب المنتج الاستعادة.
validate(candidate)
write(temp_in_same_directory, candidate)
fsync(temp_file)
rename(temp_file, active_file)
fsync(parent_directory)
report_success()
هذه شيفرة شبهية وليست أداة جاهزة للتنفيذ. طبّق صلاحيات الملف قبل إتاحته، وتعامل مع الكتّاب المتزامنين، واستخدم قاعدة بيانات معاملية عندما يجب أن تتغير عدة سجلات معًا. تشرح وثائق fsync في Linux سبب عدم ضمان حفظ عنصر المجلد بمجرد مزامنة الملف. وتظل متانة البيانات معتمدة على نظام الملفات وبرنامج التشغيل وجهاز التخزين؛ لذا اختبر فقدان الطاقة على العتاد الفعلي.
ميزانيات منفصلة للسجلات والملفات المؤقتة
يستخدم tmpfs الذاكرة الافتراضية، ويمكنه استخدام مساحة التبديل إذا كانت مفعّلة، ويفقد محتوياته عند إلغاء تركيبه. حدّد سقفًا للبايتات وعدد inode، وأدرج هذه الميزانية في اختبار ذروة الذاكرة. فقد يجعل مجلد سجلات RAM كبير وغير محدود تطبيقًا سليمًا في بقية جوانبه ينفد من الذاكرة.
في الصور المعتمدة على systemd، يحفظ Storage=volatile بيانات journal تحت /run/log/journal، بينما يستخدم الوضع الدائم /var/log/journal عند توافره. اضبط RuntimeMaxUse أو SystemMaxUse بحسب الوضع، وفق وثائق journald للإصدار المسلّم. ويحتاج BusyBox syslog إلى إعداداته الخاصة للحجم والتدوير والوجهة.
احجز مساحة للإعدادات والتحديثات مستقلةً عن التشخيصات الكثيفة. المجلدات على نظام ملفات واحد لا تعزل السعة بذاتها؛ استخدم حصصًا أو أقسامًا أو حجوزات صريحة مناسبة. حدّد الأحداث التي يجب أن تبقى بعد فقدان الطاقة، واحجب بيانات الاعتماد. ولا يفيد التسجيل البعيد إلا إذا كان سلوك فقد الاتصال ونمو الطوابير وفجوات التسليم محددًا.
تصميم الاستمرارية مع الرجوع إلى الإصدار السابق
لا توفّر خانات البرامج A/B بيانات تطبيق A/B تلقائيًا. قد يرحّل التطبيق الجديد قاعدة بيانات مشتركة إلى تنسيق لا يستطيع التطبيق القديم قراءته. تشمل الخيارات مخططات متوافقة مع الإصدارات السابقة، أو أجيال بيانات منفصلة، أو مسار استعادة مختبرًا صراحةً. تناقش إرشادات RAUC لتخزين البيانات الأقسام المشتركة والمتكررة، وتوضّح أن الترحيل يتطلب معالجة خاصة بالمنتج.
امنع ملفات تحضير التحديث من استنفاد مساحة الإعدادات. ميّز بين حزمة منزّلة، وحزمة تم التحقق منها، وخانة إقلاع مختارة، وإقلاع سليم تم تأكيده. احفظ بصورة دائمة فقط الحالة التي يحتاجها إطار التحديث المختار. يجب أن يكون لإعادة ضبط المصنع اتفاق مكتوب يحدّد ما إذا كانت تمسح إعدادات العميل والسجلات المحفوظة وبيانات الاعتماد وهوية الجهاز؛ فهذه الفئات غالبًا ما تحتاج إلى معالجة مختلفة.
اختبارات القبول واستكشاف الأخطاء
| العطل المحقون | النتيجة المتوقعة المطلوب تحديدها | أول أدلة يجب فحصها |
|---|---|---|
| فصل الطاقة أثناء تثبيت الإعداد | جيل سابق أو جديد صالح، دون قبول إعدادات تالفة بصمت | التحقق من الإعداد وعلامات الأجيال وأخطاء نظام الملفات |
| غياب وحدة التخزين الدائمة أو تلفها | سلوك الاستعادة الموثّق | سجل التركيب وهوية الجهاز وترتيب تشغيل التطبيق |
| نفاد بايتات السجلات أو inode | الاستمرار في احترام سياسة الإعدادات والتحديث | سعة نظام الملفات واستخدام inode وأخطاء مسجّل الأحداث |
| تحديث يتبعه رجوع | قدرة البرنامج القديم على استخدام البيانات المحفوظة أو المستعادة | إصدارات المخططات وسجل الترحيل |
| إقلاع بارد بعد استخدام كثيف للملفات المؤقتة | إعادة بناء حالة التشغيل ضمن ميزانية الذاكرة | حدود tmpfs وسجلات ذروة الذاكرة |
| نظام جذري جديد مع طبقة تراكب قائمة | ظهور الإعدادات الافتراضية والملفات الثنائية المحدّثة كما هو مقصود | ملفات الطبقة العليا وعلامات الحذف وسياسة الترحيل |
إذا اختفت الإعدادات، فتحقّق أولًا من أن مسار الكتابة دائم ومركّب قبل الاستخدام. وإذا استمر السلوك القديم بعد التحديث، فافحص حجب طبقة التراكب والإعدادات المحفوظة. وإذا أبلغت خدمة عن «نظام ملفات للقراءة فقط»، فحدّد محاولة الكتابة نفسها بدل إعادة تركيب الجذر كله للقراءة والكتابة. تتطلب هذه الاختبارات حقن أعطال منضبطًا في المختبر وإجراء استعادة متفقًا عليه؛ ولا تُدّعى هنا نتائج اختبار فقدان طاقة.
تُعد خدمة Obeita لتشخيص البرمجيات الثابتة وBSP نقطة مناسبة لمراجعة التخزين والإقلاع. ويوفّر مشروع واجهة HMI على Linux/Qt المسلّم سياقًا مرتبطًا بالطرفيات. ولا يمثل هذا المثال دليلًا على التحقق من بنية حفظ البيانات الموضّحة هنا.