DAEMON(7)

الاسم
daemon - كتابة وتعبئة دايمونات النظام

الوصف

الدايمون هو عملية خدمة تعمل في الخلفية وتشرف على النظام أو توفر وظائف لعمليات أخرى. تقليديًا، تُنفذ الدايمونات وفق مخطط نشأ في يونكس SysV. يجب أن تتبع الدايمونات الحديثة مخططًا أبسط لكنه أكثر قوة (يسمى هنا "دايمونات النمط الجديد")، كما ينفذه systemd(1). تغطي صفحة الدليل هذه كلا المخططين، وتتضمن بشكل خاص توصيات للدايمونات التي ينبغي تضمينها في نظام init الخاص بـ systemd.

  دايمونات SysV

عند بدء دايمون SysV تقليدي، يجب أن ينفذ الخطوات التالية كجزء من التهيئة. لاحظ أن هذه الخطوات غير ضرورية للدايمونات ذات النمط الجديد (انظر أدناه)، ويجب تنفيذها فقط إذا كان التوافق مع SysV ضروريًا.

    1. أغلق جميع واصفات الملفات المفتوحة باستثناء الإدخال والإخراج والخطأ القياسي (أي واصفات الملفات الثلاثة الأولى 0 و1 و2). يضمن هذا عدم بقاء أي واصف ملفات مُرر عن طريق الخطأ في عملية الدايمون. في لينكس، يُنفذ هذا بشكل أفضل من خلال التكرار عبر /proc/self/fd، مع خيار احتياطي للتكرار من واصف الملفات 3 إلى القيمة التي يعيدها getrlimit() لـ RLIMIT_NOFILE.

    2. أعد تعيين جميع معالجات الإشارات إلى حالتها المبدئية. يُنفذ هذا بشكل أفضل من خلال التكرار عبر الإشارات المتاحة حتى حد _NSIG وإعادة تعيينها إلى SIG_DFL.

    3. أعد تعيين قناع الإشارة باستخدام sigprocmask().

    4. عقم كتلة البيئة، بإزالة أو إعادة تعيين متغيرات البيئة التي قد تؤثر سلبًا على وقت تشغيل الدايمون.

    5. استدع fork()، لإنشاء عملية خلفية.

    6. في العملية الابنة، استدع setsid() للانفصال عن أي طرفية وإنشاء جلسة مستقلة.

    7. في العملية الابنة، استدع fork() مرة أخرى، لضمان أن الدايمون لا يمكنه أبدًا إعادة اكتساب طرفية مرة أخرى. (هذا ذو صلة إذا كان البرنامج — وجميع تبعياته — لا يحدد بعناية `O_NOCTTY` في كل استدعاء `open()` قد يفتح عقدة جهاز TTY.)

    8. استدع exit() في العملية الابنة الأولى، بحيث تبقى فقط العملية الابنة الثانية (عملية الدايمون الفعلية). يضمن هذا إعادة تبعية عملية الدايمون إلى init/PID 1، كما ينبغي لجميع الدايمونات.

    9. في عملية الدايمون، اربط /dev/null بالإدخال والإخراج والخطأ القياسي.

    10. في عملية الدايمون، أعد تعيين umask إلى 0، بحيث تتحكم أوضاع الملفات الممررة إلى open() وmkdir() وما شابه مباشرة في وضع الوصول للملفات والأدلة المنشأة.

    11. في عملية الدايمون، غير الدليل الحالي إلى الدليل الجذر (/)، لتجنب أن يمنع الدايمون نقاط الوصل من الفصل بشكل غير إرادي.

    12. في عملية الدايمون، اكتب PID الدايمون (كما يعيده getpid()) إلى ملف PID، على سبيل المثال /run/foobar.pid (لدايمون افتراضي "foobar") لضمان عدم بدء الدايمون أكثر من مرة. يجب تنفيذ هذا بطريقة خالية من السباق بحيث يُحدث ملف PID فقط عندما يُتحقق في نفس الوقت من أن PID المخزن سابقًا في ملف PID لم يعد موجودًا أو ينتمي إلى عملية أجنبية.

    13. في عملية الدايمون، أسقط الامتيازات، إذا كان ذلك ممكنًا ومناسبًا.

    14. من عملية الدايمون، أبلغ العملية الأصلية التي بدأت أن التهيئة اكتملت. يمكن تنفيذ هذا عبر أنبوب غير مسمى أو قناة اتصال مماثلة تُنشأ قبل أول fork() وبالتالي تكون متاحة في كل من العملية الأصلية وعملية الدايمون.

    15. استدع exit() في العملية الأصلية. يجب أن تكون العملية التي استدعت الدايمون قادرة على الاعتماد على أن هذا exit() يحدث بعد اكتمال التهيئة وإنشاء جميع قنوات الاتصال الخارجية وجعلها قابلة للوصول.

