مرحبًا بالجميع، نشارككم الجزء الثاني من منشور "أنظمة الملفات الافتراضية في Linux: لماذا هناك حاجة إليها وكيف تعمل؟" يمكنك قراءة الجزء الأول
كيفية مراقبة VFS باستخدام أدوات eBPF وbcc
أسهل طريقة لفهم كيفية عمل النواة على الملفات sysfs
هو رؤيته عمليًا، وأسهل طريقة لمشاهدة ARM64 هي استخدام eBPF. يتكون eBPF (اختصار لـ Berkeley Packet Filter) من جهاز افتراضي يعمل في query
) من سطر الأوامر. تخبر مصادر النواة القارئ بما يمكن أن تفعله النواة؛ يؤدي تشغيل أدوات eBPF على نظام محمل إلى إظهار ما تفعله النواة بالفعل.
لحسن الحظ، يعد البدء في استخدام eBPF أمرًا سهلاً للغاية بمساعدة الأدوات bcc
هي نصوص بايثون تحتوي على إدخالات صغيرة من كود C، مما يعني أن أي شخص على دراية باللغتين يمكنه تعديلها بسهولة. في bcc/tools
يوجد 80 نصًا برمجيًا لـ Python، مما يعني أنه من المرجح أن يتمكن المطور أو مسؤول النظام من اختيار شيء مناسب لحل المشكلة.
للحصول على فكرة سطحية على الأقل عن العمل الذي تقوم به VFS على نظام التشغيل، حاول vfscount
أو vfsstat
. سيُظهر هذا، على سبيل المثال، عشرات المكالمات vfs_open()
و"أصدقاؤه" يحدثون حرفيًا في كل ثانية.
vfsstat.py
هو برنامج نصي بلغة Python يحتوي على إدخالات كود C والتي تقوم ببساطة بحساب استدعاءات وظائف VFS.
دعونا نعطي مثالًا أكثر بساطة ونرى ما يحدث عندما نقوم بإدخال محرك أقراص فلاش USB في جهاز الكمبيوتر ويكتشفه النظام.
باستخدام eBPF يمكنك رؤية ما يحدث في
/sys
عند إدخال محرك أقراص فلاش USB. يظهر هنا مثال بسيط ومعقد.
في المثال الموضح أعلاه، bcc
أداة sysfs_create_files()
. نحن نرى ذلك sysfs_create_files()
تم إطلاقه باستخدام kworker
تيار ردا على حقيقة أنه تم إدراج محرك أقراص فلاش، ولكن تم إنشاء الملف ما؟ يوضح المثال الثاني قوة eBPF. هنا trace.py
يطبع تتبع kernel backtrace (خيار -K) واسم الملف الذي تم إنشاؤه sysfs_create_files()
. إدراج عبارة واحدة هو كود C الذي يتضمن سلسلة تنسيق يسهل التعرف عليها مقدمة من برنامج Python النصي الذي يقوم بتشغيل LLVM مترجم في الوقت المناسب. يقوم بتجميع هذا الخط وتنفيذه في جهاز افتراضي داخل النواة. توقيع الوظيفة الكاملة sysfs_create_files ()
يجب إعادة إنتاجه في الأمر الثاني حتى تتمكن سلسلة التنسيق من الإشارة إلى إحدى المعلمات. تؤدي الأخطاء في هذا الجزء من كود C إلى أخطاء يمكن التعرف عليها من مترجم C. على سبيل المثال، إذا تم حذف المعلمة -l، فسترى "فشل في ترجمة نص BPF." سيجد المطورون الذين هم على دراية بـ C وPython الأدوات bcc
من السهل التوسع والتغيير.
عند إدخال محرك أقراص USB، سيُظهر التتبع الخلفي للنواة أن PID 7711 عبارة عن خيط kworker
الذي أنشأ الملف «events»
в sysfs
. وبناء على ذلك، المكالمة من sysfs_remove_files()
سيظهر أن إزالة محرك الأقراص أدى إلى حذف الملف events
، وهو ما يتوافق مع المفهوم العام للعد المرجعي. وفي نفس الوقت المشاهدة sysfs_create_link ()
باستخدام eBPF أثناء إدخال محرك أقراص USB، سيُظهر أنه تم إنشاء 48 رابطًا رمزيًا على الأقل.
فما فائدة ملف الأحداث إذن؟ الاستخدام disk_add_events ()
، وإما "media_change"
أو "eject_request"
يمكن تسجيلها في ملف الحدث. هنا تُعلم طبقة كتلة kernel مساحة المستخدمين بظهور "قرص" وإخراجه. لاحظ مدى إفادة طريقة البحث هذه عن طريق إدخال محرك أقراص USB، مقارنة بمحاولة معرفة كيفية عمل الأشياء من المصدر فقط.
تعمل أنظمة الملفات الجذرية للقراءة فقط على تمكين الأجهزة المدمجة
وبطبيعة الحال، لا أحد يقوم بإيقاف تشغيل الخادم أو جهاز الكمبيوتر الخاص به عن طريق سحب القابس من المقبس. لكن لماذا؟ وذلك لأن أنظمة الملفات المثبتة على أجهزة التخزين الفعلية قد تكون بها عمليات كتابة متأخرة، وقد لا تتم مزامنة هياكل البيانات التي تسجل حالتها مع عمليات الكتابة إلى وحدة التخزين. عندما يحدث هذا، يتعين على مالكي النظام الانتظار حتى التمهيد التالي لتشغيل الأداة المساعدة. fsck filesystem-recovery
وفي أسوأ الحالات، فقدان البيانات.
ومع ذلك، نعلم جميعًا أن العديد من أجهزة إنترنت الأشياء، بالإضافة إلى أجهزة التوجيه وأجهزة تنظيم الحرارة والسيارات، تعمل الآن بنظام التشغيل Linux. تحتوي العديد من هذه الأجهزة على واجهة مستخدم قليلة أو معدومة، ولا توجد طريقة لإيقاف تشغيلها "بشكل نظيف". تخيل أنك بدأت تشغيل سيارة ببطارية فارغة عندما تكون الطاقة متصلة بوحدة التحكم fsck
متى يبدأ المحرك في العمل أخيرًا؟ والاجابه بسيطه. تعتمد الأجهزة المضمنة على نظام الملفات الجذر ro-rootfs
(ملف الجذر للقراءة فقط)).
ro-rootfs
تقدم العديد من الفوائد التي هي أقل وضوحا من الأصالة. إحدى المزايا هي أن البرامج الضارة لا يمكنها الكتابة إليها /usr
أو /lib
، إذا لم تتمكن عملية Linux من الكتابة هناك. والسبب الآخر هو أن نظام الملفات غير القابل للتغيير إلى حد كبير يعد أمرًا بالغ الأهمية للدعم الميداني للأجهزة البعيدة، نظرًا لأن موظفي الدعم يعتمدون على الأنظمة المحلية المتطابقة اسميًا مع الأنظمة الميدانية. ربما تكون الفائدة الأكثر أهمية (ولكنها أيضًا الأكثر خبثًا) هي أن ro-rootfs يجبر المطورين على تحديد كائنات النظام التي ستكون غير قابلة للتغيير في مرحلة تصميم النظام. يمكن أن يكون العمل مع ro-rootfs أمرًا صعبًا ومؤلمًا، نظرًا لأن متغيرات const غالبًا ما تكون موجودة في لغات البرمجة، ولكن فوائدها تبرر بسهولة النفقات الإضافية.
خلق rootfs
تتطلب القراءة فقط بعض الجهد الإضافي للمطورين المضمنين، وهنا يأتي دور VFS في الصورة. يتطلب Linux أن تكون الملفات موجودة /var
كانت قابلة للكتابة، وبالإضافة إلى ذلك، فإن العديد من التطبيقات الشائعة التي تقوم بتشغيل الأنظمة المضمنة ستحاول إنشاء التكوين dot-files
в $HOME
. عادةً ما يكون أحد الحلول لملفات التكوين الموجودة في الدليل الرئيسي هو الإنشاء المسبق لها وإدراجها فيها rootfs
. إلى /var
أحد الأساليب الممكنة هو تثبيته على قسم منفصل قابل للكتابة، بينما /
شنت للقراءة فقط. البديل الشائع الآخر هو استخدام أدوات الربط أو التراكب.
حوامل قابلة للربط والتكديس، واستخدامها بواسطة الحاويات
تنفيذ أمر man mount
هي أفضل طريقة للتعرف على التركيبات القابلة للربط والتراكب، والتي تمنح المطورين ومسؤولي النظام القدرة على إنشاء نظام ملفات في مسار واحد ثم تعريضه للتطبيقات في مسار آخر. بالنسبة للأنظمة المدمجة، هذا يعني القدرة على تخزين الملفات فيها /var
على محرك أقراص فلاش للقراءة فقط، ولكن مسار تحميل متراكب أو قابل للربط من tmpfs
в /var
عند التحميل، سيسمح للتطبيقات بكتابة الملاحظات هناك (الخربشة). في المرة التالية التي تقوم فيها بتشغيل التغييرات على /var
ستكون ضائعا. يؤدي تركيب التراكب إلى إنشاء اتحاد بين tmpfs
ونظام الملفات الأساسي ويسمح لك بإجراء تغييرات ظاهرية على الملفات الموجودة فيه ro-tootf
في حين أن التركيب القابل للربط يمكن أن يجعل التركيبات الجديدة فارغة tmpfs
المجلدات مرئية للكتابة فيها ro-rootfs
طرق. بينما overlayfs
وهذا هو الحق واحد (proper
) نوع نظام الملفات، يتم تنفيذ التثبيت القابل للربط فيه
بناءً على وصف التراكب والتركيب القابل للربط، لا أحد يتفاجأ بذلك mountsnoop
من bcc
.
دعوة system-nspawn
يبدأ الحاوية أثناء التشغيل mountsnoop.py
.
دعونا نرى ما حدث:
إطلاق mountsnoop
أثناء "تمهيد" الحاوية يظهر أن وقت تشغيل الحاوية يعتمد بشكل كبير على التثبيت الذي يتم ربطه (يتم عرض بداية الإخراج الطويل فقط).
ومن systemd-nspawn
يوفر الملفات المحددة في procfs
и sysfs
المضيف للحاوية كمسارات إليها rootfs
. الى جانب ذلك MS_BIND
العلامة التي تقوم بإعداد رابط الربط، تحدد بعض العلامات الأخرى الموجودة على الحامل العلاقة بين التغييرات في مساحات أسماء المضيف والحاوية. على سبيل المثال، يمكن للتثبيت المرتبط إما تخطي التغييرات إلى /proc
и /sys
في الحاوية، أو إخفائها حسب المكالمة.
اختتام
قد يبدو فهم الأعمال الداخلية لنظام التشغيل Linux بمثابة مهمة مستحيلة، نظرًا لأن النواة نفسها تحتوي على كمية هائلة من التعليمات البرمجية، مما يترك جانبًا تطبيقات مساحة مستخدم Linux وواجهات استدعاء النظام في مكتبات C مثل glibc
. إحدى الطرق لإحراز التقدم هي قراءة الكود المصدري لنظام فرعي واحد للنواة، مع التركيز على فهم استدعاءات النظام ورؤوس مساحة المستخدم، بالإضافة إلى واجهات النواة الداخلية الرئيسية، مثل الجدول file_operations
. توفر عمليات الملفات مبدأ "كل شيء عبارة عن ملف"، مما يجعل إدارتها ممتعة بشكل خاص. ملفات مصدر kernel C في دليل المستوى الأعلى fs/
تقديم تطبيق لأنظمة الملفات الافتراضية، وهي عبارة عن طبقة مجمعة توفر توافقًا واسعًا وبسيطًا نسبيًا بين أنظمة الملفات الشائعة وأجهزة التخزين. يعد الربط والتركيب عبر مساحات أسماء Linux هو سحر VFS الذي يجعل إنشاء حاويات للقراءة فقط وأنظمة ملفات الجذر أمرًا ممكنًا. بالإضافة إلى فحص الكود المصدري وأداة eBPF الأساسية وواجهتها bcc
مما يجعل الاستكشاف الأساسي أسهل من أي وقت مضى.
أيها الأصدقاء، اكتبوا، هل كانت هذه المقالة مفيدة لكم؟ ربما لديك أي تعليقات أو ملاحظات؟ والمهتمون بدورة Linux Administrator مدعوون إليها
المصدر: www.habr.com