لا ينبغي استخدام دالة BSD daemon()، لأنها تنفذ فقط مجموعة فرعية من هذه الخطوات.

الدايمون الذي يحتاج إلى توفير التوافق مع أنظمة SysV يجب أن ينفذ المخطط المشار إليه أعلاه. ومع ذلك، يُوصى بجعل هذا السلوك اختياريًا وقابلًا للتكوين عبر وسيط سطر أوامر لتسهيل التنقيح وكذلك لتبسيط التكامل في الأنظمة التي تستخدم systemd.

  دايمونات النمط الجديد

يجب تنفيذ الخدمات الحديثة للينكس كدايمونات ذات نمط جديد. هذا يجعل الإشراف عليها والتحكم بها في وقت التشغيل أسهل ويبسط تنفيذها.

لتطوير دايمون ذي نمط جديد، لا حاجة لتنفيذ أي من خطوات التهيئة الموصى بها لدايمونات SysV. أنظمة init ذات النمط الجديد مثل systemd تجعلها جميعًا زائدة عن الحاجة. علاوة على ذلك، نظرًا لأن بعض هذه الخطوات تتداخل مع مراقبة العملية وتمرير واصف الملفات ووظائف أخرى لمدير الخدمة، يُوصى بعدم تنفيذها عند التشغيل كخدمة ذات نمط جديد.

لاحظ أن أنظمة التهيئة ذات النمط الجديد تضمن تنفيذ عمليات الدايمون في سياق عملية نظيف: يُضمن تعقيم كتلة البيئة، وإعادة تعيين معالجات الإشارات والقناع، وعدم تمرير واصفات ملفات متبقية. ستُنفذ الدايمونات في جلسة خاصة بها، مع توصيل الإدخال القياسي بـ /dev/null والإخراج/الخطأ القياسي بخدمة التسجيل systemd-journald.service(8)، ما لم يُهيأ خلاف ذلك. كما يُعاد تعيين umask.

يُوصى للدايمونات ذات النمط الجديد بتنفيذ ما يلي:

    1. إذا كان ذلك مناسبًا، يجب على الدايمون إخطار مدير الخدمة باكتمال بدء التشغيل أو تحديثات الحالة عبر واجهة sd_notify(3)، خاصة READY=1 و STATUS=....

    2. إذا استُلمت SIGTERM، فأوقف الدايمون واخرج بشكل نظيف. يجب إرسال إشعار STOPPING=1 عبر sd_notify(3).

    3. إذا استُلمت SIGHUP، فأعد تحميل ملفات التهيئة، إذا كان ذلك مناسبًا. يجب دمج هذا مع الإشعارات عبر sd_notify(3): RELOADING=1 و READY=1.

    4. قدم رمز خروج صحيح من عملية الدايمون الرئيسة، حيث يُستخدم هذا من قبل مدير الخدمة لاكتشاف أخطاء الخدمة ومشاكلها. يوصى باتباع مخطط رمز الخروج كما هو معرف في توصيات LSB لنصوص تهيئة SysV[1].

    5. إذا كان ذلك ممكنًا ومناسبًا، اكشف واجهة التحكم في الدايمون عبر نظام D-Bus IPC واحصل على اسم ناقل كخطوة أخيرة من التهيئة.

    6. للتكامل في systemd، قدم ملف وحدة .service يحمل معلومات حول بدء وإيقاف وصيانة الدايمون. انظر systemd.service(5) للتفاصيل.

    7. اعتمد قدر الإمكان على وظائف مدير الخدمة لتقييد وصول الدايمون إلى الملفات والخدمات والموارد الأخرى، أي في حالة systemd، اعتمد على التحكم في حدود الموارد الخاص بـ systemd بدلاً من تنفيذ حدودك الخاصة، واعتمد على كود إسقاط الامتيازات الخاص بـ systemd بدلاً من تنفيذه في الدايمون، وهكذا. انظر systemd.exec(5) لعناصر التحكم المتاحة.

    8. إذا استُخدم D-Bus، فاجعل الدايمون الخاص بك قابلاً للتفعيل عبر الناقل بتوفير ملف تهيئة تفعيل خدمة D-Bus. هذا له مزايا متعددة: يمكن بدء الدايمون الخاص بك بشكل كسول عند الطلب؛ كما يمكن بدؤه بالتوازي مع دايمونات أخرى تحتاجه — مما يعظم التوازي وسرعة الإقلاع؛ ويمكن إعادة تشغيل الدايمون عند الفشل دون فقدان أي طلبات ناقل، حيث يقوم الناقل بصف الطلبات للخدمات القابلة للتفعيل. انظر أدناه للتفاصيل.

    9. إذا كان الدايمون يوفر خدمات لعمليات محلية أخرى أو عملاء بعيدين عبر مقبس، فيجب جعله قابلاً للتفعيل عبر المقبس باتباع المخطط الموضح أدناه. مثل تفعيل D-Bus، يُمكّن هذا من بدء الخدمات عند الطلب ويسمح بتحسين توازي بدء الخدمات. أيضًا، للبروتوكولات عديمة الحالة (مثل syslog، DNS)، يمكن إعادة تشغيل دايمون ينفذ التفعيل القائم على المقبس دون فقدان أي طلب. انظر أدناه للتفاصيل.

    10. إذا فتحت الخدمة مقابس أو ملفات أخرى بنفسها، وكان يجب أن تبقى واصفات الملفات تلك بعد إعادة التشغيل، فيجب على الدايمون تخزينها في مدير الخدمة عبر sd_notify(3) مع FDSTORE=1.

    11. بدلاً من استخدام استدعاء syslog() للتسجيل مباشرة في خدمة syslog للنظام، قد يختار دايمون ذو نمط جديد التسجيل ببساطة إلى الخطأ القياسي عبر fprintf()، والذي يُوجه بعد ذلك إلى syslog. إذا كانت مستويات التسجيل ضرورية، فيمكن ترميزها بإضافة بادئات لأسطر التسجيل الفردية بسلاسل مثل "<4>" (لمستوى التسجيل 4 "WARNING" في مخطط أولوية syslog)، باتباع نمط مشابه لنظام مستوى printk() في نواة لينكس. للتفاصيل، انظر sd-daemon(3) و systemd.exec(5).

    12. بما أن الدايمونات ذات النمط الجديد تُستدعى بدون TTY تحكم (ولكن كقادة جلسات خاصة بهم)، فيجب توخي الحذر لتحديد O_NOCTTY دائمًا في استدعاءات open(2) التي قد تشير إلى عقدة جهاز TTY، بحيث لا يُستحوذ على TTY تحكم عن طريق الخطأ.

تتشابه هذه التوصيات ولكنها ليست مطابقة لـ متطلبات دايمون Apple MacOS X[2].

التفعيل

توفر أنظمة التهيئة ذات النمط الجديد آليات إضافية متعددة لتفعيل الخدمات، كما هو مفصل أدناه. من الشائع أن تُهيأ الخدمات ليتم تفعيلها عبر أكثر من آلية في نفس الوقت. مثال لـ systemd: قد يتم تفعيل bluetoothd.service إما عند توصيل أجهزة بلوتوث، أو عند وصول تطبيق إلى واجهات برمجته عبر D-Bus. أو، قد يتم تفعيل دايمون خادم طباعة عند وصول حركة مرور إلى منفذ IPP، أو عند توصيل طابعة، أو عند وضع ملف في قائمة انتظار دليل الطباعة. حتى للخدمات التي يُعتزم بدؤها عند إقلاع النظام دون شروط، من الجيد تنفيذ بعض مخططات التفعيل المختلفة الموضحة أدناه، لتعظيم التوازي. إذا نفذ دايمون خدمة D-Bus أو مقبس استماع، فإن تنفيذ مخطط التفعيل الكامل للناقل والمقبس يسمح ببدء الدايمون مع عملائه بالتوازي (مما يسرع الإقلاع)، بما أن جميع قنوات الاتصال الخاصة به قد أُنشئت بالفعل، ولا يُفقد أي طلب لأن طلبات العميل ستُصطف بواسطة نظام الناقل (في حالة D-Bus) أو النواة (في حالة المقابس) حتى اكتمال التفعيل.

  التفعيل عند الإقلاع

عادة ما يتم تفعيل الدايمونات القديمة حصريًا عند الإقلاع (ويدويًا بواسطة المسؤول) عبر نصوص تهيئة SysV، كما هو مفصل في مواصفات LSB الأساسية لنظام لينكس القياسي[1]. من بين مشكلات أخرى، نصوص تهيئة SysV لها عيب إشراك نصوص صدفة في عملية الإقلاع. تم إلغاء دعم نصوص التهيئة تدريجيًا في أنظمة لينكس الحديثة، ولا ينبغي الاعتماد عليها. تستخدم أنظمة التهيئة ذات النمط الجديد بشكل عام إصدارات محدثة من التفعيل، سواء أثناء الإقلاع أو أثناء وقت التشغيل، وباستخدام ملفات وصف خدمة أكثر بساطة.

في systemd، إذا أراد المطور أو المسؤول التأكد من تفعيل خدمة أو وحدة أخرى آليًا عند الإقلاع، يوصى بوضع رابط رمزي لملف الوحدة في دليل .wants/ الخاص بـ multi-user.target أو graphical.target، واللذين يُستخدمان عادة كأهداف إقلاع عند بدء النظام. انظر systemd.unit(5) للتفاصيل حول أدلة .wants/، و systemd.special(7) للتفاصيل حول هدفي الإقلاع.

  التفعيل القائم على المقبس

من أجل تعظيم التوازي والمتانة الممكنة وتبسيط التهيئة والتطوير، يُوصى لجميع الدايمونات ذات النمط الجديد التي تتصل عبر مقابس استماع باستخدام التفعيل القائم على المقبس. في مخطط التفعيل القائم على المقبس، يُنقل إنشاء وربط مقبس الاستماع كقناة اتصال رئيسة للدايمونات إلى العملاء المحليين (وأحيانًا البعيدين) من كود الدايمون إلى مدير الخدمة. بناءً على تهيئة كل دايمون، يثبت مدير الخدمة المقابس ثم يسلمها إلى العملية المولدة بمجرد بدء تشغيل الدايمون المعني. اختياريًا، يمكن تأخير تفعيل الخدمة حتى وصول أول حركة مرور واردة إلى المقبس لتنفيذ التفعيل عند الطلب للدايمونات. ومع ذلك، فإن الميزة الرئيسة لهذا المخطط هي أنه يمكن بدء جميع مزودي ومستهلكي المقابس بالتوازي بمجرد إنشاء جميع المقابس. بالإضافة إلى ذلك، يمكن إعادة تشغيل الدايمونات مع فقدان الحد الأدنى فقط من معاملات العميل، أو حتى عدم فقدان أي طلب عميل على الإطلاق (الأخير ينطبق بشكل خاص على البروتوكولات عديمة الحالة، مثل DNS أو syslog)، لأن المقبس يبقى مربوطًا وقابلاً للوصول أثناء إعادة التشغيل، وتُصف جميع الطلبات بينما لا يستطيع الدايمون معالجتها.

يجب أن تكون الدايمونات ذات النمط الجديد التي تدعم تفعيل المقبس قادرة على استقبال مقابسهما من مدير الخدمة بدلاً من إنشائها وربطها بأنفسها. للتفاصيل حول واجهات البرمجة لهذا المخطط التي يوفرها systemd، انظر sd_listen_fds(3) و sd-daemon(3). للتفاصيل حول نقل الدايمونات الموجودة إلى التفعيل القائم على المقبس، انظر أدناه. بجهد ضئيل، يمكن تنفيذ التفعيل القائم على المقبس بالإضافة إلى إنشاء المقبس الداخلي التقليدي في نفس قاعدة الكود لدعم كل من أنظمة init ذات النمط الجديد والقديم من نفس ملف الدايمون الثنائي.

ينفذ systemd التفعيل القائم على المقبس عبر وحدات .socket، الموصوفة في systemd.socket(5). عند تهيئة وحدات المقابس للتفعيل القائم على المقبس، من الضروري جلب جميع مقابس الاستماع بواسطة وحدة الهدف الخاصة sockets.target. يوصى بوضع توجيه WantedBy=sockets.target في قسم [Install] لإضافة هذا الاعتماد آليًا عند تثبيت وحدة مقبس. ما لم يُضبط DefaultDependencies=no، يتم إنشاء تبعيات الترتيب اللازمة ضمنيًا لجميع وحدات المقابس. لمزيد من المعلومات حول sockets.target، انظر systemd.special(7). ليس من الضروري أو الموصى به وضع أي تبعيات إضافية على وحدات المقابس (على سبيل المثال من multi-user.target أو ما شابه) عندما تكون مثبتة في sockets.target.

  التفعيل القائم على الناقل

عند استخدام نظام IPC الخاص بـ D-Bus للتواصل مع العملاء، ينبغي للبرامج الخفية ذات النمط الجديد استخدام تنشيط الناقل بحيث تُنشَّط آليًا عندما يصل تطبيق عميل إلى واجهات IPC الخاصة بها. يُهيأ هذا في ملفات خدمة D-Bus (لا تخلط بينها وبين ملفات وحدات خدمة systemd!). لضمان استخدام D-Bus لـ systemd لبدء البرنامج الخفي وصيانته، استخدم التوجيه SystemdService= في ملفات الخدمة هذه لتهيئة خدمة systemd المطابقة لخدمة D-Bus. مثال: بالنسبة لخدمة D-Bus التي يكون ملف تنشيط D-Bus الخاص بها باسم org.freedesktop.RealtimeKit.service، تأكد من تعيين SystemdService=rtkit-daemon.service في ذلك الملف لربطها بخدمة systemd rtkit-daemon.service. هذا ضروري لضمان بدء البرنامج الخفي بطريقة خالية من السباق عند تنشيطه عبر آليات متعددة في وقت واحد.

  التفعيل القائم على الجهاز

غالبًا، ينبغي تنشيط البرامج الخفية التي تدير نوعًا معينًا من العتاد فقط عند توصيل العتاد من النوع المعني أو عند توفره بطريقة أخرى. في نظام init ذي النمط الجديد، من الممكن ربط التنشيط بأحداث توصيل/فصل العتاد. في systemd، يمكن عرض أجهزة النواة التي تظهر في شجرة أجهزة sysfs/udev كوحدات إذا كانت موسومة بالسلسلة "systemd". مثل أي نوع آخر من الوحدات، يمكنها بعد ذلك سحب وحدات أخرى عند تنشيطها (أي عند توصيلها) وبالتالي تنفيذ تنشيط مستند إلى الجهاز. يمكن ترميز تبعيات systemd في قاعدة بيانات udev عبر الخاصية SYSTEMD_WANTS=. انظر systemd.device(5) للتفاصيل. غالبًا، من الأفضل سحب الخدمات من الأجهزة بشكل غير مباشر فقط عبر أهداف مخصصة. مثال: بدلاً من سحب bluetoothd.service من جميع أجهزة البلوتوث المختلفة والعتاد الآخر المتاح، اسحب bluetooth.target منها و bluetoothd.service من ذلك الهدف. يوفر هذا تجريدًا أفضل ويعطي المسؤولين خيار تمكين bluetoothd.service عبر التحكم في رابط رمزي bluetooth.target.wants/ بشكل موحد بأمر مثل enable من systemctl(1) بدلاً من التلاعب بمجموعة قواعد udev.

  التفعيل القائم على المسار

غالبًا، يمكن تأخير وقت تشغيل البرامج الخفية التي تعالج ملفات أو أدلة التخزين المؤقت (مثل نظام الطباعة) حتى تغير كائنات نظام الملفات هذه حالتها، أو تصبح غير فارغة. توفر أنظمة init ذات النمط الجديد طريقة لربط تنشيط الخدمة بتغييرات نظام الملفات. ينفذ systemd هذا المخطط عبر التنشيط المستند إلى المسار المُهيأ في وحدات .path، كما هو موضح في systemd.path(5).

  التفعيل القائم على المؤقت

تستفيد بعض البرامج الخفية التي تنفذ مهام تنظيف يُقصد تنفيذها على فترات منتظمة من التنشيط المستند إلى المؤقت. في systemd، يُنفذ هذا عبر وحدات .timer، كما هو موصوف في systemd.timer(5).

  أشكال أخرى من التفعيل

اقتُرحت أشكال أخرى من التنشيط ونُفذت في بعض الأنظمة. ومع ذلك، غالبًا ما توجد بدائل أبسط أو أفضل، أو يمكن تجميعها من مجموعات المخططات أعلاه. مثال: أحيانًا، يبدو من المفيد بدء البرامج الخفية أو وحدات .socket عند تهيئة عنوان IP محدد على واجهة شبكة، لأن مقابس الشبكة ينبغي ربطها بالعنوان. ومع ذلك، البديل لتنفيذ هذا هو استخدام خيار مقبس Linux IP_FREEBIND/IPV6_FREEBIND، كما هو متاح عبر FreeBind=yes في ملفات مقبس systemd (انظر systemd.socket(5) للتفاصيل). هذا الخيار، عند تمكينه، يسمح بربط المقابس بعنوان IP غير محلي وغير مهيأ، وبالتالي يسمح بالربط بعنوان IP معين قبل أن يصبح متاحًا فعليًا، مما يجعل هذا الاعتماد الصريح على العنوان المهيأ زائدًا. المحفز الآخر المقترح غالبًا لتنشيط الخدمة هو انخفاض حمل النظام. ومع ذلك، هنا أيضًا، قد يكون النهج الأكثر إقناعًا هو الاستخدام السليم لميزات نظام التشغيل، ولا سيما جدولة CPU أو I/O في Linux. بدلاً من جدولة المهام من مساحة المستخدم بناءً على مراقبة جدولة نظام التشغيل، يُنصح بترك جدولة العمليات لجدولة نظام التشغيل نفسها. يوفر systemd وصولًا دقيقًا إلى جداول CPU و I/O. إذا كان من المفترض ألا تؤثر عملية ينفذها مدير الخدمة سلبًا على مقدار عرض النطاق الترددي لوحدة المعالجة المركزية أو الإدخال/الإخراج المتاح للعمليات الأخرى، فينبغي تهيئتها باستخدام CPUSchedulingPolicy=idle و/أو IOSchedulingClass=idle. اختياريًا، يمكن دمج هذا مع التنشيط المستند إلى المؤقت لجدولة مهام الخلفية أثناء وقت التشغيل وبأقل تأثير على النظام، وإزالتها من مرحلة الإقلاع نفسها.

التكامل مع SYSTEMD

  كتابة ملفات وحدات systemd

عند كتابة ملفات وحدات systemd، يُوصى بمراعاة الاقتراحات التالية:

    1. إذا أمكن، لا تستخدم الإعداد Type=forking في ملفات الخدمة. ولكن إذا فعلت، تأكد من تعيين مسار ملف PID باستخدام PIDFile=. انظر systemd.service(5) للتفاصيل.

    2. إذا سجل برنامجك الخفي اسم D-Bus على الناقل، تأكد من استخدام Type=dbus في ملف الخدمة إذا أمكن.

    3. تأكد من تعيين سلسلة وصف جيدة قابلة للقراءة البشرية باستخدام Description=.

    4. لا تعطل DefaultDependencies=، إلا إذا كنت تعرف حقًا ما تفعل ووحدتك متورطة في الإقلاع المبكر أو إيقاف تشغيل النظام المتأخر.

    5. عادةً، لا ينبغي تعريف سوى القليل من التبعيات بشكل صريح. ومع ذلك، إذا قمت بتهيئة تبعيات صريحة، فاشير فقط إلى أسماء الوحدات المدرجة في systemd.special(7) أو الأسماء التي قدمتها حزمتك الخاصة للحفاظ على استقلالية ملف الوحدة عن نظام التشغيل.

    6. تأكد من تضمين قسم [Install] يتضمن معلومات التثبيت لملف الوحدة. انظر systemd.unit(5) للتفاصيل. لتنشيط خدمتك عند الإقلاع، تأكد من إضافة توجيه WantedBy=multi-user.target أو WantedBy=graphical.target. لتنشيط مقبسك عند الإقلاع، تأكد من إضافة WantedBy=sockets.target. عادةً، تريد أيضًا التأكد من أنه عند تثبيت خدمتك، يُثبت مقبسك أيضًا، لذا أضف Also=foo.socket في ملف الخدمة foo.service، لبرنامج افتراضي foo.

  تثبيت ملفات خدمة systemd

في وقت تثبيت البناء (مثل make install أثناء بناء الحزمة)، يُوصى بأن تثبت الحزم ملفات وحدات systemd الخاصة بها في الدليل الذي يعيده pkg-config systemd --variable=systemdsystemunitdir (للخدمات النظامية) أو pkg-config systemd --variable=systemduserunitdir (للخدمات المستخدمة). هذا سيجعل الخدمات متاحة في النظام عند الطلب الصريح ولكن لن ينشطها آليًا أثناء الإقلاع. اختياريًا، أثناء تثبيت الحزمة (مثل rpm -i من قبل المسؤول)، ينبغي إنشاء روابط رمزية في أدلة تهيئة systemd عبر أمر enable من أداة systemctl(1) لتنشيطها آليًا عند الإقلاع.

يُوصى بأن تستخدم الحزم التي تستخدم autoconf(1) مقتطف سكريبت تهيئة مثل التالي لتحديد مسار تثبيت الوحدة أثناء تهيئة المصدر:

    PKG_PROG_PKG_CONFIG()
    AC_ARG_WITH([systemdsystemunitdir],
         [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
         [with_systemdsystemunitdir=auto])
    AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
         def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
         AS_IF([test "x$def_systemdsystemunitdir" = "x"],
       [AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
        [AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
        with_systemdsystemunitdir=no],
       [with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
    AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
          [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
    AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])

يتيح هذا المقتطف التثبيت التلقائي لملفات الوحدات على الأجهزة التي تعمل بنظام systemd، كما يتيح اختيارياً تثبيتها حتى على الأجهزة التي لا تعمل بنظام systemd. (يُترك تعديل هذا المقتطف ليتناسب مع دليل وحدات المستخدم كتمرين للقارئ.)

بالإضافة إلى ذلك، لضمان استمرار عمل make distcheck، يُنصح بإضافة ما يلي إلى ملف Makefile.am في المستوى الأعلى في المشاريع القائمة على automake(1):

    AM_DISTCHECK_CONFIGURE_FLAGS = \
      --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)

أخيرًا، يجب تثبيت ملفات الوحدات في النظام باستخدام مقتطف أتوميك مثل التالي:

    if HAVE_SYSTEMD
    systemdsystemunit_DATA = \
      foobar.socket \
      foobar.service
    endif

في ملف rpm(8) .spec، استخدم مقتطفات مثل التالية لتمكين/تعطيل الخدمة أثناء التثبيت/إلغاء التثبيت. يستخدم هذا وحدات RPM المرفقة مع systemd. راجع إرشادات التعبئة لتوزيعتك للحصول على التفاصيل والمكافئ لمديري الحزم الآخرين.

في أعلى الملف:

    BuildRequires: systemd
    %{?systemd_requires}

وكبرامج نصية، في الأسفل:

    %post
    %systemd_post foobar.service foobar.socket
    %preun
    %systemd_preun foobar.service foobar.socket
    %postun
    %systemd_postun

إذا أُعيد تشغيل الخدمة أثناء الترقيات، استبدل البرنامج النصي "%postun" أعلاه بالتالي:

    %postun
    %systemd_postun_with_restart foobar.service

لاحظ أن "%systemd_post" و "%systemd_preun" تتوقعان أسماء جميع الوحدات المثبتة/المحذوفة كوسائط، مفصولة بمسافات. "%systemd_postun" لا تتوقع وسائط. "%systemd_postun_with_restart" تتوقع الوحدات المراد إعادة تشغيلها كوسائط.

لتسهيل الترقيات من إصدار حزمة شحن نصوص SysV init فقط إلى إصدار حزمة يشحن كلًا من نص SysV init وملف خدمة systemd أصلي، استخدم مقطعًا مثل التالي:

    %triggerun -- foobar < 0.47.11-1
    if /sbin/chkconfig --level 5 foobar ; then
      /bin/systemctl --no-reload enable foobar.service foobar.socket >/dev/null 2>&1 || :
    fi

حيث 0.47.11-1 هو أول إصدار حزمة يتضمن ملف الوحدة الأصلي. سيضمن هذا المقطع أنه عند تثبيت ملف الوحدة لأول مرة، سيُمكن إذا وفقط إذا كان نص SysV init مُمكنًا، مما يضمن عدم تغيير حالة التمكين. لاحظ أن chkconfig هو أمر خاص بـ Fedora يُستخدم للتحقق مما إذا كان نص SysV init مُمكنًا. ستستخدم أنظمة التشغيل الأخرى أوامر مختلفة هنا.

نقل الدايمونات الموجودة

نظرًا لأن أنظمة init الحديثة مثل systemd متوافقة مع أنظمة SysV init التقليدية، فليس من الضروري نقل البرامج الخلفية الموجودة إلى النمط الجديد. ومع ذلك، فإن القيام بذلك يوفر وظائف إضافية للبرامج الخلفية بالإضافة إلى تبسيط التكامل في أنظمة init الحديثة.

لنقل برنامج خلفي موجود متوافق مع SysV، يُوصى بالخطوات التالية:

    1. إذا لم يُنفذ بالفعل، أضف مفتاح سطر أوامر اختياريًا للبرنامج الخلفي لتعطيل التحول إلى برنامج خلفي. هذا مفيد ليس فقط لاستخدام البرنامج الخلفي في أنظمة init الحديثة، ولكن أيضًا لتسهيل التصحيح.

    2. إذا كان البرنامج الخلفي يوفر واجهات لبرامج أخرى تعمل على النظام المحلي عبر مقابس AF_UNIX محلية، فكر في تنفيذ التنشيط القائم على المقبس (انظر أعلاه). عادةً، يكفي تصحيح بسيط لتنفيذ هذا: وسّع إنشاء المقبس في كود البرنامج الخلفي بحيث يُفحص sd_listen_fds(3) للمقابس الممررة بالفعل أولاً. إذا مُررت المقابس (أي عندما يُرجع sd_listen_fds() قيمة موجبة)، تخط خطوة إنشاء المقبس واستخدم المقابس الممررة. ثانيًا، تأكد من عدم إزالة عقد مقبس نظام الملفات لمقابس AF_UNIX المحلية المستخدمة في التنشيط القائم على المقبس عند إيقاف تشغيل البرنامج الخلفي، إذا مُررت المقابس. ثالثًا، إذا كان البرنامج الخلفي يغلق عادةً جميع واصفات الملفات المفتوحة المتبقية كجزء من تهيئته، فيجب تجنيب المقابس الممررة من مدير الخدمة. نظرًا لأن أنظمة init الحديثة تضمن عدم تمرير واصفات ملفات متبقية إلى العمليات المنفذة، فقد يكون اختيارًا جيدًا تخطي إغلاق جميع واصفات الملفات المفتوحة المتبقية إذا مُررت المقابس.

    3. اكتب وقم بتثبيت ملف وحدة systemd للخدمة (والمقابس إذا استُخدم التنشيط القائم على المقبس، بالإضافة إلى ملف وحدة مسار، إذا كان البرنامج الخلفي يعالج دليل انتظار)، انظر أعلاه للتفاصيل.

    4. إذا كان البرنامج الخلفي يعرض واجهات عبر D-Bus، اكتب وقم بتثبيت ملف تنشيط D-Bus للخدمة، انظر أعلاه للتفاصيل.

وضع بيانات البرنامج الخلفي

يُوصى باتباع الإرشادات العامة لوضع ملفات الحزمة، كما نوقش في file-hierarchy(7).

ملاحظات

جميع أمثلة الأكواد في هذه الصفحة مرخصة بموجب "MIT No Attribution" (SPDX-License-Identifier: MIT-0).

انظر أيضًا

systemd(1)، sd-daemon(3)، sd_listen_fds(3)، sd_notify(3)، daemon(3)، systemd.service(5)، file-hierarchy(7)

ملاحظات

1.  توصيات LSB لنصوص تهيئة SysV
    http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html

2.  متطلبات دايمون Apple MacOS X
    https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.